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