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 "avformat.h"
30 #include "avio_internal.h"
31 #include "internal.h"
32 #include "mpegts.h"
33 #include "mux.h"
34 #include "wtv.h"
35 
36 #define WTV_BIGSECTOR_SIZE (1 << WTV_BIGSECTOR_BITS)
37 #define INDEX_BASE 0x2
38 #define MAX_NB_INDEX 10
39 
40 /* declare utf16le strings */
41 #define _ , 0,
42 static const uint8_t timeline_table_0_header_events[] =
43  {'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};
44 static const uint8_t table_0_header_legacy_attrib[] =
45  {'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};
46 static const uint8_t table_0_redirector_legacy_attrib[] =
47  {'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};
48 static const uint8_t table_0_header_time[] =
49  {'t'_'a'_'b'_'l'_'e'_'.'_'0'_'.'_'h'_'e'_'a'_'d'_'e'_'r'_'.'_'t'_'i'_'m'_'e', 0};
50 static const uint8_t legacy_attrib[] =
51  {'l'_'e'_'g'_'a'_'c'_'y'_'_'_'a'_'t'_'t'_'r'_'i'_'b', 0};
52 #undef _
53 
54 static const ff_asf_guid sub_wtv_guid =
55  {0x8C,0xC3,0xD2,0xC2,0x7E,0x9A,0xDA,0x11,0x8B,0xF7,0x00,0x07,0xE9,0x5E,0xAD,0x8D};
56 
67 };
68 
69 typedef struct {
70  int64_t length;
71  const void *header;
72  int depth;
74 } WtvFile;
75 
76 typedef struct {
79  const ff_asf_guid * guid;
80  int stream_id;
82 
83 typedef struct {
86 } WtvSyncEntry;
87 
88 typedef struct {
91  int64_t serial; /**< chunk serial number */
92  int64_t last_chunk_pos; /**< last chunk position */
93  int64_t last_timestamp_pos; /**< last timestamp chunk position */
94  int64_t first_index_pos; /**< first index_chunk position */
95 
97  int nb_index;
99 
100  WtvSyncEntry *st_pairs; /* (serial, timestamp) pairs */
102  WtvSyncEntry *sp_pairs; /* (serial, position) pairs */
104 
107 
109 } WtvContext;
110 
111 
112 static void add_serial_pair(WtvSyncEntry ** list, int * count, int64_t serial, int64_t value)
113 {
114  int new_count = *count + 1;
115  WtvSyncEntry *new_list = av_realloc_array(*list, new_count, sizeof(WtvSyncEntry));
116  if (!new_list)
117  return;
118  new_list[*count] = (WtvSyncEntry){serial, value};
119  *list = new_list;
120  *count = new_count;
121 }
122 
124 
125 typedef struct {
126  const uint8_t *header;
130 
131 #define write_pad(pb, size) ffio_fill(pb, 0, size)
132 
133 /**
134  * Write chunk header. If header chunk (0x80000000 set) then add to list of header chunks
135  */
136 static void write_chunk_header(AVFormatContext *s, const ff_asf_guid *guid, int length, int stream_id)
137 {
138  WtvContext *wctx = s->priv_data;
139  AVIOContext *pb = s->pb;
140 
141  wctx->last_chunk_pos = avio_tell(pb) - wctx->timeline_start_pos;
142  ff_put_guid(pb, guid);
143  avio_wl32(pb, 32 + length);
144  avio_wl32(pb, stream_id);
145  avio_wl64(pb, wctx->serial);
146 
147  if ((stream_id & 0x80000000) && guid != &ff_index_guid) {
148  WtvChunkEntry *t = wctx->index + wctx->nb_index;
150  t->pos = wctx->last_chunk_pos;
151  t->serial = wctx->serial;
152  t->guid = guid;
153  t->stream_id = stream_id & 0x3FFFFFFF;
154  wctx->nb_index++;
155  }
156 }
157 
158 static void write_chunk_header2(AVFormatContext *s, const ff_asf_guid *guid, int stream_id)
159 {
160  WtvContext *wctx = s->priv_data;
161  AVIOContext *pb = s->pb;
162 
163  int64_t last_chunk_pos = wctx->last_chunk_pos;
164  write_chunk_header(s, guid, 0, stream_id); // length updated later
165  avio_wl64(pb, last_chunk_pos);
166 }
167 
169 {
170  WtvContext *wctx = s->priv_data;
171  AVIOContext *pb = s->pb;
172 
173  // update the chunk_len field and pad.
174  int64_t chunk_len = avio_tell(pb) - (wctx->last_chunk_pos + wctx->timeline_start_pos);
175  avio_seek(pb, -(chunk_len - 16), SEEK_CUR);
176  avio_wl32(pb, chunk_len);
177  avio_seek(pb, chunk_len - (16 + 4), SEEK_CUR);
178 
179  write_pad(pb, WTV_PAD8(chunk_len) - chunk_len);
180  wctx->serial++;
181 }
182 
184 {
185  AVIOContext *pb = s->pb;
186  WtvContext *wctx = s->priv_data;
187  int i;
188 
189  write_chunk_header2(s, &ff_index_guid, 0x80000000);
190  avio_wl32(pb, 0);
191  avio_wl32(pb, 0);
192 
193  for (i = 0; i < wctx->nb_index; i++) {
194  WtvChunkEntry *t = wctx->index + i;
195  ff_put_guid(pb, t->guid);
196  avio_wl64(pb, t->pos);
197  avio_wl32(pb, t->stream_id);
198  avio_wl32(pb, 0); // checksum?
199  avio_wl64(pb, t->serial);
200  }
201  wctx->nb_index = 0; // reset index
203 
204  if (!wctx->first_index_pos)
205  wctx->first_index_pos = wctx->last_chunk_pos;
206 }
207 
209 {
210  WtvContext *wctx = s->priv_data;
212  if (wctx->nb_index == MAX_NB_INDEX)
213  write_index(s);
214 }
215 
217 {
218  AVRational dar = av_mul_q(st->sample_aspect_ratio, (AVRational){st->codecpar->width, st->codecpar->height});
219  unsigned int num, den;
220  av_reduce(&num, &den, dar.num, dar.den, 0xFFFFFFFF);
221 
222  /* VIDEOINFOHEADER2 */
223  avio_wl32(pb, 0);
224  avio_wl32(pb, 0);
225  avio_wl32(pb, st->codecpar->width);
226  avio_wl32(pb, st->codecpar->height);
227 
228  avio_wl32(pb, 0);
229  avio_wl32(pb, 0);
230  avio_wl32(pb, 0);
231  avio_wl32(pb, 0);
232 
233  avio_wl32(pb, st->codecpar->bit_rate);
234  avio_wl32(pb, 0);
235  avio_wl64(pb, st->avg_frame_rate.num && st->avg_frame_rate.den ? INT64_C(10000000) / av_q2d(st->avg_frame_rate) : 0);
236  avio_wl32(pb, 0);
237  avio_wl32(pb, 0);
238 
239  avio_wl32(pb, num);
240  avio_wl32(pb, den);
241  avio_wl32(pb, 0);
242  avio_wl32(pb, 0);
243 
244  ff_put_bmp_header(pb, st->codecpar, 0, 1, 0);
245 
247  int padding = (st->codecpar->extradata_size & 3) ? 4 - (st->codecpar->extradata_size & 3) : 0;
248  /* MPEG2VIDEOINFO */
249  avio_wl32(pb, 0);
250  avio_wl32(pb, st->codecpar->extradata_size + padding);
251  avio_wl32(pb, -1);
252  avio_wl32(pb, -1);
253  avio_wl32(pb, 0);
255  ffio_fill(pb, 0, padding);
256  }
257 }
258 
260 {
261  const ff_asf_guid *g, *media_type, *format_type;
262  const AVCodecTag *tags;
263  AVIOContext *pb = s->pb;
264  int64_t hdr_pos_start;
265  int hdr_size = 0;
266 
267  if (st->codecpar->codec_type == AVMEDIA_TYPE_VIDEO) {
269  media_type = &ff_mediatype_video;
271  tags = ff_codec_bmp_tags;
272  } else if (st->codecpar->codec_type == AVMEDIA_TYPE_AUDIO) {
274  media_type = &ff_mediatype_audio;
275  format_type = &ff_format_waveformatex;
276  tags = ff_codec_wav_tags;
277  } else {
278  av_log(s, AV_LOG_ERROR, "unknown codec_type (0x%x)\n", st->codecpar->codec_type);
279  return -1;
280  }
281 
282  ff_put_guid(pb, media_type); // mediatype
284  write_pad(pb, 12);
285  ff_put_guid(pb,&ff_format_cpfilters_processed); // format type
286  avio_wl32(pb, 0); // size
287 
288  hdr_pos_start = avio_tell(pb);
289  if (st->codecpar->codec_type == AVMEDIA_TYPE_VIDEO) {
290  put_videoinfoheader2(pb, st);
291  } else {
292  if (ff_put_wav_header(s, pb, st->codecpar, 0) < 0)
293  format_type = &ff_format_none;
294  }
295  hdr_size = avio_tell(pb) - hdr_pos_start;
296 
297  // seek back write hdr_size
298  avio_seek(pb, -(hdr_size + 4), SEEK_CUR);
299  avio_wl32(pb, hdr_size + 32);
300  avio_seek(pb, hdr_size, SEEK_CUR);
301  if (g) {
302  ff_put_guid(pb, g); // actual_subtype
303  } else {
304  int tag = ff_codec_get_tag(tags, st->codecpar->codec_id);
305  if (!tag) {
306  av_log(s, AV_LOG_ERROR, "unsupported codec_id (0x%x)\n", st->codecpar->codec_id);
307  return -1;
308  }
309  avio_wl32(pb, tag);
310  avio_write(pb, (const uint8_t[]){FF_MEDIASUBTYPE_BASE_GUID}, 12);
311  }
312  ff_put_guid(pb, format_type); // actual_formattype
313 
314  return 0;
315 }
316 
318 {
319  AVIOContext *pb = s->pb;
320  int ret;
321  write_chunk_header2(s, &ff_stream1_guid, 0x80000000 | 0x01);
322 
323  avio_wl32(pb, 0x01);
324  write_pad(pb, 4);
325  write_pad(pb, 4);
326 
328  if (ret < 0) {
329  av_log(s, AV_LOG_ERROR, "write stream codec info failed codec_type(0x%x)\n", st->codecpar->codec_type);
330  return -1;
331  }
332 
333  finish_chunk(s);
334  return 0;
335 }
336 
338 {
339  AVIOContext *pb = s->pb;
340  WtvContext *wctx = s->priv_data;
341  int64_t last_chunk_pos = wctx->last_chunk_pos;
342 
343  write_chunk_header(s, &ff_sync_guid, 0x18, 0);
344  avio_wl64(pb, wctx->first_index_pos);
345  avio_wl64(pb, wctx->last_timestamp_pos);
346  avio_wl64(pb, 0);
347 
348  finish_chunk(s);
349  add_serial_pair(&wctx->sp_pairs, &wctx->nb_sp_pairs, wctx->serial, wctx->last_chunk_pos);
350 
351  wctx->last_chunk_pos = last_chunk_pos;
352 }
353 
355 {
356  AVIOContext *pb = s->pb;
357  int ret;
358 
360  avio_wl32(pb, 0x00000001);
361  avio_wl32(pb, st->index + INDEX_BASE); //stream_id
362  avio_wl32(pb, 0x00000001);
363  write_pad(pb, 8);
364 
366  if (ret < 0) {
367  av_log(s, AV_LOG_ERROR, "write stream codec info failed codec_type(0x%x)\n", st->codecpar->codec_type);
368  return -1;
369  }
370  finish_chunk(s);
371 
372  avpriv_set_pts_info(st, 64, 1, 10000000);
373 
374  return 0;
375 }
376 
378 {
379  AVIOContext *pb = s->pb;
380  WtvContext *wctx = s->priv_data;
381  int i, pad, ret;
382  AVStream *st;
383 
384  wctx->last_chunk_pos = -1;
385  wctx->last_timestamp_pos = -1;
386 
387  ff_put_guid(pb, &ff_wtv_guid);
389 
390  avio_wl32(pb, 0x01);
391  avio_wl32(pb, 0x02);
392  avio_wl32(pb, 1 << WTV_SECTOR_BITS);
393  avio_wl32(pb, 1 << WTV_BIGSECTOR_BITS);
394 
395  //write initial root fields
396  avio_wl32(pb, 0); // root_size, update later
397  write_pad(pb, 4);
398  avio_wl32(pb, 0); // root_sector, update it later.
399 
400  write_pad(pb, 32);
401  avio_wl32(pb, 0); // file ends pointer, update it later.
402 
403  pad = (1 << WTV_SECTOR_BITS) - avio_tell(pb);
404  write_pad(pb, pad);
405 
406  wctx->timeline_start_pos = avio_tell(pb);
407 
408  wctx->serial = 1;
409  wctx->last_chunk_pos = -1;
410  wctx->first_video_flag = 1;
411 
412  for (i = 0; i < s->nb_streams; i++) {
413  st = s->streams[i];
414  if (st->codecpar->codec_id == AV_CODEC_ID_MJPEG)
415  continue;
416  ret = write_stream_codec(s, st);
417  if (ret < 0) {
418  av_log(s, AV_LOG_ERROR, "write stream codec failed codec_type(0x%x)\n", st->codecpar->codec_type);
419  return -1;
420  }
421  if (!i)
422  write_sync(s);
423  }
424 
425  for (i = 0; i < s->nb_streams; i++) {
426  st = s->streams[i];
427  if (st->codecpar->codec_id == AV_CODEC_ID_MJPEG)
428  continue;
429  ret = write_stream_data(s, st);
430  if (ret < 0) {
431  av_log(s, AV_LOG_ERROR, "write stream data failed codec_type(0x%x)\n", st->codecpar->codec_type);
432  return -1;
433  }
434  }
435 
436  if (wctx->nb_index)
437  write_index(s);
438 
439  return 0;
440 }
441 
443 {
444  AVIOContext *pb = s->pb;
445  WtvContext *wctx = s->priv_data;
446  AVCodecParameters *par = s->streams[pkt->stream_index]->codecpar;
447 
449  write_pad(pb, 8);
450  avio_wl64(pb, pkt->pts == AV_NOPTS_VALUE ? -1 : pkt->pts);
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, 0);
454  avio_wl64(pb, par->codec_type == AVMEDIA_TYPE_VIDEO && (pkt->flags & AV_PKT_FLAG_KEY) ? 1 : 0);
455  avio_wl64(pb, 0);
456 
457  wctx->last_timestamp_pos = wctx->last_chunk_pos;
458 }
459 
461 {
462  AVIOContext *pb = s->pb;
463  WtvContext *wctx = s->priv_data;
464  AVStream *st = s->streams[pkt->stream_index];
465 
466  if (st->codecpar->codec_id == AV_CODEC_ID_MJPEG && !wctx->thumbnail.size) {
467  av_packet_ref(&wctx->thumbnail, pkt);
468  return 0;
469  } else if (st->codecpar->codec_id == AV_CODEC_ID_H264) {
470  int ret = ff_check_h264_startcode(s, st, pkt);
471  if (ret < 0)
472  return ret;
473  }
474 
475  /* emit sync chunk and 'timeline.table.0.entries.Event' record every 50 frames */
476  if (wctx->serial - (wctx->nb_sp_pairs ? wctx->sp_pairs[wctx->nb_sp_pairs - 1].serial : 0) >= 50)
477  write_sync(s);
478 
479  /* emit 'table.0.entries.time' record every 500ms */
480  if (pkt->pts != AV_NOPTS_VALUE && pkt->pts - (wctx->nb_st_pairs ? wctx->st_pairs[wctx->nb_st_pairs - 1].value : 0) >= 5000000)
481  add_serial_pair(&wctx->st_pairs, &wctx->nb_st_pairs, wctx->serial, pkt->pts);
482 
483  if (pkt->pts != AV_NOPTS_VALUE && pkt->pts > wctx->last_pts) {
484  wctx->last_pts = pkt->pts;
485  wctx->last_serial = wctx->serial;
486  }
487 
488  // write timestamp chunk
490 
492  avio_write(pb, pkt->data, pkt->size);
493  write_pad(pb, WTV_PAD8(pkt->size) - pkt->size);
494 
495  wctx->serial++;
496  return 0;
497 }
498 
500 {
501  avio_wl32(pb, 0x10);
502  write_pad(pb, 84);
503  avio_wl64(pb, 0x32);
504  return 96;
505 }
506 
508 {
509  int pad = 0;
510  avio_wl32(pb, 0xFFFFFFFF);
511  write_pad(pb, 12);
512  avio_write(pb, legacy_attrib, sizeof(legacy_attrib));
513  pad = WTV_PAD8(sizeof(legacy_attrib)) - sizeof(legacy_attrib);
514  write_pad(pb, pad);
515  write_pad(pb, 32);
516  return 48 + WTV_PAD8(sizeof(legacy_attrib));
517 }
518 
520 {
521  avio_wl32(pb, 0x10);
522  write_pad(pb, 76);
523  avio_wl64(pb, 0x40);
524  return 88;
525 }
526 
536 };
537 
538 static int write_root_table(AVFormatContext *s, int64_t sector_pos)
539 {
540  AVIOContext *pb = s->pb;
541  WtvContext *wctx = s->priv_data;
542  int size, pad;
543  int i;
544 
546  for (i = 0; i < sizeof(wtv_root_entry_table)/sizeof(WTVRootEntryTable); i++, h++) {
547  WtvFile *w = &wctx->file[i];
548  int filename_padding = WTV_PAD8(h->header_size) - h->header_size;
549  WTVHeaderWriteFunc *write = h->write_header;
550  int len = 0;
551  int64_t len_pos;
552 
554  len_pos = avio_tell(pb);
555  avio_wl16(pb, 40 + h->header_size + filename_padding + 8); // maybe updated later
556  write_pad(pb, 6);
557  avio_wl64(pb, write ? 0 : w->length);// maybe update later
558  avio_wl32(pb, (h->header_size + filename_padding) >> 1);
559  write_pad(pb, 4);
560 
561  avio_write(pb, h->header, h->header_size);
562  write_pad(pb, filename_padding);
563 
564  if (write) {
565  len = write(pb);
566  // update length field
567  avio_seek(pb, len_pos, SEEK_SET);
568  avio_wl64(pb, 40 + h->header_size + filename_padding + len);
569  avio_wl64(pb, len |(1ULL<<62) | (1ULL<<60));
570  avio_seek(pb, 8 + h->header_size + filename_padding + len, SEEK_CUR);
571  } else {
572  avio_wl32(pb, w->first_sector);
573  avio_wl32(pb, w->depth);
574  }
575  }
576 
577  // caculate root table size
578  size = avio_tell(pb) - sector_pos;
579  pad = WTV_SECTOR_SIZE- size;
580  write_pad(pb, pad);
581 
582  return size;
583 }
584 
585 static void write_fat(AVIOContext *pb, int start_sector, int nb_sectors, int shift)
586 {
587  int i;
588  for (i = 0; i < nb_sectors; i++) {
589  avio_wl32(pb, start_sector + (i << shift));
590  }
591  // pad left sector pointer size
592  write_pad(pb, WTV_SECTOR_SIZE - ((nb_sectors << 2) % WTV_SECTOR_SIZE));
593 }
594 
595 static int64_t write_fat_sector(AVFormatContext *s, int64_t start_pos, int nb_sectors, int sector_bits, int depth)
596 {
597  int64_t start_sector = start_pos >> WTV_SECTOR_BITS;
598  int shift = sector_bits - WTV_SECTOR_BITS;
599 
600  int64_t fat = avio_tell(s->pb);
601  write_fat(s->pb, start_sector, nb_sectors, shift);
602 
603  if (depth == 2) {
604  int64_t start_sector1 = fat >> WTV_SECTOR_BITS;
605  int nb_sectors1 = ((nb_sectors << 2) + WTV_SECTOR_SIZE - 1) / WTV_SECTOR_SIZE;
606  int64_t fat1 = avio_tell(s->pb);
607 
608  write_fat(s->pb, start_sector1, nb_sectors1, 0);
609  return fat1;
610  }
611 
612  return fat;
613 }
614 
616 {
617  AVIOContext *pb = s->pb;
618  WtvContext *wctx = s->priv_data;
619  int i;
620  for (i = 0; i < wctx->nb_sp_pairs; i++) {
621  avio_wl64(pb, wctx->sp_pairs[i].serial);
622  avio_wl64(pb, wctx->sp_pairs[i].value);
623  }
624 }
625 
627 {
628  AVIOContext *pb = s->pb;
629  WtvContext *wctx = s->priv_data;
630  int i;
631  for (i = 0; i < wctx->nb_st_pairs; i++) {
632  avio_wl64(pb, wctx->st_pairs[i].value);
633  avio_wl64(pb, wctx->st_pairs[i].serial);
634  }
635  avio_wl64(pb, wctx->last_pts);
636  avio_wl64(pb, wctx->last_serial);
637 }
638 
639 static void write_metadata_header(AVIOContext *pb, int type, const char *key, int value_size)
640 {
642  avio_wl32(pb, type);
643  avio_wl32(pb, value_size);
644  avio_put_str16le(pb, key);
645 }
646 
647 static int metadata_header_size(const char *key)
648 {
649  return 16 + 4 + 4 + strlen(key)*2 + 2;
650 }
651 
652 static void write_tag_int32(AVIOContext *pb, const char *key, int value)
653 {
654  write_metadata_header(pb, 0, key, 4);
655  avio_wl32(pb, value);
656 }
657 
658 static void write_tag(AVIOContext *pb, const char *key, const char *value)
659 {
660  write_metadata_header(pb, 1, key, strlen(value)*2 + 2);
661  avio_put_str16le(pb, value);
662 }
663 
665 {
666  return strlen("image/jpeg")*2 + 2 + 1 + (e ? strlen(e->value)*2 : 0) + 2 + 4 + pkt->size;
667 }
668 
670 {
671  WtvContext *wctx = s->priv_data;
672  AVIOContext *pb = s->pb;
673  const AVDictionaryEntry *tag = NULL;
674 
676  //FIXME: translate special tags (e.g. WM/Bitrate) to binary representation
678  while ((tag = av_dict_iterate(s->metadata, tag)))
679  write_tag(pb, tag->key, tag->value);
680 
681  if (wctx->thumbnail.size) {
682  AVStream *st = s->streams[wctx->thumbnail.stream_index];
683  tag = av_dict_get(st->metadata, "title", NULL, 0);
684  write_metadata_header(pb, 2, "WM/Picture", attachment_value_size(&wctx->thumbnail, tag));
685 
686  avio_put_str16le(pb, "image/jpeg");
687  avio_w8(pb, 0x10);
688  avio_put_str16le(pb, tag ? tag->value : "");
689 
690  avio_wl32(pb, wctx->thumbnail.size);
691  avio_write(pb, wctx->thumbnail.data, wctx->thumbnail.size);
692 
693  write_tag_int32(pb, "WM/MediaThumbType", 2);
694  }
695 }
696 
698 {
699  WtvContext *wctx = s->priv_data;
700  AVIOContext *pb = s->pb;
701  const AVDictionaryEntry *tag = NULL;
702  int64_t pos = 0;
703 
704  //FIXME: translate special tags to binary representation
705  while ((tag = av_dict_iterate(s->metadata, tag))) {
706  avio_wl64(pb, pos);
707  pos += metadata_header_size(tag->key) + strlen(tag->value)*2 + 2;
708  }
709 
710  if (wctx->thumbnail.size) {
711  AVStream *st = s->streams[wctx->thumbnail.stream_index];
712  avio_wl64(pb, pos);
713  pos += metadata_header_size("WM/Picture") + attachment_value_size(&wctx->thumbnail, av_dict_get(st->metadata, "title", NULL, 0));
714 
715  avio_wl64(pb, pos);
716  pos += metadata_header_size("WM/MediaThumbType") + 4;
717  }
718 }
719 
720 /**
721  * Pad the remainder of a file
722  * Write out fat table
723  * @return <0 on error
724  */
725 static int finish_file(AVFormatContext *s, enum WtvFileIndex index, int64_t start_pos)
726 {
727  WtvContext *wctx = s->priv_data;
728  AVIOContext *pb = s->pb;
729  WtvFile *w = &wctx->file[index];
730  int64_t end_pos = avio_tell(pb);
731  int sector_bits, nb_sectors, pad;
732 
734 
735  w->length = (end_pos - start_pos);
736 
737  // determine optimal fat table depth, sector_bits, nb_sectors
738  if (w->length <= WTV_SECTOR_SIZE) {
739  w->depth = 0;
740  sector_bits = WTV_SECTOR_BITS;
741  } else if (w->length <= (WTV_SECTOR_SIZE / 4) * WTV_SECTOR_SIZE) {
742  w->depth = 1;
743  sector_bits = WTV_SECTOR_BITS;
744  } else if (w->length <= (WTV_SECTOR_SIZE / 4) * WTV_BIGSECTOR_SIZE) {
745  w->depth = 1;
746  sector_bits = WTV_BIGSECTOR_BITS;
747  } else if (w->length <= (int64_t)(WTV_SECTOR_SIZE / 4) * (WTV_SECTOR_SIZE / 4) * WTV_SECTOR_SIZE) {
748  w->depth = 2;
749  sector_bits = WTV_SECTOR_BITS;
750  } else if (w->length <= (int64_t)(WTV_SECTOR_SIZE / 4) * (WTV_SECTOR_SIZE / 4) * WTV_BIGSECTOR_SIZE) {
751  w->depth = 2;
752  sector_bits = WTV_BIGSECTOR_BITS;
753  } else {
754  av_log(s, AV_LOG_ERROR, "unsupported file allocation table depth (%"PRIi64" bytes)\n", w->length);
755  return -1;
756  }
757 
758  // determine the nb_sectors
759  nb_sectors = (int)(w->length >> sector_bits);
760 
761  // pad sector of timeline
762  pad = (1 << sector_bits) - (w->length % (1 << sector_bits));
763  if (pad) {
764  nb_sectors++;
765  write_pad(pb, pad);
766  }
767 
768  //write fat table
769  if (w->depth > 0) {
770  w->first_sector = write_fat_sector(s, start_pos, nb_sectors, sector_bits, w->depth) >> WTV_SECTOR_BITS;
771  } else {
772  w->first_sector = start_pos >> WTV_SECTOR_BITS;
773  }
774 
775  w->length |= 1ULL<<60;
776  if (sector_bits == WTV_SECTOR_BITS)
777  w->length |= 1ULL<<63;
778 
779  return 0;
780 }
781 
783 {
784  WtvContext *wctx = s->priv_data;
785  AVIOContext *pb = s->pb;
786  int root_size;
787  int64_t sector_pos;
788  int64_t start_pos, file_end_pos;
789 
790  if (finish_file(s, WTV_TIMELINE, wctx->timeline_start_pos) < 0)
791  return -1;
792 
793  start_pos = avio_tell(pb);
796  return -1;
797 
798  start_pos = avio_tell(pb);
800  if (finish_file(s, WTV_TABLE_0_ENTRIES_LEGACY_ATTRIB, start_pos) < 0)
801  return -1;
802 
803  start_pos = avio_tell(pb);
806  return -1;
807 
808  start_pos = avio_tell(pb);
810  if (finish_file(s, WTV_TABLE_0_ENTRIES_TIME, start_pos) < 0)
811  return -1;
812 
813  // write root table
814  sector_pos = avio_tell(pb);
815  root_size = write_root_table(s, sector_pos);
816 
817  file_end_pos = avio_tell(pb);
818  // update root value
819  avio_seek(pb, 0x30, SEEK_SET);
820  avio_wl32(pb, root_size);
821  avio_seek(pb, 4, SEEK_CUR);
822  avio_wl32(pb, sector_pos >> WTV_SECTOR_BITS);
823  avio_seek(pb, 0x5c, SEEK_SET);
824  avio_wl32(pb, file_end_pos >> WTV_SECTOR_BITS);
825 
826  av_free(wctx->sp_pairs);
827  av_free(wctx->st_pairs);
828  av_packet_unref(&wctx->thumbnail);
829  return 0;
830 }
831 
833  .p.name = "wtv",
834  .p.long_name = NULL_IF_CONFIG_SMALL("Windows Television (WTV)"),
835  .p.extensions = "wtv",
836  .priv_data_size = sizeof(WtvContext),
837  .p.audio_codec = AV_CODEC_ID_AC3,
838  .p.video_codec = AV_CODEC_ID_MPEG2VIDEO,
839  .write_header = write_header,
840  .write_packet = write_packet,
841  .write_trailer = write_trailer,
842  .p.codec_tag = ff_riff_codec_tags_list,
843 };
write_table_entries_attrib
static void write_table_entries_attrib(AVFormatContext *s)
Definition: wtvenc.c:669
write_pad
#define write_pad(pb, size)
Definition: wtvenc.c:131
av_packet_unref
void av_packet_unref(AVPacket *pkt)
Wipe the packet.
Definition: avpacket.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:42
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:72
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:126
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
int64_t
long long int64_t
Definition: coverity.c:34
WtvContext
Definition: wtvdec.c:325
WtvContext::sp_pairs
WtvSyncEntry * sp_pairs
Definition: wtvenc.c:102
write_stream_codec_info
static int write_stream_codec_info(AVFormatContext *s, AVStream *st)
Definition: wtvenc.c:259
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:522
write_trailer
static int write_trailer(AVFormatContext *s)
Definition: wtvenc.c:782
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:38
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:725
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:424
write_timestamp
static void write_timestamp(AVFormatContext *s, AVPacket *pkt)
Definition: wtvenc.c:442
finish_chunk
static void finish_chunk(AVFormatContext *s)
Definition: wtvenc.c:208
WTV_TABLE_0_HEADER_TIME
@ WTV_TABLE_0_HEADER_TIME
Definition: wtvenc.c:64
write_table0_header_events
static int write_table0_header_events(AVIOContext *pb)
Definition: wtvenc.c:499
WtvChunkEntry
Definition: wtvenc.c:76
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:125
AV_PKT_FLAG_KEY
#define AV_PKT_FLAG_KEY
The packet contains a keyframe.
Definition: packet.h:577
WTVRootEntryTable::header_size
int header_size
Definition: wtvenc.c:127
FFOutputFormat::p
AVOutputFormat p
The public AVOutputFormat.
Definition: mux.h:65
WtvContext::first_video_flag
int first_video_flag
Definition: wtvenc.c:98
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:62
avio_wl16
void avio_wl16(AVIOContext *s, unsigned int val)
Definition: aviobuf.c:436
WtvContext::last_timestamp_pos
int64_t last_timestamp_pos
last timestamp chunk position
Definition: wtvenc.c:93
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:90
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:377
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:128
WTV_BIGSECTOR_SIZE
#define WTV_BIGSECTOR_SIZE
Definition: wtvenc.c:36
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:100
ff_mediatype_audio
const ff_asf_guid ff_mediatype_audio
Definition: wtv_common.c:41
avassert.h
pkt
AVPacket * pkt
Definition: movenc.c:59
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:615
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:65
WtvFile::first_sector
int first_sector
Definition: wtvenc.c:73
av_realloc_array
void * av_realloc_array(void *ptr, size_t nmemb, size_t size)
Definition: mem.c:215
write_tag
static void write_tag(AVIOContext *pb, const char *key, const char *value)
Definition: wtvenc.c:658
ff_timeline_le16
const uint8_t ff_timeline_le16[16]
Definition: wtv_common.c:50
g
const char * g
Definition: vf_curves.c:127
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:354
WtvContext::last_chunk_pos
int64_t last_chunk_pos
last chunk position
Definition: wtvenc.c:92
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:44
WtvChunkEntry::serial
int64_t serial
Definition: wtvenc.c:78
write_packet
static int write_packet(AVFormatContext *s, AVPacket *pkt)
Definition: wtvenc.c:460
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:639
WtvSyncEntry
Definition: wtvenc.c:83
AVFormatContext
Format I/O context.
Definition: avformat.h:1255
internal.h
WtvFile
Definition: wtvdec.c:52
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:106
ff_asf_metadata_conv
const AVMetadataConv ff_asf_metadata_conv[]
Definition: asf.c:27
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:61
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:652
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:178
attachment_value_size
static int attachment_value_size(const AVPacket *pkt, const AVDictionaryEntry *e)
Definition: wtvenc.c:664
ffio_fill
void ffio_fill(AVIOContext *s, int b, int64_t count)
Definition: aviobuf.c:186
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: avpacket.c:435
index
int index
Definition: gxfenc.c:89
WTV_TIMELINE_TABLE_0_ENTRIES_EVENTS
@ WTV_TIMELINE_TABLE_0_ENTRIES_EVENTS
Definition: wtvenc.c:59
WtvChunkEntry::pos
int64_t pos
Definition: wtvenc.c:77
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:79
WtvContext::first_index_pos
int64_t first_index_pos
first index_chunk position
Definition: wtvenc.c:94
WtvSyncEntry::serial
int64_t serial
Definition: wtvenc.c:84
_
#define _
Definition: wtvenc.c:41
AVIOContext
Bytestream IO Context.
Definition: avio.h:160
write_table_entries_time
static void write_table_entries_time(AVFormatContext *s)
Definition: wtvenc.c:626
AVPacket::size
int size
Definition: packet.h:523
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:106
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:105
shift
static int shift(int a, int b)
Definition: bonk.c:262
size
int size
Definition: twinvq_data.h:10344
WTV_FILES
@ WTV_FILES
Definition: wtvenc.c:66
ff_wtv_muxer
const FFOutputFormat ff_wtv_muxer
Definition: wtvenc.c:832
WtvContext::timeline_start_pos
int64_t timeline_start_pos
Definition: wtvenc.c:89
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:158
WtvContext::nb_index
int nb_index
Definition: wtvenc.c:97
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:200
WTV_TABLE_0_REDIRECTOR_LEGACY_ATTRIB
@ WTV_TABLE_0_REDIRECTOR_LEGACY_ATTRIB
Definition: wtvenc.c:63
WtvContext::serial
int64_t serial
chunk serial number
Definition: wtvenc.c:91
write_table0_header_time
static int write_table0_header_time(AVIOContext *pb)
Definition: wtvenc.c:519
avio_wl32
void avio_wl32(AVIOContext *s, unsigned int val)
Definition: aviobuf.c:356
write_fat
static void write_fat(AVIOContext *pb, int start_sector, int nb_sectors, int shift)
Definition: wtvenc.c:585
AVPacket::flags
int flags
A combination of AV_PKT_FLAG values.
Definition: packet.h:528
WtvFileIndex
WtvFileIndex
Definition: wtvenc.c:57
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:595
i
#define i(width, name, range_min, range_max)
Definition: cbs_h2645.c:255
AVPacket::pts
int64_t pts
Presentation timestamp in AVStream->time_base units; the time at which the decompressed packet will b...
Definition: packet.h:515
write_table_redirector_legacy_attrib
static void write_table_redirector_legacy_attrib(AVFormatContext *s)
Definition: wtvenc.c:697
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:216
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:538
write_stream_codec
static int write_stream_codec(AVFormatContext *s, AVStream *st)
Definition: wtvenc.c:317
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:1784
tag
uint32_t tag
Definition: movenc.c:1791
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:230
finish_chunk_noindex
static void finish_chunk_noindex(AVFormatContext *s)
Definition: wtvenc.c:168
pos
unsigned int pos
Definition: spdifenc.c:413
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:112
WtvFile::header
const void * header
Definition: wtvenc.c:71
WTV_TIMELINE
@ WTV_TIMELINE
Definition: wtvenc.c:60
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:46
ff_codec_get_tag
unsigned int ff_codec_get_tag(const AVCodecTag *tags, enum AVCodecID id)
Definition: utils.c:135
write_sync
static void write_sync(AVFormatContext *s)
Definition: wtvenc.c:337
metadata_header_size
static int metadata_header_size(const char *key)
Definition: wtvenc.c:647
WTVHeaderWriteFunc
int WTVHeaderWriteFunc(AVIOContext *pb)
Definition: wtvenc.c:123
legacy_attrib
static const uint8_t legacy_attrib[]
Definition: wtvenc.c:50
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:136
AVPacket::stream_index
int stream_index
Definition: packet.h:524
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:54
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
WTV_PAD8
#define WTV_PAD8(x)
Definition: wtv.h:31
INDEX_BASE
#define INDEX_BASE
Definition: wtvenc.c:37
WtvContext::thumbnail
AVPacket thumbnail
Definition: wtvenc.c:108
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:499
WtvContext::nb_sp_pairs
int nb_sp_pairs
Definition: wtvenc.c:103
WtvChunkEntry::stream_id
int stream_id
Definition: wtvenc.c:80
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:101
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:58
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:48
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:527
int
int
Definition: ffmpeg_filter.c:409
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:507
write_index
static void write_index(AVFormatContext *s)
Definition: wtvenc.c:183
WtvSyncEntry::value
int64_t value
Definition: wtvenc.c:85
WtvContext::index
WtvChunkEntry index[MAX_NB_INDEX]
Definition: wtvenc.c:96
mux.h