Merge commit 'ee37620b6ae4783cda637408422044b2d14a688c'
[ffmpeg.git] / 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/ac3_parser.h"
35 #include "libavcodec/get_bits.h"
36 #include "libavcodec/put_bits.h"
37 #include "libavcodec/vc1_common.h"
38 #include "libavcodec/raw.h"
39 #include "internal.h"
40 #include "libavutil/avstring.h"
41 #include "libavutil/intfloat.h"
42 #include "libavutil/mathematics.h"
43 #include "libavutil/opt.h"
44 #include "libavutil/dict.h"
45 #include "libavutil/pixdesc.h"
46 #include "libavutil/timecode.h"
47 #include "hevc.h"
48 #include "rtpenc.h"
49 #include "mov_chan.h"
50
51 #undef NDEBUG
52 #include <assert.h>
53
54 static const AVOption options[] = {
55     { "movflags", "MOV muxer flags", offsetof(MOVMuxContext, flags), AV_OPT_TYPE_FLAGS, {.i64 = 0}, INT_MIN, INT_MAX, AV_OPT_FLAG_ENCODING_PARAM, "movflags" },
56     { "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" },
57     { "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 },
58     { "empty_moov", "Make the initial moov atom empty", 0, AV_OPT_TYPE_CONST, {.i64 = FF_MOV_FLAG_EMPTY_MOOV}, INT_MIN, INT_MAX, AV_OPT_FLAG_ENCODING_PARAM, "movflags" },
59     { "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" },
60     { "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" },
61     { "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" },
62     { "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" },
63     { "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" },
64     { "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" },
65     { "disable_chpl", "Disable Nero chapter atom", 0, AV_OPT_TYPE_CONST, {.i64 = FF_MOV_FLAG_DISABLE_CHPL}, INT_MIN, INT_MAX, AV_OPT_FLAG_ENCODING_PARAM, "movflags" },
66     { "default_base_moof", "Set the default-base-is-moof flag in tfhd atoms", 0, AV_OPT_TYPE_CONST, {.i64 = FF_MOV_FLAG_DEFAULT_BASE_MOOF}, INT_MIN, INT_MAX, AV_OPT_FLAG_ENCODING_PARAM, "movflags" },
67     { "dash", "Write DASH compatible fragmented MP4", 0, AV_OPT_TYPE_CONST, {.i64 = FF_MOV_FLAG_DASH}, INT_MIN, INT_MAX, AV_OPT_FLAG_ENCODING_PARAM, "movflags" },
68     { "frag_discont", "Signal that the next fragment is discontinuous from earlier ones", 0, AV_OPT_TYPE_CONST, {.i64 = FF_MOV_FLAG_FRAG_DISCONT}, INT_MIN, INT_MAX, AV_OPT_FLAG_ENCODING_PARAM, "movflags" },
69     FF_RTP_FLAG_OPTS(MOVMuxContext, rtp_flags),
70     { "skip_iods", "Skip writing iods atom.", offsetof(MOVMuxContext, iods_skip), AV_OPT_TYPE_INT, {.i64 = 1}, 0, 1, AV_OPT_FLAG_ENCODING_PARAM},
71     { "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},
72     { "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},
73     { "frag_duration", "Maximum fragment duration", offsetof(MOVMuxContext, max_fragment_duration), AV_OPT_TYPE_INT, {.i64 = 0}, 0, INT_MAX, AV_OPT_FLAG_ENCODING_PARAM},
74     { "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},
75     { "frag_size", "Maximum fragment size", offsetof(MOVMuxContext, max_fragment_size), AV_OPT_TYPE_INT, {.i64 = 0}, 0, INT_MAX, AV_OPT_FLAG_ENCODING_PARAM},
76     { "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},
77     { "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},
78     { "brand",    "Override major brand", offsetof(MOVMuxContext, major_brand),   AV_OPT_TYPE_STRING, {.str = NULL}, .flags = AV_OPT_FLAG_ENCODING_PARAM },
79     { "use_editlist", "use edit list", offsetof(MOVMuxContext, use_editlist), AV_OPT_TYPE_INT, {.i64 = -1}, -1, 1, AV_OPT_FLAG_ENCODING_PARAM},
80     { NULL },
81 };
82
83 #define MOV_CLASS(flavor)\
84 static const AVClass flavor ## _muxer_class = {\
85     .class_name = #flavor " muxer",\
86     .item_name  = av_default_item_name,\
87     .option     = options,\
88     .version    = LIBAVUTIL_VERSION_INT,\
89 };
90
91 static int get_moov_size(AVFormatContext *s);
92
93 static int utf8len(const uint8_t *b)
94 {
95     int len = 0;
96     int val;
97     while (*b) {
98         GET_UTF8(val, *b++, return -1;)
99         len++;
100     }
101     return len;
102 }
103
104 //FIXME support 64 bit variant with wide placeholders
105 static int64_t update_size(AVIOContext *pb, int64_t pos)
106 {
107     int64_t curpos = avio_tell(pb);
108     avio_seek(pb, pos, SEEK_SET);
109     avio_wb32(pb, curpos - pos); /* rewrite size */
110     avio_seek(pb, curpos, SEEK_SET);
111
112     return curpos - pos;
113 }
114
115 static int co64_required(const MOVTrack *track)
116 {
117     if (track->entry > 0 && track->cluster[track->entry - 1].pos + track->data_offset > UINT32_MAX)
118         return 1;
119     return 0;
120 }
121
122 /* Chunk offset atom */
123 static int mov_write_stco_tag(AVIOContext *pb, MOVTrack *track)
124 {
125     int i;
126     int mode64 = co64_required(track); // use 32 bit size variant if possible
127     int64_t pos = avio_tell(pb);
128     avio_wb32(pb, 0); /* size */
129     if (mode64)
130         ffio_wfourcc(pb, "co64");
131     else
132         ffio_wfourcc(pb, "stco");
133     avio_wb32(pb, 0); /* version & flags */
134     avio_wb32(pb, track->chunkCount); /* entry count */
135     for (i = 0; i < track->entry; i++) {
136         if (!track->cluster[i].chunkNum)
137             continue;
138         if (mode64 == 1)
139             avio_wb64(pb, track->cluster[i].pos + track->data_offset);
140         else
141             avio_wb32(pb, track->cluster[i].pos + track->data_offset);
142     }
143     return update_size(pb, pos);
144 }
145
146 /* Sample size atom */
147 static int mov_write_stsz_tag(AVIOContext *pb, MOVTrack *track)
148 {
149     int equalChunks = 1;
150     int i, j, entries = 0, tst = -1, oldtst = -1;
151
152     int64_t pos = avio_tell(pb);
153     avio_wb32(pb, 0); /* size */
154     ffio_wfourcc(pb, "stsz");
155     avio_wb32(pb, 0); /* version & flags */
156
157     for (i = 0; i < track->entry; i++) {
158         tst = track->cluster[i].size / track->cluster[i].entries;
159         if (oldtst != -1 && tst != oldtst)
160             equalChunks = 0;
161         oldtst = tst;
162         entries += track->cluster[i].entries;
163     }
164     if (equalChunks && track->entry) {
165         int sSize = track->entry ? track->cluster[0].size / track->cluster[0].entries : 0;
166         sSize = FFMAX(1, sSize); // adpcm mono case could make sSize == 0
167         avio_wb32(pb, sSize); // sample size
168         avio_wb32(pb, entries); // sample count
169     } else {
170         avio_wb32(pb, 0); // sample size
171         avio_wb32(pb, entries); // sample count
172         for (i = 0; i < track->entry; i++) {
173             for (j = 0; j < track->cluster[i].entries; j++) {
174                 avio_wb32(pb, track->cluster[i].size /
175                           track->cluster[i].entries);
176             }
177         }
178     }
179     return update_size(pb, pos);
180 }
181
182 /* Sample to chunk atom */
183 static int mov_write_stsc_tag(AVIOContext *pb, MOVTrack *track)
184 {
185     int index = 0, oldval = -1, i;
186     int64_t entryPos, curpos;
187
188     int64_t pos = avio_tell(pb);
189     avio_wb32(pb, 0); /* size */
190     ffio_wfourcc(pb, "stsc");
191     avio_wb32(pb, 0); // version & flags
192     entryPos = avio_tell(pb);
193     avio_wb32(pb, track->chunkCount); // entry count
194     for (i = 0; i < track->entry; i++) {
195         if (oldval != track->cluster[i].samples_in_chunk && track->cluster[i].chunkNum) {
196             avio_wb32(pb, track->cluster[i].chunkNum); // first chunk
197             avio_wb32(pb, track->cluster[i].samples_in_chunk); // samples per chunk
198             avio_wb32(pb, 0x1); // sample description index
199             oldval = track->cluster[i].samples_in_chunk;
200             index++;
201         }
202     }
203     curpos = avio_tell(pb);
204     avio_seek(pb, entryPos, SEEK_SET);
205     avio_wb32(pb, index); // rewrite size
206     avio_seek(pb, curpos, SEEK_SET);
207
208     return update_size(pb, pos);
209 }
210
211 /* Sync sample atom */
212 static int mov_write_stss_tag(AVIOContext *pb, MOVTrack *track, uint32_t flag)
213 {
214     int64_t curpos, entryPos;
215     int i, index = 0;
216     int64_t pos = avio_tell(pb);
217     avio_wb32(pb, 0); // size
218     ffio_wfourcc(pb, flag == MOV_SYNC_SAMPLE ? "stss" : "stps");
219     avio_wb32(pb, 0); // version & flags
220     entryPos = avio_tell(pb);
221     avio_wb32(pb, track->entry); // entry count
222     for (i = 0; i < track->entry; i++) {
223         if (track->cluster[i].flags & flag) {
224             avio_wb32(pb, i + 1);
225             index++;
226         }
227     }
228     curpos = avio_tell(pb);
229     avio_seek(pb, entryPos, SEEK_SET);
230     avio_wb32(pb, index); // rewrite size
231     avio_seek(pb, curpos, SEEK_SET);
232     return update_size(pb, pos);
233 }
234
235 static int mov_write_amr_tag(AVIOContext *pb, MOVTrack *track)
236 {
237     avio_wb32(pb, 0x11); /* size */
238     if (track->mode == MODE_MOV) ffio_wfourcc(pb, "samr");
239     else                         ffio_wfourcc(pb, "damr");
240     ffio_wfourcc(pb, "FFMP");
241     avio_w8(pb, 0); /* decoder version */
242
243     avio_wb16(pb, 0x81FF); /* Mode set (all modes for AMR_NB) */
244     avio_w8(pb, 0x00); /* Mode change period (no restriction) */
245     avio_w8(pb, 0x01); /* Frames per sample */
246     return 0x11;
247 }
248
249 static int mov_write_ac3_tag(AVIOContext *pb, MOVTrack *track)
250 {
251     GetBitContext gbc;
252     PutBitContext pbc;
253     uint8_t buf[3];
254     int fscod, bsid, bsmod, acmod, lfeon, frmsizecod;
255
256     if (track->vos_len < 7)
257         return -1;
258
259     avio_wb32(pb, 11);
260     ffio_wfourcc(pb, "dac3");
261
262     init_get_bits(&gbc, track->vos_data + 4, (track->vos_len - 4) * 8);
263     fscod      = get_bits(&gbc, 2);
264     frmsizecod = get_bits(&gbc, 6);
265     bsid       = get_bits(&gbc, 5);
266     bsmod      = get_bits(&gbc, 3);
267     acmod      = get_bits(&gbc, 3);
268     if (acmod == 2) {
269         skip_bits(&gbc, 2); // dsurmod
270     } else {
271         if ((acmod & 1) && acmod != 1)
272             skip_bits(&gbc, 2); // cmixlev
273         if (acmod & 4)
274             skip_bits(&gbc, 2); // surmixlev
275     }
276     lfeon = get_bits1(&gbc);
277
278     init_put_bits(&pbc, buf, sizeof(buf));
279     put_bits(&pbc, 2, fscod);
280     put_bits(&pbc, 5, bsid);
281     put_bits(&pbc, 3, bsmod);
282     put_bits(&pbc, 3, acmod);
283     put_bits(&pbc, 1, lfeon);
284     put_bits(&pbc, 5, frmsizecod >> 1); // bit_rate_code
285     put_bits(&pbc, 5, 0); // reserved
286
287     flush_put_bits(&pbc);
288     avio_write(pb, buf, sizeof(buf));
289
290     return 11;
291 }
292
293 struct eac3_info {
294     AVPacket pkt;
295     uint8_t ec3_done;
296     uint8_t num_blocks;
297
298     /* Layout of the EC3SpecificBox */
299     /* maximum bitrate */
300     uint16_t data_rate;
301     /* number of independent substreams */
302     uint8_t  num_ind_sub;
303     struct {
304         /* sample rate code (see ff_ac3_sample_rate_tab) 2 bits */
305         uint8_t fscod;
306         /* bit stream identification 5 bits */
307         uint8_t bsid;
308         /* one bit reserved */
309         /* audio service mixing (not supported yet) 1 bit */
310         /* bit stream mode 3 bits */
311         uint8_t bsmod;
312         /* audio coding mode 3 bits */
313         uint8_t acmod;
314         /* sub woofer on 1 bit */
315         uint8_t lfeon;
316         /* 3 bits reserved */
317         /* number of dependent substreams associated with this substream 4 bits */
318         uint8_t num_dep_sub;
319         /* channel locations of the dependent substream(s), if any, 9 bits */
320         uint16_t chan_loc;
321         /* if there is no dependent substream, then one bit reserved instead */
322     } substream[1]; /* TODO: support 8 independent substreams */
323 };
324
325 static int handle_eac3(MOVMuxContext *mov, AVPacket *pkt, MOVTrack *track)
326 {
327     GetBitContext gbc;
328     AC3HeaderInfo tmp, *hdr = &tmp;
329     struct eac3_info *info;
330     int num_blocks;
331
332     if (!track->eac3_priv && !(track->eac3_priv = av_mallocz(sizeof(*info))))
333         return AVERROR(ENOMEM);
334     info = track->eac3_priv;
335
336     init_get_bits(&gbc, pkt->data, pkt->size * 8);
337     if (avpriv_ac3_parse_header2(&gbc, &hdr) < 0) {
338         /* drop the packets until we see a good one */
339         if (!track->entry) {
340             av_log(mov, AV_LOG_WARNING, "Dropping invalid packet from start of the stream\n");
341             return 0;
342         }
343         return AVERROR_INVALIDDATA;
344     }
345
346     info->data_rate = FFMAX(info->data_rate, hdr->bit_rate / 1000);
347     num_blocks = hdr->num_blocks;
348
349     if (!info->ec3_done) {
350         /* AC-3 substream must be the first one */
351         if (hdr->bitstream_id <= 10 && hdr->substreamid != 0)
352             return AVERROR(EINVAL);
353
354         /* this should always be the case, given that our AC-3 parser
355          * concatenates dependent frames to their independent parent */
356         if (hdr->frame_type == EAC3_FRAME_TYPE_INDEPENDENT) {
357             /* substream ids must be incremental */
358             if (hdr->substreamid > info->num_ind_sub + 1)
359                 return AVERROR(EINVAL);
360
361             if (hdr->substreamid == info->num_ind_sub + 1) {
362                 //info->num_ind_sub++;
363                 avpriv_request_sample(track->enc, "Multiple independent substreams");
364                 return AVERROR_PATCHWELCOME;
365             } else if (hdr->substreamid < info->num_ind_sub ||
366                        hdr->substreamid == 0 && info->substream[0].bsid) {
367                 info->ec3_done = 1;
368                 goto concatenate;
369             }
370         }
371
372         /* fill the info needed for the "dec3" atom */
373         info->substream[hdr->substreamid].fscod = hdr->sr_code;
374         info->substream[hdr->substreamid].bsid  = hdr->bitstream_id;
375         info->substream[hdr->substreamid].bsmod = hdr->bitstream_mode;
376         info->substream[hdr->substreamid].acmod = hdr->channel_mode;
377         info->substream[hdr->substreamid].lfeon = hdr->lfe_on;
378
379         /* Parse dependent substream(s), if any */
380         if (pkt->size != hdr->frame_size) {
381             int cumul_size = hdr->frame_size;
382             int parent = hdr->substreamid;
383
384             while (cumul_size != pkt->size) {
385                 int i;
386                 init_get_bits(&gbc, pkt->data + cumul_size, (pkt->size - cumul_size) * 8);
387                 if (avpriv_ac3_parse_header2(&gbc, &hdr) < 0)
388                     return AVERROR_INVALIDDATA;
389                 if (hdr->frame_type != EAC3_FRAME_TYPE_DEPENDENT)
390                     return AVERROR(EINVAL);
391                 cumul_size += hdr->frame_size;
392                 info->substream[parent].num_dep_sub++;
393
394                 /* header is parsed up to lfeon, but custom channel map may be needed */
395                 /* skip bsid */
396                 skip_bits(&gbc, 5);
397                 /* skip volume control params */
398                 for (i = 0; i < (hdr->channel_mode ? 1 : 2); i++) {
399                     skip_bits(&gbc, 5); // skip dialog normalization
400                     if (get_bits1(&gbc)) {
401                         skip_bits(&gbc, 8); // skip compression gain word
402                     }
403                 }
404                 /* get the dependent stream channel map, if exists */
405                 if (get_bits1(&gbc))
406                     info->substream[parent].chan_loc |= (get_bits(&gbc, 16) >> 5) & 0x1f;
407                 else
408                     info->substream[parent].chan_loc |= hdr->channel_mode;
409             }
410         }
411     }
412
413 concatenate:
414     if (!info->num_blocks && num_blocks == 6)
415         return pkt->size;
416     else if (info->num_blocks + num_blocks > 6)
417         return AVERROR_INVALIDDATA;
418
419     if (!info->num_blocks) {
420         int ret;
421         if ((ret = av_copy_packet(&info->pkt, pkt)) < 0)
422             return ret;
423         info->num_blocks = num_blocks;
424         return 0;
425     } else {
426         int ret;
427         if ((ret = av_grow_packet(&info->pkt, pkt->size)) < 0)
428             return ret;
429         memcpy(info->pkt.data + info->pkt.size - pkt->size, pkt->data, pkt->size);
430         info->num_blocks += num_blocks;
431         info->pkt.duration += pkt->duration;
432         if ((ret = av_copy_packet_side_data(&info->pkt, pkt)) < 0)
433             return ret;
434         if (info->num_blocks != 6)
435             return 0;
436         av_free_packet(pkt);
437         if ((ret = av_copy_packet(pkt, &info->pkt)) < 0)
438             return ret;
439         av_free_packet(&info->pkt);
440         info->num_blocks = 0;
441     }
442
443     return pkt->size;
444 }
445
446 static int mov_write_eac3_tag(AVIOContext *pb, MOVTrack *track)
447 {
448     PutBitContext pbc;
449     uint8_t *buf;
450     struct eac3_info *info;
451     int size, i;
452
453     if (!track->eac3_priv)
454         return AVERROR(EINVAL);
455
456     info = track->eac3_priv;
457     size = 2 + 4 * (info->num_ind_sub + 1);
458     buf = av_malloc(size);
459     if (!buf) {
460         size = AVERROR(ENOMEM);
461         goto end;
462     }
463
464     init_put_bits(&pbc, buf, size);
465     put_bits(&pbc, 13, info->data_rate);
466     put_bits(&pbc,  3, info->num_ind_sub);
467     for (i = 0; i <= info->num_ind_sub; i++) {
468         put_bits(&pbc, 2, info->substream[i].fscod);
469         put_bits(&pbc, 5, info->substream[i].bsid);
470         put_bits(&pbc, 1, 0); /* reserved */
471         put_bits(&pbc, 1, 0); /* asvc */
472         put_bits(&pbc, 3, info->substream[i].bsmod);
473         put_bits(&pbc, 3, info->substream[i].acmod);
474         put_bits(&pbc, 1, info->substream[i].lfeon);
475         put_bits(&pbc, 5, 0); /* reserved */
476         put_bits(&pbc, 4, info->substream[i].num_dep_sub);
477         if (!info->substream[i].num_dep_sub) {
478             put_bits(&pbc, 1, 0); /* reserved */
479             size--;
480         } else {
481             put_bits(&pbc, 9, info->substream[i].chan_loc);
482         }
483     }
484     flush_put_bits(&pbc);
485
486     avio_wb32(pb, size + 8);
487     ffio_wfourcc(pb, "dec3");
488     avio_write(pb, buf, size);
489
490     av_free(buf);
491
492 end:
493     av_free_packet(&info->pkt);
494     av_freep(&track->eac3_priv);
495
496     return size;
497 }
498
499 /**
500  * This function writes extradata "as is".
501  * Extradata must be formatted like a valid atom (with size and tag).
502  */
503 static int mov_write_extradata_tag(AVIOContext *pb, MOVTrack *track)
504 {
505     avio_write(pb, track->enc->extradata, track->enc->extradata_size);
506     return track->enc->extradata_size;
507 }
508
509 static int mov_write_enda_tag(AVIOContext *pb)
510 {
511     avio_wb32(pb, 10);
512     ffio_wfourcc(pb, "enda");
513     avio_wb16(pb, 1); /* little endian */
514     return 10;
515 }
516
517 static int mov_write_enda_tag_be(AVIOContext *pb)
518 {
519   avio_wb32(pb, 10);
520   ffio_wfourcc(pb, "enda");
521   avio_wb16(pb, 0); /* big endian */
522   return 10;
523 }
524
525 static void put_descr(AVIOContext *pb, int tag, unsigned int size)
526 {
527     int i = 3;
528     avio_w8(pb, tag);
529     for (; i > 0; i--)
530         avio_w8(pb, (size >> (7 * i)) | 0x80);
531     avio_w8(pb, size & 0x7F);
532 }
533
534 static unsigned compute_avg_bitrate(MOVTrack *track)
535 {
536     uint64_t size = 0;
537     int i;
538     if (!track->track_duration)
539         return 0;
540     for (i = 0; i < track->entry; i++)
541         size += track->cluster[i].size;
542     return size * 8 * track->timescale / track->track_duration;
543 }
544
545 static int mov_write_esds_tag(AVIOContext *pb, MOVTrack *track) // Basic
546 {
547     int64_t pos = avio_tell(pb);
548     int decoder_specific_info_len = track->vos_len ? 5 + track->vos_len : 0;
549     unsigned avg_bitrate;
550
551     avio_wb32(pb, 0); // size
552     ffio_wfourcc(pb, "esds");
553     avio_wb32(pb, 0); // Version
554
555     // ES descriptor
556     put_descr(pb, 0x03, 3 + 5+13 + decoder_specific_info_len + 5+1);
557     avio_wb16(pb, track->track_id);
558     avio_w8(pb, 0x00); // flags (= no flags)
559
560     // DecoderConfig descriptor
561     put_descr(pb, 0x04, 13 + decoder_specific_info_len);
562
563     // Object type indication
564     if ((track->enc->codec_id == AV_CODEC_ID_MP2 ||
565          track->enc->codec_id == AV_CODEC_ID_MP3) &&
566         track->enc->sample_rate > 24000)
567         avio_w8(pb, 0x6B); // 11172-3
568     else
569         avio_w8(pb, ff_codec_get_tag(ff_mp4_obj_type, track->enc->codec_id));
570
571     // the following fields is made of 6 bits to identify the streamtype (4 for video, 5 for audio)
572     // plus 1 bit to indicate upstream and 1 bit set to 1 (reserved)
573     if (track->enc->codec_id == AV_CODEC_ID_DVD_SUBTITLE)
574         avio_w8(pb, (0x38 << 2) | 1); // flags (= NeroSubpicStream)
575     else if (track->enc->codec_type == AVMEDIA_TYPE_AUDIO)
576         avio_w8(pb, 0x15); // flags (= Audiostream)
577     else
578         avio_w8(pb, 0x11); // flags (= Visualstream)
579
580     avio_wb24(pb, track->enc->rc_buffer_size >> 3); // Buffersize DB
581
582     avg_bitrate = compute_avg_bitrate(track);
583     // maxbitrate (FIXME should be max rate in any 1 sec window)
584     avio_wb32(pb, FFMAX3(track->enc->bit_rate, track->enc->rc_max_rate, avg_bitrate));
585     avio_wb32(pb, avg_bitrate);
586
587     if (track->vos_len) {
588         // DecoderSpecific info descriptor
589         put_descr(pb, 0x05, track->vos_len);
590         avio_write(pb, track->vos_data, track->vos_len);
591     }
592
593     // SL descriptor
594     put_descr(pb, 0x06, 1);
595     avio_w8(pb, 0x02);
596     return update_size(pb, pos);
597 }
598
599 static int mov_pcm_le_gt16(enum AVCodecID codec_id)
600 {
601     return codec_id == AV_CODEC_ID_PCM_S24LE ||
602            codec_id == AV_CODEC_ID_PCM_S32LE ||
603            codec_id == AV_CODEC_ID_PCM_F32LE ||
604            codec_id == AV_CODEC_ID_PCM_F64LE;
605 }
606
607 static int mov_pcm_be_gt16(enum AVCodecID codec_id)
608 {
609     return codec_id == AV_CODEC_ID_PCM_S24BE ||
610            codec_id == AV_CODEC_ID_PCM_S32BE ||
611            codec_id == AV_CODEC_ID_PCM_F32BE ||
612            codec_id == AV_CODEC_ID_PCM_F64BE;
613 }
614
615 static int mov_write_ms_tag(AVIOContext *pb, MOVTrack *track)
616 {
617     int ret;
618     int64_t pos = avio_tell(pb);
619     avio_wb32(pb, 0);
620     avio_wl32(pb, track->tag); // store it byteswapped
621     track->enc->codec_tag = av_bswap16(track->tag >> 16);
622     if ((ret = ff_put_wav_header(pb, track->enc, 0)) < 0)
623         return ret;
624     return update_size(pb, pos);
625 }
626
627 static int mov_write_wfex_tag(AVIOContext *pb, MOVTrack *track)
628 {
629     int ret;
630     int64_t pos = avio_tell(pb);
631     avio_wb32(pb, 0);
632     ffio_wfourcc(pb, "wfex");
633     if ((ret = ff_put_wav_header(pb, track->enc, FF_PUT_WAV_HEADER_FORCE_WAVEFORMATEX)) < 0)
634         return ret;
635     return update_size(pb, pos);
636 }
637
638 static int mov_write_chan_tag(AVIOContext *pb, MOVTrack *track)
639 {
640     uint32_t layout_tag, bitmap;
641     int64_t pos = avio_tell(pb);
642
643     layout_tag = ff_mov_get_channel_layout_tag(track->enc->codec_id,
644                                                track->enc->channel_layout,
645                                                &bitmap);
646     if (!layout_tag) {
647         av_log(track->enc, AV_LOG_WARNING, "not writing 'chan' tag due to "
648                "lack of channel information\n");
649         return 0;
650     }
651
652     if (track->multichannel_as_mono)
653         return 0;
654
655     avio_wb32(pb, 0);           // Size
656     ffio_wfourcc(pb, "chan");   // Type
657     avio_w8(pb, 0);             // Version
658     avio_wb24(pb, 0);           // Flags
659     avio_wb32(pb, layout_tag);  // mChannelLayoutTag
660     avio_wb32(pb, bitmap);      // mChannelBitmap
661     avio_wb32(pb, 0);           // mNumberChannelDescriptions
662
663     return update_size(pb, pos);
664 }
665
666 static int mov_write_wave_tag(AVIOContext *pb, MOVTrack *track)
667 {
668     int64_t pos = avio_tell(pb);
669
670     avio_wb32(pb, 0);     /* size */
671     ffio_wfourcc(pb, "wave");
672
673     if (track->enc->codec_id != AV_CODEC_ID_QDM2) {
674     avio_wb32(pb, 12);    /* size */
675     ffio_wfourcc(pb, "frma");
676     avio_wl32(pb, track->tag);
677     }
678
679     if (track->enc->codec_id == AV_CODEC_ID_AAC) {
680         /* useless atom needed by mplayer, ipod, not needed by quicktime */
681         avio_wb32(pb, 12); /* size */
682         ffio_wfourcc(pb, "mp4a");
683         avio_wb32(pb, 0);
684         mov_write_esds_tag(pb, track);
685     } else if (mov_pcm_le_gt16(track->enc->codec_id))  {
686       mov_write_enda_tag(pb);
687     } else if (mov_pcm_be_gt16(track->enc->codec_id))  {
688       mov_write_enda_tag_be(pb);
689     } else if (track->enc->codec_id == AV_CODEC_ID_AMR_NB) {
690         mov_write_amr_tag(pb, track);
691     } else if (track->enc->codec_id == AV_CODEC_ID_AC3) {
692         mov_write_ac3_tag(pb, track);
693     } else if (track->enc->codec_id == AV_CODEC_ID_EAC3) {
694         mov_write_eac3_tag(pb, track);
695     } else if (track->enc->codec_id == AV_CODEC_ID_ALAC ||
696                track->enc->codec_id == AV_CODEC_ID_QDM2) {
697         mov_write_extradata_tag(pb, track);
698     } else if (track->enc->codec_id == AV_CODEC_ID_ADPCM_MS ||
699                track->enc->codec_id == AV_CODEC_ID_ADPCM_IMA_WAV) {
700         mov_write_ms_tag(pb, track);
701     }
702
703     avio_wb32(pb, 8);     /* size */
704     avio_wb32(pb, 0);     /* null tag */
705
706     return update_size(pb, pos);
707 }
708
709 static int mov_write_dvc1_structs(MOVTrack *track, uint8_t *buf)
710 {
711     uint8_t *unescaped;
712     const uint8_t *start, *next, *end = track->vos_data + track->vos_len;
713     int unescaped_size, seq_found = 0;
714     int level = 0, interlace = 0;
715     int packet_seq   = track->vc1_info.packet_seq;
716     int packet_entry = track->vc1_info.packet_entry;
717     int slices       = track->vc1_info.slices;
718     PutBitContext pbc;
719
720     if (track->start_dts == AV_NOPTS_VALUE) {
721         /* No packets written yet, vc1_info isn't authoritative yet. */
722         /* Assume inline sequence and entry headers. This will be
723          * overwritten at the end if the file is seekable. */
724         packet_seq = packet_entry = 1;
725     }
726
727     unescaped = av_mallocz(track->vos_len + FF_INPUT_BUFFER_PADDING_SIZE);
728     if (!unescaped)
729         return AVERROR(ENOMEM);
730     start = find_next_marker(track->vos_data, end);
731     for (next = start; next < end; start = next) {
732         GetBitContext gb;
733         int size;
734         next = find_next_marker(start + 4, end);
735         size = next - start - 4;
736         if (size <= 0)
737             continue;
738         unescaped_size = vc1_unescape_buffer(start + 4, size, unescaped);
739         init_get_bits(&gb, unescaped, 8 * unescaped_size);
740         if (AV_RB32(start) == VC1_CODE_SEQHDR) {
741             int profile = get_bits(&gb, 2);
742             if (profile != PROFILE_ADVANCED) {
743                 av_free(unescaped);
744                 return AVERROR(ENOSYS);
745             }
746             seq_found = 1;
747             level = get_bits(&gb, 3);
748             /* chromaformat, frmrtq_postproc, bitrtq_postproc, postprocflag,
749              * width, height */
750             skip_bits_long(&gb, 2 + 3 + 5 + 1 + 2*12);
751             skip_bits(&gb, 1); /* broadcast */
752             interlace = get_bits1(&gb);
753             skip_bits(&gb, 4); /* tfcntrflag, finterpflag, reserved, psf */
754         }
755     }
756     if (!seq_found) {
757         av_free(unescaped);
758         return AVERROR(ENOSYS);
759     }
760
761     init_put_bits(&pbc, buf, 7);
762     /* VC1DecSpecStruc */
763     put_bits(&pbc, 4, 12); /* profile - advanced */
764     put_bits(&pbc, 3, level);
765     put_bits(&pbc, 1, 0); /* reserved */
766     /* VC1AdvDecSpecStruc */
767     put_bits(&pbc, 3, level);
768     put_bits(&pbc, 1, 0); /* cbr */
769     put_bits(&pbc, 6, 0); /* reserved */
770     put_bits(&pbc, 1, !interlace); /* no interlace */
771     put_bits(&pbc, 1, !packet_seq); /* no multiple seq */
772     put_bits(&pbc, 1, !packet_entry); /* no multiple entry */
773     put_bits(&pbc, 1, !slices); /* no slice code */
774     put_bits(&pbc, 1, 0); /* no bframe */
775     put_bits(&pbc, 1, 0); /* reserved */
776
777     /* framerate */
778     if (track->st->avg_frame_rate.num > 0 && track->st->avg_frame_rate.den > 0)
779         put_bits32(&pbc, track->st->avg_frame_rate.num / track->st->avg_frame_rate.den);
780     else
781         put_bits32(&pbc, 0xffffffff);
782
783     flush_put_bits(&pbc);
784
785     av_free(unescaped);
786
787     return 0;
788 }
789
790 static int mov_write_dvc1_tag(AVIOContext *pb, MOVTrack *track)
791 {
792     uint8_t buf[7] = { 0 };
793     int ret;
794
795     if ((ret = mov_write_dvc1_structs(track, buf)) < 0)
796         return ret;
797
798     avio_wb32(pb, track->vos_len + 8 + sizeof(buf));
799     ffio_wfourcc(pb, "dvc1");
800     track->vc1_info.struct_offset = avio_tell(pb);
801     avio_write(pb, buf, sizeof(buf));
802     avio_write(pb, track->vos_data, track->vos_len);
803
804     return 0;
805 }
806
807 static int mov_write_glbl_tag(AVIOContext *pb, MOVTrack *track)
808 {
809     avio_wb32(pb, track->vos_len + 8);
810     ffio_wfourcc(pb, "glbl");
811     avio_write(pb, track->vos_data, track->vos_len);
812     return 8 + track->vos_len;
813 }
814
815 /**
816  * Compute flags for 'lpcm' tag.
817  * See CoreAudioTypes and AudioStreamBasicDescription at Apple.
818  */
819 static int mov_get_lpcm_flags(enum AVCodecID codec_id)
820 {
821     switch (codec_id) {
822     case AV_CODEC_ID_PCM_F32BE:
823     case AV_CODEC_ID_PCM_F64BE:
824         return 11;
825     case AV_CODEC_ID_PCM_F32LE:
826     case AV_CODEC_ID_PCM_F64LE:
827         return 9;
828     case AV_CODEC_ID_PCM_U8:
829         return 10;
830     case AV_CODEC_ID_PCM_S16BE:
831     case AV_CODEC_ID_PCM_S24BE:
832     case AV_CODEC_ID_PCM_S32BE:
833         return 14;
834     case AV_CODEC_ID_PCM_S8:
835     case AV_CODEC_ID_PCM_S16LE:
836     case AV_CODEC_ID_PCM_S24LE:
837     case AV_CODEC_ID_PCM_S32LE:
838         return 12;
839     default:
840         return 0;
841     }
842 }
843
844 static int get_cluster_duration(MOVTrack *track, int cluster_idx)
845 {
846     int64_t next_dts;
847
848     if (cluster_idx >= track->entry)
849         return 0;
850
851     if (cluster_idx + 1 == track->entry)
852         next_dts = track->track_duration + track->start_dts;
853     else
854         next_dts = track->cluster[cluster_idx + 1].dts;
855
856     next_dts -= track->cluster[cluster_idx].dts;
857
858     av_assert0(next_dts >= 0);
859     av_assert0(next_dts <= INT_MAX);
860
861     return next_dts;
862 }
863
864 static int get_samples_per_packet(MOVTrack *track)
865 {
866     int i, first_duration;
867
868 // return track->enc->frame_size;
869
870     /* use 1 for raw PCM */
871     if (!track->audio_vbr)
872         return 1;
873
874     /* check to see if duration is constant for all clusters */
875     if (!track->entry)
876         return 0;
877     first_duration = get_cluster_duration(track, 0);
878     for (i = 1; i < track->entry; i++) {
879         if (get_cluster_duration(track, i) != first_duration)
880             return 0;
881     }
882     return first_duration;
883 }
884
885 static int mov_write_audio_tag(AVIOContext *pb, MOVTrack *track)
886 {
887     int64_t pos = avio_tell(pb);
888     int version = 0;
889     uint32_t tag = track->tag;
890
891     if (track->mode == MODE_MOV) {
892         if (track->timescale > UINT16_MAX) {
893             if (mov_get_lpcm_flags(track->enc->codec_id))
894                 tag = AV_RL32("lpcm");
895             version = 2;
896         } else if (track->audio_vbr || mov_pcm_le_gt16(track->enc->codec_id) ||
897                    mov_pcm_be_gt16(track->enc->codec_id) ||
898                    track->enc->codec_id == AV_CODEC_ID_ADPCM_MS ||
899                    track->enc->codec_id == AV_CODEC_ID_ADPCM_IMA_WAV ||
900                    track->enc->codec_id == AV_CODEC_ID_QDM2) {
901             version = 1;
902         }
903     }
904
905     avio_wb32(pb, 0); /* size */
906     avio_wl32(pb, tag); // store it byteswapped
907     avio_wb32(pb, 0); /* Reserved */
908     avio_wb16(pb, 0); /* Reserved */
909     avio_wb16(pb, 1); /* Data-reference index, XXX  == 1 */
910
911     /* SoundDescription */
912     avio_wb16(pb, version); /* Version */
913     avio_wb16(pb, 0); /* Revision level */
914     avio_wb32(pb, 0); /* Reserved */
915
916     if (version == 2) {
917         avio_wb16(pb, 3);
918         avio_wb16(pb, 16);
919         avio_wb16(pb, 0xfffe);
920         avio_wb16(pb, 0);
921         avio_wb32(pb, 0x00010000);
922         avio_wb32(pb, 72);
923         avio_wb64(pb, av_double2int(track->enc->sample_rate));
924         avio_wb32(pb, track->enc->channels);
925         avio_wb32(pb, 0x7F000000);
926         avio_wb32(pb, av_get_bits_per_sample(track->enc->codec_id));
927         avio_wb32(pb, mov_get_lpcm_flags(track->enc->codec_id));
928         avio_wb32(pb, track->sample_size);
929         avio_wb32(pb, get_samples_per_packet(track));
930     } else {
931         if (track->mode == MODE_MOV) {
932             avio_wb16(pb, track->enc->channels);
933             if (track->enc->codec_id == AV_CODEC_ID_PCM_U8 ||
934                 track->enc->codec_id == AV_CODEC_ID_PCM_S8)
935                 avio_wb16(pb, 8); /* bits per sample */
936             else if (track->enc->codec_id == AV_CODEC_ID_ADPCM_G726)
937                 avio_wb16(pb, track->enc->bits_per_coded_sample);
938             else
939                 avio_wb16(pb, 16);
940             avio_wb16(pb, track->audio_vbr ? -2 : 0); /* compression ID */
941         } else { /* reserved for mp4/3gp */
942             avio_wb16(pb, 2);
943             avio_wb16(pb, 16);
944             avio_wb16(pb, 0);
945         }
946
947         avio_wb16(pb, 0); /* packet size (= 0) */
948         avio_wb16(pb, track->enc->sample_rate <= UINT16_MAX ?
949                       track->enc->sample_rate : 0);
950         avio_wb16(pb, 0); /* Reserved */
951     }
952
953     if (version == 1) { /* SoundDescription V1 extended info */
954         if (mov_pcm_le_gt16(track->enc->codec_id) ||
955             mov_pcm_be_gt16(track->enc->codec_id))
956             avio_wb32(pb, 1); /*  must be 1 for  uncompressed formats */
957         else
958             avio_wb32(pb, track->enc->frame_size); /* Samples per packet */
959         avio_wb32(pb, track->sample_size / track->enc->channels); /* Bytes per packet */
960         avio_wb32(pb, track->sample_size); /* Bytes per frame */
961         avio_wb32(pb, 2); /* Bytes per sample */
962     }
963
964     if (track->mode == MODE_MOV &&
965         (track->enc->codec_id == AV_CODEC_ID_AAC           ||
966          track->enc->codec_id == AV_CODEC_ID_AC3           ||
967          track->enc->codec_id == AV_CODEC_ID_EAC3          ||
968          track->enc->codec_id == AV_CODEC_ID_AMR_NB        ||
969          track->enc->codec_id == AV_CODEC_ID_ALAC          ||
970          track->enc->codec_id == AV_CODEC_ID_ADPCM_MS      ||
971          track->enc->codec_id == AV_CODEC_ID_ADPCM_IMA_WAV ||
972          track->enc->codec_id == AV_CODEC_ID_QDM2          ||
973          (mov_pcm_le_gt16(track->enc->codec_id) && version==1) ||
974          (mov_pcm_be_gt16(track->enc->codec_id) && version==1)))
975         mov_write_wave_tag(pb, track);
976     else if (track->tag == MKTAG('m','p','4','a'))
977         mov_write_esds_tag(pb, track);
978     else if (track->enc->codec_id == AV_CODEC_ID_AMR_NB)
979         mov_write_amr_tag(pb, track);
980     else if (track->enc->codec_id == AV_CODEC_ID_AC3)
981         mov_write_ac3_tag(pb, track);
982     else if (track->enc->codec_id == AV_CODEC_ID_EAC3)
983         mov_write_eac3_tag(pb, track);
984     else if (track->enc->codec_id == AV_CODEC_ID_ALAC)
985         mov_write_extradata_tag(pb, track);
986     else if (track->enc->codec_id == AV_CODEC_ID_WMAPRO)
987         mov_write_wfex_tag(pb, track);
988     else if (track->vos_len > 0)
989         mov_write_glbl_tag(pb, track);
990
991     if (track->mode == MODE_MOV && track->enc->codec_type == AVMEDIA_TYPE_AUDIO)
992         mov_write_chan_tag(pb, track);
993
994     return update_size(pb, pos);
995 }
996
997 static int mov_write_d263_tag(AVIOContext *pb)
998 {
999     avio_wb32(pb, 0xf); /* size */
1000     ffio_wfourcc(pb, "d263");
1001     ffio_wfourcc(pb, "FFMP");
1002     avio_w8(pb, 0); /* decoder version */
1003     /* FIXME use AVCodecContext level/profile, when encoder will set values */
1004     avio_w8(pb, 0xa); /* level */
1005     avio_w8(pb, 0); /* profile */
1006     return 0xf;
1007 }
1008
1009 static int mov_write_avcc_tag(AVIOContext *pb, MOVTrack *track)
1010 {
1011     int64_t pos = avio_tell(pb);
1012
1013     avio_wb32(pb, 0);
1014     ffio_wfourcc(pb, "avcC");
1015     ff_isom_write_avcc(pb, track->vos_data, track->vos_len);
1016     return update_size(pb, pos);
1017 }
1018
1019 static int mov_write_hvcc_tag(AVIOContext *pb, MOVTrack *track)
1020 {
1021     int64_t pos = avio_tell(pb);
1022
1023     avio_wb32(pb, 0);
1024     ffio_wfourcc(pb, "hvcC");
1025     ff_isom_write_hvcc(pb, track->vos_data, track->vos_len, 0);
1026     return update_size(pb, pos);
1027 }
1028
1029 /* also used by all avid codecs (dv, imx, meridien) and their variants */
1030 static int mov_write_avid_tag(AVIOContext *pb, MOVTrack *track)
1031 {
1032     int i;
1033     avio_wb32(pb, 24); /* size */
1034     ffio_wfourcc(pb, "ACLR");
1035     ffio_wfourcc(pb, "ACLR");
1036     ffio_wfourcc(pb, "0001");
1037     if (track->enc->color_range == AVCOL_RANGE_MPEG) { /* Legal range (16-235) */
1038         avio_wb32(pb, 1); /* Corresponds to 709 in official encoder */
1039     } else { /* Full range (0-255) */
1040         avio_wb32(pb, 2); /* Corresponds to RGB in official encoder */
1041     }
1042     avio_wb32(pb, 0); /* unknown */
1043
1044     avio_wb32(pb, 24); /* size */
1045     ffio_wfourcc(pb, "APRG");
1046     ffio_wfourcc(pb, "APRG");
1047     ffio_wfourcc(pb, "0001");
1048     avio_wb32(pb, 1); /* unknown */
1049     avio_wb32(pb, 0); /* unknown */
1050
1051     avio_wb32(pb, 120); /* size */
1052     ffio_wfourcc(pb, "ARES");
1053     ffio_wfourcc(pb, "ARES");
1054     ffio_wfourcc(pb, "0001");
1055     avio_wb32(pb, AV_RB32(track->vos_data + 0x28)); /* dnxhd cid, some id ? */
1056     avio_wb32(pb, track->enc->width);
1057     /* values below are based on samples created with quicktime and avid codecs */
1058     if (track->vos_data[5] & 2) { // interlaced
1059         avio_wb32(pb, track->enc->height / 2);
1060         avio_wb32(pb, 2); /* unknown */
1061         avio_wb32(pb, 0); /* unknown */
1062         avio_wb32(pb, 4); /* unknown */
1063     } else {
1064         avio_wb32(pb, track->enc->height);
1065         avio_wb32(pb, 1); /* unknown */
1066         avio_wb32(pb, 0); /* unknown */
1067         if (track->enc->height == 1080)
1068             avio_wb32(pb, 5); /* unknown */
1069         else
1070             avio_wb32(pb, 6); /* unknown */
1071     }
1072     /* padding */
1073     for (i = 0; i < 10; i++)
1074         avio_wb64(pb, 0);
1075
1076     /* extra padding for stsd needed */
1077     avio_wb32(pb, 0);
1078     return 0;
1079 }
1080
1081 static int mp4_get_codec_tag(AVFormatContext *s, MOVTrack *track)
1082 {
1083     int tag = track->enc->codec_tag;
1084
1085     if (!ff_codec_get_tag(ff_mp4_obj_type, track->enc->codec_id))
1086         return 0;
1087
1088     if      (track->enc->codec_id == AV_CODEC_ID_H264)      tag = MKTAG('a','v','c','1');
1089     else if (track->enc->codec_id == AV_CODEC_ID_HEVC)      tag = MKTAG('h','e','v','1');
1090     else if (track->enc->codec_id == AV_CODEC_ID_AC3)       tag = MKTAG('a','c','-','3');
1091     else if (track->enc->codec_id == AV_CODEC_ID_EAC3)      tag = MKTAG('e','c','-','3');
1092     else if (track->enc->codec_id == AV_CODEC_ID_DIRAC)     tag = MKTAG('d','r','a','c');
1093     else if (track->enc->codec_id == AV_CODEC_ID_MOV_TEXT)  tag = MKTAG('t','x','3','g');
1094     else if (track->enc->codec_id == AV_CODEC_ID_VC1)       tag = MKTAG('v','c','-','1');
1095     else if (track->enc->codec_type == AVMEDIA_TYPE_VIDEO)  tag = MKTAG('m','p','4','v');
1096     else if (track->enc->codec_type == AVMEDIA_TYPE_AUDIO)  tag = MKTAG('m','p','4','a');
1097     else if (track->enc->codec_id == AV_CODEC_ID_DVD_SUBTITLE)  tag = MKTAG('m','p','4','s');
1098
1099     return tag;
1100 }
1101
1102 static const AVCodecTag codec_ipod_tags[] = {
1103     { AV_CODEC_ID_H264,     MKTAG('a','v','c','1') },
1104     { AV_CODEC_ID_MPEG4,    MKTAG('m','p','4','v') },
1105     { AV_CODEC_ID_AAC,      MKTAG('m','p','4','a') },
1106     { AV_CODEC_ID_ALAC,     MKTAG('a','l','a','c') },
1107     { AV_CODEC_ID_AC3,      MKTAG('a','c','-','3') },
1108     { AV_CODEC_ID_MOV_TEXT, MKTAG('t','x','3','g') },
1109     { AV_CODEC_ID_MOV_TEXT, MKTAG('t','e','x','t') },
1110     { AV_CODEC_ID_NONE, 0 },
1111 };
1112
1113 static int ipod_get_codec_tag(AVFormatContext *s, MOVTrack *track)
1114 {
1115     int tag = track->enc->codec_tag;
1116
1117     // keep original tag for subs, ipod supports both formats
1118     if (!(track->enc->codec_type == AVMEDIA_TYPE_SUBTITLE &&
1119           (tag == MKTAG('t', 'x', '3', 'g') ||
1120            tag == MKTAG('t', 'e', 'x', 't'))))
1121         tag = ff_codec_get_tag(codec_ipod_tags, track->enc->codec_id);
1122
1123     if (!av_match_ext(s->filename, "m4a") &&
1124         !av_match_ext(s->filename, "m4b") &&
1125         !av_match_ext(s->filename, "m4v"))
1126         av_log(s, AV_LOG_WARNING, "Warning, extension is not .m4a, .m4v nor  .m4b "
1127                "Quicktime/Ipod might not play the file\n");
1128
1129     return tag;
1130 }
1131
1132 static int mov_get_dv_codec_tag(AVFormatContext *s, MOVTrack *track)
1133 {
1134     int tag;
1135
1136     if (track->enc->width == 720) { /* SD */
1137         if (track->enc->height == 480) { /* NTSC */
1138             if  (track->enc->pix_fmt == AV_PIX_FMT_YUV422P) tag = MKTAG('d','v','5','n');
1139             else                                            tag = MKTAG('d','v','c',' ');
1140        }else if (track->enc->pix_fmt == AV_PIX_FMT_YUV422P) tag = MKTAG('d','v','5','p');
1141         else if (track->enc->pix_fmt == AV_PIX_FMT_YUV420P) tag = MKTAG('d','v','c','p');
1142         else                                                tag = MKTAG('d','v','p','p');
1143     } else if (track->enc->height == 720) { /* HD 720 line */
1144         if  (track->st->time_base.den == 50)                tag = MKTAG('d','v','h','q');
1145         else                                                tag = MKTAG('d','v','h','p');
1146     } else if (track->enc->height == 1080) { /* HD 1080 line */
1147         if  (track->st->time_base.den == 25)                tag = MKTAG('d','v','h','5');
1148         else                                                tag = MKTAG('d','v','h','6');
1149     } else {
1150         av_log(s, AV_LOG_ERROR, "unsupported height for dv codec\n");
1151         return 0;
1152     }
1153
1154     return tag;
1155 }
1156
1157 static AVRational find_fps(AVFormatContext *s, AVStream *st)
1158 {
1159     AVRational rate = {st->codec->time_base.den, st->codec->time_base.num};
1160     /* if the codec time base makes no sense, try to fallback on stream frame rate */
1161     if (av_timecode_check_frame_rate(rate) < 0) {
1162         av_log(s, AV_LOG_DEBUG, "timecode: tbc=%d/%d invalid, fallback on %d/%d\n",
1163                rate.num, rate.den, st->avg_frame_rate.num, st->avg_frame_rate.den);
1164         rate = st->avg_frame_rate;
1165     }
1166
1167     return rate;
1168 }
1169
1170 static int mov_get_mpeg2_xdcam_codec_tag(AVFormatContext *s, MOVTrack *track)
1171 {
1172     int tag = track->enc->codec_tag;
1173     int interlaced = track->enc->field_order > AV_FIELD_PROGRESSIVE;
1174     AVStream *st = track->st;
1175     int rate = av_q2d(find_fps(s, st));
1176
1177     if (!tag)
1178         tag = MKTAG('m', '2', 'v', '1'); //fallback tag
1179
1180     if (track->enc->pix_fmt == AV_PIX_FMT_YUV420P) {
1181         if (track->enc->width == 1280 && track->enc->height == 720) {
1182             if (!interlaced) {
1183                 if      (rate == 24) tag = MKTAG('x','d','v','4');
1184                 else if (rate == 25) tag = MKTAG('x','d','v','5');
1185                 else if (rate == 30) tag = MKTAG('x','d','v','1');
1186                 else if (rate == 50) tag = MKTAG('x','d','v','a');
1187                 else if (rate == 60) tag = MKTAG('x','d','v','9');
1188             }
1189         } else if (track->enc->width == 1440 && track->enc->height == 1080) {
1190             if (!interlaced) {
1191                 if      (rate == 24) tag = MKTAG('x','d','v','6');
1192                 else if (rate == 25) tag = MKTAG('x','d','v','7');
1193                 else if (rate == 30) tag = MKTAG('x','d','v','8');
1194             } else {
1195                 if      (rate == 25) tag = MKTAG('x','d','v','3');
1196                 else if (rate == 30) tag = MKTAG('x','d','v','2');
1197             }
1198         } else if (track->enc->width == 1920 && track->enc->height == 1080) {
1199             if (!interlaced) {
1200                 if      (rate == 24) tag = MKTAG('x','d','v','d');
1201                 else if (rate == 25) tag = MKTAG('x','d','v','e');
1202                 else if (rate == 30) tag = MKTAG('x','d','v','f');
1203             } else {
1204                 if      (rate == 25) tag = MKTAG('x','d','v','c');
1205                 else if (rate == 30) tag = MKTAG('x','d','v','b');
1206             }
1207         }
1208     } else if (track->enc->pix_fmt == AV_PIX_FMT_YUV422P) {
1209         if (track->enc->width == 1280 && track->enc->height == 720) {
1210             if (!interlaced) {
1211                 if      (rate == 24) tag = MKTAG('x','d','5','4');
1212                 else if (rate == 25) tag = MKTAG('x','d','5','5');
1213                 else if (rate == 30) tag = MKTAG('x','d','5','1');
1214                 else if (rate == 50) tag = MKTAG('x','d','5','a');
1215                 else if (rate == 60) tag = MKTAG('x','d','5','9');
1216             }
1217         } else if (track->enc->width == 1920 && track->enc->height == 1080) {
1218             if (!interlaced) {
1219                 if      (rate == 24) tag = MKTAG('x','d','5','d');
1220                 else if (rate == 25) tag = MKTAG('x','d','5','e');
1221                 else if (rate == 30) tag = MKTAG('x','d','5','f');
1222             } else {
1223                 if      (rate == 25) tag = MKTAG('x','d','5','c');
1224                 else if (rate == 30) tag = MKTAG('x','d','5','b');
1225             }
1226         }
1227     }
1228
1229     return tag;
1230 }
1231
1232 static int mov_get_h264_codec_tag(AVFormatContext *s, MOVTrack *track)
1233 {
1234     int tag = track->enc->codec_tag;
1235     int interlaced = track->enc->field_order > AV_FIELD_PROGRESSIVE;
1236     AVStream *st = track->st;
1237     int rate = av_q2d(find_fps(s, st));
1238
1239     if (!tag)
1240         tag = MKTAG('a', 'v', 'c', 'i'); //fallback tag
1241
1242     if (track->enc->pix_fmt == AV_PIX_FMT_YUV420P10) {
1243         if (track->enc->width == 960 && track->enc->height == 720) {
1244             if (!interlaced) {
1245                 if      (rate == 24) tag = MKTAG('a','i','5','p');
1246                 else if (rate == 25) tag = MKTAG('a','i','5','q');
1247                 else if (rate == 30) tag = MKTAG('a','i','5','p');
1248                 else if (rate == 50) tag = MKTAG('a','i','5','q');
1249                 else if (rate == 60) tag = MKTAG('a','i','5','p');
1250             }
1251         } else if (track->enc->width == 1440 && track->enc->height == 1080) {
1252             if (!interlaced) {
1253                 if      (rate == 24) tag = MKTAG('a','i','5','3');
1254                 else if (rate == 25) tag = MKTAG('a','i','5','2');
1255                 else if (rate == 30) tag = MKTAG('a','i','5','3');
1256             } else {
1257                 if      (rate == 50) tag = MKTAG('a','i','5','5');
1258                 else if (rate == 60) tag = MKTAG('a','i','5','6');
1259             }
1260         }
1261     } else if (track->enc->pix_fmt == AV_PIX_FMT_YUV422P10) {
1262         if (track->enc->width == 1280 && track->enc->height == 720) {
1263             if (!interlaced) {
1264                 if      (rate == 24) tag = MKTAG('a','i','1','p');
1265                 else if (rate == 25) tag = MKTAG('a','i','1','q');
1266                 else if (rate == 30) tag = MKTAG('a','i','1','p');
1267                 else if (rate == 50) tag = MKTAG('a','i','1','q');
1268                 else if (rate == 60) tag = MKTAG('a','i','1','p');
1269             }
1270         } else if (track->enc->width == 1920 && track->enc->height == 1080) {
1271             if (!interlaced) {
1272                 if      (rate == 24) tag = MKTAG('a','i','1','3');
1273                 else if (rate == 25) tag = MKTAG('a','i','1','2');
1274                 else if (rate == 30) tag = MKTAG('a','i','1','3');
1275             } else {
1276                 if      (rate == 25) tag = MKTAG('a','i','1','5');
1277                 else if (rate == 50) tag = MKTAG('a','i','1','5');
1278                 else if (rate == 60) tag = MKTAG('a','i','1','6');
1279             }
1280         }
1281     }
1282
1283     return tag;
1284 }
1285
1286 static const struct {
1287     enum AVPixelFormat pix_fmt;
1288     uint32_t tag;
1289     unsigned bps;
1290 } mov_pix_fmt_tags[] = {
1291     { AV_PIX_FMT_YUYV422, MKTAG('y','u','v','2'),  0 },
1292     { AV_PIX_FMT_YUYV422, MKTAG('y','u','v','s'),  0 },
1293     { AV_PIX_FMT_UYVY422, MKTAG('2','v','u','y'),  0 },
1294     { AV_PIX_FMT_RGB555BE,MKTAG('r','a','w',' '), 16 },
1295     { AV_PIX_FMT_RGB555LE,MKTAG('L','5','5','5'), 16 },
1296     { AV_PIX_FMT_RGB565LE,MKTAG('L','5','6','5'), 16 },
1297     { AV_PIX_FMT_RGB565BE,MKTAG('B','5','6','5'), 16 },
1298     { AV_PIX_FMT_GRAY16BE,MKTAG('b','1','6','g'), 16 },
1299     { AV_PIX_FMT_RGB24,   MKTAG('r','a','w',' '), 24 },
1300     { AV_PIX_FMT_BGR24,   MKTAG('2','4','B','G'), 24 },
1301     { AV_PIX_FMT_ARGB,    MKTAG('r','a','w',' '), 32 },
1302     { AV_PIX_FMT_BGRA,    MKTAG('B','G','R','A'), 32 },
1303     { AV_PIX_FMT_RGBA,    MKTAG('R','G','B','A'), 32 },
1304     { AV_PIX_FMT_ABGR,    MKTAG('A','B','G','R'), 32 },
1305     { AV_PIX_FMT_RGB48BE, MKTAG('b','4','8','r'), 48 },
1306 };
1307
1308 static int mov_get_rawvideo_codec_tag(AVFormatContext *s, MOVTrack *track)
1309 {
1310     int tag = track->enc->codec_tag;
1311     int i;
1312     enum AVPixelFormat pix_fmt;
1313
1314     for (i = 0; i < FF_ARRAY_ELEMS(mov_pix_fmt_tags); i++) {
1315         if (track->enc->pix_fmt == mov_pix_fmt_tags[i].pix_fmt) {
1316             tag = mov_pix_fmt_tags[i].tag;
1317             track->enc->bits_per_coded_sample = mov_pix_fmt_tags[i].bps;
1318             if (track->enc->codec_tag == mov_pix_fmt_tags[i].tag)
1319                 break;
1320         }
1321     }
1322
1323     pix_fmt = avpriv_find_pix_fmt(avpriv_pix_fmt_bps_mov,
1324                                   track->enc->bits_per_coded_sample);
1325     if (tag == MKTAG('r','a','w',' ') &&
1326         track->enc->pix_fmt != pix_fmt &&
1327         track->enc->pix_fmt != AV_PIX_FMT_NONE)
1328         av_log(s, AV_LOG_ERROR, "%s rawvideo cannot be written to mov, output file will be unreadable\n",
1329                av_get_pix_fmt_name(track->enc->pix_fmt));
1330     return tag;
1331 }
1332
1333 static int mov_get_codec_tag(AVFormatContext *s, MOVTrack *track)
1334 {
1335     int tag = track->enc->codec_tag;
1336
1337     if (!tag || (s->strict_std_compliance >= FF_COMPLIANCE_NORMAL &&
1338                  (track->enc->codec_id == AV_CODEC_ID_DVVIDEO ||
1339                   track->enc->codec_id == AV_CODEC_ID_RAWVIDEO ||
1340                   track->enc->codec_id == AV_CODEC_ID_H263 ||
1341                   track->enc->codec_id == AV_CODEC_ID_H264 ||
1342                   track->enc->codec_id == AV_CODEC_ID_MPEG2VIDEO ||
1343                   av_get_bits_per_sample(track->enc->codec_id)))) { // pcm audio
1344         if (track->enc->codec_id == AV_CODEC_ID_DVVIDEO)
1345             tag = mov_get_dv_codec_tag(s, track);
1346         else if (track->enc->codec_id == AV_CODEC_ID_RAWVIDEO)
1347             tag = mov_get_rawvideo_codec_tag(s, track);
1348         else if (track->enc->codec_id == AV_CODEC_ID_MPEG2VIDEO)
1349             tag = mov_get_mpeg2_xdcam_codec_tag(s, track);
1350         else if (track->enc->codec_id == AV_CODEC_ID_H264)
1351             tag = mov_get_h264_codec_tag(s, track);
1352         else if (track->enc->codec_type == AVMEDIA_TYPE_VIDEO) {
1353             tag = ff_codec_get_tag(ff_codec_movvideo_tags, track->enc->codec_id);
1354             if (!tag) { // if no mac fcc found, try with Microsoft tags
1355                 tag = ff_codec_get_tag(ff_codec_bmp_tags, track->enc->codec_id);
1356                 if (tag)
1357                     av_log(s, AV_LOG_WARNING, "Using MS style video codec tag, "
1358                            "the file may be unplayable!\n");
1359             }
1360         } else if (track->enc->codec_type == AVMEDIA_TYPE_AUDIO) {
1361             tag = ff_codec_get_tag(ff_codec_movaudio_tags, track->enc->codec_id);
1362             if (!tag) { // if no mac fcc found, try with Microsoft tags
1363                 int ms_tag = ff_codec_get_tag(ff_codec_wav_tags, track->enc->codec_id);
1364                 if (ms_tag) {
1365                     tag = MKTAG('m', 's', ((ms_tag >> 8) & 0xff), (ms_tag & 0xff));
1366                     av_log(s, AV_LOG_WARNING, "Using MS style audio codec tag, "
1367                            "the file may be unplayable!\n");
1368                 }
1369             }
1370         } else if (track->enc->codec_type == AVMEDIA_TYPE_SUBTITLE)
1371             tag = ff_codec_get_tag(ff_codec_movsubtitle_tags, track->enc->codec_id);
1372     }
1373
1374     return tag;
1375 }
1376
1377 static const AVCodecTag codec_3gp_tags[] = {
1378     { AV_CODEC_ID_H263,     MKTAG('s','2','6','3') },
1379     { AV_CODEC_ID_H264,     MKTAG('a','v','c','1') },
1380     { AV_CODEC_ID_MPEG4,    MKTAG('m','p','4','v') },
1381     { AV_CODEC_ID_AAC,      MKTAG('m','p','4','a') },
1382     { AV_CODEC_ID_AMR_NB,   MKTAG('s','a','m','r') },
1383     { AV_CODEC_ID_AMR_WB,   MKTAG('s','a','w','b') },
1384     { AV_CODEC_ID_MOV_TEXT, MKTAG('t','x','3','g') },
1385     { AV_CODEC_ID_NONE, 0 },
1386 };
1387
1388 static const AVCodecTag codec_f4v_tags[] = { // XXX: add GIF/PNG/JPEG?
1389     { AV_CODEC_ID_MP3,    MKTAG('.','m','p','3') },
1390     { AV_CODEC_ID_AAC,    MKTAG('m','p','4','a') },
1391     { AV_CODEC_ID_H264,   MKTAG('a','v','c','1') },
1392     { AV_CODEC_ID_VP6A,   MKTAG('V','P','6','A') },
1393     { AV_CODEC_ID_VP6F,   MKTAG('V','P','6','F') },
1394     { AV_CODEC_ID_NONE, 0 },
1395 };
1396
1397 static int mov_find_codec_tag(AVFormatContext *s, MOVTrack *track)
1398 {
1399     int tag;
1400
1401     if (track->mode == MODE_MP4 || track->mode == MODE_PSP)
1402         tag = mp4_get_codec_tag(s, track);
1403     else if (track->mode == MODE_ISM) {
1404         tag = mp4_get_codec_tag(s, track);
1405         if (!tag && track->enc->codec_id == AV_CODEC_ID_WMAPRO)
1406             tag = MKTAG('w', 'm', 'a', ' ');
1407     } else if (track->mode == MODE_IPOD)
1408         tag = ipod_get_codec_tag(s, track);
1409     else if (track->mode & MODE_3GP)
1410         tag = ff_codec_get_tag(codec_3gp_tags, track->enc->codec_id);
1411     else if (track->mode == MODE_F4V)
1412         tag = ff_codec_get_tag(codec_f4v_tags, track->enc->codec_id);
1413     else
1414         tag = mov_get_codec_tag(s, track);
1415
1416     return tag;
1417 }
1418
1419 /** Write uuid atom.
1420  * Needed to make file play in iPods running newest firmware
1421  * goes after avcC atom in moov.trak.mdia.minf.stbl.stsd.avc1
1422  */
1423 static int mov_write_uuid_tag_ipod(AVIOContext *pb)
1424 {
1425     avio_wb32(pb, 28);
1426     ffio_wfourcc(pb, "uuid");
1427     avio_wb32(pb, 0x6b6840f2);
1428     avio_wb32(pb, 0x5f244fc5);
1429     avio_wb32(pb, 0xba39a51b);
1430     avio_wb32(pb, 0xcf0323f3);
1431     avio_wb32(pb, 0x0);
1432     return 28;
1433 }
1434
1435 static const uint16_t fiel_data[] = {
1436     0x0000, 0x0100, 0x0201, 0x0206, 0x0209, 0x020e
1437 };
1438
1439 static int mov_write_fiel_tag(AVIOContext *pb, MOVTrack *track)
1440 {
1441     unsigned mov_field_order = 0;
1442     if (track->enc->field_order < FF_ARRAY_ELEMS(fiel_data))
1443         mov_field_order = fiel_data[track->enc->field_order];
1444     else
1445         return 0;
1446     avio_wb32(pb, 10);
1447     ffio_wfourcc(pb, "fiel");
1448     avio_wb16(pb, mov_field_order);
1449     return 10;
1450 }
1451
1452 static int mov_write_subtitle_tag(AVIOContext *pb, MOVTrack *track)
1453 {
1454     int64_t pos = avio_tell(pb);
1455     avio_wb32(pb, 0);    /* size */
1456     avio_wl32(pb, track->tag); // store it byteswapped
1457     avio_wb32(pb, 0);    /* Reserved */
1458     avio_wb16(pb, 0);    /* Reserved */
1459     avio_wb16(pb, 1);    /* Data-reference index */
1460
1461     if (track->enc->codec_id == AV_CODEC_ID_DVD_SUBTITLE)
1462         mov_write_esds_tag(pb, track);
1463     else if (track->enc->extradata_size)
1464         avio_write(pb, track->enc->extradata, track->enc->extradata_size);
1465
1466     return update_size(pb, pos);
1467 }
1468
1469 static int mov_write_pasp_tag(AVIOContext *pb, MOVTrack *track)
1470 {
1471     AVRational sar;
1472     av_reduce(&sar.num, &sar.den, track->enc->sample_aspect_ratio.num,
1473               track->enc->sample_aspect_ratio.den, INT_MAX);
1474
1475     avio_wb32(pb, 16);
1476     ffio_wfourcc(pb, "pasp");
1477     avio_wb32(pb, sar.num);
1478     avio_wb32(pb, sar.den);
1479     return 16;
1480 }
1481
1482 static void find_compressor(char * compressor_name, int len, MOVTrack *track)
1483 {
1484     AVDictionaryEntry *encoder;
1485     int xdcam_res =  (track->enc->width == 1280 && track->enc->height == 720)
1486                   || (track->enc->width == 1440 && track->enc->height == 1080)
1487                   || (track->enc->width == 1920 && track->enc->height == 1080);
1488
1489     if (track->mode == MODE_MOV &&
1490         (encoder = av_dict_get(track->st->metadata, "encoder", NULL, 0))) {
1491         av_strlcpy(compressor_name, encoder->value, 32);
1492     } else if (track->enc->codec_id == AV_CODEC_ID_MPEG2VIDEO && xdcam_res) {
1493         int interlaced = track->enc->field_order > AV_FIELD_PROGRESSIVE;
1494         AVStream *st = track->st;
1495         int rate = av_q2d(find_fps(NULL, st));
1496         av_strlcatf(compressor_name, len, "XDCAM");
1497         if (track->enc->pix_fmt == AV_PIX_FMT_YUV422P) {
1498             av_strlcatf(compressor_name, len, " HD422");
1499         } else if(track->enc->width == 1440) {
1500             av_strlcatf(compressor_name, len, " HD");
1501         } else
1502             av_strlcatf(compressor_name, len, " EX");
1503
1504         av_strlcatf(compressor_name, len, " %d%c", track->enc->height, interlaced ? 'i' : 'p');
1505
1506         av_strlcatf(compressor_name, len, "%d", rate * (interlaced + 1));
1507     }
1508 }
1509
1510 static int mov_write_video_tag(AVIOContext *pb, MOVTrack *track)
1511 {
1512     int64_t pos = avio_tell(pb);
1513     char compressor_name[32] = { 0 };
1514
1515     avio_wb32(pb, 0); /* size */
1516     avio_wl32(pb, track->tag); // store it byteswapped
1517     avio_wb32(pb, 0); /* Reserved */
1518     avio_wb16(pb, 0); /* Reserved */
1519     avio_wb16(pb, 1); /* Data-reference index */
1520
1521     avio_wb16(pb, 0); /* Codec stream version */
1522     avio_wb16(pb, 0); /* Codec stream revision (=0) */
1523     if (track->mode == MODE_MOV) {
1524         ffio_wfourcc(pb, "FFMP"); /* Vendor */
1525         if (track->enc->codec_id == AV_CODEC_ID_RAWVIDEO) {
1526             avio_wb32(pb, 0); /* Temporal Quality */
1527             avio_wb32(pb, 0x400); /* Spatial Quality = lossless*/
1528         } else {
1529             avio_wb32(pb, 0x200); /* Temporal Quality = normal */
1530             avio_wb32(pb, 0x200); /* Spatial Quality = normal */
1531         }
1532     } else {
1533         avio_wb32(pb, 0); /* Reserved */
1534         avio_wb32(pb, 0); /* Reserved */
1535         avio_wb32(pb, 0); /* Reserved */
1536     }
1537     avio_wb16(pb, track->enc->width); /* Video width */
1538     avio_wb16(pb, track->height); /* Video height */
1539     avio_wb32(pb, 0x00480000); /* Horizontal resolution 72dpi */
1540     avio_wb32(pb, 0x00480000); /* Vertical resolution 72dpi */
1541     avio_wb32(pb, 0); /* Data size (= 0) */
1542     avio_wb16(pb, 1); /* Frame count (= 1) */
1543
1544     /* FIXME not sure, ISO 14496-1 draft where it shall be set to 0 */
1545     find_compressor(compressor_name, 32, track);
1546     avio_w8(pb, strlen(compressor_name));
1547     avio_write(pb, compressor_name, 31);
1548
1549     if (track->mode == MODE_MOV && track->enc->bits_per_coded_sample)
1550         avio_wb16(pb, track->enc->bits_per_coded_sample);
1551     else
1552         avio_wb16(pb, 0x18); /* Reserved */
1553     avio_wb16(pb, 0xffff); /* Reserved */
1554     if (track->tag == MKTAG('m','p','4','v'))
1555         mov_write_esds_tag(pb, track);
1556     else if (track->enc->codec_id == AV_CODEC_ID_H263)
1557         mov_write_d263_tag(pb);
1558     else if (track->enc->codec_id == AV_CODEC_ID_AVUI ||
1559             track->enc->codec_id == AV_CODEC_ID_SVQ3) {
1560         mov_write_extradata_tag(pb, track);
1561         avio_wb32(pb, 0);
1562     } else if (track->enc->codec_id == AV_CODEC_ID_DNXHD)
1563         mov_write_avid_tag(pb, track);
1564     else if (track->enc->codec_id == AV_CODEC_ID_HEVC)
1565         mov_write_hvcc_tag(pb, track);
1566     else if (track->enc->codec_id == AV_CODEC_ID_H264 && !TAG_IS_AVCI(track->tag)) {
1567         mov_write_avcc_tag(pb, track);
1568         if (track->mode == MODE_IPOD)
1569             mov_write_uuid_tag_ipod(pb);
1570     } else if (track->enc->codec_id == AV_CODEC_ID_VC1 && track->vos_len > 0)
1571         mov_write_dvc1_tag(pb, track);
1572     else if (track->enc->codec_id == AV_CODEC_ID_VP6F ||
1573              track->enc->codec_id == AV_CODEC_ID_VP6A) {
1574         /* Don't write any potential extradata here - the cropping
1575          * is signalled via the normal width/height fields. */
1576     } else if (track->vos_len > 0)
1577         mov_write_glbl_tag(pb, track);
1578
1579     if (track->enc->codec_id != AV_CODEC_ID_H264 &&
1580         track->enc->codec_id != AV_CODEC_ID_MPEG4 &&
1581         track->enc->codec_id != AV_CODEC_ID_DNXHD)
1582         if (track->enc->field_order != AV_FIELD_UNKNOWN)
1583             mov_write_fiel_tag(pb, track);
1584
1585     if (track->enc->sample_aspect_ratio.den && track->enc->sample_aspect_ratio.num &&
1586         track->enc->sample_aspect_ratio.den != track->enc->sample_aspect_ratio.num) {
1587         mov_write_pasp_tag(pb, track);
1588     }
1589
1590     return update_size(pb, pos);
1591 }
1592
1593 static int mov_write_rtp_tag(AVIOContext *pb, MOVTrack *track)
1594 {
1595     int64_t pos = avio_tell(pb);
1596     avio_wb32(pb, 0); /* size */
1597     ffio_wfourcc(pb, "rtp ");
1598     avio_wb32(pb, 0); /* Reserved */
1599     avio_wb16(pb, 0); /* Reserved */
1600     avio_wb16(pb, 1); /* Data-reference index */
1601
1602     avio_wb16(pb, 1); /* Hint track version */
1603     avio_wb16(pb, 1); /* Highest compatible version */
1604     avio_wb32(pb, track->max_packet_size); /* Max packet size */
1605
1606     avio_wb32(pb, 12); /* size */
1607     ffio_wfourcc(pb, "tims");
1608     avio_wb32(pb, track->timescale);
1609
1610     return update_size(pb, pos);
1611 }
1612
1613 static int mov_write_source_reference_tag(AVIOContext *pb, MOVTrack *track, const char *reel_name)
1614 {
1615     uint64_t str_size =strlen(reel_name);
1616     int64_t pos = avio_tell(pb);
1617
1618     if (str_size >= UINT16_MAX){
1619         av_log(NULL, AV_LOG_ERROR, "reel_name length %"PRIu64" is too large\n", str_size);
1620         avio_wb16(pb, 0);
1621         return AVERROR(EINVAL);
1622     }
1623
1624     avio_wb32(pb, 0);                              /* size */
1625     ffio_wfourcc(pb, "name");                      /* Data format */
1626     avio_wb16(pb, str_size);                       /* string size */
1627     avio_wb16(pb, track->language);                /* langcode */
1628     avio_write(pb, reel_name, str_size);           /* reel name */
1629     return update_size(pb,pos);
1630 }
1631
1632 static int mov_write_tmcd_tag(AVIOContext *pb, MOVTrack *track)
1633 {
1634     int64_t pos = avio_tell(pb);
1635 #if 1
1636     int frame_duration = av_rescale(track->timescale, track->enc->time_base.num, track->enc->time_base.den);
1637     int nb_frames = 1.0/av_q2d(track->enc->time_base) + 0.5;
1638     AVDictionaryEntry *t = NULL;
1639
1640     if (nb_frames > 255) {
1641         av_log(NULL, AV_LOG_ERROR, "fps %d is too large\n", nb_frames);
1642         return AVERROR(EINVAL);
1643     }
1644
1645     avio_wb32(pb, 0); /* size */
1646     ffio_wfourcc(pb, "tmcd");               /* Data format */
1647     avio_wb32(pb, 0);                       /* Reserved */
1648     avio_wb32(pb, 1);                       /* Data reference index */
1649     avio_wb32(pb, 0);                       /* Flags */
1650     avio_wb32(pb, track->timecode_flags);   /* Flags (timecode) */
1651     avio_wb32(pb, track->timescale);        /* Timescale */
1652     avio_wb32(pb, frame_duration);          /* Frame duration */
1653     avio_w8(pb, nb_frames);                 /* Number of frames */
1654     avio_w8(pb, 0);                         /* Reserved */
1655
1656     if (track->st)
1657         t = av_dict_get(track->st->metadata, "reel_name", NULL, 0);
1658
1659     if (t && utf8len(t->value))
1660         mov_write_source_reference_tag(pb, track, t->value);
1661     else
1662         avio_wb16(pb, 0); /* zero size */
1663 #else
1664
1665     avio_wb32(pb, 0); /* size */
1666     ffio_wfourcc(pb, "tmcd");               /* Data format */
1667     avio_wb32(pb, 0);                       /* Reserved */
1668     avio_wb32(pb, 1);                       /* Data reference index */
1669     if (track->enc->extradata_size)
1670         avio_write(pb, track->enc->extradata, track->enc->extradata_size);
1671 #endif
1672     return update_size(pb, pos);
1673 }
1674
1675 static int mov_write_stsd_tag(AVIOContext *pb, MOVTrack *track)
1676 {
1677     int64_t pos = avio_tell(pb);
1678     avio_wb32(pb, 0); /* size */
1679     ffio_wfourcc(pb, "stsd");
1680     avio_wb32(pb, 0); /* version & flags */
1681     avio_wb32(pb, 1); /* entry count */
1682     if (track->enc->codec_type == AVMEDIA_TYPE_VIDEO)
1683         mov_write_video_tag(pb, track);
1684     else if (track->enc->codec_type == AVMEDIA_TYPE_AUDIO)
1685         mov_write_audio_tag(pb, track);
1686     else if (track->enc->codec_type == AVMEDIA_TYPE_SUBTITLE)
1687         mov_write_subtitle_tag(pb, track);
1688     else if (track->enc->codec_tag == MKTAG('r','t','p',' '))
1689         mov_write_rtp_tag(pb, track);
1690     else if (track->enc->codec_tag == MKTAG('t','m','c','d'))
1691         mov_write_tmcd_tag(pb, track);
1692     return update_size(pb, pos);
1693 }
1694
1695 static int mov_write_ctts_tag(AVIOContext *pb, MOVTrack *track)
1696 {
1697     MOVStts *ctts_entries;
1698     uint32_t entries = 0;
1699     uint32_t atom_size;
1700     int i;
1701
1702     ctts_entries = av_malloc_array((track->entry + 1), sizeof(*ctts_entries)); /* worst case */
1703     ctts_entries[0].count = 1;
1704     ctts_entries[0].duration = track->cluster[0].cts;
1705     for (i = 1; i < track->entry; i++) {
1706         if (track->cluster[i].cts == ctts_entries[entries].duration) {
1707             ctts_entries[entries].count++; /* compress */
1708         } else {
1709             entries++;
1710             ctts_entries[entries].duration = track->cluster[i].cts;
1711             ctts_entries[entries].count = 1;
1712         }
1713     }
1714     entries++; /* last one */
1715     atom_size = 16 + (entries * 8);
1716     avio_wb32(pb, atom_size); /* size */
1717     ffio_wfourcc(pb, "ctts");
1718     avio_wb32(pb, 0); /* version & flags */
1719     avio_wb32(pb, entries); /* entry count */
1720     for (i = 0; i < entries; i++) {
1721         avio_wb32(pb, ctts_entries[i].count);
1722         avio_wb32(pb, ctts_entries[i].duration);
1723     }
1724     av_free(ctts_entries);
1725     return atom_size;
1726 }
1727
1728 /* Time to sample atom */
1729 static int mov_write_stts_tag(AVIOContext *pb, MOVTrack *track)
1730 {
1731     MOVStts *stts_entries;
1732     uint32_t entries = -1;
1733     uint32_t atom_size;
1734     int i;
1735
1736     if (track->enc->codec_type == AVMEDIA_TYPE_AUDIO && !track->audio_vbr) {
1737         stts_entries = av_malloc(sizeof(*stts_entries)); /* one entry */
1738         stts_entries[0].count = track->sample_count;
1739         stts_entries[0].duration = 1;
1740         entries = 1;
1741     } else {
1742         stts_entries = track->entry ?
1743                        av_malloc_array(track->entry, sizeof(*stts_entries)) : /* worst case */
1744                        NULL;
1745         for (i = 0; i < track->entry; i++) {
1746             int duration = get_cluster_duration(track, i);
1747             if (i && duration == stts_entries[entries].duration) {
1748                 stts_entries[entries].count++; /* compress */
1749             } else {
1750                 entries++;
1751                 stts_entries[entries].duration = duration;
1752                 stts_entries[entries].count = 1;
1753             }
1754         }
1755         entries++; /* last one */
1756     }
1757     atom_size = 16 + (entries * 8);
1758     avio_wb32(pb, atom_size); /* size */
1759     ffio_wfourcc(pb, "stts");
1760     avio_wb32(pb, 0); /* version & flags */
1761     avio_wb32(pb, entries); /* entry count */
1762     for (i = 0; i < entries; i++) {
1763         avio_wb32(pb, stts_entries[i].count);
1764         avio_wb32(pb, stts_entries[i].duration);
1765     }
1766     av_free(stts_entries);
1767     return atom_size;
1768 }
1769
1770 static int mov_write_dref_tag(AVIOContext *pb)
1771 {
1772     avio_wb32(pb, 28); /* size */
1773     ffio_wfourcc(pb, "dref");
1774     avio_wb32(pb, 0); /* version & flags */
1775     avio_wb32(pb, 1); /* entry count */
1776
1777     avio_wb32(pb, 0xc); /* size */
1778     //FIXME add the alis and rsrc atom
1779     ffio_wfourcc(pb, "url ");
1780     avio_wb32(pb, 1); /* version & flags */
1781
1782     return 28;
1783 }
1784
1785 static int mov_write_stbl_tag(AVIOContext *pb, MOVTrack *track)
1786 {
1787     int64_t pos = avio_tell(pb);
1788     avio_wb32(pb, 0); /* size */
1789     ffio_wfourcc(pb, "stbl");
1790     mov_write_stsd_tag(pb, track);
1791     mov_write_stts_tag(pb, track);
1792     if ((track->enc->codec_type == AVMEDIA_TYPE_VIDEO ||
1793          track->enc->codec_tag == MKTAG('r','t','p',' ')) &&
1794         track->has_keyframes && track->has_keyframes < track->entry)
1795         mov_write_stss_tag(pb, track, MOV_SYNC_SAMPLE);
1796     if (track->mode == MODE_MOV && track->flags & MOV_TRACK_STPS)
1797         mov_write_stss_tag(pb, track, MOV_PARTIAL_SYNC_SAMPLE);
1798     if (track->enc->codec_type == AVMEDIA_TYPE_VIDEO &&
1799         track->flags & MOV_TRACK_CTTS)
1800         mov_write_ctts_tag(pb, track);
1801     mov_write_stsc_tag(pb, track);
1802     mov_write_stsz_tag(pb, track);
1803     mov_write_stco_tag(pb, track);
1804     return update_size(pb, pos);
1805 }
1806
1807 static int mov_write_dinf_tag(AVIOContext *pb)
1808 {
1809     int64_t pos = avio_tell(pb);
1810     avio_wb32(pb, 0); /* size */
1811     ffio_wfourcc(pb, "dinf");
1812     mov_write_dref_tag(pb);
1813     return update_size(pb, pos);
1814 }
1815
1816 static int mov_write_nmhd_tag(AVIOContext *pb)
1817 {
1818     avio_wb32(pb, 12);
1819     ffio_wfourcc(pb, "nmhd");
1820     avio_wb32(pb, 0);
1821     return 12;
1822 }
1823
1824 static int mov_write_tcmi_tag(AVIOContext *pb, MOVTrack *track)
1825 {
1826     int64_t pos = avio_tell(pb);
1827     const char *font = "Lucida Grande";
1828     avio_wb32(pb, 0);                   /* size */
1829     ffio_wfourcc(pb, "tcmi");           /* timecode media information atom */
1830     avio_wb32(pb, 0);                   /* version & flags */
1831     avio_wb16(pb, 0);                   /* text font */
1832     avio_wb16(pb, 0);                   /* text face */
1833     avio_wb16(pb, 12);                  /* text size */
1834     avio_wb16(pb, 0);                   /* (unknown, not in the QT specs...) */
1835     avio_wb16(pb, 0x0000);              /* text color (red) */
1836     avio_wb16(pb, 0x0000);              /* text color (green) */
1837     avio_wb16(pb, 0x0000);              /* text color (blue) */
1838     avio_wb16(pb, 0xffff);              /* background color (red) */
1839     avio_wb16(pb, 0xffff);              /* background color (green) */
1840     avio_wb16(pb, 0xffff);              /* background color (blue) */
1841     avio_w8(pb, strlen(font));          /* font len (part of the pascal string) */
1842     avio_write(pb, font, strlen(font)); /* font name */
1843     return update_size(pb, pos);
1844 }
1845
1846 static int mov_write_gmhd_tag(AVIOContext *pb, MOVTrack *track)
1847 {
1848     int64_t pos = avio_tell(pb);
1849     avio_wb32(pb, 0);      /* size */
1850     ffio_wfourcc(pb, "gmhd");
1851     avio_wb32(pb, 0x18);   /* gmin size */
1852     ffio_wfourcc(pb, "gmin");/* generic media info */
1853     avio_wb32(pb, 0);      /* version & flags */
1854     avio_wb16(pb, 0x40);   /* graphics mode = */
1855     avio_wb16(pb, 0x8000); /* opColor (r?) */
1856     avio_wb16(pb, 0x8000); /* opColor (g?) */
1857     avio_wb16(pb, 0x8000); /* opColor (b?) */
1858     avio_wb16(pb, 0);      /* balance */
1859     avio_wb16(pb, 0);      /* reserved */
1860
1861     /*
1862      * This special text atom is required for
1863      * Apple Quicktime chapters. The contents
1864      * don't appear to be documented, so the
1865      * bytes are copied verbatim.
1866      */
1867     if (track->tag != MKTAG('c','6','0','8')) {
1868     avio_wb32(pb, 0x2C);   /* size */
1869     ffio_wfourcc(pb, "text");
1870     avio_wb16(pb, 0x01);
1871     avio_wb32(pb, 0x00);
1872     avio_wb32(pb, 0x00);
1873     avio_wb32(pb, 0x00);
1874     avio_wb32(pb, 0x01);
1875     avio_wb32(pb, 0x00);
1876     avio_wb32(pb, 0x00);
1877     avio_wb32(pb, 0x00);
1878     avio_wb32(pb, 0x00004000);
1879     avio_wb16(pb, 0x0000);
1880     }
1881
1882     if (track->enc->codec_tag == MKTAG('t','m','c','d')) {
1883         int64_t tmcd_pos = avio_tell(pb);
1884         avio_wb32(pb, 0); /* size */
1885         ffio_wfourcc(pb, "tmcd");
1886         mov_write_tcmi_tag(pb, track);
1887         update_size(pb, tmcd_pos);
1888     }
1889     return update_size(pb, pos);
1890 }
1891
1892 static int mov_write_smhd_tag(AVIOContext *pb)
1893 {
1894     avio_wb32(pb, 16); /* size */
1895     ffio_wfourcc(pb, "smhd");
1896     avio_wb32(pb, 0); /* version & flags */
1897     avio_wb16(pb, 0); /* reserved (balance, normally = 0) */
1898     avio_wb16(pb, 0); /* reserved */
1899     return 16;
1900 }
1901
1902 static int mov_write_vmhd_tag(AVIOContext *pb)
1903 {
1904     avio_wb32(pb, 0x14); /* size (always 0x14) */
1905     ffio_wfourcc(pb, "vmhd");
1906     avio_wb32(pb, 0x01); /* version & flags */
1907     avio_wb64(pb, 0); /* reserved (graphics mode = copy) */
1908     return 0x14;
1909 }
1910
1911 static int is_clcp_track(MOVTrack *track)
1912 {
1913     return track->tag == MKTAG('c','7','0','8') ||
1914            track->tag == MKTAG('c','6','0','8');
1915 }
1916
1917 static int mov_write_hdlr_tag(AVIOContext *pb, MOVTrack *track)
1918 {
1919     const char *hdlr, *descr = NULL, *hdlr_type = NULL;
1920     int64_t pos = avio_tell(pb);
1921
1922     hdlr      = "dhlr";
1923     hdlr_type = "url ";
1924     descr     = "DataHandler";
1925
1926     if (track) {
1927         hdlr = (track->mode == MODE_MOV) ? "mhlr" : "\0\0\0\0";
1928         if (track->enc->codec_type == AVMEDIA_TYPE_VIDEO) {
1929             hdlr_type = "vide";
1930             descr     = "VideoHandler";
1931         } else if (track->enc->codec_type == AVMEDIA_TYPE_AUDIO) {
1932             hdlr_type = "soun";
1933             descr     = "SoundHandler";
1934         } else if (track->enc->codec_type == AVMEDIA_TYPE_SUBTITLE) {
1935             if (is_clcp_track(track)) {
1936                 hdlr_type = "clcp";
1937                 descr = "ClosedCaptionHandler";
1938             } else {
1939                 if (track->tag == MKTAG('t','x','3','g')) {
1940                     hdlr_type = "sbtl";
1941                 } else if (track->tag == MKTAG('m','p','4','s')) {
1942                     hdlr_type = "subp";
1943                 } else {
1944                     hdlr_type = "text";
1945                 }
1946             descr = "SubtitleHandler";
1947             }
1948         } else if (track->enc->codec_tag == MKTAG('r','t','p',' ')) {
1949             hdlr_type = "hint";
1950             descr     = "HintHandler";
1951         } else if (track->enc->codec_tag == MKTAG('t','m','c','d')) {
1952             hdlr_type = "tmcd";
1953             descr = "TimeCodeHandler";
1954         } else {
1955             char tag_buf[32];
1956             av_get_codec_tag_string(tag_buf, sizeof(tag_buf),
1957                                     track->enc->codec_tag);
1958
1959             av_log(track->enc, AV_LOG_WARNING,
1960                    "Unknown hldr_type for %s / 0x%04X, writing dummy values\n",
1961                    tag_buf, track->enc->codec_tag);
1962         }
1963         if (track->st) {
1964             // hdlr.name is used by some players to identify the content title
1965             // of the track. So if an alternate handler description is
1966             // specified, use it.
1967             AVDictionaryEntry *t;
1968             t = av_dict_get(track->st->metadata, "handler", NULL, 0);
1969             if (t && utf8len(t->value))
1970                 descr = t->value;
1971         }
1972     }
1973
1974     avio_wb32(pb, 0); /* size */
1975     ffio_wfourcc(pb, "hdlr");
1976     avio_wb32(pb, 0); /* Version & flags */
1977     avio_write(pb, hdlr, 4); /* handler */
1978     ffio_wfourcc(pb, hdlr_type); /* handler type */
1979     avio_wb32(pb, 0); /* reserved */
1980     avio_wb32(pb, 0); /* reserved */
1981     avio_wb32(pb, 0); /* reserved */
1982     if (!track || track->mode == MODE_MOV)
1983         avio_w8(pb, strlen(descr)); /* pascal string */
1984     avio_write(pb, descr, strlen(descr)); /* handler description */
1985     if (track && track->mode != MODE_MOV)
1986         avio_w8(pb, 0); /* c string */
1987     return update_size(pb, pos);
1988 }
1989
1990 static int mov_write_hmhd_tag(AVIOContext *pb)
1991 {
1992     /* This atom must be present, but leaving the values at zero
1993      * seems harmless. */
1994     avio_wb32(pb, 28); /* size */
1995     ffio_wfourcc(pb, "hmhd");
1996     avio_wb32(pb, 0); /* version, flags */
1997     avio_wb16(pb, 0); /* maxPDUsize */
1998     avio_wb16(pb, 0); /* avgPDUsize */
1999     avio_wb32(pb, 0); /* maxbitrate */
2000     avio_wb32(pb, 0); /* avgbitrate */
2001     avio_wb32(pb, 0); /* reserved */
2002     return 28;
2003 }
2004
2005 static int mov_write_minf_tag(AVIOContext *pb, MOVTrack *track)
2006 {
2007     int64_t pos = avio_tell(pb);
2008     avio_wb32(pb, 0); /* size */
2009     ffio_wfourcc(pb, "minf");
2010     if (track->enc->codec_type == AVMEDIA_TYPE_VIDEO)
2011         mov_write_vmhd_tag(pb);
2012     else if (track->enc->codec_type == AVMEDIA_TYPE_AUDIO)
2013         mov_write_smhd_tag(pb);
2014     else if (track->enc->codec_type == AVMEDIA_TYPE_SUBTITLE) {
2015         if (track->tag == MKTAG('t','e','x','t') || is_clcp_track(track)) {
2016             mov_write_gmhd_tag(pb, track);
2017         } else {
2018             mov_write_nmhd_tag(pb);
2019         }
2020     } else if (track->tag == MKTAG('r','t','p',' ')) {
2021         mov_write_hmhd_tag(pb);
2022     } else if (track->tag == MKTAG('t','m','c','d')) {
2023         mov_write_gmhd_tag(pb, track);
2024     }
2025     if (track->mode == MODE_MOV) /* FIXME: Why do it for MODE_MOV only ? */
2026         mov_write_hdlr_tag(pb, NULL);
2027     mov_write_dinf_tag(pb);
2028     mov_write_stbl_tag(pb, track);
2029     return update_size(pb, pos);
2030 }
2031
2032 static int mov_write_mdhd_tag(AVIOContext *pb, MOVMuxContext *mov,
2033                               MOVTrack *track)
2034 {
2035     int version = track->track_duration < INT32_MAX ? 0 : 1;
2036
2037     if (track->mode == MODE_ISM)
2038         version = 1;
2039
2040     (version == 1) ? avio_wb32(pb, 44) : avio_wb32(pb, 32); /* size */
2041     ffio_wfourcc(pb, "mdhd");
2042     avio_w8(pb, version);
2043     avio_wb24(pb, 0); /* flags */
2044     if (version == 1) {
2045         avio_wb64(pb, track->time);
2046         avio_wb64(pb, track->time);
2047     } else {
2048         avio_wb32(pb, track->time); /* creation time */
2049         avio_wb32(pb, track->time); /* modification time */
2050     }
2051     avio_wb32(pb, track->timescale); /* time scale (sample rate for audio) */
2052     if (!track->entry && mov->mode == MODE_ISM)
2053         (version == 1) ? avio_wb64(pb, UINT64_C(0xffffffffffffffff)) : avio_wb32(pb, 0xffffffff);
2054     else if (!track->entry)
2055         (version == 1) ? avio_wb64(pb, 0) : avio_wb32(pb, 0);
2056     else
2057         (version == 1) ? avio_wb64(pb, track->track_duration) : avio_wb32(pb, track->track_duration); /* duration */
2058     avio_wb16(pb, track->language); /* language */
2059     avio_wb16(pb, 0); /* reserved (quality) */
2060
2061     if (version != 0 && track->mode == MODE_MOV) {
2062         av_log(NULL, AV_LOG_ERROR,
2063                "FATAL error, file duration too long for timebase, this file will not be\n"
2064                "playable with quicktime. Choose a different timebase or a different\n"
2065                "container format\n");
2066     }
2067
2068     return 32;
2069 }
2070
2071 static int mov_write_mdia_tag(AVIOContext *pb, MOVMuxContext *mov,
2072                               MOVTrack *track)
2073 {
2074     int64_t pos = avio_tell(pb);
2075     avio_wb32(pb, 0); /* size */
2076     ffio_wfourcc(pb, "mdia");
2077     mov_write_mdhd_tag(pb, mov, track);
2078     mov_write_hdlr_tag(pb, track);
2079     mov_write_minf_tag(pb, track);
2080     return update_size(pb, pos);
2081 }
2082
2083 /* transformation matrix
2084      |a  b  u|
2085      |c  d  v|
2086      |tx ty w| */
2087 static void write_matrix(AVIOContext *pb, int16_t a, int16_t b, int16_t c,
2088                          int16_t d, int16_t tx, int16_t ty)
2089 {
2090     avio_wb32(pb, a << 16);  /* 16.16 format */
2091     avio_wb32(pb, b << 16);  /* 16.16 format */
2092     avio_wb32(pb, 0);        /* u in 2.30 format */
2093     avio_wb32(pb, c << 16);  /* 16.16 format */
2094     avio_wb32(pb, d << 16);  /* 16.16 format */
2095     avio_wb32(pb, 0);        /* v in 2.30 format */
2096     avio_wb32(pb, tx << 16); /* 16.16 format */
2097     avio_wb32(pb, ty << 16); /* 16.16 format */
2098     avio_wb32(pb, 1 << 30);  /* w in 2.30 format */
2099 }
2100
2101 static int mov_write_tkhd_tag(AVIOContext *pb, MOVMuxContext *mov,
2102                               MOVTrack *track, AVStream *st)
2103 {
2104     int64_t duration = av_rescale_rnd(track->track_duration, MOV_TIMESCALE,
2105                                       track->timescale, AV_ROUND_UP);
2106     int version = duration < INT32_MAX ? 0 : 1;
2107     int flags   = MOV_TKHD_FLAG_IN_MOVIE;
2108     int rotation = 0;
2109     int group   = 0;
2110
2111
2112     if (st) {
2113         if (mov->per_stream_grouping)
2114             group = st->index;
2115         else
2116             group = st->codec->codec_type;
2117     }
2118
2119     if (track->flags & MOV_TRACK_ENABLED)
2120         flags |= MOV_TKHD_FLAG_ENABLED;
2121
2122     if (track->mode == MODE_ISM)
2123         version = 1;
2124
2125     (version == 1) ? avio_wb32(pb, 104) : avio_wb32(pb, 92); /* size */
2126     ffio_wfourcc(pb, "tkhd");
2127     avio_w8(pb, version);
2128     avio_wb24(pb, flags);
2129     if (version == 1) {
2130         avio_wb64(pb, track->time);
2131         avio_wb64(pb, track->time);
2132     } else {
2133         avio_wb32(pb, track->time); /* creation time */
2134         avio_wb32(pb, track->time); /* modification time */
2135     }
2136     avio_wb32(pb, track->track_id); /* track-id */
2137     avio_wb32(pb, 0); /* reserved */
2138     if (!track->entry && mov->mode == MODE_ISM)
2139         (version == 1) ? avio_wb64(pb, UINT64_C(0xffffffffffffffff)) : avio_wb32(pb, 0xffffffff);
2140     else if (!track->entry)
2141         (version == 1) ? avio_wb64(pb, 0) : avio_wb32(pb, 0);
2142     else
2143         (version == 1) ? avio_wb64(pb, duration) : avio_wb32(pb, duration);
2144
2145     avio_wb32(pb, 0); /* reserved */
2146     avio_wb32(pb, 0); /* reserved */
2147     avio_wb16(pb, 0); /* layer */
2148     avio_wb16(pb, group); /* alternate group) */
2149     /* Volume, only for audio */
2150     if (track->enc->codec_type == AVMEDIA_TYPE_AUDIO)
2151         avio_wb16(pb, 0x0100);
2152     else
2153         avio_wb16(pb, 0);
2154     avio_wb16(pb, 0); /* reserved */
2155
2156     /* Matrix structure */
2157     if (st && st->metadata) {
2158         AVDictionaryEntry *rot = av_dict_get(st->metadata, "rotate", NULL, 0);
2159         rotation = (rot && rot->value) ? atoi(rot->value) : 0;
2160     }
2161     if (rotation == 90) {
2162         write_matrix(pb,  0,  1, -1,  0, track->enc->height, 0);
2163     } else if (rotation == 180) {
2164         write_matrix(pb, -1,  0,  0, -1, track->enc->width, track->enc->height);
2165     } else if (rotation == 270) {
2166         write_matrix(pb,  0, -1,  1,  0, 0, track->enc->width);
2167     } else {
2168         write_matrix(pb,  1,  0,  0,  1, 0, 0);
2169     }
2170     /* Track width and height, for visual only */
2171     if (st && (track->enc->codec_type == AVMEDIA_TYPE_VIDEO ||
2172                track->enc->codec_type == AVMEDIA_TYPE_SUBTITLE)) {
2173         if (track->mode == MODE_MOV) {
2174             avio_wb32(pb, track->enc->width << 16);
2175             avio_wb32(pb, track->height << 16);
2176         } else {
2177             double sample_aspect_ratio = av_q2d(st->sample_aspect_ratio);
2178             if (!sample_aspect_ratio || track->height != track->enc->height)
2179                 sample_aspect_ratio = 1;
2180             avio_wb32(pb, sample_aspect_ratio * track->enc->width * 0x10000);
2181             avio_wb32(pb, track->height * 0x10000);
2182         }
2183     } else {
2184         avio_wb32(pb, 0);
2185         avio_wb32(pb, 0);
2186     }
2187     return 0x5c;
2188 }
2189
2190 static int mov_write_tapt_tag(AVIOContext *pb, MOVTrack *track)
2191 {
2192     int32_t width = av_rescale(track->enc->sample_aspect_ratio.num, track->enc->width,
2193                                track->enc->sample_aspect_ratio.den);
2194
2195     int64_t pos = avio_tell(pb);
2196
2197     avio_wb32(pb, 0); /* size */
2198     ffio_wfourcc(pb, "tapt");
2199
2200     avio_wb32(pb, 20);
2201     ffio_wfourcc(pb, "clef");
2202     avio_wb32(pb, 0);
2203     avio_wb32(pb, width << 16);
2204     avio_wb32(pb, track->enc->height << 16);
2205
2206     avio_wb32(pb, 20);
2207     ffio_wfourcc(pb, "prof");
2208     avio_wb32(pb, 0);
2209     avio_wb32(pb, width << 16);
2210     avio_wb32(pb, track->enc->height << 16);
2211
2212     avio_wb32(pb, 20);
2213     ffio_wfourcc(pb, "enof");
2214     avio_wb32(pb, 0);
2215     avio_wb32(pb, track->enc->width << 16);
2216     avio_wb32(pb, track->enc->height << 16);
2217
2218     return update_size(pb, pos);
2219 }
2220
2221 // This box seems important for the psp playback ... without it the movie seems to hang
2222 static int mov_write_edts_tag(AVIOContext *pb, MOVMuxContext *mov,
2223                               MOVTrack *track)
2224 {
2225     int64_t duration = av_rescale_rnd(track->track_duration, MOV_TIMESCALE,
2226                                       track->timescale, AV_ROUND_UP);
2227     int version = duration < INT32_MAX ? 0 : 1;
2228     int entry_size, entry_count, size;
2229     int64_t delay, start_ct = track->cluster[0].cts;
2230     delay = av_rescale_rnd(track->cluster[0].dts + start_ct, MOV_TIMESCALE,
2231                            track->timescale, AV_ROUND_DOWN);
2232     version |= delay < INT32_MAX ? 0 : 1;
2233
2234     entry_size = (version == 1) ? 20 : 12;
2235     entry_count = 1 + (delay > 0);
2236     size = 24 + entry_count * entry_size;
2237
2238     /* write the atom data */
2239     avio_wb32(pb, size);
2240     ffio_wfourcc(pb, "edts");
2241     avio_wb32(pb, size - 8);
2242     ffio_wfourcc(pb, "elst");
2243     avio_w8(pb, version);
2244     avio_wb24(pb, 0); /* flags */
2245
2246     avio_wb32(pb, entry_count);
2247     if (delay > 0) { /* add an empty edit to delay presentation */
2248         /* In the positive delay case, the delay includes the cts
2249          * offset, and the second edit list entry below trims out
2250          * the same amount from the actual content. This makes sure
2251          * that the offsetted last sample is included in the edit
2252          * list duration as well. */
2253         if (version == 1) {
2254             avio_wb64(pb, delay);
2255             avio_wb64(pb, -1);
2256         } else {
2257             avio_wb32(pb, delay);
2258             avio_wb32(pb, -1);
2259         }
2260         avio_wb32(pb, 0x00010000);
2261     } else {
2262         /* Avoid accidentally ending up with start_ct = -1 which has got a
2263          * special meaning. Normally start_ct should end up positive or zero
2264          * here, but use FFMIN in case dts is a a small positive integer
2265          * rounded to 0 when represented in MOV_TIMESCALE units. */
2266         av_assert0(av_rescale_rnd(track->cluster[0].dts, MOV_TIMESCALE, track->timescale, AV_ROUND_DOWN) <= 0);
2267         start_ct  = -FFMIN(track->cluster[0].dts, 0);
2268         /* Note, this delay is calculated from the pts of the first sample,
2269          * ensuring that we don't reduce the duration for cases with
2270          * dts<0 pts=0. */
2271         duration += delay;
2272     }
2273
2274     /* For fragmented files, we don't know the full length yet. Setting
2275      * duration to 0 allows us to only specify the offset, including
2276      * the rest of the content (from all future fragments) without specifying
2277      * an explicit duration. */
2278     if (mov->flags & FF_MOV_FLAG_FRAGMENT)
2279         duration = 0;
2280
2281     /* duration */
2282     if (version == 1) {
2283         avio_wb64(pb, duration);
2284         avio_wb64(pb, start_ct);
2285     } else {
2286         avio_wb32(pb, duration);
2287         avio_wb32(pb, start_ct);
2288     }
2289     avio_wb32(pb, 0x00010000);
2290     return size;
2291 }
2292
2293 static int mov_write_tref_tag(AVIOContext *pb, MOVTrack *track)
2294 {
2295     avio_wb32(pb, 20);   // size
2296     ffio_wfourcc(pb, "tref");
2297     avio_wb32(pb, 12);   // size (subatom)
2298     avio_wl32(pb, track->tref_tag);
2299     avio_wb32(pb, track->tref_id);
2300     return 20;
2301 }
2302
2303 // goes at the end of each track!  ... Critical for PSP playback ("Incompatible data" without it)
2304 static int mov_write_uuid_tag_psp(AVIOContext *pb, MOVTrack *mov)
2305 {
2306     avio_wb32(pb, 0x34); /* size ... reports as 28 in mp4box! */
2307     ffio_wfourcc(pb, "uuid");
2308     ffio_wfourcc(pb, "USMT");
2309     avio_wb32(pb, 0x21d24fce);
2310     avio_wb32(pb, 0xbb88695c);
2311     avio_wb32(pb, 0xfac9c740);
2312     avio_wb32(pb, 0x1c);     // another size here!
2313     ffio_wfourcc(pb, "MTDT");
2314     avio_wb32(pb, 0x00010012);
2315     avio_wb32(pb, 0x0a);
2316     avio_wb32(pb, 0x55c40000);
2317     avio_wb32(pb, 0x1);
2318     avio_wb32(pb, 0x0);
2319     return 0x34;
2320 }
2321
2322 static int mov_write_udta_sdp(AVIOContext *pb, MOVTrack *track)
2323 {
2324     AVFormatContext *ctx = track->rtp_ctx;
2325     char buf[1000] = "";
2326     int len;
2327
2328     ff_sdp_write_media(buf, sizeof(buf), ctx->streams[0], track->src_track,
2329                        NULL, NULL, 0, 0, ctx);
2330     av_strlcatf(buf, sizeof(buf), "a=control:streamid=%d\r\n", track->track_id);
2331     len = strlen(buf);
2332
2333     avio_wb32(pb, len + 24);
2334     ffio_wfourcc(pb, "udta");
2335     avio_wb32(pb, len + 16);
2336     ffio_wfourcc(pb, "hnti");
2337     avio_wb32(pb, len + 8);
2338     ffio_wfourcc(pb, "sdp ");
2339     avio_write(pb, buf, len);
2340     return len + 24;
2341 }
2342
2343 static int mov_write_track_metadata(AVIOContext *pb, AVStream *st,
2344                                     const char *tag, const char *str)
2345 {
2346     int64_t pos = avio_tell(pb);
2347     AVDictionaryEntry *t = av_dict_get(st->metadata, str, NULL, 0);
2348     if (!t || !utf8len(t->value))
2349         return 0;
2350
2351     avio_wb32(pb, 0);   /* size */
2352     ffio_wfourcc(pb, tag); /* type */
2353     avio_write(pb, t->value, strlen(t->value)); /* UTF8 string value */
2354     return update_size(pb, pos);
2355 }
2356
2357 static int mov_write_track_udta_tag(AVIOContext *pb, MOVMuxContext *mov,
2358                                     AVStream *st)
2359 {
2360     AVIOContext *pb_buf;
2361     int ret, size;
2362     uint8_t *buf;
2363
2364     if (!st || mov->fc->flags & AVFMT_FLAG_BITEXACT)
2365         return 0;
2366
2367     ret = avio_open_dyn_buf(&pb_buf);
2368     if (ret < 0)
2369         return ret;
2370
2371     if (mov->mode & MODE_MP4)
2372         mov_write_track_metadata(pb_buf, st, "name", "title");
2373
2374     if ((size = avio_close_dyn_buf(pb_buf, &buf)) > 0) {
2375         avio_wb32(pb, size + 8);
2376         ffio_wfourcc(pb, "udta");
2377         avio_write(pb, buf, size);
2378     }
2379     av_free(buf);
2380
2381     return 0;
2382 }
2383
2384 static int mov_write_trak_tag(AVIOContext *pb, MOVMuxContext *mov,
2385                               MOVTrack *track, AVStream *st)
2386 {
2387     int64_t pos = avio_tell(pb);
2388     avio_wb32(pb, 0); /* size */
2389     ffio_wfourcc(pb, "trak");
2390     mov_write_tkhd_tag(pb, mov, track, st);
2391
2392     av_assert2(mov->use_editlist >= 0);
2393
2394
2395     if (track->entry) {
2396         if (mov->use_editlist)
2397             mov_write_edts_tag(pb, mov, track);  // PSP Movies and several other cases require edts box
2398         else if ((track->entry && track->cluster[0].dts) || track->mode == MODE_PSP || is_clcp_track(track))
2399             av_log(mov->fc, AV_LOG_WARNING,
2400                    "Not writing any edit list even though one would have been required\n");
2401     }
2402
2403     if (track->tref_tag)
2404         mov_write_tref_tag(pb, track);
2405     mov_write_mdia_tag(pb, mov, track);
2406     if (track->mode == MODE_PSP)
2407         mov_write_uuid_tag_psp(pb, track); // PSP Movies require this uuid box
2408     if (track->tag == MKTAG('r','t','p',' '))
2409         mov_write_udta_sdp(pb, track);
2410     if (track->mode == MODE_MOV) {
2411         if (track->enc->codec_type == AVMEDIA_TYPE_VIDEO) {
2412             double sample_aspect_ratio = av_q2d(st->sample_aspect_ratio);
2413             if (st->sample_aspect_ratio.num && 1.0 != sample_aspect_ratio) {
2414                 mov_write_tapt_tag(pb, track);
2415             }
2416         }
2417         if (is_clcp_track(track) && st->sample_aspect_ratio.num) {
2418             mov_write_tapt_tag(pb, track);
2419         }
2420     }
2421     mov_write_track_udta_tag(pb, mov, st);
2422     return update_size(pb, pos);
2423 }
2424
2425 static int mov_write_iods_tag(AVIOContext *pb, MOVMuxContext *mov)
2426 {
2427     int i, has_audio = 0, has_video = 0;
2428     int64_t pos = avio_tell(pb);
2429     int audio_profile = mov->iods_audio_profile;
2430     int video_profile = mov->iods_video_profile;
2431     for (i = 0; i < mov->nb_streams; i++) {
2432         if (mov->tracks[i].entry > 0 || mov->flags & FF_MOV_FLAG_EMPTY_MOOV) {
2433             has_audio |= mov->tracks[i].enc->codec_type == AVMEDIA_TYPE_AUDIO;
2434             has_video |= mov->tracks[i].enc->codec_type == AVMEDIA_TYPE_VIDEO;
2435         }
2436     }
2437     if (audio_profile < 0)
2438         audio_profile = 0xFF - has_audio;
2439     if (video_profile < 0)
2440         video_profile = 0xFF - has_video;
2441     avio_wb32(pb, 0x0); /* size */
2442     ffio_wfourcc(pb, "iods");
2443     avio_wb32(pb, 0);    /* version & flags */
2444     put_descr(pb, 0x10, 7);
2445     avio_wb16(pb, 0x004f);
2446     avio_w8(pb, 0xff);
2447     avio_w8(pb, 0xff);
2448     avio_w8(pb, audio_profile);
2449     avio_w8(pb, video_profile);
2450     avio_w8(pb, 0xff);
2451     return update_size(pb, pos);
2452 }
2453
2454 static int mov_write_trex_tag(AVIOContext *pb, MOVTrack *track)
2455 {
2456     avio_wb32(pb, 0x20); /* size */
2457     ffio_wfourcc(pb, "trex");
2458     avio_wb32(pb, 0);   /* version & flags */
2459     avio_wb32(pb, track->track_id); /* track ID */
2460     avio_wb32(pb, 1);   /* default sample description index */
2461     avio_wb32(pb, 0);   /* default sample duration */
2462     avio_wb32(pb, 0);   /* default sample size */
2463     avio_wb32(pb, 0);   /* default sample flags */
2464     return 0;
2465 }
2466
2467 static int mov_write_mvex_tag(AVIOContext *pb, MOVMuxContext *mov)
2468 {
2469     int64_t pos = avio_tell(pb);
2470     int i;
2471     avio_wb32(pb, 0x0); /* size */
2472     ffio_wfourcc(pb, "mvex");
2473     for (i = 0; i < mov->nb_streams; i++)
2474         mov_write_trex_tag(pb, &mov->tracks[i]);
2475     return update_size(pb, pos);
2476 }
2477
2478 static int mov_write_mvhd_tag(AVIOContext *pb, MOVMuxContext *mov)
2479 {
2480     int max_track_id = 1, i;
2481     int64_t max_track_len_temp, max_track_len = 0;
2482     int version;
2483
2484     for (i = 0; i < mov->nb_streams; i++) {
2485         if (mov->tracks[i].entry > 0 && mov->tracks[i].timescale) {
2486             max_track_len_temp = av_rescale_rnd(mov->tracks[i].track_duration,
2487                                                 MOV_TIMESCALE,
2488                                                 mov->tracks[i].timescale,
2489                                                 AV_ROUND_UP);
2490             if (max_track_len < max_track_len_temp)
2491                 max_track_len = max_track_len_temp;
2492             if (max_track_id < mov->tracks[i].track_id)
2493                 max_track_id = mov->tracks[i].track_id;
2494         }
2495     }
2496
2497     version = max_track_len < UINT32_MAX ? 0 : 1;
2498     (version == 1) ? avio_wb32(pb, 120) : avio_wb32(pb, 108); /* size */
2499     ffio_wfourcc(pb, "mvhd");
2500     avio_w8(pb, version);
2501     avio_wb24(pb, 0); /* flags */
2502     if (version == 1) {
2503         avio_wb64(pb, mov->time);
2504         avio_wb64(pb, mov->time);
2505     } else {
2506         avio_wb32(pb, mov->time); /* creation time */
2507         avio_wb32(pb, mov->time); /* modification time */
2508     }
2509     avio_wb32(pb, MOV_TIMESCALE);
2510     (version == 1) ? avio_wb64(pb, max_track_len) : avio_wb32(pb, max_track_len); /* duration of longest track */
2511
2512     avio_wb32(pb, 0x00010000); /* reserved (preferred rate) 1.0 = normal */
2513     avio_wb16(pb, 0x0100); /* reserved (preferred volume) 1.0 = normal */
2514     avio_wb16(pb, 0); /* reserved */
2515     avio_wb32(pb, 0); /* reserved */
2516     avio_wb32(pb, 0); /* reserved */
2517
2518     /* Matrix structure */
2519     write_matrix(pb, 1, 0, 0, 1, 0, 0);
2520
2521     avio_wb32(pb, 0); /* reserved (preview time) */
2522     avio_wb32(pb, 0); /* reserved (preview duration) */
2523     avio_wb32(pb, 0); /* reserved (poster time) */
2524     avio_wb32(pb, 0); /* reserved (selection time) */
2525     avio_wb32(pb, 0); /* reserved (selection duration) */
2526     avio_wb32(pb, 0); /* reserved (current time) */
2527     avio_wb32(pb, max_track_id + 1); /* Next track id */
2528     return 0x6c;
2529 }
2530
2531 static int mov_write_itunes_hdlr_tag(AVIOContext *pb, MOVMuxContext *mov,
2532                                      AVFormatContext *s)
2533 {
2534     avio_wb32(pb, 33); /* size */
2535     ffio_wfourcc(pb, "hdlr");
2536     avio_wb32(pb, 0);
2537     avio_wb32(pb, 0);
2538     ffio_wfourcc(pb, "mdir");
2539     ffio_wfourcc(pb, "appl");
2540     avio_wb32(pb, 0);
2541     avio_wb32(pb, 0);
2542     avio_w8(pb, 0);
2543     return 33;
2544 }
2545
2546 /* helper function to write a data tag with the specified string as data */
2547 static int mov_write_string_data_tag(AVIOContext *pb, const char *data, int lang, int long_style)
2548 {
2549     if (long_style) {
2550         int size = 16 + strlen(data);
2551         avio_wb32(pb, size); /* size */
2552         ffio_wfourcc(pb, "data");
2553         avio_wb32(pb, 1);
2554         avio_wb32(pb, 0);
2555         avio_write(pb, data, strlen(data));
2556         return size;
2557     } else {
2558         if (!lang)
2559             lang = ff_mov_iso639_to_lang("und", 1);
2560         avio_wb16(pb, strlen(data)); /* string length */
2561         avio_wb16(pb, lang);
2562         avio_write(pb, data, strlen(data));
2563         return strlen(data) + 4;
2564     }
2565 }
2566
2567 static int mov_write_string_tag(AVIOContext *pb, const char *name,
2568                                 const char *value, int lang, int long_style)
2569 {
2570     int size = 0;
2571     if (value && value[0]) {
2572         int64_t pos = avio_tell(pb);
2573         avio_wb32(pb, 0); /* size */
2574         ffio_wfourcc(pb, name);
2575         mov_write_string_data_tag(pb, value, lang, long_style);
2576         size = update_size(pb, pos);
2577     }
2578     return size;
2579 }
2580
2581 static int mov_write_string_metadata(AVFormatContext *s, AVIOContext *pb,
2582                                      const char *name, const char *tag,
2583                                      int long_style)
2584 {
2585     int l, lang = 0, len, len2;
2586     AVDictionaryEntry *t, *t2 = NULL;
2587     char tag2[16];
2588
2589     if (!(t = av_dict_get(s->metadata, tag, NULL, 0)))
2590         return 0;
2591
2592     len = strlen(t->key);
2593     snprintf(tag2, sizeof(tag2), "%s-", tag);
2594     while ((t2 = av_dict_get(s->metadata, tag2, t2, AV_DICT_IGNORE_SUFFIX))) {
2595         len2 = strlen(t2->key);
2596         if (len2 == len + 4 && !strcmp(t->value, t2->value)
2597             && (l = ff_mov_iso639_to_lang(&t2->key[len2 - 3], 1)) >= 0) {
2598             lang = l;
2599             break;
2600         }
2601     }
2602     return mov_write_string_tag(pb, name, t->value, lang, long_style);
2603 }
2604
2605 /* iTunes bpm number */
2606 static int mov_write_tmpo_tag(AVIOContext *pb, AVFormatContext *s)
2607 {
2608     AVDictionaryEntry *t = av_dict_get(s->metadata, "tmpo", NULL, 0);
2609     int size = 0, tmpo = t ? atoi(t->value) : 0;
2610     if (tmpo) {
2611         size = 26;
2612         avio_wb32(pb, size);
2613         ffio_wfourcc(pb, "tmpo");
2614         avio_wb32(pb, size-8); /* size */
2615         ffio_wfourcc(pb, "data");
2616         avio_wb32(pb, 0x15);  //type specifier
2617         avio_wb32(pb, 0);
2618         avio_wb16(pb, tmpo);        // data
2619     }
2620     return size;
2621 }
2622
2623 /* iTunes track or disc number */
2624 static int mov_write_trkn_tag(AVIOContext *pb, MOVMuxContext *mov,
2625                               AVFormatContext *s, int disc)
2626 {
2627     AVDictionaryEntry *t = av_dict_get(s->metadata,
2628                                        disc ? "disc" : "track",
2629                                        NULL, 0);
2630     int size = 0, track = t ? atoi(t->value) : 0;
2631     if (track) {
2632         int tracks = 0;
2633         char *slash = strchr(t->value, '/');
2634         if (slash)
2635             tracks = atoi(slash + 1);
2636         avio_wb32(pb, 32); /* size */
2637         ffio_wfourcc(pb, disc ? "disk" : "trkn");
2638         avio_wb32(pb, 24); /* size */
2639         ffio_wfourcc(pb, "data");
2640         avio_wb32(pb, 0);        // 8 bytes empty
2641         avio_wb32(pb, 0);
2642         avio_wb16(pb, 0);        // empty
2643         avio_wb16(pb, track);    // track / disc number
2644         avio_wb16(pb, tracks);   // total track / disc number
2645         avio_wb16(pb, 0);        // empty
2646         size = 32;
2647     }
2648     return size;
2649 }
2650
2651 static int mov_write_int8_metadata(AVFormatContext *s, AVIOContext *pb,
2652                                    const char *name, const char *tag,
2653                                    int len)
2654 {
2655     AVDictionaryEntry *t = NULL;
2656     uint8_t num;
2657     int size = 24 + len;
2658
2659     if (len != 1 && len != 4)
2660         return -1;
2661
2662     if (!(t = av_dict_get(s->metadata, tag, NULL, 0)))
2663         return 0;
2664     num = atoi(t->value);
2665
2666     avio_wb32(pb, size);
2667     ffio_wfourcc(pb, name);
2668     avio_wb32(pb, size - 8);
2669     ffio_wfourcc(pb, "data");
2670     avio_wb32(pb, 0x15);
2671     avio_wb32(pb, 0);
2672     if (len==4) avio_wb32(pb, num);
2673     else        avio_w8 (pb, num);
2674
2675     return size;
2676 }
2677
2678 /* iTunes meta data list */
2679 static int mov_write_ilst_tag(AVIOContext *pb, MOVMuxContext *mov,
2680                               AVFormatContext *s)
2681 {
2682     int64_t pos = avio_tell(pb);
2683     avio_wb32(pb, 0); /* size */
2684     ffio_wfourcc(pb, "ilst");
2685     mov_write_string_metadata(s, pb, "\251nam", "title"    , 1);
2686     mov_write_string_metadata(s, pb, "\251ART", "artist"   , 1);
2687     mov_write_string_metadata(s, pb, "aART", "album_artist", 1);
2688     mov_write_string_metadata(s, pb, "\251wrt", "composer" , 1);
2689     mov_write_string_metadata(s, pb, "\251alb", "album"    , 1);
2690     mov_write_string_metadata(s, pb, "\251day", "date"     , 1);
2691     if (!mov->exact &&
2692         !mov_write_string_metadata(s, pb, "\251too", "encoding_tool", 1))
2693         mov_write_string_tag(pb, "\251too", LIBAVFORMAT_IDENT, 0, 1);
2694     mov_write_string_metadata(s, pb, "\251cmt", "comment"  , 1);
2695     mov_write_string_metadata(s, pb, "\251gen", "genre"    , 1);
2696     mov_write_string_metadata(s, pb, "\251cpy", "copyright", 1);
2697     mov_write_string_metadata(s, pb, "\251grp", "grouping" , 1);
2698     mov_write_string_metadata(s, pb, "\251lyr", "lyrics"   , 1);
2699     mov_write_string_metadata(s, pb, "desc",    "description",1);
2700     mov_write_string_metadata(s, pb, "ldes",    "synopsis" , 1);
2701     mov_write_string_metadata(s, pb, "tvsh",    "show"     , 1);
2702     mov_write_string_metadata(s, pb, "tven",    "episode_id",1);
2703     mov_write_string_metadata(s, pb, "tvnn",    "network"  , 1);
2704     mov_write_int8_metadata  (s, pb, "tves",    "episode_sort",4);
2705     mov_write_int8_metadata  (s, pb, "tvsn",    "season_number",4);
2706     mov_write_int8_metadata  (s, pb, "stik",    "media_type",1);
2707     mov_write_int8_metadata  (s, pb, "hdvd",    "hd_video",  1);
2708     mov_write_int8_metadata  (s, pb, "pgap",    "gapless_playback",1);
2709     mov_write_int8_metadata  (s, pb, "cpil",    "compilation", 1);
2710     mov_write_trkn_tag(pb, mov, s, 0); // track number
2711     mov_write_trkn_tag(pb, mov, s, 1); // disc number
2712     mov_write_tmpo_tag(pb, s);
2713     return update_size(pb, pos);
2714 }
2715
2716 /* iTunes meta data tag */
2717 static int mov_write_meta_tag(AVIOContext *pb, MOVMuxContext *mov,
2718                               AVFormatContext *s)
2719 {
2720     int size = 0;
2721     int64_t pos = avio_tell(pb);
2722     avio_wb32(pb, 0); /* size */
2723     ffio_wfourcc(pb, "meta");
2724     avio_wb32(pb, 0);
2725     mov_write_itunes_hdlr_tag(pb, mov, s);
2726     mov_write_ilst_tag(pb, mov, s);
2727     size = update_size(pb, pos);
2728     return size;
2729 }
2730
2731 static int mov_write_raw_metadata_tag(AVFormatContext *s, AVIOContext *pb,
2732                                       const char *name, const char *key)
2733 {
2734     int len;
2735     AVDictionaryEntry *t;
2736
2737     if (!(t = av_dict_get(s->metadata, key, NULL, 0)))
2738         return 0;
2739
2740     len = strlen(t->value);
2741     if (len > 0) {
2742         int size = len + 8;
2743         avio_wb32(pb, size);
2744         ffio_wfourcc(pb, name);
2745         avio_write(pb, t->value, len);
2746         return size;
2747     }
2748     return 0;
2749 }
2750
2751 static int ascii_to_wc(AVIOContext *pb, const uint8_t *b)
2752 {
2753     int val;
2754     while (*b) {
2755         GET_UTF8(val, *b++, return -1;)
2756         avio_wb16(pb, val);
2757     }
2758     avio_wb16(pb, 0x00);
2759     return 0;
2760 }
2761
2762 static uint16_t language_code(const char *str)
2763 {
2764     return (((str[0] - 0x60) & 0x1F) << 10) +
2765            (((str[1] - 0x60) & 0x1F) <<  5) +
2766            (( str[2] - 0x60) & 0x1F);
2767 }
2768
2769 static int mov_write_3gp_udta_tag(AVIOContext *pb, AVFormatContext *s,
2770                                   const char *tag, const char *str)
2771 {
2772     int64_t pos = avio_tell(pb);
2773     AVDictionaryEntry *t = av_dict_get(s->metadata, str, NULL, 0);
2774     if (!t || !utf8len(t->value))
2775         return 0;
2776     avio_wb32(pb, 0);   /* size */
2777     ffio_wfourcc(pb, tag); /* type */
2778     avio_wb32(pb, 0);   /* version + flags */
2779     if (!strcmp(tag, "yrrc"))
2780         avio_wb16(pb, atoi(t->value));
2781     else {
2782         avio_wb16(pb, language_code("eng")); /* language */
2783         avio_write(pb, t->value, strlen(t->value) + 1); /* UTF8 string value */
2784         if (!strcmp(tag, "albm") &&
2785             (t = av_dict_get(s->metadata, "track", NULL, 0)))
2786             avio_w8(pb, atoi(t->value));
2787     }
2788     return update_size(pb, pos);
2789 }
2790
2791 static int mov_write_chpl_tag(AVIOContext *pb, AVFormatContext *s)
2792 {
2793     int64_t pos = avio_tell(pb);
2794     int i, nb_chapters = FFMIN(s->nb_chapters, 255);
2795
2796     avio_wb32(pb, 0);            // size
2797     ffio_wfourcc(pb, "chpl");
2798     avio_wb32(pb, 0x01000000);   // version + flags
2799     avio_wb32(pb, 0);            // unknown
2800     avio_w8(pb, nb_chapters);
2801
2802     for (i = 0; i < nb_chapters; i++) {
2803         AVChapter *c = s->chapters[i];
2804         AVDictionaryEntry *t;
2805         avio_wb64(pb, av_rescale_q(c->start, c->time_base, (AVRational){1,10000000}));
2806
2807         if ((t = av_dict_get(c->metadata, "title", NULL, 0))) {
2808             int len = FFMIN(strlen(t->value), 255);
2809             avio_w8(pb, len);
2810             avio_write(pb, t->value, len);
2811         } else
2812             avio_w8(pb, 0);
2813     }
2814     return update_size(pb, pos);
2815 }
2816
2817 static int mov_write_udta_tag(AVIOContext *pb, MOVMuxContext *mov,
2818                               AVFormatContext *s)
2819 {
2820     AVIOContext *pb_buf;
2821     int ret, size;
2822     uint8_t *buf;
2823
2824     ret = avio_open_dyn_buf(&pb_buf);
2825     if (ret < 0)
2826         return ret;
2827
2828     if (mov->mode & MODE_3GP) {
2829         mov_write_3gp_udta_tag(pb_buf, s, "perf", "artist");
2830         mov_write_3gp_udta_tag(pb_buf, s, "titl", "title");
2831         mov_write_3gp_udta_tag(pb_buf, s, "auth", "author");
2832         mov_write_3gp_udta_tag(pb_buf, s, "gnre", "genre");
2833         mov_write_3gp_udta_tag(pb_buf, s, "dscp", "comment");
2834         mov_write_3gp_udta_tag(pb_buf, s, "albm", "album");
2835         mov_write_3gp_udta_tag(pb_buf, s, "cprt", "copyright");
2836         mov_write_3gp_udta_tag(pb_buf, s, "yrrc", "date");
2837     } else if (mov->mode == MODE_MOV) { // the title field breaks gtkpod with mp4 and my suspicion is that stuff is not valid in mp4
2838         mov_write_string_metadata(s, pb_buf, "\251ART", "artist",      0);
2839         mov_write_string_metadata(s, pb_buf, "\251nam", "title",       0);
2840         mov_write_string_metadata(s, pb_buf, "\251aut", "author",      0);
2841         mov_write_string_metadata(s, pb_buf, "\251alb", "album",       0);
2842         mov_write_string_metadata(s, pb_buf, "\251day", "date",        0);
2843         mov_write_string_metadata(s, pb_buf, "\251swr", "encoder",     0);
2844         // currently ignored by mov.c
2845         mov_write_string_metadata(s, pb_buf, "\251des", "comment",     0);
2846         // add support for libquicktime, this atom is also actually read by mov.c
2847         mov_write_string_metadata(s, pb_buf, "\251cmt", "comment",     0);
2848         mov_write_string_metadata(s, pb_buf, "\251gen", "genre",       0);
2849         mov_write_string_metadata(s, pb_buf, "\251cpy", "copyright",   0);
2850         mov_write_raw_metadata_tag(s, pb_buf, "XMP_", "xmp");
2851     } else {
2852         /* iTunes meta data */
2853         mov_write_meta_tag(pb_buf, mov, s);
2854     }
2855
2856     if (s->nb_chapters && !(mov->flags & FF_MOV_FLAG_DISABLE_CHPL))
2857         mov_write_chpl_tag(pb_buf, s);
2858
2859     if ((size = avio_close_dyn_buf(pb_buf, &buf)) > 0) {
2860         avio_wb32(pb, size + 8);
2861         ffio_wfourcc(pb, "udta");
2862         avio_write(pb, buf, size);
2863     }
2864     av_free(buf);
2865
2866     return 0;
2867 }
2868
2869 static void mov_write_psp_udta_tag(AVIOContext *pb,
2870                                    const char *str, const char *lang, int type)
2871 {
2872     int len = utf8len(str) + 1;
2873     if (len <= 0)
2874         return;
2875     avio_wb16(pb, len * 2 + 10);        /* size */
2876     avio_wb32(pb, type);                /* type */
2877     avio_wb16(pb, language_code(lang)); /* language */
2878     avio_wb16(pb, 0x01);                /* ? */
2879     ascii_to_wc(pb, str);
2880 }
2881
2882 static int mov_write_uuidusmt_tag(AVIOContext *pb, AVFormatContext *s)
2883 {
2884     MOVMuxContext *mov = s->priv_data;
2885     AVDictionaryEntry *title = av_dict_get(s->metadata, "title", NULL, 0);
2886     int64_t pos, pos2;
2887
2888     if (title) {
2889         pos = avio_tell(pb);
2890         avio_wb32(pb, 0); /* size placeholder*/
2891         ffio_wfourcc(pb, "uuid");
2892         ffio_wfourcc(pb, "USMT");
2893         avio_wb32(pb, 0x21d24fce); /* 96 bit UUID */
2894         avio_wb32(pb, 0xbb88695c);
2895         avio_wb32(pb, 0xfac9c740);
2896
2897         pos2 = avio_tell(pb);
2898         avio_wb32(pb, 0); /* size placeholder*/
2899         ffio_wfourcc(pb, "MTDT");
2900         avio_wb16(pb, 4);
2901
2902         // ?
2903         avio_wb16(pb, 0x0C);                 /* size */
2904         avio_wb32(pb, 0x0B);                 /* type */
2905         avio_wb16(pb, language_code("und")); /* language */
2906         avio_wb16(pb, 0x0);                  /* ? */
2907         avio_wb16(pb, 0x021C);               /* data */
2908
2909         if (!mov->exact)
2910             mov_write_psp_udta_tag(pb, LIBAVCODEC_IDENT,      "eng", 0x04);
2911         mov_write_psp_udta_tag(pb, title->value,          "eng", 0x01);
2912         mov_write_psp_udta_tag(pb, "2006/04/01 11:11:11", "und", 0x03);
2913
2914         update_size(pb, pos2);
2915         return update_size(pb, pos);
2916     }
2917
2918     return 0;
2919 }
2920
2921 static void build_chunks(MOVTrack *trk)
2922 {
2923     int i;
2924     MOVIentry *chunk = &trk->cluster[0];
2925     uint64_t chunkSize = chunk->size;
2926     chunk->chunkNum = 1;
2927     if (trk->chunkCount)
2928         return;
2929     trk->chunkCount = 1;
2930     for (i = 1; i<trk->entry; i++){
2931         if (chunk->pos + chunkSize == trk->cluster[i].pos &&
2932             chunkSize + trk->cluster[i].size < (1<<20)){
2933             chunkSize             += trk->cluster[i].size;
2934             chunk->samples_in_chunk += trk->cluster[i].entries;
2935         } else {
2936             trk->cluster[i].chunkNum = chunk->chunkNum+1;
2937             chunk=&trk->cluster[i];
2938             chunkSize = chunk->size;
2939             trk->chunkCount++;
2940         }
2941     }
2942 }
2943
2944 static int mov_write_moov_tag(AVIOContext *pb, MOVMuxContext *mov,
2945                               AVFormatContext *s)
2946 {
2947     int i;
2948     int64_t pos = avio_tell(pb);
2949     avio_wb32(pb, 0); /* size placeholder*/
2950     ffio_wfourcc(pb, "moov");
2951
2952     for (i = 0; i < mov->nb_streams; i++) {
2953         if (mov->tracks[i].entry <= 0 && !(mov->flags & FF_MOV_FLAG_FRAGMENT))
2954             continue;
2955
2956         mov->tracks[i].time     = mov->time;
2957         mov->tracks[i].track_id = i + 1;
2958
2959         if (mov->tracks[i].entry)
2960             build_chunks(&mov->tracks[i]);
2961     }
2962
2963     if (mov->chapter_track)
2964         for (i = 0; i < s->nb_streams; i++) {
2965             mov->tracks[i].tref_tag = MKTAG('c','h','a','p');
2966             mov->tracks[i].tref_id  = mov->tracks[mov->chapter_track].track_id;
2967         }
2968     for (i = 0; i < mov->nb_streams; i++) {
2969         if (mov->tracks[i].tag == MKTAG('r','t','p',' ')) {
2970             mov->tracks[i].tref_tag = MKTAG('h','i','n','t');
2971             mov->tracks[i].tref_id =
2972                 mov->tracks[mov->tracks[i].src_track].track_id;
2973         }
2974     }
2975     for (i = 0; i < mov->nb_streams; i++) {
2976         if (mov->tracks[i].tag == MKTAG('t','m','c','d')) {
2977             int src_trk = mov->tracks[i].src_track;
2978             mov->tracks[src_trk].tref_tag = mov->tracks[i].tag;
2979             mov->tracks[src_trk].tref_id  = mov->tracks[i].track_id;
2980             //src_trk may have a different timescale than the tmcd track
2981             mov->tracks[i].track_duration = av_rescale(mov->tracks[src_trk].track_duration,
2982                                                        mov->tracks[i].timescale,
2983                                                        mov->tracks[src_trk].timescale);
2984         }
2985     }
2986
2987     mov_write_mvhd_tag(pb, mov);
2988     if (mov->mode != MODE_MOV && !mov->iods_skip)
2989         mov_write_iods_tag(pb, mov);
2990     for (i = 0; i < mov->nb_streams; i++) {
2991         if (mov->tracks[i].entry > 0 || mov->flags & FF_MOV_FLAG_FRAGMENT) {
2992             mov_write_trak_tag(pb, mov, &(mov->tracks[i]), i < s->nb_streams ? s->streams[i] : NULL);
2993         }
2994     }
2995     if (mov->flags & FF_MOV_FLAG_FRAGMENT)
2996         mov_write_mvex_tag(pb, mov); /* QuickTime requires trak to precede this */
2997
2998     if (mov->mode == MODE_PSP)
2999         mov_write_uuidusmt_tag(pb, s);
3000     else
3001         mov_write_udta_tag(pb, mov, s);
3002
3003     return update_size(pb, pos);
3004 }
3005
3006 static void param_write_int(AVIOContext *pb, const char *name, int value)
3007 {
3008     avio_printf(pb, "<param name=\"%s\" value=\"%d\" valuetype=\"data\"/>\n", name, value);
3009 }
3010
3011 static void param_write_string(AVIOContext *pb, const char *name, const char *value)
3012 {
3013     avio_printf(pb, "<param name=\"%s\" value=\"%s\" valuetype=\"data\"/>\n", name, value);
3014 }
3015
3016 static void param_write_hex(AVIOContext *pb, const char *name, const uint8_t *value, int len)
3017 {
3018     char buf[150];
3019     len = FFMIN(sizeof(buf) / 2 - 1, len);
3020     ff_data_to_hex(buf, value, len, 0);
3021     buf[2 * len] = '\0';
3022     avio_printf(pb, "<param name=\"%s\" value=\"%s\" valuetype=\"data\"/>\n", name, buf);
3023 }
3024
3025 static int mov_write_isml_manifest(AVIOContext *pb, MOVMuxContext *mov)
3026 {
3027     int64_t pos = avio_tell(pb);
3028     int i;
3029     static const uint8_t uuid[] = {
3030         0xa5, 0xd4, 0x0b, 0x30, 0xe8, 0x14, 0x11, 0xdd,
3031         0xba, 0x2f, 0x08, 0x00, 0x20, 0x0c, 0x9a, 0x66
3032     };
3033
3034     avio_wb32(pb, 0);
3035     ffio_wfourcc(pb, "uuid");
3036     avio_write(pb, uuid, sizeof(uuid));
3037     avio_wb32(pb, 0);
3038
3039     avio_printf(pb, "<?xml version=\"1.0\" encoding=\"utf-8\"?>\n");
3040     avio_printf(pb, "<smil xmlns=\"http://www.w3.org/2001/SMIL20/Language\">\n");
3041     avio_printf(pb, "<head>\n");
3042     if (!mov->exact)
3043         avio_printf(pb, "<meta name=\"creator\" content=\"%s\" />\n",
3044                     LIBAVFORMAT_IDENT);
3045     avio_printf(pb, "</head>\n");
3046     avio_printf(pb, "<body>\n");
3047     avio_printf(pb, "<switch>\n");
3048     for (i = 0; i < mov->nb_streams; i++) {
3049         MOVTrack *track = &mov->tracks[i];
3050         const char *type;
3051         /* track->track_id is initialized in write_moov, and thus isn't known
3052          * here yet */
3053         int track_id = i + 1;
3054
3055         if (track->enc->codec_type == AVMEDIA_TYPE_VIDEO) {
3056             type = "video";
3057         } else if (track->enc->codec_type == AVMEDIA_TYPE_AUDIO) {
3058             type = "audio";
3059         } else {
3060             continue;
3061         }
3062         avio_printf(pb, "<%s systemBitrate=\"%d\">\n", type,
3063                                                        track->enc->bit_rate);
3064         param_write_int(pb, "systemBitrate", track->enc->bit_rate);
3065         param_write_int(pb, "trackID", track_id);
3066         if (track->enc->codec_type == AVMEDIA_TYPE_VIDEO) {
3067             if (track->enc->codec_id == AV_CODEC_ID_H264) {
3068                 uint8_t *ptr;
3069                 int size = track->enc->extradata_size;
3070                 if (!ff_avc_write_annexb_extradata(track->enc->extradata, &ptr,
3071                                                    &size)) {
3072                     param_write_hex(pb, "CodecPrivateData",
3073                                     ptr ? ptr : track->enc->extradata,
3074                                     size);
3075                     av_free(ptr);
3076                 }
3077                 param_write_string(pb, "FourCC", "H264");
3078             } else if (track->enc->codec_id == AV_CODEC_ID_VC1) {
3079                 param_write_string(pb, "FourCC", "WVC1");
3080                 param_write_hex(pb, "CodecPrivateData", track->enc->extradata,
3081                                 track->enc->extradata_size);
3082             }
3083             param_write_int(pb, "MaxWidth", track->enc->width);
3084             param_write_int(pb, "MaxHeight", track->enc->height);
3085             param_write_int(pb, "DisplayWidth", track->enc->width);
3086             param_write_int(pb, "DisplayHeight", track->enc->height);
3087         } else {
3088             if (track->enc->codec_id == AV_CODEC_ID_AAC) {
3089                 param_write_string(pb, "FourCC", "AACL");
3090             } else if (track->enc->codec_id == AV_CODEC_ID_WMAPRO) {
3091                 param_write_string(pb, "FourCC", "WMAP");
3092             }
3093             param_write_hex(pb, "CodecPrivateData", track->enc->extradata,
3094                             track->enc->extradata_size);
3095             param_write_int(pb, "AudioTag", ff_codec_get_tag(ff_codec_wav_tags,
3096                                                              track->enc->codec_id));
3097             param_write_int(pb, "Channels", track->enc->channels);
3098             param_write_int(pb, "SamplingRate", track->enc->sample_rate);
3099             param_write_int(pb, "BitsPerSample", 16);
3100             param_write_int(pb, "PacketSize", track->enc->block_align ?
3101                                               track->enc->block_align : 4);
3102         }
3103         avio_printf(pb, "</%s>\n", type);
3104     }
3105     avio_printf(pb, "</switch>\n");
3106     avio_printf(pb, "</body>\n");
3107     avio_printf(pb, "</smil>\n");
3108
3109     return update_size(pb, pos);
3110 }
3111
3112 static int mov_write_mfhd_tag(AVIOContext *pb, MOVMuxContext *mov)
3113 {
3114     avio_wb32(pb, 16);
3115     ffio_wfourcc(pb, "mfhd");
3116     avio_wb32(pb, 0);
3117     avio_wb32(pb, mov->fragments);
3118     return 0;
3119 }
3120
3121 static int mov_write_tfhd_tag(AVIOContext *pb, MOVMuxContext *mov,
3122                               MOVTrack *track, int64_t moof_offset)
3123 {
3124     int64_t pos = avio_tell(pb);
3125     uint32_t flags = MOV_TFHD_DEFAULT_SIZE | MOV_TFHD_DEFAULT_DURATION |
3126                      MOV_TFHD_BASE_DATA_OFFSET;
3127     if (!track->entry) {
3128         flags |= MOV_TFHD_DURATION_IS_EMPTY;
3129     } else {
3130         flags |= MOV_TFHD_DEFAULT_FLAGS;
3131     }
3132     if (mov->flags & FF_MOV_FLAG_OMIT_TFHD_OFFSET)
3133         flags &= ~MOV_TFHD_BASE_DATA_OFFSET;
3134     if (mov->flags & FF_MOV_FLAG_DEFAULT_BASE_MOOF) {
3135         flags &= ~MOV_TFHD_BASE_DATA_OFFSET;
3136         flags |= MOV_TFHD_DEFAULT_BASE_IS_MOOF;
3137     }
3138
3139     /* Don't set a default sample size, the silverlight player refuses
3140      * to play files with that set. Don't set a default sample duration,
3141      * WMP freaks out if it is set. Don't set a base data offset, PIFF
3142      * file format says it MUST NOT be set. */
3143     if (track->mode == MODE_ISM)
3144         flags &= ~(MOV_TFHD_DEFAULT_SIZE | MOV_TFHD_DEFAULT_DURATION |
3145                    MOV_TFHD_BASE_DATA_OFFSET);
3146
3147     avio_wb32(pb, 0); /* size placeholder */
3148     ffio_wfourcc(pb, "tfhd");
3149     avio_w8(pb, 0); /* version */
3150     avio_wb24(pb, flags);
3151
3152     avio_wb32(pb, track->track_id); /* track-id */
3153     if (flags & MOV_TFHD_BASE_DATA_OFFSET)
3154         avio_wb64(pb, moof_offset);
3155     if (flags & MOV_TFHD_DEFAULT_DURATION) {
3156         track->default_duration = get_cluster_duration(track, 0);
3157         avio_wb32(pb, track->default_duration);
3158     }
3159     if (flags & MOV_TFHD_DEFAULT_SIZE) {
3160         track->default_size = track->entry ? track->cluster[0].size : 1;
3161         avio_wb32(pb, track->default_size);
3162     } else
3163         track->default_size = -1;
3164
3165     if (flags & MOV_TFHD_DEFAULT_FLAGS) {
3166         track->default_sample_flags =
3167             track->enc->codec_type == AVMEDIA_TYPE_VIDEO ?
3168             (MOV_FRAG_SAMPLE_FLAG_DEPENDS_YES | MOV_FRAG_SAMPLE_FLAG_IS_NON_SYNC) :
3169             MOV_FRAG_SAMPLE_FLAG_DEPENDS_NO;
3170         avio_wb32(pb, track->default_sample_flags);
3171     }
3172
3173     return update_size(pb, pos);
3174 }
3175
3176 static uint32_t get_sample_flags(MOVTrack *track, MOVIentry *entry)
3177 {
3178     return entry->flags & MOV_SYNC_SAMPLE ? MOV_FRAG_SAMPLE_FLAG_DEPENDS_NO :
3179            (MOV_FRAG_SAMPLE_FLAG_DEPENDS_YES | MOV_FRAG_SAMPLE_FLAG_IS_NON_SYNC);
3180 }
3181
3182 static int mov_write_trun_tag(AVIOContext *pb, MOVMuxContext *mov,
3183                               MOVTrack *track, int moof_size)
3184 {
3185     int64_t pos = avio_tell(pb);
3186     uint32_t flags = MOV_TRUN_DATA_OFFSET;
3187     int i;
3188
3189     for (i = 0; i < track->entry; i++) {
3190         if (get_cluster_duration(track, i) != track->default_duration)
3191             flags |= MOV_TRUN_SAMPLE_DURATION;
3192         if (track->cluster[i].size != track->default_size)
3193             flags |= MOV_TRUN_SAMPLE_SIZE;
3194         if (i > 0 && get_sample_flags(track, &track->cluster[i]) != track->default_sample_flags)
3195             flags |= MOV_TRUN_SAMPLE_FLAGS;
3196     }
3197     if (!(flags & MOV_TRUN_SAMPLE_FLAGS))
3198         flags |= MOV_TRUN_FIRST_SAMPLE_FLAGS;
3199     if (track->flags & MOV_TRACK_CTTS)
3200         flags |= MOV_TRUN_SAMPLE_CTS;
3201
3202     avio_wb32(pb, 0); /* size placeholder */
3203     ffio_wfourcc(pb, "trun");
3204     avio_w8(pb, 0); /* version */
3205     avio_wb24(pb, flags);
3206
3207     avio_wb32(pb, track->entry); /* sample count */
3208     if (mov->flags & FF_MOV_FLAG_OMIT_TFHD_OFFSET &&
3209         !(mov->flags & FF_MOV_FLAG_DEFAULT_BASE_MOOF) &&
3210         !mov->first_trun)
3211         avio_wb32(pb, 0); /* Later tracks follow immediately after the previous one */
3212     else
3213         avio_wb32(pb, moof_size + 8 + track->data_offset +
3214                       track->cluster[0].pos); /* data offset */
3215     if (flags & MOV_TRUN_FIRST_SAMPLE_FLAGS)
3216         avio_wb32(pb, get_sample_flags(track, &track->cluster[0]));
3217
3218     for (i = 0; i < track->entry; i++) {
3219         if (flags & MOV_TRUN_SAMPLE_DURATION)
3220             avio_wb32(pb, get_cluster_duration(track, i));
3221         if (flags & MOV_TRUN_SAMPLE_SIZE)
3222             avio_wb32(pb, track->cluster[i].size);
3223         if (flags & MOV_TRUN_SAMPLE_FLAGS)
3224             avio_wb32(pb, get_sample_flags(track, &track->cluster[i]));
3225         if (flags & MOV_TRUN_SAMPLE_CTS)
3226             avio_wb32(pb, track->cluster[i].cts);
3227     }
3228
3229     mov->first_trun = 0;
3230     return update_size(pb, pos);
3231 }
3232
3233 static int mov_write_tfxd_tag(AVIOContext *pb, MOVTrack *track)
3234 {
3235     int64_t pos = avio_tell(pb);
3236     static const uint8_t uuid[] = {
3237         0x6d, 0x1d, 0x9b, 0x05, 0x42, 0xd5, 0x44, 0xe6,
3238         0x80, 0xe2, 0x14, 0x1d, 0xaf, 0xf7, 0x57, 0xb2
3239     };
3240
3241     avio_wb32(pb, 0); /* size placeholder */
3242     ffio_wfourcc(pb, "uuid");
3243     avio_write(pb, uuid, sizeof(uuid));
3244     avio_w8(pb, 1);
3245     avio_wb24(pb, 0);
3246     avio_wb64(pb, track->frag_start);
3247     avio_wb64(pb, track->start_dts + track->track_duration -
3248                   track->cluster[0].dts);
3249
3250     return update_size(pb, pos);
3251 }
3252
3253 static int mov_write_tfrf_tag(AVIOContext *pb, MOVMuxContext *mov,
3254                               MOVTrack *track, int entry)
3255 {
3256     int n = track->nb_frag_info - 1 - entry, i;
3257     int size = 8 + 16 + 4 + 1 + 16*n;
3258     static const uint8_t uuid[] = {
3259         0xd4, 0x80, 0x7e, 0xf2, 0xca, 0x39, 0x46, 0x95,
3260         0x8e, 0x54, 0x26, 0xcb, 0x9e, 0x46, 0xa7, 0x9f
3261     };
3262
3263     if (entry < 0)
3264         return 0;
3265
3266     avio_seek(pb, track->frag_info[entry].tfrf_offset, SEEK_SET);
3267     avio_wb32(pb, size);
3268     ffio_wfourcc(pb, "uuid");
3269     avio_write(pb, uuid, sizeof(uuid));
3270     avio_w8(pb, 1);
3271     avio_wb24(pb, 0);
3272     avio_w8(pb, n);
3273     for (i = 0; i < n; i++) {
3274         int index = entry + 1 + i;
3275         avio_wb64(pb, track->frag_info[index].time);
3276         avio_wb64(pb, track->frag_info[index].duration);
3277     }
3278     if (n < mov->ism_lookahead) {
3279         int free_size = 16 * (mov->ism_lookahead - n);
3280         avio_wb32(pb, free_size);
3281         ffio_wfourcc(pb, "free");
3282         ffio_fill(pb, 0, free_size - 8);
3283     }
3284
3285     return 0;
3286 }
3287
3288 static int mov_write_tfrf_tags(AVIOContext *pb, MOVMuxContext *mov,
3289                                MOVTrack *track)
3290 {
3291     int64_t pos = avio_tell(pb);
3292     int i;
3293     for (i = 0; i < mov->ism_lookahead; i++) {
3294         /* Update the tfrf tag for the last ism_lookahead fragments,
3295          * nb_frag_info - 1 is the next fragment to be written. */
3296         mov_write_tfrf_tag(pb, mov, track, track->nb_frag_info - 2 - i);
3297     }
3298     avio_seek(pb, pos, SEEK_SET);
3299     return 0;
3300 }
3301
3302 static int mov_add_tfra_entries(AVIOContext *pb, MOVMuxContext *mov, int tracks,
3303                                 int size)
3304 {
3305     int i;
3306     for (i = 0; i < mov->nb_streams; i++) {
3307         MOVTrack *track = &mov->tracks[i];
3308         MOVFragmentInfo *info;
3309         if ((tracks >= 0 && i != tracks) || !track->entry)
3310             continue;
3311         track->nb_frag_info++;
3312         if (track->nb_frag_info >= track->frag_info_capacity) {
3313             unsigned new_capacity = track->nb_frag_info + MOV_FRAG_INFO_ALLOC_INCREMENT;
3314             if (av_reallocp_array(&track->frag_info,
3315                                   new_capacity,
3316                                   sizeof(*track->frag_info)))
3317                 return AVERROR(ENOMEM);
3318             track->frag_info_capacity = new_capacity;
3319         }
3320         info = &track->frag_info[track->nb_frag_info - 1];
3321         info->offset   = avio_tell(pb);
3322         info->size     = size;
3323         // Try to recreate the original pts for the first packet
3324         // from the fields we have stored
3325         info->time     = track->start_dts + track->frag_start +
3326                          track->cluster[0].cts;
3327         // If the pts is less than zero, we will have trimmed
3328         // away parts of the media track using an edit list,
3329         // and the corresponding start presentation time is zero.
3330         if (info->time < 0)
3331             info->time = 0;
3332         info->duration = track->start_dts + track->track_duration -
3333                          track->cluster[0].dts;
3334         info->tfrf_offset = 0;
3335         mov_write_tfrf_tags(pb, mov, track);
3336     }
3337     return 0;
3338 }
3339
3340 static int mov_write_tfdt_tag(AVIOContext *pb, MOVTrack *track)
3341 {
3342     int64_t pos = avio_tell(pb);
3343
3344     avio_wb32(pb, 0); /* size */
3345     ffio_wfourcc(pb, "tfdt");
3346     avio_w8(pb, 1); /* version */
3347     avio_wb24(pb, 0);
3348     avio_wb64(pb, track->frag_start);
3349     return update_size(pb, pos);
3350 }
3351
3352 static int mov_write_traf_tag(AVIOContext *pb, MOVMuxContext *mov,
3353                               MOVTrack *track, int64_t moof_offset,
3354                               int moof_size)
3355 {
3356     int64_t pos = avio_tell(pb);
3357     avio_wb32(pb, 0); /* size placeholder */
3358     ffio_wfourcc(pb, "traf");
3359
3360     mov_write_tfhd_tag(pb, mov, track, moof_offset);
3361     if (mov->mode != MODE_ISM)
3362         mov_write_tfdt_tag(pb, track);
3363     mov_write_trun_tag(pb, mov, track, moof_size);
3364     if (mov->mode == MODE_ISM) {
3365         mov_write_tfxd_tag(pb, track);
3366
3367         if (mov->ism_lookahead) {
3368             int i, size = 16 + 4 + 1 + 16 * mov->ism_lookahead;
3369
3370             if (track->nb_frag_info > 0) {
3371                 MOVFragmentInfo *info = &track->frag_info[track->nb_frag_info - 1];
3372                 if (!info->tfrf_offset)
3373                     info->tfrf_offset = avio_tell(pb);
3374             }
3375             avio_wb32(pb, 8 + size);
3376             ffio_wfourcc(pb, "free");
3377             for (i = 0; i < size; i++)
3378                 avio_w8(pb, 0);
3379         }
3380     }
3381
3382     return update_size(pb, pos);
3383 }
3384
3385 static int mov_write_moof_tag_internal(AVIOContext *pb, MOVMuxContext *mov,
3386                                        int tracks, int moof_size)
3387 {
3388     int64_t pos = avio_tell(pb);
3389     int i;
3390
3391     avio_wb32(pb, 0); /* size placeholder */
3392     ffio_wfourcc(pb, "moof");
3393     mov->first_trun = 1;
3394
3395     mov_write_mfhd_tag(pb, mov);
3396     for (i = 0; i < mov->nb_streams; i++) {
3397         MOVTrack *track = &mov->tracks[i];
3398         if (tracks >= 0 && i != tracks)
3399             continue;
3400         if (!track->entry)
3401             continue;
3402         mov_write_traf_tag(pb, mov, track, pos, moof_size);
3403     }
3404
3405     return update_size(pb, pos);
3406 }
3407
3408 static int mov_write_sidx_tag(AVIOContext *pb,
3409                               MOVTrack *track, int ref_size, int total_sidx_size)
3410 {
3411     int64_t pos = avio_tell(pb), offset_pos, end_pos;
3412     int64_t presentation_time, duration, offset;
3413     int starts_with_SAP, i, entries;
3414
3415     if (track->entry) {
3416         entries = 1;
3417         presentation_time = track->start_dts + track->frag_start +
3418                             track->cluster[0].cts;
3419         duration = track->start_dts + track->track_duration -
3420                    track->cluster[0].dts;
3421         starts_with_SAP = track->cluster[0].flags & MOV_SYNC_SAMPLE;
3422     } else {
3423         entries = track->nb_frag_info;
3424         presentation_time = track->frag_info[0].time;
3425     }
3426
3427     // pts<0 should be cut away using edts
3428     if (presentation_time < 0)
3429         presentation_time = 0;
3430
3431     avio_wb32(pb, 0); /* size */
3432     ffio_wfourcc(pb, "sidx");
3433     avio_w8(pb, 1); /* version */
3434     avio_wb24(pb, 0);
3435     avio_wb32(pb, track->track_id); /* reference_ID */
3436     avio_wb32(pb, track->timescale); /* timescale */
3437     avio_wb64(pb, presentation_time); /* earliest_presentation_time */
3438     offset_pos = avio_tell(pb);
3439     avio_wb64(pb, 0); /* first_offset (offset to referenced moof) */
3440     avio_wb16(pb, 0); /* reserved */
3441
3442     avio_wb16(pb, entries); /* reference_count */
3443     for (i = 0; i < entries; i++) {
3444         if (!track->entry) {
3445             if (i > 1 && track->frag_info[i].offset != track->frag_info[i - 1].offset + track->frag_info[i - 1].size) {
3446                av_log(NULL, AV_LOG_ERROR, "Non-consecutive fragments, writing incorrect sidx\n");
3447             }
3448             duration = track->frag_info[i].duration;
3449             ref_size = track->frag_info[i].size;
3450             starts_with_SAP = 1;
3451         }
3452         avio_wb32(pb, (0 << 31) | (ref_size & 0x7fffffff)); /* reference_type (0 = media) | referenced_size */
3453         avio_wb32(pb, duration); /* subsegment_duration */
3454         avio_wb32(pb, (starts_with_SAP << 31) | (0 << 28) | 0); /* starts_with_SAP | SAP_type | SAP_delta_time */
3455     }
3456
3457     end_pos = avio_tell(pb);
3458     offset = pos + total_sidx_size - end_pos;
3459     avio_seek(pb, offset_pos, SEEK_SET);
3460     avio_wb64(pb, offset);
3461     avio_seek(pb, end_pos, SEEK_SET);
3462     return update_size(pb, pos);
3463 }
3464
3465 static int mov_write_sidx_tags(AVIOContext *pb, MOVMuxContext *mov,
3466                                int tracks, int ref_size)
3467 {
3468     int i, round, ret;
3469     AVIOContext *avio_buf;
3470     int total_size = 0;
3471     for (round = 0; round < 2; round++) {
3472         // First run one round to calculate the total size of all
3473         // sidx atoms.
3474         // This would be much simpler if we'd only write one sidx
3475         // atom, for the first track in the moof.
3476         if (round == 0) {
3477             if ((ret = ffio_open_null_buf(&avio_buf)) < 0)
3478                 return ret;
3479         } else {
3480             avio_buf = pb;
3481         }
3482         for (i = 0; i < mov->nb_streams; i++) {
3483             MOVTrack *track = &mov->tracks[i];
3484             if (tracks >= 0 && i != tracks)
3485                 continue;
3486             // When writing a sidx for the full file, entry is 0, but
3487             // we want to include all tracks. ref_size is 0 in this case,
3488             // since we read it from frag_info instead.
3489             if (!track->entry && ref_size > 0)
3490                 continue;
3491             total_size -= mov_write_sidx_tag(avio_buf, track, ref_size,
3492                                              total_size);
3493         }
3494         if (round == 0)
3495             total_size = ffio_close_null_buf(avio_buf);
3496     }
3497     return 0;
3498 }
3499
3500 static int mov_write_moof_tag(AVIOContext *pb, MOVMuxContext *mov, int tracks,
3501                               int64_t mdat_size)
3502 {
3503     AVIOContext *avio_buf;
3504     int ret, moof_size;
3505
3506     if ((ret = ffio_open_null_buf(&avio_buf)) < 0)
3507         return ret;
3508     mov_write_moof_tag_internal(avio_buf, mov, tracks, 0);
3509     moof_size = ffio_close_null_buf(avio_buf);
3510
3511     if (mov->flags & FF_MOV_FLAG_DASH && !(mov->flags & FF_MOV_FLAG_FASTSTART))
3512         mov_write_sidx_tags(pb, mov, tracks, moof_size + 8 + mdat_size);
3513
3514     if ((ret = mov_add_tfra_entries(pb, mov, tracks, moof_size + 8 + mdat_size)) < 0)
3515         return ret;
3516
3517     return mov_write_moof_tag_internal(pb, mov, tracks, moof_size);
3518 }
3519
3520 static int mov_write_tfra_tag(AVIOContext *pb, MOVTrack *track)
3521 {
3522     int64_t pos = avio_tell(pb);
3523     int i;
3524
3525     avio_wb32(pb, 0); /* size placeholder */
3526     ffio_wfourcc(pb, "tfra");
3527     avio_w8(pb, 1); /* version */
3528     avio_wb24(pb, 0);
3529
3530     avio_wb32(pb, track->track_id);
3531     avio_wb32(pb, 0); /* length of traf/trun/sample num */
3532     avio_wb32(pb, track->nb_frag_info);
3533     for (i = 0; i < track->nb_frag_info; i++) {
3534         avio_wb64(pb, track->frag_info[i].time);
3535         avio_wb64(pb, track->frag_info[i].offset + track->data_offset);
3536         avio_w8(pb, 1); /* traf number */
3537         avio_w8(pb, 1); /* trun number */
3538         avio_w8(pb, 1); /* sample number */
3539     }
3540
3541     return update_size(pb, pos);
3542 }
3543
3544 static int mov_write_mfra_tag(AVIOContext *pb, MOVMuxContext *mov)
3545 {
3546     int64_t pos = avio_tell(pb);
3547     int i;
3548
3549     avio_wb32(pb, 0); /* size placeholder */
3550     ffio_wfourcc(pb, "mfra");
3551     /* An empty mfra atom is enough to indicate to the publishing point that
3552      * the stream has ended. */
3553     if (mov->flags & FF_MOV_FLAG_ISML)
3554         return update_size(pb, pos);
3555
3556     for (i = 0; i < mov->nb_streams; i++) {
3557         MOVTrack *track = &mov->tracks[i];
3558         if (track->nb_frag_info)
3559             mov_write_tfra_tag(pb, track);
3560     }
3561
3562     avio_wb32(pb, 16);
3563     ffio_wfourcc(pb, "mfro");
3564     avio_wb32(pb, 0); /* version + flags */
3565     avio_wb32(pb, avio_tell(pb) + 4 - pos);
3566
3567     return update_size(pb, pos);
3568 }
3569
3570 static int mov_write_mdat_tag(AVIOContext *pb, MOVMuxContext *mov)
3571 {
3572     avio_wb32(pb, 8);    // placeholder for extended size field (64 bit)
3573     ffio_wfourcc(pb, mov->mode == MODE_MOV ? "wide" : "free");
3574
3575     mov->mdat_pos = avio_tell(pb);
3576     avio_wb32(pb, 0); /* size placeholder*/
3577     ffio_wfourcc(pb, "mdat");
3578     return 0;
3579 }
3580
3581 /* TODO: This needs to be more general */
3582 static int mov_write_ftyp_tag(AVIOContext *pb, AVFormatContext *s)
3583 {
3584     MOVMuxContext *mov = s->priv_data;
3585     int64_t pos = avio_tell(pb);
3586     int has_h264 = 0, has_video = 0;
3587     int minor = 0x200;
3588     int i;
3589
3590     for (i = 0; i < s->nb_streams; i++) {
3591         AVStream *st = s->streams[i];
3592         if (st->codec->codec_type == AVMEDIA_TYPE_VIDEO)
3593             has_video = 1;
3594         if (st->codec->codec_id == AV_CODEC_ID_H264)
3595             has_h264 = 1;
3596     }
3597
3598     avio_wb32(pb, 0); /* size */
3599     ffio_wfourcc(pb, "ftyp");
3600
3601     if (mov->major_brand && strlen(mov->major_brand) >= 4)
3602         ffio_wfourcc(pb, mov->major_brand);