movenc.c
Go to the documentation of this file.
1 /*
2  * MOV, 3GP, MP4 muxer
3  * Copyright (c) 2003 Thomas Raivio
4  * Copyright (c) 2004 Gildas Bazin <gbazin at videolan dot org>
5  * Copyright (c) 2009 Baptiste Coudurier <baptiste dot coudurier at gmail dot com>
6  *
7  * This file is part of FFmpeg.
8  *
9  * FFmpeg is free software; you can redistribute it and/or
10  * modify it under the terms of the GNU Lesser General Public
11  * License as published by the Free Software Foundation; either
12  * version 2.1 of the License, or (at your option) any later version.
13  *
14  * FFmpeg is distributed in the hope that it will be useful,
15  * but WITHOUT ANY WARRANTY; without even the implied warranty of
16  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
17  * Lesser General Public License for more details.
18  *
19  * You should have received a copy of the GNU Lesser General Public
20  * License along with FFmpeg; if not, write to the Free Software
21  * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
22  */
23 
24 #include "movenc.h"
25 #include "avformat.h"
26 #include "avio_internal.h"
27 #include "riff.h"
28 #include "avio.h"
29 #include "isom.h"
30 #include "avc.h"
31 #include "libavcodec/get_bits.h"
32 #include "libavcodec/put_bits.h"
33 #include "libavcodec/vc1.h"
34 #include "internal.h"
35 #include "libavutil/avstring.h"
36 #include "libavutil/intfloat.h"
37 #include "libavutil/mathematics.h"
38 #include "libavutil/opt.h"
39 #include "libavutil/dict.h"
40 #include "rtpenc.h"
41 #include "mov_chan.h"
42 
43 #undef NDEBUG
44 #include <assert.h>
45 
46 static const AVOption options[] = {
47  { "movflags", "MOV muxer flags", offsetof(MOVMuxContext, flags), AV_OPT_TYPE_FLAGS, {.i64 = 0}, INT_MIN, INT_MAX, AV_OPT_FLAG_ENCODING_PARAM, "movflags" },
48  { "rtphint", "Add RTP hint tracks", 0, AV_OPT_TYPE_CONST, {.i64 = FF_MOV_FLAG_RTP_HINT}, INT_MIN, INT_MAX, AV_OPT_FLAG_ENCODING_PARAM, "movflags" },
49  { "moov_size", "maximum moov size so it can be placed at the begin", offsetof(MOVMuxContext, reserved_moov_size), AV_OPT_TYPE_INT, {.i64 = 0}, 0, INT_MAX, AV_OPT_FLAG_ENCODING_PARAM, 0 },
50  { "empty_moov", "Make the initial moov atom empty (not supported by QuickTime)", 0, AV_OPT_TYPE_CONST, {.i64 = FF_MOV_FLAG_EMPTY_MOOV}, INT_MIN, INT_MAX, AV_OPT_FLAG_ENCODING_PARAM, "movflags" },
51  { "frag_keyframe", "Fragment at video keyframes", 0, AV_OPT_TYPE_CONST, {.i64 = FF_MOV_FLAG_FRAG_KEYFRAME}, INT_MIN, INT_MAX, AV_OPT_FLAG_ENCODING_PARAM, "movflags" },
52  { "separate_moof", "Write separate moof/mdat atoms for each track", 0, AV_OPT_TYPE_CONST, {.i64 = FF_MOV_FLAG_SEPARATE_MOOF}, INT_MIN, INT_MAX, AV_OPT_FLAG_ENCODING_PARAM, "movflags" },
53  { "frag_custom", "Flush fragments on caller requests", 0, AV_OPT_TYPE_CONST, {.i64 = FF_MOV_FLAG_FRAG_CUSTOM}, INT_MIN, INT_MAX, AV_OPT_FLAG_ENCODING_PARAM, "movflags" },
54  { "isml", "Create a live smooth streaming feed (for pushing to a publishing point)", 0, AV_OPT_TYPE_CONST, {.i64 = FF_MOV_FLAG_ISML}, INT_MIN, INT_MAX, AV_OPT_FLAG_ENCODING_PARAM, "movflags" },
55  { "faststart", "Run a second pass to put the moov at the beginning of the file", 0, AV_OPT_TYPE_CONST, {.i64 = FF_MOV_FLAG_FASTSTART}, INT_MIN, INT_MAX, AV_OPT_FLAG_ENCODING_PARAM, "movflags" },
56  FF_RTP_FLAG_OPTS(MOVMuxContext, rtp_flags),
57  { "skip_iods", "Skip writing iods atom.", offsetof(MOVMuxContext, iods_skip), AV_OPT_TYPE_INT, {.i64 = 1}, 0, 1, AV_OPT_FLAG_ENCODING_PARAM},
58  { "iods_audio_profile", "iods audio profile atom.", offsetof(MOVMuxContext, iods_audio_profile), AV_OPT_TYPE_INT, {.i64 = -1}, -1, 255, AV_OPT_FLAG_ENCODING_PARAM},
59  { "iods_video_profile", "iods video profile atom.", offsetof(MOVMuxContext, iods_video_profile), AV_OPT_TYPE_INT, {.i64 = -1}, -1, 255, AV_OPT_FLAG_ENCODING_PARAM},
60  { "frag_duration", "Maximum fragment duration", offsetof(MOVMuxContext, max_fragment_duration), AV_OPT_TYPE_INT, {.i64 = 0}, 0, INT_MAX, AV_OPT_FLAG_ENCODING_PARAM},
61  { "min_frag_duration", "Minimum fragment duration", offsetof(MOVMuxContext, min_fragment_duration), AV_OPT_TYPE_INT, {.i64 = 0}, 0, INT_MAX, AV_OPT_FLAG_ENCODING_PARAM},
62  { "frag_size", "Maximum fragment size", offsetof(MOVMuxContext, max_fragment_size), AV_OPT_TYPE_INT, {.i64 = 0}, 0, INT_MAX, AV_OPT_FLAG_ENCODING_PARAM},
63  { "ism_lookahead", "Number of lookahead entries for ISM files", offsetof(MOVMuxContext, ism_lookahead), AV_OPT_TYPE_INT, {.i64 = 0}, 0, INT_MAX, AV_OPT_FLAG_ENCODING_PARAM},
64  { "use_editlist", "use edit list", offsetof(MOVMuxContext, use_editlist), AV_OPT_TYPE_INT, {.i64 = -1}, -1, 1, AV_OPT_FLAG_ENCODING_PARAM},
65  { NULL },
66 };
67 
68 #define MOV_CLASS(flavor)\
69 static const AVClass flavor ## _muxer_class = {\
70  .class_name = #flavor " muxer",\
71  .item_name = av_default_item_name,\
72  .option = options,\
73  .version = LIBAVUTIL_VERSION_INT,\
74 };
75 
76 //FIXME support 64 bit variant with wide placeholders
77 static int64_t update_size(AVIOContext *pb, int64_t pos)
78 {
79  int64_t curpos = avio_tell(pb);
80  avio_seek(pb, pos, SEEK_SET);
81  avio_wb32(pb, curpos - pos); /* rewrite size */
82  avio_seek(pb, curpos, SEEK_SET);
83 
84  return curpos - pos;
85 }
86 
87 static int supports_edts(MOVMuxContext *mov)
88 {
89  // EDTS with fragments is tricky as we dont know the duration when its written
90  return (mov->use_editlist<0 && !(mov->flags & FF_MOV_FLAG_FRAGMENT)) || mov->use_editlist>0;
91 }
92 
93 static int is_co64_required(const MOVTrack *track)
94 {
95  int i;
96 
97  for (i = 0; i < track->entry; i++) {
98  if (!track->cluster[i].chunkNum)
99  continue;
100  if (track->cluster[i].pos + track->data_offset > UINT32_MAX)
101  return 1;
102  }
103  return 0;
104 }
105 
106 /* Chunk offset atom */
108 {
109  int i;
110  int mode64 = is_co64_required(track); // use 32 bit size variant if possible
111  int64_t pos = avio_tell(pb);
112  avio_wb32(pb, 0); /* size */
113  if (mode64)
114  ffio_wfourcc(pb, "co64");
115  else
116  ffio_wfourcc(pb, "stco");
117  avio_wb32(pb, 0); /* version & flags */
118  avio_wb32(pb, track->chunkCount); /* entry count */
119  for (i=0; i<track->entry; i++) {
120  if(!track->cluster[i].chunkNum)
121  continue;
122  if(mode64 == 1)
123  avio_wb64(pb, track->cluster[i].pos + track->data_offset);
124  else
125  avio_wb32(pb, track->cluster[i].pos + track->data_offset);
126  }
127  return update_size(pb, pos);
128 }
129 
130 /* Sample size atom */
132 {
133  int equalChunks = 1;
134  int i, j, entries = 0, tst = -1, oldtst = -1;
135 
136  int64_t pos = avio_tell(pb);
137  avio_wb32(pb, 0); /* size */
138  ffio_wfourcc(pb, "stsz");
139  avio_wb32(pb, 0); /* version & flags */
140 
141  for (i=0; i<track->entry; i++) {
142  tst = track->cluster[i].size/track->cluster[i].entries;
143  if(oldtst != -1 && tst != oldtst) {
144  equalChunks = 0;
145  }
146  oldtst = tst;
147  entries += track->cluster[i].entries;
148  }
149  if (equalChunks && track->entry) {
150  int sSize = track->entry ? track->cluster[0].size/track->cluster[0].entries : 0;
151  sSize = FFMAX(1, sSize); // adpcm mono case could make sSize == 0
152  avio_wb32(pb, sSize); // sample size
153  avio_wb32(pb, entries); // sample count
154  }
155  else {
156  avio_wb32(pb, 0); // sample size
157  avio_wb32(pb, entries); // sample count
158  for (i=0; i<track->entry; i++) {
159  for (j=0; j<track->cluster[i].entries; j++) {
160  avio_wb32(pb, track->cluster[i].size /
161  track->cluster[i].entries);
162  }
163  }
164  }
165  return update_size(pb, pos);
166 }
167 
168 /* Sample to chunk atom */
170 {
171  int index = 0, oldval = -1, i;
172  int64_t entryPos, curpos;
173 
174  int64_t pos = avio_tell(pb);
175  avio_wb32(pb, 0); /* size */
176  ffio_wfourcc(pb, "stsc");
177  avio_wb32(pb, 0); // version & flags
178  entryPos = avio_tell(pb);
179  avio_wb32(pb, track->chunkCount); // entry count
180  for (i=0; i<track->entry; i++) {
181  if (oldval != track->cluster[i].samples_in_chunk && track->cluster[i].chunkNum)
182  {
183  avio_wb32(pb, track->cluster[i].chunkNum); // first chunk
184  avio_wb32(pb, track->cluster[i].samples_in_chunk); // samples per chunk
185  avio_wb32(pb, 0x1); // sample description index
186  oldval = track->cluster[i].samples_in_chunk;
187  index++;
188  }
189  }
190  curpos = avio_tell(pb);
191  avio_seek(pb, entryPos, SEEK_SET);
192  avio_wb32(pb, index); // rewrite size
193  avio_seek(pb, curpos, SEEK_SET);
194 
195  return update_size(pb, pos);
196 }
197 
198 /* Sync sample atom */
199 static int mov_write_stss_tag(AVIOContext *pb, MOVTrack *track, uint32_t flag)
200 {
201  int64_t curpos, entryPos;
202  int i, index = 0;
203  int64_t pos = avio_tell(pb);
204  avio_wb32(pb, 0); // size
205  ffio_wfourcc(pb, flag == MOV_SYNC_SAMPLE ? "stss" : "stps");
206  avio_wb32(pb, 0); // version & flags
207  entryPos = avio_tell(pb);
208  avio_wb32(pb, track->entry); // entry count
209  for (i=0; i<track->entry; i++) {
210  if (track->cluster[i].flags & flag) {
211  avio_wb32(pb, i+1);
212  index++;
213  }
214  }
215  curpos = avio_tell(pb);
216  avio_seek(pb, entryPos, SEEK_SET);
217  avio_wb32(pb, index); // rewrite size
218  avio_seek(pb, curpos, SEEK_SET);
219  return update_size(pb, pos);
220 }
221 
223 {
224  avio_wb32(pb, 0x11); /* size */
225  if (track->mode == MODE_MOV) ffio_wfourcc(pb, "samr");
226  else ffio_wfourcc(pb, "damr");
227  ffio_wfourcc(pb, "FFMP");
228  avio_w8(pb, 0); /* decoder version */
229 
230  avio_wb16(pb, 0x81FF); /* Mode set (all modes for AMR_NB) */
231  avio_w8(pb, 0x00); /* Mode change period (no restriction) */
232  avio_w8(pb, 0x01); /* Frames per sample */
233  return 0x11;
234 }
235 
237 {
238  GetBitContext gbc;
239  PutBitContext pbc;
240  uint8_t buf[3];
241  int fscod, bsid, bsmod, acmod, lfeon, frmsizecod;
242 
243  if (track->vos_len < 7)
244  return -1;
245 
246  avio_wb32(pb, 11);
247  ffio_wfourcc(pb, "dac3");
248 
249  init_get_bits(&gbc, track->vos_data + 4, (track->vos_len - 4) * 8);
250  fscod = get_bits(&gbc, 2);
251  frmsizecod = get_bits(&gbc, 6);
252  bsid = get_bits(&gbc, 5);
253  bsmod = get_bits(&gbc, 3);
254  acmod = get_bits(&gbc, 3);
255  if (acmod == 2) {
256  skip_bits(&gbc, 2); // dsurmod
257  } else {
258  if ((acmod & 1) && acmod != 1)
259  skip_bits(&gbc, 2); // cmixlev
260  if (acmod & 4)
261  skip_bits(&gbc, 2); // surmixlev
262  }
263  lfeon = get_bits1(&gbc);
264 
265  init_put_bits(&pbc, buf, sizeof(buf));
266  put_bits(&pbc, 2, fscod);
267  put_bits(&pbc, 5, bsid);
268  put_bits(&pbc, 3, bsmod);
269  put_bits(&pbc, 3, acmod);
270  put_bits(&pbc, 1, lfeon);
271  put_bits(&pbc, 5, frmsizecod>>1); // bit_rate_code
272  put_bits(&pbc, 5, 0); // reserved
273 
274  flush_put_bits(&pbc);
275  avio_write(pb, buf, sizeof(buf));
276 
277  return 11;
278 }
279 
280 /**
281  * This function writes extradata "as is".
282  * Extradata must be formatted like a valid atom (with size and tag).
283  */
285 {
286  avio_write(pb, track->enc->extradata, track->enc->extradata_size);
287  return track->enc->extradata_size;
288 }
289 
291 {
292  avio_wb32(pb, 10);
293  ffio_wfourcc(pb, "enda");
294  avio_wb16(pb, 1); /* little endian */
295  return 10;
296 }
297 
299 {
300  avio_wb32(pb, 10);
301  ffio_wfourcc(pb, "enda");
302  avio_wb16(pb, 0); /* big endian */
303  return 10;
304 }
305 
306 static void put_descr(AVIOContext *pb, int tag, unsigned int size)
307 {
308  int i = 3;
309  avio_w8(pb, tag);
310  for(; i>0; i--)
311  avio_w8(pb, (size>>(7*i)) | 0x80);
312  avio_w8(pb, size & 0x7F);
313 }
314 
316 {
317  uint64_t size = 0;
318  int i;
319  if (!track->track_duration)
320  return 0;
321  for (i = 0; i < track->entry; i++)
322  size += track->cluster[i].size;
323  return size * 8 * track->timescale / track->track_duration;
324 }
325 
326 static int mov_write_esds_tag(AVIOContext *pb, MOVTrack *track) // Basic
327 {
328  int64_t pos = avio_tell(pb);
329  int decoder_specific_info_len = track->vos_len ? 5 + track->vos_len : 0;
330  unsigned avg_bitrate;
331 
332  avio_wb32(pb, 0); // size
333  ffio_wfourcc(pb, "esds");
334  avio_wb32(pb, 0); // Version
335 
336  // ES descriptor
337  put_descr(pb, 0x03, 3 + 5+13 + decoder_specific_info_len + 5+1);
338  avio_wb16(pb, track->track_id);
339  avio_w8(pb, 0x00); // flags (= no flags)
340 
341  // DecoderConfig descriptor
342  put_descr(pb, 0x04, 13 + decoder_specific_info_len);
343 
344  // Object type indication
345  if ((track->enc->codec_id == AV_CODEC_ID_MP2 ||
346  track->enc->codec_id == AV_CODEC_ID_MP3) &&
347  track->enc->sample_rate > 24000)
348  avio_w8(pb, 0x6B); // 11172-3
349  else
351 
352  // the following fields is made of 6 bits to identify the streamtype (4 for video, 5 for audio)
353  // plus 1 bit to indicate upstream and 1 bit set to 1 (reserved)
354  if(track->enc->codec_type == AVMEDIA_TYPE_AUDIO)
355  avio_w8(pb, 0x15); // flags (= Audiostream)
356  else
357  avio_w8(pb, 0x11); // flags (= Visualstream)
358 
359  avio_wb24(pb, track->enc->rc_buffer_size >> 3); // Buffersize DB
360 
361  avg_bitrate = compute_avg_bitrate(track);
362  // maxbitrate (FIXME should be max rate in any 1 sec window)
363  avio_wb32(pb, FFMAX3(track->enc->bit_rate, track->enc->rc_max_rate, avg_bitrate));
364  avio_wb32(pb, avg_bitrate);
365 
366  if (track->vos_len) {
367  // DecoderSpecific info descriptor
368  put_descr(pb, 0x05, track->vos_len);
369  avio_write(pb, track->vos_data, track->vos_len);
370  }
371 
372  // SL descriptor
373  put_descr(pb, 0x06, 1);
374  avio_w8(pb, 0x02);
375  return update_size(pb, pos);
376 }
377 
379 {
380  return codec_id == AV_CODEC_ID_PCM_S24LE ||
381  codec_id == AV_CODEC_ID_PCM_S32LE ||
382  codec_id == AV_CODEC_ID_PCM_F32LE ||
383  codec_id == AV_CODEC_ID_PCM_F64LE;
384 }
385 
387 {
388  return codec_id == AV_CODEC_ID_PCM_S24BE ||
389  codec_id == AV_CODEC_ID_PCM_S32BE ||
390  codec_id == AV_CODEC_ID_PCM_F32BE ||
391  codec_id == AV_CODEC_ID_PCM_F64BE;
392 }
393 
395 {
396  int64_t pos = avio_tell(pb);
397  avio_wb32(pb, 0);
398  avio_wl32(pb, track->tag); // store it byteswapped
399  track->enc->codec_tag = av_bswap16(track->tag >> 16);
400  ff_put_wav_header(pb, track->enc);
401  return update_size(pb, pos);
402 }
403 
405 {
406  int64_t pos = avio_tell(pb);
407  avio_wb32(pb, 0);
408  ffio_wfourcc(pb, "wfex");
409  ff_put_wav_header(pb, track->enc);
410  return update_size(pb, pos);
411 }
412 
414 {
415  uint32_t layout_tag, bitmap;
416  int64_t pos = avio_tell(pb);
417 
418  layout_tag = ff_mov_get_channel_layout_tag(track->enc->codec_id,
419  track->enc->channel_layout,
420  &bitmap);
421  if (!layout_tag) {
422  av_log(track->enc, AV_LOG_WARNING, "not writing 'chan' tag due to "
423  "lack of channel information\n");
424  return 0;
425  }
426 
427  avio_wb32(pb, 0); // Size
428  ffio_wfourcc(pb, "chan"); // Type
429  avio_w8(pb, 0); // Version
430  avio_wb24(pb, 0); // Flags
431  avio_wb32(pb, layout_tag); // mChannelLayoutTag
432  avio_wb32(pb, bitmap); // mChannelBitmap
433  avio_wb32(pb, 0); // mNumberChannelDescriptions
434 
435  return update_size(pb, pos);
436 }
437 
439 {
440  int64_t pos = avio_tell(pb);
441 
442  avio_wb32(pb, 0); /* size */
443  ffio_wfourcc(pb, "wave");
444 
445  if (track->enc->codec_id != AV_CODEC_ID_QDM2) {
446  avio_wb32(pb, 12); /* size */
447  ffio_wfourcc(pb, "frma");
448  avio_wl32(pb, track->tag);
449  }
450 
451  if (track->enc->codec_id == AV_CODEC_ID_AAC) {
452  /* useless atom needed by mplayer, ipod, not needed by quicktime */
453  avio_wb32(pb, 12); /* size */
454  ffio_wfourcc(pb, "mp4a");
455  avio_wb32(pb, 0);
456  mov_write_esds_tag(pb, track);
457  } else if (mov_pcm_le_gt16(track->enc->codec_id)) {
458  mov_write_enda_tag(pb);
459  } else if (mov_pcm_be_gt16(track->enc->codec_id)) {
461  } else if (track->enc->codec_id == AV_CODEC_ID_AMR_NB) {
462  mov_write_amr_tag(pb, track);
463  } else if (track->enc->codec_id == AV_CODEC_ID_AC3) {
464  mov_write_ac3_tag(pb, track);
465  } else if (track->enc->codec_id == AV_CODEC_ID_ALAC ||
466  track->enc->codec_id == AV_CODEC_ID_QDM2) {
467  mov_write_extradata_tag(pb, track);
468  } else if (track->enc->codec_id == AV_CODEC_ID_ADPCM_MS ||
470  mov_write_ms_tag(pb, track);
471  }
472 
473  avio_wb32(pb, 8); /* size */
474  avio_wb32(pb, 0); /* null tag */
475 
476  return update_size(pb, pos);
477 }
478 
480 {
481  uint8_t *unescaped;
482  const uint8_t *start, *next, *end = track->vos_data + track->vos_len;
483  int unescaped_size, seq_found = 0;
484  int level = 0, interlace = 0;
485  int packet_seq = track->vc1_info.packet_seq;
486  int packet_entry = track->vc1_info.packet_entry;
487  int slices = track->vc1_info.slices;
488  PutBitContext pbc;
489 
490  if (track->start_dts == AV_NOPTS_VALUE) {
491  /* No packets written yet, vc1_info isn't authoritative yet. */
492  /* Assume inline sequence and entry headers. This will be
493  * overwritten at the end if the file is seekable. */
494  packet_seq = packet_entry = 1;
495  }
496 
497  unescaped = av_mallocz(track->vos_len + FF_INPUT_BUFFER_PADDING_SIZE);
498  if (!unescaped)
499  return AVERROR(ENOMEM);
500  start = find_next_marker(track->vos_data, end);
501  for (next = start; next < end; start = next) {
502  GetBitContext gb;
503  int size;
504  next = find_next_marker(start + 4, end);
505  size = next - start - 4;
506  if (size <= 0)
507  continue;
508  unescaped_size = vc1_unescape_buffer(start + 4, size, unescaped);
509  init_get_bits(&gb, unescaped, 8 * unescaped_size);
510  if (AV_RB32(start) == VC1_CODE_SEQHDR) {
511  int profile = get_bits(&gb, 2);
512  if (profile != PROFILE_ADVANCED) {
513  av_free(unescaped);
514  return AVERROR(ENOSYS);
515  }
516  seq_found = 1;
517  level = get_bits(&gb, 3);
518  /* chromaformat, frmrtq_postproc, bitrtq_postproc, postprocflag,
519  * width, height */
520  skip_bits_long(&gb, 2 + 3 + 5 + 1 + 2*12);
521  skip_bits(&gb, 1); /* broadcast */
522  interlace = get_bits1(&gb);
523  skip_bits(&gb, 4); /* tfcntrflag, finterpflag, reserved, psf */
524  }
525  }
526  if (!seq_found) {
527  av_free(unescaped);
528  return AVERROR(ENOSYS);
529  }
530 
531  init_put_bits(&pbc, buf, 7);
532  /* VC1DecSpecStruc */
533  put_bits(&pbc, 4, 12); /* profile - advanced */
534  put_bits(&pbc, 3, level);
535  put_bits(&pbc, 1, 0); /* reserved */
536  /* VC1AdvDecSpecStruc */
537  put_bits(&pbc, 3, level);
538  put_bits(&pbc, 1, 0); /* cbr */
539  put_bits(&pbc, 6, 0); /* reserved */
540  put_bits(&pbc, 1, !interlace); /* no interlace */
541  put_bits(&pbc, 1, !packet_seq); /* no multiple seq */
542  put_bits(&pbc, 1, !packet_entry); /* no multiple entry */
543  put_bits(&pbc, 1, !slices); /* no slice code */
544  put_bits(&pbc, 1, 0); /* no bframe */
545  put_bits(&pbc, 1, 0); /* reserved */
546  put_bits32(&pbc, track->enc->time_base.den); /* framerate */
547  flush_put_bits(&pbc);
548 
549  av_free(unescaped);
550 
551  return 0;
552 }
553 
555 {
556  uint8_t buf[7] = { 0 };
557  int ret;
558 
559  if ((ret = mov_write_dvc1_structs(track, buf)) < 0)
560  return ret;
561 
562  avio_wb32(pb, track->vos_len + 8 + sizeof(buf));
563  ffio_wfourcc(pb, "dvc1");
564  track->vc1_info.struct_offset = avio_tell(pb);
565  avio_write(pb, buf, sizeof(buf));
566  avio_write(pb, track->vos_data, track->vos_len);
567 
568  return 0;
569 }
570 
572 {
573  avio_wb32(pb, track->vos_len + 8);
574  ffio_wfourcc(pb, "glbl");
575  avio_write(pb, track->vos_data, track->vos_len);
576  return 8 + track->vos_len;
577 }
578 
579 /**
580  * Compute flags for 'lpcm' tag.
581  * See CoreAudioTypes and AudioStreamBasicDescription at Apple.
582  */
584 {
585  switch (codec_id) {
588  return 11;
591  return 9;
592  case AV_CODEC_ID_PCM_U8:
593  return 10;
597  return 14;
598  case AV_CODEC_ID_PCM_S8:
602  return 12;
603  default:
604  return 0;
605  }
606 }
607 
608 static int get_cluster_duration(MOVTrack *track, int cluster_idx)
609 {
610  int64_t next_dts;
611 
612  if (cluster_idx >= track->entry)
613  return 0;
614 
615  if (cluster_idx + 1 == track->entry)
616  next_dts = track->track_duration + track->start_dts;
617  else
618  next_dts = track->cluster[cluster_idx + 1].dts;
619 
620  return next_dts - track->cluster[cluster_idx].dts;
621 }
622 
624 {
625  int i, first_duration;
626 
627 // return track->enc->frame_size;
628 
629  /* use 1 for raw PCM */
630  if (!track->audio_vbr)
631  return 1;
632 
633  /* check to see if duration is constant for all clusters */
634  if (!track->entry)
635  return 0;
636  first_duration = get_cluster_duration(track, 0);
637  for (i = 1; i < track->entry; i++) {
638  if (get_cluster_duration(track, i) != first_duration)
639  return 0;
640  }
641  return first_duration;
642 }
643 
645 {
646  int64_t pos = avio_tell(pb);
647  int version = 0;
648  uint32_t tag = track->tag;
649 
650  if (track->mode == MODE_MOV) {
651  if (track->timescale > UINT16_MAX) {
652  if (mov_get_lpcm_flags(track->enc->codec_id))
653  tag = AV_RL32("lpcm");
654  version = 2;
655  } else if (track->audio_vbr || mov_pcm_le_gt16(track->enc->codec_id) ||
656  mov_pcm_be_gt16(track->enc->codec_id) ||
657  track->enc->codec_id == AV_CODEC_ID_ADPCM_MS ||
659  track->enc->codec_id == AV_CODEC_ID_QDM2) {
660  version = 1;
661  }
662  }
663 
664  avio_wb32(pb, 0); /* size */
665  avio_wl32(pb, tag); // store it byteswapped
666  avio_wb32(pb, 0); /* Reserved */
667  avio_wb16(pb, 0); /* Reserved */
668  avio_wb16(pb, 1); /* Data-reference index, XXX == 1 */
669 
670  /* SoundDescription */
671  avio_wb16(pb, version); /* Version */
672  avio_wb16(pb, 0); /* Revision level */
673  avio_wb32(pb, 0); /* Reserved */
674 
675  if (version == 2) {
676  avio_wb16(pb, 3);
677  avio_wb16(pb, 16);
678  avio_wb16(pb, 0xfffe);
679  avio_wb16(pb, 0);
680  avio_wb32(pb, 0x00010000);
681  avio_wb32(pb, 72);
682  avio_wb64(pb, av_double2int(track->enc->sample_rate));
683  avio_wb32(pb, track->enc->channels);
684  avio_wb32(pb, 0x7F000000);
687  avio_wb32(pb, track->sample_size);
688  avio_wb32(pb, get_samples_per_packet(track));
689  } else {
690  if (track->mode == MODE_MOV) {
691  avio_wb16(pb, track->enc->channels);
692  if (track->enc->codec_id == AV_CODEC_ID_PCM_U8 ||
693  track->enc->codec_id == AV_CODEC_ID_PCM_S8)
694  avio_wb16(pb, 8); /* bits per sample */
695  else
696  avio_wb16(pb, 16);
697  avio_wb16(pb, track->audio_vbr ? -2 : 0); /* compression ID */
698  } else { /* reserved for mp4/3gp */
699  avio_wb16(pb, 2);
700  avio_wb16(pb, 16);
701  avio_wb16(pb, 0);
702  }
703 
704  avio_wb16(pb, 0); /* packet size (= 0) */
705  avio_wb16(pb, track->enc->sample_rate <= UINT16_MAX ?
706  track->enc->sample_rate : 0);
707  avio_wb16(pb, 0); /* Reserved */
708  }
709 
710  if(version == 1) { /* SoundDescription V1 extended info */
711  if (mov_pcm_le_gt16(track->enc->codec_id) ||
712  mov_pcm_be_gt16(track->enc->codec_id))
713  avio_wb32(pb, 1); /* must be 1 for uncompressed formats */
714  else
715  avio_wb32(pb, track->enc->frame_size); /* Samples per packet */
716  avio_wb32(pb, track->sample_size / track->enc->channels); /* Bytes per packet */
717  avio_wb32(pb, track->sample_size); /* Bytes per frame */
718  avio_wb32(pb, 2); /* Bytes per sample */
719  }
720 
721  if(track->mode == MODE_MOV &&
722  (track->enc->codec_id == AV_CODEC_ID_AAC ||
723  track->enc->codec_id == AV_CODEC_ID_AC3 ||
724  track->enc->codec_id == AV_CODEC_ID_AMR_NB ||
725  track->enc->codec_id == AV_CODEC_ID_ALAC ||
726  track->enc->codec_id == AV_CODEC_ID_ADPCM_MS ||
728  track->enc->codec_id == AV_CODEC_ID_QDM2 ||
729  (mov_pcm_le_gt16(track->enc->codec_id) && version==1) ||
730  (mov_pcm_be_gt16(track->enc->codec_id) && version==1)))
731  mov_write_wave_tag(pb, track);
732  else if(track->tag == MKTAG('m','p','4','a'))
733  mov_write_esds_tag(pb, track);
734  else if(track->enc->codec_id == AV_CODEC_ID_AMR_NB)
735  mov_write_amr_tag(pb, track);
736  else if(track->enc->codec_id == AV_CODEC_ID_AC3)
737  mov_write_ac3_tag(pb, track);
738  else if(track->enc->codec_id == AV_CODEC_ID_ALAC)
739  mov_write_extradata_tag(pb, track);
740  else if (track->enc->codec_id == AV_CODEC_ID_WMAPRO)
741  mov_write_wfex_tag(pb, track);
742  else if (track->vos_len > 0)
743  mov_write_glbl_tag(pb, track);
744 
745  if (track->mode == MODE_MOV && track->enc->codec_type == AVMEDIA_TYPE_AUDIO)
746  mov_write_chan_tag(pb, track);
747 
748  return update_size(pb, pos);
749 }
750 
752 {
753  avio_wb32(pb, 0xf); /* size */
754  ffio_wfourcc(pb, "d263");
755  ffio_wfourcc(pb, "FFMP");
756  avio_w8(pb, 0); /* decoder version */
757  /* FIXME use AVCodecContext level/profile, when encoder will set values */
758  avio_w8(pb, 0xa); /* level */
759  avio_w8(pb, 0); /* profile */
760  return 0xf;
761 }
762 
764 {
765  int64_t pos = avio_tell(pb);
766 
767  avio_wb32(pb, 0);
768  ffio_wfourcc(pb, "avcC");
769  ff_isom_write_avcc(pb, track->vos_data, track->vos_len);
770  return update_size(pb, pos);
771 }
772 
773 /* also used by all avid codecs (dv, imx, meridien) and their variants */
775 {
776  int i;
777  avio_wb32(pb, 24); /* size */
778  ffio_wfourcc(pb, "ACLR");
779  ffio_wfourcc(pb, "ACLR");
780  ffio_wfourcc(pb, "0001");
781  avio_wb32(pb, 2); /* yuv range: full 1 / normal 2 */
782  avio_wb32(pb, 0); /* unknown */
783 
784  avio_wb32(pb, 24); /* size */
785  ffio_wfourcc(pb, "APRG");
786  ffio_wfourcc(pb, "APRG");
787  ffio_wfourcc(pb, "0001");
788  avio_wb32(pb, 1); /* unknown */
789  avio_wb32(pb, 0); /* unknown */
790 
791  avio_wb32(pb, 120); /* size */
792  ffio_wfourcc(pb, "ARES");
793  ffio_wfourcc(pb, "ARES");
794  ffio_wfourcc(pb, "0001");
795  avio_wb32(pb, AV_RB32(track->vos_data + 0x28)); /* dnxhd cid, some id ? */
796  avio_wb32(pb, track->enc->width);
797  /* values below are based on samples created with quicktime and avid codecs */
798  if (track->vos_data[5] & 2) { // interlaced
799  avio_wb32(pb, track->enc->height/2);
800  avio_wb32(pb, 2); /* unknown */
801  avio_wb32(pb, 0); /* unknown */
802  avio_wb32(pb, 4); /* unknown */
803  } else {
804  avio_wb32(pb, track->enc->height);
805  avio_wb32(pb, 1); /* unknown */
806  avio_wb32(pb, 0); /* unknown */
807  if (track->enc->height == 1080)
808  avio_wb32(pb, 5); /* unknown */
809  else
810  avio_wb32(pb, 6); /* unknown */
811  }
812  /* padding */
813  for (i = 0; i < 10; i++)
814  avio_wb64(pb, 0);
815 
816  /* extra padding for stsd needed */
817  avio_wb32(pb, 0);
818  return 0;
819 }
820 
822 {
823  int tag = track->enc->codec_tag;
824 
826  return 0;
827 
828  if (track->enc->codec_id == AV_CODEC_ID_H264) tag = MKTAG('a','v','c','1');
829  else if (track->enc->codec_id == AV_CODEC_ID_AC3) tag = MKTAG('a','c','-','3');
830  else if (track->enc->codec_id == AV_CODEC_ID_DIRAC) tag = MKTAG('d','r','a','c');
831  else if (track->enc->codec_id == AV_CODEC_ID_MOV_TEXT) tag = MKTAG('t','x','3','g');
832  else if (track->enc->codec_id == AV_CODEC_ID_VC1) tag = MKTAG('v','c','-','1');
833  else if (track->enc->codec_type == AVMEDIA_TYPE_VIDEO) tag = MKTAG('m','p','4','v');
834  else if (track->enc->codec_type == AVMEDIA_TYPE_AUDIO) tag = MKTAG('m','p','4','a');
835 
836  return tag;
837 }
838 
839 static const AVCodecTag codec_ipod_tags[] = {
840  { AV_CODEC_ID_H264, MKTAG('a','v','c','1') },
841  { AV_CODEC_ID_MPEG4, MKTAG('m','p','4','v') },
842  { AV_CODEC_ID_AAC, MKTAG('m','p','4','a') },
843  { AV_CODEC_ID_ALAC, MKTAG('a','l','a','c') },
844  { AV_CODEC_ID_AC3, MKTAG('a','c','-','3') },
845  { AV_CODEC_ID_MOV_TEXT, MKTAG('t','x','3','g') },
846  { AV_CODEC_ID_MOV_TEXT, MKTAG('t','e','x','t') },
847  { AV_CODEC_ID_NONE, 0 },
848 };
849 
851 {
852  int tag = track->enc->codec_tag;
853 
854  // keep original tag for subs, ipod supports both formats
855  if (!(track->enc->codec_type == AVMEDIA_TYPE_SUBTITLE &&
856  (tag == MKTAG('t','x','3','g') ||
857  tag == MKTAG('t','e','x','t'))))
858  tag = ff_codec_get_tag(codec_ipod_tags, track->enc->codec_id);
859 
860  if (!av_match_ext(s->filename, "m4a") && !av_match_ext(s->filename, "m4v"))
861  av_log(s, AV_LOG_WARNING, "Warning, extension is not .m4a nor .m4v "
862  "Quicktime/Ipod might not play the file\n");
863 
864  return tag;
865 }
866 
868 {
869  int tag;
870 
871  if (track->enc->width == 720) { /* SD */
872  if (track->enc->height == 480) { /* NTSC */
873  if (track->enc->pix_fmt == AV_PIX_FMT_YUV422P) tag = MKTAG('d','v','5','n');
874  else tag = MKTAG('d','v','c',' ');
875  }else if (track->enc->pix_fmt == AV_PIX_FMT_YUV422P) tag = MKTAG('d','v','5','p');
876  else if (track->enc->pix_fmt == AV_PIX_FMT_YUV420P) tag = MKTAG('d','v','c','p');
877  else tag = MKTAG('d','v','p','p');
878  } else if (track->enc->height == 720) { /* HD 720 line */
879  if (track->enc->time_base.den == 50) tag = MKTAG('d','v','h','q');
880  else tag = MKTAG('d','v','h','p');
881  } else if (track->enc->height == 1080) { /* HD 1080 line */
882  if (track->enc->time_base.den == 25) tag = MKTAG('d','v','h','5');
883  else tag = MKTAG('d','v','h','6');
884  } else {
885  av_log(s, AV_LOG_ERROR, "unsupported height for dv codec\n");
886  return 0;
887  }
888 
889  return tag;
890 }
891 
892 static const struct {
894  uint32_t tag;
895  unsigned bps;
896 } mov_pix_fmt_tags[] = {
897  { AV_PIX_FMT_YUYV422, MKTAG('y','u','v','2'), 0 },
898  { AV_PIX_FMT_YUYV422, MKTAG('y','u','v','s'), 0 },
899  { AV_PIX_FMT_UYVY422, MKTAG('2','v','u','y'), 0 },
900  { AV_PIX_FMT_RGB555BE,MKTAG('r','a','w',' '), 16 },
901  { AV_PIX_FMT_RGB555LE,MKTAG('L','5','5','5'), 16 },
902  { AV_PIX_FMT_RGB565LE,MKTAG('L','5','6','5'), 16 },
903  { AV_PIX_FMT_RGB565BE,MKTAG('B','5','6','5'), 16 },
904  { AV_PIX_FMT_GRAY16BE,MKTAG('b','1','6','g'), 16 },
905  { AV_PIX_FMT_RGB24, MKTAG('r','a','w',' '), 24 },
906  { AV_PIX_FMT_BGR24, MKTAG('2','4','B','G'), 24 },
907  { AV_PIX_FMT_ARGB, MKTAG('r','a','w',' '), 32 },
908  { AV_PIX_FMT_BGRA, MKTAG('B','G','R','A'), 32 },
909  { AV_PIX_FMT_RGBA, MKTAG('R','G','B','A'), 32 },
910  { AV_PIX_FMT_ABGR, MKTAG('A','B','G','R'), 32 },
911  { AV_PIX_FMT_RGB48BE, MKTAG('b','4','8','r'), 48 },
912 };
913 
915 {
916  int tag = track->enc->codec_tag;
917  int i;
918 
919  for (i = 0; i < FF_ARRAY_ELEMS(mov_pix_fmt_tags); i++) {
920  if (track->enc->pix_fmt == mov_pix_fmt_tags[i].pix_fmt) {
921  tag = mov_pix_fmt_tags[i].tag;
923  if (track->enc->codec_tag == mov_pix_fmt_tags[i].tag)
924  break;
925  }
926  }
927 
928  return tag;
929 }
930 
932 {
933  int tag = track->enc->codec_tag;
934 
935  if (!tag || (track->enc->strict_std_compliance >= FF_COMPLIANCE_NORMAL &&
936  (track->enc->codec_id == AV_CODEC_ID_DVVIDEO ||
937  track->enc->codec_id == AV_CODEC_ID_RAWVIDEO ||
938  track->enc->codec_id == AV_CODEC_ID_H263 ||
939  av_get_bits_per_sample(track->enc->codec_id)))) { // pcm audio
940  if (track->enc->codec_id == AV_CODEC_ID_DVVIDEO)
941  tag = mov_get_dv_codec_tag(s, track);
942  else if (track->enc->codec_id == AV_CODEC_ID_RAWVIDEO)
943  tag = mov_get_rawvideo_codec_tag(s, track);
944  else if (track->enc->codec_type == AVMEDIA_TYPE_VIDEO) {
946  if (!tag) { // if no mac fcc found, try with Microsoft tags
948  if (tag)
949  av_log(s, AV_LOG_WARNING, "Using MS style video codec tag, "
950  "the file may be unplayable!\n");
951  }
952  } else if (track->enc->codec_type == AVMEDIA_TYPE_AUDIO) {
954  if (!tag) { // if no mac fcc found, try with Microsoft tags
955  int ms_tag = ff_codec_get_tag(ff_codec_wav_tags, track->enc->codec_id);
956  if (ms_tag) {
957  tag = MKTAG('m', 's', ((ms_tag >> 8) & 0xff), (ms_tag & 0xff));
958  av_log(s, AV_LOG_WARNING, "Using MS style audio codec tag, "
959  "the file may be unplayable!\n");
960  }
961  }
962  } else if (track->enc->codec_type == AVMEDIA_TYPE_SUBTITLE)
964  }
965 
966  return tag;
967 }
968 
969 static const AVCodecTag codec_3gp_tags[] = {
970  { AV_CODEC_ID_H263, MKTAG('s','2','6','3') },
971  { AV_CODEC_ID_H264, MKTAG('a','v','c','1') },
972  { AV_CODEC_ID_MPEG4, MKTAG('m','p','4','v') },
973  { AV_CODEC_ID_AAC, MKTAG('m','p','4','a') },
974  { AV_CODEC_ID_AMR_NB, MKTAG('s','a','m','r') },
975  { AV_CODEC_ID_AMR_WB, MKTAG('s','a','w','b') },
976  { AV_CODEC_ID_MOV_TEXT, MKTAG('t','x','3','g') },
977  { AV_CODEC_ID_NONE, 0 },
978 };
979 
980 static const AVCodecTag codec_f4v_tags[] = { // XXX: add GIF/PNG/JPEG?
981  { AV_CODEC_ID_MP3, MKTAG('.','m','p','3') },
982  { AV_CODEC_ID_AAC, MKTAG('m','p','4','a') },
983  { AV_CODEC_ID_H264, MKTAG('a','v','c','1') },
984  { AV_CODEC_ID_VP6F, MKTAG('V','P','6','F') },
985  { AV_CODEC_ID_NONE, 0 },
986 };
987 
989 {
990  int tag;
991 
992  if (track->mode == MODE_MP4 || track->mode == MODE_PSP)
993  tag = mp4_get_codec_tag(s, track);
994  else if (track->mode == MODE_ISM) {
995  tag = mp4_get_codec_tag(s, track);
996  if (!tag && track->enc->codec_id == AV_CODEC_ID_WMAPRO)
997  tag = MKTAG('w', 'm', 'a', ' ');
998  } else if (track->mode == MODE_IPOD)
999  tag = ipod_get_codec_tag(s, track);
1000  else if (track->mode & MODE_3GP)
1001  tag = ff_codec_get_tag(codec_3gp_tags, track->enc->codec_id);
1002  else if (track->mode & MODE_F4V)
1003  tag = ff_codec_get_tag(codec_f4v_tags, track->enc->codec_id);
1004  else
1005  tag = mov_get_codec_tag(s, track);
1006 
1007  return tag;
1008 }
1009 
1010 /** Write uuid atom.
1011  * Needed to make file play in iPods running newest firmware
1012  * goes after avcC atom in moov.trak.mdia.minf.stbl.stsd.avc1
1013  */
1015 {
1016  avio_wb32(pb, 28);
1017  ffio_wfourcc(pb, "uuid");
1018  avio_wb32(pb, 0x6b6840f2);
1019  avio_wb32(pb, 0x5f244fc5);
1020  avio_wb32(pb, 0xba39a51b);
1021  avio_wb32(pb, 0xcf0323f3);
1022  avio_wb32(pb, 0x0);
1023  return 28;
1024 }
1025 
1026 static const uint16_t fiel_data[] = {
1027  0x0000, 0x0100, 0x0201, 0x0206, 0x0209, 0x020e
1028 };
1029 
1031 {
1032  unsigned mov_field_order = 0;
1033  if (track->enc->field_order < FF_ARRAY_ELEMS(fiel_data))
1034  mov_field_order = fiel_data[track->enc->field_order];
1035  else
1036  return 0;
1037  avio_wb32(pb, 10);
1038  ffio_wfourcc(pb, "fiel");
1039  avio_wb16(pb, mov_field_order);
1040  return 10;
1041 }
1042 
1044 {
1045  int64_t pos = avio_tell(pb);
1046  avio_wb32(pb, 0); /* size */
1047  avio_wl32(pb, track->tag); // store it byteswapped
1048  avio_wb32(pb, 0); /* Reserved */
1049  avio_wb16(pb, 0); /* Reserved */
1050  avio_wb16(pb, 1); /* Data-reference index */
1051 
1052  if (track->enc->extradata_size)
1053  avio_write(pb, track->enc->extradata, track->enc->extradata_size);
1054 
1055  return update_size(pb, pos);
1056 }
1057 
1059 {
1060  AVRational sar;
1061  av_reduce(&sar.num, &sar.den, track->enc->sample_aspect_ratio.num,
1062  track->enc->sample_aspect_ratio.den, INT_MAX);
1063 
1064  avio_wb32(pb, 16);
1065  ffio_wfourcc(pb, "pasp");
1066  avio_wb32(pb, sar.num);
1067  avio_wb32(pb, sar.den);
1068  return 16;
1069 }
1070 
1072 {
1073  int64_t pos = avio_tell(pb);
1074  char compressor_name[32] = { 0 };
1075 
1076  avio_wb32(pb, 0); /* size */
1077  avio_wl32(pb, track->tag); // store it byteswapped
1078  avio_wb32(pb, 0); /* Reserved */
1079  avio_wb16(pb, 0); /* Reserved */
1080  avio_wb16(pb, 1); /* Data-reference index */
1081 
1082  avio_wb16(pb, 0); /* Codec stream version */
1083  avio_wb16(pb, 0); /* Codec stream revision (=0) */
1084  if (track->mode == MODE_MOV) {
1085  ffio_wfourcc(pb, "FFMP"); /* Vendor */
1086  if(track->enc->codec_id == AV_CODEC_ID_RAWVIDEO) {
1087  avio_wb32(pb, 0); /* Temporal Quality */
1088  avio_wb32(pb, 0x400); /* Spatial Quality = lossless*/
1089  } else {
1090  avio_wb32(pb, 0x200); /* Temporal Quality = normal */
1091  avio_wb32(pb, 0x200); /* Spatial Quality = normal */
1092  }
1093  } else {
1094  avio_wb32(pb, 0); /* Reserved */
1095  avio_wb32(pb, 0); /* Reserved */
1096  avio_wb32(pb, 0); /* Reserved */
1097  }
1098  avio_wb16(pb, track->enc->width); /* Video width */
1099  avio_wb16(pb, track->height); /* Video height */
1100  avio_wb32(pb, 0x00480000); /* Horizontal resolution 72dpi */
1101  avio_wb32(pb, 0x00480000); /* Vertical resolution 72dpi */
1102  avio_wb32(pb, 0); /* Data size (= 0) */
1103  avio_wb16(pb, 1); /* Frame count (= 1) */
1104 
1105  /* FIXME not sure, ISO 14496-1 draft where it shall be set to 0 */
1106  if (track->mode == MODE_MOV && track->enc->codec && track->enc->codec->name)
1107  av_strlcpy(compressor_name,track->enc->codec->name,32);
1108  avio_w8(pb, strlen(compressor_name));
1109  avio_write(pb, compressor_name, 31);
1110 
1111  if (track->mode == MODE_MOV && track->enc->bits_per_coded_sample)
1112  avio_wb16(pb, track->enc->bits_per_coded_sample);
1113  else
1114  avio_wb16(pb, 0x18); /* Reserved */
1115  avio_wb16(pb, 0xffff); /* Reserved */
1116  if(track->tag == MKTAG('m','p','4','v'))
1117  mov_write_esds_tag(pb, track);
1118  else if(track->enc->codec_id == AV_CODEC_ID_H263)
1119  mov_write_d263_tag(pb);
1120  else if(track->enc->codec_id == AV_CODEC_ID_AVUI ||
1121  track->enc->codec_id == AV_CODEC_ID_SVQ3) {
1122  mov_write_extradata_tag(pb, track);
1123  avio_wb32(pb, 0);
1124  } else if(track->enc->codec_id == AV_CODEC_ID_DNXHD)
1125  mov_write_avid_tag(pb, track);
1126  else if(track->enc->codec_id == AV_CODEC_ID_H264) {
1127  mov_write_avcc_tag(pb, track);
1128  if(track->mode == MODE_IPOD)
1130  } else if (track->enc->codec_id == AV_CODEC_ID_VC1 && track->vos_len > 0)
1131  mov_write_dvc1_tag(pb, track);
1132  else if (track->vos_len > 0)
1133  mov_write_glbl_tag(pb, track);
1134 
1135  if (track->enc->codec_id != AV_CODEC_ID_H264 &&
1136  track->enc->codec_id != AV_CODEC_ID_MPEG4 &&
1137  track->enc->codec_id != AV_CODEC_ID_DNXHD)
1138  if (track->enc->field_order != AV_FIELD_UNKNOWN)
1139  mov_write_fiel_tag(pb, track);
1140 
1141  if (track->enc->sample_aspect_ratio.den && track->enc->sample_aspect_ratio.num &&
1142  track->enc->sample_aspect_ratio.den != track->enc->sample_aspect_ratio.num) {
1143  mov_write_pasp_tag(pb, track);
1144  }
1145 
1146  return update_size(pb, pos);
1147 }
1148 
1150 {
1151  int64_t pos = avio_tell(pb);
1152  int frame_duration = av_rescale(track->timescale, track->enc->time_base.num, track->enc->time_base.den);
1153  int nb_frames = 1.0/av_q2d(track->enc->time_base) + 0.5;
1154 
1155  if (nb_frames > 255) {
1156  av_log(NULL, AV_LOG_ERROR, "fps %d is too large\n", nb_frames);
1157  return AVERROR(EINVAL);
1158  }
1159 
1160  avio_wb32(pb, 0); /* size */
1161  ffio_wfourcc(pb, "tmcd"); /* Data format */
1162  avio_wb32(pb, 0); /* Reserved */
1163  avio_wb32(pb, 1); /* Data reference index */
1164  avio_wb32(pb, 0); /* Flags */
1165  avio_wb32(pb, track->timecode_flags); /* Flags (timecode) */
1166  avio_wb32(pb, track->timescale); /* Timescale */
1167  avio_wb32(pb, frame_duration); /* Frame duration */
1168  avio_w8(pb, nb_frames); /* Number of frames */
1169  avio_wb24(pb, 0); /* Reserved */
1170  /* TODO: source reference string */
1171  return update_size(pb, pos);
1172 }
1173 
1175 {
1176  int64_t pos = avio_tell(pb);
1177  avio_wb32(pb, 0); /* size */
1178  ffio_wfourcc(pb, "rtp ");
1179  avio_wb32(pb, 0); /* Reserved */
1180  avio_wb16(pb, 0); /* Reserved */
1181  avio_wb16(pb, 1); /* Data-reference index */
1182 
1183  avio_wb16(pb, 1); /* Hint track version */
1184  avio_wb16(pb, 1); /* Highest compatible version */
1185  avio_wb32(pb, track->max_packet_size); /* Max packet size */
1186 
1187  avio_wb32(pb, 12); /* size */
1188  ffio_wfourcc(pb, "tims");
1189  avio_wb32(pb, track->timescale);
1190 
1191  return update_size(pb, pos);
1192 }
1193 
1195 {
1196  int64_t pos = avio_tell(pb);
1197  avio_wb32(pb, 0); /* size */
1198  ffio_wfourcc(pb, "stsd");
1199  avio_wb32(pb, 0); /* version & flags */
1200  avio_wb32(pb, 1); /* entry count */
1201  if (track->enc->codec_type == AVMEDIA_TYPE_VIDEO)
1202  mov_write_video_tag(pb, track);
1203  else if (track->enc->codec_type == AVMEDIA_TYPE_AUDIO)
1204  mov_write_audio_tag(pb, track);
1205  else if (track->enc->codec_type == AVMEDIA_TYPE_SUBTITLE)
1206  mov_write_subtitle_tag(pb, track);
1207  else if (track->enc->codec_tag == MKTAG('r','t','p',' '))
1208  mov_write_rtp_tag(pb, track);
1209  else if (track->enc->codec_tag == MKTAG('t','m','c','d'))
1210  mov_write_tmcd_tag(pb, track);
1211  return update_size(pb, pos);
1212 }
1213 
1215 {
1216  MOVStts *ctts_entries;
1217  uint32_t entries = 0;
1218  uint32_t atom_size;
1219  int i;
1220 
1221  ctts_entries = av_malloc((track->entry + 1) * sizeof(*ctts_entries)); /* worst case */
1222  ctts_entries[0].count = 1;
1223  ctts_entries[0].duration = track->cluster[0].cts;
1224  for (i=1; i<track->entry; i++) {
1225  if (track->cluster[i].cts == ctts_entries[entries].duration) {
1226  ctts_entries[entries].count++; /* compress */
1227  } else {
1228  entries++;
1229  ctts_entries[entries].duration = track->cluster[i].cts;
1230  ctts_entries[entries].count = 1;
1231  }
1232  }
1233  entries++; /* last one */
1234  atom_size = 16 + (entries * 8);
1235  avio_wb32(pb, atom_size); /* size */
1236  ffio_wfourcc(pb, "ctts");
1237  avio_wb32(pb, 0); /* version & flags */
1238  avio_wb32(pb, entries); /* entry count */
1239  for (i=0; i<entries; i++) {
1240  avio_wb32(pb, ctts_entries[i].count);
1241  avio_wb32(pb, ctts_entries[i].duration);
1242  }
1243  av_free(ctts_entries);
1244  return atom_size;
1245 }
1246 
1247 /* Time to sample atom */
1249 {
1250  MOVStts *stts_entries;
1251  uint32_t entries = -1;
1252  uint32_t atom_size;
1253  int i;
1254 
1255  if (track->enc->codec_type == AVMEDIA_TYPE_AUDIO && !track->audio_vbr) {
1256  stts_entries = av_malloc(sizeof(*stts_entries)); /* one entry */
1257  stts_entries[0].count = track->sample_count;
1258  stts_entries[0].duration = 1;
1259  entries = 1;
1260  } else {
1261  stts_entries = track->entry ?
1262  av_malloc(track->entry * sizeof(*stts_entries)) : /* worst case */
1263  NULL;
1264  for (i=0; i<track->entry; i++) {
1265  int duration = get_cluster_duration(track, i);
1266  if (i && duration == stts_entries[entries].duration) {
1267  stts_entries[entries].count++; /* compress */
1268  } else {
1269  entries++;
1270  stts_entries[entries].duration = duration;
1271  stts_entries[entries].count = 1;
1272  }
1273  }
1274  entries++; /* last one */
1275  }
1276  atom_size = 16 + (entries * 8);
1277  avio_wb32(pb, atom_size); /* size */
1278  ffio_wfourcc(pb, "stts");
1279  avio_wb32(pb, 0); /* version & flags */
1280  avio_wb32(pb, entries); /* entry count */
1281  for (i=0; i<entries; i++) {
1282  avio_wb32(pb, stts_entries[i].count);
1283  avio_wb32(pb, stts_entries[i].duration);
1284  }
1285  av_free(stts_entries);
1286  return atom_size;
1287 }
1288 
1290 {
1291  avio_wb32(pb, 28); /* size */
1292  ffio_wfourcc(pb, "dref");
1293  avio_wb32(pb, 0); /* version & flags */
1294  avio_wb32(pb, 1); /* entry count */
1295 
1296  avio_wb32(pb, 0xc); /* size */
1297  //FIXME add the alis and rsrc atom
1298  ffio_wfourcc(pb, "url ");
1299  avio_wb32(pb, 1); /* version & flags */
1300 
1301  return 28;
1302 }
1303 
1305 {
1306  int64_t pos = avio_tell(pb);
1307  avio_wb32(pb, 0); /* size */
1308  ffio_wfourcc(pb, "stbl");
1309  mov_write_stsd_tag(pb, track);
1310  mov_write_stts_tag(pb, track);
1311  if ((track->enc->codec_type == AVMEDIA_TYPE_VIDEO ||
1312  track->enc->codec_tag == MKTAG('r','t','p',' ')) &&
1313  track->has_keyframes && track->has_keyframes < track->entry)
1314  mov_write_stss_tag(pb, track, MOV_SYNC_SAMPLE);
1315  if (track->mode == MODE_MOV && track->flags & MOV_TRACK_STPS)
1317  if (track->enc->codec_type == AVMEDIA_TYPE_VIDEO &&
1318  track->flags & MOV_TRACK_CTTS)
1319  mov_write_ctts_tag(pb, track);
1320  mov_write_stsc_tag(pb, track);
1321  mov_write_stsz_tag(pb, track);
1322  mov_write_stco_tag(pb, track);
1323  return update_size(pb, pos);
1324 }
1325 
1327 {
1328  int64_t pos = avio_tell(pb);
1329  avio_wb32(pb, 0); /* size */
1330  ffio_wfourcc(pb, "dinf");
1331  mov_write_dref_tag(pb);
1332  return update_size(pb, pos);
1333 }
1334 
1336 {
1337  avio_wb32(pb, 12);
1338  ffio_wfourcc(pb, "nmhd");
1339  avio_wb32(pb, 0);
1340  return 12;
1341 }
1342 
1344 {
1345  int64_t pos = avio_tell(pb);
1346  const char *font = "Lucida Grande";
1347  avio_wb32(pb, 0); /* size */
1348  ffio_wfourcc(pb, "tcmi"); /* timecode media information atom */
1349  avio_wb32(pb, 0); /* version & flags */
1350  avio_wb16(pb, 0); /* text font */
1351  avio_wb16(pb, 0); /* text face */
1352  avio_wb16(pb, 12); /* text size */
1353  avio_wb16(pb, 0); /* (unknown, not in the QT specs...) */
1354  avio_wb16(pb, 0x0000); /* text color (red) */
1355  avio_wb16(pb, 0x0000); /* text color (green) */
1356  avio_wb16(pb, 0x0000); /* text color (blue) */
1357  avio_wb16(pb, 0xffff); /* background color (red) */
1358  avio_wb16(pb, 0xffff); /* background color (green) */
1359  avio_wb16(pb, 0xffff); /* background color (blue) */
1360  avio_w8(pb, strlen(font)); /* font len (part of the pascal string) */
1361  avio_write(pb, font, strlen(font)); /* font name */
1362  return update_size(pb, pos);
1363 }
1364 
1366 {
1367  int64_t pos = avio_tell(pb);
1368  avio_wb32(pb, 0); /* size */
1369  ffio_wfourcc(pb, "gmhd");
1370  avio_wb32(pb, 0x18); /* gmin size */
1371  ffio_wfourcc(pb, "gmin");/* generic media info */
1372  avio_wb32(pb, 0); /* version & flags */
1373  avio_wb16(pb, 0x40); /* graphics mode = */
1374  avio_wb16(pb, 0x8000); /* opColor (r?) */
1375  avio_wb16(pb, 0x8000); /* opColor (g?) */
1376  avio_wb16(pb, 0x8000); /* opColor (b?) */
1377  avio_wb16(pb, 0); /* balance */
1378  avio_wb16(pb, 0); /* reserved */
1379 
1380  /*
1381  * This special text atom is required for
1382  * Apple Quicktime chapters. The contents
1383  * don't appear to be documented, so the
1384  * bytes are copied verbatim.
1385  */
1386  if (track->tag != MKTAG('c','6','0','8')) {
1387  avio_wb32(pb, 0x2C); /* size */
1388  ffio_wfourcc(pb, "text");
1389  avio_wb16(pb, 0x01);
1390  avio_wb32(pb, 0x00);
1391  avio_wb32(pb, 0x00);
1392  avio_wb32(pb, 0x00);
1393  avio_wb32(pb, 0x01);
1394  avio_wb32(pb, 0x00);
1395  avio_wb32(pb, 0x00);
1396  avio_wb32(pb, 0x00);
1397  avio_wb32(pb, 0x00004000);
1398  avio_wb16(pb, 0x0000);
1399  }
1400 
1401  if (track->enc->codec_tag == MKTAG('t','m','c','d')) {
1402  int64_t tmcd_pos = avio_tell(pb);
1403  avio_wb32(pb, 0); /* size */
1404  ffio_wfourcc(pb, "tmcd");
1405  mov_write_tcmi_tag(pb, track);
1406  update_size(pb, tmcd_pos);
1407  }
1408  return update_size(pb, pos);
1409 }
1410 
1412 {
1413  avio_wb32(pb, 16); /* size */
1414  ffio_wfourcc(pb, "smhd");
1415  avio_wb32(pb, 0); /* version & flags */
1416  avio_wb16(pb, 0); /* reserved (balance, normally = 0) */
1417  avio_wb16(pb, 0); /* reserved */
1418  return 16;
1419 }
1420 
1422 {
1423  avio_wb32(pb, 0x14); /* size (always 0x14) */
1424  ffio_wfourcc(pb, "vmhd");
1425  avio_wb32(pb, 0x01); /* version & flags */
1426  avio_wb64(pb, 0); /* reserved (graphics mode = copy) */
1427  return 0x14;
1428 }
1429 
1431 {
1432  const char *hdlr, *descr = NULL, *hdlr_type = NULL;
1433  int64_t pos = avio_tell(pb);
1434 
1435  if (!track) { /* no media --> data handler */
1436  hdlr = "dhlr";
1437  hdlr_type = "url ";
1438  descr = "DataHandler";
1439  } else {
1440  hdlr = (track->mode == MODE_MOV) ? "mhlr" : "\0\0\0\0";
1441  if (track->enc->codec_type == AVMEDIA_TYPE_VIDEO) {
1442  hdlr_type = "vide";
1443  descr = "VideoHandler";
1444  } else if (track->enc->codec_type == AVMEDIA_TYPE_AUDIO) {
1445  hdlr_type = "soun";
1446  descr = "SoundHandler";
1447  } else if (track->enc->codec_type == AVMEDIA_TYPE_SUBTITLE) {
1448  if (track->tag == MKTAG('c','6','0','8')) {
1449  hdlr_type = "clcp";
1450  descr = "ClosedCaptionHandler";
1451  } else {
1452  if (track->tag == MKTAG('t','x','3','g')) hdlr_type = "sbtl";
1453  else hdlr_type = "text";
1454  descr = "SubtitleHandler";
1455  }
1456  } else if (track->enc->codec_tag == MKTAG('t','m','c','d')) {
1457  hdlr_type = "tmcd";
1458  descr = "TimeCodeHandler";
1459  } else if (track->enc->codec_tag == MKTAG('r','t','p',' ')) {
1460  hdlr_type = "hint";
1461  descr = "HintHandler";
1462  } else {
1463  hdlr = "dhlr";
1464  hdlr_type = "url ";
1465  descr = "DataHandler";
1466  }
1467  }
1468 
1469  avio_wb32(pb, 0); /* size */
1470  ffio_wfourcc(pb, "hdlr");
1471  avio_wb32(pb, 0); /* Version & flags */
1472  avio_write(pb, hdlr, 4); /* handler */
1473  ffio_wfourcc(pb, hdlr_type); /* handler type */
1474  avio_wb32(pb ,0); /* reserved */
1475  avio_wb32(pb ,0); /* reserved */
1476  avio_wb32(pb ,0); /* reserved */
1477  if (!track || track->mode == MODE_MOV)
1478  avio_w8(pb, strlen(descr)); /* pascal string */
1479  avio_write(pb, descr, strlen(descr)); /* handler description */
1480  if (track && track->mode != MODE_MOV)
1481  avio_w8(pb, 0); /* c string */
1482  return update_size(pb, pos);
1483 }
1484 
1486 {
1487  /* This atom must be present, but leaving the values at zero
1488  * seems harmless. */
1489  avio_wb32(pb, 28); /* size */
1490  ffio_wfourcc(pb, "hmhd");
1491  avio_wb32(pb, 0); /* version, flags */
1492  avio_wb16(pb, 0); /* maxPDUsize */
1493  avio_wb16(pb, 0); /* avgPDUsize */
1494  avio_wb32(pb, 0); /* maxbitrate */
1495  avio_wb32(pb, 0); /* avgbitrate */
1496  avio_wb32(pb, 0); /* reserved */
1497  return 28;
1498 }
1499 
1501 {
1502  int64_t pos = avio_tell(pb);
1503  avio_wb32(pb, 0); /* size */
1504  ffio_wfourcc(pb, "minf");
1505  if(track->enc->codec_type == AVMEDIA_TYPE_VIDEO)
1506  mov_write_vmhd_tag(pb);
1507  else if (track->enc->codec_type == AVMEDIA_TYPE_AUDIO)
1508  mov_write_smhd_tag(pb);
1509  else if (track->enc->codec_type == AVMEDIA_TYPE_SUBTITLE) {
1510  if (track->tag == MKTAG('t','e','x','t') || track->tag == MKTAG('c','6','0','8')) {
1511  mov_write_gmhd_tag(pb, track);
1512  } else {
1513  mov_write_nmhd_tag(pb);
1514  }
1515  } else if (track->tag == MKTAG('t','m','c','d')) {
1516  mov_write_gmhd_tag(pb, track);
1517  } else if (track->tag == MKTAG('r','t','p',' ')) {
1518  mov_write_hmhd_tag(pb);
1519  }
1520  if (track->mode == MODE_MOV) /* FIXME: Why do it for MODE_MOV only ? */
1521  mov_write_hdlr_tag(pb, NULL);
1522  mov_write_dinf_tag(pb);
1523  mov_write_stbl_tag(pb, track);
1524  return update_size(pb, pos);
1525 }
1526 
1528 {
1529  int version = track->track_duration < INT32_MAX ? 0 : 1;
1530 
1531  if (track->mode == MODE_ISM)
1532  version = 1;
1533 
1534  (version == 1) ? avio_wb32(pb, 44) : avio_wb32(pb, 32); /* size */
1535  ffio_wfourcc(pb, "mdhd");
1536  avio_w8(pb, version);
1537  avio_wb24(pb, 0); /* flags */
1538  if (version == 1) {
1539  avio_wb64(pb, track->time);
1540  avio_wb64(pb, track->time);
1541  } else {
1542  avio_wb32(pb, track->time); /* creation time */
1543  avio_wb32(pb, track->time); /* modification time */
1544  }
1545  avio_wb32(pb, track->timescale); /* time scale (sample rate for audio) */
1546  if (!track->entry)
1547  (version == 1) ? avio_wb64(pb, UINT64_C(0xffffffffffffffff)) : avio_wb32(pb, 0xffffffff);
1548  else
1549  (version == 1) ? avio_wb64(pb, track->track_duration) : avio_wb32(pb, track->track_duration); /* duration */
1550  avio_wb16(pb, track->language); /* language */
1551  avio_wb16(pb, 0); /* reserved (quality) */
1552 
1553  if(version!=0 && track->mode == MODE_MOV){
1555  "FATAL error, file duration too long for timebase, this file will not be\n"
1556  "playable with quicktime. Choose a different timebase or a different\n"
1557  "container format\n");
1558  }
1559 
1560  return 32;
1561 }
1562 
1564 {
1565  int64_t pos = avio_tell(pb);
1566  avio_wb32(pb, 0); /* size */
1567  ffio_wfourcc(pb, "mdia");
1568  mov_write_mdhd_tag(pb, track);
1569  mov_write_hdlr_tag(pb, track);
1570  mov_write_minf_tag(pb, track);
1571  return update_size(pb, pos);
1572 }
1573 
1574 /* transformation matrix
1575  |a b u|
1576  |c d v|
1577  |tx ty w| */
1578 static void write_matrix(AVIOContext *pb, int16_t a, int16_t b, int16_t c,
1579  int16_t d, int16_t tx, int16_t ty)
1580 {
1581  avio_wb32(pb, a << 16); /* 16.16 format */
1582  avio_wb32(pb, b << 16); /* 16.16 format */
1583  avio_wb32(pb, 0); /* u in 2.30 format */
1584  avio_wb32(pb, c << 16); /* 16.16 format */
1585  avio_wb32(pb, d << 16); /* 16.16 format */
1586  avio_wb32(pb, 0); /* v in 2.30 format */
1587  avio_wb32(pb, tx << 16); /* 16.16 format */
1588  avio_wb32(pb, ty << 16); /* 16.16 format */
1589  avio_wb32(pb, 1 << 30); /* w in 2.30 format */
1590 }
1591 
1593 {
1595  track->timescale, AV_ROUND_UP);
1596  int version = duration < INT32_MAX ? 0 : 1;
1597  int rotation = 0;
1598 
1599  if (track->mode == MODE_ISM)
1600  version = 1;
1601 
1602  (version == 1) ? avio_wb32(pb, 104) : avio_wb32(pb, 92); /* size */
1603  ffio_wfourcc(pb, "tkhd");
1604  avio_w8(pb, version);
1605  avio_wb24(pb, track->secondary ? 0x2 : 0xf); /* flags (first track enabled) */
1606  if (version == 1) {
1607  avio_wb64(pb, track->time);
1608  avio_wb64(pb, track->time);
1609  } else {
1610  avio_wb32(pb, track->time); /* creation time */
1611  avio_wb32(pb, track->time); /* modification time */
1612  }
1613  avio_wb32(pb, track->track_id); /* track-id */
1614  avio_wb32(pb, 0); /* reserved */
1615  if (!track->entry)
1616  (version == 1) ? avio_wb64(pb, UINT64_C(0xffffffffffffffff)) : avio_wb32(pb, 0xffffffff);
1617  else
1618  (version == 1) ? avio_wb64(pb, duration) : avio_wb32(pb, duration);
1619 
1620  avio_wb32(pb, 0); /* reserved */
1621  avio_wb32(pb, 0); /* reserved */
1622  avio_wb16(pb, 0); /* layer */
1623  avio_wb16(pb, st ? st->codec->codec_type : 0); /* alternate group) */
1624  /* Volume, only for audio */
1625  if(track->enc->codec_type == AVMEDIA_TYPE_AUDIO)
1626  avio_wb16(pb, 0x0100);
1627  else
1628  avio_wb16(pb, 0);
1629  avio_wb16(pb, 0); /* reserved */
1630 
1631  /* Matrix structure */
1632  if (st && st->metadata) {
1633  AVDictionaryEntry *rot = av_dict_get(st->metadata, "rotate", NULL, 0);
1634  rotation = (rot && rot->value) ? atoi(rot->value) : 0;
1635  }
1636  if (rotation == 90) {
1637  write_matrix(pb, 0, 1, -1, 0, track->enc->height, 0);
1638  } else if (rotation == 180) {
1639  write_matrix(pb, -1, 0, 0, -1, track->enc->width, track->enc->height);
1640  } else if (rotation == 270) {
1641  write_matrix(pb, 0, -1, 1, 0, 0, track->enc->width);
1642  } else {
1643  write_matrix(pb, 1, 0, 0, 1, 0, 0);
1644  }
1645  /* Track width and height, for visual only */
1646  if(st && (track->enc->codec_type == AVMEDIA_TYPE_VIDEO ||
1647  track->enc->codec_type == AVMEDIA_TYPE_SUBTITLE)) {
1648  if(track->mode == MODE_MOV) {
1649  avio_wb32(pb, track->enc->width << 16);
1650  avio_wb32(pb, track->height << 16);
1651  } else {
1652  double sample_aspect_ratio = av_q2d(st->sample_aspect_ratio);
1653  if(!sample_aspect_ratio || track->height != track->enc->height)
1654  sample_aspect_ratio = 1;
1655  avio_wb32(pb, sample_aspect_ratio * track->enc->width*0x10000);
1656  avio_wb32(pb, track->height*0x10000);
1657  }
1658  }
1659  else {
1660  avio_wb32(pb, 0);
1661  avio_wb32(pb, 0);
1662  }
1663  return 0x5c;
1664 }
1665 
1667 {
1669  track->enc->sample_aspect_ratio.den);
1670 
1671  int64_t pos = avio_tell(pb);
1672 
1673  avio_wb32(pb, 0); /* size */
1674  ffio_wfourcc(pb, "tapt");
1675 
1676  avio_wb32(pb, 20);
1677  ffio_wfourcc(pb, "clef");
1678  avio_wb32(pb, 0);
1679  avio_wb32(pb, width << 16);
1680  avio_wb32(pb, track->enc->height << 16);
1681 
1682  avio_wb32(pb, 20);
1683  ffio_wfourcc(pb, "prof");
1684  avio_wb32(pb, 0);
1685  avio_wb32(pb, width << 16);
1686  avio_wb32(pb, track->enc->height << 16);
1687 
1688  avio_wb32(pb, 20);
1689  ffio_wfourcc(pb, "enof");
1690  avio_wb32(pb, 0);
1691  avio_wb32(pb, track->enc->width << 16);
1692  avio_wb32(pb, track->enc->height << 16);
1693 
1694  return update_size(pb, pos);
1695 }
1696 
1697 // This box seems important for the psp playback ... without it the movie seems to hang
1699 {
1701  track->timescale, AV_ROUND_UP);
1702  int version = duration < INT32_MAX ? 0 : 1;
1703  int entry_size, entry_count, size;
1704  int64_t delay, start_ct = track->cluster[0].cts;
1705  delay = av_rescale_rnd(track->cluster[0].dts + start_ct, MOV_TIMESCALE,
1706  track->timescale, AV_ROUND_DOWN);
1707  version |= delay < INT32_MAX ? 0 : 1;
1708 
1709  entry_size = (version == 1) ? 20 : 12;
1710  entry_count = 1 + (delay > 0);
1711  size = 24 + entry_count * entry_size;
1712 
1713  /* write the atom data */
1714  avio_wb32(pb, size);
1715  ffio_wfourcc(pb, "edts");
1716  avio_wb32(pb, size - 8);
1717  ffio_wfourcc(pb, "elst");
1718  avio_w8(pb, version);
1719  avio_wb24(pb, 0); /* flags */
1720 
1721  avio_wb32(pb, entry_count);
1722  if (delay > 0) { /* add an empty edit to delay presentation */
1723  if (version == 1) {
1724  avio_wb64(pb, delay);
1725  avio_wb64(pb, -1);
1726  } else {
1727  avio_wb32(pb, delay);
1728  avio_wb32(pb, -1);
1729  }
1730  avio_wb32(pb, 0x00010000);
1731  } else {
1733  start_ct = -FFMIN(track->cluster[0].dts, 0); //FFMIN needed due to rounding
1734  duration += delay;
1735  }
1736 
1737  /* duration */
1738  if (version == 1) {
1739  avio_wb64(pb, duration);
1740  avio_wb64(pb, start_ct);
1741  } else {
1742  avio_wb32(pb, duration);
1743  avio_wb32(pb, start_ct);
1744  }
1745  avio_wb32(pb, 0x00010000);
1746  return size;
1747 }
1748 
1750 {
1751  avio_wb32(pb, 20); // size
1752  ffio_wfourcc(pb, "tref");
1753  avio_wb32(pb, 12); // size (subatom)
1754  avio_wl32(pb, track->tref_tag);
1755  avio_wb32(pb, track->tref_id);
1756  return 20;
1757 }
1758 
1759 // goes at the end of each track! ... Critical for PSP playback ("Incompatible data" without it)
1761 {
1762  avio_wb32(pb, 0x34); /* size ... reports as 28 in mp4box! */
1763  ffio_wfourcc(pb, "uuid");
1764  ffio_wfourcc(pb, "USMT");
1765  avio_wb32(pb, 0x21d24fce);
1766  avio_wb32(pb, 0xbb88695c);
1767  avio_wb32(pb, 0xfac9c740);
1768  avio_wb32(pb, 0x1c); // another size here!
1769  ffio_wfourcc(pb, "MTDT");
1770  avio_wb32(pb, 0x00010012);
1771  avio_wb32(pb, 0x0a);
1772  avio_wb32(pb, 0x55c40000);
1773  avio_wb32(pb, 0x1);
1774  avio_wb32(pb, 0x0);
1775  return 0x34;
1776 }
1777 
1779 {
1780 
1781  AVFormatContext *ctx = track->rtp_ctx;
1782  char buf[1000] = "";
1783  int len;
1784 
1785  ff_sdp_write_media(buf, sizeof(buf), ctx->streams[0], track->src_track,
1786  NULL, NULL, 0, 0, ctx);
1787  av_strlcatf(buf, sizeof(buf), "a=control:streamid=%d\r\n", track->track_id);
1788  len = strlen(buf);
1789 
1790  avio_wb32(pb, len + 24);
1791  ffio_wfourcc(pb, "udta");
1792  avio_wb32(pb, len + 16);
1793  ffio_wfourcc(pb, "hnti");
1794  avio_wb32(pb, len + 8);
1795  ffio_wfourcc(pb, "sdp ");
1796  avio_write(pb, buf, len);
1797  return len + 24;
1798 }
1799 
1801  MOVTrack *track, AVStream *st)
1802 {
1803  int64_t pos = avio_tell(pb);
1804  avio_wb32(pb, 0); /* size */
1805  ffio_wfourcc(pb, "trak");
1806  mov_write_tkhd_tag(pb, track, st);
1807  if (supports_edts(mov))
1808  mov_write_edts_tag(pb, track); // PSP Movies and several other cases require edts box
1809  if (track->tref_tag)
1810  mov_write_tref_tag(pb, track);
1811  mov_write_mdia_tag(pb, track);
1812  if (track->mode == MODE_PSP)
1813  mov_write_uuid_tag_psp(pb,track); // PSP Movies require this uuid box
1814  if (track->tag == MKTAG('r','t','p',' '))
1815  mov_write_udta_sdp(pb, track);
1816  if (track->enc->codec_type == AVMEDIA_TYPE_VIDEO && track->mode == MODE_MOV) {
1817  double sample_aspect_ratio = av_q2d(st->sample_aspect_ratio);
1818  if (st->sample_aspect_ratio.num && 1.0 != sample_aspect_ratio)
1819  mov_write_tapt_tag(pb, track);
1820  };
1821  return update_size(pb, pos);
1822 }
1823 
1825 {
1826  int i, has_audio = 0, has_video = 0;
1827  int64_t pos = avio_tell(pb);
1828  int audio_profile = mov->iods_audio_profile;
1829  int video_profile = mov->iods_video_profile;
1830  for (i = 0; i < mov->nb_streams; i++) {
1831  if(mov->tracks[i].entry > 0) {
1832  has_audio |= mov->tracks[i].enc->codec_type == AVMEDIA_TYPE_AUDIO;
1833  has_video |= mov->tracks[i].enc->codec_type == AVMEDIA_TYPE_VIDEO;
1834  }
1835  }
1836  if (audio_profile < 0)
1837  audio_profile = 0xFF - has_audio;
1838  if (video_profile < 0)
1839  video_profile = 0xFF - has_video;
1840  avio_wb32(pb, 0x0); /* size */
1841  ffio_wfourcc(pb, "iods");
1842  avio_wb32(pb, 0); /* version & flags */
1843  put_descr(pb, 0x10, 7);
1844  avio_wb16(pb, 0x004f);
1845  avio_w8(pb, 0xff);
1846  avio_w8(pb, 0xff);
1847  avio_w8(pb, audio_profile);
1848  avio_w8(pb, video_profile);
1849  avio_w8(pb, 0xff);
1850  return update_size(pb, pos);
1851 }
1852 
1854 {
1855  avio_wb32(pb, 0x20); /* size */
1856  ffio_wfourcc(pb, "trex");
1857  avio_wb32(pb, 0); /* version & flags */
1858  avio_wb32(pb, track->track_id); /* track ID */
1859  avio_wb32(pb, 1); /* default sample description index */
1860  avio_wb32(pb, 0); /* default sample duration */
1861  avio_wb32(pb, 0); /* default sample size */
1862  avio_wb32(pb, 0); /* default sample flags */
1863  return 0;
1864 }
1865 
1867 {
1868  int64_t pos = avio_tell(pb);
1869  int i;
1870  avio_wb32(pb, 0x0); /* size */
1871  ffio_wfourcc(pb, "mvex");
1872  for (i = 0; i < mov->nb_streams; i++)
1873  mov_write_trex_tag(pb, &mov->tracks[i]);
1874  return update_size(pb, pos);
1875 }
1876 
1878 {
1879  int max_track_id = 1, i;
1880  int64_t max_track_len_temp, max_track_len = 0;
1881  int version;
1882 
1883  for (i=0; i<mov->nb_streams; i++) {
1884  if(mov->tracks[i].entry > 0) {
1885  max_track_len_temp = av_rescale_rnd(mov->tracks[i].track_duration,
1886  MOV_TIMESCALE,
1887  mov->tracks[i].timescale,
1888  AV_ROUND_UP);
1889  if (max_track_len < max_track_len_temp)
1890  max_track_len = max_track_len_temp;
1891  if (max_track_id < mov->tracks[i].track_id)
1892  max_track_id = mov->tracks[i].track_id;
1893  }
1894  }
1895 
1896  version = max_track_len < UINT32_MAX ? 0 : 1;
1897  (version == 1) ? avio_wb32(pb, 120) : avio_wb32(pb, 108); /* size */
1898  ffio_wfourcc(pb, "mvhd");
1899  avio_w8(pb, version);
1900  avio_wb24(pb, 0); /* flags */
1901  if (version == 1) {
1902  avio_wb64(pb, mov->time);
1903  avio_wb64(pb, mov->time);
1904  } else {
1905  avio_wb32(pb, mov->time); /* creation time */
1906  avio_wb32(pb, mov->time); /* modification time */
1907  }
1908  avio_wb32(pb, MOV_TIMESCALE);
1909  (version == 1) ? avio_wb64(pb, max_track_len) : avio_wb32(pb, max_track_len); /* duration of longest track */
1910 
1911  avio_wb32(pb, 0x00010000); /* reserved (preferred rate) 1.0 = normal */
1912  avio_wb16(pb, 0x0100); /* reserved (preferred volume) 1.0 = normal */
1913  avio_wb16(pb, 0); /* reserved */
1914  avio_wb32(pb, 0); /* reserved */
1915  avio_wb32(pb, 0); /* reserved */
1916 
1917  /* Matrix structure */
1918  write_matrix(pb, 1, 0, 0, 1, 0, 0);
1919 
1920  avio_wb32(pb, 0); /* reserved (preview time) */
1921  avio_wb32(pb, 0); /* reserved (preview duration) */
1922  avio_wb32(pb, 0); /* reserved (poster time) */
1923  avio_wb32(pb, 0); /* reserved (selection time) */
1924  avio_wb32(pb, 0); /* reserved (selection duration) */
1925  avio_wb32(pb, 0); /* reserved (current time) */
1926  avio_wb32(pb, max_track_id + 1); /* Next track id */
1927  return 0x6c;
1928 }
1929 
1931  AVFormatContext *s)
1932 {
1933  avio_wb32(pb, 33); /* size */
1934  ffio_wfourcc(pb, "hdlr");
1935  avio_wb32(pb, 0);
1936  avio_wb32(pb, 0);
1937  ffio_wfourcc(pb, "mdir");
1938  ffio_wfourcc(pb, "appl");
1939  avio_wb32(pb, 0);
1940  avio_wb32(pb, 0);
1941  avio_w8(pb, 0);
1942  return 33;
1943 }
1944 
1945 /* helper function to write a data tag with the specified string as data */
1946 static int mov_write_string_data_tag(AVIOContext *pb, const char *data, int lang, int long_style)
1947 {
1948  if(long_style){
1949  int size = 16 + strlen(data);
1950  avio_wb32(pb, size); /* size */
1951  ffio_wfourcc(pb, "data");
1952  avio_wb32(pb, 1);
1953  avio_wb32(pb, 0);
1954  avio_write(pb, data, strlen(data));
1955  return size;
1956  }else{
1957  if (!lang)
1958  lang = ff_mov_iso639_to_lang("und", 1);
1959  avio_wb16(pb, strlen(data)); /* string length */
1960  avio_wb16(pb, lang);
1961  avio_write(pb, data, strlen(data));
1962  return strlen(data) + 4;
1963  }
1964 }
1965 
1966 static int mov_write_string_tag(AVIOContext *pb, const char *name, const char *value, int lang, int long_style){
1967  int size = 0;
1968  if (value && value[0]) {
1969  int64_t pos = avio_tell(pb);
1970  avio_wb32(pb, 0); /* size */
1971  ffio_wfourcc(pb, name);
1972  mov_write_string_data_tag(pb, value, lang, long_style);
1973  size = update_size(pb, pos);
1974  }
1975  return size;
1976 }
1977 
1979  const char *name, const char *tag,
1980  int long_style)
1981 {
1982  int l, lang = 0, len, len2;
1983  AVDictionaryEntry *t, *t2 = NULL;
1984  char tag2[16];
1985 
1986  if (!(t = av_dict_get(s->metadata, tag, NULL, 0)))
1987  return 0;
1988 
1989  len = strlen(t->key);
1990  snprintf(tag2, sizeof(tag2), "%s-", tag);
1991  while ((t2 = av_dict_get(s->metadata, tag2, t2, AV_DICT_IGNORE_SUFFIX))) {
1992  len2 = strlen(t2->key);
1993  if (len2 == len+4 && !strcmp(t->value, t2->value)
1994  && (l=ff_mov_iso639_to_lang(&t2->key[len2-3], 1)) >= 0) {
1995  lang = l;
1996  break;
1997  }
1998  }
1999  return mov_write_string_tag(pb, name, t->value, lang, long_style);
2000 }
2001 
2002 /* iTunes bpm number */
2004 {
2005  AVDictionaryEntry *t = av_dict_get(s->metadata, "tmpo", NULL, 0);
2006  int size = 0, tmpo = t ? atoi(t->value) : 0;
2007  if (tmpo) {
2008  size = 26;
2009  avio_wb32(pb, size);
2010  ffio_wfourcc(pb, "tmpo");
2011  avio_wb32(pb, size-8); /* size */
2012  ffio_wfourcc(pb, "data");
2013  avio_wb32(pb, 0x15); //type specifier
2014  avio_wb32(pb, 0);
2015  avio_wb16(pb, tmpo); // data
2016  }
2017  return size;
2018 }
2019 
2020 /* iTunes track number */
2022  AVFormatContext *s)
2023 {
2024  AVDictionaryEntry *t = av_dict_get(s->metadata, "track", NULL, 0);
2025  int size = 0, track = t ? atoi(t->value) : 0;
2026  if (track) {
2027  avio_wb32(pb, 32); /* size */
2028  ffio_wfourcc(pb, "trkn");
2029  avio_wb32(pb, 24); /* size */
2030  ffio_wfourcc(pb, "data");
2031  avio_wb32(pb, 0); // 8 bytes empty
2032  avio_wb32(pb, 0);
2033  avio_wb16(pb, 0); // empty
2034  avio_wb16(pb, track); // track number
2035  avio_wb16(pb, 0); // total track number
2036  avio_wb16(pb, 0); // empty
2037  size = 32;
2038  }
2039  return size;
2040 }
2041 
2043  const char *name, const char *tag,
2044  int len)
2045 {
2047  uint8_t num;
2048 
2049  if (!(t = av_dict_get(s->metadata, tag, NULL, 0)))
2050  return 0;
2051  num = atoi(t->value);
2052 
2053  avio_wb32(pb, len+8);
2054  ffio_wfourcc(pb, name);
2055  if (len==4) avio_wb32(pb, num);
2056  else avio_w8 (pb, num);
2057  return len+8;
2058 }
2059 
2060 /* iTunes meta data list */
2062  AVFormatContext *s)
2063 {
2064  int64_t pos = avio_tell(pb);
2065  avio_wb32(pb, 0); /* size */
2066  ffio_wfourcc(pb, "ilst");
2067  mov_write_string_metadata(s, pb, "\251nam", "title" , 1);
2068  mov_write_string_metadata(s, pb, "\251ART", "artist" , 1);
2069  mov_write_string_metadata(s, pb, "aART", "album_artist", 1);
2070  mov_write_string_metadata(s, pb, "\251wrt", "composer" , 1);
2071  mov_write_string_metadata(s, pb, "\251alb", "album" , 1);
2072  mov_write_string_metadata(s, pb, "\251day", "date" , 1);
2073  mov_write_string_tag(pb, "\251too", LIBAVFORMAT_IDENT, 0, 1);
2074  mov_write_string_metadata(s, pb, "\251cmt", "comment" , 1);
2075  mov_write_string_metadata(s, pb, "\251gen", "genre" , 1);
2076  mov_write_string_metadata(s, pb, "\251cpy", "copyright", 1);
2077  mov_write_string_metadata(s, pb, "\251grp", "grouping" , 1);
2078  mov_write_string_metadata(s, pb, "\251lyr", "lyrics" , 1);
2079  mov_write_string_metadata(s, pb, "desc", "description",1);
2080  mov_write_string_metadata(s, pb, "ldes", "synopsis" , 1);
2081  mov_write_string_metadata(s, pb, "tvsh", "show" , 1);
2082  mov_write_string_metadata(s, pb, "tven", "episode_id",1);
2083  mov_write_string_metadata(s, pb, "tvnn", "network" , 1);
2084  mov_write_int8_metadata (s, pb, "tves", "episode_sort",4);
2085  mov_write_int8_metadata (s, pb, "tvsn", "season_number",4);
2086  mov_write_int8_metadata (s, pb, "stik", "media_type",1);
2087  mov_write_int8_metadata (s, pb, "hdvd", "hd_video", 1);
2088  mov_write_int8_metadata (s, pb, "pgap", "gapless_playback",1);
2089  mov_write_trkn_tag(pb, mov, s);
2090  mov_write_tmpo_tag(pb, s);
2091  return update_size(pb, pos);
2092 }
2093 
2094 /* iTunes meta data tag */
2096  AVFormatContext *s)
2097 {
2098  int size = 0;
2099  int64_t pos = avio_tell(pb);
2100  avio_wb32(pb, 0); /* size */
2101  ffio_wfourcc(pb, "meta");
2102  avio_wb32(pb, 0);
2103  mov_write_itunes_hdlr_tag(pb, mov, s);
2104  mov_write_ilst_tag(pb, mov, s);
2105  size = update_size(pb, pos);
2106  return size;
2107 }
2108 
2109 static int utf8len(const uint8_t *b)
2110 {
2111  int len=0;
2112  int val;
2113  while(*b){
2114  GET_UTF8(val, *b++, return -1;)
2115  len++;
2116  }
2117  return len;
2118 }
2119 
2120 static int ascii_to_wc(AVIOContext *pb, const uint8_t *b)
2121 {
2122  int val;
2123  while(*b){
2124  GET_UTF8(val, *b++, return -1;)
2125  avio_wb16(pb, val);
2126  }
2127  avio_wb16(pb, 0x00);
2128  return 0;
2129 }
2130 
2131 static uint16_t language_code(const char *str)
2132 {
2133  return (((str[0]-0x60) & 0x1F) << 10) + (((str[1]-0x60) & 0x1F) << 5) + ((str[2]-0x60) & 0x1F);
2134 }
2135 
2137  const char *tag, const char *str)
2138 {
2139  int64_t pos = avio_tell(pb);
2140  AVDictionaryEntry *t = av_dict_get(s->metadata, str, NULL, 0);
2141  if (!t || !utf8len(t->value))
2142  return 0;
2143  avio_wb32(pb, 0); /* size */
2144  ffio_wfourcc(pb, tag); /* type */
2145  avio_wb32(pb, 0); /* version + flags */
2146  if (!strcmp(tag, "yrrc"))
2147  avio_wb16(pb, atoi(t->value));
2148  else {
2149  avio_wb16(pb, language_code("eng")); /* language */
2150  avio_write(pb, t->value, strlen(t->value)+1); /* UTF8 string value */
2151  if (!strcmp(tag, "albm") &&
2152  (t = av_dict_get(s->metadata, "track", NULL, 0)))
2153  avio_w8(pb, atoi(t->value));
2154  }
2155  return update_size(pb, pos);
2156 }
2157 
2159 {
2160  int64_t pos = avio_tell(pb);
2161  int i, nb_chapters = FFMIN(s->nb_chapters, 255);
2162 
2163  avio_wb32(pb, 0); // size
2164  ffio_wfourcc(pb, "chpl");
2165  avio_wb32(pb, 0x01000000); // version + flags
2166  avio_wb32(pb, 0); // unknown
2167  avio_w8(pb, nb_chapters);
2168 
2169  for (i = 0; i < nb_chapters; i++) {
2170  AVChapter *c = s->chapters[i];
2172  avio_wb64(pb, av_rescale_q(c->start, c->time_base, (AVRational){1,10000000}));
2173 
2174  if ((t = av_dict_get(c->metadata, "title", NULL, 0))) {
2175  int len = FFMIN(strlen(t->value), 255);
2176  avio_w8(pb, len);
2177  avio_write(pb, t->value, len);
2178  } else
2179  avio_w8(pb, 0);
2180  }
2181  return update_size(pb, pos);
2182 }
2183 
2185  AVFormatContext *s)
2186 {
2187  AVIOContext *pb_buf;
2188  int i, ret, size;
2189  uint8_t *buf;
2190 
2191  for (i = 0; i < s->nb_streams; i++)
2192  if (mov->tracks[i].enc->flags & CODEC_FLAG_BITEXACT) {
2193  return 0;
2194  }
2195 
2196  ret = avio_open_dyn_buf(&pb_buf);
2197  if(ret < 0)
2198  return ret;
2199 
2200  if (mov->mode & MODE_3GP) {
2201  mov_write_3gp_udta_tag(pb_buf, s, "perf", "artist");
2202  mov_write_3gp_udta_tag(pb_buf, s, "titl", "title");
2203  mov_write_3gp_udta_tag(pb_buf, s, "auth", "author");
2204  mov_write_3gp_udta_tag(pb_buf, s, "gnre", "genre");
2205  mov_write_3gp_udta_tag(pb_buf, s, "dscp", "comment");
2206  mov_write_3gp_udta_tag(pb_buf, s, "albm", "album");
2207  mov_write_3gp_udta_tag(pb_buf, s, "cprt", "copyright");
2208  mov_write_3gp_udta_tag(pb_buf, s, "yrrc", "date");
2209  } else if (mov->mode == MODE_MOV) { // the title field breaks gtkpod with mp4 and my suspicion is that stuff is not valid in mp4
2210  mov_write_string_metadata(s, pb_buf, "\251ART", "artist" , 0);
2211  mov_write_string_metadata(s, pb_buf, "\251nam", "title" , 0);
2212  mov_write_string_metadata(s, pb_buf, "\251aut", "author" , 0);
2213  mov_write_string_metadata(s, pb_buf, "\251alb", "album" , 0);
2214  mov_write_string_metadata(s, pb_buf, "\251day", "date" , 0);
2215  mov_write_string_metadata(s, pb_buf, "\251swr", "encoder" , 0);
2216  // currently ignored by mov.c
2217  mov_write_string_metadata(s, pb_buf, "\251des", "comment" , 0);
2218  // add support for libquicktime, this atom is also actually read by mov.c
2219  mov_write_string_metadata(s, pb_buf, "\251cmt", "comment" , 0);
2220  mov_write_string_metadata(s, pb_buf, "\251gen", "genre" , 0);
2221  mov_write_string_metadata(s, pb_buf, "\251cpy", "copyright" , 0);
2222  } else {
2223  /* iTunes meta data */
2224  mov_write_meta_tag(pb_buf, mov, s);
2225  }
2226 
2227  if (s->nb_chapters)
2228  mov_write_chpl_tag(pb_buf, s);
2229 
2230  if ((size = avio_close_dyn_buf(pb_buf, &buf)) > 0) {
2231  avio_wb32(pb, size+8);
2232  ffio_wfourcc(pb, "udta");
2233  avio_write(pb, buf, size);
2234  }
2235  av_free(buf);
2236 
2237  return 0;
2238 }
2239 
2241  const char *str, const char *lang, int type)
2242 {
2243  int len = utf8len(str)+1;
2244  if(len<=0)
2245  return;
2246  avio_wb16(pb, len*2+10); /* size */
2247  avio_wb32(pb, type); /* type */
2248  avio_wb16(pb, language_code(lang)); /* language */
2249  avio_wb16(pb, 0x01); /* ? */
2250  ascii_to_wc(pb, str);
2251 }
2252 
2254 {
2255  AVDictionaryEntry *title = av_dict_get(s->metadata, "title", NULL, 0);
2256  int64_t pos, pos2;
2257 
2258  if (title) {
2259  pos = avio_tell(pb);
2260  avio_wb32(pb, 0); /* size placeholder*/
2261  ffio_wfourcc(pb, "uuid");
2262  ffio_wfourcc(pb, "USMT");
2263  avio_wb32(pb, 0x21d24fce); /* 96 bit UUID */
2264  avio_wb32(pb, 0xbb88695c);
2265  avio_wb32(pb, 0xfac9c740);
2266 
2267  pos2 = avio_tell(pb);
2268  avio_wb32(pb, 0); /* size placeholder*/
2269  ffio_wfourcc(pb, "MTDT");
2270  avio_wb16(pb, 4);
2271 
2272  // ?
2273  avio_wb16(pb, 0x0C); /* size */
2274  avio_wb32(pb, 0x0B); /* type */
2275  avio_wb16(pb, language_code("und")); /* language */
2276  avio_wb16(pb, 0x0); /* ? */
2277  avio_wb16(pb, 0x021C); /* data */
2278 
2279  mov_write_psp_udta_tag(pb, LIBAVCODEC_IDENT, "eng", 0x04);
2280  mov_write_psp_udta_tag(pb, title->value, "eng", 0x01);
2281  mov_write_psp_udta_tag(pb, "2006/04/01 11:11:11", "und", 0x03);
2282 
2283  update_size(pb, pos2);
2284  return update_size(pb, pos);
2285  }
2286 
2287  return 0;
2288 }
2289 
2290 static void build_chunks(MOVTrack *trk)
2291 {
2292  int i;
2293  MOVIentry *chunk= &trk->cluster[0];
2294  uint64_t chunkSize = chunk->size;
2295  chunk->chunkNum= 1;
2296  if (trk->chunkCount)
2297  return;
2298  trk->chunkCount= 1;
2299  for(i=1; i<trk->entry; i++){
2300  if(chunk->pos + chunkSize == trk->cluster[i].pos &&
2301  chunkSize + trk->cluster[i].size < (1<<20)){
2302  chunkSize += trk->cluster[i].size;
2303  chunk->samples_in_chunk += trk->cluster[i].entries;
2304  }else{
2305  trk->cluster[i].chunkNum = chunk->chunkNum+1;
2306  chunk=&trk->cluster[i];
2307  chunkSize = chunk->size;
2308  trk->chunkCount++;
2309  }
2310  }
2311 }
2312 
2314  AVFormatContext *s)
2315 {
2316  int i;
2317  int64_t pos = avio_tell(pb);
2318  int not_first[AVMEDIA_TYPE_NB]={0};
2319  avio_wb32(pb, 0); /* size placeholder*/
2320  ffio_wfourcc(pb, "moov");
2321 
2322  for (i=0; i<mov->nb_streams; i++) {
2323  if (mov->tracks[i].entry <= 0 && !(mov->flags & FF_MOV_FLAG_FRAGMENT))
2324  continue;
2325 
2326  mov->tracks[i].time = mov->time;
2327  mov->tracks[i].track_id = i+1;
2328 
2329  if (mov->tracks[i].entry)
2330  build_chunks(&mov->tracks[i]);
2331  }
2332 
2333  if (mov->chapter_track)
2334  for (i=0; i<s->nb_streams; i++) {
2335  mov->tracks[i].tref_tag = MKTAG('c','h','a','p');
2336  mov->tracks[i].tref_id = mov->tracks[mov->chapter_track].track_id;
2337  }
2338  for (i = 0; i < mov->nb_streams; i++) {
2339  if (mov->tracks[i].tag == MKTAG('r','t','p',' ')) {
2340  mov->tracks[i].tref_tag = MKTAG('h','i','n','t');
2341  mov->tracks[i].tref_id =
2342  mov->tracks[mov->tracks[i].src_track].track_id;
2343  }
2344  }
2345  for (i = 0; i < mov->nb_streams; i++) {
2346  if (mov->tracks[i].tag == MKTAG('t','m','c','d')) {
2347  int src_trk = mov->tracks[i].src_track;
2348  mov->tracks[src_trk].tref_tag = mov->tracks[i].tag;
2349  mov->tracks[src_trk].tref_id = mov->tracks[i].track_id;
2350  mov->tracks[i].track_duration = mov->tracks[src_trk].track_duration;
2351  }
2352  }
2353 
2354  mov_write_mvhd_tag(pb, mov);
2355  if (mov->mode != MODE_MOV && !mov->iods_skip)
2356  mov_write_iods_tag(pb, mov);
2357  for (i=0; i<mov->nb_streams; i++) {
2358  if (mov->tracks[i].entry > 0 || mov->flags & FF_MOV_FLAG_FRAGMENT) {
2359  if(i < s->nb_streams){
2360  int codec_type= s->streams[i]->codec->codec_type;
2361  if(codec_type==AVMEDIA_TYPE_AUDIO || codec_type==AVMEDIA_TYPE_SUBTITLE){
2362  mov->tracks[i].secondary= not_first[codec_type];
2363  not_first[codec_type]= 1;
2364  }
2365  }
2366  mov_write_trak_tag(pb, mov, &(mov->tracks[i]), i < s->nb_streams ? s->streams[i] : NULL);
2367  }
2368  }
2369  if (mov->flags & FF_MOV_FLAG_FRAGMENT)
2370  mov_write_mvex_tag(pb, mov); /* QuickTime requires trak to precede this */
2371 
2372  if (mov->mode == MODE_PSP)
2373  mov_write_uuidusmt_tag(pb, s);
2374  else
2375  mov_write_udta_tag(pb, mov, s);
2376 
2377  return update_size(pb, pos);
2378 }
2379 
2380 static void param_write_int(AVIOContext *pb, const char *name, int value)
2381 {
2382  avio_printf(pb, "<param name=\"%s\" value=\"%d\" valuetype=\"data\"/>\n", name, value);
2383 }
2384 
2385 static void param_write_string(AVIOContext *pb, const char *name, const char *value)
2386 {
2387  avio_printf(pb, "<param name=\"%s\" value=\"%s\" valuetype=\"data\"/>\n", name, value);
2388 }
2389 
2390 static void param_write_hex(AVIOContext *pb, const char *name, const uint8_t *value, int len)
2391 {
2392  char buf[150];
2393  len = FFMIN(sizeof(buf)/2 - 1, len);
2394  ff_data_to_hex(buf, value, len, 0);
2395  buf[2*len] = '\0';
2396  avio_printf(pb, "<param name=\"%s\" value=\"%s\" valuetype=\"data\"/>\n", name, buf);
2397 }
2398 
2400 {
2401  int64_t pos = avio_tell(pb);
2402  int i;
2403  const uint8_t uuid[] = {
2404  0xa5, 0xd4, 0x0b, 0x30, 0xe8, 0x14, 0x11, 0xdd,
2405  0xba, 0x2f, 0x08, 0x00, 0x20, 0x0c, 0x9a, 0x66
2406  };
2407 
2408  avio_wb32(pb, 0);
2409  ffio_wfourcc(pb, "uuid");
2410  avio_write(pb, uuid, sizeof(uuid));
2411  avio_wb32(pb, 0);
2412 
2413  avio_printf(pb, "<?xml version=\"1.0\" encoding=\"utf-8\"?>\n");
2414  avio_printf(pb, "<smil xmlns=\"http://www.w3.org/2001/SMIL20/Language\">\n");
2415  avio_printf(pb, "<head>\n");
2416  avio_printf(pb, "<meta name=\"creator\" content=\"%s\" />\n",
2418  avio_printf(pb, "</head>\n");
2419  avio_printf(pb, "<body>\n");
2420  avio_printf(pb, "<switch>\n");
2421  for (i = 0; i < mov->nb_streams; i++) {
2422  MOVTrack *track = &mov->tracks[i];
2423  const char *type;
2424  /* track->track_id is initialized in write_moov, and thus isn't known
2425  * here yet */
2426  int track_id = i + 1;
2427 
2428  if (track->enc->codec_type == AVMEDIA_TYPE_VIDEO) {
2429  type = "video";
2430  } else if (track->enc->codec_type == AVMEDIA_TYPE_AUDIO) {
2431  type = "audio";
2432  } else {
2433  continue;
2434  }
2435  avio_printf(pb, "<%s systemBitrate=\"%d\">\n", type,
2436  track->enc->bit_rate);
2437  param_write_int(pb, "systemBitrate", track->enc->bit_rate);
2438  param_write_int(pb, "trackID", track_id);
2439  if (track->enc->codec_type == AVMEDIA_TYPE_VIDEO) {
2440  if (track->enc->codec_id == AV_CODEC_ID_H264) {
2441  uint8_t *ptr;
2442  int size = track->enc->extradata_size;
2443  if (!ff_avc_write_annexb_extradata(track->enc->extradata, &ptr,
2444  &size)) {
2445  param_write_hex(pb, "CodecPrivateData",
2446  ptr ? ptr : track->enc->extradata,
2447  size);
2448  av_free(ptr);
2449  }
2450  param_write_string(pb, "FourCC", "H264");
2451  } else if (track->enc->codec_id == AV_CODEC_ID_VC1) {
2452  param_write_string(pb, "FourCC", "WVC1");
2453  param_write_hex(pb, "CodecPrivateData", track->enc->extradata,
2454  track->enc->extradata_size);
2455  }
2456  param_write_int(pb, "MaxWidth", track->enc->width);
2457  param_write_int(pb, "MaxHeight", track->enc->height);
2458  param_write_int(pb, "DisplayWidth", track->enc->width);
2459  param_write_int(pb, "DisplayHeight", track->enc->height);
2460  } else {
2461  if (track->enc->codec_id == AV_CODEC_ID_AAC) {
2462  param_write_string(pb, "FourCC", "AACL");
2463  } else if (track->enc->codec_id == AV_CODEC_ID_WMAPRO) {
2464  param_write_string(pb, "FourCC", "WMAP");
2465  }
2466  param_write_hex(pb, "CodecPrivateData", track->enc->extradata,
2467  track->enc->extradata_size);
2469  track->enc->codec_id));
2470  param_write_int(pb, "Channels", track->enc->channels);
2471  param_write_int(pb, "SamplingRate", track->enc->sample_rate);
2472  param_write_int(pb, "BitsPerSample", 16);
2473  param_write_int(pb, "PacketSize", track->enc->block_align ?
2474  track->enc->block_align : 4);
2475  }
2476  avio_printf(pb, "</%s>\n", type);
2477  }
2478  avio_printf(pb, "</switch>\n");
2479  avio_printf(pb, "</body>\n");
2480  avio_printf(pb, "</smil>\n");
2481 
2482  return update_size(pb, pos);
2483 }
2484 
2486 {
2487  avio_wb32(pb, 16);
2488  ffio_wfourcc(pb, "mfhd");
2489  avio_wb32(pb, 0);
2490  avio_wb32(pb, mov->fragments);
2491  return 0;
2492 }
2493 
2495  int64_t moof_offset)
2496 {
2497  int64_t pos = avio_tell(pb);
2500  if (!track->entry) {
2501  flags |= MOV_TFHD_DURATION_IS_EMPTY;
2502  } else {
2503  flags |= MOV_TFHD_DEFAULT_FLAGS;
2504  }
2505 
2506  /* Don't set a default sample size, the silverlight player refuses
2507  * to play files with that set. Don't set a default sample duration,
2508  * WMP freaks out if it is set. */
2509  if (track->mode == MODE_ISM)
2511 
2512  avio_wb32(pb, 0); /* size placeholder */
2513  ffio_wfourcc(pb, "tfhd");
2514  avio_w8(pb, 0); /* version */
2515  avio_wb24(pb, flags);
2516 
2517  avio_wb32(pb, track->track_id); /* track-id */
2518  if (flags & MOV_TFHD_BASE_DATA_OFFSET)
2519  avio_wb64(pb, moof_offset);
2520  if (flags & MOV_TFHD_DEFAULT_DURATION) {
2521  track->default_duration = get_cluster_duration(track, 0);
2522  avio_wb32(pb, track->default_duration);
2523  }
2524  if (flags & MOV_TFHD_DEFAULT_SIZE) {
2525  track->default_size = track->entry ? track->cluster[0].size : 1;
2526  avio_wb32(pb, track->default_size);
2527  } else
2528  track->default_size = -1;
2529 
2530  if (flags & MOV_TFHD_DEFAULT_FLAGS) {
2531  track->default_sample_flags =
2532  track->enc->codec_type == AVMEDIA_TYPE_VIDEO ?
2535  avio_wb32(pb, track->default_sample_flags);
2536  }
2537 
2538  return update_size(pb, pos);
2539 }
2540 
2541 static uint32_t get_sample_flags(MOVTrack *track, MOVIentry *entry)
2542 {
2545 }
2546 
2548 {
2549  int64_t pos = avio_tell(pb);
2550  uint32_t flags = MOV_TRUN_DATA_OFFSET;
2551  int i;
2552 
2553  for (i = 0; i < track->entry; i++) {
2554  if (get_cluster_duration(track, i) != track->default_duration)
2555  flags |= MOV_TRUN_SAMPLE_DURATION;
2556  if (track->cluster[i].size != track->default_size)
2557  flags |= MOV_TRUN_SAMPLE_SIZE;
2558  if (i > 0 && get_sample_flags(track, &track->cluster[i]) != track->default_sample_flags)
2559  flags |= MOV_TRUN_SAMPLE_FLAGS;
2560  }
2561  if (!(flags & MOV_TRUN_SAMPLE_FLAGS))
2562  flags |= MOV_TRUN_FIRST_SAMPLE_FLAGS;
2563  if (track->flags & MOV_TRACK_CTTS)
2564  flags |= MOV_TRUN_SAMPLE_CTS;
2565 
2566  avio_wb32(pb, 0); /* size placeholder */
2567  ffio_wfourcc(pb, "trun");
2568  avio_w8(pb, 0); /* version */
2569  avio_wb24(pb, flags);
2570 
2571  avio_wb32(pb, track->entry); /* sample count */
2572  track->moof_size_offset = avio_tell(pb);
2573  avio_wb32(pb, 0); /* data offset */
2574  if (flags & MOV_TRUN_FIRST_SAMPLE_FLAGS)
2575  avio_wb32(pb, get_sample_flags(track, &track->cluster[0]));
2576 
2577  for (i = 0; i < track->entry; i++) {
2578  if (flags & MOV_TRUN_SAMPLE_DURATION)
2579  avio_wb32(pb, get_cluster_duration(track, i));
2580  if (flags & MOV_TRUN_SAMPLE_SIZE)
2581  avio_wb32(pb, track->cluster[i].size);
2582  if (flags & MOV_TRUN_SAMPLE_FLAGS)
2583  avio_wb32(pb, get_sample_flags(track, &track->cluster[i]));
2584  if (flags & MOV_TRUN_SAMPLE_CTS)
2585  avio_wb32(pb, track->cluster[i].cts);
2586  }
2587 
2588  return update_size(pb, pos);
2589 }
2590 
2592 {
2593  int64_t pos = avio_tell(pb);
2594  const uint8_t uuid[] = {
2595  0x6d, 0x1d, 0x9b, 0x05, 0x42, 0xd5, 0x44, 0xe6,
2596  0x80, 0xe2, 0x14, 0x1d, 0xaf, 0xf7, 0x57, 0xb2
2597  };
2598 
2599  avio_wb32(pb, 0); /* size placeholder */
2600  ffio_wfourcc(pb, "uuid");
2601  avio_write(pb, uuid, sizeof(uuid));
2602  avio_w8(pb, 1);
2603  avio_wb24(pb, 0);
2604  avio_wb64(pb, track->frag_start);
2605  avio_wb64(pb, track->start_dts + track->track_duration -
2606  track->cluster[0].dts);
2607 
2608  return update_size(pb, pos);
2609 }
2610 
2612  MOVTrack *track, int entry)
2613 {
2614  int n = track->nb_frag_info - 1 - entry, i;
2615  int size = 8 + 16 + 4 + 1 + 16*n;
2616  const uint8_t uuid[] = {
2617  0xd4, 0x80, 0x7e, 0xf2, 0xca, 0x39, 0x46, 0x95,
2618  0x8e, 0x54, 0x26, 0xcb, 0x9e, 0x46, 0xa7, 0x9f
2619  };
2620 
2621  if (entry < 0)
2622  return 0;
2623 
2624  avio_seek(pb, track->frag_info[entry].tfrf_offset, SEEK_SET);
2625  avio_wb32(pb, size);
2626  ffio_wfourcc(pb, "uuid");
2627  avio_write(pb, uuid, sizeof(uuid));
2628  avio_w8(pb, 1);
2629  avio_wb24(pb, 0);
2630  avio_w8(pb, n);
2631  for (i = 0; i < n; i++) {
2632  int index = entry + 1 + i;
2633  avio_wb64(pb, track->frag_info[index].time);
2634  avio_wb64(pb, track->frag_info[index].duration);
2635  }
2636  if (n < mov->ism_lookahead) {
2637  int free_size = 16*(mov->ism_lookahead - n);
2638  avio_wb32(pb, free_size);
2639  ffio_wfourcc(pb, "free");
2640  for (i = 0; i < free_size - 8; i++)
2641  avio_w8(pb, 0);
2642  }
2643 
2644  return 0;
2645 }
2646 
2648  MOVTrack *track)
2649 {
2650  int64_t pos = avio_tell(pb);
2651  int i;
2652  for (i = 0; i < mov->ism_lookahead; i++) {
2653  /* Update the tfrf tag for the last ism_lookahead fragments,
2654  * nb_frag_info - 1 is the next fragment to be written. */
2655  mov_write_tfrf_tag(pb, mov, track, track->nb_frag_info - 2 - i);
2656  }
2657  avio_seek(pb, pos, SEEK_SET);
2658  return 0;
2659 }
2660 
2662  MOVTrack *track, int64_t moof_offset)
2663 {
2664  int64_t pos = avio_tell(pb);
2665  avio_wb32(pb, 0); /* size placeholder */
2666  ffio_wfourcc(pb, "traf");
2667 
2668  mov_write_tfhd_tag(pb, track, moof_offset);
2669  mov_write_trun_tag(pb, track);
2670  if (mov->mode == MODE_ISM) {
2671  mov_write_tfxd_tag(pb, track);
2672 
2673  if (mov->ism_lookahead) {
2674  int i, size = 16 + 4 + 1 + 16*mov->ism_lookahead;
2675 
2676  track->tfrf_offset = avio_tell(pb);
2677  avio_wb32(pb, 8 + size);
2678  ffio_wfourcc(pb, "free");
2679  for (i = 0; i < size; i++)
2680  avio_w8(pb, 0);
2681  }
2682  }
2683 
2684  return update_size(pb, pos);
2685 }
2686 
2687 static int mov_write_moof_tag(AVIOContext *pb, MOVMuxContext *mov, int tracks)
2688 {
2689  int64_t pos = avio_tell(pb), end;
2690  int i, moof_size;
2691 
2692  avio_wb32(pb, 0); /* size placeholder */
2693  ffio_wfourcc(pb, "moof");
2694 
2695  mov_write_mfhd_tag(pb, mov);
2696  for (i = 0; i < mov->nb_streams; i++) {
2697  MOVTrack *track = &mov->tracks[i];
2698  if (tracks >= 0 && i != tracks)
2699  continue;
2700  if (!track->entry)
2701  continue;
2702  mov_write_traf_tag(pb, mov, track, pos);
2703  }
2704 
2705  end = avio_tell(pb);
2706  moof_size = end - pos;
2707  for (i = 0; i < mov->nb_streams; i++) {
2708  MOVTrack *track = &mov->tracks[i];
2709  if (tracks >= 0 && i != tracks)
2710  continue;
2711  if (!track->entry)
2712  continue;
2713  avio_seek(pb, mov->tracks[i].moof_size_offset, SEEK_SET);
2714  avio_wb32(pb, moof_size + 8 + mov->tracks[i].data_offset);
2715  }
2716  avio_seek(pb, end, SEEK_SET);
2717 
2718  return update_size(pb, pos);
2719 }
2720 
2722 {
2723  int64_t pos = avio_tell(pb);
2724  int i;
2725 
2726  avio_wb32(pb, 0); /* size placeholder */
2727  ffio_wfourcc(pb, "tfra");
2728  avio_w8(pb, 1); /* version */
2729  avio_wb24(pb, 0);
2730 
2731  avio_wb32(pb, track->track_id);
2732  avio_wb32(pb, 0); /* length of traf/trun/sample num */
2733  avio_wb32(pb, track->nb_frag_info);
2734  for (i = 0; i < track->nb_frag_info; i++) {
2735  avio_wb64(pb, track->frag_info[i].time);
2736  avio_wb64(pb, track->frag_info[i].offset);
2737  avio_w8(pb, 1); /* traf number */
2738  avio_w8(pb, 1); /* trun number */
2739  avio_w8(pb, 1); /* sample number */
2740  }
2741 
2742  return update_size(pb, pos);
2743 }
2744 
2746 {
2747  int64_t pos = avio_tell(pb);
2748  int i;
2749 
2750  avio_wb32(pb, 0); /* size placeholder */
2751  ffio_wfourcc(pb, "mfra");
2752  /* An empty mfra atom is enough to indicate to the publishing point that
2753  * the stream has ended. */
2754  if (mov->flags & FF_MOV_FLAG_ISML)
2755  return update_size(pb, pos);
2756 
2757  for (i = 0; i < mov->nb_streams; i++) {
2758  MOVTrack *track = &mov->tracks[i];
2759  if (track->nb_frag_info)
2760  mov_write_tfra_tag(pb, track);
2761  }
2762 
2763  avio_wb32(pb, 16);
2764  ffio_wfourcc(pb, "mfro");
2765  avio_wb32(pb, 0); /* version + flags */
2766  avio_wb32(pb, avio_tell(pb) + 4 - pos);
2767 
2768  return update_size(pb, pos);
2769 }
2770 
2772 {
2773  avio_wb32(pb, 8); // placeholder for extended size field (64 bit)
2774  ffio_wfourcc(pb, mov->mode == MODE_MOV ? "wide" : "free");
2775 
2776  mov->mdat_pos = avio_tell(pb);
2777  avio_wb32(pb, 0); /* size placeholder*/
2778  ffio_wfourcc(pb, "mdat");
2779  return 0;
2780 }
2781 
2782 /* TODO: This needs to be more general */
2784 {
2785  MOVMuxContext *mov = s->priv_data;
2786  int64_t pos = avio_tell(pb);
2787  int has_h264 = 0, has_video = 0;
2788  int minor = 0x200;
2789  int i;
2790 
2791  for (i = 0; i < s->nb_streams; i++) {
2792  AVStream *st = s->streams[i];
2793  if (st->codec->codec_type == AVMEDIA_TYPE_VIDEO)
2794  has_video = 1;
2795  if (st->codec->codec_id == AV_CODEC_ID_H264)
2796  has_h264 = 1;
2797  }
2798 
2799  avio_wb32(pb, 0); /* size */
2800  ffio_wfourcc(pb, "ftyp");
2801 
2802  if (mov->mode == MODE_3GP) {
2803  ffio_wfourcc(pb, has_h264 ? "3gp6" : "3gp4");
2804  minor = has_h264 ? 0x100 : 0x200;
2805  } else if (mov->mode & MODE_3G2) {
2806  ffio_wfourcc(pb, has_h264 ? "3g2b" : "3g2a");
2807  minor = has_h264 ? 0x20000 : 0x10000;
2808  }else if (mov->mode == MODE_PSP)
2809  ffio_wfourcc(pb, "MSNV");
2810  else if (mov->mode == MODE_MP4)
2811  ffio_wfourcc(pb, "isom");
2812  else if (mov->mode == MODE_IPOD)
2813  ffio_wfourcc(pb, has_video ? "M4V ":"M4A ");
2814  else if (mov->mode == MODE_ISM)
2815  ffio_wfourcc(pb, "isml");
2816  else if (mov->mode == MODE_F4V)
2817  ffio_wfourcc(pb, "f4v ");
2818  else
2819  ffio_wfourcc(pb, "qt ");
2820 
2821  avio_wb32(pb, minor);
2822 
2823  if(mov->mode == MODE_MOV)
2824  ffio_wfourcc(pb, "qt ");
2825  else if (mov->mode == MODE_ISM) {
2826  ffio_wfourcc(pb, "piff");
2827  ffio_wfourcc(pb, "iso2");
2828  } else {
2829  ffio_wfourcc(pb, "isom");
2830  ffio_wfourcc(pb, "iso2");
2831  if(has_h264)
2832  ffio_wfourcc(pb, "avc1");
2833  }
2834 
2835  if (mov->mode == MODE_3GP)
2836  ffio_wfourcc(pb, has_h264 ? "3gp6":"3gp4");
2837  else if (mov->mode & MODE_3G2)
2838  ffio_wfourcc(pb, has_h264 ? "3g2b":"3g2a");
2839  else if (mov->mode == MODE_PSP)
2840  ffio_wfourcc(pb, "MSNV");
2841  else if (mov->mode == MODE_MP4)
2842  ffio_wfourcc(pb, "mp41");
2843  return update_size(pb, pos);
2844 }
2845 
2847 {
2848  AVCodecContext *video_codec = s->streams[0]->codec;
2849  AVCodecContext *audio_codec = s->streams[1]->codec;
2850  int audio_rate = audio_codec->sample_rate;
2851  int frame_rate = ((video_codec->time_base.den) * (0x10000))/ (video_codec->time_base.num);
2852  int audio_kbitrate = audio_codec->bit_rate / 1000;
2853  int video_kbitrate = FFMIN(video_codec->bit_rate / 1000, 800 - audio_kbitrate);
2854 
2855  avio_wb32(pb, 0x94); /* size */
2856  ffio_wfourcc(pb, "uuid");
2857  ffio_wfourcc(pb, "PROF");
2858 
2859  avio_wb32(pb, 0x21d24fce); /* 96 bit UUID */
2860  avio_wb32(pb, 0xbb88695c);
2861  avio_wb32(pb, 0xfac9c740);
2862 
2863  avio_wb32(pb, 0x0); /* ? */
2864  avio_wb32(pb, 0x3); /* 3 sections ? */
2865 
2866  avio_wb32(pb, 0x14); /* size */
2867  ffio_wfourcc(pb, "FPRF");
2868  avio_wb32(pb, 0x0); /* ? */
2869  avio_wb32(pb, 0x0); /* ? */
2870  avio_wb32(pb, 0x0); /* ? */
2871 
2872  avio_wb32(pb, 0x2c); /* size */
2873  ffio_wfourcc(pb, "APRF");/* audio */
2874  avio_wb32(pb, 0x0);
2875  avio_wb32(pb, 0x2); /* TrackID */
2876  ffio_wfourcc(pb, "mp4a");
2877  avio_wb32(pb, 0x20f);
2878  avio_wb32(pb, 0x0);
2879  avio_wb32(pb, audio_kbitrate);
2880  avio_wb32(pb, audio_kbitrate);
2881  avio_wb32(pb, audio_rate);
2882  avio_wb32(pb, audio_codec->channels);
2883 
2884  avio_wb32(pb, 0x34); /* size */
2885  ffio_wfourcc(pb, "VPRF"); /* video */
2886  avio_wb32(pb, 0x0);
2887  avio_wb32(pb, 0x1); /* TrackID */
2888  if (video_codec->codec_id == AV_CODEC_ID_H264) {
2889  ffio_wfourcc(pb, "avc1");
2890  avio_wb16(pb, 0x014D);
2891  avio_wb16(pb, 0x0015);
2892  } else {
2893  ffio_wfourcc(pb, "mp4v");
2894  avio_wb16(pb, 0x0000);
2895  avio_wb16(pb, 0x0103);
2896  }
2897  avio_wb32(pb, 0x0);
2898  avio_wb32(pb, video_kbitrate);
2899  avio_wb32(pb, video_kbitrate);
2900  avio_wb32(pb, frame_rate);
2901  avio_wb32(pb, frame_rate);
2902  avio_wb16(pb, video_codec->width);
2903  avio_wb16(pb, video_codec->height);
2904  avio_wb32(pb, 0x010001); /* ? */
2905 }
2906 
2907 static int mov_parse_mpeg2_frame(AVPacket *pkt, uint32_t *flags)
2908 {
2909  uint32_t c = -1;
2910  int i, closed_gop = 0;
2911 
2912  for (i = 0; i < pkt->size - 4; i++) {
2913  c = (c<<8) + pkt->data[i];
2914  if (c == 0x1b8) { // gop
2915  closed_gop = pkt->data[i+4]>>6 & 0x01;
2916  } else if (c == 0x100) { // pic
2917  int temp_ref = (pkt->data[i+1]<<2) | (pkt->data[i+2]>>6);
2918  if (!temp_ref || closed_gop) // I picture is not reordered
2919  *flags = MOV_SYNC_SAMPLE;
2920  else
2921  *flags = MOV_PARTIAL_SYNC_SAMPLE;
2922  break;
2923  }
2924  }
2925  return 0;
2926 }
2927 
2928 static void mov_parse_vc1_frame(AVPacket *pkt, MOVTrack *trk, int fragment)
2929 {
2930  const uint8_t *start, *next, *end = pkt->data + pkt->size;
2931  int seq = 0, entry = 0;
2932  int key = pkt->flags & AV_PKT_FLAG_KEY;
2933  start = find_next_marker(pkt->data, end);
2934  for (next = start; next < end; start = next) {
2935  next = find_next_marker(start + 4, end);
2936  switch (AV_RB32(start)) {
2937  case VC1_CODE_SEQHDR:
2938  seq = 1;
2939  break;
2940  case VC1_CODE_ENTRYPOINT:
2941  entry = 1;
2942  break;
2943  case VC1_CODE_SLICE:
2944  trk->vc1_info.slices = 1;
2945  break;
2946  }
2947  }
2948  if (!trk->entry && !fragment) {
2949  /* First packet in first fragment */
2950  trk->vc1_info.first_packet_seq = seq;
2951  trk->vc1_info.first_packet_entry = entry;
2952  } else if ((seq && !trk->vc1_info.packet_seq) ||
2953  (entry && !trk->vc1_info.packet_entry)) {
2954  int i;
2955  for (i = 0; i < trk->entry; i++)
2956  trk->cluster[i].flags &= ~MOV_SYNC_SAMPLE;
2957  trk->has_keyframes = 0;
2958  if (seq)
2959  trk->vc1_info.packet_seq = 1;
2960  if (entry)
2961  trk->vc1_info.packet_entry = 1;
2962  if (!fragment) {
2963  /* First fragment */
2964  if ((!seq || trk->vc1_info.first_packet_seq) &&
2965  (!entry || trk->vc1_info.first_packet_entry)) {
2966  /* First packet had the same headers as this one, readd the
2967  * sync sample flag. */
2968  trk->cluster[0].flags |= MOV_SYNC_SAMPLE;
2969  trk->has_keyframes = 1;
2970  }
2971  }
2972  }
2973  if (trk->vc1_info.packet_seq && trk->vc1_info.packet_entry)
2974  key = seq && entry;
2975  else if (trk->vc1_info.packet_seq)
2976  key = seq;
2977  else if (trk->vc1_info.packet_entry)
2978  key = entry;
2979  if (key) {
2980  trk->cluster[trk->entry].flags |= MOV_SYNC_SAMPLE;
2981  trk->has_keyframes++;
2982  }
2983 }
2984 
2986 {
2987  int ret;
2988  uint8_t *buf;
2989  AVIOContext *moov_buf;
2990  MOVMuxContext *mov = s->priv_data;
2991 
2992  if ((ret = avio_open_dyn_buf(&moov_buf)) < 0)
2993  return ret;
2994  mov_write_moov_tag(moov_buf, mov, s);
2995  ret = avio_close_dyn_buf(moov_buf, &buf);
2996  av_free(buf);
2997  return ret;
2998 }
2999 
3001 {
3002  MOVMuxContext *mov = s->priv_data;
3003  int i, first_track = -1;
3004  int64_t mdat_size = 0;
3005 
3006  if (!(mov->flags & FF_MOV_FLAG_FRAGMENT))
3007  return 0;
3008 
3009  if (!(mov->flags & FF_MOV_FLAG_EMPTY_MOOV) && mov->fragments == 0) {
3010  int64_t pos = avio_tell(s->pb);
3011  uint8_t *buf;
3012  int buf_size, moov_size;
3013 
3014  for (i = 0; i < mov->nb_streams; i++)
3015  if (!mov->tracks[i].entry)
3016  break;
3017  /* Don't write the initial moov unless all tracks have data */
3018  if (i < mov->nb_streams)
3019  return 0;
3020 
3021  moov_size = get_moov_size(s);
3022  for (i = 0; i < mov->nb_streams; i++)
3023  mov->tracks[i].data_offset = pos + moov_size + 8;
3024 
3025  mov_write_moov_tag(s->pb, mov, s);
3026 
3027  buf_size = avio_close_dyn_buf(mov->mdat_buf, &buf);
3028  mov->mdat_buf = NULL;
3029  avio_wb32(s->pb, buf_size + 8);
3030  ffio_wfourcc(s->pb, "mdat");
3031  avio_write(s->pb, buf, buf_size);
3032  av_free(buf);
3033 
3034  mov->fragments++;
3035  mov->mdat_size = 0;
3036  for (i = 0; i < mov->nb_streams; i++) {
3037  if (mov->tracks[i].entry)
3038  mov->tracks[i].frag_start += mov->tracks[i].start_dts +
3039  mov->tracks[i].track_duration -
3040  mov->tracks[i].cluster[0].dts;
3041  mov->tracks[i].entry = 0;
3042  }
3043  avio_flush(s->pb);
3044  return 0;
3045  }
3046 
3047  for (i = 0; i < mov->nb_streams; i++) {
3048  MOVTrack *track = &mov->tracks[i];
3049  if (mov->flags & FF_MOV_FLAG_SEPARATE_MOOF)
3050  track->data_offset = 0;
3051  else
3052  track->data_offset = mdat_size;
3053  if (!track->mdat_buf)
3054  continue;
3055  mdat_size += avio_tell(track->mdat_buf);
3056  if (first_track < 0)
3057  first_track = i;
3058  }
3059 
3060  if (!mdat_size)
3061  return 0;
3062 
3063  for (i = 0; i < mov->nb_streams; i++) {
3064  MOVTrack *track = &mov->tracks[i];
3065  int buf_size, write_moof = 1, moof_tracks = -1;
3066  uint8_t *buf;
3067  int64_t duration = 0;
3068 
3069  if (track->entry)
3070  duration = track->start_dts + track->track_duration -
3071  track->cluster[0].dts;
3072  if (mov->flags & FF_MOV_FLAG_SEPARATE_MOOF) {
3073  if (!track->mdat_buf)
3074  continue;
3075  mdat_size = avio_tell(track->mdat_buf);
3076  moof_tracks = i;
3077  } else {
3078  write_moof = i == first_track;
3079  }
3080 
3081  if (write_moof) {
3083  avio_flush(s->pb);
3084  track->nb_frag_info++;
3085  track->frag_info = av_realloc(track->frag_info,
3086  sizeof(*track->frag_info) *
3087  track->nb_frag_info);
3088  info = &track->frag_info[track->nb_frag_info - 1];
3089  info->offset = avio_tell(s->pb);
3090  info->time = mov->tracks[i].frag_start;
3091  info->duration = duration;
3092  mov_write_tfrf_tags(s->pb, mov, track);
3093 
3094  mov_write_moof_tag(s->pb, mov, moof_tracks);
3095  info->tfrf_offset = track->tfrf_offset;
3096  mov->fragments++;
3097 
3098  avio_wb32(s->pb, mdat_size + 8);
3099  ffio_wfourcc(s->pb, "mdat");
3100  }
3101 
3102  if (track->entry)
3103  track->frag_start += duration;
3104  track->entry = 0;
3105  if (!track->mdat_buf)
3106  continue;
3107  buf_size = avio_close_dyn_buf(track->mdat_buf, &buf);
3108  track->mdat_buf = NULL;
3109 
3110  avio_write(s->pb, buf, buf_size);
3111  av_free(buf);
3112  }
3113 
3114  mov->mdat_size = 0;
3115 
3116  avio_flush(s->pb);
3117  return 0;
3118 }
3119 
3121 {
3122  MOVMuxContext *mov = s->priv_data;
3123  AVIOContext *pb = s->pb;
3124  MOVTrack *trk = &mov->tracks[pkt->stream_index];
3125  AVCodecContext *enc = trk->enc;
3126  unsigned int samples_in_chunk = 0;
3127  int size= pkt->size;
3128  uint8_t *reformatted_data = NULL;
3129 
3130  if (mov->flags & FF_MOV_FLAG_FRAGMENT) {
3131  int ret;
3132  if (mov->fragments > 0) {
3133  if (!trk->mdat_buf) {
3134  if ((ret = avio_open_dyn_buf(&trk->mdat_buf)) < 0)
3135  return ret;
3136  }
3137  pb = trk->mdat_buf;
3138  } else {
3139  if (!mov->mdat_buf) {
3140  if ((ret = avio_open_dyn_buf(&mov->mdat_buf)) < 0)
3141  return ret;
3142  }
3143  pb = mov->mdat_buf;
3144  }
3145  }
3146 
3147  if (enc->codec_id == AV_CODEC_ID_AMR_NB) {
3148  /* We must find out how many AMR blocks there are in one packet */
3149  static uint16_t packed_size[16] =
3150  {13, 14, 16, 18, 20, 21, 27, 32, 6, 0, 0, 0, 0, 0, 0, 1};
3151  int len = 0;
3152 
3153  while (len < size && samples_in_chunk < 100) {
3154  len += packed_size[(pkt->data[len] >> 3) & 0x0F];
3155  samples_in_chunk++;
3156  }
3157  if (samples_in_chunk > 1) {
3158  av_log(s, AV_LOG_ERROR, "fatal error, input is not a single packet, implement a AVParser for it\n");
3159  return -1;
3160  }
3161  } else if (enc->codec_id == AV_CODEC_ID_ADPCM_MS ||
3163  samples_in_chunk = enc->frame_size;
3164  } else if (trk->sample_size)
3165  samples_in_chunk = size / trk->sample_size;
3166  else
3167  samples_in_chunk = 1;
3168 
3169  /* copy extradata if it exists */
3170  if (trk->vos_len == 0 && enc->extradata_size > 0) {
3171  trk->vos_len = enc->extradata_size;
3172  trk->vos_data = av_malloc(trk->vos_len);
3173  memcpy(trk->vos_data, enc->extradata, trk->vos_len);
3174  }
3175 
3176  if (enc->codec_id == AV_CODEC_ID_AAC && pkt->size > 2 &&
3177  (AV_RB16(pkt->data) & 0xfff0) == 0xfff0) {
3178  if (!s->streams[pkt->stream_index]->nb_frames) {
3179  av_log(s, AV_LOG_ERROR, "malformated aac bitstream, use -absf aac_adtstoasc\n");
3180  return -1;
3181  }
3182  av_log(s, AV_LOG_WARNING, "aac bitstream error\n");
3183  }
3184  if (enc->codec_id == AV_CODEC_ID_H264 && trk->vos_len > 0 && *(uint8_t *)trk->vos_data != 1) {
3185  /* from x264 or from bytestream h264 */
3186  /* nal reformating needed */
3187  if (trk->hint_track >= 0 && trk->hint_track < mov->nb_streams) {
3188  ff_avc_parse_nal_units_buf(pkt->data, &reformatted_data,
3189  &size);
3190  avio_write(pb, reformatted_data, size);
3191  } else {
3192  size = ff_avc_parse_nal_units(pb, pkt->data, pkt->size);
3193  }
3194  } else {
3195  avio_write(pb, pkt->data, size);
3196  }
3197 
3198  if ((enc->codec_id == AV_CODEC_ID_DNXHD ||
3199  enc->codec_id == AV_CODEC_ID_AC3) && !trk->vos_len) {
3200  /* copy frame to create needed atoms */
3201  trk->vos_len = size;
3202  trk->vos_data = av_malloc(size);
3203  if (!trk->vos_data)
3204  return AVERROR(ENOMEM);
3205  memcpy(trk->vos_data, pkt->data, size);
3206  }
3207 
3208  if (!(trk->entry % MOV_INDEX_CLUSTER_SIZE)) {
3209  trk->cluster = av_realloc_f(trk->cluster, sizeof(*trk->cluster), (trk->entry + MOV_INDEX_CLUSTER_SIZE));
3210  if (!trk->cluster)
3211  return -1;
3212  }
3213 
3214  trk->cluster[trk->entry].pos = avio_tell(pb) - size;
3215  trk->cluster[trk->entry].samples_in_chunk = samples_in_chunk;
3216  trk->cluster[trk->entry].chunkNum = 0;
3217  trk->cluster[trk->entry].size = size;
3218  trk->cluster[trk->entry].entries = samples_in_chunk;
3219  trk->cluster[trk->entry].dts = pkt->dts;
3220  if (!trk->entry && trk->start_dts != AV_NOPTS_VALUE) {
3221  /* First packet of a new fragment. We already wrote the duration
3222  * of the last packet of the previous fragment based on track_duration,
3223  * which might not exactly match our dts. Therefore adjust the dts
3224  * of this packet to be what the previous packets duration implies. */
3225  trk->cluster[trk->entry].dts = trk->start_dts + trk->track_duration;
3226  }
3227  if (!trk->entry && trk->start_dts == AV_NOPTS_VALUE && !supports_edts(mov)) {
3228  trk->cluster[trk->entry].dts = trk->start_dts = 0;
3229  }
3230  if (trk->start_dts == AV_NOPTS_VALUE)
3231  trk->start_dts = pkt->dts;
3232  trk->track_duration = pkt->dts - trk->start_dts + pkt->duration;
3233  trk->last_sample_is_subtitle_end = 0;
3234 
3235  if (pkt->pts == AV_NOPTS_VALUE) {
3236  av_log(s, AV_LOG_WARNING, "pts has no value\n");
3237  pkt->pts = pkt->dts;
3238  }
3239  if (pkt->dts != pkt->pts)
3240  trk->flags |= MOV_TRACK_CTTS;
3241  trk->cluster[trk->entry].cts = pkt->pts - pkt->dts;
3242  trk->cluster[trk->entry].flags = 0;
3243  if (enc->codec_id == AV_CODEC_ID_VC1) {
3244  mov_parse_vc1_frame(pkt, trk, mov->fragments);
3245  } else if (pkt->flags & AV_PKT_FLAG_KEY) {
3246  if (mov->mode == MODE_MOV && enc->codec_id == AV_CODEC_ID_MPEG2VIDEO &&
3247  trk->entry > 0) { // force sync sample for the first key frame
3248  mov_parse_mpeg2_frame(pkt, &trk->cluster[trk->entry].flags);
3249  if (trk->cluster[trk->entry].flags & MOV_PARTIAL_SYNC_SAMPLE)
3250  trk->flags |= MOV_TRACK_STPS;
3251  } else {
3252  trk->cluster[trk->entry].flags = MOV_SYNC_SAMPLE;
3253  }
3254  if (trk->cluster[trk->entry].flags & MOV_SYNC_SAMPLE)
3255  trk->has_keyframes++;
3256  }
3257  trk->entry++;
3258  trk->sample_count += samples_in_chunk;
3259  mov->mdat_size += size;
3260 
3261  avio_flush(pb);
3262 
3263  if (trk->hint_track >= 0 && trk->hint_track < mov->nb_streams)
3264  ff_mov_add_hinted_packet(s, pkt, trk->hint_track, trk->entry,
3265  reformatted_data, size);
3266  av_free(reformatted_data);
3267  return 0;
3268 }
3269 
3271 {
3272  MOVMuxContext *mov = s->priv_data;
3273  MOVTrack *trk = &mov->tracks[pkt->stream_index];
3274  AVCodecContext *enc = trk->enc;
3275  int64_t frag_duration = 0;
3276  int size = pkt->size;
3277 
3278  if (!pkt->size) return 0; /* Discard 0 sized packets */
3279 
3280  if (trk->entry && pkt->stream_index < s->nb_streams)
3281  frag_duration = av_rescale_q(pkt->dts - trk->cluster[0].dts,
3282  s->streams[pkt->stream_index]->time_base,
3283  AV_TIME_BASE_Q);
3284  if ((mov->max_fragment_duration &&
3285  frag_duration >= mov->max_fragment_duration) ||
3286  (mov->max_fragment_size && mov->mdat_size + size >= mov->max_fragment_size) ||
3287  (mov->flags & FF_MOV_FLAG_FRAG_KEYFRAME &&
3288  enc->codec_type == AVMEDIA_TYPE_VIDEO &&
3289  trk->entry && pkt->flags & AV_PKT_FLAG_KEY)) {
3290  if (frag_duration >= mov->min_fragment_duration)
3291  mov_flush_fragment(s);
3292  }
3293 
3294  return ff_mov_write_packet(s, pkt);
3295 }
3296 
3298  int stream_index,
3299  int64_t dts) {
3300  AVPacket end;
3301  uint8_t data[2] = {0};
3302  int ret;
3303 
3304  av_init_packet(&end);
3305  end.size = sizeof(data);
3306  end.data = data;
3307  end.pts = dts;
3308  end.dts = dts;
3309  end.duration = 0;
3310  end.stream_index = stream_index;
3311 
3312  ret = mov_write_single_packet(s, &end);
3313  av_free_packet(&end);
3314 
3315  return ret;
3316 }
3317 
3319 {
3320  if (!pkt) {
3321  mov_flush_fragment(s);
3322  return 1;
3323  } else {
3324  int i;
3325  MOVMuxContext *mov = s->priv_data;
3326 
3327  if (!pkt->size) return 0; /* Discard 0 sized packets */
3328 
3329  /*
3330  * Subtitles require special handling.
3331  *
3332  * 1) For full complaince, every track must have a sample at
3333  * dts == 0, which is rarely true for subtitles. So, as soon
3334  * as we see any packet with dts > 0, write an empty subtitle
3335  * at dts == 0 for any subtitle track with no samples in it.
3336  *
3337  * 2) For each subtitle track, check if the current packet's
3338  * dts is past the duration of the last subtitle sample. If
3339  * so, we now need to write an end sample for that subtitle.
3340  *
3341  * This must be done conditionally to allow for subtitles that
3342  * immediately replace each other, in which case an end sample
3343  * is not needed, and is, in fact, actively harmful.
3344  *
3345  * 3) See mov_write_trailer for how the final end sample is
3346  * handled.
3347  */
3348  for (i = 0; i < mov->nb_streams; i++) {
3349  MOVTrack *trk = &mov->tracks[i];
3350  int ret;
3351 
3352  if (trk->enc->codec_id == AV_CODEC_ID_MOV_TEXT &&
3353  trk->track_duration < pkt->dts &&
3354  (trk->entry == 0 || !trk->last_sample_is_subtitle_end)) {
3356  if (ret < 0) return ret;
3357  trk->last_sample_is_subtitle_end = 1;
3358  }
3359  }
3360 
3361  return mov_write_single_packet(s, pkt);
3362  }
3363 }
3364 
3365 // QuickTime chapters involve an additional text track with the chapter names
3366 // as samples, and a tref pointing from the other tracks to the chapter one.
3367 static void mov_create_chapter_track(AVFormatContext *s, int tracknum)
3368 {
3369  AVIOContext *pb;
3370 
3371  MOVMuxContext *mov = s->priv_data;
3372  MOVTrack *track = &mov->tracks[tracknum];
3373  AVPacket pkt = { .stream_index = tracknum, .flags = AV_PKT_FLAG_KEY };
3374  int i, len;
3375 
3376  track->mode = mov->mode;
3377  track->tag = MKTAG('t','e','x','t');
3378  track->timescale = MOV_TIMESCALE;
3379  track->enc = avcodec_alloc_context3(NULL);
3381 
3382  if (avio_open_dyn_buf(&pb) >= 0) {
3383  int size;
3384  uint8_t *buf;
3385 
3386  /* Stub header (usually for Quicktime chapter track) */
3387  // TextSampleEntry
3388  avio_wb32(pb, 0x01); // displayFlags
3389  avio_w8(pb, 0x00); // horizontal justification
3390  avio_w8(pb, 0x00); // vertical justification
3391  avio_w8(pb, 0x00); // bgColourRed
3392  avio_w8(pb, 0x00); // bgColourGreen
3393  avio_w8(pb, 0x00); // bgColourBlue
3394  avio_w8(pb, 0x00); // bgColourAlpha
3395  // BoxRecord
3396  avio_wb16(pb, 0x00); // defTextBoxTop
3397  avio_wb16(pb, 0x00); // defTextBoxLeft
3398  avio_wb16(pb, 0x00); // defTextBoxBottom
3399  avio_wb16(pb, 0x00); // defTextBoxRight
3400  // StyleRecord
3401  avio_wb16(pb, 0x00); // startChar
3402  avio_wb16(pb, 0x00); // endChar
3403  avio_wb16(pb, 0x01); // fontID
3404  avio_w8(pb, 0x00); // fontStyleFlags
3405  avio_w8(pb, 0x00); // fontSize
3406  avio_w8(pb, 0x00); // fgColourRed
3407  avio_w8(pb, 0x00); // fgColourGreen
3408  avio_w8(pb, 0x00); // fgColourBlue
3409  avio_w8(pb, 0x00); // fgColourAlpha
3410  // FontTableBox
3411  avio_wb32(pb, 0x0D); // box size
3412  ffio_wfourcc(pb, "ftab"); // box atom name
3413  avio_wb16(pb, 0x01); // entry count
3414  // FontRecord
3415  avio_wb16(pb, 0x01); // font ID
3416  avio_w8(pb, 0x00); // font name length
3417 
3418  if ((size = avio_close_dyn_buf(pb, &buf)) > 0) {
3419  track->enc->extradata = buf;
3420  track->enc->extradata_size = size;
3421  } else {
3422  av_free(&buf);
3423  }
3424  }
3425 
3426  for (i = 0; i < s->nb_chapters; i++) {
3427  AVChapter *c = s->chapters[i];
3429 
3430  int64_t end = av_rescale_q(c->end, c->time_base, (AVRational){1,MOV_TIMESCALE});
3431  pkt.pts = pkt.dts = av_rescale_q(c->start, c->time_base, (AVRational){1,MOV_TIMESCALE});
3432  pkt.duration = end - pkt.dts;
3433 
3434  if ((t = av_dict_get(c->metadata, "title", NULL, 0))) {
3435  len = strlen(t->value);
3436  pkt.size = len+2;
3437  pkt.data = av_malloc(pkt.size);
3438  AV_WB16(pkt.data, len);
3439  memcpy(pkt.data+2, t->value, len);
3440  ff_mov_write_packet(s, &pkt);
3441  av_freep(&pkt.data);
3442  }
3443  }
3444 }
3445 
3446 static int mov_create_timecode_track(AVFormatContext *s, int index, int src_index, const char *tcstr)
3447 {
3448  int ret;
3449  MOVMuxContext *mov = s->priv_data;
3450  MOVTrack *track = &mov->tracks[index];
3451  AVStream *src_st = s->streams[src_index];
3452  AVTimecode tc;
3453  AVPacket pkt = {.stream_index = index, .flags = AV_PKT_FLAG_KEY, .size = 4};
3454  AVRational rate = {src_st->codec->time_base.den, src_st->codec->time_base.num};
3455 
3456  /* if the codec time base makes no sense, try to fallback on stream frame rate */
3457  if (av_timecode_check_frame_rate(rate) < 0) {
3458  av_log(s, AV_LOG_DEBUG, "timecode: tbc=%d/%d invalid, fallback on %d/%d\n",
3459  rate.num, rate.den, src_st->avg_frame_rate.num, src_st->avg_frame_rate.den);
3460  rate = src_st->avg_frame_rate;
3461  }
3462 
3463  /* compute the frame number */
3464  ret = av_timecode_init_from_string(&tc, rate, tcstr, s);
3465  if (ret < 0)
3466  return ret;
3467 
3468  /* tmcd track based on video stream */
3469  track->mode = mov->mode;
3470  track->tag = MKTAG('t','m','c','d');
3471  track->src_track = src_index;
3472  track->timescale = mov->tracks[src_index].timescale;
3475 
3476  /* encode context: tmcd data stream */
3477  track->enc = avcodec_alloc_context3(NULL);
3478  track->enc->codec_type = AVMEDIA_TYPE_DATA;
3479  track->enc->codec_tag = track->tag;
3480  track->enc->time_base = src_st->codec->time_base;
3481 
3482  /* the tmcd track just contains one packet with the frame number */
3483  pkt.data = av_malloc(pkt.size);
3484  AV_WB32(pkt.data, tc.start);
3485  ret = ff_mov_write_packet(s, &pkt);
3486  av_free(pkt.data);
3487  return ret;
3488 }
3489 
3491 {
3492  AVIOContext *pb = s->pb;
3493  MOVMuxContext *mov = s->priv_data;
3494  AVDictionaryEntry *t, *global_tcr = av_dict_get(s->metadata, "timecode", NULL, 0);
3495  int i, hint_track = 0, tmcd_track = 0;
3496 
3497  /* Set the FRAGMENT flag if any of the fragmentation methods are
3498  * enabled. */
3499  if (mov->max_fragment_duration || mov->max_fragment_size ||
3500  mov->flags & (FF_MOV_FLAG_EMPTY_MOOV |
3503  mov->flags |= FF_MOV_FLAG_FRAGMENT;
3504 
3505  /* faststart: moov at the beginning of the file, if supported */
3506  if (mov->flags & FF_MOV_FLAG_FASTSTART) {
3507  if (mov->flags & FF_MOV_FLAG_FRAGMENT)
3508  mov->flags &= ~FF_MOV_FLAG_FASTSTART;
3509  else
3510  mov->reserved_moov_size = -1;
3511  }
3512 
3513  if (!supports_edts(mov) && s->avoid_negative_ts < 0) {
3514  s->avoid_negative_ts = 1;
3515  }
3516 
3517  /* Non-seekable output is ok if using fragmentation. If ism_lookahead
3518  * is enabled, we don't support non-seekable output at all. */
3519  if (!s->pb->seekable &&
3520  ((!(mov->flags & FF_MOV_FLAG_FRAGMENT) &&
3521  !(s->oformat && !strcmp(s->oformat->name, "ismv")))
3522  || mov->ism_lookahead)) {
3523  av_log(s, AV_LOG_ERROR, "muxer does not support non seekable output\n");
3524  return -1;
3525  }
3526 
3527  /* Default mode == MP4 */
3528  mov->mode = MODE_MP4;
3529 
3530  if (s->oformat != NULL) {
3531  if (!strcmp("3gp", s->oformat->name)) mov->mode = MODE_3GP;
3532  else if (!strcmp("3g2", s->oformat->name)) mov->mode = MODE_3GP|MODE_3G2;
3533  else if (!strcmp("mov", s->oformat->name)) mov->mode = MODE_MOV;
3534  else if (!strcmp("psp", s->oformat->name)) mov->mode = MODE_PSP;
3535  else if (!strcmp("ipod",s->oformat->name)) mov->mode = MODE_IPOD;
3536  else if (!strcmp("ismv",s->oformat->name)) mov->mode = MODE_ISM;
3537  else if (!strcmp("f4v", s->oformat->name)) mov->mode = MODE_F4V;
3538 
3539  mov_write_ftyp_tag(pb,s);
3540  if (mov->mode == MODE_PSP) {
3541  if (s->nb_streams != 2) {
3542  av_log(s, AV_LOG_ERROR, "PSP mode need one video and one audio stream\n");
3543  return -1;
3544  }
3545  mov_write_uuidprof_tag(pb,s);
3546  }
3547  }
3548 
3549  mov->nb_streams = s->nb_streams;
3550  if (mov->mode & (MODE_MOV|MODE_IPOD) && s->nb_chapters)
3551  mov->chapter_track = mov->nb_streams++;
3552 
3553  if (mov->flags & FF_MOV_FLAG_RTP_HINT) {
3554  /* Add hint tracks for each audio and video stream */
3555  hint_track = mov->nb_streams;
3556  for (i = 0; i < s->nb_streams; i++) {
3557  AVStream *st = s->streams[i];
3558  if (st->codec->codec_type == AVMEDIA_TYPE_VIDEO ||
3560  mov->nb_streams++;
3561  }
3562  }
3563  }
3564 
3565  if (mov->mode == MODE_MOV) {
3566  tmcd_track = mov->nb_streams;
3567 
3568  /* +1 tmcd track for each video stream with a timecode */
3569  for (i = 0; i < s->nb_streams; i++) {
3570  AVStream *st = s->streams[i];
3571  if (st->codec->codec_type == AVMEDIA_TYPE_VIDEO &&
3572  (global_tcr || av_dict_get(st->metadata, "timecode", NULL, 0)))
3573  mov->nb_meta_tmcd++;
3574  }
3575 
3576  /* check if there is already a tmcd track to remux */
3577  if (mov->nb_meta_tmcd) {
3578  for (i = 0; i < s->nb_streams; i++) {
3579  AVStream *st = s->streams[i];
3580  if (st->codec->codec_tag == MKTAG('t','m','c','d')) {
3581  av_log(s, AV_LOG_WARNING, "You requested a copy of the original timecode track "
3582  "so timecode metadata are now ignored\n");
3583  mov->nb_meta_tmcd = 0;
3584  }
3585  }
3586  }
3587 
3588  mov->nb_streams += mov->nb_meta_tmcd;
3589  }
3590 
3591  mov->tracks = av_mallocz(mov->nb_streams*sizeof(*mov->tracks));
3592  if (!mov->tracks)
3593  return AVERROR(ENOMEM);
3594 
3595  for(i=0; i<s->nb_streams; i++){
3596  AVStream *st= s->streams[i];
3597  MOVTrack *track= &mov->tracks[i];
3598  AVDictionaryEntry *lang = av_dict_get(st->metadata, "language", NULL,0);
3599 
3600  track->enc = st->codec;
3601  track->language = ff_mov_iso639_to_lang(lang?lang->value:"und", mov->mode!=MODE_MOV);
3602  if (track->language < 0)
3603  track->language = 0;
3604  track->mode = mov->mode;
3605  track->tag = mov_find_codec_tag(s, track);
3606  if (!track->tag) {
3607  av_log(s, AV_LOG_ERROR, "track %d: could not find tag, "
3608  "codec not currently supported in container\n", i);
3609  goto error;
3610  }
3611  /* If hinting of this track is enabled by a later hint track,
3612  * this is updated. */
3613  track->hint_track = -1;
3614  track->start_dts = AV_NOPTS_VALUE;
3615  if(st->codec->codec_type == AVMEDIA_TYPE_VIDEO){
3616  if (track->tag == MKTAG('m','x','3','p') || track->tag == MKTAG('m','x','3','n') ||
3617  track->tag == MKTAG('m','x','4','p') || track->tag == MKTAG('m','x','4','n') ||
3618  track->tag == MKTAG('m','x','5','p') || track->tag == MKTAG('m','x','5','n')) {
3619  if (st->codec->width != 720 || (st->codec->height != 608 && st->codec->height != 512)) {
3620  av_log(s, AV_LOG_ERROR, "D-10/IMX must use 720x608 or 720x512 video resolution\n");
3621  goto error;
3622  }
3623  track->height = track->tag>>24 == 'n' ? 486 : 576;
3624  }
3625  track->timescale = st->codec->time_base.den;
3626  while(track->timescale < 10000)
3627  track->timescale *= 2;
3628  if (track->mode == MODE_MOV && track->timescale > 100000)
3630  "WARNING codec timebase is very high. If duration is too long,\n"
3631  "file may not be playable by quicktime. Specify a shorter timebase\n"
3632  "or choose different container.\n");
3633  }else if(st->codec->codec_type == AVMEDIA_TYPE_AUDIO){
3634  track->timescale = st->codec->sample_rate;
3635  if(!st->codec->frame_size && !av_get_bits_per_sample(st->codec->codec_id)) {
3636  av_log(s, AV_LOG_WARNING, "track %d: codec frame size is not set\n", i);
3637  track->audio_vbr = 1;
3638  }else if(st->codec->codec_id == AV_CODEC_ID_ADPCM_MS ||
3640  st->codec->codec_id == AV_CODEC_ID_ILBC){
3641  if (!st->codec->block_align) {
3642  av_log(s, AV_LOG_ERROR, "track %d: codec block align is not set for adpcm\n", i);
3643  goto error;
3644  }
3645  track->sample_size = st->codec->block_align;
3646  }else if(st->codec->frame_size > 1){ /* assume compressed audio */
3647  track->audio_vbr = 1;
3648  }else{
3649  track->sample_size = (av_get_bits_per_sample(st->codec->codec_id) >> 3) * st->codec->channels;
3650  }
3651  if (track->mode != MODE_MOV &&
3652  track->enc->codec_id == AV_CODEC_ID_MP3 && track->timescale < 16000) {
3653  av_log(s, AV_LOG_ERROR, "track %d: muxing mp3 at %dhz is not supported\n",
3654  i, track->enc->sample_rate);
3655  goto error;
3656  }
3657  }else if(st->codec->codec_type == AVMEDIA_TYPE_SUBTITLE){
3658  track->timescale = st->codec->time_base.den;
3659  }else{
3660  track->timescale = MOV_TIMESCALE;
3661  }
3662  if (!track->height)
3663  track->height = st->codec->height;
3664  /* The ism specific timescale isn't mandatory, but is assumed by
3665  * some tools, such as mp4split. */
3666  if (mov->mode == MODE_ISM)
3667  track->timescale = 10000000;
3668 
3669  avpriv_set_pts_info(st, 64, 1, track->timescale);
3670 
3671  /* copy extradata if it exists */
3672  if (st->codec->extradata_size) {
3673  track->vos_len = st->codec->extradata_size;
3674  track->vos_data = av_malloc(track->vos_len);
3675  memcpy(track->vos_data, st->codec->extradata, track->vos_len);
3676  }
3677  }
3678 
3679  if (mov->mode == MODE_ISM) {
3680  /* If no fragmentation options have been set, set a default. */
3681  if (!(mov->flags & (FF_MOV_FLAG_FRAG_KEYFRAME |
3684  mov->max_fragment_duration = 5000000;
3687  }
3688 
3689  if(mov->reserved_moov_size){
3690  mov->reserved_moov_pos= avio_tell(pb);
3691  if (mov->reserved_moov_size > 0)
3692  avio_skip(pb, mov->reserved_moov_size);
3693  }
3694 
3695  if (!(mov->flags & FF_MOV_FLAG_FRAGMENT))
3696  mov_write_mdat_tag(pb, mov);
3697 
3698  if (t = av_dict_get(s->metadata, "creation_time", NULL, 0))
3699  mov->time = ff_iso8601_to_unix_time(t->value);
3700  if (mov->time)
3701  mov->time += 0x7C25B080; // 1970 based -> 1904 based
3702 
3703  if (mov->chapter_track)
3705 
3706  if (mov->flags & FF_MOV_FLAG_RTP_HINT) {
3707  /* Initialize the hint tracks for each audio and video stream */
3708  for (i = 0; i < s->nb_streams; i++) {
3709  AVStream *st = s->streams[i];
3710  if (st->codec->codec_type == AVMEDIA_TYPE_VIDEO ||
3712  ff_mov_init_hinting(s, hint_track, i);
3713  hint_track++;
3714  }
3715  }
3716  }
3717 
3718  if (mov->nb_meta_tmcd) {
3719  /* Initialize the tmcd tracks */
3720  for (i = 0; i < s->nb_streams; i++) {
3721  AVStream *st = s->streams[i];
3722  t = global_tcr;
3723 
3724  if (st->codec->codec_type == AVMEDIA_TYPE_VIDEO) {
3725  if (!t)
3726  t = av_dict_get(st->metadata, "timecode", NULL, 0);
3727  if (!t)
3728  continue;
3729  if (mov_create_timecode_track(s, tmcd_track, i, t->value) < 0)
3730  goto error;
3731  tmcd_track++;
3732  }
3733  }
3734  }
3735 
3736  avio_flush(pb);
3737 
3738  if (mov->flags & FF_MOV_FLAG_ISML)
3739  mov_write_isml_manifest(pb, mov);
3740 
3741  if (mov->flags & FF_MOV_FLAG_EMPTY_MOOV) {
3742  mov_write_moov_tag(pb, mov, s);
3743  mov->fragments++;
3744  }
3745 
3746  return 0;
3747  error:
3748  av_freep(&mov->tracks);
3749  return -1;
3750 }
3751 
3752 /**
3753  * This function gets the moov size if moved to the top of the file: the chunk
3754  * offset table can switch between stco (32-bit entries) to co64 (64-bit
3755  * entries) when the moov is moved to the top, so the size of the moov would
3756  * change. It also updates the chunk offset tables.
3757  */
3759 {
3760  int i, moov_size, moov_size2;
3761  MOVMuxContext *mov = s->priv_data;
3762 
3763  moov_size = get_moov_size(s);
3764  if (moov_size < 0)
3765  return moov_size;
3766 
3767  for (i = 0; i < mov->nb_streams; i++)
3768  mov->tracks[i].data_offset += moov_size;
3769 
3770  moov_size2 = get_moov_size(s);
3771  if (moov_size2 < 0)
3772  return moov_size2;
3773 
3774  /* if the size changed, we just switched from stco to co64 and needs to
3775  * update the offsets */
3776  if (moov_size2 != moov_size)
3777  for (i = 0; i < mov->nb_streams; i++)
3778  mov->tracks[i].data_offset += moov_size2 - moov_size;
3779 
3780  return moov_size2;
3781 }
3782 
3784 {
3785  int ret = 0, moov_size;
3786  MOVMuxContext *mov = s->priv_data;
3787  int64_t pos, pos_end = avio_tell(s->pb);
3788  uint8_t *buf, *read_buf[2];
3789  int read_buf_id = 0;
3790  int read_size[2];
3791  AVIOContext *read_pb;
3792 
3793  moov_size = compute_moov_size(s);
3794  if (moov_size < 0)
3795  return moov_size;
3796 
3797  buf = av_malloc(moov_size * 2);
3798  if (!buf)
3799  return AVERROR(ENOMEM);
3800  read_buf[0] = buf;
3801  read_buf[1] = buf + moov_size;
3802 
3803  /* Shift the data: the AVIO context of the output can only be used for
3804  * writing, so we re-open the same output, but for reading. It also avoids
3805  * a read/seek/write/seek back and forth. */
3806  avio_flush(s->pb);
3807  ret = avio_open(&read_pb, s->filename, AVIO_FLAG_READ);
3808  if (ret < 0) {
3809  av_log(s, AV_LOG_ERROR, "Unable to re-open %s output file for "
3810  "the second pass (faststart)\n", s->filename);
3811  goto end;
3812  }
3813 
3814  /* mark the end of the shift to up to the last data we wrote, and get ready
3815  * for writing */
3816  pos_end = avio_tell(s->pb);
3817  avio_seek(s->pb, mov->reserved_moov_pos + moov_size, SEEK_SET);
3818 
3819  /* start reading at where the new moov will be placed */
3820  avio_seek(read_pb, mov->reserved_moov_pos, SEEK_SET);
3821  pos = avio_tell(read_pb);
3822 
3823 #define READ_BLOCK do { \
3824  read_size[read_buf_id] = avio_read(read_pb, read_buf[read_buf_id], moov_size); \
3825  read_buf_id ^= 1; \
3826 } while (0)
3827 
3828  /* shift data by chunk of at most moov_size */
3829  READ_BLOCK;
3830  do {
3831  int n;
3832  READ_BLOCK;
3833  n = read_size[read_buf_id];
3834  if (n <= 0)
3835  break;
3836  avio_write(s->pb, read_buf[read_buf_id], n);
3837  pos += n;
3838  } while (pos < pos_end);
3839  avio_close(read_pb);
3840 
3841 end:
3842  av_free(buf);
3843  return ret;
3844 }
3845 
3847 {
3848  MOVMuxContext *mov = s->priv_data;
3849  AVIOContext *pb = s->pb;
3850  int64_t moov_pos;
3851  int res = 0;
3852  int i;
3853 
3854  /*
3855  * Before actually writing the trailer, make sure that there are no
3856  * dangling subtitles, that need a terminating sample.
3857  */
3858  for (i = 0; i < mov->nb_streams; i++) {
3859  MOVTrack *trk = &mov->tracks[i];
3860  if (trk->enc->codec_id == AV_CODEC_ID_MOV_TEXT &&
3863  trk->last_sample_is_subtitle_end = 1;
3864  }
3865  }
3866 
3867  moov_pos = avio_tell(pb);
3868 
3869  if (!(mov->flags & FF_MOV_FLAG_FRAGMENT)) {
3870  /* Write size of mdat tag */
3871  if (mov->mdat_size + 8 <= UINT32_MAX) {
3872  avio_seek(pb, mov->mdat_pos, SEEK_SET);
3873  avio_wb32(pb, mov->mdat_size + 8);
3874  } else {
3875  /* overwrite 'wide' placeholder atom */
3876  avio_seek(pb, mov->mdat_pos - 8, SEEK_SET);
3877  /* special value: real atom size will be 64 bit value after
3878  * tag field */
3879  avio_wb32(pb, 1);
3880  ffio_wfourcc(pb, "mdat");
3881  avio_wb64(pb, mov->mdat_size + 16);
3882  }
3883  avio_seek(pb, mov->reserved_moov_size > 0 ? mov->reserved_moov_pos : moov_pos, SEEK_SET);
3884 
3885  if (mov->reserved_moov_size == -1) {
3886  av_log(s, AV_LOG_INFO, "Starting second pass: moving header on top of the file\n");
3887  res = shift_data(s);
3888  if (res == 0) {
3889  avio_seek(s->pb, mov->reserved_moov_pos, SEEK_SET);
3890  mov_write_moov_tag(pb, mov, s);
3891  }
3892  } else if (mov->reserved_moov_size > 0) {
3893  int64_t size;
3894  mov_write_moov_tag(pb, mov, s);
3895  size = mov->reserved_moov_size - (avio_tell(pb) - mov->reserved_moov_pos);
3896  if(size < 8){
3897  av_log(s, AV_LOG_ERROR, "reserved_moov_size is too small, needed %"PRId64" additional\n", 8-size);
3898  return -1;
3899  }
3900  avio_wb32(pb, size);
3901  ffio_wfourcc(pb, "free");
3902  for(i=0; i<size; i++)
3903  avio_w8(pb, 0);
3904  avio_seek(pb, moov_pos, SEEK_SET);
3905  } else {
3906  mov_write_moov_tag(pb, mov, s);
3907  }
3908  } else {
3909  mov_flush_fragment(s);
3910  mov_write_mfra_tag(pb, mov);
3911  }
3912 
3913  if (mov->chapter_track)
3914  av_freep(&mov->tracks[mov->chapter_track].enc);
3915 
3916  for (i=0; i<mov->nb_streams; i++) {
3917  if (mov->tracks[i].tag == MKTAG('r','t','p',' '))
3918  ff_mov_close_hinting(&mov->tracks[i]);
3919  else if (mov->tracks[i].tag == MKTAG('t','m','c','d') && mov->nb_meta_tmcd)
3920  av_freep(&mov->tracks[i].enc);
3921  if (mov->flags & FF_MOV_FLAG_FRAGMENT &&
3922  mov->tracks[i].vc1_info.struct_offset && s->pb->seekable) {
3923  int64_t off = avio_tell(pb);
3924  uint8_t buf[7];
3925  if (mov_write_dvc1_structs(&mov->tracks[i], buf) >= 0) {
3926  avio_seek(pb, mov->tracks[i].vc1_info.struct_offset, SEEK_SET);
3927  avio_write(pb, buf, 7);
3928  avio_seek(pb, off, SEEK_SET);
3929  }
3930  }
3931  av_freep(&mov->tracks[i].cluster);
3932  av_freep(&mov->tracks[i].frag_info);
3933 
3934  if (mov->tracks[i].vos_len)
3935  av_free(mov->tracks[i].vos_data);
3936 
3937  }
3938 
3939  av_freep(&mov->tracks);
3940 
3941  return res;
3942 }
3943 
3944 #if CONFIG_MOV_MUXER
3945 MOV_CLASS(mov)
3946 AVOutputFormat ff_mov_muxer = {
3947  .name = "mov",
3948  .long_name = NULL_IF_CONFIG_SMALL("QuickTime / MOV"),
3949  .extensions = "mov",
3950  .priv_data_size = sizeof(MOVMuxContext),
3951  .audio_codec = AV_CODEC_ID_AAC,
3952  .video_codec = CONFIG_LIBX264_ENCODER ?
3958  .codec_tag = (const AVCodecTag* const []){
3960  },
3961  .priv_class = &mov_muxer_class,
3962 };
3963 #endif
3964 #if CONFIG_TGP_MUXER
3965 MOV_CLASS(tgp)
3966 AVOutputFormat ff_tgp_muxer = {
3967  .name = "3gp",
3968  .long_name = NULL_IF_CONFIG_SMALL("3GP (3GPP file format)"),
3969  .extensions = "3gp",
3970  .priv_data_size = sizeof(MOVMuxContext),
3971  .audio_codec = AV_CODEC_ID_AMR_NB,
3972  .video_codec = AV_CODEC_ID_H263,
3977  .codec_tag = (const AVCodecTag* const []){ codec_3gp_tags, 0 },
3978  .priv_class = &tgp_muxer_class,
3979 };
3980 #endif
3981 #if CONFIG_MP4_MUXER
3982 MOV_CLASS(mp4)
3983 AVOutputFormat ff_mp4_muxer = {
3984  .name = "mp4",
3985  .long_name = NULL_IF_CONFIG_SMALL("MP4 (MPEG-4 Part 14)"),
3986  .mime_type = "application/mp4",
3987  .extensions = "mp4",
3988  .priv_data_size = sizeof(MOVMuxContext),
3989  .audio_codec = AV_CODEC_ID_AAC,
3990  .video_codec = CONFIG_LIBX264_ENCODER ?
3996  .codec_tag = (const AVCodecTag* const []){ ff_mp4_obj_type, 0 },
3997  .priv_class = &mp4_muxer_class,
3998 };
3999 #endif
4000 #if CONFIG_PSP_MUXER
4001 MOV_CLASS(psp)
4002 AVOutputFormat ff_psp_muxer = {
4003  .name = "psp",
4004  .long_name = NULL_IF_CONFIG_SMALL("PSP MP4 (MPEG-4 Part 14)"),
4005  .extensions = "mp4,psp",
4006  .priv_data_size = sizeof(MOVMuxContext),
4007  .audio_codec = AV_CODEC_ID_AAC,
4008  .video_codec = CONFIG_LIBX264_ENCODER ?
4014  .codec_tag = (const AVCodecTag* const []){ ff_mp4_obj_type, 0 },
4015  .priv_class = &psp_muxer_class,
4016 };
4017 #endif
4018 #if CONFIG_TG2_MUXER
4019 MOV_CLASS(tg2)
4020 AVOutputFormat ff_tg2_muxer = {
4021  .name = "3g2",
4022  .long_name = NULL_IF_CONFIG_SMALL("3GP2 (3GPP2 file format)"),
4023  .extensions = "3g2",
4024  .priv_data_size = sizeof(MOVMuxContext),
4025  .audio_codec = AV_CODEC_ID_AMR_NB,
4026  .video_codec = AV_CODEC_ID_H263,
4031  .codec_tag = (const AVCodecTag* const []){ codec_3gp_tags, 0 },
4032  .priv_class = &tg2_muxer_class,
4033 };
4034 #endif
4035 #if CONFIG_IPOD_MUXER
4036 MOV_CLASS(ipod)
4037 AVOutputFormat ff_ipod_muxer = {
4038  .name = "ipod",
4039  .long_name = NULL_IF_CONFIG_SMALL("iPod H.264 MP4 (MPEG-4 Part 14)"),
4040  .mime_type = "application/mp4",
4041  .extensions = "m4v,m4a",
4042  .priv_data_size = sizeof(MOVMuxContext),
4043  .audio_codec = AV_CODEC_ID_AAC,
4044  .video_codec = AV_CODEC_ID_H264,
4049  .codec_tag = (const AVCodecTag* const []){ codec_ipod_tags, 0 },
4050  .priv_class = &ipod_muxer_class,
4051 };
4052 #endif
4053 #if CONFIG_ISMV_MUXER
4054 MOV_CLASS(ismv)
4055 AVOutputFormat ff_ismv_muxer = {
4056  .name = "ismv",
4057  .long_name = NULL_IF_CONFIG_SMALL("ISMV/ISMA (Smooth Streaming)"),
4058  .mime_type = "application/mp4",
4059  .extensions = "ismv,isma",
4060  .priv_data_size = sizeof(MOVMuxContext),
4061  .audio_codec = AV_CODEC_ID_AAC,
4062  .video_codec = AV_CODEC_ID_H264,
4067  .codec_tag = (const AVCodecTag* const []){ ff_mp4_obj_type, 0 },
4068  .priv_class = &ismv_muxer_class,
4069 };
4070 #endif
4071 #if CONFIG_F4V_MUXER
4072 MOV_CLASS(f4v)
4073 AVOutputFormat ff_f4v_muxer = {
4074  .name = "f4v",
4075  .long_name = NULL_IF_CONFIG_SMALL("F4V Adobe Flash Video"),
4076  .mime_type = "application/f4v",
4077  .extensions = "f4v",
4078  .priv_data_size = sizeof(MOVMuxContext),
4079  .audio_codec = AV_CODEC_ID_AAC,
4080  .video_codec = AV_CODEC_ID_H264,
4085  .codec_tag = (const AVCodecTag* const []){ codec_f4v_tags, 0 },
4086  .priv_class = &f4v_muxer_class,
4087 };
4088 #endif
unsigned int nb_chapters
Definition: avformat.h:1089
int first_packet_entry
Definition: movenc.h:136
const char * name
Definition: avisynth_c.h:675
#define MOV_TRACK_STPS
Definition: movenc.h:90
int avio_open(AVIOContext **s, const char *url, int flags)
Create and initialize a AVIOContext for accessing the resource indicated by url.
Definition: aviobuf.c:799
static int utf8len(const uint8_t *b)
Definition: movenc.c:2109
static int mov_write_extradata_tag(AVIOContext *pb, MOVTrack *track)
This function writes extradata "as is".
Definition: movenc.c:284
packed YUV 4:2:2, 16bpp, Cb Y0 Cr Y1
Definition: pixfmt.h:85
AVFormatContext * rtp_ctx
the format context for the hinting rtp muxer
Definition: movenc.h:113
int ff_mov_iso639_to_lang(const char lang[4], int mp4)
Definition: isom.c:336
void avio_wb64(AVIOContext *s, uint64_t val)
Definition: aviobuf.c:361
void * av_mallocz(size_t size)
Allocate a block of size bytes with alignment suitable for all memory accesses (including vectors if ...
Definition: mem.c:205
static void av_unused put_bits32(PutBitContext *s, uint32_t value)
Write exactly 32 bits into a bitstream.
Definition: put_bits.h:182
const struct AVCodec * codec
static int ascii_to_wc(AVIOContext *pb, const uint8_t *b)
Definition: movenc.c:2120
const char * s
Definition: avisynth_c.h:668
Bytestream IO Context.
Definition: avio.h:68
int language
Definition: movenc.h:96
#define FF_MOV_FLAG_FASTSTART
Definition: movenc.h:180
static int get_cluster_duration(MOVTrack *track, int cluster_idx)
Definition: movenc.c:608
static int mov_write_dinf_tag(AVIOContext *pb)
Definition: movenc.c:1326
Buffered I/O operations.
int use_editlist
Definition: movenc.h:170
#define GET_UTF8(val, GET_BYTE, ERROR)
Convert a UTF-8 character (up to 4 bytes) to its 32-bit UCS-4 encoded form.
Definition: common.h:296
void av_free_packet(AVPacket *pkt)
Free a packet.
Definition: avpacket.c:242
int avio_close_dyn_buf(AVIOContext *s, uint8_t **pbuffer)
Return the written size and a pointer to the buffer.
Definition: aviobuf.c:988
AVOption.
Definition: opt.h:251
static int mov_write_ac3_tag(AVIOContext *pb, MOVTrack *track)
Definition: movenc.c:236
int nb_frag_info
Definition: movenc.h:130
static void mov_write_psp_udta_tag(AVIOContext *pb, const char *str, const char *lang, int type)
Definition: movenc.c:2240
#define MOV_TFHD_DEFAULT_DURATION
Definition: isom.h:181
unsigned int entries
Definition: movenc.h:50
static int is_co64_required(const MOVTrack *track)
Definition: movenc.c:93
int first_packet_seq
Definition: movenc.h:135
AVIOContext * mdat_buf
Definition: movenc.h:168
int64_t av_rescale_rnd(int64_t a, int64_t b, int64_t c, enum AVRounding rnd)
Rescale a 64-bit integer with specified rounding.
Definition: mathematics.c:60
static int mov_write_tmcd_tag(AVIOContext *pb, MOVTrack *track)
Definition: movenc.c:1149
Definition: isom.h:45
static unsigned int get_bits(GetBitContext *s, int n)
Read 1-25 bits.
Definition: get_bits.h:240
static void param_write_int(AVIOContext *pb, const char *name, int value)
Definition: movenc.c:2380
void * av_realloc_f(void *ptr, size_t nelem, size_t elsize)
Allocate or reallocate a block of memory.
Definition: mem.c:168
#define FF_MOV_FLAG_FRAGMENT
Definition: movenc.h:174
uint32_t timecode_flags
Definition: movenc.h:95
packed RGB 8:8:8, 24bpp, RGBRGB...
Definition: pixfmt.h:70
static int mov_write_subtitle_end_packet(AVFormatContext *s, int stream_index, int64_t dts)
Definition: movenc.c:3297
static int mov_write_enda_tag_be(AVIOContext *pb)
Definition: movenc.c:298
int max_fragment_size
Definition: movenc.h:166
void avpriv_set_pts_info(AVStream *s, int pts_wrap_bits, unsigned int pts_num, unsigned int pts_den)
Set the time base and wrapping info for a given stream.
static void skip_bits_long(GetBitContext *s, int n)
Definition: get_bits.h:198
static int mov_write_dref_tag(AVIOContext *pb)
Definition: movenc.c:1289
static int mov_write_string_metadata(AVFormatContext *s, AVIOContext *pb, const char *name, const char *tag, int long_style)
Definition: movenc.c:1978
static const AVCodecTag codec_f4v_tags[]
Definition: movenc.c:980
int src_track
the track that this hint (or tmcd) track describes
Definition: movenc.h:112
#define AV_LOG_WARNING
Something somehow does not look correct.
Definition: log.h:154
static int write_packet(AVFormatContext *s, AVPacket *pkt)
static int mov_pcm_be_gt16(enum AVCodecID codec_id)
Definition: movenc.c:386
int ff_mov_add_hinted_packet(AVFormatContext *s, AVPacket *pkt, int track_index, int sample, uint8_t *sample_data, int sample_size)
Definition: movenchint.c:390
static int mov_get_rawvideo_codec_tag(AVFormatContext *s, MOVTrack *track)
Definition: movenc.c:914
AVRational sample_aspect_ratio
sample aspect ratio (0 if unknown)
Definition: avformat.h:709
int num
numerator
Definition: rational.h:44
packed RGB 5:5:5, 16bpp, (msb)1A 5R 5G 5B(lsb), little-endian, most significant bit to 0 ...
Definition: pixfmt.h:117
title('Sinusoid at 1/4 the Spampling Rate')
#define MOV_TRUN_SAMPLE_CTS
Definition: isom.h:191
int64_t avio_seek(AVIOContext *s, int64_t offset, int whence)
fseek() equivalent for AVIOContext.
Definition: aviobuf.c:199
#define AVIO_FLAG_READ
read-only
Definition: avio.h:332
int av_timecode_init_from_string(AVTimecode *tc, AVRational rate, const char *str, void *log_ctx)
Parse timecode representation (hh:mm:ss[:;.
#define av_bswap16
Definition: sh4/bswap.h:31
AVRational sample_aspect_ratio
sample aspect ratio (0 if unknown) That is the width of a pixel divided by the height of the pixel...
static int mov_write_ms_tag(AVIOContext *pb, MOVTrack *track)
Definition: movenc.c:394
enum AVMediaType codec_type
Definition: rtp.c:36
enum AVPixelFormat pix_fmt
Pixel format, see AV_PIX_FMT_xxx.
#define tc
Definition: regdef.h:69
static av_always_inline uint64_t av_double2int(double f)
Reinterpret a double as a 64-bit integer.
Definition: intfloat.h:70
struct MOVIndex::@149 vc1_info
static int mov_write_moof_tag(AVIOContext *pb, MOVMuxContext *mov, int tracks)
Definition: movenc.c:2687
uint32_t tref_tag
Definition: movenc.h:107
x1
Definition: genspecsines3.m:7
static int mov_write_pasp_tag(AVIOContext *pb, MOVTrack *track)
Definition: movenc.c:1058
AVCodecContext * enc
Definition: movenc.h:100
int64_t avio_skip(AVIOContext *s, int64_t offset)
Skip given number of bytes forward.
Definition: aviobuf.c:256
unsigned int ff_codec_get_tag(const AVCodecTag *tags, enum AVCodecID id)
void * av_realloc(void *ptr, size_t size)
Allocate or reallocate a block of memory.
Definition: mem.c:141
#define FF_ARRAY_ELEMS(a)
int version
Definition: avisynth_c.h:666
#define FF_MOV_FLAG_ISML
Definition: movenc.h:179
static int mov_write_tcmi_tag(AVIOContext *pb, MOVTrack *track)
Definition: movenc.c:1343
#define MOV_TFHD_DURATION_IS_EMPTY
Definition: isom.h:184
AVDictionary * metadata
Definition: avformat.h:922
AVDictionaryEntry * av_dict_get(AVDictionary *m, const char *key, const AVDictionaryEntry *prev, int flags)
Get a dictionary entry with matching key.
Definition: dict.c:39
static uint16_t language_code(const char *str)
Definition: movenc.c:2131
#define AVFMT_ALLOW_FLUSH
Format allows flushing.
Definition: avformat.h:361
static int mov_write_hdlr_tag(AVIOContext *pb, MOVTrack *track)
Definition: movenc.c:1430
int64_t moof_size_offset
Definition: movenc.h:125
static const struct @148 mov_pix_fmt_tags[]
int avio_open_dyn_buf(AVIOContext **s)
Open a write only memory stream.
Definition: aviobuf.c:976
int block_align
number of bytes per packet if constant and known or 0 Used by some WAV based audio codecs...
static int mov_write_tfrf_tag(AVIOContext *pb, MOVMuxContext *mov, MOVTrack *track, int entry)
Definition: movenc.c:2611
AVRational time_base
This is the fundamental unit of time (in seconds) in terms of which frame timestamps are represented...
void av_freep(void *arg)
Free a memory block which has been allocated with av_malloc(z)() or av_realloc() and set the pointer ...
Definition: mem.c:198
static int mov_write_glbl_tag(AVIOContext *pb, MOVTrack *track)
Definition: movenc.c:571
packed RGB 5:6:5, 16bpp, (msb) 5R 6G 5B(lsb), little-endian
Definition: pixfmt.h:115
set threshold d
static int shift_data(AVFormatContext *s)
Definition: movenc.c:3783
initialize output if(nPeaks >3)%at least 3 peaks in spectrum for trying to find f0 nf0peaks
Format I/O context.
Definition: avformat.h:944
static int mov_write_stsc_tag(AVIOContext *pb, MOVTrack *track)
Definition: movenc.c:169
static int mov_write_packet(AVFormatContext *s, AVPacket *pkt)
Definition: movenc.c:3318
#define AV_WB32(p, darg)
Definition: intreadwrite.h:265
int packet_entry
Definition: movenc.h:138
static int mov_write_fiel_tag(AVIOContext *pb, MOVTrack *track)
Definition: movenc.c:1030
int64_t tfrf_offset
Definition: movenc.h:128
#define av_assert0(cond)
assert() equivalent, that is always enabled.
Definition: avassert.h:37
static int mov_write_single_packet(AVFormatContext *s, AVPacket *pkt)
Definition: movenc.c:3270
Public dictionary API.
static int mov_write_uuidusmt_tag(AVIOContext *pb, AVFormatContext *s)
Definition: movenc.c:2253
int last_sample_is_subtitle_end
Definition: movenc.h:84
#define READ_BLOCK
#define FF_MOV_FLAG_EMPTY_MOOV
Definition: movenc.h:175
void avio_wl32(AVIOContext *s, unsigned int val)
Definition: aviobuf.c:291
uint8_t
Round toward +infinity.
Definition: mathematics.h:71
static int mov_write_uuid_tag_psp(AVIOContext *pb, MOVTrack *mov)
Definition: movenc.c:1760
Opaque data information usually continuous.
Definition: avutil.h:145
uint64_t mdat_size
Definition: movenc.h:151
unsigned int samples_in_chunk
Definition: movenc.h:48
#define MOV_CLASS(flavor)
Definition: movenc.c:68
AVOptions.
static int get_samples_per_packet(MOVTrack *track)
Definition: movenc.c:623
const AVCodecTag ff_codec_movvideo_tags[]
Definition: isom.c:68
static int mov_pcm_le_gt16(enum AVCodecID codec_id)
Definition: movenc.c:378
#define AV_RB32
static AVPacket pkt
Definition: demuxing.c:56
static int mov_get_codec_tag(AVFormatContext *s, MOVTrack *track)
Definition: movenc.c:931
static void mov_write_uuidprof_tag(AVIOContext *pb, AVFormatContext *s)
Definition: movenc.c:2846
long sample_size
Definition: movenc.h:86
#define b
Definition: input.c:42
end end
int64_t start_dts
Definition: movenc.h:109
static const AVOption options[]
Definition: movenc.c:46
#define MODE_PSP
Definition: movenc.h:37
uint8_t * extradata
some codecs need / can use extradata like Huffman tables.
static int mov_write_tapt_tag(AVIOContext *pb, MOVTrack *track)
Definition: movenc.c:1666
AVStream ** streams
Definition: avformat.h:992
static int mov_write_vmhd_tag(AVIOContext *pb)
Definition: movenc.c:1421
#define MODE_MP4
Definition: movenc.h:34
packed RGB 5:6:5, 16bpp, (msb) 5R 6G 5B(lsb), big-endian
Definition: pixfmt.h:114
static int mov_write_amr_tag(AVIOContext *pb, MOVTrack *track)
Definition: movenc.c:222
int64_t default_duration
Definition: movenc.h:118
packed ABGR 8:8:8:8, 32bpp, ABGRABGR...
Definition: pixfmt.h:98
static int mov_write_moov_tag(AVIOContext *pb, MOVMuxContext *mov, AVFormatContext *s)
Definition: movenc.c:2313
int64_t track_duration
Definition: movenc.h:83
static double av_q2d(AVRational a)
Convert rational to double.
Definition: rational.h:69
int ff_avc_write_annexb_extradata(const uint8_t *in, uint8_t **buf, int *size)
Definition: avc.c:164
int chapter_track
qt chapter track number
Definition: movenc.h:149
uint8_t * data
int start
timecode frame start (first base frame number)
int64_t time
Definition: movenc.h:73
static int mov_write_minf_tag(AVIOContext *pb, MOVTrack *track)
Definition: movenc.c:1500
#define MOV_TRUN_SAMPLE_SIZE
Definition: isom.h:189
uint32_t tag
Definition: movenc.c:894
static int mov_write_itunes_hdlr_tag(AVIOContext *pb, MOVMuxContext *mov, AVFormatContext *s)
Definition: movenc.c:1930
int fragments
Definition: movenc.h:163
static int mov_write_subtitle_tag(AVIOContext *pb, MOVTrack *track)
Definition: movenc.c:1043
static int mov_write_chan_tag(AVIOContext *pb, MOVTrack *track)
Definition: movenc.c:413
int iods_audio_profile
Definition: movenc.h:161
bitstream reader API header.
#define MOV_TIMESCALE
Definition: movenc.h:30
int max_fragment_duration
Definition: movenc.h:164
#define CODEC_FLAG_BITEXACT
Use only bitexact stuff (except (I)DCT).
int av_match_ext(const char *filename, const char *extensions)
Return a positive value if the given filename has one of the given extensions, 0 otherwise.
AVIOContext * mdat_buf
Definition: movenc.h:124
static int mov_write_wave_tag(AVIOContext *pb, MOVTrack *track)
Definition: movenc.c:438
int64_t mdat_pos
Definition: movenc.h:150
static av_always_inline int64_t avio_tell(AVIOContext *s)
ftell() equivalent for AVIOContext.
Definition: avio.h:248
void ff_mov_close_hinting(MOVTrack *track)
Definition: movenchint.c:448
int bits_per_coded_sample
bits per sample/pixel from the demuxer (needed for huffyuv).
int av_timecode_check_frame_rate(AVRational rate)
Check if the timecode feature is available for the given frame rate.
static int64_t duration
Definition: ffplay.c:294
static int mov_write_uuid_tag_ipod(AVIOContext *pb)
Write uuid atom.
Definition: movenc.c:1014
unsigned int size
Definition: movenc.h:47
void avio_write(AVIOContext *s, const unsigned char *buf, int size)
Definition: aviobuf.c:173
static av_always_inline void ffio_wfourcc(AVIOContext *pb, const uint8_t *s)
Definition: avio_internal.h:50
int duration
Duration of this packet in AVStream->time_base units, 0 if unknown.
static const uint16_t fiel_data[]
Definition: movenc.c:1026
static int write_trailer(AVFormatContext *s)
#define MOV_TFHD_DEFAULT_SIZE
Definition: isom.h:182
static int mov_write_nmhd_tag(AVIOContext *pb)
Definition: movenc.c:1335
#define AV_OPT_FLAG_ENCODING_PARAM
a generic parameter which can be set by the user for muxing or encoding
Definition: opt.h:281
int ism_lookahead
Definition: movenc.h:167
struct AVOutputFormat * oformat
Definition: avformat.h:958
#define AV_PKT_FLAG_KEY
The packet contains a keyframe.
#define MODE_3G2
Definition: movenc.h:39
static int mov_find_codec_tag(AVFormatContext *s, MOVTrack *track)
Definition: movenc.c:988
uint32_t flags
Definition: movenc.h:91
int64_t av_rescale_q(int64_t a, AVRational bq, AVRational cq)
Rescale a 64-bit integer by 2 rational numbers.
Definition: mathematics.c:130
uint32_t flags
Definition: movenc.h:54
int height
active picture (w/o VBI) height for D-10/IMX
Definition: movenc.h:106
#define MOV_TIMECODE_FLAG_DROPFRAME
Definition: movenc.h:92
struct MOVMuxContext MOVMuxContext
static int mov_write_udta_sdp(AVIOContext *pb, MOVTrack *track)
Definition: movenc.c:1778
AVCodecID
Identify the syntax and semantics of the bitstream.
AVDictionary * metadata
Definition: avformat.h:1092
int av_get_bits_per_sample(enum AVCodecID codec_id)
Return codec bits per sample.
void av_free(void *ptr)
Free a memory block which has been allocated with av_malloc(z)() or av_realloc(). ...
Definition: mem.c:183
static int mov_write_meta_tag(AVIOContext *pb, MOVMuxContext *mov, AVFormatContext *s)
Definition: movenc.c:2095
int64_t tfrf_offset
Definition: movenc.h:75
#define MOV_FRAG_SAMPLE_FLAG_DEPENDS_NO
Definition: isom.h:200
static int mov_write_mdat_tag(AVIOContext *pb, MOVMuxContext *mov)
Definition: movenc.c:2771
unsigned timescale
Definition: movenc.h:81
int tag
stsd fourcc
Definition: movenc.h:99
static int mov_write_stsz_tag(AVIOContext *pb, MOVTrack *track)
Definition: movenc.c:131
int64_t duration
Definition: movenc.h:74
static void put_descr(AVIOContext *pb, int tag, unsigned int size)
Definition: movenc.c:306
static int mov_flush_fragment(AVFormatContext *s)
Definition: movenc.c:3000
static int mov_write_ilst_tag(AVIOContext *pb, MOVMuxContext *mov, AVFormatContext *s)
Definition: movenc.c:2061
static int mov_write_avid_tag(AVIOContext *pb, MOVTrack *track)
Definition: movenc.c:774
#define AV_RB16
static int mov_write_int8_metadata(AVFormatContext *s, AVIOContext *pb, const char *name, const char *tag, int len)
Definition: movenc.c:2042
static void mov_parse_vc1_frame(AVPacket *pkt, MOVTrack *trk, int fragment)
Definition: movenc.c:2928
static int mov_write_dvc1_structs(MOVTrack *track, uint8_t *buf)
Definition: movenc.c:479
int audio_vbr
Definition: movenc.h:105
#define NULL_IF_CONFIG_SMALL(x)
Return NULL if CONFIG_SMALL is true, otherwise the argument without modification. ...
#define MODE_3GP
Definition: movenc.h:36
int avio_close(AVIOContext *s)
Close the resource accessed by the AVIOContext s and free it.
Definition: aviobuf.c:821
packed BGRA 8:8:8:8, 32bpp, BGRABGRA...
Definition: pixfmt.h:99
Spectrum Plot time data
#define FF_COMPLIANCE_NORMAL
preferred ID for decoding MPEG audio layer 1, 2 or 3
int flags
CODEC_FLAG_*.
static int mov_write_tkhd_tag(AVIOContext *pb, MOVTrack *track, AVStream *st)
Definition: movenc.c:1592
AVChapter ** chapters
Definition: avformat.h:1090
int rc_max_rate
maximum bitrate
void av_log(void *avcl, int level, const char *fmt,...)
Definition: log.c:246
const char * name
Name of the codec implementation.
static int mov_write_isml_manifest(AVIOContext *pb, MOVMuxContext *mov)
Definition: movenc.c:2399
int hint_track
the track that hints this track, -1 if no hint track is set
Definition: movenc.h:111
#define FF_MOV_FLAG_SEPARATE_MOOF
Definition: movenc.h:177
enum AVCodecID codec_id
Definition: mov_chan.c:433
static void put_bits(J2kEncoderContext *s, int val, int n)
put n times val bit
Definition: j2kenc.c:160
AVRational avg_frame_rate
Average framerate.
Definition: avformat.h:716
const AVCodecTag ff_codec_wav_tags[]
Definition: riff.c:334
#define FFMAX(a, b)
Definition: common.h:56
int ff_avc_parse_nal_units_buf(const uint8_t *buf_in, uint8_t **buf, int *size)
Definition: avc.c:92
packed ARGB 8:8:8:8, 32bpp, ARGBARGB...
Definition: pixfmt.h:96
#define MOV_FRAG_SAMPLE_FLAG_DEPENDS_YES
Definition: isom.h:201
size_t av_strlcpy(char *dst, const char *src, size_t size)
Copy the string src to dst, but no more than size - 1 bytes, and null-terminate dst.
Definition: avstring.c:82
const AVCodecTag ff_mp4_obj_type[]
Definition: isom.c:34
const AVCodecTag ff_codec_movsubtitle_tags[]
Definition: isom.c:303
packed RGBA 8:8:8:8, 32bpp, RGBARGBA...
Definition: pixfmt.h:97
int size
static int mov_write_mdhd_tag(AVIOContext *pb, MOVTrack *track)
Definition: movenc.c:1527
int flags
A combination of AV_PKT_FLAG values.
uint32_t default_sample_flags
Definition: movenc.h:119
uint64_t channel_layout
Audio channel layout.
planar YUV 4:2:2, 16bpp, (1 Cr & Cb sample per 2x1 Y samples)
Definition: pixfmt.h:72
AVCodecContext * codec
Codec context associated with this stream.
Definition: avformat.h:662
int rc_buffer_size
decoder bitstream buffer size
static int mov_write_wfex_tag(AVIOContext *pb, MOVTrack *track)
Definition: movenc.c:404
int av_reduce(int *dst_num, int *dst_den, int64_t num, int64_t den, int64_t max)
Reduce a fraction.
Definition: rational.c:36
static int mov_write_traf_tag(AVIOContext *pb, MOVMuxContext *mov, MOVTrack *track, int64_t moof_offset)
Definition: movenc.c:2661
int iods_skip
Definition: movenc.h:159
#define FF_INPUT_BUFFER_PADDING_SIZE
Required number of additionally allocated bytes at the end of the input bitstream for decoding...
unsigned int nb_streams
A list of all streams in the file.
Definition: avformat.h:991
int ff_avc_parse_nal_units(AVIOContext *pb, const uint8_t *buf_in, int size)
Definition: avc.c:70
#define LIBAVFORMAT_IDENT
MIPS optimizations info
Definition: mips.txt:2
uint64_t pos
Definition: movenc.h:45
int64_t dts
Definition: movenc.h:46
static int mov_write_stts_tag(AVIOContext *pb, MOVTrack *track)
Definition: movenc.c:1248
int seekable
A combination of AVIO_SEEKABLE_ flags or 0 when the stream is not seekable.
Definition: avio.h:117
int bit_rate
the average bitrate
static int mov_write_trkn_tag(AVIOContext *pb, MOVMuxContext *mov, AVFormatContext *s)
Definition: movenc.c:2021
int64_t data_offset
Definition: movenc.h:126
int void avio_flush(AVIOContext *s)
Force flushing of buffered data to the output s.
Definition: aviobuf.c:193
char filename[1024]
input or output filename
Definition: avformat.h:994
int64_t av_rescale(int64_t a, int64_t b, int64_t c)
Rescale a 64-bit integer with rounding to nearest.
Definition: mathematics.c:118
#define FFMIN(a, b)
Definition: common.h:58
int nb_meta_tmcd
number of new created tmcd track based on metadata (aka not data copy)
Definition: movenc.h:148
const AVCodecTag ff_codec_bmp_tags[]
Definition: riff.c:35
static int mov_write_mvex_tag(AVIOContext *pb, MOVMuxContext *mov)
Definition: movenc.c:1866
AVCodecContext * avcodec_alloc_context3(const AVCodec *codec)
Allocate an AVCodecContext and set its fields to default values.
static int mov_write_chpl_tag(AVIOContext *pb, AVFormatContext *s)
Definition: movenc.c:2158
ret
Definition: avfilter.c:821
#define MOV_PARTIAL_SYNC_SAMPLE
Definition: movenc.h:53
int width
picture width / height.
MOVFragmentInfo * frag_info
Definition: movenc.h:131
int ff_mov_init_hinting(AVFormatContext *s, int index, int src_index)
Definition: movenchint.c:29
int64_t ff_iso8601_to_unix_time(const char *datestr)
Convert a date string in ISO8601 format to Unix timestamp.
static int mov_write_avcc_tag(AVIOContext *pb, MOVTrack *track)
Definition: movenc.c:763
#define AVFMT_GLOBALHEADER
Format wants global header.
Definition: avformat.h:351
static int mov_write_trak_tag(AVIOContext *pb, MOVMuxContext *mov, MOVTrack *track, AVStream *st)
Definition: movenc.c:1800
void avio_wb24(AVIOContext *s, unsigned int val)
Definition: aviobuf.c:385
t
Definition: genspecsines3.m:6
const char * name
Definition: avformat.h:378
uint64_t time
Definition: movenc.h:82
internal header for RIFF based (de)muxers do NOT include this in end user applications ...
int slices
Definition: movenc.h:139
int32_t
int tref_id
trackID of the referenced track
Definition: movenc.h:108
uint32_t max_packet_size
Definition: movenc.h:116
static int mov_get_dv_codec_tag(AVFormatContext *s, MOVTrack *track)
Definition: movenc.c:867
static int mov_write_string_tag(AVIOContext *pb, const char *name, const char *value, int lang, int long_style)
Definition: movenc.c:1966
static int mov_write_smhd_tag(AVIOContext *pb)
Definition: movenc.c:1411
int avoid_negative_ts
Avoid negative timestamps during muxing.
Definition: avformat.h:1180
int reserved_moov_size
0 for disabled, -1 for automatic, size otherwise
Definition: movenc.h:156
static int mov_write_stco_tag(AVIOContext *pb, MOVTrack *track)
Definition: movenc.c:107
#define AV_RL32
static void mov_create_chapter_track(AVFormatContext *s, int tracknum)
Definition: movenc.c:3367
static void param_write_string(AVIOContext *pb, const char *name, const char *value)
Definition: movenc.c:2385
#define MOV_TRUN_SAMPLE_DURATION
Definition: isom.h:188
AVDictionary * metadata
Definition: avformat.h:711
packed RGB 8:8:8, 24bpp, BGRBGR...
Definition: pixfmt.h:71
enum AVPixelFormat pix_fmt
Definition: movenc.c:893
FIXME Range Coding of cr are level
Definition: snow.txt:367
static int mov_write_trex_tag(AVIOContext *pb, MOVTrack *track)
Definition: movenc.c:1853
preferred ID for MPEG-1/2 video decoding
int64_t struct_offset
Definition: movenc.h:134
#define MOV_TRACK_CTTS
Definition: movenc.h:89
static int mov_write_mfhd_tag(AVIOContext *pb, MOVMuxContext *mov)
Definition: movenc.c:2485
int iods_video_profile
Definition: movenc.h:160
int void ff_sdp_write_media(char *buff, int size, AVStream *st, int idx, const char *dest_addr, const char *dest_type, int port, int ttl, AVFormatContext *fmt)
Append the media-specific SDP fragment for the media stream c to the buffer buff. ...
Definition: sdp.c:708
Stream structure.
Definition: avformat.h:643
int64_t reserved_moov_pos
Definition: movenc.h:157
int64_t end
chapter start/end time in time_base units
Definition: avformat.h:921
int frame_size
Number of samples per channel in an audio frame.
NULL
Definition: eval.c:55
static int width
Definition: tests/utils.c:158
static int mov_write_esds_tag(AVIOContext *pb, MOVTrack *track)
Definition: movenc.c:326
#define MOV_INDEX_CLUSTER_SIZE
Definition: movenc.h:29
static int mov_write_d263_tag(AVIOContext *pb)
Definition: movenc.c:751
enum AVMediaType codec_type
const AVCodecTag ff_codec_movaudio_tags[]
Definition: isom.c:250
static int mov_write_ctts_tag(AVIOContext *pb, MOVTrack *track)
Definition: movenc.c:1214
int duration
Definition: isom.h:47
enum AVCodecID codec_id
#define AV_TIME_BASE_Q
Internal time base represented as fractional value.
Definition: avutil.h:202
int cts
Definition: movenc.h:51
int sample_rate
samples per second
AVIOContext * pb
I/O context.
Definition: avformat.h:977
uint8_t * vos_data
Definition: movenc.h:103
#define FF_RTP_FLAG_OPTS(ctx, fieldname)
Definition: rtpenc.h:74
void avio_w8(AVIOContext *s, int b)
Definition: aviobuf.c:151
main external API structure.
#define MOV_TRUN_FIRST_SAMPLE_FLAGS
Definition: isom.h:187
#define FF_MOV_FLAG_FRAG_CUSTOM
Definition: movenc.h:178
static int mov_write_video_tag(AVIOContext *pb, MOVTrack *track)
Definition: movenc.c:1071
static int mov_write_hmhd_tag(AVIOContext *pb)
Definition: movenc.c:1485
#define AV_LOG_ERROR
Something went wrong and cannot losslessly be recovered.
Definition: log.h:148
unsigned int codec_tag
fourcc (LSB first, so "ABCD" -> (&#39;D&#39;<<24) + (&#39;C&#39;<<16) + (&#39;B&#39;<<8) + &#39;A&#39;).
static int mov_parse_mpeg2_frame(AVPacket *pkt, uint32_t *flags)
Definition: movenc.c:2907
packed YUV 4:2:2, 16bpp, Y0 Cb Y1 Cr
Definition: pixfmt.h:69
static int mov_write_dvc1_tag(AVIOContext *pb, MOVTrack *track)
Definition: movenc.c:554
static void build_chunks(MOVTrack *trk)
Definition: movenc.c:2290
static int supports_edts(MOVMuxContext *mov)
Definition: movenc.c:87
void * buf
Definition: avisynth_c.h:594
static unsigned int get_bits1(GetBitContext *s)
Definition: get_bits.h:273
static int mov_write_edts_tag(AVIOContext *pb, MOVTrack *track)
Definition: movenc.c:1698
double value
Definition: eval.c:82
void * av_malloc(size_t size)
Allocate a block of size bytes with alignment suitable for all memory accesses (including vectors if ...
Definition: mem.c:73
x2
Definition: genspecsines3.m:8
#define FF_MOV_FLAG_RTP_HINT
Definition: movenc.h:173
static void skip_bits(GetBitContext *s, int n)
Definition: get_bits.h:265
int64_t frag_start
Definition: movenc.h:127
int count
Definition: isom.h:46
Y , 16bpp, big-endian.
Definition: pixfmt.h:101
int index
Definition: gxfenc.c:89
unsigned int chunkNum
Chunk number if the current entry is a chunk start otherwise 0.
Definition: movenc.h:49
synthesis window for stochastic i
#define AV_WB16(p, darg)
Definition: intreadwrite.h:237
rational number numerator/denominator
Definition: rational.h:43
static void param_write_hex(AVIOContext *pb, const char *name, const uint8_t *value, int len)
Definition: movenc.c:2390
static int init_get_bits(GetBitContext *s, const uint8_t *buffer, int bit_size)
Initialize GetBitContext.
Definition: get_bits.h:379
int64_t time
Definition: movenc.h:146
size_t av_strlcatf(char *dst, size_t size, const char *fmt,...)
Definition: avstring.c:100
int mode
Definition: movenc.h:79
#define MOV_TFHD_DEFAULT_FLAGS
Definition: isom.h:183
#define snprintf
Definition: snprintf.h:34
#define MOV_TRUN_SAMPLE_FLAGS
Definition: isom.h:190
Filter the word “frame” indicates either a video frame or a group of audio as stored in an AVFilterBuffer 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 all references to the list are updated That means that if a filter requires that its input and output have the same format amongst a supported all it has to do is use a reference to the same list of formats query_formats can leave some formats unset and return AVERROR(EAGAIN) to cause the negotiation mechanism toagain later.That can be used by filters with complex requirements to use the format negotiated on one link to set the formats supported on another.Buffer references ownership and permissions
#define type
Round toward -infinity.
Definition: mathematics.h:70
static const AVCodecTag codec_3gp_tags[]
Definition: movenc.c:969
static int mov_write_enda_tag(AVIOContext *pb)
Definition: movenc.c:290
static int mov_write_gmhd_tag(AVIOContext *pb, MOVTrack *track)
Definition: movenc.c:1365
void avio_wb16(AVIOContext *s, unsigned int val)
Definition: aviobuf.c:373
track
Definition: brsc.py:18
static void write_matrix(AVIOContext *pb, int16_t a, int16_t b, int16_t c, int16_t d, int16_t tx, int16_t ty)
Definition: movenc.c:1578
static int mp4_get_codec_tag(AVFormatContext *s, MOVTrack *track)
Definition: movenc.c:821
static int flags
Definition: cpu.c:23
packed RGB 5:5:5, 16bpp, (msb)1A 5R 5G 5B(lsb), big-endian, most significant bit to 0 ...
Definition: pixfmt.h:116
long sample_count
Definition: movenc.h:85
static int mov_write_udta_tag(AVIOContext *pb, MOVMuxContext *mov, AVFormatContext *s)
Definition: movenc.c:2184
static int mov_write_trailer(AVFormatContext *s)
Definition: movenc.c:3846
int64_t start
Definition: avformat.h:921
#define FF_MOV_FLAG_FRAG_KEYFRAME
Definition: movenc.h:176
int vos_len
Definition: movenc.h:102
int packet_seq
Definition: movenc.h:137
static int mov_write_3gp_udta_tag(AVIOContext *pb, AVFormatContext *s, const char *tag, const char *str)
Definition: movenc.c:2136
static int mov_write_mvhd_tag(AVIOContext *pb, MOVMuxContext *mov)
Definition: movenc.c:1877
int entry
Definition: movenc.h:80
Main libavformat public API header.
static int mov_write_tfrf_tags(AVIOContext *pb, MOVMuxContext *mov, MOVTrack *track)
Definition: movenc.c:2647
static int mov_write_trun_tag(AVIOContext *pb, MOVTrack *track)
Definition: movenc.c:2547
planar YUV 4:2:0, 12bpp, (1 Cr & Cb sample per 2x2 Y samples)
Definition: pixfmt.h:68
static int mov_write_tfra_tag(AVIOContext *pb, MOVTrack *track)
Definition: movenc.c:2721
#define AV_LOG_DEBUG
Stuff which is only useful for libav* developers.
Definition: log.h:162
static void flush_put_bits(PutBitContext *s)
Pad the end of the output stream with zeros.
Definition: put_bits.h:81
#define MOV_TFHD_BASE_DATA_OFFSET
Definition: isom.h:179
static uint32_t get_sample_flags(MOVTrack *track, MOVIentry *entry)
Definition: movenc.c:2541
#define MOV_SYNC_SAMPLE
Definition: movenc.h:52
static int mov_write_tfxd_tag(AVIOContext *pb, MOVTrack *track)
Definition: movenc.c:2591
static double c[64]
packed RGB 16:16:16, 48bpp, 16R, 16G, 16B, the 2-byte value for each R/G/B component is stored as big...
Definition: pixfmt.h:111
int ff_put_wav_header(AVIOContext *pb, AVCodecContext *enc)
AVRational time_base
time base in which the start/end timestamps are specified
Definition: avformat.h:920
void av_init_packet(AVPacket *pkt)
Initialize optional fields of a packet with default values.
Definition: avpacket.c:56
static int mov_write_mdia_tag(AVIOContext *pb, MOVTrack *track)
Definition: movenc.c:1563
int64_t nb_frames
number of frames in this stream if known or 0
Definition: avformat.h:698
char * key
Definition: dict.h:81
static void init_put_bits(PutBitContext *s, uint8_t *buffer, int buffer_size)
Initialize the PutBitContext s.
Definition: put_bits.h:54
int den
denominator
Definition: rational.h:45
unsigned bps
Definition: movenc.c:895
static int mov_create_timecode_track(AVFormatContext *s, int index, int src_index, const char *tcstr)
Definition: movenc.c:3446
#define MODE_IPOD
Definition: movenc.h:40
static int mov_write_tmpo_tag(AVIOContext *pb, AVFormatContext *s)
Definition: movenc.c:2003
static int mov_write_tfhd_tag(AVIOContext *pb, MOVTrack *track, int64_t moof_offset)
Definition: movenc.c:2494
static int mov_write_audio_tag(AVIOContext *pb, MOVTrack *track)
Definition: movenc.c:644
static int mov_write_iods_tag(AVIOContext *pb, MOVMuxContext *mov)
Definition: movenc.c:1824
static int mov_write_stss_tag(AVIOContext *pb, MOVTrack *track, uint32_t flag)
Definition: movenc.c:199
MOVIentry * cluster
Definition: movenc.h:104
char * value
Definition: dict.h:82
int len
static int mov_write_mfra_tag(AVIOContext *pb, MOVMuxContext *mov)
Definition: movenc.c:2745
int channels
number of audio channels
static int mov_write_string_data_tag(AVIOContext *pb, const char *data, int lang, int long_style)
Definition: movenc.c:1946
long chunkCount
Definition: movenc.h:87
void * priv_data
Format private data.
Definition: avformat.h:964
static int mov_write_header(AVFormatContext *s)
Definition: movenc.c:3490
static void write_header(FFV1Context *f)
Definition: ffv1enc.c:470
static int64_t update_size(AVIOContext *pb, int64_t pos)
Definition: movenc.c:77
#define MOV_TRUN_DATA_OFFSET
Definition: isom.h:186
static av_always_inline int vc1_unescape_buffer(const uint8_t *src, int size, uint8_t *dst)
Definition: vc1.h:422
int has_keyframes
Definition: movenc.h:88
#define LIBAVCODEC_IDENT
int64_t dts
Decompression timestamp in AVStream->time_base units; the time at which the packet is decompressed...
static int mov_write_ftyp_tag(AVIOContext *pb, AVFormatContext *s)
Definition: movenc.c:2783
void avio_wb32(AVIOContext *s, unsigned int val)
Definition: aviobuf.c:299
#define AV_LOG_INFO
Definition: log.h:156
void INT64 INT64 count
Definition: avisynth_c.h:594
static const AVCodecTag codec_ipod_tags[]
Definition: movenc.c:839
static unsigned compute_avg_bitrate(MOVTrack *track)
Definition: movenc.c:315
enum AVFieldOrder field_order
Field order.
void INT64 start
Definition: avisynth_c.h:594
#define AV_DICT_IGNORE_SUFFIX
Definition: dict.h:68
static int mov_write_rtp_tag(AVIOContext *pb, MOVTrack *track)
Definition: movenc.c:1174
static int mov_write_tref_tag(AVIOContext *pb, MOVTrack *track)
Definition: movenc.c:1749
#define MODE_F4V
Definition: movenc.h:42
int ff_mov_write_packet(AVFormatContext *s, AVPacket *pkt)
Definition: movenc.c:3120
int track_id
Definition: movenc.h:98
static int mov_get_lpcm_flags(enum AVCodecID codec_id)
Compute flags for &#39;lpcm&#39; tag.
Definition: movenc.c:583
static int mov_write_stbl_tag(AVIOContext *pb, MOVTrack *track)
Definition: movenc.c:1304
#define MODE_MOV
Definition: movenc.h:35
AVRational time_base
This is the fundamental unit of time (in seconds) in terms of which frame timestamps are represented...
Definition: avformat.h:679
uint32_t ff_mov_get_channel_layout_tag(enum AVCodecID codec_id, uint64_t channel_layout, uint32_t *bitmap)
Get the channel layout tag for the specified codec id and channel layout.
Definition: mov_chan.c:494
static int ipod_get_codec_tag(AVFormatContext *s, MOVTrack *track)
Definition: movenc.c:850
static int mov_write_stsd_tag(AVIOContext *pb, MOVTrack *track)
Definition: movenc.c:1194
#define CONFIG_LIBX264_ENCODER
Definition: config.h:1169
#define MKTAG(a, b, c, d)
Definition: common.h:282
uint32_t flags
flags such as drop frame, +24 hours support, ...
#define MODE_ISM
Definition: movenc.h:41
AVPixelFormat
Pixel format.
Definition: pixfmt.h:66
char * ff_data_to_hex(char *buf, const uint8_t *src, int size, int lowercase)
This structure stores compressed data.
int secondary
Definition: movenc.h:97
int64_t offset
Definition: movenc.h:72
int min_fragment_duration
Definition: movenc.h:165
MOVTrack * tracks
Definition: movenc.h:152
int strict_std_compliance
strictly follow the standard (MPEG4, ...).
int64_t pts
Presentation timestamp in AVStream->time_base units; the time at which the decompressed packet will b...
int ff_isom_write_avcc(AVIOContext *pb, const uint8_t *data, int len)
Definition: avc.c:106
#define t2
Definition: regdef.h:30
#define FFMAX3(a, b, c)
Definition: common.h:57
int nb_streams
Definition: movenc.h:147
#define AV_NOPTS_VALUE
Undefined timestamp value.
Definition: avutil.h:190
static av_always_inline const uint8_t * find_next_marker(const uint8_t *src, const uint8_t *end)
Find VC-1 marker in buffer.
Definition: vc1.h:408
timecode is drop frame
uint32_t default_size
Definition: movenc.h:120
int avio_printf(AVIOContext *s, const char *fmt,...) av_printf_format(2
#define MOV_FRAG_SAMPLE_FLAG_IS_NON_SYNC
Definition: isom.h:194
static int compute_moov_size(AVFormatContext *s)
This function gets the moov size if moved to the top of the file: the chunk offset table can switch b...
Definition: movenc.c:3758
static int get_moov_size(AVFormatContext *s)
Definition: movenc.c:2985
bitstream writer API