]> git.sesse.net Git - ffmpeg/blob - libavformat/movenc.c
Merge commit 'e02524025bce2c8bf8b5bffd96479785c75a70d4'
[ffmpeg] / libavformat / movenc.c
1 /*
2  * MOV, 3GP, MP4 muxer
3  * Copyright (c) 2003 Thomas Raivio
4  * Copyright (c) 2004 Gildas Bazin <gbazin at videolan dot org>
5  * Copyright (c) 2009 Baptiste Coudurier <baptiste dot coudurier at gmail dot com>
6  *
7  * This file is part of FFmpeg.
8  *
9  * FFmpeg is free software; you can redistribute it and/or
10  * modify it under the terms of the GNU Lesser General Public
11  * License as published by the Free Software Foundation; either
12  * version 2.1 of the License, or (at your option) any later version.
13  *
14  * FFmpeg is distributed in the hope that it will be useful,
15  * but WITHOUT ANY WARRANTY; without even the implied warranty of
16  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
17  * Lesser General Public License for more details.
18  *
19  * You should have received a copy of the GNU Lesser General Public
20  * License along with FFmpeg; if not, write to the Free Software
21  * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
22  */
23
24 #include <stdint.h>
25 #include <inttypes.h>
26
27 #include "movenc.h"
28 #include "avformat.h"
29 #include "avio_internal.h"
30 #include "riff.h"
31 #include "avio.h"
32 #include "isom.h"
33 #include "avc.h"
34 #include "libavcodec/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->streams[i]->id;
3601         }
3602
3603         for (i = 0; i < mov->nb_streams; i++) {
3604             if (mov->tracks[i].entry <= 0 && !(mov->flags & FF_MOV_FLAG_FRAGMENT))
3605                 continue;
3606
3607             mov->tracks[i].track_id = i >= s->nb_streams ? ++next_generated_track_id : s->streams[i]->id;
3608         }
3609     } else {
3610         for (i = 0; i < mov->nb_streams; i++) {
3611             if (mov->tracks[i].entry <= 0 && !(mov->flags & FF_MOV_FLAG_FRAGMENT))
3612                 continue;
3613
3614             mov->tracks[i].track_id = i + 1;
3615         }
3616     }
3617
3618     mov->track_ids_ok = 1;
3619
3620     return 0;
3621 }
3622
3623 static int mov_write_moov_tag(AVIOContext *pb, MOVMuxContext *mov,
3624                               AVFormatContext *s)
3625 {
3626     int i;
3627     int64_t pos = avio_tell(pb);
3628     avio_wb32(pb, 0); /* size placeholder*/
3629     ffio_wfourcc(pb, "moov");
3630
3631     mov_setup_track_ids(mov, s);
3632
3633     for (i = 0; i < mov->nb_streams; i++) {
3634         if (mov->tracks[i].entry <= 0 && !(mov->flags & FF_MOV_FLAG_FRAGMENT))
3635             continue;
3636
3637         mov->tracks[i].time     = mov->time;
3638
3639         if (mov->tracks[i].entry)
3640             build_chunks(&mov->tracks[i]);
3641     }
3642
3643     if (mov->chapter_track)
3644         for (i = 0; i < s->nb_streams; i++) {
3645             mov->tracks[i].tref_tag = MKTAG('c','h','a','p');
3646             mov->tracks[i].tref_id  = mov->tracks[mov->chapter_track].track_id;
3647         }
3648     for (i = 0; i < mov->nb_streams; i++) {
3649         MOVTrack *track = &mov->tracks[i];
3650         if (track->tag == MKTAG('r','t','p',' ')) {
3651             track->tref_tag = MKTAG('h','i','n','t');
3652             track->tref_id = mov->tracks[track->src_track].track_id;
3653         } else if (track->par->codec_type == AVMEDIA_TYPE_AUDIO) {
3654             int * fallback, size;
3655             fallback = (int*)av_stream_get_side_data(track->st,
3656                                                      AV_PKT_DATA_FALLBACK_TRACK,
3657                                                      &size);
3658             if (fallback != NULL && size == sizeof(int)) {
3659                 if (*fallback >= 0 && *fallback < mov->nb_streams) {
3660                     track->tref_tag = MKTAG('f','a','l','l');
3661                     track->tref_id = mov->tracks[*fallback].track_id;
3662                 }
3663             }
3664         }
3665     }
3666     for (i = 0; i < mov->nb_streams; i++) {
3667         if (mov->tracks[i].tag == MKTAG('t','m','c','d')) {
3668             int src_trk = mov->tracks[i].src_track;
3669             mov->tracks[src_trk].tref_tag = mov->tracks[i].tag;
3670             mov->tracks[src_trk].tref_id  = mov->tracks[i].track_id;
3671             //src_trk may have a different timescale than the tmcd track
3672             mov->tracks[i].track_duration = av_rescale(mov->tracks[src_trk].track_duration,
3673                                                        mov->tracks[i].timescale,
3674                                                        mov->tracks[src_trk].timescale);
3675         }
3676     }
3677
3678     mov_write_mvhd_tag(pb, mov);
3679     if (mov->mode != MODE_MOV && !mov->iods_skip)
3680         mov_write_iods_tag(pb, mov);
3681     for (i = 0; i < mov->nb_streams; i++) {
3682         if (mov->tracks[i].entry > 0 || mov->flags & FF_MOV_FLAG_FRAGMENT) {
3683             int ret = mov_write_trak_tag(s, pb, mov, &(mov->tracks[i]), i < s->nb_streams ? s->streams[i] : NULL);
3684             if (ret < 0)
3685                 return ret;
3686         }
3687     }
3688     if (mov->flags & FF_MOV_FLAG_FRAGMENT)
3689         mov_write_mvex_tag(pb, mov); /* QuickTime requires trak to precede this */
3690
3691     if (mov->mode == MODE_PSP)
3692         mov_write_uuidusmt_tag(pb, s);
3693     else
3694         mov_write_udta_tag(pb, mov, s);
3695
3696     return update_size(pb, pos);
3697 }
3698
3699 static void param_write_int(AVIOContext *pb, const char *name, int value)
3700 {
3701     avio_printf(pb, "<param name=\"%s\" value=\"%d\" valuetype=\"data\"/>\n", name, value);
3702 }
3703
3704 static void param_write_string(AVIOContext *pb, const char *name, const char *value)
3705 {
3706     avio_printf(pb, "<param name=\"%s\" value=\"%s\" valuetype=\"data\"/>\n", name, value);
3707 }
3708
3709 static void param_write_hex(AVIOContext *pb, const char *name, const uint8_t *value, int len)
3710 {
3711     char buf[150];
3712     len = FFMIN(sizeof(buf) / 2 - 1, len);
3713     ff_data_to_hex(buf, value, len, 0);
3714     buf[2 * len] = '\0';
3715     avio_printf(pb, "<param name=\"%s\" value=\"%s\" valuetype=\"data\"/>\n", name, buf);
3716 }
3717
3718 static int mov_write_isml_manifest(AVIOContext *pb, MOVMuxContext *mov, AVFormatContext *s)
3719 {
3720     int64_t pos = avio_tell(pb);
3721     int i;
3722     int64_t manifest_bit_rate = 0;
3723     AVCPBProperties *props = NULL;
3724
3725     static const uint8_t uuid[] = {
3726         0xa5, 0xd4, 0x0b, 0x30, 0xe8, 0x14, 0x11, 0xdd,
3727         0xba, 0x2f, 0x08, 0x00, 0x20, 0x0c, 0x9a, 0x66
3728     };
3729
3730     avio_wb32(pb, 0);
3731     ffio_wfourcc(pb, "uuid");
3732     avio_write(pb, uuid, sizeof(uuid));
3733     avio_wb32(pb, 0);
3734
3735     avio_printf(pb, "<?xml version=\"1.0\" encoding=\"utf-8\"?>\n");
3736     avio_printf(pb, "<smil xmlns=\"http://www.w3.org/2001/SMIL20/Language\">\n");
3737     avio_printf(pb, "<head>\n");
3738     if (!(mov->fc->flags & AVFMT_FLAG_BITEXACT))
3739         avio_printf(pb, "<meta name=\"creator\" content=\"%s\" />\n",
3740                     LIBAVFORMAT_IDENT);
3741     avio_printf(pb, "</head>\n");
3742     avio_printf(pb, "<body>\n");
3743     avio_printf(pb, "<switch>\n");
3744
3745     mov_setup_track_ids(mov, s);
3746
3747     for (i = 0; i < mov->nb_streams; i++) {
3748         MOVTrack *track = &mov->tracks[i];
3749         const char *type;
3750         int track_id = track->track_id;
3751         char track_name_buf[32] = { 0 };
3752
3753         AVStream *st = track->st;
3754         AVDictionaryEntry *lang = av_dict_get(st->metadata, "language", NULL,0);
3755
3756         if (track->par->codec_type == AVMEDIA_TYPE_VIDEO) {
3757             type = "video";
3758         } else if (track->par->codec_type == AVMEDIA_TYPE_AUDIO) {
3759             type = "audio";
3760         } else {
3761             continue;
3762         }
3763
3764         props = (AVCPBProperties*)av_stream_get_side_data(track->st, AV_PKT_DATA_CPB_PROPERTIES, NULL);
3765
3766         if (track->par->bit_rate) {
3767             manifest_bit_rate = track->par->bit_rate;
3768         } else if (props) {
3769             manifest_bit_rate = props->max_bitrate;
3770         }
3771
3772         avio_printf(pb, "<%s systemBitrate=\"%"PRId64"\">\n", type,
3773                     manifest_bit_rate);
3774         param_write_int(pb, "systemBitrate", manifest_bit_rate);
3775         param_write_int(pb, "trackID", track_id);
3776         param_write_string(pb, "systemLanguage", lang ? lang->value : "und");
3777
3778         /* Build track name piece by piece: */
3779         /* 1. track type */
3780         av_strlcat(track_name_buf, type, sizeof(track_name_buf));
3781         /* 2. track language, if available */
3782         if (lang)
3783             av_strlcatf(track_name_buf, sizeof(track_name_buf),
3784                         "_%s", lang->value);
3785         /* 3. special type suffix */
3786         /* "_cc" = closed captions, "_ad" = audio_description */
3787         if (st->disposition & AV_DISPOSITION_HEARING_IMPAIRED)
3788             av_strlcat(track_name_buf, "_cc", sizeof(track_name_buf));
3789         else if (st->disposition & AV_DISPOSITION_VISUAL_IMPAIRED)
3790             av_strlcat(track_name_buf, "_ad", sizeof(track_name_buf));
3791
3792         param_write_string(pb, "trackName", track_name_buf);
3793
3794         if (track->par->codec_type == AVMEDIA_TYPE_VIDEO) {
3795             if (track->par->codec_id == AV_CODEC_ID_H264) {
3796                 uint8_t *ptr;
3797                 int size = track->par->extradata_size;
3798                 if (!ff_avc_write_annexb_extradata(track->par->extradata, &ptr,
3799                                                    &size)) {
3800                     param_write_hex(pb, "CodecPrivateData",
3801                                     ptr ? ptr : track->par->extradata,
3802                                     size);
3803                     av_free(ptr);
3804                 }
3805                 param_write_string(pb, "FourCC", "H264");
3806             } else if (track->par->codec_id == AV_CODEC_ID_VC1) {
3807                 param_write_string(pb, "FourCC", "WVC1");
3808                 param_write_hex(pb, "CodecPrivateData", track->par->extradata,
3809                                 track->par->extradata_size);
3810             }
3811             param_write_int(pb, "MaxWidth", track->par->width);
3812             param_write_int(pb, "MaxHeight", track->par->height);
3813             param_write_int(pb, "DisplayWidth", track->par->width);
3814             param_write_int(pb, "DisplayHeight", track->par->height);
3815         } else {
3816             if (track->par->codec_id == AV_CODEC_ID_AAC) {
3817                 switch (track->par->profile)
3818                 {
3819                     case FF_PROFILE_AAC_HE_V2:
3820                         param_write_string(pb, "FourCC", "AACP");
3821                         break;
3822                     case FF_PROFILE_AAC_HE:
3823                         param_write_string(pb, "FourCC", "AACH");
3824                         break;
3825                     default:
3826                         param_write_string(pb, "FourCC", "AACL");
3827                 }
3828             } else if (track->par->codec_id == AV_CODEC_ID_WMAPRO) {
3829                 param_write_string(pb, "FourCC", "WMAP");
3830             }
3831             param_write_hex(pb, "CodecPrivateData", track->par->extradata,
3832                             track->par->extradata_size);
3833             param_write_int(pb, "AudioTag", ff_codec_get_tag(ff_codec_wav_tags,
3834                                                              track->par->codec_id));
3835             param_write_int(pb, "Channels", track->par->channels);
3836             param_write_int(pb, "SamplingRate", track->par->sample_rate);
3837             param_write_int(pb, "BitsPerSample", 16);
3838             param_write_int(pb, "PacketSize", track->par->block_align ?
3839                                               track->par->block_align : 4);
3840         }
3841         avio_printf(pb, "</%s>\n", type);
3842     }
3843     avio_printf(pb, "</switch>\n");
3844     avio_printf(pb, "</body>\n");
3845     avio_printf(pb, "</smil>\n");
3846
3847     return update_size(pb, pos);
3848 }
3849
3850 static int mov_write_mfhd_tag(AVIOContext *pb, MOVMuxContext *mov)
3851 {
3852     avio_wb32(pb, 16);
3853     ffio_wfourcc(pb, "mfhd");
3854     avio_wb32(pb, 0);
3855     avio_wb32(pb, mov->fragments);
3856     return 0;
3857 }
3858
3859 static uint32_t get_sample_flags(MOVTrack *track, MOVIentry *entry)
3860 {
3861     return entry->flags & MOV_SYNC_SAMPLE ? MOV_FRAG_SAMPLE_FLAG_DEPENDS_NO :
3862            (MOV_FRAG_SAMPLE_FLAG_DEPENDS_YES | MOV_FRAG_SAMPLE_FLAG_IS_NON_SYNC);
3863 }
3864
3865 static int mov_write_tfhd_tag(AVIOContext *pb, MOVMuxContext *mov,
3866                               MOVTrack *track, int64_t moof_offset)
3867 {
3868     int64_t pos = avio_tell(pb);
3869     uint32_t flags = MOV_TFHD_DEFAULT_SIZE | MOV_TFHD_DEFAULT_DURATION |
3870                      MOV_TFHD_BASE_DATA_OFFSET;
3871     if (!track->entry) {
3872         flags |= MOV_TFHD_DURATION_IS_EMPTY;
3873     } else {
3874         flags |= MOV_TFHD_DEFAULT_FLAGS;
3875     }
3876     if (mov->flags & FF_MOV_FLAG_OMIT_TFHD_OFFSET)
3877         flags &= ~MOV_TFHD_BASE_DATA_OFFSET;
3878     if (mov->flags & FF_MOV_FLAG_DEFAULT_BASE_MOOF) {
3879         flags &= ~MOV_TFHD_BASE_DATA_OFFSET;
3880         flags |= MOV_TFHD_DEFAULT_BASE_IS_MOOF;
3881     }
3882
3883     /* Don't set a default sample size, the silverlight player refuses
3884      * to play files with that set. Don't set a default sample duration,
3885      * WMP freaks out if it is set. Don't set a base data offset, PIFF
3886      * file format says it MUST NOT be set. */
3887     if (track->mode == MODE_ISM)
3888         flags &= ~(MOV_TFHD_DEFAULT_SIZE | MOV_TFHD_DEFAULT_DURATION |
3889                    MOV_TFHD_BASE_DATA_OFFSET);
3890
3891     avio_wb32(pb, 0); /* size placeholder */
3892     ffio_wfourcc(pb, "tfhd");
3893     avio_w8(pb, 0); /* version */
3894     avio_wb24(pb, flags);
3895
3896     avio_wb32(pb, track->track_id); /* track-id */
3897     if (flags & MOV_TFHD_BASE_DATA_OFFSET)
3898         avio_wb64(pb, moof_offset);
3899     if (flags & MOV_TFHD_DEFAULT_DURATION) {
3900         track->default_duration = get_cluster_duration(track, 0);
3901         avio_wb32(pb, track->default_duration);
3902     }
3903     if (flags & MOV_TFHD_DEFAULT_SIZE) {
3904         track->default_size = track->entry ? track->cluster[0].size : 1;
3905         avio_wb32(pb, track->default_size);
3906     } else
3907         track->default_size = -1;
3908
3909     if (flags & MOV_TFHD_DEFAULT_FLAGS) {
3910         /* Set the default flags based on the second sample, if available.
3911          * If the first sample is different, that can be signaled via a separate field. */
3912         if (track->entry > 1)
3913             track->default_sample_flags = get_sample_flags(track, &track->cluster[1]);
3914         else
3915             track->default_sample_flags =
3916                 track->par->codec_type == AVMEDIA_TYPE_VIDEO ?
3917                 (MOV_FRAG_SAMPLE_FLAG_DEPENDS_YES | MOV_FRAG_SAMPLE_FLAG_IS_NON_SYNC) :
3918                 MOV_FRAG_SAMPLE_FLAG_DEPENDS_NO;
3919         avio_wb32(pb, track->default_sample_flags);
3920     }
3921
3922     return update_size(pb, pos);
3923 }
3924
3925 static int mov_write_trun_tag(AVIOContext *pb, MOVMuxContext *mov,
3926                               MOVTrack *track, int moof_size,
3927                               int first, int end)
3928 {
3929     int64_t pos = avio_tell(pb);
3930     uint32_t flags = MOV_TRUN_DATA_OFFSET;
3931     int i;
3932
3933     for (i = first; i < end; i++) {
3934         if (get_cluster_duration(track, i) != track->default_duration)
3935             flags |= MOV_TRUN_SAMPLE_DURATION;
3936         if (track->cluster[i].size != track->default_size)
3937             flags |= MOV_TRUN_SAMPLE_SIZE;
3938         if (i > first && get_sample_flags(track, &track->cluster[i]) != track->default_sample_flags)
3939             flags |= MOV_TRUN_SAMPLE_FLAGS;
3940     }
3941     if (!(flags & MOV_TRUN_SAMPLE_FLAGS) && track->entry > 0 &&
3942          get_sample_flags(track, &track->cluster[0]) != track->default_sample_flags)
3943         flags |= MOV_TRUN_FIRST_SAMPLE_FLAGS;
3944     if (track->flags & MOV_TRACK_CTTS)
3945         flags |= MOV_TRUN_SAMPLE_CTS;
3946
3947     avio_wb32(pb, 0); /* size placeholder */
3948     ffio_wfourcc(pb, "trun");
3949     avio_w8(pb, 0); /* version */
3950     avio_wb24(pb, flags);
3951
3952     avio_wb32(pb, end - first); /* sample count */
3953     if (mov->flags & FF_MOV_FLAG_OMIT_TFHD_OFFSET &&
3954         !(mov->flags & FF_MOV_FLAG_DEFAULT_BASE_MOOF) &&
3955         !mov->first_trun)
3956         avio_wb32(pb, 0); /* Later tracks follow immediately after the previous one */
3957     else
3958         avio_wb32(pb, moof_size + 8 + track->data_offset +
3959                       track->cluster[first].pos); /* data offset */
3960     if (flags & MOV_TRUN_FIRST_SAMPLE_FLAGS)
3961         avio_wb32(pb, get_sample_flags(track, &track->cluster[first]));
3962
3963     for (i = first; i < end; i++) {
3964         if (flags & MOV_TRUN_SAMPLE_DURATION)
3965             avio_wb32(pb, get_cluster_duration(track, i));
3966         if (flags & MOV_TRUN_SAMPLE_SIZE)
3967             avio_wb32(pb, track->cluster[i].size);
3968         if (flags & MOV_TRUN_SAMPLE_FLAGS)
3969             avio_wb32(pb, get_sample_flags(track, &track->cluster[i]));
3970         if (flags & MOV_TRUN_SAMPLE_CTS)
3971             avio_wb32(pb, track->cluster[i].cts);
3972     }
3973
3974     mov->first_trun = 0;
3975     return update_size(pb, pos);
3976 }
3977
3978 static int mov_write_tfxd_tag(AVIOContext *pb, MOVTrack *track)
3979 {
3980     int64_t pos = avio_tell(pb);
3981     static const uint8_t uuid[] = {
3982         0x6d, 0x1d, 0x9b, 0x05, 0x42, 0xd5, 0x44, 0xe6,
3983         0x80, 0xe2, 0x14, 0x1d, 0xaf, 0xf7, 0x57, 0xb2
3984     };
3985
3986     avio_wb32(pb, 0); /* size placeholder */
3987     ffio_wfourcc(pb, "uuid");
3988     avio_write(pb, uuid, sizeof(uuid));
3989     avio_w8(pb, 1);
3990     avio_wb24(pb, 0);
3991     avio_wb64(pb, track->start_dts + track->frag_start +
3992                   track->cluster[0].cts);
3993     avio_wb64(pb, track->end_pts -
3994                   (track->cluster[0].dts + track->cluster[0].cts));
3995
3996     return update_size(pb, pos);
3997 }
3998
3999 static int mov_write_tfrf_tag(AVIOContext *pb, MOVMuxContext *mov,
4000                               MOVTrack *track, int entry)
4001 {
4002     int n = track->nb_frag_info - 1 - entry, i;
4003     int size = 8 + 16 + 4 + 1 + 16*n;
4004     static const uint8_t uuid[] = {
4005         0xd4, 0x80, 0x7e, 0xf2, 0xca, 0x39, 0x46, 0x95,
4006         0x8e, 0x54, 0x26, 0xcb, 0x9e, 0x46, 0xa7, 0x9f
4007     };
4008
4009     if (entry < 0)
4010         return 0;
4011
4012     avio_seek(pb, track->frag_info[entry].tfrf_offset, SEEK_SET);
4013     avio_wb32(pb, size);
4014     ffio_wfourcc(pb, "uuid");
4015     avio_write(pb, uuid, sizeof(uuid));
4016     avio_w8(pb, 1);
4017     avio_wb24(pb, 0);
4018     avio_w8(pb, n);
4019     for (i = 0; i < n; i++) {
4020         int index = entry + 1 + i;
4021         avio_wb64(pb, track->frag_info[index].time);
4022         avio_wb64(pb, track->frag_info[index].duration);
4023     }
4024     if (n < mov->ism_lookahead) {
4025         int free_size = 16 * (mov->ism_lookahead - n);
4026         avio_wb32(pb, free_size);
4027         ffio_wfourcc(pb, "free");
4028         ffio_fill(pb, 0, free_size - 8);
4029     }
4030
4031     return 0;
4032 }
4033
4034 static int mov_write_tfrf_tags(AVIOContext *pb, MOVMuxContext *mov,
4035                                MOVTrack *track)
4036 {
4037     int64_t pos = avio_tell(pb);
4038     int i;
4039     for (i = 0; i < mov->ism_lookahead; i++) {
4040         /* Update the tfrf tag for the last ism_lookahead fragments,
4041          * nb_frag_info - 1 is the next fragment to be written. */
4042         mov_write_tfrf_tag(pb, mov, track, track->nb_frag_info - 2 - i);
4043     }
4044     avio_seek(pb, pos, SEEK_SET);
4045     return 0;
4046 }
4047
4048 static int mov_add_tfra_entries(AVIOContext *pb, MOVMuxContext *mov, int tracks,
4049                                 int size)
4050 {
4051     int i;
4052     for (i = 0; i < mov->nb_streams; i++) {
4053         MOVTrack *track = &mov->tracks[i];
4054         MOVFragmentInfo *info;
4055         if ((tracks >= 0 && i != tracks) || !track->entry)
4056             continue;
4057         track->nb_frag_info++;
4058         if (track->nb_frag_info >= track->frag_info_capacity) {
4059             unsigned new_capacity = track->nb_frag_info + MOV_FRAG_INFO_ALLOC_INCREMENT;
4060             if (av_reallocp_array(&track->frag_info,
4061                                   new_capacity,
4062                                   sizeof(*track->frag_info)))
4063                 return AVERROR(ENOMEM);
4064             track->frag_info_capacity = new_capacity;
4065         }
4066         info = &track->frag_info[track->nb_frag_info - 1];
4067         info->offset   = avio_tell(pb);
4068         info->size     = size;
4069         // Try to recreate the original pts for the first packet
4070         // from the fields we have stored
4071         info->time     = track->start_dts + track->frag_start +
4072                          track->cluster[0].cts;
4073         info->duration = track->end_pts -
4074                          (track->cluster[0].dts + track->cluster[0].cts);
4075         // If the pts is less than zero, we will have trimmed
4076         // away parts of the media track using an edit list,
4077         // and the corresponding start presentation time is zero.
4078         if (info->time < 0) {
4079             info->duration += info->time;
4080             info->time = 0;
4081         }
4082         info->tfrf_offset = 0;
4083         mov_write_tfrf_tags(pb, mov, track);
4084     }
4085     return 0;
4086 }
4087
4088 static void mov_prune_frag_info(MOVMuxContext *mov, int tracks, int max)
4089 {
4090     int i;
4091     for (i = 0; i < mov->nb_streams; i++) {
4092         MOVTrack *track = &mov->tracks[i];
4093         if ((tracks >= 0 && i != tracks) || !track->entry)
4094             continue;
4095         if (track->nb_frag_info > max) {
4096             memmove(track->frag_info, track->frag_info + (track->nb_frag_info - max), max * sizeof(*track->frag_info));
4097             track->nb_frag_info = max;
4098         }
4099     }
4100 }
4101
4102 static int mov_write_tfdt_tag(AVIOContext *pb, MOVTrack *track)
4103 {
4104     int64_t pos = avio_tell(pb);
4105
4106     avio_wb32(pb, 0); /* size */
4107     ffio_wfourcc(pb, "tfdt");
4108     avio_w8(pb, 1); /* version */
4109     avio_wb24(pb, 0);
4110     avio_wb64(pb, track->frag_start);
4111     return update_size(pb, pos);
4112 }
4113
4114 static int mov_write_traf_tag(AVIOContext *pb, MOVMuxContext *mov,
4115                               MOVTrack *track, int64_t moof_offset,
4116                               int moof_size)
4117 {
4118     int64_t pos = avio_tell(pb);
4119     int i, start = 0;
4120     avio_wb32(pb, 0); /* size placeholder */
4121     ffio_wfourcc(pb, "traf");
4122
4123     mov_write_tfhd_tag(pb, mov, track, moof_offset);
4124     if (mov->mode != MODE_ISM)
4125         mov_write_tfdt_tag(pb, track);
4126     for (i = 1; i < track->entry; i++) {
4127         if (track->cluster[i].pos != track->cluster[i - 1].pos + track->cluster[i - 1].size) {
4128             mov_write_trun_tag(pb, mov, track, moof_size, start, i);
4129             start = i;
4130         }
4131     }
4132     mov_write_trun_tag(pb, mov, track, moof_size, start, track->entry);
4133     if (mov->mode == MODE_ISM) {
4134         mov_write_tfxd_tag(pb, track);
4135
4136         if (mov->ism_lookahead) {
4137             int i, size = 16 + 4 + 1 + 16 * mov->ism_lookahead;
4138
4139             if (track->nb_frag_info > 0) {
4140                 MOVFragmentInfo *info = &track->frag_info[track->nb_frag_info - 1];
4141                 if (!info->tfrf_offset)
4142                     info->tfrf_offset = avio_tell(pb);
4143             }
4144             avio_wb32(pb, 8 + size);
4145             ffio_wfourcc(pb, "free");
4146             for (i = 0; i < size; i++)
4147                 avio_w8(pb, 0);
4148         }
4149     }
4150
4151     return update_size(pb, pos);
4152 }
4153
4154 static int mov_write_moof_tag_internal(AVIOContext *pb, MOVMuxContext *mov,
4155                                        int tracks, int moof_size)
4156 {
4157     int64_t pos = avio_tell(pb);
4158     int i;
4159
4160     avio_wb32(pb, 0); /* size placeholder */
4161     ffio_wfourcc(pb, "moof");
4162     mov->first_trun = 1;
4163
4164     mov_write_mfhd_tag(pb, mov);
4165     for (i = 0; i < mov->nb_streams; i++) {
4166         MOVTrack *track = &mov->tracks[i];
4167         if (tracks >= 0 && i != tracks)
4168             continue;
4169         if (!track->entry)
4170             continue;
4171         mov_write_traf_tag(pb, mov, track, pos, moof_size);
4172     }
4173
4174     return update_size(pb, pos);
4175 }
4176
4177 static int mov_write_sidx_tag(AVIOContext *pb,
4178                               MOVTrack *track, int ref_size, int total_sidx_size)
4179 {
4180     int64_t pos = avio_tell(pb), offset_pos, end_pos;
4181     int64_t presentation_time, duration, offset;
4182     int starts_with_SAP, i, entries;
4183
4184     if (track->entry) {
4185         entries = 1;
4186         presentation_time = track->start_dts + track->frag_start +
4187                             track->cluster[0].cts;
4188         duration = track->end_pts -
4189                    (track->cluster[0].dts + track->cluster[0].cts);
4190         starts_with_SAP = track->cluster[0].flags & MOV_SYNC_SAMPLE;
4191
4192         // pts<0 should be cut away using edts
4193         if (presentation_time < 0) {
4194             duration += presentation_time;
4195             presentation_time = 0;
4196         }
4197     } else {
4198         entries = track->nb_frag_info;
4199         if (entries <= 0)
4200             return 0;
4201         presentation_time = track->frag_info[0].time;
4202     }
4203
4204     avio_wb32(pb, 0); /* size */
4205     ffio_wfourcc(pb, "sidx");
4206     avio_w8(pb, 1); /* version */
4207     avio_wb24(pb, 0);
4208     avio_wb32(pb, track->track_id); /* reference_ID */
4209     avio_wb32(pb, track->timescale); /* timescale */
4210     avio_wb64(pb, presentation_time); /* earliest_presentation_time */
4211     offset_pos = avio_tell(pb);
4212     avio_wb64(pb, 0); /* first_offset (offset to referenced moof) */
4213     avio_wb16(pb, 0); /* reserved */
4214
4215     avio_wb16(pb, entries); /* reference_count */
4216     for (i = 0; i < entries; i++) {
4217         if (!track->entry) {
4218             if (i > 1 && track->frag_info[i].offset != track->frag_info[i - 1].offset + track->frag_info[i - 1].size) {
4219                av_log(NULL, AV_LOG_ERROR, "Non-consecutive fragments, writing incorrect sidx\n");
4220             }
4221             duration = track->frag_info[i].duration;
4222             ref_size = track->frag_info[i].size;
4223             starts_with_SAP = 1;
4224         }
4225         avio_wb32(pb, (0 << 31) | (ref_size & 0x7fffffff)); /* reference_type (0 = media) | referenced_size */
4226         avio_wb32(pb, duration); /* subsegment_duration */
4227         avio_wb32(pb, (starts_with_SAP << 31) | (0 << 28) | 0); /* starts_with_SAP | SAP_type | SAP_delta_time */
4228     }
4229
4230     end_pos = avio_tell(pb);
4231     offset = pos + total_sidx_size - end_pos;
4232     avio_seek(pb, offset_pos, SEEK_SET);
4233     avio_wb64(pb, offset);
4234     avio_seek(pb, end_pos, SEEK_SET);
4235     return update_size(pb, pos);
4236 }
4237
4238 static int mov_write_sidx_tags(AVIOContext *pb, MOVMuxContext *mov,
4239                                int tracks, int ref_size)
4240 {
4241     int i, round, ret;
4242     AVIOContext *avio_buf;
4243     int total_size = 0;
4244     for (round = 0; round < 2; round++) {
4245         // First run one round to calculate the total size of all
4246         // sidx atoms.
4247         // This would be much simpler if we'd only write one sidx
4248         // atom, for the first track in the moof.
4249         if (round == 0) {
4250             if ((ret = ffio_open_null_buf(&avio_buf)) < 0)
4251                 return ret;
4252         } else {
4253             avio_buf = pb;
4254         }
4255         for (i = 0; i < mov->nb_streams; i++) {
4256             MOVTrack *track = &mov->tracks[i];
4257             if (tracks >= 0 && i != tracks)
4258                 continue;
4259             // When writing a sidx for the full file, entry is 0, but
4260             // we want to include all tracks. ref_size is 0 in this case,
4261             // since we read it from frag_info instead.
4262             if (!track->entry && ref_size > 0)
4263                 continue;
4264             total_size -= mov_write_sidx_tag(avio_buf, track, ref_size,
4265                                              total_size);
4266         }
4267         if (round == 0)
4268             total_size = ffio_close_null_buf(avio_buf);
4269     }
4270     return 0;
4271 }
4272
4273 static int mov_write_moof_tag(AVIOContext *pb, MOVMuxContext *mov, int tracks,
4274                               int64_t mdat_size)
4275 {
4276     AVIOContext *avio_buf;
4277     int ret, moof_size;
4278
4279     if ((ret = ffio_open_null_buf(&avio_buf)) < 0)
4280         return ret;
4281     mov_write_moof_tag_internal(avio_buf, mov, tracks, 0);
4282     moof_size = ffio_close_null_buf(avio_buf);
4283
4284     if (mov->flags & FF_MOV_FLAG_DASH && !(mov->flags & FF_MOV_FLAG_GLOBAL_SIDX))
4285         mov_write_sidx_tags(pb, mov, tracks, moof_size + 8 + mdat_size);
4286
4287     if (mov->flags & FF_MOV_FLAG_GLOBAL_SIDX ||
4288         !(mov->flags & FF_MOV_FLAG_SKIP_TRAILER) ||
4289         mov->ism_lookahead) {
4290         if ((ret = mov_add_tfra_entries(pb, mov, tracks, moof_size + 8 + mdat_size)) < 0)
4291             return ret;
4292         if (!(mov->flags & FF_MOV_FLAG_GLOBAL_SIDX) &&
4293             mov->flags & FF_MOV_FLAG_SKIP_TRAILER) {
4294             mov_prune_frag_info(mov, tracks, mov->ism_lookahead + 1);
4295         }
4296     }
4297
4298     return mov_write_moof_tag_internal(pb, mov, tracks, moof_size);
4299 }
4300
4301 static int mov_write_tfra_tag(AVIOContext *pb, MOVTrack *track)
4302 {
4303     int64_t pos = avio_tell(pb);
4304     int i;
4305
4306     avio_wb32(pb, 0); /* size placeholder */
4307     ffio_wfourcc(pb, "tfra");
4308     avio_w8(pb, 1); /* version */
4309     avio_wb24(pb, 0);
4310
4311     avio_wb32(pb, track->track_id);
4312     avio_wb32(pb, 0); /* length of traf/trun/sample num */
4313     avio_wb32(pb, track->nb_frag_info);
4314     for (i = 0; i < track->nb_frag_info; i++) {
4315         avio_wb64(pb, track->frag_info[i].time);
4316         avio_wb64(pb, track->frag_info[i].offset + track->data_offset);
4317         avio_w8(pb, 1); /* traf number */
4318         avio_w8(pb, 1); /* trun number */
4319         avio_w8(pb, 1); /* sample number */
4320     }
4321
4322     return update_size(pb, pos);
4323 }
4324
4325 static int mov_write_mfra_tag(AVIOContext *pb, MOVMuxContext *mov)
4326 {
4327     int64_t pos = avio_tell(pb);
4328     int i;
4329
4330     avio_wb32(pb, 0); /* size placeholder */
4331     ffio_wfourcc(pb, "mfra");
4332     /* An empty mfra atom is enough to indicate to the publishing point that
4333      * the stream has ended. */
4334     if (mov->flags & FF_MOV_FLAG_ISML)
4335         return update_size(pb, pos);
4336
4337     for (i = 0; i < mov->nb_streams; i++) {
4338         MOVTrack *track = &mov->tracks[i];
4339         if (track->nb_frag_info)
4340             mov_write_tfra_tag(pb, track);
4341     }
4342
4343     avio_wb32(pb, 16);
4344     ffio_wfourcc(pb, "mfro");
4345     avio_wb32(pb, 0); /* version + flags */
4346     avio_wb32(pb, avio_tell(pb) + 4 - pos);
4347
4348     return update_size(pb, pos);
4349 }
4350
4351 static int mov_write_mdat_tag(AVIOContext *pb, MOVMuxContext *mov)
4352 {
4353     avio_wb32(pb, 8);    // placeholder for extended size field (64 bit)
4354     ffio_wfourcc(pb, mov->mode == MODE_MOV ? "wide" : "free");
4355
4356     mov->mdat_pos = avio_tell(pb);
4357     avio_wb32(pb, 0); /* size placeholder*/
4358     ffio_wfourcc(pb, "mdat");
4359     return 0;
4360 }
4361
4362 /* TODO: This needs to be more general */
4363 static int mov_write_ftyp_tag(AVIOContext *pb, AVFormatContext *s)
4364 {
4365     MOVMuxContext *mov = s->priv_data;
4366     int64_t pos = avio_tell(pb);
4367     int has_h264 = 0, has_video = 0;
4368     int minor = 0x200;
4369     int i;
4370
4371     for (i = 0; i < s->nb_streams; i++) {
4372         AVStream *st = s->streams[i];
4373         if (st->codecpar->codec_type == AVMEDIA_TYPE_VIDEO)
4374             has_video = 1;
4375         if (st->codecpar->codec_id == AV_CODEC_ID_H264)
4376             has_h264 = 1;
4377     }
4378
4379     avio_wb32(pb, 0); /* size */
4380     ffio_wfourcc(pb, "ftyp");
4381
4382     if (mov->major_brand && strlen(mov->major_brand) >= 4)
4383         ffio_wfourcc(pb, mov->major_brand);
4384     else if (mov->mode == MODE_3GP) {
4385         ffio_wfourcc(pb, has_h264 ? "3gp6"  : "3gp4");
4386         minor =     has_h264 ?   0x100 :   0x200;
4387     } else if (mov->mode & MODE_3G2) {
4388         ffio_wfourcc(pb, has_h264 ? "3g2b"  : "3g2a");
4389         minor =     has_h264 ? 0x20000 : 0x10000;
4390     } else if (mov->mode == MODE_PSP)
4391         ffio_wfourcc(pb, "MSNV");
4392     else if (mov->mode == MODE_MP4 && mov->flags & FF_MOV_FLAG_DEFAULT_BASE_MOOF)
4393         ffio_wfourcc(pb, "iso5"); // Required when using default-base-is-moof
4394     else if (mov->mode == MODE_MP4)
4395         ffio_wfourcc(pb, "isom");
4396     else if (mov->mode == MODE_IPOD)
4397         ffio_wfourcc(pb, has_video ? "M4V ":"M4A ");
4398     else if (mov->mode == MODE_ISM)
4399         ffio_wfourcc(pb, "isml");
4400     else if (mov->mode == MODE_F4V)
4401         ffio_wfourcc(pb, "f4v ");
4402     else
4403         ffio_wfourcc(pb, "qt  ");
4404
4405     avio_wb32(pb, minor);
4406
4407     if (mov->mode == MODE_MOV)
4408         ffio_wfourcc(pb, "qt  ");
4409     else if (mov->mode == MODE_ISM) {
4410         ffio_wfourcc(pb, "piff");
4411     } else if (!(mov->flags & FF_MOV_FLAG_DEFAULT_BASE_MOOF)) {
4412         ffio_wfourcc(pb, "isom");
4413         ffio_wfourcc(pb, "iso2");
4414         if (has_h264)
4415             ffio_wfourcc(pb, "avc1");
4416     }
4417
4418     // We add tfdt atoms when fragmenting, signal this with the iso6 compatible
4419     // brand. This is compatible with users that don't understand tfdt.
4420     if (mov->flags & FF_MOV_FLAG_FRAGMENT && mov->mode != MODE_ISM)
4421         ffio_wfourcc(pb, "iso6");
4422
4423     if (mov->mode == MODE_3GP)
4424         ffio_wfourcc(pb, has_h264 ? "3gp6":"3gp4");
4425     else if (mov->mode & MODE_3G2)
4426         ffio_wfourcc(pb, has_h264 ? "3g2b":"3g2a");
4427     else if (mov->mode == MODE_PSP)
4428         ffio_wfourcc(pb, "MSNV");
4429     else if (mov->mode == MODE_MP4)
4430         ffio_wfourcc(pb, "mp41");
4431
4432     if (mov->flags & FF_MOV_FLAG_DASH && mov->flags & FF_MOV_FLAG_GLOBAL_SIDX)
4433         ffio_wfourcc(pb, "dash");
4434
4435     return update_size(pb, pos);
4436 }
4437
4438 static int mov_write_uuidprof_tag(AVIOContext *pb, AVFormatContext *s)
4439 {
4440     AVStream       *video_st    = s->streams[0];
4441     AVCodecParameters *video_par = s->streams[0]->codecpar;
4442     AVCodecParameters *audio_par = s->streams[1]->codecpar;
4443     int audio_rate = audio_par->sample_rate;
4444     int64_t frame_rate = video_st->avg_frame_rate.den ?
4445                         (video_st->avg_frame_rate.num * 0x10000LL) / video_st->avg_frame_rate.den :
4446                         0;
4447     int audio_kbitrate = audio_par->bit_rate / 1000;
4448     int video_kbitrate = FFMIN(video_par->bit_rate / 1000, 800 - audio_kbitrate);
4449
4450     if (frame_rate < 0 || frame_rate > INT32_MAX) {
4451         av_log(s, AV_LOG_ERROR, "Frame rate %f outside supported range\n", frame_rate / (double)0x10000);
4452         return AVERROR(EINVAL);
4453     }
4454
4455     avio_wb32(pb, 0x94); /* size */
4456     ffio_wfourcc(pb, "uuid");
4457     ffio_wfourcc(pb, "PROF");
4458
4459     avio_wb32(pb, 0x21d24fce); /* 96 bit UUID */
4460     avio_wb32(pb, 0xbb88695c);
4461     avio_wb32(pb, 0xfac9c740);
4462
4463     avio_wb32(pb, 0x0);  /* ? */
4464     avio_wb32(pb, 0x3);  /* 3 sections ? */
4465
4466     avio_wb32(pb, 0x14); /* size */
4467     ffio_wfourcc(pb, "FPRF");
4468     avio_wb32(pb, 0x0);  /* ? */
4469     avio_wb32(pb, 0x0);  /* ? */
4470     avio_wb32(pb, 0x0);  /* ? */
4471
4472     avio_wb32(pb, 0x2c);  /* size */
4473     ffio_wfourcc(pb, "APRF"); /* audio */
4474     avio_wb32(pb, 0x0);
4475     avio_wb32(pb, 0x2);   /* TrackID */
4476     ffio_wfourcc(pb, "mp4a");
4477     avio_wb32(pb, 0x20f);
4478     avio_wb32(pb, 0x0);
4479     avio_wb32(pb, audio_kbitrate);
4480     avio_wb32(pb, audio_kbitrate);
4481     avio_wb32(pb, audio_rate);
4482     avio_wb32(pb, audio_par->channels);
4483
4484     avio_wb32(pb, 0x34);  /* size */
4485     ffio_wfourcc(pb, "VPRF");   /* video */
4486     avio_wb32(pb, 0x0);
4487     avio_wb32(pb, 0x1);    /* TrackID */
4488     if (video_par->codec_id == AV_CODEC_ID_H264) {
4489         ffio_wfourcc(pb, "avc1");
4490         avio_wb16(pb, 0x014D);
4491         avio_wb16(pb, 0x0015);
4492     } else {
4493         ffio_wfourcc(pb, "mp4v");
4494         avio_wb16(pb, 0x0000);
4495         avio_wb16(pb, 0x0103);
4496     }
4497     avio_wb32(pb, 0x0);
4498     avio_wb32(pb, video_kbitrate);
4499     avio_wb32(pb, video_kbitrate);
4500     avio_wb32(pb, frame_rate);
4501     avio_wb32(pb, frame_rate);
4502     avio_wb16(pb, video_par->width);
4503     avio_wb16(pb, video_par->height);
4504     avio_wb32(pb, 0x010001); /* ? */
4505
4506     return 0;
4507 }
4508
4509 static int mov_write_identification(AVIOContext *pb, AVFormatContext *s)
4510 {
4511     MOVMuxContext *mov = s->priv_data;
4512     int i;
4513
4514     mov_write_ftyp_tag(pb,s);
4515     if (mov->mode == MODE_PSP) {
4516         int video_streams_nb = 0, audio_streams_nb = 0, other_streams_nb = 0;
4517         for (i = 0; i < s->nb_streams; i++) {
4518             AVStream *st = s->streams[i];
4519             if (st->codecpar->codec_type == AVMEDIA_TYPE_VIDEO)
4520                 video_streams_nb++;
4521             else if (st->codecpar->codec_type == AVMEDIA_TYPE_AUDIO)
4522                 audio_streams_nb++;
4523             else
4524                 other_streams_nb++;
4525             }
4526
4527         if (video_streams_nb != 1 || audio_streams_nb != 1 || other_streams_nb) {
4528             av_log(s, AV_LOG_ERROR, "PSP mode need one video and one audio stream\n");
4529             return AVERROR(EINVAL);
4530         }
4531         return mov_write_uuidprof_tag(pb, s);
4532     }
4533     return 0;
4534 }
4535
4536 static int mov_parse_mpeg2_frame(AVPacket *pkt, uint32_t *flags)
4537 {
4538     uint32_t c = -1;
4539     int i, closed_gop = 0;
4540
4541     for (i = 0; i < pkt->size - 4; i++) {
4542         c = (c << 8) + pkt->data[i];
4543         if (c == 0x1b8) { // gop
4544             closed_gop = pkt->data[i + 4] >> 6 & 0x01;
4545         } else if (c == 0x100) { // pic
4546             int temp_ref = (pkt->data[i + 1] << 2) | (pkt->data[i + 2] >> 6);
4547             if (!temp_ref || closed_gop) // I picture is not reordered
4548                 *flags = MOV_SYNC_SAMPLE;
4549             else
4550                 *flags = MOV_PARTIAL_SYNC_SAMPLE;
4551             break;
4552         }
4553     }
4554     return 0;
4555 }
4556
4557 static void mov_parse_vc1_frame(AVPacket *pkt, MOVTrack *trk)
4558 {
4559     const uint8_t *start, *next, *end = pkt->data + pkt->size;
4560     int seq = 0, entry = 0;
4561     int key = pkt->flags & AV_PKT_FLAG_KEY;
4562     start = find_next_marker(pkt->data, end);
4563     for (next = start; next < end; start = next) {
4564         next = find_next_marker(start + 4, end);
4565         switch (AV_RB32(start)) {
4566         case VC1_CODE_SEQHDR:
4567             seq = 1;
4568             break;
4569         case VC1_CODE_ENTRYPOINT:
4570             entry = 1;
4571             break;
4572         case VC1_CODE_SLICE:
4573             trk->vc1_info.slices = 1;
4574             break;
4575         }
4576     }
4577     if (!trk->entry && trk->vc1_info.first_packet_seen)
4578         trk->vc1_info.first_frag_written = 1;
4579     if (!trk->entry && !trk->vc1_info.first_frag_written) {
4580         /* First packet in first fragment */
4581         trk->vc1_info.first_packet_seq   = seq;
4582         trk->vc1_info.first_packet_entry = entry;
4583         trk->vc1_info.first_packet_seen  = 1;
4584     } else if ((seq && !trk->vc1_info.packet_seq) ||
4585                (entry && !trk->vc1_info.packet_entry)) {
4586         int i;
4587         for (i = 0; i < trk->entry; i++)
4588             trk->cluster[i].flags &= ~MOV_SYNC_SAMPLE;
4589         trk->has_keyframes = 0;
4590         if (seq)
4591             trk->vc1_info.packet_seq = 1;
4592         if (entry)
4593             trk->vc1_info.packet_entry = 1;
4594         if (!trk->vc1_info.first_frag_written) {
4595             /* First fragment */
4596             if ((!seq   || trk->vc1_info.first_packet_seq) &&
4597                 (!entry || trk->vc1_info.first_packet_entry)) {
4598                 /* First packet had the same headers as this one, readd the
4599                  * sync sample flag. */
4600                 trk->cluster[0].flags |= MOV_SYNC_SAMPLE;
4601                 trk->has_keyframes = 1;
4602             }
4603         }
4604     }
4605     if (trk->vc1_info.packet_seq && trk->vc1_info.packet_entry)
4606         key = seq && entry;
4607     else if (trk->vc1_info.packet_seq)
4608         key = seq;
4609     else if (trk->vc1_info.packet_entry)
4610         key = entry;
4611     if (key) {
4612         trk->cluster[trk->entry].flags |= MOV_SYNC_SAMPLE;
4613         trk->has_keyframes++;
4614     }
4615 }
4616
4617 static int mov_flush_fragment_interleaving(AVFormatContext *s, MOVTrack *track)
4618 {
4619     MOVMuxContext *mov = s->priv_data;
4620     int ret, buf_size;
4621     uint8_t *buf;
4622     int i, offset;
4623
4624     if (!track->mdat_buf)
4625         return 0;
4626     if (!mov->mdat_buf) {
4627         if ((ret = avio_open_dyn_buf(&mov->mdat_buf)) < 0)
4628             return ret;
4629     }
4630     buf_size = avio_close_dyn_buf(track->mdat_buf, &buf);
4631     track->mdat_buf = NULL;
4632
4633     offset = avio_tell(mov->mdat_buf);
4634     avio_write(mov->mdat_buf, buf, buf_size);
4635     av_free(buf);
4636
4637     for (i = track->entries_flushed; i < track->entry; i++)
4638         track->cluster[i].pos += offset;
4639     track->entries_flushed = track->entry;
4640     return 0;
4641 }
4642
4643 static int mov_flush_fragment(AVFormatContext *s, int force)
4644 {
4645     MOVMuxContext *mov = s->priv_data;
4646     int i, first_track = -1;
4647     int64_t mdat_size = 0;
4648     int ret;
4649     int has_video = 0, starts_with_key = 0, first_video_track = 1;
4650
4651     if (!(mov->flags & FF_MOV_FLAG_FRAGMENT))
4652         return 0;
4653
4654     // Try to fill in the duration of the last packet in each stream
4655     // from queued packets in the interleave queues. If the flushing
4656     // of fragments was triggered automatically by an AVPacket, we
4657     // already have reliable info for the end of that track, but other
4658     // tracks may need to be filled in.
4659     for (i = 0; i < s->nb_streams; i++) {
4660         MOVTrack *track = &mov->tracks[i];
4661         if (!track->end_reliable) {
4662             AVPacket pkt;
4663             if (!ff_interleaved_peek(s, i, &pkt, 1)) {
4664                 track->track_duration = pkt.dts - track->start_dts;
4665                 if (pkt.pts != AV_NOPTS_VALUE)
4666                     track->end_pts = pkt.pts;
4667                 else
4668                     track->end_pts = pkt.dts;
4669             }
4670         }
4671     }
4672
4673     for (i = 0; i < mov->nb_streams; i++) {
4674         MOVTrack *track = &mov->tracks[i];
4675         if (track->entry <= 1)
4676             continue;
4677         // Sample durations are calculated as the diff of dts values,
4678         // but for the last sample in a fragment, we don't know the dts
4679         // of the first sample in the next fragment, so we have to rely
4680         // on what was set as duration in the AVPacket. Not all callers
4681         // set this though, so we might want to replace it with an
4682         // estimate if it currently is zero.
4683         if (get_cluster_duration(track, track->entry - 1) != 0)
4684             continue;
4685         // Use the duration (i.e. dts diff) of the second last sample for
4686         // the last one. This is a wild guess (and fatal if it turns out
4687         // to be too long), but probably the best we can do - having a zero
4688         // duration is bad as well.
4689         track->track_duration += get_cluster_duration(track, track->entry - 2);
4690         track->end_pts        += get_cluster_duration(track, track->entry - 2);
4691         if (!mov->missing_duration_warned) {
4692             av_log(s, AV_LOG_WARNING,
4693                    "Estimating the duration of the last packet in a "
4694                    "fragment, consider setting the duration field in "
4695                    "AVPacket instead.\n");
4696             mov->missing_duration_warned = 1;
4697         }
4698     }
4699
4700     if (!mov->moov_written) {
4701         int64_t pos = avio_tell(s->pb);
4702         uint8_t *buf;
4703         int buf_size, moov_size;
4704
4705         for (i = 0; i < mov->nb_streams; i++)
4706             if (!mov->tracks[i].entry)
4707                 break;
4708         /* Don't write the initial moov unless all tracks have data */
4709         if (i < mov->nb_streams && !force)
4710             return 0;
4711
4712         moov_size = get_moov_size(s);
4713         for (i = 0; i < mov->nb_streams; i++)
4714             mov->tracks[i].data_offset = pos + moov_size + 8;
4715
4716         avio_write_marker(s->pb, AV_NOPTS_VALUE, AVIO_DATA_MARKER_HEADER);
4717         if (mov->flags & FF_MOV_FLAG_DELAY_MOOV)
4718             mov_write_identification(s->pb, s);
4719         if ((ret = mov_write_moov_tag(s->pb, mov, s)) < 0)
4720             return ret;
4721
4722         if (mov->flags & FF_MOV_FLAG_DELAY_MOOV) {
4723             if (mov->flags & FF_MOV_FLAG_GLOBAL_SIDX)
4724                 mov->reserved_header_pos = avio_tell(s->pb);
4725             avio_flush(s->pb);
4726             mov->moov_written = 1;
4727             return 0;
4728         }
4729
4730         buf_size = avio_close_dyn_buf(mov->mdat_buf, &buf);
4731         mov->mdat_buf = NULL;
4732         avio_wb32(s->pb, buf_size + 8);
4733         ffio_wfourcc(s->pb, "mdat");
4734         avio_write(s->pb, buf, buf_size);
4735         av_free(buf);
4736
4737         if (mov->flags & FF_MOV_FLAG_GLOBAL_SIDX)
4738             mov->reserved_header_pos = avio_tell(s->pb);
4739
4740         mov->moov_written = 1;
4741         mov->mdat_size = 0;
4742         for (i = 0; i < mov->nb_streams; i++) {
4743             if (mov->tracks[i].entry)
4744                 mov->tracks[i].frag_start += mov->tracks[i].start_dts +
4745                                              mov->tracks[i].track_duration -
4746                                              mov->tracks[i].cluster[0].dts;
4747             mov->tracks[i].entry = 0;
4748             mov->tracks[i].end_reliable = 0;
4749         }
4750         avio_flush(s->pb);
4751         return 0;
4752     }
4753
4754     if (mov->frag_interleave) {
4755         for (i = 0; i < mov->nb_streams; i++) {
4756             MOVTrack *track = &mov->tracks[i];
4757             int ret;
4758             if ((ret = mov_flush_fragment_interleaving(s, track)) < 0)
4759                 return ret;
4760         }
4761
4762         if (!mov->mdat_buf)
4763             return 0;
4764         mdat_size = avio_tell(mov->mdat_buf);
4765     }
4766
4767     for (i = 0; i < mov->nb_streams; i++) {
4768         MOVTrack *track = &mov->tracks[i];
4769         if (mov->flags & FF_MOV_FLAG_SEPARATE_MOOF || mov->frag_interleave)
4770             track->data_offset = 0;
4771         else
4772             track->data_offset = mdat_size;
4773         if (track->par->codec_type == AVMEDIA_TYPE_VIDEO) {
4774             has_video = 1;
4775             if (first_video_track) {
4776                 if (track->entry)
4777                     starts_with_key = track->cluster[0].flags & MOV_SYNC_SAMPLE;
4778                 first_video_track = 0;
4779             }
4780         }
4781         if (!track->entry)
4782             continue;
4783         if (track->mdat_buf)
4784             mdat_size += avio_tell(track->mdat_buf);
4785         if (first_track < 0)
4786             first_track = i;
4787     }
4788
4789     if (!mdat_size)
4790         return 0;
4791
4792     avio_write_marker(s->pb,
4793                       av_rescale(mov->tracks[first_track].cluster[0].dts, AV_TIME_BASE, mov->tracks[first_track].timescale),
4794                       (has_video ? starts_with_key : mov->tracks[first_track].cluster[0].flags & MOV_SYNC_SAMPLE) ? AVIO_DATA_MARKER_SYNC_POINT : AVIO_DATA_MARKER_BOUNDARY_POINT);
4795
4796     for (i = 0; i < mov->nb_streams; i++) {
4797         MOVTrack *track = &mov->tracks[i];
4798         int buf_size, write_moof = 1, moof_tracks = -1;
4799         uint8_t *buf;
4800         int64_t duration = 0;
4801
4802         if (track->entry)
4803             duration = track->start_dts + track->track_duration -
4804                        track->cluster[0].dts;
4805         if (mov->flags & FF_MOV_FLAG_SEPARATE_MOOF) {
4806             if (!track->mdat_buf)
4807                 continue;
4808             mdat_size = avio_tell(track->mdat_buf);
4809             moof_tracks = i;
4810         } else {
4811             write_moof = i == first_track;
4812         }
4813
4814         if (write_moof) {
4815             avio_flush(s->pb);
4816
4817             mov_write_moof_tag(s->pb, mov, moof_tracks, mdat_size);
4818             mov->fragments++;
4819
4820             avio_wb32(s->pb, mdat_size + 8);
4821             ffio_wfourcc(s->pb, "mdat");
4822         }
4823
4824         if (track->entry)
4825             track->frag_start += duration;
4826         track->entry = 0;
4827         track->entries_flushed = 0;
4828         track->end_reliable = 0;
4829         if (!mov->frag_interleave) {
4830             if (!track->mdat_buf)
4831                 continue;
4832             buf_size = avio_close_dyn_buf(track->mdat_buf, &buf);
4833             track->mdat_buf = NULL;
4834         } else {
4835             if (!mov->mdat_buf)
4836                 continue;
4837             buf_size = avio_close_dyn_buf(mov->mdat_buf, &buf);
4838             mov->mdat_buf = NULL;
4839         }
4840
4841         avio_write(s->pb, buf, buf_size);
4842         av_free(buf);
4843     }
4844
4845     mov->mdat_size = 0;
4846
4847     avio_flush(s->pb);
4848     return 0;
4849 }
4850
4851 static int mov_auto_flush_fragment(AVFormatContext *s, int force)
4852 {
4853     MOVMuxContext *mov = s->priv_data;
4854     int had_moov = mov->moov_written;
4855     int ret = mov_flush_fragment(s, force);
4856     if (ret < 0)
4857         return ret;
4858     // If using delay_moov, the first flush only wrote the moov,
4859     // not the actual moof+mdat pair, thus flush once again.
4860     if (!had_moov && mov->flags & FF_MOV_FLAG_DELAY_MOOV)
4861         ret = mov_flush_fragment(s, force);
4862     return ret;
4863 }
4864
4865 static int check_pkt(AVFormatContext *s, AVPacket *pkt)
4866 {
4867     MOVMuxContext *mov = s->priv_data;
4868     MOVTrack *trk = &mov->tracks[pkt->stream_index];
4869     int64_t ref;
4870     uint64_t duration;
4871
4872     if (trk->entry) {
4873         ref = trk->cluster[trk->entry - 1].dts;
4874     } else if (   trk->start_dts != AV_NOPTS_VALUE
4875                && !trk->frag_discont) {
4876         ref = trk->start_dts + trk->track_duration;
4877     } else
4878         ref = pkt->dts; // Skip tests for the first packet
4879
4880     duration = pkt->dts - ref;
4881     if (pkt->dts < ref || duration >= INT_MAX) {
4882         av_log(s, AV_LOG_ERROR, "Application provided duration: %"PRId64" / timestamp: %"PRId64" is out of range for mov/mp4 format\n",
4883             duration, pkt->dts
4884         );
4885
4886         pkt->dts = ref + 1;
4887         pkt->pts = AV_NOPTS_VALUE;
4888     }
4889
4890     if (pkt->duration < 0 || pkt->duration > INT_MAX) {
4891         av_log(s, AV_LOG_ERROR, "Application provided duration: %"PRId64" is invalid\n", pkt->duration);
4892         return AVERROR(EINVAL);
4893     }
4894     return 0;
4895 }
4896
4897 int ff_mov_write_packet(AVFormatContext *s, AVPacket *pkt)
4898 {
4899     MOVMuxContext *mov = s->priv_data;
4900     AVIOContext *pb = s->pb;
4901     MOVTrack *trk = &mov->tracks[pkt->stream_index];
4902     AVCodecParameters *par = trk->par;
4903     unsigned int samples_in_chunk = 0;
4904     int size = pkt->size, ret = 0;
4905     uint8_t *reformatted_data = NULL;
4906
4907     ret = check_pkt(s, pkt);
4908     if (ret < 0)
4909         return ret;
4910
4911     if (mov->flags & FF_MOV_FLAG_FRAGMENT) {
4912         int ret;
4913         if (mov->moov_written || mov->flags & FF_MOV_FLAG_EMPTY_MOOV) {
4914             if (mov->frag_interleave && mov->fragments > 0) {
4915                 if (trk->entry - trk->entries_flushed >= mov->frag_interleave) {
4916                     if ((ret = mov_flush_fragment_interleaving(s, trk)) < 0)
4917                         return ret;
4918                 }
4919             }
4920
4921             if (!trk->mdat_buf) {
4922                 if ((ret = avio_open_dyn_buf(&trk->mdat_buf)) < 0)
4923                     return ret;
4924             }
4925             pb = trk->mdat_buf;
4926         } else {
4927             if (!mov->mdat_buf) {
4928                 if ((ret = avio_open_dyn_buf(&mov->mdat_buf)) < 0)
4929                     return ret;
4930             }
4931             pb = mov->mdat_buf;
4932         }
4933     }
4934
4935     if (par->codec_id == AV_CODEC_ID_AMR_NB) {
4936         /* We must find out how many AMR blocks there are in one packet */
4937         static const uint16_t packed_size[16] =
4938             {13, 14, 16, 18, 20, 21, 27, 32, 6, 0, 0, 0, 0, 0, 0, 1};
4939         int len = 0;
4940
4941         while (len < size && samples_in_chunk < 100) {
4942             len += packed_size[(pkt->data[len] >> 3) & 0x0F];
4943             samples_in_chunk++;
4944         }
4945         if (samples_in_chunk > 1) {
4946             av_log(s, AV_LOG_ERROR, "fatal error, input is not a single packet, implement a AVParser for it\n");
4947             return -1;
4948         }
4949     } else if (par->codec_id == AV_CODEC_ID_ADPCM_MS ||
4950                par->codec_id == AV_CODEC_ID_ADPCM_IMA_WAV) {
4951         samples_in_chunk = trk->par->frame_size;
4952     } else if (trk->sample_size)
4953         samples_in_chunk = size / trk->sample_size;
4954     else
4955         samples_in_chunk = 1;
4956
4957     /* copy extradata if it exists */
4958     if (trk->vos_len == 0 && par->extradata_size > 0 &&
4959         !TAG_IS_AVCI(trk->tag) &&
4960         (par->codec_id != AV_CODEC_ID_DNXHD)) {
4961         trk->vos_len  = par->extradata_size;
4962         trk->vos_data = av_malloc(trk->vos_len);
4963         if (!trk->vos_data) {
4964             ret = AVERROR(ENOMEM);
4965             goto err;
4966         }
4967         memcpy(trk->vos_data, par->extradata, trk->vos_len);
4968     }
4969
4970     if (par->codec_id == AV_CODEC_ID_AAC && pkt->size > 2 &&
4971         (AV_RB16(pkt->data) & 0xfff0) == 0xfff0) {
4972         if (!s->streams[pkt->stream_index]->nb_frames) {
4973             av_log(s, AV_LOG_ERROR, "Malformed AAC bitstream detected: "
4974                    "use the audio bitstream filter 'aac_adtstoasc' to fix it "
4975                    "('-bsf:a aac_adtstoasc' option with ffmpeg)\n");
4976             return -1;
4977         }
4978         av_log(s, AV_LOG_WARNING, "aac bitstream error\n");
4979     }
4980     if (par->codec_id == AV_CODEC_ID_H264 && trk->vos_len > 0 && *(uint8_t *)trk->vos_data != 1 && !TAG_IS_AVCI(trk->tag)) {
4981         /* from x264 or from bytestream H.264 */
4982         /* NAL reformatting needed */
4983         if (trk->hint_track >= 0 && trk->hint_track < mov->nb_streams) {
4984             ff_avc_parse_nal_units_buf(pkt->data, &reformatted_data,
4985                                        &size);
4986             avio_write(pb, reformatted_data, size);
4987         } else {
4988             if (mov->encryption_scheme == MOV_ENC_CENC_AES_CTR) {
4989                 size = ff_mov_cenc_avc_parse_nal_units(&trk->cenc, pb, pkt->data, size);
4990                 if (size < 0) {
4991                     ret = size;
4992                     goto err;
4993                 }
4994             } else {
4995                 size = ff_avc_parse_nal_units(pb, pkt->data, pkt->size);
4996             }
4997         }
4998     } else if (par->codec_id == AV_CODEC_ID_HEVC && trk->vos_len > 6 &&
4999                (AV_RB24(trk->vos_data) == 1 || AV_RB32(trk->vos_data) == 1)) {
5000         /* extradata is Annex B, assume the bitstream is too and convert it */
5001         if (trk->hint_track >= 0 && trk->hint_track < mov->nb_streams) {
5002             ff_hevc_annexb2mp4_buf(pkt->data, &reformatted_data, &size, 0, NULL);
5003             avio_write(pb, reformatted_data, size);
5004         } else {
5005             size = ff_hevc_annexb2mp4(pb, pkt->data, pkt->size, 0, NULL);
5006         }
5007 #if CONFIG_AC3_PARSER
5008     } else if (par->codec_id == AV_CODEC_ID_EAC3) {
5009         size = handle_eac3(mov, pkt, trk);
5010         if (size < 0)
5011             return size;
5012         else if (!size)
5013             goto end;
5014         avio_write(pb, pkt->data, size);
5015 #endif
5016     } else {
5017         if (mov->encryption_scheme == MOV_ENC_CENC_AES_CTR) {
5018             if (par->codec_id == AV_CODEC_ID_H264 && par->extradata_size > 4) {
5019                 int nal_size_length = (par->extradata[4] & 0x3) + 1;
5020                 ret = ff_mov_cenc_avc_write_nal_units(s, &trk->cenc, nal_size_length, pb, pkt->data, size);
5021             } else {
5022                 ret = ff_mov_cenc_write_packet(&trk->cenc, pb, pkt->data, size);
5023             }
5024
5025             if (ret) {
5026                 goto err;
5027             }
5028         } else {
5029             avio_write(pb, pkt->data, size);
5030         }
5031     }
5032
5033     if ((par->codec_id == AV_CODEC_ID_DNXHD ||
5034          par->codec_id == AV_CODEC_ID_AC3) && !trk->vos_len) {
5035         /* copy frame to create needed atoms */
5036         trk->vos_len  = size;
5037         trk->vos_data = av_malloc(size);
5038         if (!trk->vos_data) {
5039             ret = AVERROR(ENOMEM);
5040             goto err;
5041         }
5042         memcpy(trk->vos_data, pkt->data, size);
5043     }
5044
5045     if (trk->entry >= trk->cluster_capacity) {
5046         unsigned new_capacity = 2 * (trk->entry + MOV_INDEX_CLUSTER_SIZE);
5047         if (av_reallocp_array(&trk->cluster, new_capacity,
5048                               sizeof(*trk->cluster))) {
5049             ret = AVERROR(ENOMEM);
5050             goto err;
5051         }
5052         trk->cluster_capacity = new_capacity;
5053     }
5054
5055     trk->cluster[trk->entry].pos              = avio_tell(pb) - size;
5056     trk->cluster[trk->entry].samples_in_chunk = samples_in_chunk;
5057     trk->cluster[trk->entry].chunkNum         = 0;
5058     trk->cluster[trk->entry].size             = size;
5059     trk->cluster[trk->entry].entries          = samples_in_chunk;
5060     trk->cluster[trk->entry].dts              = pkt->dts;
5061     if (!trk->entry && trk->start_dts != AV_NOPTS_VALUE) {
5062         if (!trk->frag_discont) {
5063             /* First packet of a new fragment. We already wrote the duration
5064              * of the last packet of the previous fragment based on track_duration,
5065              * which might not exactly match our dts. Therefore adjust the dts
5066              * of this packet to be what the previous packets duration implies. */
5067             trk->cluster[trk->entry].dts = trk->start_dts + trk->track_duration;
5068             /* We also may have written the pts and the corresponding duration
5069              * in sidx/tfrf/tfxd tags; make sure the sidx pts and duration match up with
5070              * the next fragment. This means the cts of the first sample must
5071              * be the same in all fragments, unless end_pts was updated by
5072              * the packet causing the fragment to be written. */
5073             if ((mov->flags & FF_MOV_FLAG_DASH && !(mov->flags & FF_MOV_FLAG_GLOBAL_SIDX)) ||
5074                 mov->mode == MODE_ISM)
5075                 pkt->pts = pkt->dts + trk->end_pts - trk->cluster[trk->entry].dts;
5076         } else {
5077             /* New fragment, but discontinuous from previous fragments.
5078              * Pretend the duration sum of the earlier fragments is
5079              * pkt->dts - trk->start_dts. */
5080             trk->frag_start = pkt->dts - trk->start_dts;
5081             trk->end_pts = AV_NOPTS_VALUE;
5082             trk->frag_discont = 0;
5083         }
5084     }
5085
5086     if (!trk->entry && trk->start_dts == AV_NOPTS_VALUE && !mov->use_editlist &&
5087         s->avoid_negative_ts == AVFMT_AVOID_NEG_TS_MAKE_ZERO) {
5088         /* Not using edit lists and shifting the first track to start from zero.
5089          * If the other streams start from a later timestamp, we won't be able
5090          * to signal the difference in starting time without an edit list.
5091          * Thus move the timestamp for this first sample to 0, increasing
5092          * its duration instead. */
5093         trk->cluster[trk->entry].dts = trk->start_dts = 0;
5094     }
5095     if (trk->start_dts == AV_NOPTS_VALUE) {
5096         trk->start_dts = pkt->dts;
5097         if (trk->frag_discont) {
5098             if (mov->use_editlist) {
5099                 /* Pretend the whole stream started at pts=0, with earlier fragments
5100                  * already written. If the stream started at pts=0, the duration sum
5101                  * of earlier fragments would have been pkt->pts. */
5102                 trk->frag_start = pkt->pts;
5103                 trk->start_dts  = pkt->dts - pkt->pts;
5104             } else {
5105                 /* Pretend the whole stream started at dts=0, with earlier fragments
5106                  * already written, with a duration summing up to pkt->dts. */
5107                 trk->frag_start = pkt->dts;
5108                 trk->start_dts  = 0;
5109             }
5110             trk->frag_discont = 0;
5111         } else if (pkt->dts && mov->moov_written)
5112             av_log(s, AV_LOG_WARNING,
5113                    "Track %d starts with a nonzero dts %"PRId64", while the moov "
5114                    "already has been written. Set the delay_moov flag to handle "
5115                    "this case.\n",
5116                    pkt->stream_index, pkt->dts);
5117     }
5118     trk->track_duration = pkt->dts - trk->start_dts + pkt->duration;
5119     trk->last_sample_is_subtitle_end = 0;
5120
5121     if (pkt->pts == AV_NOPTS_VALUE) {
5122         av_log(s, AV_LOG_WARNING, "pts has no value\n");
5123         pkt->pts = pkt->dts;
5124     }
5125     if (pkt->dts != pkt->pts)
5126         trk->flags |= MOV_TRACK_CTTS;
5127     trk->cluster[trk->entry].cts   = pkt->pts - pkt->dts;
5128     trk->cluster[trk->entry].flags = 0;
5129     if (trk->start_cts == AV_NOPTS_VALUE)
5130         trk->start_cts = pkt->pts - pkt->dts;
5131     if (trk->end_pts == AV_NOPTS_VALUE)
5132         trk->end_pts = trk->cluster[trk->entry].dts +
5133                        trk->cluster[trk->entry].cts + pkt->duration;
5134     else
5135         trk->end_pts = FFMAX(trk->end_pts, trk->cluster[trk->entry].dts +
5136                                            trk->cluster[trk->entry].cts +
5137                                            pkt->duration);
5138
5139     if (par->codec_id == AV_CODEC_ID_VC1) {
5140         mov_parse_vc1_frame(pkt, trk);
5141     } else if (pkt->flags & AV_PKT_FLAG_KEY) {
5142         if (mov->mode == MODE_MOV && par->codec_id == AV_CODEC_ID_MPEG2VIDEO &&
5143             trk->entry > 0) { // force sync sample for the first key frame
5144             mov_parse_mpeg2_frame(pkt, &trk->cluster[trk->entry].flags);
5145             if (trk->cluster[trk->entry].flags & MOV_PARTIAL_SYNC_SAMPLE)
5146                 trk->flags |= MOV_TRACK_STPS;
5147         } else {
5148             trk->cluster[trk->entry].flags = MOV_SYNC_SAMPLE;
5149         }
5150         if (trk->cluster[trk->entry].flags & MOV_SYNC_SAMPLE)
5151             trk->has_keyframes++;
5152     }
5153     trk->entry++;
5154     trk->sample_count += samples_in_chunk;
5155     mov->mdat_size    += size;
5156
5157     if (trk->hint_track >= 0 && trk->hint_track < mov->nb_streams)
5158         ff_mov_add_hinted_packet(s, pkt, trk->hint_track, trk->entry,
5159                                  reformatted_data, size);
5160
5161 end:
5162 err:
5163
5164     av_free(reformatted_data);
5165     return ret;
5166 }
5167
5168 static int mov_write_single_packet(AVFormatContext *s, AVPacket *pkt)
5169 {
5170         MOVMuxContext *mov = s->priv_data;
5171         MOVTrack *trk = &mov->tracks[pkt->stream_index];
5172         AVCodecParameters *par = trk->par;
5173         int64_t frag_duration = 0;
5174         int size = pkt->size;
5175
5176         int ret = check_pkt(s, pkt);
5177         if (ret < 0)
5178             return ret;
5179
5180         if (mov->flags & FF_MOV_FLAG_FRAG_DISCONT) {
5181             int i;
5182             for (i = 0; i < s->nb_streams; i++)
5183                 mov->tracks[i].frag_discont = 1;
5184             mov->flags &= ~FF_MOV_FLAG_FRAG_DISCONT;
5185         }
5186
5187         if (!pkt->size) {
5188             if (trk->start_dts == AV_NOPTS_VALUE && trk->frag_discont) {
5189                 trk->start_dts = pkt->dts;
5190                 if (pkt->pts != AV_NOPTS_VALUE)
5191                     trk->start_cts = pkt->pts - pkt->dts;
5192                 else
5193                     trk->start_cts = 0;
5194             }
5195
5196             if (trk->par->codec_id == AV_CODEC_ID_MP4ALS ||
5197                 trk->par->codec_id == AV_CODEC_ID_FLAC) {
5198                 int side_size = 0;
5199                 uint8_t *side = av_packet_get_side_data(pkt, AV_PKT_DATA_NEW_EXTRADATA, &side_size);
5200                 if (side && side_size > 0 && (side_size != par->extradata_size || memcmp(side, par->extradata, side_size))) {
5201                     void *newextra = av_mallocz(side_size + AV_INPUT_BUFFER_PADDING_SIZE);
5202                     if (!newextra)
5203                         return AVERROR(ENOMEM);
5204                     av_free(par->extradata);
5205                     par->extradata = newextra;
5206                     memcpy(par->extradata, side, side_size);
5207                     par->extradata_size = side_size;
5208                     mov->need_rewrite_extradata = 1;
5209                 }
5210             }
5211
5212             return 0;             /* Discard 0 sized packets */
5213         }
5214
5215         if (trk->entry && pkt->stream_index < s->nb_streams)
5216             frag_duration = av_rescale_q(pkt->dts - trk->cluster[0].dts,
5217                                          s->streams[pkt->stream_index]->time_base,
5218                                          AV_TIME_BASE_Q);
5219         if ((mov->max_fragment_duration &&
5220              frag_duration >= mov->max_fragment_duration) ||
5221              (mov->max_fragment_size && mov->mdat_size + size >= mov->max_fragment_size) ||
5222              (mov->flags & FF_MOV_FLAG_FRAG_KEYFRAME &&
5223               par->codec_type == AVMEDIA_TYPE_VIDEO &&
5224               trk->entry && pkt->flags & AV_PKT_FLAG_KEY)) {
5225             if (frag_duration >= mov->min_fragment_duration) {
5226                 // Set the duration of this track to line up with the next
5227                 // sample in this track. This avoids relying on AVPacket
5228                 // duration, but only helps for this particular track, not
5229                 // for the other ones that are flushed at the same time.
5230                 trk->track_duration = pkt->dts - trk->start_dts;
5231                 if (pkt->pts != AV_NOPTS_VALUE)
5232                     trk->end_pts = pkt->pts;
5233                 else
5234                     trk->end_pts = pkt->dts;
5235                 trk->end_reliable = 1;
5236                 mov_auto_flush_fragment(s, 0);
5237             }
5238         }
5239
5240         return ff_mov_write_packet(s, pkt);
5241 }
5242
5243 static int mov_write_subtitle_end_packet(AVFormatContext *s,
5244                                          int stream_index,
5245                                          int64_t dts) {
5246     AVPacket end;
5247     uint8_t data[2] = {0};
5248     int ret;
5249
5250     av_init_packet(&end);
5251     end.size = sizeof(data);
5252     end.data = data;
5253     end.pts = dts;
5254     end.dts = dts;
5255     end.duration = 0;
5256     end.stream_index = stream_index;
5257
5258     ret = mov_write_single_packet(s, &end);
5259     av_packet_unref(&end);
5260
5261     return ret;
5262 }
5263
5264 static int mov_write_packet(AVFormatContext *s, AVPacket *pkt)
5265 {
5266     if (!pkt) {
5267         mov_flush_fragment(s, 1);
5268         return 1;
5269     } else {
5270         int i;
5271         MOVMuxContext *mov = s->priv_data;
5272         MOVTrack *trk = &mov->tracks[pkt->stream_index];
5273
5274         if (!pkt->size)
5275             return mov_write_single_packet(s, pkt); /* Passthrough. */
5276
5277         /*
5278          * Subtitles require special handling.
5279          *
5280          * 1) For full complaince, every track must have a sample at
5281          * dts == 0, which is rarely true for subtitles. So, as soon
5282          * as we see any packet with dts > 0, write an empty subtitle
5283          * at dts == 0 for any subtitle track with no samples in it.
5284          *
5285          * 2) For each subtitle track, check if the current packet's
5286          * dts is past the duration of the last subtitle sample. If
5287          * so, we now need to write an end sample for that subtitle.
5288          *
5289          * This must be done conditionally to allow for subtitles that
5290          * immediately replace each other, in which case an end sample
5291          * is not needed, and is, in fact, actively harmful.
5292          *
5293          * 3) See mov_write_trailer for how the final end sample is
5294          * handled.
5295          */
5296         for (i = 0; i < mov->nb_streams; i++) {
5297             MOVTrack *trk = &mov->tracks[i];
5298             int ret;
5299
5300             if (trk->par->codec_id == AV_CODEC_ID_MOV_TEXT &&
5301                 trk->track_duration < pkt->dts &&
5302                 (trk->entry == 0 || !trk->last_sample_is_subtitle_end)) {
5303                 ret = mov_write_subtitle_end_packet(s, i, trk->track_duration);
5304                 if (ret < 0) return ret;
5305                 trk->last_sample_is_subtitle_end = 1;
5306             }
5307         }
5308
5309         if (trk->mode == MODE_MOV && trk->par->codec_type == AVMEDIA_TYPE_VIDEO) {
5310             AVPacket *opkt = pkt;
5311             int reshuffle_ret, ret;
5312             if (trk->is_unaligned_qt_rgb) {
5313                 int64_t bpc = trk->par->bits_per_coded_sample != 15 ? trk->par->bits_per_coded_sample : 16;
5314                 int expected_stride = ((trk->par->width * bpc + 15) >> 4)*2;
5315                 reshuffle_ret = ff_reshuffle_raw_rgb(s, &pkt, trk->par, expected_stride);
5316                 if (reshuffle_ret < 0)
5317                     return reshuffle_ret;
5318             } else
5319                 reshuffle_ret = 0;
5320             if (trk->par->format == AV_PIX_FMT_PAL8 && !trk->pal_done) {
5321                 ret = ff_get_packet_palette(s, opkt, reshuffle_ret, trk->palette);
5322                 if (ret < 0)
5323                     goto fail;
5324                 if (ret)
5325                     trk->pal_done++;
5326             } else if (trk->par->codec_id == AV_CODEC_ID_RAWVIDEO &&
5327                        (trk->par->format == AV_PIX_FMT_GRAY8 ||
5328                        trk->par->format == AV_PIX_FMT_MONOBLACK)) {
5329                 for (i = 0; i < pkt->size; i++)
5330                     pkt->data[i] = ~pkt->data[i];
5331             }
5332             if (reshuffle_ret) {
5333                 ret = mov_write_single_packet(s, pkt);
5334 fail:
5335                 if (reshuffle_ret)
5336                     av_packet_free(&pkt);
5337                 return ret;
5338             }
5339         }
5340
5341         return mov_write_single_packet(s, pkt);
5342     }
5343 }
5344
5345 // QuickTime chapters involve an additional text track with the chapter names
5346 // as samples, and a tref pointing from the other tracks to the chapter one.
5347 static int mov_create_chapter_track(AVFormatContext *s, int tracknum)
5348 {
5349     AVIOContext *pb;
5350
5351     MOVMuxContext *mov = s->priv_data;
5352     MOVTrack *track = &mov->tracks[tracknum];
5353     AVPacket pkt = { .stream_index = tracknum, .flags = AV_PKT_FLAG_KEY };
5354     int i, len;
5355
5356     track->mode = mov->mode;
5357     track->tag = MKTAG('t','e','x','t');
5358     track->timescale = MOV_TIMESCALE;
5359     track->par = avcodec_parameters_alloc();
5360     if (!track->par)
5361         return AVERROR(ENOMEM);
5362     track->par->codec_type = AVMEDIA_TYPE_SUBTITLE;
5363 #if 0
5364     // These properties are required to make QT recognize the chapter track
5365     uint8_t chapter_properties[43] = { 0, 0, 0, 0, 0, 0, 0, 1, };
5366     if (ff_alloc_extradata(track->par, sizeof(chapter_properties)))
5367         return AVERROR(ENOMEM);
5368     memcpy(track->par->extradata, chapter_properties, sizeof(chapter_properties));
5369 #else
5370     if (avio_open_dyn_buf(&pb) >= 0) {
5371         int size;
5372         uint8_t *buf;
5373
5374         /* Stub header (usually for Quicktime chapter track) */
5375         // TextSampleEntry
5376         avio_wb32(pb, 0x01); // displayFlags
5377         avio_w8(pb, 0x00);   // horizontal justification
5378         avio_w8(pb, 0x00);   // vertical justification
5379         avio_w8(pb, 0x00);   // bgColourRed
5380         avio_w8(pb, 0x00);   // bgColourGreen
5381         avio_w8(pb, 0x00);   // bgColourBlue
5382         avio_w8(pb, 0x00);   // bgColourAlpha
5383         // BoxRecord
5384         avio_wb16(pb, 0x00); // defTextBoxTop
5385         avio_wb16(pb, 0x00); // defTextBoxLeft
5386         avio_wb16(pb, 0x00); // defTextBoxBottom
5387         avio_wb16(pb, 0x00); // defTextBoxRight
5388         // StyleRecord
5389         avio_wb16(pb, 0x00); // startChar
5390         avio_wb16(pb, 0x00); // endChar
5391         avio_wb16(pb, 0x01); // fontID
5392         avio_w8(pb, 0x00);   // fontStyleFlags
5393         avio_w8(pb, 0x00);   // fontSize
5394         avio_w8(pb, 0x00);   // fgColourRed
5395         avio_w8(pb, 0x00);   // fgColourGreen
5396         avio_w8(pb, 0x00);   // fgColourBlue
5397         avio_w8(pb, 0x00);   // fgColourAlpha
5398         // FontTableBox
5399         avio_wb32(pb, 0x0D); // box size
5400         ffio_wfourcc(pb, "ftab"); // box atom name
5401         avio_wb16(pb, 0x01); // entry count
5402         // FontRecord
5403         avio_wb16(pb, 0x01); // font ID
5404         avio_w8(pb, 0x00);   // font name length
5405
5406         if ((size = avio_close_dyn_buf(pb, &buf)) > 0) {
5407             track->par->extradata = buf;
5408             track->par->extradata_size = size;
5409         } else {
5410             av_freep(&buf);
5411         }
5412     }
5413 #endif
5414
5415     for (i = 0; i < s->nb_chapters; i++) {
5416         AVChapter *c = s->chapters[i];
5417         AVDictionaryEntry *t;
5418
5419         int64_t end = av_rescale_q(c->end, c->time_base, (AVRational){1,MOV_TIMESCALE});
5420         pkt.pts = pkt.dts = av_rescale_q(c->start, c->time_base, (AVRational){1,MOV_TIMESCALE});
5421         pkt.duration = end - pkt.dts;
5422
5423         if ((t = av_dict_get(c->metadata, "title", NULL, 0))) {
5424             static const char encd[12] = {
5425                 0x00, 0x00, 0x00, 0x0C,
5426                 'e',  'n',  'c',  'd',
5427                 0x00, 0x00, 0x01, 0x00 };
5428             len      = strlen(t->value);
5429             pkt.size = len + 2 + 12;
5430             pkt.data = av_malloc(pkt.size);
5431             if (!pkt.data)
5432                 return AVERROR(ENOMEM);
5433             AV_WB16(pkt.data, len);
5434             memcpy(pkt.data + 2, t->value, len);
5435             memcpy(pkt.data + len + 2, encd, sizeof(encd));
5436             ff_mov_write_packet(s, &pkt);
5437             av_freep(&pkt.data);
5438         }
5439     }
5440
5441     return 0;
5442 }
5443
5444
5445 static int mov_check_timecode_track(AVFormatContext *s, AVTimecode *tc, int src_index, const char *tcstr)
5446 {
5447     int ret;
5448
5449     /* compute the frame number */
5450     ret = av_timecode_init_from_string(tc, find_fps(s,  s->streams[src_index]), tcstr, s);
5451     return ret;
5452 }
5453
5454 static int mov_create_timecode_track(AVFormatContext *s, int index, int src_index, AVTimecode tc)
5455 {
5456     int ret;
5457     MOVMuxContext *mov  = s->priv_data;
5458     MOVTrack *track     = &mov->tracks[index];
5459     AVStream *src_st    = s->streams[src_index];
5460     AVPacket pkt    = {.stream_index = index, .flags = AV_PKT_FLAG_KEY, .size = 4};
5461     AVRational rate = find_fps(s, src_st);
5462
5463     /* tmcd track based on video stream */
5464     track->mode      = mov->mode;
5465     track->tag       = MKTAG('t','m','c','d');
5466     track->src_track = src_index;
5467     track->timescale = mov->tracks[src_index].timescale;
5468     if (tc.flags & AV_TIMECODE_FLAG_DROPFRAME)
5469         track->timecode_flags |= MOV_TIMECODE_FLAG_DROPFRAME;
5470
5471     /* set st to src_st for metadata access*/
5472     track->st = src_st;
5473
5474     /* encode context: tmcd data stream */
5475     track->par = avcodec_parameters_alloc();
5476     if (!track->par)
5477         return AVERROR(ENOMEM);
5478     track->par->codec_type = AVMEDIA_TYPE_DATA;
5479     track->par->codec_tag  = track->tag;
5480     track->st->avg_frame_rate = av_inv_q(rate);
5481
5482     /* the tmcd track just contains one packet with the frame number */
5483     pkt.data = av_malloc(pkt.size);
5484     if (!pkt.data)
5485         return AVERROR(ENOMEM);
5486     AV_WB32(pkt.data, tc.start);
5487     ret = ff_mov_write_packet(s, &pkt);
5488     av_free(pkt.data);
5489     return ret;
5490 }
5491
5492 /*
5493  * st->disposition controls the "enabled" flag in the tkhd tag.
5494  * QuickTime will not play a track if it is not enabled.  So make sure
5495  * that one track of each type (audio, video, subtitle) is enabled.
5496  *
5497  * Subtitles are special.  For audio and video, setting "enabled" also
5498  * makes the track "default" (i.e. it is rendered when played). For
5499  * subtitles, an "enabled" subtitle is not rendered by default, but
5500  * if no subtitle is enabled, the subtitle menu in QuickTime will be
5501  * empty!
5502  */
5503 static void enable_tracks(AVFormatContext *s)
5504 {
5505     MOVMuxContext *mov = s->priv_data;
5506     int i;
5507     int enabled[AVMEDIA_TYPE_NB];
5508     int first[AVMEDIA_TYPE_NB];
5509
5510     for (i = 0; i < AVMEDIA_TYPE_NB; i++) {
5511         enabled[i] = 0;
5512         first[i] = -1;
5513     }
5514
5515     for (i = 0; i < s->nb_streams; i++) {
5516         AVStream *st = s->streams[i];
5517
5518         if (st->codecpar->codec_type <= AVMEDIA_TYPE_UNKNOWN ||
5519             st->codecpar->codec_type >= AVMEDIA_TYPE_NB)
5520             continue;
5521
5522         if (first[st->codecpar->codec_type] < 0)
5523             first[st->codecpar->codec_type] = i;
5524         if (st->disposition & AV_DISPOSITION_DEFAULT) {
5525             mov->tracks[i].flags |= MOV_TRACK_ENABLED;
5526             enabled[st->codecpar->codec_type]++;
5527         }
5528     }
5529
5530     for (i = 0; i < AVMEDIA_TYPE_NB; i++) {
5531         switch (i) {
5532         case AVMEDIA_TYPE_VIDEO:
5533         case AVMEDIA_TYPE_AUDIO:
5534         case AVMEDIA_TYPE_SUBTITLE:
5535             if (enabled[i] > 1)
5536                 mov->per_stream_grouping = 1;
5537             if (!enabled[i] && first[i] >= 0)
5538                 mov->tracks[first[i]].flags |= MOV_TRACK_ENABLED;
5539             break;
5540         }
5541     }
5542 }
5543
5544 static void mov_free(AVFormatContext *s)
5545 {
5546     MOVMuxContext *mov = s->priv_data;
5547     int i;
5548
5549     if (mov->chapter_track) {
5550         if (mov->tracks[mov->chapter_track].par)
5551             av_freep(&mov->tracks[mov->chapter_track].par->extradata);
5552         av_freep(&mov->tracks[mov->chapter_track].par);
5553     }
5554
5555     for (i = 0; i < mov->nb_streams; i++) {
5556         if (mov->tracks[i].tag == MKTAG('r','t','p',' '))
5557             ff_mov_close_hinting(&mov->tracks[i]);
5558         else if (mov->tracks[i].tag == MKTAG('t','m','c','d') && mov->nb_meta_tmcd)
5559             av_freep(&mov->tracks[i].par);
5560         av_freep(&mov->tracks[i].cluster);
5561         av_freep(&mov->tracks[i].frag_info);
5562
5563         if (mov->tracks[i].vos_len)
5564             av_freep(&mov->tracks[i].vos_data);
5565
5566         ff_mov_cenc_free(&mov->tracks[i].cenc);
5567     }
5568
5569     av_freep(&mov->tracks);
5570 }
5571
5572 static uint32_t rgb_to_yuv(uint32_t rgb)
5573 {
5574     uint8_t r, g, b;
5575     int y, cb, cr;
5576
5577     r = (rgb >> 16) & 0xFF;
5578     g = (rgb >>  8) & 0xFF;
5579     b = (rgb      ) & 0xFF;
5580
5581     y  = av_clip_uint8(( 16000 +  257 * r + 504 * g +  98 * b)/1000);
5582     cb = av_clip_uint8((128000 -  148 * r - 291 * g + 439 * b)/1000);
5583     cr = av_clip_uint8((128000 +  439 * r - 368 * g -  71 * b)/1000);
5584
5585     return (y << 16) | (cr << 8) | cb;
5586 }
5587
5588 static int mov_create_dvd_sub_decoder_specific_info(MOVTrack *track,
5589                                                     AVStream *st)
5590 {
5591     int i, width = 720, height = 480;
5592     int have_palette = 0, have_size = 0;
5593     uint32_t palette[16];
5594     char *cur = st->codecpar->extradata;
5595
5596     while (cur && *cur) {
5597         if (strncmp("palette:", cur, 8) == 0) {
5598             int i, count;
5599             count = sscanf(cur + 8,
5600                 "%06"PRIx32", %06"PRIx32", %06"PRIx32", %06"PRIx32", "
5601                 "%06"PRIx32", %06"PRIx32", %06"PRIx32", %06"PRIx32", "
5602                 "%06"PRIx32", %06"PRIx32", %06"PRIx32", %06"PRIx32", "
5603                 "%06"PRIx32", %06"PRIx32", %06"PRIx32", %06"PRIx32"",
5604                 &palette[ 0], &palette[ 1], &palette[ 2], &palette[ 3],
5605                 &palette[ 4], &palette[ 5], &palette[ 6], &palette[ 7],
5606                 &palette[ 8], &palette[ 9], &palette[10], &palette[11],
5607                 &palette[12], &palette[13], &palette[14], &palette[15]);
5608
5609             for (i = 0; i < count; i++) {
5610                 palette[i] = rgb_to_yuv(palette[i]);
5611             }
5612             have_palette = 1;
5613         } else if (!strncmp("size:", cur, 5)) {
5614             sscanf(cur + 5, "%dx%d", &width, &height);
5615             have_size = 1;
5616         }
5617         if (have_palette && have_size)
5618             break;
5619         cur += strcspn(cur, "\n\r");
5620         cur += strspn(cur, "\n\r");
5621     }
5622     if (have_palette) {
5623         track->vos_data = av_malloc(16*4);
5624         if (!track->vos_data)
5625             return AVERROR(ENOMEM);
5626         for (i = 0; i < 16; i++) {
5627             AV_WB32(track->vos_data + i * 4, palette[i]);
5628         }
5629         track->vos_len = 16 * 4;
5630     }
5631     st->codecpar->width = width;
5632     st->codecpar->height = track->height = height;
5633
5634     return 0;
5635 }
5636
5637 static int mov_init(AVFormatContext *s)
5638 {
5639     MOVMuxContext *mov = s->priv_data;
5640     AVDictionaryEntry *global_tcr = av_dict_get(s->metadata, "timecode", NULL, 0);
5641     int i, ret;
5642
5643     mov->fc = s;
5644
5645     /* Default mode == MP4 */
5646     mov->mode = MODE_MP4;
5647
5648     if (s->oformat) {
5649         if (!strcmp("3gp", s->oformat->name)) mov->mode = MODE_3GP;
5650         else if (!strcmp("3g2", s->oformat->name)) mov->mode = MODE_3GP|MODE_3G2;
5651         else if (!strcmp("mov", s->oformat->name)) mov->mode = MODE_MOV;
5652         else if (!strcmp("psp", s->oformat->name)) mov->mode = MODE_PSP;
5653         else if (!strcmp("ipod",s->oformat->name)) mov->mode = MODE_IPOD;
5654         else if (!strcmp("ismv",s->oformat->name)) mov->mode = MODE_ISM;
5655         else if (!strcmp("f4v", s->oformat->name)) mov->mode = MODE_F4V;
5656     }
5657
5658     if (mov->flags & FF_MOV_FLAG_DELAY_MOOV)
5659         mov->flags |= FF_MOV_FLAG_EMPTY_MOOV;
5660
5661     /* Set the FRAGMENT flag if any of the fragmentation methods are
5662      * enabled. */
5663     if (mov->max_fragment_duration || mov->max_fragment_size ||
5664         mov->flags & (FF_MOV_FLAG_EMPTY_MOOV |
5665                       FF_MOV_FLAG_FRAG_KEYFRAME |
5666                       FF_MOV_FLAG_FRAG_CUSTOM))
5667         mov->flags |= FF_MOV_FLAG_FRAGMENT;
5668
5669     /* Set other implicit flags immediately */
5670     if (mov->mode == MODE_ISM)
5671         mov->flags |= FF_MOV_FLAG_EMPTY_MOOV | FF_MOV_FLAG_SEPARATE_MOOF |
5672                       FF_MOV_FLAG_FRAGMENT;
5673     if (mov->flags & FF_MOV_FLAG_DASH)
5674         mov->flags |= FF_MOV_FLAG_FRAGMENT | FF_MOV_FLAG_EMPTY_MOOV |
5675                       FF_MOV_FLAG_DEFAULT_BASE_MOOF;
5676
5677     if (mov->flags & FF_MOV_FLAG_EMPTY_MOOV && s->flags & AVFMT_FLAG_AUTO_BSF) {
5678         av_log(s, AV_LOG_VERBOSE, "Empty MOOV enabled; disabling automatic bitstream filtering\n");
5679         s->flags &= ~AVFMT_FLAG_AUTO_BSF;
5680     }
5681
5682     if (mov->flags & FF_MOV_FLAG_FASTSTART) {
5683         mov->reserved_moov_size = -1;
5684     }
5685
5686     if (mov->use_editlist < 0) {
5687         mov->use_editlist = 1;
5688         if (mov->flags & FF_MOV_FLAG_FRAGMENT &&
5689             !(mov->flags & FF_MOV_FLAG_DELAY_MOOV)) {
5690             // If we can avoid needing an edit list by shifting the
5691             // tracks, prefer that over (trying to) write edit lists
5692             // in fragmented output.
5693             if (s->avoid_negative_ts == AVFMT_AVOID_NEG_TS_AUTO ||
5694                 s->avoid_negative_ts == AVFMT_AVOID_NEG_TS_MAKE_ZERO)
5695                 mov->use_editlist = 0;
5696         }
5697     }
5698     if (mov->flags & FF_MOV_FLAG_EMPTY_MOOV &&
5699         !(mov->flags & FF_MOV_FLAG_DELAY_MOOV) && mov->use_editlist)
5700         av_log(s, AV_LOG_WARNING, "No meaningful edit list will be written when using empty_moov without delay_moov\n");
5701
5702     if (!mov->use_editlist && s->avoid_negative_ts == AVFMT_AVOID_NEG_TS_AUTO)
5703         s->avoid_negative_ts = AVFMT_AVOID_NEG_TS_MAKE_ZERO;
5704
5705     /* Clear the omit_tfhd_offset flag if default_base_moof is set;
5706      * if the latter is set that's enough and omit_tfhd_offset doesn't
5707      * add anything extra on top of that. */
5708     if (mov->flags & FF_MOV_FLAG_OMIT_TFHD_OFFSET &&
5709         mov->flags & FF_MOV_FLAG_DEFAULT_BASE_MOOF)
5710         mov->flags &= ~FF_MOV_FLAG_OMIT_TFHD_OFFSET;
5711
5712     if (mov->frag_interleave &&
5713         mov->flags & (FF_MOV_FLAG_OMIT_TFHD_OFFSET | FF_MOV_FLAG_SEPARATE_MOOF)) {
5714         av_log(s, AV_LOG_ERROR,
5715                "Sample interleaving in fragments is mutually exclusive with "
5716                "omit_tfhd_offset and separate_moof\n");
5717         return AVERROR(EINVAL);
5718     }
5719
5720     /* Non-seekable output is ok if using fragmentation. If ism_lookahead
5721      * is enabled, we don't support non-seekable output at all. */
5722     if (!(s->pb->seekable & AVIO_SEEKABLE_NORMAL) &&
5723         (!(mov->flags & FF_MOV_FLAG_FRAGMENT) || mov->ism_lookahead)) {
5724         av_log(s, AV_LOG_ERROR, "muxer does not support non seekable output\n");
5725         return AVERROR(EINVAL);
5726     }
5727
5728     mov->nb_streams = s->nb_streams;
5729     if (mov->mode & (MODE_MP4|MODE_MOV|MODE_IPOD) && s->nb_chapters)
5730         mov->chapter_track = mov->nb_streams++;
5731
5732     if (mov->flags & FF_MOV_FLAG_RTP_HINT) {
5733         /* Add hint tracks for each audio and video stream */
5734         for (i = 0; i < s->nb_streams; i++) {
5735             AVStream *st = s->streams[i];
5736             if (st->codecpar->codec_type == AVMEDIA_TYPE_VIDEO ||
5737                 st->codecpar->codec_type == AVMEDIA_TYPE_AUDIO) {
5738                 mov->nb_streams++;
5739             }
5740         }
5741     }
5742
5743     if (   mov->write_tmcd == -1 && (mov->mode == MODE_MOV || mov->mode == MODE_MP4)
5744         || mov->write_tmcd == 1) {
5745         /* +1 tmcd track for each video stream with a timecode */
5746         for (i = 0; i < s->nb_streams; i++) {
5747             AVStream *st = s->streams[i];
5748             AVDictionaryEntry *t = global_tcr;
5749             if (st->codecpar->codec_type == AVMEDIA_TYPE_VIDEO &&
5750                 (t || (t=av_dict_get(st->metadata, "timecode", NULL, 0)))) {
5751                 AVTimecode tc;
5752                 ret = mov_check_timecode_track(s, &tc, i, t->value);
5753                 if (ret >= 0)
5754                     mov->nb_meta_tmcd++;
5755             }
5756         }
5757
5758         /* check if there is already a tmcd track to remux */
5759         if (mov->nb_meta_tmcd) {
5760             for (i = 0; i < s->nb_streams; i++) {
5761                 AVStream *st = s->streams[i];
5762                 if (st->codecpar->codec_tag == MKTAG('t','m','c','d')) {
5763                     av_log(s, AV_LOG_WARNING, "You requested a copy of the original timecode track "
5764                            "so timecode metadata are now ignored\n");
5765                     mov->nb_meta_tmcd = 0;
5766                 }
5767             }
5768         }
5769
5770         mov->nb_streams += mov->nb_meta_tmcd;
5771     }
5772
5773     // Reserve an extra stream for chapters for the case where chapters
5774     // are written in the trailer
5775     mov->tracks = av_mallocz_array((mov->nb_streams + 1), sizeof(*mov->tracks));
5776     if (!mov->tracks)
5777         return AVERROR(ENOMEM);
5778
5779     if (mov->encryption_scheme_str != NULL && strcmp(mov->encryption_scheme_str, "none") != 0) {
5780         if (strcmp(mov->encryption_scheme_str, "cenc-aes-ctr") == 0) {
5781             mov->encryption_scheme = MOV_ENC_CENC_AES_CTR;
5782
5783             if (mov->encryption_key_len != AES_CTR_KEY_SIZE) {
5784                 av_log(s, AV_LOG_ERROR, "Invalid encryption key len %d expected %d\n",
5785                     mov->encryption_key_len, AES_CTR_KEY_SIZE);
5786                 return AVERROR(EINVAL);
5787             }
5788
5789             if (mov->encryption_kid_len != CENC_KID_SIZE) {
5790                 av_log(s, AV_LOG_ERROR, "Invalid encryption kid len %d expected %d\n",
5791                     mov->encryption_kid_len, CENC_KID_SIZE);
5792                 return AVERROR(EINVAL);
5793             }
5794         } else {
5795             av_log(s, AV_LOG_ERROR, "unsupported encryption scheme %s\n",
5796                 mov->encryption_scheme_str);
5797             return AVERROR(EINVAL);
5798         }
5799     }
5800
5801     for (i = 0; i < s->nb_streams; i++) {
5802         AVStream *st= s->streams[i];
5803         MOVTrack *track= &mov->tracks[i];
5804         AVDictionaryEntry *lang = av_dict_get(st->metadata, "language", NULL,0);
5805
5806         track->st  = st;
5807         track->par = st->codecpar;
5808         track->language = ff_mov_iso639_to_lang(lang?lang->value:"und", mov->mode!=MODE_MOV);
5809         if (track->language < 0)
5810             track->language = 0;
5811         track->mode = mov->mode;
5812         track->tag  = mov_find_codec_tag(s, track);
5813         if (!track->tag) {
5814             av_log(s, AV_LOG_ERROR, "Could not find tag for codec %s in stream #%d, "
5815                    "codec not currently supported in container\n",
5816                    avcodec_get_name(st->codecpar->codec_id), i);
5817             return AVERROR(EINVAL);
5818         }
5819         /* If hinting of this track is enabled by a later hint track,
5820          * this is updated. */
5821         track->hint_track = -1;
5822         track->start_dts  = AV_NOPTS_VALUE;
5823         track->start_cts  = AV_NOPTS_VALUE;
5824         track->end_pts    = AV_NOPTS_VALUE;
5825         if (st->codecpar->codec_type == AVMEDIA_TYPE_VIDEO) {
5826             if (track->tag == MKTAG('m','x','3','p') || track->tag == MKTAG('m','x','3','n') ||
5827                 track->tag == MKTAG('m','x','4','p') || track->tag == MKTAG('m','x','4','n') ||
5828                 track->tag == MKTAG('m','x','5','p') || track->tag == MKTAG('m','x','5','n')) {
5829                 if (st->codecpar->width != 720 || (st->codecpar->height != 608 && st->codecpar->height != 512)) {
5830                     av_log(s, AV_LOG_ERROR, "D-10/IMX must use 720x608 or 720x512 video resolution\n");
5831                     return AVERROR(EINVAL);
5832                 }
5833                 track->height = track->tag >> 24 == 'n' ? 486 : 576;
5834             }
5835             if (mov->video_track_timescale) {
5836                 track->timescale = mov->video_track_timescale;
5837             } else {
5838                 track->timescale = st->time_base.den;
5839                 while(track->timescale < 10000)
5840                     track->timescale *= 2;
5841             }
5842             if (st->codecpar->width > 65535 || st->codecpar->height > 65535) {
5843                 av_log(s, AV_LOG_ERROR, "Resolution %dx%d too large for mov/mp4\n", st->codecpar->width, st->codecpar->height);
5844                 return AVERROR(EINVAL);
5845             }
5846             if (track->mode == MODE_MOV && track->timescale > 100000)
5847                 av_log(s, AV_LOG_WARNING,
5848                        "WARNING codec timebase is very high. If duration is too long,\n"
5849                        "file may not be playable by quicktime. Specify a shorter timebase\n"
5850                        "or choose different container.\n");
5851             if (track->mode == MODE_MOV &&
5852                 track->par->codec_id == AV_CODEC_ID_RAWVIDEO &&
5853                 track->tag == MKTAG('r','a','w',' ')) {
5854                 enum AVPixelFormat pix_fmt = track->par->format;
5855                 if (pix_fmt == AV_PIX_FMT_NONE && track->par->bits_per_coded_sample == 1)
5856                     pix_fmt = AV_PIX_FMT_MONOWHITE;
5857                 track->is_unaligned_qt_rgb =
5858                         pix_fmt == AV_PIX_FMT_RGB24 ||
5859                         pix_fmt == AV_PIX_FMT_BGR24 ||
5860                         pix_fmt == AV_PIX_FMT_PAL8 ||
5861                         pix_fmt == AV_PIX_FMT_GRAY8 ||
5862                         pix_fmt == AV_PIX_FMT_MONOWHITE ||
5863                         pix_fmt == AV_PIX_FMT_MONOBLACK;
5864             }
5865             if (track->par->codec_id == AV_CODEC_ID_VP9) {
5866                 if (track->mode != MODE_MP4) {
5867                     av_log(s, AV_LOG_ERROR, "VP9 only supported in MP4.\n");
5868                     return AVERROR(EINVAL);
5869                 }
5870                 if (s->strict_std_compliance > FF_COMPLIANCE_EXPERIMENTAL) {
5871                     av_log(s, AV_LOG_ERROR,
5872                            "VP9 in MP4 support is experimental, add "
5873                            "'-strict %d' if you want to use it.\n",
5874                            FF_COMPLIANCE_EXPERIMENTAL);
5875                     return AVERROR_EXPERIMENTAL;
5876                 }
5877             }
5878         } else if (st->codecpar->codec_type == AVMEDIA_TYPE_AUDIO) {
5879             track->timescale = st->codecpar->sample_rate;
5880             if (!st->codecpar->frame_size && !av_get_bits_per_sample(st->codecpar->codec_id)) {
5881                 av_log(s, AV_LOG_WARNING, "track %d: codec frame size is not set\n", i);
5882                 track->audio_vbr = 1;
5883             }else if (st->codecpar->codec_id == AV_CODEC_ID_ADPCM_MS ||
5884                      st->codecpar->codec_id == AV_CODEC_ID_ADPCM_IMA_WAV ||
5885                      st->codecpar->codec_id == AV_CODEC_ID_ILBC){
5886                 if (!st->codecpar->block_align) {
5887                     av_log(s, AV_LOG_ERROR, "track %d: codec block align is not set for adpcm\n", i);
5888                     return AVERROR(EINVAL);
5889                 }
5890                 track->sample_size = st->codecpar->block_align;
5891             }else if (st->codecpar->frame_size > 1){ /* assume compressed audio */
5892                 track->audio_vbr = 1;
5893             }else{
5894                 track->sample_size = (av_get_bits_per_sample(st->codecpar->codec_id) >> 3) * st->codecpar->channels;
5895             }
5896             if (st->codecpar->codec_id == AV_CODEC_ID_ILBC ||
5897                 st->codecpar->codec_id == AV_CODEC_ID_ADPCM_IMA_QT) {
5898                 track->audio_vbr = 1;
5899             }
5900             if (track->mode != MODE_MOV &&
5901                 track->par->codec_id == AV_CODEC_ID_MP3 && track->timescale < 16000) {
5902                 if (s->strict_std_compliance >= FF_COMPLIANCE_NORMAL) {
5903                     av_log(s, AV_LOG_ERROR, "track %d: muxing mp3 at %dhz is not standard, to mux anyway set strict to -1\n",
5904                         i, track->par->sample_rate);
5905                     return AVERROR(EINVAL);
5906                 } else {
5907                     av_log(s, AV_LOG_WARNING, "track %d: muxing mp3 at %dhz is not standard in MP4\n",
5908                            i, track->par->sample_rate);
5909                 }
5910             }
5911             if (track->par->codec_id == AV_CODEC_ID_FLAC) {
5912                 if (track->mode != MODE_MP4) {
5913                     av_log(s, AV_LOG_ERROR, "FLAC only supported in MP4.\n");
5914                     return AVERROR(EINVAL);
5915                 }
5916                 if (s->strict_std_compliance > FF_COMPLIANCE_EXPERIMENTAL) {
5917                     av_log(s, AV_LOG_ERROR,
5918                            "FLAC in MP4 support is experimental, add "
5919                            "'-strict %d' if you want to use it.\n",
5920                            FF_COMPLIANCE_EXPERIMENTAL);
5921                     return AVERROR_EXPERIMENTAL;
5922                 }
5923             }
5924         } else if (st->codecpar->codec_type == AVMEDIA_TYPE_SUBTITLE) {
5925             track->timescale = st->time_base.den;
5926         } else if (st->codecpar->codec_type == AVMEDIA_TYPE_DATA) {
5927             track->timescale = st->time_base.den;
5928         } else {
5929             track->timescale = MOV_TIMESCALE;
5930         }
5931         if (!track->height)
5932             track->height = st->codecpar->height;
5933         /* The ism specific timescale isn't mandatory, but is assumed by
5934          * some tools, such as mp4split. */
5935         if (mov->mode == MODE_ISM)
5936             track->timescale = 10000000;
5937
5938         avpriv_set_pts_info(st, 64, 1, track->timescale);
5939
5940         if (mov->encryption_scheme == MOV_ENC_CENC_AES_CTR) {
5941             ret = ff_mov_cenc_init(&track->cenc, mov->encryption_key,
5942                 track->par->codec_id == AV_CODEC_ID_H264, s->flags & AVFMT_FLAG_BITEXACT);
5943             if (ret)
5944                 return ret;
5945         }
5946     }
5947
5948     enable_tracks(s);
5949     return 0;
5950 }
5951
5952 static int mov_write_header(AVFormatContext *s)
5953 {
5954     AVIOContext *pb = s->pb;
5955     MOVMuxContext *mov = s->priv_data;
5956     AVDictionaryEntry *t, *global_tcr = av_dict_get(s->metadata, "timecode", NULL, 0);
5957     int i, ret, hint_track = 0, tmcd_track = 0, nb_tracks = s->nb_streams;
5958
5959     if (mov->mode & (MODE_MP4|MODE_MOV|MODE_IPOD) && s->nb_chapters)
5960         nb_tracks++;
5961
5962     if (mov->flags & FF_MOV_FLAG_RTP_HINT) {
5963         /* Add hint tracks for each audio and video stream */
5964         hint_track = nb_tracks;
5965         for (i = 0; i < s->nb_streams; i++) {
5966             AVStream *st = s->streams[i];
5967             if (st->codecpar->codec_type == AVMEDIA_TYPE_VIDEO ||
5968                 st->codecpar->codec_type == AVMEDIA_TYPE_AUDIO) {
5969                 nb_tracks++;
5970             }
5971         }
5972     }
5973
5974     if (mov->mode == MODE_MOV || mov->mode == MODE_MP4)
5975         tmcd_track = nb_tracks;
5976
5977     for (i = 0; i < s->nb_streams; i++) {
5978         int j;
5979         AVStream *st= s->streams[i];
5980         MOVTrack *track= &mov->tracks[i];
5981
5982         /* copy extradata if it exists */
5983         if (st->codecpar->extradata_size) {
5984             if (st->codecpar->codec_id == AV_CODEC_ID_DVD_SUBTITLE)
5985                 mov_create_dvd_sub_decoder_specific_info(track, st);
5986             else if (!TAG_IS_AVCI(track->tag) && st->codecpar->codec_id != AV_CODEC_ID_DNXHD) {
5987                 track->vos_len  = st->codecpar->extradata_size;
5988                 track->vos_data = av_malloc(track->vos_len);
5989                 if (!track->vos_data) {
5990                     return AVERROR(ENOMEM);
5991                 }
5992                 memcpy(track->vos_data, st->codecpar->extradata, track->vos_len);
5993             }
5994         }
5995
5996         if (st->codecpar->codec_type != AVMEDIA_TYPE_AUDIO ||
5997             track->par->channel_layout != AV_CH_LAYOUT_MONO)
5998             continue;
5999
6000         for (j = 0; j < s->nb_streams; j++) {
6001             AVStream *stj= s->streams[j];
6002             MOVTrack *trackj= &mov->tracks[j];
6003             if (j == i)
6004                 continue;
6005
6006             if (stj->codecpar->codec_type != AVMEDIA_TYPE_AUDIO ||
6007                 trackj->par->channel_layout != AV_CH_LAYOUT_MONO ||
6008                 trackj->language != track->language ||
6009                 trackj->tag != track->tag
6010             )
6011                 continue;
6012             track->multichannel_as_mono++;
6013         }
6014     }
6015
6016     if (!(mov->flags & FF_MOV_FLAG_DELAY_MOOV)) {
6017         if ((ret = mov_write_identification(pb, s)) < 0)
6018             return ret;
6019     }
6020
6021     if (mov->reserved_moov_size){
6022         mov->reserved_header_pos = avio_tell(pb);
6023         if (mov->reserved_moov_size > 0)
6024             avio_skip(pb, mov->reserved_moov_size);
6025     }
6026
6027     if (mov->flags & FF_MOV_FLAG_FRAGMENT) {
6028         /* If no fragmentation options have been set, set a default. */
6029         if (!(mov->flags & (FF_MOV_FLAG_FRAG_KEYFRAME |
6030                             FF_MOV_FLAG_FRAG_CUSTOM)) &&
6031             !mov->max_fragment_duration && !mov->max_fragment_size)
6032             mov->flags |= FF_MOV_FLAG_FRAG_KEYFRAME;
6033     } else {
6034         if (mov->flags & FF_MOV_FLAG_FASTSTART)
6035             mov->reserved_header_pos = avio_tell(pb);
6036         mov_write_mdat_tag(pb, mov);
6037     }
6038
6039     ff_parse_creation_time_metadata(s, &mov->time, 1);
6040     if (mov->time)
6041         mov->time += 0x7C25B080; // 1970 based -> 1904 based
6042
6043     if (mov->chapter_track)
6044         if ((ret = mov_create_chapter_track(s, mov->chapter_track)) < 0)
6045             return ret;
6046
6047     if (mov->flags & FF_MOV_FLAG_RTP_HINT) {
6048         /* Initialize the hint tracks for each audio and video stream */
6049         for (i = 0; i < s->nb_streams; i++) {
6050             AVStream *st = s->streams[i];
6051             if (st->codecpar->codec_type == AVMEDIA_TYPE_VIDEO ||
6052                 st->codecpar->codec_type == AVMEDIA_TYPE_AUDIO) {
6053                 if ((ret = ff_mov_init_hinting(s, hint_track, i)) < 0)
6054                     return ret;
6055                 hint_track++;
6056             }
6057         }
6058     }
6059
6060     if (mov->nb_meta_tmcd) {
6061         /* Initialize the tmcd tracks */
6062         for (i = 0; i < s->nb_streams; i++) {
6063             AVStream *st = s->streams[i];
6064             t = global_tcr;
6065
6066             if (st->codecpar->codec_type == AVMEDIA_TYPE_VIDEO) {
6067                 AVTimecode tc;
6068                 if (!t)
6069                     t = av_dict_get(st->metadata, "timecode", NULL, 0);
6070                 if (!t)
6071                     continue;
6072                 if (mov_check_timecode_track(s, &tc, i, t->value) < 0)
6073                     continue;
6074                 if ((ret = mov_create_timecode_track(s, tmcd_track, i, tc)) < 0)
6075                     return ret;
6076                 tmcd_track++;
6077             }
6078         }
6079     }
6080
6081     avio_flush(pb);
6082
6083     if (mov->flags & FF_MOV_FLAG_ISML)
6084         mov_write_isml_manifest(pb, mov, s);
6085
6086     if (mov->flags & FF_MOV_FLAG_EMPTY_MOOV &&
6087         !(mov->flags & FF_MOV_FLAG_DELAY_MOOV)) {
6088         if ((ret = mov_write_moov_tag(pb, mov, s)) < 0)
6089             return ret;
6090         avio_flush(pb);
6091         mov->moov_written = 1;
6092         if (mov->flags & FF_MOV_FLAG_GLOBAL_SIDX)
6093             mov->reserved_header_pos = avio_tell(pb);
6094     }
6095
6096     return 0;
6097 }
6098
6099 static int get_moov_size(AVFormatContext *s)
6100 {
6101     int ret;
6102     AVIOContext *moov_buf;
6103     MOVMuxContext *mov = s->priv_data;
6104
6105     if ((ret = ffio_open_null_buf(&moov_buf)) < 0)
6106         return ret;
6107     if ((ret = mov_write_moov_tag(moov_buf, mov, s)) < 0)
6108         return ret;
6109     return ffio_close_null_buf(moov_buf);
6110 }
6111
6112 static int get_sidx_size(AVFormatContext *s)
6113 {
6114     int ret;
6115     AVIOContext *buf;
6116     MOVMuxContext *mov = s->priv_data;
6117
6118     if ((ret = ffio_open_null_buf(&buf)) < 0)
6119         return ret;
6120     mov_write_sidx_tags(buf, mov, -1, 0);
6121     return ffio_close_null_buf(buf);
6122 }
6123
6124 /*
6125  * This function gets the moov size if moved to the top of the file: the chunk
6126  * offset table can switch between stco (32-bit entries) to co64 (64-bit
6127  * entries) when the moov is moved to the beginning, so the size of the moov
6128  * would change. It also updates the chunk offset tables.
6129  */
6130 static int compute_moov_size(AVFormatContext *s)
6131 {
6132     int i, moov_size, moov_size2;
6133     MOVMuxContext *mov = s->priv_data;
6134
6135     moov_size = get_moov_size(s);
6136     if (moov_size < 0)
6137         return moov_size;
6138
6139     for (i = 0; i < mov->nb_streams; i++)
6140         mov->tracks[i].data_offset += moov_size;
6141
6142     moov_size2 = get_moov_size(s);
6143     if (moov_size2 < 0)
6144         return moov_size2;
6145
6146     /* if the size changed, we just switched from stco to co64 and need to
6147      * update the offsets */
6148     if (moov_size2 != moov_size)
6149         for (i = 0; i < mov->nb_streams; i++)
6150             mov->tracks[i].data_offset += moov_size2 - moov_size;
6151
6152     return moov_size2;
6153 }
6154
6155 static int compute_sidx_size(AVFormatContext *s)
6156 {
6157     int i, sidx_size;
6158     MOVMuxContext *mov = s->priv_data;
6159
6160     sidx_size = get_sidx_size(s);
6161     if (sidx_size < 0)
6162         return sidx_size;
6163
6164     for (i = 0; i < mov->nb_streams; i++)
6165         mov->tracks[i].data_offset += sidx_size;
6166
6167     return sidx_size;
6168 }
6169
6170 static int shift_data(AVFormatContext *s)
6171 {
6172     int ret = 0, moov_size;
6173     MOVMuxContext *mov = s->priv_data;
6174     int64_t pos, pos_end = avio_tell(s->pb);
6175     uint8_t *buf, *read_buf[2];
6176     int read_buf_id = 0;
6177     int read_size[2];
6178     AVIOContext *read_pb;
6179
6180     if (mov->flags & FF_MOV_FLAG_FRAGMENT)
6181         moov_size = compute_sidx_size(s);
6182     else
6183         moov_size = compute_moov_size(s);
6184     if (moov_size < 0)
6185         return moov_size;
6186
6187     buf = av_malloc(moov_size * 2);
6188     if (!buf)
6189         return AVERROR(ENOMEM);
6190     read_buf[0] = buf;
6191     read_buf[1] = buf + moov_size;
6192
6193     /* Shift the data: the AVIO context of the output can only be used for
6194      * writing, so we re-open the same output, but for reading. It also avoids
6195      * a read/seek/write/seek back and forth. */
6196     avio_flush(s->pb);
6197     ret = s->io_open(s, &read_pb, s->filename, AVIO_FLAG_READ, NULL);
6198     if (ret < 0) {
6199         av_log(s, AV_LOG_ERROR, "Unable to re-open %s output file for "
6200                "the second pass (faststart)\n", s->filename);
6201         goto end;
6202     }
6203
6204     /* mark the end of the shift to up to the last data we wrote, and get ready
6205      * for writing */
6206     pos_end = avio_tell(s->pb);
6207     avio_seek(s->pb, mov->reserved_header_pos + moov_size, SEEK_SET);
6208
6209     /* start reading at where the new moov will be placed */
6210     avio_seek(read_pb, mov->reserved_header_pos, SEEK_SET);
6211     pos = avio_tell(read_pb);
6212
6213 #define READ_BLOCK do {                                                             \
6214     read_size[read_buf_id] = avio_read(read_pb, read_buf[read_buf_id], moov_size);  \
6215     read_buf_id ^= 1;                                                               \
6216 } while (0)
6217
6218     /* shift data by chunk of at most moov_size */
6219     READ_BLOCK;
6220     do {
6221         int n;
6222         READ_BLOCK;
6223         n = read_size[read_buf_id];
6224         if (n <= 0)
6225             break;
6226         avio_write(s->pb, read_buf[read_buf_id], n);
6227         pos += n;
6228     } while (pos < pos_end);
6229     ff_format_io_close(s, &read_pb);
6230
6231 end:
6232     av_free(buf);
6233     return ret;
6234 }
6235
6236 static int mov_write_trailer(AVFormatContext *s)
6237 {
6238     MOVMuxContext *mov = s->priv_data;
6239     AVIOContext *pb = s->pb;
6240     int res = 0;
6241     int i;
6242     int64_t moov_pos;
6243
6244     if (mov->need_rewrite_extradata) {
6245         for (i = 0; i < s->nb_streams; i++) {
6246             MOVTrack *track = &mov->tracks[i];
6247             AVCodecParameters *par = track->par;
6248
6249             track->vos_len  = par->extradata_size;
6250             track->vos_data = av_malloc(track->vos_len);
6251             if (!track->vos_data)
6252                 return AVERROR(ENOMEM);
6253             memcpy(track->vos_data, par->extradata, track->vos_len);
6254         }
6255         mov->need_rewrite_extradata = 0;
6256     }
6257
6258     /*
6259      * Before actually writing the trailer, make sure that there are no
6260      * dangling subtitles, that need a terminating sample.
6261      */
6262     for (i = 0; i < mov->nb_streams; i++) {
6263         MOVTrack *trk = &mov->tracks[i];
6264         if (trk->par->codec_id == AV_CODEC_ID_MOV_TEXT &&
6265             !trk->last_sample_is_subtitle_end) {
6266             mov_write_subtitle_end_packet(s, i, trk->track_duration);
6267             trk->last_sample_is_subtitle_end = 1;
6268         }
6269     }
6270
6271     // If there were no chapters when the header was written, but there
6272     // are chapters now, write them in the trailer.  This only works
6273     // when we are not doing fragments.
6274     if (!mov->chapter_track && !(mov->flags & FF_MOV_FLAG_FRAGMENT)) {
6275         if (mov->mode & (MODE_MP4|MODE_MOV|MODE_IPOD) && s->nb_chapters) {
6276             mov->chapter_track = mov->nb_streams++;
6277             if ((res = mov_create_chapter_track(s, mov->chapter_track)) < 0)
6278                 return res;
6279         }
6280     }
6281
6282     if (!(mov->flags & FF_MOV_FLAG_FRAGMENT)) {
6283         moov_pos = avio_tell(pb);
6284
6285         /* Write size of mdat tag */
6286         if (mov->mdat_size + 8 <= UINT32_MAX) {
6287             avio_seek(pb, mov->mdat_pos, SEEK_SET);
6288             avio_wb32(pb, mov->mdat_size + 8);
6289         } else {
6290             /* overwrite 'wide' placeholder atom */
6291             avio_seek(pb, mov->mdat_pos - 8, SEEK_SET);
6292             /* special value: real atom size will be 64 bit value after
6293              * tag field */
6294             avio_wb32(pb, 1);
6295             ffio_wfourcc(pb, "mdat");
6296             avio_wb64(pb, mov->mdat_size + 16);
6297         }
6298         avio_seek(pb, mov->reserved_moov_size > 0 ? mov->reserved_header_pos : moov_pos, SEEK_SET);
6299
6300         if (mov->flags & FF_MOV_FLAG_FASTSTART) {
6301             av_log(s, AV_LOG_INFO, "Starting second pass: moving the moov atom to the beginning of the file\n");
6302             res = shift_data(s);
6303             if (res < 0)
6304                 return res;
6305             avio_seek(pb, mov->reserved_header_pos, SEEK_SET);
6306             if ((res = mov_write_moov_tag(pb, mov, s)) < 0)
6307                 return res;
6308         } else if (mov->reserved_moov_size > 0) {
6309             int64_t size;
6310             if ((res = mov_write_moov_tag(pb, mov, s)) < 0)
6311                 return res;
6312             size = mov->reserved_moov_size - (avio_tell(pb) - mov->reserved_header_pos);
6313             if (size < 8){
6314                 av_log(s, AV_LOG_ERROR, "reserved_moov_size is too small, needed %"PRId64" additional\n", 8-size);
6315                 return AVERROR(EINVAL);
6316             }
6317             avio_wb32(pb, size);
6318             ffio_wfourcc(pb, "free");
6319             ffio_fill(pb, 0, size - 8);
6320             avio_seek(pb, moov_pos, SEEK_SET);
6321         } else {
6322             if ((res = mov_write_moov_tag(pb, mov, s)) < 0)
6323                 return res;
6324         }
6325         res = 0;
6326     } else {
6327         mov_auto_flush_fragment(s, 1);
6328         for (i = 0; i < mov->nb_streams; i++)
6329            mov->tracks[i].data_offset = 0;
6330         if (mov->flags & FF_MOV_FLAG_GLOBAL_SIDX) {
6331             int64_t end;
6332             av_log(s, AV_LOG_INFO, "Starting second pass: inserting sidx atoms\n");
6333             res = shift_data(s);
6334             if (res < 0)
6335                 return res;
6336             end = avio_tell(pb);
6337             avio_seek(pb, mov->reserved_header_pos, SEEK_SET);
6338             mov_write_sidx_tags(pb, mov, -1, 0);
6339             avio_seek(pb, end, SEEK_SET);
6340             avio_write_marker(s->pb, AV_NOPTS_VALUE, AVIO_DATA_MARKER_TRAILER);
6341             mov_write_mfra_tag(pb, mov);
6342         } else if (!(mov->flags & FF_MOV_FLAG_SKIP_TRAILER)) {
6343             avio_write_marker(s->pb, AV_NOPTS_VALUE, AVIO_DATA_MARKER_TRAILER);
6344             mov_write_mfra_tag(pb, mov);
6345         }
6346     }
6347
6348     return res;
6349 }
6350
6351 static int mov_check_bitstream(struct AVFormatContext *s, const AVPacket *pkt)
6352 {
6353     int ret = 1;
6354     AVStream *st = s->streams[pkt->stream_index];
6355
6356     if (st->codecpar->codec_id == AV_CODEC_ID_AAC) {
6357         if (pkt->size > 2 && (AV_RB16(pkt->data) & 0xfff0) == 0xfff0)
6358             ret = ff_stream_add_bitstream_filter(st, "aac_adtstoasc", NULL);
6359     }
6360
6361     return ret;
6362 }
6363
6364 #if CONFIG_MOV_MUXER
6365 MOV_CLASS(mov)
6366 AVOutputFormat ff_mov_muxer = {
6367     .name              = "mov",
6368     .long_name         = NULL_IF_CONFIG_SMALL("QuickTime / MOV"),
6369     .extensions        = "mov",
6370     .priv_data_size    = sizeof(MOVMuxContext),
6371     .audio_codec       = AV_CODEC_ID_AAC,
6372     .video_codec       = CONFIG_LIBX264_ENCODER ?
6373                          AV_CODEC_ID_H264 : AV_CODEC_ID_MPEG4,
6374     .init              = mov_init,
6375     .write_header      = mov_write_header,
6376     .write_packet      = mov_write_packet,
6377     .write_trailer     = mov_write_trailer,
6378     .deinit            = mov_free,
6379     .flags             = AVFMT_GLOBALHEADER | AVFMT_ALLOW_FLUSH | AVFMT_TS_NEGATIVE,
6380     .codec_tag         = (const AVCodecTag* const []){
6381         ff_codec_movvideo_tags, ff_codec_movaudio_tags, 0
6382     },
6383     .check_bitstream   = mov_check_bitstream,
6384     .priv_class        = &mov_muxer_class,
6385 };
6386 #endif
6387 #if CONFIG_TGP_MUXER
6388 MOV_CLASS(tgp)
6389 AVOutputFormat ff_tgp_muxer = {
6390     .name              = "3gp",
6391     .long_name         = NULL_IF_CONFIG_SMALL("3GP (3GPP file format)"),
6392     .extensions        = "3gp",
6393     .priv_data_size    = sizeof(MOVMuxContext),
6394     .audio_codec       = AV_CODEC_ID_AMR_NB,
6395     .video_codec       = AV_CODEC_ID_H263,
6396     .init              = mov_init,
6397     .write_header      = mov_write_header,
6398     .write_packet      = mov_write_packet,
6399     .write_trailer     = mov_write_trailer,
6400     .deinit            = mov_free,
6401     .flags             = AVFMT_GLOBALHEADER | AVFMT_ALLOW_FLUSH | AVFMT_TS_NEGATIVE,
6402     .codec_tag         = (const AVCodecTag* const []){ codec_3gp_tags, 0 },
6403     .check_bitstream   = mov_check_bitstream,
6404     .priv_class        = &tgp_muxer_class,
6405 };
6406 #endif
6407 #if CONFIG_MP4_MUXER
6408 MOV_CLASS(mp4)
6409 AVOutputFormat ff_mp4_muxer = {
6410     .name              = "mp4",
6411     .long_name         = NULL_IF_CONFIG_SMALL("MP4 (MPEG-4 Part 14)"),
6412     .mime_type         = "video/mp4",
6413     .extensions        = "mp4",
6414     .priv_data_size    = sizeof(MOVMuxContext),
6415     .audio_codec       = AV_CODEC_ID_AAC,
6416     .video_codec       = CONFIG_LIBX264_ENCODER ?
6417                          AV_CODEC_ID_H264 : AV_CODEC_ID_MPEG4,
6418     .init              = mov_init,
6419     .write_header      = mov_write_header,
6420     .write_packet      = mov_write_packet,
6421     .write_trailer     = mov_write_trailer,
6422     .deinit            = mov_free,
6423     .flags             = AVFMT_GLOBALHEADER | AVFMT_ALLOW_FLUSH | AVFMT_TS_NEGATIVE,
6424     .codec_tag         = (const AVCodecTag* const []){ ff_mp4_obj_type, 0 },
6425     .check_bitstream   = mov_check_bitstream,
6426     .priv_class        = &mp4_muxer_class,
6427 };
6428 #endif
6429 #if CONFIG_PSP_MUXER
6430 MOV_CLASS(psp)
6431 AVOutputFormat ff_psp_muxer = {
6432     .name              = "psp",
6433     .long_name         = NULL_IF_CONFIG_SMALL("PSP MP4 (MPEG-4 Part 14)"),
6434     .extensions        = "mp4,psp",
6435     .priv_data_size    = sizeof(MOVMuxContext),
6436     .audio_codec       = AV_CODEC_ID_AAC,
6437     .video_codec       = CONFIG_LIBX264_ENCODER ?
6438                          AV_CODEC_ID_H264 : AV_CODEC_ID_MPEG4,
6439     .init              = mov_init,
6440     .write_header      = mov_write_header,
6441     .write_packet      = mov_write_packet,
6442     .write_trailer     = mov_write_trailer,
6443     .deinit            = mov_free,
6444     .flags             = AVFMT_GLOBALHEADER | AVFMT_ALLOW_FLUSH | AVFMT_TS_NEGATIVE,
6445     .codec_tag         = (const AVCodecTag* const []){ ff_mp4_obj_type, 0 },
6446     .check_bitstream   = mov_check_bitstream,
6447     .priv_class        = &psp_muxer_class,
6448 };
6449 #endif
6450 #if CONFIG_TG2_MUXER
6451 MOV_CLASS(tg2)
6452 AVOutputFormat ff_tg2_muxer = {
6453     .name              = "3g2",
6454     .long_name         = NULL_IF_CONFIG_SMALL("3GP2 (3GPP2 file format)"),
6455     .extensions        = "3g2",
6456     .priv_data_size    = sizeof(MOVMuxContext),
6457     .audio_codec       = AV_CODEC_ID_AMR_NB,
6458     .video_codec       = AV_CODEC_ID_H263,
6459     .init              = mov_init,
6460     .write_header      = mov_write_header,
6461     .write_packet      = mov_write_packet,
6462     .write_trailer     = mov_write_trailer,
6463     .deinit            = mov_free,
6464     .flags             = AVFMT_GLOBALHEADER | AVFMT_ALLOW_FLUSH | AVFMT_TS_NEGATIVE,
6465     .codec_tag         = (const AVCodecTag* const []){ codec_3gp_tags, 0 },
6466     .check_bitstream   = mov_check_bitstream,
6467     .priv_class        = &tg2_muxer_class,
6468 };
6469 #endif
6470 #if CONFIG_IPOD_MUXER
6471 MOV_CLASS(ipod)
6472 AVOutputFormat ff_ipod_muxer = {
6473     .name              = "ipod",
6474     .long_name         = NULL_IF_CONFIG_SMALL("iPod H.264 MP4 (MPEG-4 Part 14)"),
6475     .mime_type         = "video/mp4",
6476     .extensions        = "m4v,m4a",
6477     .priv_data_size    = sizeof(MOVMuxContext),
6478     .audio_codec       = AV_CODEC_ID_AAC,
6479     .video_codec       = AV_CODEC_ID_H264,
6480     .init              = mov_init,
6481     .write_header      = mov_write_header,
6482     .write_packet      = mov_write_packet,
6483     .write_trailer     = mov_write_trailer,
6484     .deinit            = mov_free,
6485     .flags             = AVFMT_GLOBALHEADER | AVFMT_ALLOW_FLUSH | AVFMT_TS_NEGATIVE,
6486     .codec_tag         = (const AVCodecTag* const []){ codec_ipod_tags, 0 },
6487     .check_bitstream   = mov_check_bitstream,
6488     .priv_class        = &ipod_muxer_class,
6489 };
6490 #endif
6491 #if CONFIG_ISMV_MUXER
6492 MOV_CLASS(ismv)
6493 AVOutputFormat ff_ismv_muxer = {
6494     .name              = "ismv",
6495     .long_name         = NULL_IF_CONFIG_SMALL("ISMV/ISMA (Smooth Streaming)"),
6496     .mime_type         = "video/mp4",
6497     .extensions        = "ismv,isma",
6498     .priv_data_size    = sizeof(MOVMuxContext),
6499     .audio_codec       = AV_CODEC_ID_AAC,
6500     .video_codec       = AV_CODEC_ID_H264,
6501     .init              = mov_init,
6502     .write_header      = mov_write_header,
6503     .write_packet      = mov_write_packet,
6504     .write_trailer     = mov_write_trailer,
6505     .deinit            = mov_free,
6506     .flags             = AVFMT_GLOBALHEADER | AVFMT_ALLOW_FLUSH | AVFMT_TS_NEGATIVE,
6507     .codec_tag         = (const AVCodecTag* const []){ ff_mp4_obj_type, 0 },
6508     .check_bitstream   = mov_check_bitstream,
6509     .priv_class        = &ismv_muxer_class,
6510 };
6511 #endif
6512 #if CONFIG_F4V_MUXER
6513 MOV_CLASS(f4v)
6514 AVOutputFormat ff_f4v_muxer = {
6515     .name              = "f4v",
6516     .long_name         = NULL_IF_CONFIG_SMALL("F4V Adobe Flash Video"),
6517     .mime_type         = "application/f4v",
6518     .extensions        = "f4v",
6519     .priv_data_size    = sizeof(MOVMuxContext),
6520     .audio_codec       = AV_CODEC_ID_AAC,
6521     .video_codec       = AV_CODEC_ID_H264,
6522     .init              = mov_init,
6523     .write_header      = mov_write_header,
6524     .write_packet      = mov_write_packet,
6525     .write_trailer     = mov_write_trailer,
6526     .deinit            = mov_free,
6527     .flags             = AVFMT_GLOBALHEADER | AVFMT_ALLOW_FLUSH,
6528     .codec_tag         = (const AVCodecTag* const []){ codec_f4v_tags, 0 },
6529     .check_bitstream   = mov_check_bitstream,
6530     .priv_class        = &f4v_muxer_class,
6531 };
6532 #endif