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