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