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