FFmpeg
wtvenc.c
Go to the documentation of this file.
1 /*
2  * Windows Television (WTV) muxer
3  * Copyright (c) 2011 Zhentan Feng <spyfeng at gmail dot com>
4  * Copyright (c) 2011 Peter Ross <pross@xvid.org>
5  * This file is part of FFmpeg.
6  *
7  * FFmpeg is free software; you can redistribute it and/or
8  * modify it under the terms of the GNU Lesser General Public
9  * License as published by the Free Software Foundation; either
10  * version 2.1 of the License, or (at your option) any later version.
11  *
12  * FFmpeg is distributed in the hope that it will be useful,
13  * but WITHOUT ANY WARRANTY; without even the implied warranty of
14  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
15  * Lesser General Public License for more details.
16  *
17  * You should have received a copy of the GNU Lesser General Public
18  * License along with FFmpeg; if not, write to the Free Software
19  * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
20  */
21 
22 /**
23  * @file
24  * Windows Television (WTV) demuxer
25  * @author Zhentan Feng <spyfeng at gmail dot com>
26  */
27 
28 #include "libavutil/avassert.h"
29 #include "libavutil/mem.h"
30 #include "avformat.h"
31 #include "avio_internal.h"
32 #include "internal.h"
33 #include "mpegts.h"
34 #include "mux.h"
35 #include "wtv.h"
36 
37 #define WTV_BIGSECTOR_SIZE (1 << WTV_BIGSECTOR_BITS)
38 #define INDEX_BASE 0x2
39 #define MAX_NB_INDEX 10
40 
41 /* declare utf16le strings */
42 #define _ , 0,
43 static const uint8_t timeline_table_0_header_events[] =
44  {'t'_'i'_'m'_'e'_'l'_'i'_'n'_'e'_'.'_'t'_'a'_'b'_'l'_'e'_'.'_'0'_'.'_'h'_'e'_'a'_'d'_'e'_'r'_'.'_'E'_'v'_'e'_'n'_'t'_'s', 0};
45 static const uint8_t table_0_header_legacy_attrib[] =
46  {'t'_'a'_'b'_'l'_'e'_'.'_'0'_'.'_'h'_'e'_'a'_'d'_'e'_'r'_'.'_'l'_'e'_'g'_'a'_'c'_'y'_'_'_'a'_'t'_'t'_'r'_'i'_'b', 0};
47 static const uint8_t table_0_redirector_legacy_attrib[] =
48  {'t'_'a'_'b'_'l'_'e'_'.'_'0'_'.'_'r'_'e'_'d'_'i'_'r'_'e'_'c'_'t'_'o'_'r'_'.'_'l'_'e'_'g'_'a'_'c'_'y'_'_'_'a'_'t'_'t'_'r'_'i'_'b', 0};
49 static const uint8_t table_0_header_time[] =
50  {'t'_'a'_'b'_'l'_'e'_'.'_'0'_'.'_'h'_'e'_'a'_'d'_'e'_'r'_'.'_'t'_'i'_'m'_'e', 0};
51 static const uint8_t legacy_attrib[] =
52  {'l'_'e'_'g'_'a'_'c'_'y'_'_'_'a'_'t'_'t'_'r'_'i'_'b', 0};
53 #undef _
54 
55 static const ff_asf_guid sub_wtv_guid =
56  {0x8C,0xC3,0xD2,0xC2,0x7E,0x9A,0xDA,0x11,0x8B,0xF7,0x00,0x07,0xE9,0x5E,0xAD,0x8D};
57 
68 };
69 
70 typedef struct {
71  int64_t length;
72  const void *header;
73  int depth;
75 } WtvFile;
76 
77 typedef struct {
78  int64_t pos;
79  int64_t serial;
80  const ff_asf_guid * guid;
81  int stream_id;
83 
84 typedef struct {
85  int64_t serial;
86  int64_t value;
87 } WtvSyncEntry;
88 
89 typedef struct {
92  int64_t serial; /**< chunk serial number */
93  int64_t last_chunk_pos; /**< last chunk position */
94  int64_t last_timestamp_pos; /**< last timestamp chunk position */
95  int64_t first_index_pos; /**< first index_chunk position */
96 
98  int nb_index;
100 
101  WtvSyncEntry *st_pairs; /* (serial, timestamp) pairs */
103  WtvSyncEntry *sp_pairs; /* (serial, position) pairs */
105 
106  int64_t last_pts;
107  int64_t last_serial;
108 
110 } WtvContext;
111 
112 
113 static void add_serial_pair(WtvSyncEntry ** list, int * count, int64_t serial, int64_t value)
114 {
115  int new_count = *count + 1;
116  WtvSyncEntry *new_list = av_realloc_array(*list, new_count, sizeof(WtvSyncEntry));
117  if (!new_list)
118  return;
119  new_list[*count] = (WtvSyncEntry){serial, value};
120  *list = new_list;
121  *count = new_count;
122 }
123 
125 
126 typedef struct {
127  const uint8_t *header;
131 
132 #define write_pad(pb, size) ffio_fill(pb, 0, size)
133 
134 /**
135  * Write chunk header. If header chunk (0x80000000 set) then add to list of header chunks
136  */
137 static void write_chunk_header(AVFormatContext *s, const ff_asf_guid *guid, int length, int stream_id)
138 {
139  WtvContext *wctx = s->priv_data;
140  AVIOContext *pb = s->pb;
141 
142  wctx->last_chunk_pos = avio_tell(pb) - wctx->timeline_start_pos;
143  ff_put_guid(pb, guid);
144  avio_wl32(pb, 32 + length);
145  avio_wl32(pb, stream_id);
146  avio_wl64(pb, wctx->serial);
147 
148  if ((stream_id & 0x80000000) && guid != &ff_index_guid) {
149  WtvChunkEntry *t = wctx->index + wctx->nb_index;
151  t->pos = wctx->last_chunk_pos;
152  t->serial = wctx->serial;
153  t->guid = guid;
154  t->stream_id = stream_id & 0x3FFFFFFF;
155  wctx->nb_index++;
156  }
157 }
158 
159 static void write_chunk_header2(AVFormatContext *s, const ff_asf_guid *guid, int stream_id)
160 {
161  WtvContext *wctx = s->priv_data;
162  AVIOContext *pb = s->pb;
163 
164  int64_t last_chunk_pos = wctx->last_chunk_pos;
165  write_chunk_header(s, guid, 0, stream_id); // length updated later
166  avio_wl64(pb, last_chunk_pos);
167 }
168 
170 {
171  WtvContext *wctx = s->priv_data;
172  AVIOContext *pb = s->pb;
173 
174  // update the chunk_len field and pad.
175  int64_t chunk_len = avio_tell(pb) - (wctx->last_chunk_pos + wctx->timeline_start_pos);
176  avio_seek(pb, -(chunk_len - 16), SEEK_CUR);
177  avio_wl32(pb, chunk_len);
178  avio_seek(pb, chunk_len - (16 + 4), SEEK_CUR);
179 
180  write_pad(pb, WTV_PAD8(chunk_len) - chunk_len);
181  wctx->serial++;
182 }
183 
185 {
186  AVIOContext *pb = s->pb;
187  WtvContext *wctx = s->priv_data;
188  int i;
189 
190  write_chunk_header2(s, &ff_index_guid, 0x80000000);
191  avio_wl32(pb, 0);
192  avio_wl32(pb, 0);
193 
194  for (i = 0; i < wctx->nb_index; i++) {
195  WtvChunkEntry *t = wctx->index + i;
196  ff_put_guid(pb, t->guid);
197  avio_wl64(pb, t->pos);
198  avio_wl32(pb, t->stream_id);
199  avio_wl32(pb, 0); // checksum?
200  avio_wl64(pb, t->serial);
201  }
202  wctx->nb_index = 0; // reset index
204 
205  if (!wctx->first_index_pos)
206  wctx->first_index_pos = wctx->last_chunk_pos;
207 }
208 
210 {
211  WtvContext *wctx = s->priv_data;
213  if (wctx->nb_index == MAX_NB_INDEX)
214  write_index(s);
215 }
216 
218 {
219  AVRational dar = av_mul_q(st->sample_aspect_ratio, (AVRational){st->codecpar->width, st->codecpar->height});
220  unsigned int num, den;
221  av_reduce(&num, &den, dar.num, dar.den, 0xFFFFFFFF);
222 
223  /* VIDEOINFOHEADER2 */
224  avio_wl32(pb, 0);
225  avio_wl32(pb, 0);
226  avio_wl32(pb, st->codecpar->width);
227  avio_wl32(pb, st->codecpar->height);
228 
229  avio_wl32(pb, 0);
230  avio_wl32(pb, 0);
231  avio_wl32(pb, 0);
232  avio_wl32(pb, 0);
233 
234  avio_wl32(pb, st->codecpar->bit_rate);
235  avio_wl32(pb, 0);
236  avio_wl64(pb, st->avg_frame_rate.num && st->avg_frame_rate.den ? INT64_C(10000000) / av_q2d(st->avg_frame_rate) : 0);
237  avio_wl32(pb, 0);
238  avio_wl32(pb, 0);
239 
240  avio_wl32(pb, num);
241  avio_wl32(pb, den);
242  avio_wl32(pb, 0);
243  avio_wl32(pb, 0);
244 
245  ff_put_bmp_header(pb, st->codecpar, 0, 1, 0);
246 
248  int padding = (st->codecpar->extradata_size & 3) ? 4 - (st->codecpar->extradata_size & 3) : 0;
249  /* MPEG2VIDEOINFO */
250  avio_wl32(pb, 0);
251  avio_wl32(pb, st->codecpar->extradata_size + padding);
252  avio_wl32(pb, -1);
253  avio_wl32(pb, -1);
254  avio_wl32(pb, 0);
256  ffio_fill(pb, 0, padding);
257  }
258 }
259 
261 {
262  const ff_asf_guid *g, *media_type, *format_type;
263  const AVCodecTag *tags;
264  AVIOContext *pb = s->pb;
265  int64_t hdr_pos_start;
266  int hdr_size = 0;
267 
268  if (st->codecpar->codec_type == AVMEDIA_TYPE_VIDEO) {
270  media_type = &ff_mediatype_video;
272  tags = ff_codec_bmp_tags;
273  } else if (st->codecpar->codec_type == AVMEDIA_TYPE_AUDIO) {
275  media_type = &ff_mediatype_audio;
276  format_type = &ff_format_waveformatex;
277  tags = ff_codec_wav_tags;
278  } else {
279  av_log(s, AV_LOG_ERROR, "unknown codec_type (0x%x)\n", st->codecpar->codec_type);
280  return -1;
281  }
282 
283  ff_put_guid(pb, media_type); // mediatype
285  write_pad(pb, 12);
286  ff_put_guid(pb,&ff_format_cpfilters_processed); // format type
287  avio_wl32(pb, 0); // size
288 
289  hdr_pos_start = avio_tell(pb);
290  if (st->codecpar->codec_type == AVMEDIA_TYPE_VIDEO) {
291  put_videoinfoheader2(pb, st);
292  } else {
293  if (ff_put_wav_header(s, pb, st->codecpar, 0) < 0)
294  format_type = &ff_format_none;
295  }
296  hdr_size = avio_tell(pb) - hdr_pos_start;
297 
298  // seek back write hdr_size
299  avio_seek(pb, -(hdr_size + 4), SEEK_CUR);
300  avio_wl32(pb, hdr_size + 32);
301  avio_seek(pb, hdr_size, SEEK_CUR);
302  if (g) {
303  ff_put_guid(pb, g); // actual_subtype
304  } else {
305  int tag = ff_codec_get_tag(tags, st->codecpar->codec_id);
306  if (!tag) {
307  av_log(s, AV_LOG_ERROR, "unsupported codec_id (0x%x)\n", st->codecpar->codec_id);
308  return -1;
309  }
310  avio_wl32(pb, tag);
311  avio_write(pb, (const uint8_t[]){FF_MEDIASUBTYPE_BASE_GUID}, 12);
312  }
313  ff_put_guid(pb, format_type); // actual_formattype
314 
315  return 0;
316 }
317 
319 {
320  AVIOContext *pb = s->pb;
321  int ret;
322  write_chunk_header2(s, &ff_stream1_guid, 0x80000000 | 0x01);
323 
324  avio_wl32(pb, 0x01);
325  write_pad(pb, 4);
326  write_pad(pb, 4);
327 
329  if (ret < 0) {
330  av_log(s, AV_LOG_ERROR, "write stream codec info failed codec_type(0x%x)\n", st->codecpar->codec_type);
331  return -1;
332  }
333 
334  finish_chunk(s);
335  return 0;
336 }
337 
339 {
340  AVIOContext *pb = s->pb;
341  WtvContext *wctx = s->priv_data;
342  int64_t last_chunk_pos = wctx->last_chunk_pos;
343 
344  write_chunk_header(s, &ff_sync_guid, 0x18, 0);
345  avio_wl64(pb, wctx->first_index_pos);
346  avio_wl64(pb, wctx->last_timestamp_pos);
347  avio_wl64(pb, 0);
348 
349  finish_chunk(s);
350  add_serial_pair(&wctx->sp_pairs, &wctx->nb_sp_pairs, wctx->serial, wctx->last_chunk_pos);
351 
352  wctx->last_chunk_pos = last_chunk_pos;
353 }
354 
356 {
357  AVIOContext *pb = s->pb;
358  int ret;
359 
361  avio_wl32(pb, 0x00000001);
362  avio_wl32(pb, st->index + INDEX_BASE); //stream_id
363  avio_wl32(pb, 0x00000001);
364  write_pad(pb, 8);
365 
367  if (ret < 0) {
368  av_log(s, AV_LOG_ERROR, "write stream codec info failed codec_type(0x%x)\n", st->codecpar->codec_type);
369  return -1;
370  }
371  finish_chunk(s);
372 
373  avpriv_set_pts_info(st, 64, 1, 10000000);
374 
375  return 0;
376 }
377 
379 {
380  AVIOContext *pb = s->pb;
381  WtvContext *wctx = s->priv_data;
382  int i, pad, ret;
383  AVStream *st;
384 
385  wctx->last_chunk_pos = -1;
386  wctx->last_timestamp_pos = -1;
387 
388  ff_put_guid(pb, &ff_wtv_guid);
390 
391  avio_wl32(pb, 0x01);
392  avio_wl32(pb, 0x02);
393  avio_wl32(pb, 1 << WTV_SECTOR_BITS);
394  avio_wl32(pb, 1 << WTV_BIGSECTOR_BITS);
395 
396  //write initial root fields
397  avio_wl32(pb, 0); // root_size, update later
398  write_pad(pb, 4);
399  avio_wl32(pb, 0); // root_sector, update it later.
400 
401  write_pad(pb, 32);
402  avio_wl32(pb, 0); // file ends pointer, update it later.
403 
404  pad = (1 << WTV_SECTOR_BITS) - avio_tell(pb);
405  write_pad(pb, pad);
406 
407  wctx->timeline_start_pos = avio_tell(pb);
408 
409  wctx->serial = 1;
410  wctx->last_chunk_pos = -1;
411  wctx->first_video_flag = 1;
412 
413  for (i = 0; i < s->nb_streams; i++) {
414  st = s->streams[i];
415  if (st->codecpar->codec_id == AV_CODEC_ID_MJPEG)
416  continue;
417  ret = write_stream_codec(s, st);
418  if (ret < 0) {
419  av_log(s, AV_LOG_ERROR, "write stream codec failed codec_type(0x%x)\n", st->codecpar->codec_type);
420  return -1;
421  }
422  if (!i)
423  write_sync(s);
424  }
425 
426  for (i = 0; i < s->nb_streams; i++) {
427  st = s->streams[i];
428  if (st->codecpar->codec_id == AV_CODEC_ID_MJPEG)
429  continue;
430  ret = write_stream_data(s, st);
431  if (ret < 0) {
432  av_log(s, AV_LOG_ERROR, "write stream data failed codec_type(0x%x)\n", st->codecpar->codec_type);
433  return -1;
434  }
435  }
436 
437  if (wctx->nb_index)
438  write_index(s);
439 
440  return 0;
441 }
442 
444 {
445  AVIOContext *pb = s->pb;
446  WtvContext *wctx = s->priv_data;
447  AVCodecParameters *par = s->streams[pkt->stream_index]->codecpar;
448 
450  write_pad(pb, 8);
451  avio_wl64(pb, pkt->pts == AV_NOPTS_VALUE ? -1 : pkt->pts);
452  avio_wl64(pb, pkt->pts == AV_NOPTS_VALUE ? -1 : pkt->pts);
453  avio_wl64(pb, pkt->pts == AV_NOPTS_VALUE ? -1 : pkt->pts);
454  avio_wl64(pb, 0);
455  avio_wl64(pb, par->codec_type == AVMEDIA_TYPE_VIDEO && (pkt->flags & AV_PKT_FLAG_KEY) ? 1 : 0);
456  avio_wl64(pb, 0);
457 
458  wctx->last_timestamp_pos = wctx->last_chunk_pos;
459 }
460 
462 {
463  AVIOContext *pb = s->pb;
464  WtvContext *wctx = s->priv_data;
465  AVStream *st = s->streams[pkt->stream_index];
466 
467  if (st->codecpar->codec_id == AV_CODEC_ID_MJPEG && !wctx->thumbnail.size) {
468  av_packet_ref(&wctx->thumbnail, pkt);
469  return 0;
470  } else if (st->codecpar->codec_id == AV_CODEC_ID_H264) {
471  int ret = ff_check_h264_startcode(s, st, pkt);
472  if (ret < 0)
473  return ret;
474  }
475 
476  /* emit sync chunk and 'timeline.table.0.entries.Event' record every 50 frames */
477  if (wctx->serial - (wctx->nb_sp_pairs ? wctx->sp_pairs[wctx->nb_sp_pairs - 1].serial : 0) >= 50)
478  write_sync(s);
479 
480  /* emit 'table.0.entries.time' record every 500ms */
481  if (pkt->pts != AV_NOPTS_VALUE && pkt->pts - (wctx->nb_st_pairs ? wctx->st_pairs[wctx->nb_st_pairs - 1].value : 0) >= 5000000)
482  add_serial_pair(&wctx->st_pairs, &wctx->nb_st_pairs, wctx->serial, pkt->pts);
483 
484  if (pkt->pts != AV_NOPTS_VALUE && pkt->pts > wctx->last_pts) {
485  wctx->last_pts = pkt->pts;
486  wctx->last_serial = wctx->serial;
487  }
488 
489  // write timestamp chunk
491 
493  avio_write(pb, pkt->data, pkt->size);
494  write_pad(pb, WTV_PAD8(pkt->size) - pkt->size);
495 
496  wctx->serial++;
497  return 0;
498 }
499 
501 {
502  avio_wl32(pb, 0x10);
503  write_pad(pb, 84);
504  avio_wl64(pb, 0x32);
505  return 96;
506 }
507 
509 {
510  int pad = 0;
511  avio_wl32(pb, 0xFFFFFFFF);
512  write_pad(pb, 12);
513  avio_write(pb, legacy_attrib, sizeof(legacy_attrib));
514  pad = WTV_PAD8(sizeof(legacy_attrib)) - sizeof(legacy_attrib);
515  write_pad(pb, pad);
516  write_pad(pb, 32);
517  return 48 + WTV_PAD8(sizeof(legacy_attrib));
518 }
519 
521 {
522  avio_wl32(pb, 0x10);
523  write_pad(pb, 76);
524  avio_wl64(pb, 0x40);
525  return 88;
526 }
527 
537 };
538 
539 static int write_root_table(AVFormatContext *s, int64_t sector_pos)
540 {
541  AVIOContext *pb = s->pb;
542  WtvContext *wctx = s->priv_data;
543  int size, pad;
544  int i;
545 
547  for (i = 0; i < sizeof(wtv_root_entry_table)/sizeof(WTVRootEntryTable); i++, h++) {
548  WtvFile *w = &wctx->file[i];
549  int filename_padding = WTV_PAD8(h->header_size) - h->header_size;
550  WTVHeaderWriteFunc *write = h->write_header;
551  int len = 0;
552  int64_t len_pos;
553 
555  len_pos = avio_tell(pb);
556  avio_wl16(pb, 40 + h->header_size + filename_padding + 8); // maybe updated later
557  write_pad(pb, 6);
558  avio_wl64(pb, write ? 0 : w->length);// maybe update later
559  avio_wl32(pb, (h->header_size + filename_padding) >> 1);
560  write_pad(pb, 4);
561 
562  avio_write(pb, h->header, h->header_size);
563  write_pad(pb, filename_padding);
564 
565  if (write) {
566  len = write(pb);
567  // update length field
568  avio_seek(pb, len_pos, SEEK_SET);
569  avio_wl64(pb, 40 + h->header_size + filename_padding + len);
570  avio_wl64(pb, len |(1ULL<<62) | (1ULL<<60));
571  avio_seek(pb, 8 + h->header_size + filename_padding + len, SEEK_CUR);
572  } else {
573  avio_wl32(pb, w->first_sector);
574  avio_wl32(pb, w->depth);
575  }
576  }
577 
578  // caculate root table size
579  size = avio_tell(pb) - sector_pos;
580  pad = WTV_SECTOR_SIZE- size;
581  write_pad(pb, pad);
582 
583  return size;
584 }
585 
586 static void write_fat(AVIOContext *pb, int start_sector, int nb_sectors, int shift)
587 {
588  int i;
589  for (i = 0; i < nb_sectors; i++) {
590  avio_wl32(pb, start_sector + (i << shift));
591  }
592  // pad left sector pointer size
593  write_pad(pb, WTV_SECTOR_SIZE - ((nb_sectors << 2) % WTV_SECTOR_SIZE));
594 }
595 
596 static int64_t write_fat_sector(AVFormatContext *s, int64_t start_pos, int nb_sectors, int sector_bits, int depth)
597 {
598  int64_t start_sector = start_pos >> WTV_SECTOR_BITS;
599  int shift = sector_bits - WTV_SECTOR_BITS;
600 
601  int64_t fat = avio_tell(s->pb);
602  write_fat(s->pb, start_sector, nb_sectors, shift);
603 
604  if (depth == 2) {
605  int64_t start_sector1 = fat >> WTV_SECTOR_BITS;
606  int nb_sectors1 = ((nb_sectors << 2) + WTV_SECTOR_SIZE - 1) / WTV_SECTOR_SIZE;
607  int64_t fat1 = avio_tell(s->pb);
608 
609  write_fat(s->pb, start_sector1, nb_sectors1, 0);
610  return fat1;
611  }
612 
613  return fat;
614 }
615 
617 {
618  AVIOContext *pb = s->pb;
619  WtvContext *wctx = s->priv_data;
620  int i;
621  for (i = 0; i < wctx->nb_sp_pairs; i++) {
622  avio_wl64(pb, wctx->sp_pairs[i].serial);
623  avio_wl64(pb, wctx->sp_pairs[i].value);
624  }
625 }
626 
628 {
629  AVIOContext *pb = s->pb;
630  WtvContext *wctx = s->priv_data;
631  int i;
632  for (i = 0; i < wctx->nb_st_pairs; i++) {
633  avio_wl64(pb, wctx->st_pairs[i].value);
634  avio_wl64(pb, wctx->st_pairs[i].serial);
635  }
636  avio_wl64(pb, wctx->last_pts);
637  avio_wl64(pb, wctx->last_serial);
638 }
639 
640 static void write_metadata_header(AVIOContext *pb, int type, const char *key, int value_size)
641 {
643  avio_wl32(pb, type);
644  avio_wl32(pb, value_size);
645  avio_put_str16le(pb, key);
646 }
647 
648 static int metadata_header_size(const char *key)
649 {
650  return 16 + 4 + 4 + strlen(key)*2 + 2;
651 }
652 
653 static void write_tag_int32(AVIOContext *pb, const char *key, int value)
654 {
655  write_metadata_header(pb, 0, key, 4);
656  avio_wl32(pb, value);
657 }
658 
659 static void write_tag(AVIOContext *pb, const char *key, const char *value)
660 {
661  write_metadata_header(pb, 1, key, strlen(value)*2 + 2);
662  avio_put_str16le(pb, value);
663 }
664 
666 {
667  return strlen("image/jpeg")*2 + 2 + 1 + (e ? strlen(e->value)*2 : 0) + 2 + 4 + pkt->size;
668 }
669 
671 {
672  WtvContext *wctx = s->priv_data;
673  AVIOContext *pb = s->pb;
674  const AVDictionaryEntry *tag = NULL;
675 
677  //FIXME: translate special tags (e.g. WM/Bitrate) to binary representation
679  while ((tag = av_dict_iterate(s->metadata, tag)))
680  write_tag(pb, tag->key, tag->value);
681 
682  if (wctx->thumbnail.size) {
683  AVStream *st = s->streams[wctx->thumbnail.stream_index];
684  tag = av_dict_get(st->metadata, "title", NULL, 0);
685  write_metadata_header(pb, 2, "WM/Picture", attachment_value_size(&wctx->thumbnail, tag));
686 
687  avio_put_str16le(pb, "image/jpeg");
688  avio_w8(pb, 0x10);
689  avio_put_str16le(pb, tag ? tag->value : "");
690 
691  avio_wl32(pb, wctx->thumbnail.size);
692  avio_write(pb, wctx->thumbnail.data, wctx->thumbnail.size);
693 
694  write_tag_int32(pb, "WM/MediaThumbType", 2);
695  }
696 }
697 
699 {
700  WtvContext *wctx = s->priv_data;
701  AVIOContext *pb = s->pb;
702  const AVDictionaryEntry *tag = NULL;
703  int64_t pos = 0;
704 
705  //FIXME: translate special tags to binary representation
706  while ((tag = av_dict_iterate(s->metadata, tag))) {
707  avio_wl64(pb, pos);
708  pos += metadata_header_size(tag->key) + strlen(tag->value)*2 + 2;
709  }
710 
711  if (wctx->thumbnail.size) {
712  AVStream *st = s->streams[wctx->thumbnail.stream_index];
713  avio_wl64(pb, pos);
714  pos += metadata_header_size("WM/Picture") + attachment_value_size(&wctx->thumbnail, av_dict_get(st->metadata, "title", NULL, 0));
715 
716  avio_wl64(pb, pos);
717  pos += metadata_header_size("WM/MediaThumbType") + 4;
718  }
719 }
720 
721 /**
722  * Pad the remainder of a file
723  * Write out fat table
724  * @return <0 on error
725  */
726 static int finish_file(AVFormatContext *s, enum WtvFileIndex index, int64_t start_pos)
727 {
728  WtvContext *wctx = s->priv_data;
729  AVIOContext *pb = s->pb;
730  WtvFile *w = &wctx->file[index];
731  int64_t end_pos = avio_tell(pb);
732  int sector_bits, nb_sectors, pad;
733 
735 
736  w->length = (end_pos - start_pos);
737 
738  // determine optimal fat table depth, sector_bits, nb_sectors
739  if (w->length <= WTV_SECTOR_SIZE) {
740  w->depth = 0;
741  sector_bits = WTV_SECTOR_BITS;
742  } else if (w->length <= (WTV_SECTOR_SIZE / 4) * WTV_SECTOR_SIZE) {
743  w->depth = 1;
744  sector_bits = WTV_SECTOR_BITS;
745  } else if (w->length <= (WTV_SECTOR_SIZE / 4) * WTV_BIGSECTOR_SIZE) {
746  w->depth = 1;
747  sector_bits = WTV_BIGSECTOR_BITS;
748  } else if (w->length <= (int64_t)(WTV_SECTOR_SIZE / 4) * (WTV_SECTOR_SIZE / 4) * WTV_SECTOR_SIZE) {
749  w->depth = 2;
750  sector_bits = WTV_SECTOR_BITS;
751  } else if (w->length <= (int64_t)(WTV_SECTOR_SIZE / 4) * (WTV_SECTOR_SIZE / 4) * WTV_BIGSECTOR_SIZE) {
752  w->depth = 2;
753  sector_bits = WTV_BIGSECTOR_BITS;
754  } else {
755  av_log(s, AV_LOG_ERROR, "unsupported file allocation table depth (%"PRIi64" bytes)\n", w->length);
756  return -1;
757  }
758 
759  // determine the nb_sectors
760  nb_sectors = (int)(w->length >> sector_bits);
761 
762  // pad sector of timeline
763  pad = (1 << sector_bits) - (w->length % (1 << sector_bits));
764  if (pad) {
765  nb_sectors++;
766  write_pad(pb, pad);
767  }
768 
769  //write fat table
770  if (w->depth > 0) {
771  w->first_sector = write_fat_sector(s, start_pos, nb_sectors, sector_bits, w->depth) >> WTV_SECTOR_BITS;
772  } else {
773  w->first_sector = start_pos >> WTV_SECTOR_BITS;
774  }
775 
776  w->length |= 1ULL<<60;
777  if (sector_bits == WTV_SECTOR_BITS)
778  w->length |= 1ULL<<63;
779 
780  return 0;
781 }
782 
784 {
785  WtvContext *wctx = s->priv_data;
786  AVIOContext *pb = s->pb;
787  int root_size;
788  int64_t sector_pos;
789  int64_t start_pos, file_end_pos;
790 
791  if (finish_file(s, WTV_TIMELINE, wctx->timeline_start_pos) < 0)
792  return -1;
793 
794  start_pos = avio_tell(pb);
797  return -1;
798 
799  start_pos = avio_tell(pb);
801  if (finish_file(s, WTV_TABLE_0_ENTRIES_LEGACY_ATTRIB, start_pos) < 0)
802  return -1;
803 
804  start_pos = avio_tell(pb);
807  return -1;
808 
809  start_pos = avio_tell(pb);
811  if (finish_file(s, WTV_TABLE_0_ENTRIES_TIME, start_pos) < 0)
812  return -1;
813 
814  // write root table
815  sector_pos = avio_tell(pb);
816  root_size = write_root_table(s, sector_pos);
817 
818  file_end_pos = avio_tell(pb);
819  // update root value
820  avio_seek(pb, 0x30, SEEK_SET);
821  avio_wl32(pb, root_size);
822  avio_seek(pb, 4, SEEK_CUR);
823  avio_wl32(pb, sector_pos >> WTV_SECTOR_BITS);
824  avio_seek(pb, 0x5c, SEEK_SET);
825  avio_wl32(pb, file_end_pos >> WTV_SECTOR_BITS);
826 
827  av_free(wctx->sp_pairs);
828  av_free(wctx->st_pairs);
829  av_packet_unref(&wctx->thumbnail);
830  return 0;
831 }
832 
834  .p.name = "wtv",
835  .p.long_name = NULL_IF_CONFIG_SMALL("Windows Television (WTV)"),
836  .p.extensions = "wtv",
837  .priv_data_size = sizeof(WtvContext),
838  .p.audio_codec = AV_CODEC_ID_AC3,
839  .p.video_codec = AV_CODEC_ID_MPEG2VIDEO,
840  .write_header = write_header,
841  .write_packet = write_packet,
842  .write_trailer = write_trailer,
843  .p.codec_tag = ff_riff_codec_tags_list,
844 };
write_table_entries_attrib
static void write_table_entries_attrib(AVFormatContext *s)
Definition: wtvenc.c:670
write_pad
#define write_pad(pb, size)
Definition: wtvenc.c:132
av_packet_unref
void av_packet_unref(AVPacket *pkt)
Wipe the packet.
Definition: packet.c:427
AVCodecParameters::extradata
uint8_t * extradata
Extra binary data needed for initializing the decoder, codec-dependent.
Definition: codec_par.h:69
AV_CODEC_ID_AC3
@ AV_CODEC_ID_AC3
Definition: codec_id.h:443
timeline_table_0_header_events
static const uint8_t timeline_table_0_header_events[]
Definition: wtvenc.c:43
ff_mediasubtype_cpfilters_processed
const ff_asf_guid ff_mediasubtype_cpfilters_processed
Definition: wtv_common.c:68
AVOutputFormat::name
const char * name
Definition: avformat.h:510
WtvFile::depth
int depth
Definition: wtvenc.c:73
AVCodecParameters::codec_type
enum AVMediaType codec_type
General type of the encoded data.
Definition: codec_par.h:51
mpegts.h
WTVRootEntryTable::header
const uint8_t * header
Definition: wtvenc.c:127
AVCodecParameters
This struct describes the properties of an encoded stream.
Definition: codec_par.h:47
ff_mediatype_video
const ff_asf_guid ff_mediatype_video
Definition: wtv_common.c:43
ff_timestamp_guid
const ff_asf_guid ff_timestamp_guid
Definition: wtv_common.c:29
ff_put_bmp_header
void ff_put_bmp_header(AVIOContext *pb, AVCodecParameters *par, int for_asf, int ignore_extradata, int rgb_frame_is_flipped)
Definition: riffenc.c:215
WtvContext
Definition: wtvdec.c:326
WtvContext::sp_pairs
WtvSyncEntry * sp_pairs
Definition: wtvenc.c:103
write_stream_codec_info
static int write_stream_codec_info(AVFormatContext *s, AVStream *st)
Definition: wtvenc.c:260
ff_metadata_conv
void ff_metadata_conv(AVDictionary **pm, const AVMetadataConv *d_conv, const AVMetadataConv *s_conv)
Definition: metadata.c:26
w
uint8_t w
Definition: llviddspenc.c:38
AVPacket::data
uint8_t * data
Definition: packet.h:524
write_trailer
static int write_trailer(AVFormatContext *s)
Definition: wtvenc.c:783
ff_sync_guid
const ff_asf_guid ff_sync_guid
Definition: wtv_common.c:37
MAX_NB_INDEX
#define MAX_NB_INDEX
Definition: wtvenc.c:39
ff_format_waveformatex
const ff_asf_guid ff_format_waveformatex
Definition: wtv_common.c:74
AVStream::avg_frame_rate
AVRational avg_frame_rate
Average framerate.
Definition: avformat.h:832
finish_file
static int finish_file(AVFormatContext *s, enum WtvFileIndex index, int64_t start_pos)
Pad the remainder of a file Write out fat table.
Definition: wtvenc.c:726
ff_codec_wav_tags
const AVCodecTag ff_codec_wav_tags[]
Definition: riff.c:518
avio_wl64
void avio_wl64(AVIOContext *s, uint64_t val)
Definition: aviobuf.c:425
write_timestamp
static void write_timestamp(AVFormatContext *s, AVPacket *pkt)
Definition: wtvenc.c:443
finish_chunk
static void finish_chunk(AVFormatContext *s)
Definition: wtvenc.c:209
WTV_TABLE_0_HEADER_TIME
@ WTV_TABLE_0_HEADER_TIME
Definition: wtvenc.c:65
write_table0_header_events
static int write_table0_header_events(AVIOContext *pb)
Definition: wtvenc.c:500
WtvChunkEntry
Definition: wtvenc.c:77
ff_timeline_table_0_entries_Events_le16
const uint8_t ff_timeline_table_0_entries_Events_le16[62]
Definition: wtv_common.c:52
WTVRootEntryTable
Definition: wtvenc.c:126
AV_PKT_FLAG_KEY
#define AV_PKT_FLAG_KEY
The packet contains a keyframe.
Definition: packet.h:579
WTVRootEntryTable::header_size
int header_size
Definition: wtvenc.c:128
FFOutputFormat::p
AVOutputFormat p
The public AVOutputFormat.
Definition: mux.h:65
WtvContext::first_video_flag
int first_video_flag
Definition: wtvenc.c:99
ff_stream1_guid
const ff_asf_guid ff_stream1_guid
Definition: wtv_common.c:35
WTV_TABLE_0_ENTRIES_LEGACY_ATTRIB
@ WTV_TABLE_0_ENTRIES_LEGACY_ATTRIB
Definition: wtvenc.c:63
avio_wl16
void avio_wl16(AVIOContext *s, unsigned int val)
Definition: aviobuf.c:437
WtvContext::last_timestamp_pos
int64_t last_timestamp_pos
last timestamp chunk position
Definition: wtvenc.c:94
avpriv_set_pts_info
void avpriv_set_pts_info(AVStream *st, int pts_wrap_bits, unsigned int pts_num, unsigned int pts_den)
Set the time base and wrapping info for a given stream.
Definition: avformat.c:853
WtvContext::file
WtvFile file[WTV_FILES]
Definition: wtvenc.c:91
ff_index_guid
const ff_asf_guid ff_index_guid
Definition: wtv_common.c:39
write_header
static int write_header(AVFormatContext *s)
Definition: wtvenc.c:378
ff_data_guid
const ff_asf_guid ff_data_guid
Definition: wtv_common.c:31
avio_tell
static av_always_inline int64_t avio_tell(AVIOContext *s)
ftell() equivalent for AVIOContext.
Definition: avio.h:494
type
it s the only field you need to keep assuming you have a context There is some magic you don t need to care about around this just let it vf type
Definition: writing_filters.txt:86
WTVRootEntryTable::write_header
WTVHeaderWriteFunc * write_header
Definition: wtvenc.c:129
WTV_BIGSECTOR_SIZE
#define WTV_BIGSECTOR_SIZE
Definition: wtvenc.c:37
av_reduce
int av_reduce(int *dst_num, int *dst_den, int64_t num, int64_t den, int64_t max)
Reduce a fraction.
Definition: rational.c:35
ff_video_guids
const AVCodecGuid ff_video_guids[]
Definition: wtv_common.c:81
AVRational::num
int num
Numerator.
Definition: rational.h:59
WtvContext::st_pairs
WtvSyncEntry * st_pairs
Definition: wtvenc.c:101
ff_mediatype_audio
const ff_asf_guid ff_mediatype_audio
Definition: wtv_common.c:41
avassert.h
pkt
AVPacket * pkt
Definition: movenc.c:60
AV_LOG_ERROR
#define AV_LOG_ERROR
Something went wrong and cannot losslessly be recovered.
Definition: log.h:180
AVCodecTag
Definition: internal.h:42
write_table_entries_events
static void write_table_entries_events(AVFormatContext *s)
Definition: wtvenc.c:616
av_dict_get
AVDictionaryEntry * av_dict_get(const AVDictionary *m, const char *key, const AVDictionaryEntry *prev, int flags)
Get a dictionary entry with matching key.
Definition: dict.c:62
s
#define s(width, name)
Definition: cbs_vp9.c:198
WTV_TABLE_0_ENTRIES_TIME
@ WTV_TABLE_0_ENTRIES_TIME
Definition: wtvenc.c:66
WtvFile::first_sector
int first_sector
Definition: wtvenc.c:74
av_realloc_array
void * av_realloc_array(void *ptr, size_t nmemb, size_t size)
Definition: mem.c:217
write_tag
static void write_tag(AVIOContext *pb, const char *key, const char *value)
Definition: wtvenc.c:659
ff_timeline_le16
const uint8_t ff_timeline_le16[16]
Definition: wtv_common.c:50
g
const char * g
Definition: vf_curves.c:128
AVMEDIA_TYPE_AUDIO
@ AVMEDIA_TYPE_AUDIO
Definition: avutil.h:202
AVCodecParameters::width
int width
Video only.
Definition: codec_par.h:134
av_q2d
static double av_q2d(AVRational a)
Convert an AVRational to a double.
Definition: rational.h:104
write_stream_data
static int write_stream_data(AVFormatContext *s, AVStream *st)
Definition: wtvenc.c:355
WtvContext::last_chunk_pos
int64_t last_chunk_pos
last chunk position
Definition: wtvenc.c:93
av_assert0
#define av_assert0(cond)
assert() equivalent, that is always enabled.
Definition: avassert.h:40
ff_format_none
const ff_asf_guid ff_format_none
Definition: wtv_common.c:45
table_0_header_legacy_attrib
static const uint8_t table_0_header_legacy_attrib[]
Definition: wtvenc.c:45
WtvChunkEntry::serial
int64_t serial
Definition: wtvenc.c:79
write_packet
static int write_packet(AVFormatContext *s, AVPacket *pkt)
Definition: wtvenc.c:461
key
const char * key
Definition: hwcontext_opencl.c:189
AV_CODEC_ID_H264
@ AV_CODEC_ID_H264
Definition: codec_id.h:79
write_metadata_header
static void write_metadata_header(AVIOContext *pb, int type, const char *key, int value_size)
Definition: wtvenc.c:640
WtvSyncEntry
Definition: wtvenc.c:84
AVFormatContext
Format I/O context.
Definition: avformat.h:1255
internal.h
WtvFile
Definition: wtvdec.c:53
AVStream::codecpar
AVCodecParameters * codecpar
Codec parameters associated with this stream.
Definition: avformat.h:766
WTV_BIGSECTOR_BITS
#define WTV_BIGSECTOR_BITS
Definition: wtv.h:30
NULL
#define NULL
Definition: coverity.c:32
ff_asf_guid
uint8_t ff_asf_guid[16]
Definition: riff.h:96
ff_put_wav_header
int ff_put_wav_header(AVFormatContext *s, AVIOContext *pb, AVCodecParameters *par, int flags)
Write WAVEFORMAT header structure.
Definition: riffenc.c:54
WtvContext::last_serial
int64_t last_serial
Definition: wtvenc.c:107
ff_asf_metadata_conv
const AVMetadataConv ff_asf_metadata_conv[]
Definition: asf.c:28
AVRational
Rational number (pair of numerator and denominator).
Definition: rational.h:58
WTV_TABLE_0_HEADER_LEGACY_ATTRIB
@ WTV_TABLE_0_HEADER_LEGACY_ATTRIB
Definition: wtvenc.c:62
list
Filter the word “frame” indicates either a video frame or a group of audio as stored in an AVFrame structure Format for each input and each output the list of supported formats For video that means pixel format For audio that means channel sample they are references to shared objects When the negotiation mechanism computes the intersection of the formats supported at each end of a all references to both lists are replaced with a reference to the intersection And when a single format is eventually chosen for a link amongst the remaining list
Definition: filter_design.txt:25
ff_format_cpfilters_processed
const ff_asf_guid ff_format_cpfilters_processed
Definition: wtv_common.c:72
write_tag_int32
static void write_tag_int32(AVIOContext *pb, const char *key, int value)
Definition: wtvenc.c:653
AVStream::metadata
AVDictionary * metadata
Definition: avformat.h:823
FFOutputFormat
Definition: mux.h:61
avio_w8
void avio_w8(AVIOContext *s, int b)
Definition: aviobuf.c:179
attachment_value_size
static int attachment_value_size(const AVPacket *pkt, const AVDictionaryEntry *e)
Definition: wtvenc.c:665
ffio_fill
void ffio_fill(AVIOContext *s, int b, int64_t count)
Definition: aviobuf.c:187
av_packet_ref
int av_packet_ref(AVPacket *dst, const AVPacket *src)
Setup a new reference to the data described by a given packet.
Definition: packet.c:435
index
int index
Definition: gxfenc.c:90
WTV_TIMELINE_TABLE_0_ENTRIES_EVENTS
@ WTV_TIMELINE_TABLE_0_ENTRIES_EVENTS
Definition: wtvenc.c:60
WtvChunkEntry::pos
int64_t pos
Definition: wtvenc.c:78
AVCodecParameters::extradata_size
int extradata_size
Size of the extradata content in bytes.
Definition: codec_par.h:73
ff_wtv_guid
const ff_asf_guid ff_wtv_guid
Definition: wtv_common.c:27
WtvChunkEntry::guid
const ff_asf_guid * guid
Definition: wtvenc.c:80
WtvContext::first_index_pos
int64_t first_index_pos
first index_chunk position
Definition: wtvenc.c:95
WtvSyncEntry::serial
int64_t serial
Definition: wtvenc.c:85
_
#define _
Definition: wtvenc.c:42
AVIOContext
Bytestream IO Context.
Definition: avio.h:160
write_table_entries_time
static void write_table_entries_time(AVFormatContext *s)
Definition: wtvenc.c:627
AVPacket::size
int size
Definition: packet.h:525
NULL_IF_CONFIG_SMALL
#define NULL_IF_CONFIG_SMALL(x)
Return NULL if CONFIG_SMALL is true, otherwise the argument without modification.
Definition: internal.h:94
ff_standardize_creation_time
int ff_standardize_creation_time(AVFormatContext *s)
Standardize creation_time metadata in AVFormatContext to an ISO-8601 timestamp string.
Definition: mux_utils.c:155
WtvContext::last_pts
int64_t last_pts
Definition: wtvenc.c:106
shift
static int shift(int a, int b)
Definition: bonk.c:261
size
int size
Definition: twinvq_data.h:10344
WTV_FILES
@ WTV_FILES
Definition: wtvenc.c:67
ff_wtv_muxer
const FFOutputFormat ff_wtv_muxer
Definition: wtvenc.c:833
WtvContext::timeline_start_pos
int64_t timeline_start_pos
Definition: wtvenc.c:90
AV_NOPTS_VALUE
#define AV_NOPTS_VALUE
Undefined timestamp value.
Definition: avutil.h:248
write_chunk_header2
static void write_chunk_header2(AVFormatContext *s, const ff_asf_guid *guid, int stream_id)
Definition: wtvenc.c:159
WtvContext::nb_index
int nb_index
Definition: wtvenc.c:98
ff_format_mpeg2_video
const ff_asf_guid ff_format_mpeg2_video
Definition: wtv_common.c:76
AVStream::sample_aspect_ratio
AVRational sample_aspect_ratio
sample aspect ratio (0 if unknown)
Definition: avformat.h:821
avio_write
void avio_write(AVIOContext *s, const unsigned char *buf, int size)
Definition: aviobuf.c:201
WTV_TABLE_0_REDIRECTOR_LEGACY_ATTRIB
@ WTV_TABLE_0_REDIRECTOR_LEGACY_ATTRIB
Definition: wtvenc.c:64
WtvContext::serial
int64_t serial
chunk serial number
Definition: wtvenc.c:92
write_table0_header_time
static int write_table0_header_time(AVIOContext *pb)
Definition: wtvenc.c:520
avio_wl32
void avio_wl32(AVIOContext *s, unsigned int val)
Definition: aviobuf.c:357
write_fat
static void write_fat(AVIOContext *pb, int start_sector, int nb_sectors, int shift)
Definition: wtvenc.c:586
AVPacket::flags
int flags
A combination of AV_PKT_FLAG values.
Definition: packet.h:530
WtvFileIndex
WtvFileIndex
Definition: wtvenc.c:58
AV_CODEC_ID_MJPEG
@ AV_CODEC_ID_MJPEG
Definition: codec_id.h:59
write_fat_sector
static int64_t write_fat_sector(AVFormatContext *s, int64_t start_pos, int nb_sectors, int sector_bits, int depth)
Definition: wtvenc.c:596
i
#define i(width, name, range_min, range_max)
Definition: cbs_h2645.c:256
AVPacket::pts
int64_t pts
Presentation timestamp in AVStream->time_base units; the time at which the decompressed packet will b...
Definition: packet.h:517
write_table_redirector_legacy_attrib
static void write_table_redirector_legacy_attrib(AVFormatContext *s)
Definition: wtvenc.c:698
avio_internal.h
WTV_SECTOR_SIZE
#define WTV_SECTOR_SIZE
Definition: wtv.h:29
AVCodecParameters::height
int height
Definition: codec_par.h:135
put_videoinfoheader2
static void put_videoinfoheader2(AVIOContext *pb, AVStream *st)
Definition: wtvenc.c:217
value
it s the only field you need to keep assuming you have a context There is some magic you don t need to care about around this just let it vf default value
Definition: writing_filters.txt:86
len
int len
Definition: vorbis_enc_data.h:426
write_root_table
static int write_root_table(AVFormatContext *s, int64_t sector_pos)
Definition: wtvenc.c:539
write_stream_codec
static int write_stream_codec(AVFormatContext *s, AVStream *st)
Definition: wtvenc.c:318
ff_check_h264_startcode
int ff_check_h264_startcode(AVFormatContext *s, const AVStream *st, const AVPacket *pkt)
Check presence of H264 startcode.
Definition: mpegtsenc.c:1785
tag
uint32_t tag
Definition: movenc.c:1787
ret
ret
Definition: filter_design.txt:187
AVStream
Stream structure.
Definition: avformat.h:743
WTV_SECTOR_BITS
#define WTV_SECTOR_BITS
Definition: wtv.h:28
avio_seek
int64_t avio_seek(AVIOContext *s, int64_t offset, int whence)
fseek() equivalent for AVIOContext.
Definition: aviobuf.c:231
finish_chunk_noindex
static void finish_chunk_noindex(AVFormatContext *s)
Definition: wtvenc.c:169
pos
unsigned int pos
Definition: spdifenc.c:414
avformat.h
ff_table_0_entries_time_le16
const uint8_t ff_table_0_entries_time_le16[40]
Definition: wtv_common.c:56
add_serial_pair
static void add_serial_pair(WtvSyncEntry **list, int *count, int64_t serial, int64_t value)
Definition: wtvenc.c:113
WtvFile::header
const void * header
Definition: wtvenc.c:72
WTV_TIMELINE
@ WTV_TIMELINE
Definition: wtvenc.c:61
ff_SBE2_STREAM_DESC_EVENT
const ff_asf_guid ff_SBE2_STREAM_DESC_EVENT
Definition: wtv_common.c:33
AVStream::index
int index
stream index in AVFormatContext
Definition: avformat.h:749
ff_codec_bmp_tags
const AVCodecTag ff_codec_bmp_tags[]
Definition: riff.c:36
ff_format_videoinfo2
const ff_asf_guid ff_format_videoinfo2
Definition: wtv_common.c:78
ff_put_guid
void ff_put_guid(AVIOContext *s, const ff_asf_guid *g)
Definition: riffenc.c:358
AVRational::den
int den
Denominator.
Definition: rational.h:60
table_0_redirector_legacy_attrib
static const uint8_t table_0_redirector_legacy_attrib[]
Definition: wtvenc.c:47
ff_codec_get_tag
unsigned int ff_codec_get_tag(const AVCodecTag *tags, enum AVCodecID id)
Definition: utils.c:136
write_sync
static void write_sync(AVFormatContext *s)
Definition: wtvenc.c:338
metadata_header_size
static int metadata_header_size(const char *key)
Definition: wtvenc.c:648
WTVHeaderWriteFunc
int WTVHeaderWriteFunc(AVIOContext *pb)
Definition: wtvenc.c:124
legacy_attrib
static const uint8_t legacy_attrib[]
Definition: wtvenc.c:51
ff_dir_entry_guid
const ff_asf_guid ff_dir_entry_guid
Definition: wtv_common.c:25
av_mul_q
AVRational av_mul_q(AVRational b, AVRational c)
Multiply two rationals.
Definition: rational.c:80
write_chunk_header
static void write_chunk_header(AVFormatContext *s, const ff_asf_guid *guid, int length, int stream_id)
Write chunk header.
Definition: wtvenc.c:137
AVPacket::stream_index
int stream_index
Definition: packet.h:526
FF_MEDIASUBTYPE_BASE_GUID
#define FF_MEDIASUBTYPE_BASE_GUID
Definition: riff.h:115
sub_wtv_guid
static const ff_asf_guid sub_wtv_guid
Definition: wtvenc.c:55
ff_get_codec_guid
const ff_asf_guid * ff_get_codec_guid(enum AVCodecID id, const AVCodecGuid *av_guid)
Definition: riffenc.c:364
AVMEDIA_TYPE_VIDEO
@ AVMEDIA_TYPE_VIDEO
Definition: avutil.h:201
mem.h
WTV_PAD8
#define WTV_PAD8(x)
Definition: wtv.h:31
INDEX_BASE
#define INDEX_BASE
Definition: wtvenc.c:38
WtvContext::thumbnail
AVPacket thumbnail
Definition: wtvenc.c:109
av_free
#define av_free(p)
Definition: tableprint_vlc.h:33
AVDictionaryEntry
Definition: dict.h:89
AVCodecParameters::codec_id
enum AVCodecID codec_id
Specific type of the encoded data (the codec used).
Definition: codec_par.h:55
AVPacket
This structure stores compressed data.
Definition: packet.h:501
WtvContext::nb_sp_pairs
int nb_sp_pairs
Definition: wtvenc.c:104
WtvChunkEntry::stream_id
int stream_id
Definition: wtvenc.c:81
ff_codec_wav_guids
const AVCodecGuid ff_codec_wav_guids[]
Definition: riff.c:648
avio_put_str16le
int avio_put_str16le(AVIOContext *s, const char *str)
Convert an UTF-8 string to UTF-16LE and write it.
ff_table_0_entries_legacy_attrib_le16
const uint8_t ff_table_0_entries_legacy_attrib_le16[58]
Definition: wtv_common.c:54
WtvContext::nb_st_pairs
int nb_st_pairs
Definition: wtvenc.c:102
AVCodecParameters::bit_rate
int64_t bit_rate
The average bitrate of the encoded data (in bits per second).
Definition: codec_par.h:97
WTV_TIMELINE_TABLE_0_HEADER_EVENTS
@ WTV_TIMELINE_TABLE_0_HEADER_EVENTS
Definition: wtvenc.c:59
av_log
#define av_log(a,...)
Definition: tableprint_vlc.h:27
table_0_header_time
static const uint8_t table_0_header_time[]
Definition: wtvenc.c:49
h
h
Definition: vp9dsp_template.c:2038
AVDictionaryEntry::value
char * value
Definition: dict.h:91
ff_metadata_guid
const ff_asf_guid ff_metadata_guid
Definition: wtv_common.c:62
wtv.h
wtv_root_entry_table
static const WTVRootEntryTable wtv_root_entry_table[]
Definition: wtvenc.c:528
int
int
Definition: ffmpeg_filter.c:424
AV_CODEC_ID_MPEG2VIDEO
@ AV_CODEC_ID_MPEG2VIDEO
preferred ID for MPEG-1/2 video decoding
Definition: codec_id.h:54
ff_riff_codec_tags_list
const AVCodecTag *const ff_riff_codec_tags_list[]
av_dict_iterate
const AVDictionaryEntry * av_dict_iterate(const AVDictionary *m, const AVDictionaryEntry *prev)
Iterate over a dictionary.
Definition: dict.c:44
write_table0_header_legacy_attrib
static int write_table0_header_legacy_attrib(AVIOContext *pb)
Definition: wtvenc.c:508
write_index
static void write_index(AVFormatContext *s)
Definition: wtvenc.c:184
WtvSyncEntry::value
int64_t value
Definition: wtvenc.c:86
WtvContext::index
WtvChunkEntry index[MAX_NB_INDEX]
Definition: wtvenc.c:97
mux.h