lavc/aarch64: Fix addp overflow in ff_pred16x16_plane_neon_10
[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 "dovi_isom.h"
31 #include "riff.h"
32 #include "avio.h"
33 #include "isom.h"
34 #include "av1.h"
35 #include "avc.h"
36 #include "libavcodec/ac3_parser_internal.h"
37 #include "libavcodec/dnxhddata.h"
38 #include "libavcodec/flac.h"
39 #include "libavcodec/get_bits.h"
40
41 #include "libavcodec/internal.h"
42 #include "libavcodec/put_bits.h"
43 #include "libavcodec/vc1_common.h"
44 #include "libavcodec/raw.h"
45 #include "internal.h"
46 #include "libavutil/avstring.h"
47 #include "libavutil/channel_layout.h"
48 #include "libavutil/intfloat.h"
49 #include "libavutil/mathematics.h"
50 #include "libavutil/libm.h"
51 #include "libavutil/opt.h"
52 #include "libavutil/dict.h"
53 #include "libavutil/pixdesc.h"
54 #include "libavutil/stereo3d.h"
55 #include "libavutil/timecode.h"
56 #include "libavutil/dovi_meta.h"
57 #include "libavutil/color_utils.h"
58 #include "hevc.h"
59 #include "rtpenc.h"
60 #include "mov_chan.h"
61 #include "movenc_ttml.h"
62 #include "ttmlenc.h"
63 #include "vpcc.h"
64
65 static const AVOption options[] = {
66 { "movflags", "MOV muxer flags", offsetof(MOVMuxContext, flags), AV_OPT_TYPE_FLAGS, {.i64 = 0}, INT_MIN, INT_MAX, AV_OPT_FLAG_ENCODING_PARAM, "movflags" },
67 { "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" },
68 { "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 },
69 { "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" },
70 { "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" },
71 { "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" },
72 { "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" },
73 { "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" },
74 { "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" },
75 { "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" },
76 { "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" },
77 { "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" },
78 { "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" },
79 { "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" },
80 { "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" },
81 { "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" },
82 { "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" },
83 { "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" },
84 { "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" },
85 { "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" },
86 { "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" },
87 { "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" },
88 { "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" },
89 { "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" },
90 { "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" },
91 FF_RTP_FLAG_OPTS(MOVMuxContext, rtp_flags),
92 { "skip_iods", "Skip writing iods atom.", offsetof(MOVMuxContext, iods_skip), AV_OPT_TYPE_BOOL, {.i64 = 1}, 0, 1, AV_OPT_FLAG_ENCODING_PARAM},
93 { "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},
94 { "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},
95 { "frag_duration", "Maximum fragment duration", offsetof(MOVMuxContext, max_fragment_duration), AV_OPT_TYPE_INT, {.i64 = 0}, 0, INT_MAX, AV_OPT_FLAG_ENCODING_PARAM},
96 { "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},
97 { "frag_size", "Maximum fragment size", offsetof(MOVMuxContext, max_fragment_size), AV_OPT_TYPE_INT, {.i64 = 0}, 0, INT_MAX, AV_OPT_FLAG_ENCODING_PARAM},
98 { "ism_lookahead", "Number of lookahead entries for ISM files", offsetof(MOVMuxContext, ism_lookahead), AV_OPT_TYPE_INT, {.i64 = 0}, 0, 255, AV_OPT_FLAG_ENCODING_PARAM},
99 { "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},
100 { "brand", "Override major brand", offsetof(MOVMuxContext, major_brand), AV_OPT_TYPE_STRING, {.str = NULL}, .flags = AV_OPT_FLAG_ENCODING_PARAM },
101 { "use_editlist", "use edit list", offsetof(MOVMuxContext, use_editlist), AV_OPT_TYPE_BOOL, {.i64 = -1}, -1, 1, AV_OPT_FLAG_ENCODING_PARAM},
102 { "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},
103 { "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},
104 { "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 },
105 { "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 },
106 { "encryption_key", "The media encryption key (hex)", offsetof(MOVMuxContext, encryption_key), AV_OPT_TYPE_BINARY, .flags = AV_OPT_FLAG_ENCODING_PARAM },
107 { "encryption_kid", "The media encryption key identifier (hex)", offsetof(MOVMuxContext, encryption_kid), AV_OPT_TYPE_BINARY, .flags = AV_OPT_FLAG_ENCODING_PARAM },
108 { "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},
109 { "write_tmcd", "force or disable writing tmcd", offsetof(MOVMuxContext, write_tmcd), AV_OPT_TYPE_BOOL, {.i64 = -1}, -1, 1, AV_OPT_FLAG_ENCODING_PARAM},
110 { "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"},
111 { "wallclock", NULL, 0, AV_OPT_TYPE_CONST, {.i64 = MOV_PRFT_SRC_WALLCLOCK}, 0, 0, AV_OPT_FLAG_ENCODING_PARAM, "prft"},
112 { "pts", NULL, 0, AV_OPT_TYPE_CONST, {.i64 = MOV_PRFT_SRC_PTS}, 0, 0, AV_OPT_FLAG_ENCODING_PARAM, "prft"},
113 { "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},
114 { "movie_timescale", "set movie timescale", offsetof(MOVMuxContext, movie_timescale), AV_OPT_TYPE_INT, {.i64 = MOV_TIMESCALE}, 1, INT_MAX, AV_OPT_FLAG_ENCODING_PARAM},
115 { NULL },
116 };
117
118 static const AVClass mov_isobmff_muxer_class = {
119 .class_name = "mov/mp4/tgp/psp/tg2/ipod/ismv/f4v muxer",
120 .item_name = av_default_item_name,
121 .option = options,
122 .version = LIBAVUTIL_VERSION_INT,
123 };
124
125 static int get_moov_size(AVFormatContext *s);
126 static int mov_write_single_packet(AVFormatContext *s, AVPacket *pkt);
127
128 static int utf8len(const uint8_t *b)
129 {
130 int len = 0;
131 int val;
132 while (*b) {
133 GET_UTF8(val, *b++, return -1;)
134 len++;
135 }
136 return len;
137 }
138
139 //FIXME support 64 bit variant with wide placeholders
140 static int64_t update_size(AVIOContext *pb, int64_t pos)
141 {
142 int64_t curpos = avio_tell(pb);
143 avio_seek(pb, pos, SEEK_SET);
144 avio_wb32(pb, curpos - pos); /* rewrite size */
145 avio_seek(pb, curpos, SEEK_SET);
146
147 return curpos - pos;
148 }
149
150 static int co64_required(const MOVTrack *track)
151 {
152 if (track->entry > 0 && track->cluster[track->entry - 1].pos + track->data_offset > UINT32_MAX)
153 return 1;
154 return 0;
155 }
156
157 static int is_cover_image(const AVStream *st)
158 {
159 /* Eg. AV_DISPOSITION_ATTACHED_PIC | AV_DISPOSITION_TIMED_THUMBNAILS
160 * is encoded as sparse video track */
161 return st && st->disposition == AV_DISPOSITION_ATTACHED_PIC;
162 }
163
164 static int rtp_hinting_needed(const AVStream *st)
165 {
166 /* Add hint tracks for each real audio and video stream */
167 if (is_cover_image(st))
168 return 0;
169 return st->codecpar->codec_type == AVMEDIA_TYPE_VIDEO ||
170 st->codecpar->codec_type == AVMEDIA_TYPE_AUDIO;
171 }
172
173 /* Chunk offset atom */
174 static int mov_write_stco_tag(AVIOContext *pb, MOVTrack *track)
175 {
176 int i;
177 int mode64 = co64_required(track); // use 32 bit size variant if possible
178 int64_t pos = avio_tell(pb);
179 avio_wb32(pb, 0); /* size */
180 if (mode64)
181 ffio_wfourcc(pb, "co64");
182 else
183 ffio_wfourcc(pb, "stco");
184 avio_wb32(pb, 0); /* version & flags */
185 avio_wb32(pb, track->chunkCount); /* entry count */
186 for (i = 0; i < track->entry; i++) {
187 if (!track->cluster[i].chunkNum)
188 continue;
189 if (mode64 == 1)
190 avio_wb64(pb, track->cluster[i].pos + track->data_offset);
191 else
192 avio_wb32(pb, track->cluster[i].pos + track->data_offset);
193 }
194 return update_size(pb, pos);
195 }
196
197 /* Sample size atom */
198 static int mov_write_stsz_tag(AVIOContext *pb, MOVTrack *track)
199 {
200 int equalChunks = 1;
201 int i, j, entries = 0, tst = -1, oldtst = -1;
202
203 int64_t pos = avio_tell(pb);
204 avio_wb32(pb, 0); /* size */
205 ffio_wfourcc(pb, "stsz");
206 avio_wb32(pb, 0); /* version & flags */
207
208 for (i = 0; i < track->entry; i++) {
209 tst = track->cluster[i].size / track->cluster[i].entries;
210 if (oldtst != -1 && tst != oldtst)
211 equalChunks = 0;
212 oldtst = tst;
213 entries += track->cluster[i].entries;
214 }
215 if (equalChunks && track->entry) {
216 int sSize = track->entry ? track->cluster[0].size / track->cluster[0].entries : 0;
217 sSize = FFMAX(1, sSize); // adpcm mono case could make sSize == 0
218 avio_wb32(pb, sSize); // sample size
219 avio_wb32(pb, entries); // sample count
220 } else {
221 avio_wb32(pb, 0); // sample size
222 avio_wb32(pb, entries); // sample count
223 for (i = 0; i < track->entry; i++) {
224 for (j = 0; j < track->cluster[i].entries; j++) {
225 avio_wb32(pb, track->cluster[i].size /
226 track->cluster[i].entries);
227 }
228 }
229 }
230 return update_size(pb, pos);
231 }
232
233 /* Sample to chunk atom */
234 static int mov_write_stsc_tag(AVIOContext *pb, MOVTrack *track)
235 {
236 int index = 0, oldval = -1, i;
237 int64_t entryPos, curpos;
238
239 int64_t pos = avio_tell(pb);
240 avio_wb32(pb, 0); /* size */
241 ffio_wfourcc(pb, "stsc");
242 avio_wb32(pb, 0); // version & flags
243 entryPos = avio_tell(pb);
244 avio_wb32(pb, track->chunkCount); // entry count
245 for (i = 0; i < track->entry; i++) {
246 if (oldval != track->cluster[i].samples_in_chunk && track->cluster[i].chunkNum) {
247 avio_wb32(pb, track->cluster[i].chunkNum); // first chunk
248 avio_wb32(pb, track->cluster[i].samples_in_chunk); // samples per chunk
249 avio_wb32(pb, 0x1); // sample description index
250 oldval = track->cluster[i].samples_in_chunk;
251 index++;
252 }
253 }
254 curpos = avio_tell(pb);
255 avio_seek(pb, entryPos, SEEK_SET);
256 avio_wb32(pb, index); // rewrite size
257 avio_seek(pb, curpos, SEEK_SET);
258
259 return update_size(pb, pos);
260 }
261
262 /* Sync sample atom */
263 static int mov_write_stss_tag(AVIOContext *pb, MOVTrack *track, uint32_t flag)
264 {
265 int64_t curpos, entryPos;
266 int i, index = 0;
267 int64_t pos = avio_tell(pb);
268 avio_wb32(pb, 0); // size
269 ffio_wfourcc(pb, flag == MOV_SYNC_SAMPLE ? "stss" : "stps");
270 avio_wb32(pb, 0); // version & flags
271 entryPos = avio_tell(pb);
272 avio_wb32(pb, track->entry); // entry count
273 for (i = 0; i < track->entry; i++) {
274 if (track->cluster[i].flags & flag) {
275 avio_wb32(pb, i + 1);
276 index++;
277 }
278 }
279 curpos = avio_tell(pb);
280 avio_seek(pb, entryPos, SEEK_SET);
281 avio_wb32(pb, index); // rewrite size
282 avio_seek(pb, curpos, SEEK_SET);
283 return update_size(pb, pos);
284 }
285
286 /* Sample dependency atom */
287 static int mov_write_sdtp_tag(AVIOContext *pb, MOVTrack *track)
288 {
289 int i;
290 uint8_t leading, dependent, reference, redundancy;
291 int64_t pos = avio_tell(pb);
292 avio_wb32(pb, 0); // size
293 ffio_wfourcc(pb, "sdtp");
294 avio_wb32(pb, 0); // version & flags
295 for (i = 0; i < track->entry; i++) {
296 dependent = MOV_SAMPLE_DEPENDENCY_YES;
297 leading = reference = redundancy = MOV_SAMPLE_DEPENDENCY_UNKNOWN;
298 if (track->cluster[i].flags & MOV_DISPOSABLE_SAMPLE) {
299 reference = MOV_SAMPLE_DEPENDENCY_NO;
300 }
301 if (track->cluster[i].flags & MOV_SYNC_SAMPLE) {
302 dependent = MOV_SAMPLE_DEPENDENCY_NO;
303 }
304 avio_w8(pb, (leading << 6) | (dependent << 4) |
305 (reference << 2) | redundancy);
306 }
307 return update_size(pb, pos);
308 }
309
310 static int mov_write_amr_tag(AVIOContext *pb, MOVTrack *track)
311 {
312 avio_wb32(pb, 0x11); /* size */
313 if (track->mode == MODE_MOV) ffio_wfourcc(pb, "samr");
314 else ffio_wfourcc(pb, "damr");
315 ffio_wfourcc(pb, "FFMP");
316 avio_w8(pb, 0); /* decoder version */
317
318 avio_wb16(pb, 0x81FF); /* Mode set (all modes for AMR_NB) */
319 avio_w8(pb, 0x00); /* Mode change period (no restriction) */
320 avio_w8(pb, 0x01); /* Frames per sample */
321 return 0x11;
322 }
323
324 static int mov_write_ac3_tag(AVFormatContext *s, AVIOContext *pb, MOVTrack *track)
325 {
326 GetBitContext gbc;
327 PutBitContext pbc;
328 uint8_t buf[3];
329 int fscod, bsid, bsmod, acmod, lfeon, frmsizecod;
330
331 if (track->vos_len < 7) {
332 av_log(s, AV_LOG_ERROR,
333 "Cannot write moov atom before AC3 packets."
334 " Set the delay_moov flag to fix this.\n");
335 return AVERROR(EINVAL);
336 }
337
338 avio_wb32(pb, 11);
339 ffio_wfourcc(pb, "dac3");
340
341 init_get_bits(&gbc, track->vos_data + 4, (track->vos_len - 4) * 8);
342 fscod = get_bits(&gbc, 2);
343 frmsizecod = get_bits(&gbc, 6);
344 bsid = get_bits(&gbc, 5);
345 bsmod = get_bits(&gbc, 3);
346 acmod = get_bits(&gbc, 3);
347 if (acmod == 2) {
348 skip_bits(&gbc, 2); // dsurmod
349 } else {
350 if ((acmod & 1) && acmod != 1)
351 skip_bits(&gbc, 2); // cmixlev
352 if (acmod & 4)
353 skip_bits(&gbc, 2); // surmixlev
354 }
355 lfeon = get_bits1(&gbc);
356
357 init_put_bits(&pbc, buf, sizeof(buf));
358 put_bits(&pbc, 2, fscod);
359 put_bits(&pbc, 5, bsid);
360 put_bits(&pbc, 3, bsmod);
361 put_bits(&pbc, 3, acmod);
362 put_bits(&pbc, 1, lfeon);
363 put_bits(&pbc, 5, frmsizecod >> 1); // bit_rate_code
364 put_bits(&pbc, 5, 0); // reserved
365
366 flush_put_bits(&pbc);
367 avio_write(pb, buf, sizeof(buf));
368
369 return 11;
370 }
371
372 struct eac3_info {
373 AVPacket *pkt;
374 uint8_t ec3_done;
375 uint8_t num_blocks;
376
377 /* Layout of the EC3SpecificBox */
378 /* maximum bitrate */
379 uint16_t data_rate;
380 /* number of independent substreams */
381 uint8_t num_ind_sub;
382 struct {
383 /* sample rate code (see ff_ac3_sample_rate_tab) 2 bits */
384 uint8_t fscod;
385 /* bit stream identification 5 bits */
386 uint8_t bsid;
387 /* one bit reserved */
388 /* audio service mixing (not supported yet) 1 bit */
389 /* bit stream mode 3 bits */
390 uint8_t bsmod;
391 /* audio coding mode 3 bits */
392 uint8_t acmod;
393 /* sub woofer on 1 bit */
394 uint8_t lfeon;
395 /* 3 bits reserved */
396 /* number of dependent substreams associated with this substream 4 bits */
397 uint8_t num_dep_sub;
398 /* channel locations of the dependent substream(s), if any, 9 bits */
399 uint16_t chan_loc;
400 /* if there is no dependent substream, then one bit reserved instead */
401 } substream[1]; /* TODO: support 8 independent substreams */
402 };
403
404 #if CONFIG_AC3_PARSER
405 static int handle_eac3(MOVMuxContext *mov, AVPacket *pkt, MOVTrack *track)
406 {
407 AC3HeaderInfo *hdr = NULL;
408 struct eac3_info *info;
409 int num_blocks, ret;
410
411 if (!track->eac3_priv && !(track->eac3_priv = av_mallocz(sizeof(*info))))
412 return AVERROR(ENOMEM);
413 info = track->eac3_priv;
414
415 if (!info->pkt && !(info->pkt = av_packet_alloc()))
416 return AVERROR(ENOMEM);
417
418 if (avpriv_ac3_parse_header(&hdr, pkt->data, pkt->size) < 0) {
419 /* drop the packets until we see a good one */
420 if (!track->entry) {
421 av_log(mov->fc, AV_LOG_WARNING, "Dropping invalid packet from start of the stream\n");
422 ret = 0;
423 } else
424 ret = AVERROR_INVALIDDATA;
425 goto end;
426 }
427
428 info->data_rate = FFMAX(info->data_rate, hdr->bit_rate / 1000);
429 num_blocks = hdr->num_blocks;
430
431 if (!info->ec3_done) {
432 /* AC-3 substream must be the first one */
433 if (hdr->bitstream_id <= 10 && hdr->substreamid != 0) {
434 ret = AVERROR(EINVAL);
435 goto end;
436 }
437
438 /* this should always be the case, given that our AC-3 parser
439 * concatenates dependent frames to their independent parent */
440 if (hdr->frame_type == EAC3_FRAME_TYPE_INDEPENDENT) {
441 /* substream ids must be incremental */
442 if (hdr->substreamid > info->num_ind_sub + 1) {
443 ret = AVERROR(EINVAL);
444 goto end;
445 }
446
447 if (hdr->substreamid == info->num_ind_sub + 1) {
448 //info->num_ind_sub++;
449 avpriv_request_sample(mov->fc, "Multiple independent substreams");
450 ret = AVERROR_PATCHWELCOME;
451 goto end;
452 } else if (hdr->substreamid < info->num_ind_sub ||
453 hdr->substreamid == 0 && info->substream[0].bsid) {
454 info->ec3_done = 1;
455 goto concatenate;
456 }
457 } else {
458 if (hdr->substreamid != 0) {
459 avpriv_request_sample(mov->fc, "Multiple non EAC3 independent substreams");
460 ret = AVERROR_PATCHWELCOME;
461 goto end;
462 }
463 }
464
465 /* fill the info needed for the "dec3" atom */
466 info->substream[hdr->substreamid].fscod = hdr->sr_code;
467 info->substream[hdr->substreamid].bsid = hdr->bitstream_id;
468 info->substream[hdr->substreamid].bsmod = hdr->bitstream_mode;
469 info->substream[hdr->substreamid].acmod = hdr->channel_mode;
470 info->substream[hdr->substreamid].lfeon = hdr->lfe_on;
471
472 /* Parse dependent substream(s), if any */
473 if (pkt->size != hdr->frame_size) {
474 int cumul_size = hdr->frame_size;
475 int parent = hdr->substreamid;
476
477 while (cumul_size != pkt->size) {
478 GetBitContext gbc;
479 int i;
480 ret = avpriv_ac3_parse_header(&hdr, pkt->data + cumul_size, pkt->size - cumul_size);
481 if (ret < 0)
482 goto end;
483 if (hdr->frame_type != EAC3_FRAME_TYPE_DEPENDENT) {
484 ret = AVERROR(EINVAL);
485 goto end;
486 }
487 info->substream[parent].num_dep_sub++;
488 ret /= 8;
489
490 /* header is parsed up to lfeon, but custom channel map may be needed */
491 init_get_bits8(&gbc, pkt->data + cumul_size + ret, pkt->size - cumul_size - ret);
492 /* skip bsid */
493 skip_bits(&gbc, 5);
494 /* skip volume control params */
495 for (i = 0; i < (hdr->channel_mode ? 1 : 2); i++) {
496 skip_bits(&gbc, 5); // skip dialog normalization
497 if (get_bits1(&gbc)) {
498 skip_bits(&gbc, 8); // skip compression gain word
499 }
500 }
501 /* get the dependent stream channel map, if exists */
502 if (get_bits1(&gbc))
503 info->substream[parent].chan_loc |= (get_bits(&gbc, 16) >> 5) & 0x1f;
504 else
505 info->substream[parent].chan_loc |= hdr->channel_mode;
506 cumul_size += hdr->frame_size;
507 }
508 }
509 }
510
511 concatenate:
512 if (!info->num_blocks && num_blocks == 6) {
513 ret = pkt->size;
514 goto end;
515 }
516 else if (info->num_blocks + num_blocks > 6) {
517 ret = AVERROR_INVALIDDATA;
518 goto end;
519 }
520
521 if (!info->num_blocks) {
522 ret = av_packet_ref(info->pkt, pkt);
523 if (!ret)
524 info->num_blocks = num_blocks;
525 goto end;
526 } else {
527 if ((ret = av_grow_packet(info->pkt, pkt->size)) < 0)
528 goto end;
529 memcpy(info->pkt->data + info->pkt->size - pkt->size, pkt->data, pkt->size);
530 info->num_blocks += num_blocks;
531 info->pkt->duration += pkt->duration;
532 if (info->num_blocks != 6)
533 goto end;
534 av_packet_unref(pkt);
535 av_packet_move_ref(pkt, info->pkt);
536 info->num_blocks = 0;
537 }
538 ret = pkt->size;
539
540 end:
541 av_free(hdr);
542
543 return ret;
544 }
545 #endif
546
547 static int mov_write_eac3_tag(AVFormatContext *s, AVIOContext *pb, MOVTrack *track)
548 {
549 PutBitContext pbc;
550 uint8_t *buf;
551 struct eac3_info *info;
552 int size, i;
553
554 if (!track->eac3_priv) {
555 av_log(s, AV_LOG_ERROR,
556 "Cannot write moov atom before EAC3 packets parsed.\n");
557 return AVERROR(EINVAL);
558 }
559
560 info = track->eac3_priv;
561 size = 2 + ((34 * (info->num_ind_sub + 1) + 7) >> 3);
562 buf = av_malloc(size);
563 if (!buf) {
564 return AVERROR(ENOMEM);
565 }
566
567 init_put_bits(&pbc, buf, size);
568 put_bits(&pbc, 13, info->data_rate);
569 put_bits(&pbc, 3, info->num_ind_sub);
570 for (i = 0; i <= info->num_ind_sub; i++) {
571 put_bits(&pbc, 2, info->substream[i].fscod);
572 put_bits(&pbc, 5, info->substream[i].bsid);
573 put_bits(&pbc, 1, 0); /* reserved */
574 put_bits(&pbc, 1, 0); /* asvc */
575 put_bits(&pbc, 3, info->substream[i].bsmod);
576 put_bits(&pbc, 3, info->substream[i].acmod);
577 put_bits(&pbc, 1, info->substream[i].lfeon);
578 put_bits(&pbc, 5, 0); /* reserved */
579 put_bits(&pbc, 4, info->substream[i].num_dep_sub);
580 if (!info->substream[i].num_dep_sub) {
581 put_bits(&pbc, 1, 0); /* reserved */
582 } else {
583 put_bits(&pbc, 9, info->substream[i].chan_loc);
584 }
585 }
586 flush_put_bits(&pbc);
587 size = put_bytes_output(&pbc);
588
589 avio_wb32(pb, size + 8);
590 ffio_wfourcc(pb, "dec3");
591 avio_write(pb, buf, size);
592
593 av_free(buf);
594
595 return size;
596 }
597
598 /**
599 * This function writes extradata "as is".
600 * Extradata must be formatted like a valid atom (with size and tag).
601 */
602 static int mov_write_extradata_tag(AVIOContext *pb, MOVTrack *track)
603 {
604 avio_write(pb, track->par->extradata, track->par->extradata_size);
605 return track->par->extradata_size;
606 }
607
608 static int mov_write_enda_tag(AVIOContext *pb)
609 {
610 avio_wb32(pb, 10);
611 ffio_wfourcc(pb, "enda");
612 avio_wb16(pb, 1); /* little endian */
613 return 10;
614 }
615
616 static int mov_write_enda_tag_be(AVIOContext *pb)
617 {
618 avio_wb32(pb, 10);
619 ffio_wfourcc(pb, "enda");
620 avio_wb16(pb, 0); /* big endian */
621 return 10;
622 }
623
624 static void put_descr(AVIOContext *pb, int tag, unsigned int size)
625 {
626 int i = 3;
627 avio_w8(pb, tag);
628 for (; i > 0; i--)
629 avio_w8(pb, (size >> (7 * i)) | 0x80);
630 avio_w8(pb, size & 0x7F);
631 }
632
633 static unsigned compute_avg_bitrate(MOVTrack *track)
634 {
635 uint64_t size = 0;
636 int i;
637 if (!track->track_duration)
638 return 0;
639 for (i = 0; i < track->entry; i++)
640 size += track->cluster[i].size;
641 return size * 8 * track->timescale / track->track_duration;
642 }
643
644 struct mpeg4_bit_rate_values {
645 uint32_t buffer_size; ///< Size of the decoding buffer for the elementary stream in bytes.
646 uint32_t max_bit_rate; ///< Maximum rate in bits/second over any window of one second.
647 uint32_t avg_bit_rate; ///< Average rate in bits/second over the entire presentation.
648 };
649
650 static struct mpeg4_bit_rate_values calculate_mpeg4_bit_rates(MOVTrack *track)
651 {
652 AVCPBProperties *props = track->st ?
653 (AVCPBProperties*)av_stream_get_side_data(track->st,
654 AV_PKT_DATA_CPB_PROPERTIES,
655 NULL) :
656 NULL;
657 struct mpeg4_bit_rate_values bit_rates = { 0 };
658
659 bit_rates.avg_bit_rate = compute_avg_bitrate(track);
660 if (!bit_rates.avg_bit_rate) {
661 // if the average bit rate cannot be calculated at this point, such as
662 // in the case of fragmented MP4, utilize the following values as
663 // fall-back in priority order:
664 //
665 // 1. average bit rate property
666 // 2. bit rate (usually average over the whole clip)
667 // 3. maximum bit rate property
668
669 if (props && props->avg_bitrate) {
670 bit_rates.avg_bit_rate = props->avg_bitrate;
671 } else if (track->par->bit_rate) {
672 bit_rates.avg_bit_rate = track->par->bit_rate;
673 } else if (props && props->max_bitrate) {
674 bit_rates.avg_bit_rate = props->max_bitrate;
675 }
676 }
677
678 // (FIXME should be max rate in any 1 sec window)
679 bit_rates.max_bit_rate = FFMAX(track->par->bit_rate,
680 bit_rates.avg_bit_rate);
681
682 // utilize values from properties if we have them available
683 if (props) {
684 bit_rates.max_bit_rate = FFMAX(bit_rates.max_bit_rate,
685 props->max_bitrate);
686 bit_rates.buffer_size = props->buffer_size / 8;
687 }
688
689 return bit_rates;
690 }
691
692 static int mov_write_esds_tag(AVIOContext *pb, MOVTrack *track) // Basic
693 {
694 struct mpeg4_bit_rate_values bit_rates = calculate_mpeg4_bit_rates(track);
695 int64_t pos = avio_tell(pb);
696 int decoder_specific_info_len = track->vos_len ? 5 + track->vos_len : 0;
697
698 avio_wb32(pb, 0); // size
699 ffio_wfourcc(pb, "esds");
700 avio_wb32(pb, 0); // Version
701
702 // ES descriptor
703 put_descr(pb, 0x03, 3 + 5+13 + decoder_specific_info_len + 5+1);
704 avio_wb16(pb, track->track_id);
705 avio_w8(pb, 0x00); // flags (= no flags)
706
707 // DecoderConfig descriptor
708 put_descr(pb, 0x04, 13 + decoder_specific_info_len);
709
710 // Object type indication
711 if ((track->par->codec_id == AV_CODEC_ID_MP2 ||
712 track->par->codec_id == AV_CODEC_ID_MP3) &&
713 track->par->sample_rate > 24000)
714 avio_w8(pb, 0x6B); // 11172-3
715 else
716 avio_w8(pb, ff_codec_get_tag(ff_mp4_obj_type, track->par->codec_id));
717
718 // the following fields is made of 6 bits to identify the streamtype (4 for video, 5 for audio)
719 // plus 1 bit to indicate upstream and 1 bit set to 1 (reserved)
720 if (track->par->codec_id == AV_CODEC_ID_DVD_SUBTITLE)
721 avio_w8(pb, (0x38 << 2) | 1); // flags (= NeroSubpicStream)
722 else if (track->par->codec_type == AVMEDIA_TYPE_AUDIO)
723 avio_w8(pb, 0x15); // flags (= Audiostream)
724 else
725 avio_w8(pb, 0x11); // flags (= Visualstream)
726
727 avio_wb24(pb, bit_rates.buffer_size); // Buffersize DB
728 avio_wb32(pb, bit_rates.max_bit_rate); // maxbitrate
729 avio_wb32(pb, bit_rates.avg_bit_rate);
730
731 if (track->vos_len) {
732 // DecoderSpecific info descriptor
733 put_descr(pb, 0x05, track->vos_len);
734 avio_write(pb, track->vos_data, track->vos_len);
735 }
736
737 // SL descriptor
738 put_descr(pb, 0x06, 1);
739 avio_w8(pb, 0x02);
740 return update_size(pb, pos);
741 }
742
743 static int mov_pcm_le_gt16(enum AVCodecID codec_id)
744 {
745 return codec_id == AV_CODEC_ID_PCM_S24LE ||
746 codec_id == AV_CODEC_ID_PCM_S32LE ||
747 codec_id == AV_CODEC_ID_PCM_F32LE ||
748 codec_id == AV_CODEC_ID_PCM_F64LE;
749 }
750
751 static int mov_pcm_be_gt16(enum AVCodecID codec_id)
752 {
753 return codec_id == AV_CODEC_ID_PCM_S24BE ||
754 codec_id == AV_CODEC_ID_PCM_S32BE ||
755 codec_id == AV_CODEC_ID_PCM_F32BE ||
756 codec_id == AV_CODEC_ID_PCM_F64BE;
757 }
758
759 static int mov_write_ms_tag(AVFormatContext *s, AVIOContext *pb, MOVTrack *track)
760 {
761 int ret;
762 int64_t pos = avio_tell(pb);
763 avio_wb32(pb, 0);
764 avio_wl32(pb, track->tag); // store it byteswapped
765 track->par->codec_tag = av_bswap16(track->tag >> 16);
766 if ((ret = ff_put_wav_header(s, pb, track->par, 0)) < 0)
767 return ret;
768 return update_size(pb, pos);
769 }
770
771 static int mov_write_wfex_tag(AVFormatContext *s, AVIOContext *pb, MOVTrack *track)
772 {
773 int ret;
774 int64_t pos = avio_tell(pb);
775 avio_wb32(pb, 0);
776 ffio_wfourcc(pb, "wfex");
777 if ((ret = ff_put_wav_header(s, pb, track->st->codecpar, FF_PUT_WAV_HEADER_FORCE_WAVEFORMATEX)) < 0)
778 return ret;
779 return update_size(pb, pos);
780 }
781
782 static int mov_write_dfla_tag(AVIOContext *pb, MOVTrack *track)
783 {
784 int64_t pos = avio_tell(pb);
785 avio_wb32(pb, 0);
786 ffio_wfourcc(pb, "dfLa");
787 avio_w8(pb, 0); /* version */
788 avio_wb24(pb, 0); /* flags */
789
790 /* Expect the encoder to pass a METADATA_BLOCK_TYPE_STREAMINFO. */
791 if (track->par->extradata_size != FLAC_STREAMINFO_SIZE)
792 return AVERROR_INVALIDDATA;
793
794 /* TODO: Write other METADATA_BLOCK_TYPEs if the encoder makes them available. */
795 avio_w8(pb, 1 << 7 | FLAC_METADATA_TYPE_STREAMINFO); /* LastMetadataBlockFlag << 7 | BlockType */
796 avio_wb24(pb, track->par->extradata_size); /* Length */
797 avio_write(pb, track->par->extradata, track->par->extradata_size); /* BlockData[Length] */
798
799 return update_size(pb, pos);
800 }
801
802 static int mov_write_dops_tag(AVFormatContext *s, AVIOContext *pb, MOVTrack *track)
803 {
804 int64_t pos = avio_tell(pb);
805 int channels, channel_map;
806 avio_wb32(pb, 0);
807 ffio_wfourcc(pb, "dOps");
808 avio_w8(pb, 0); /* Version */
809 if (track->par->extradata_size < 19) {
810 av_log(s, AV_LOG_ERROR, "invalid extradata size\n");
811 return AVERROR_INVALIDDATA;
812 }
813 /* extradata contains an Ogg OpusHead, other than byte-ordering and
814 OpusHead's preceeding magic/version, OpusSpecificBox is currently
815 identical. */
816 channels = AV_RB8(track->par->extradata + 9);
817 channel_map = AV_RB8(track->par->extradata + 18);
818
819 avio_w8(pb, channels); /* OuputChannelCount */
820 avio_wb16(pb, AV_RL16(track->par->extradata + 10)); /* PreSkip */
821 avio_wb32(pb, AV_RL32(track->par->extradata + 12)); /* InputSampleRate */
822 avio_wb16(pb, AV_RL16(track->par->extradata + 16)); /* OutputGain */
823 avio_w8(pb, channel_map); /* ChannelMappingFamily */
824 /* Write the rest of the header out without byte-swapping. */
825 if (channel_map) {
826 if (track->par->extradata_size < 21 + channels) {
827 av_log(s, AV_LOG_ERROR, "invalid extradata size\n");
828 return AVERROR_INVALIDDATA;
829 }
830 avio_write(pb, track->par->extradata + 19, 2 + channels); /* ChannelMappingTable */
831 }
832
833 return update_size(pb, pos);
834 }
835
836 static int mov_write_dmlp_tag(AVFormatContext *s, AVIOContext *pb, MOVTrack *track)
837 {
838 int64_t pos = avio_tell(pb);
839 int length;
840 avio_wb32(pb, 0);
841 ffio_wfourcc(pb, "dmlp");
842
843 if (track->vos_len < 20) {
844 av_log(s, AV_LOG_ERROR,
845 "Cannot write moov atom before TrueHD packets."
846 " Set the delay_moov flag to fix this.\n");
847 return AVERROR(EINVAL);
848 }
849
850 length = (AV_RB16(track->vos_data) & 0xFFF) * 2;
851 if (length < 20 || length > track->vos_len)
852 return AVERROR_INVALIDDATA;
853
854 // Only TrueHD is supported
855 if (AV_RB32(track->vos_data + 4) != 0xF8726FBA)
856 return AVERROR_INVALIDDATA;
857
858 avio_wb32(pb, AV_RB32(track->vos_data + 8)); /* format_info */
859 avio_wb16(pb, AV_RB16(track->vos_data + 18) << 1); /* peak_data_rate */
860 avio_wb32(pb, 0); /* reserved */
861
862 return update_size(pb, pos);
863 }
864
865 static int mov_write_chan_tag(AVFormatContext *s, AVIOContext *pb, MOVTrack *track)
866 {
867 uint32_t layout_tag, bitmap;
868 int64_t pos = avio_tell(pb);
869
870 layout_tag = ff_mov_get_channel_layout_tag(track->par->codec_id,
871 track->par->channel_layout,
872 &bitmap);
873 if (!layout_tag) {
874 av_log(s, AV_LOG_WARNING, "not writing 'chan' tag due to "
875 "lack of channel information\n");
876 return 0;
877 }
878
879 if (track->multichannel_as_mono)
880 return 0;
881
882 avio_wb32(pb, 0); // Size
883 ffio_wfourcc(pb, "chan"); // Type
884 avio_w8(pb, 0); // Version
885 avio_wb24(pb, 0); // Flags
886 avio_wb32(pb, layout_tag); // mChannelLayoutTag
887 avio_wb32(pb, bitmap); // mChannelBitmap
888 avio_wb32(pb, 0); // mNumberChannelDescriptions
889
890 return update_size(pb, pos);
891 }
892
893 static int mov_write_wave_tag(AVFormatContext *s, AVIOContext *pb, MOVTrack *track)
894 {
895 int64_t pos = avio_tell(pb);
896
897 avio_wb32(pb, 0); /* size */
898 ffio_wfourcc(pb, "wave");
899
900 if (track->par->codec_id != AV_CODEC_ID_QDM2) {
901 avio_wb32(pb, 12); /* size */
902 ffio_wfourcc(pb, "frma");
903 avio_wl32(pb, track->tag);
904 }
905
906 if (track->par->codec_id == AV_CODEC_ID_AAC) {
907 /* useless atom needed by mplayer, ipod, not needed by quicktime */
908 avio_wb32(pb, 12); /* size */
909 ffio_wfourcc(pb, "mp4a");
910 avio_wb32(pb, 0);
911 mov_write_esds_tag(pb, track);
912 } else if (mov_pcm_le_gt16(track->par->codec_id)) {
913 mov_write_enda_tag(pb);
914 } else if (mov_pcm_be_gt16(track->par->codec_id)) {
915 mov_write_enda_tag_be(pb);
916 } else if (track->par->codec_id == AV_CODEC_ID_AMR_NB) {
917 mov_write_amr_tag(pb, track);
918 } else if (track->par->codec_id == AV_CODEC_ID_AC3) {
919 mov_write_ac3_tag(s, pb, track);
920 } else if (track->par->codec_id == AV_CODEC_ID_EAC3) {
921 mov_write_eac3_tag(s, pb, track);
922 } else if (track->par->codec_id == AV_CODEC_ID_ALAC ||
923 track->par->codec_id == AV_CODEC_ID_QDM2) {
924 mov_write_extradata_tag(pb, track);
925 } else if (track->par->codec_id == AV_CODEC_ID_ADPCM_MS ||
926 track->par->codec_id == AV_CODEC_ID_ADPCM_IMA_WAV) {
927 mov_write_ms_tag(s, pb, track);
928 }
929
930 avio_wb32(pb, 8); /* size */
931 avio_wb32(pb, 0); /* null tag */
932
933 return update_size(pb, pos);
934 }
935
936 static int mov_write_dvc1_structs(MOVTrack *track, uint8_t *buf)
937 {
938 uint8_t *unescaped;
939 const uint8_t *start, *next, *end = track->vos_data + track->vos_len;
940 int unescaped_size, seq_found = 0;
941 int level = 0, interlace = 0;
942 int packet_seq = track->vc1_info.packet_seq;
943 int packet_entry = track->vc1_info.packet_entry;
944 int slices = track->vc1_info.slices;
945 PutBitContext pbc;
946
947 if (track->start_dts == AV_NOPTS_VALUE) {
948 /* No packets written yet, vc1_info isn't authoritative yet. */
949 /* Assume inline sequence and entry headers. */
950 packet_seq = packet_entry = 1;
951 av_log(NULL, AV_LOG_WARNING,
952 "moov atom written before any packets, unable to write correct "
953 "dvc1 atom. Set the delay_moov flag to fix this.\n");
954 }
955
956 unescaped = av_mallocz(track->vos_len + AV_INPUT_BUFFER_PADDING_SIZE);
957 if (!unescaped)
958 return AVERROR(ENOMEM);
959 start = find_next_marker(track->vos_data, end);
960 for (next = start; next < end; start = next) {
961 GetBitContext gb;
962 int size;
963 next = find_next_marker(start + 4, end);
964 size = next - start - 4;
965 if (size <= 0)
966 continue;
967 unescaped_size = vc1_unescape_buffer(start + 4, size, unescaped);
968 init_get_bits(&gb, unescaped, 8 * unescaped_size);
969 if (AV_RB32(start) == VC1_CODE_SEQHDR) {
970 int profile = get_bits(&gb, 2);
971 if (profile != PROFILE_ADVANCED) {
972 av_free(unescaped);
973 return AVERROR(ENOSYS);
974 }
975 seq_found = 1;
976 level = get_bits(&gb, 3);
977 /* chromaformat, frmrtq_postproc, bitrtq_postproc, postprocflag,
978 * width, height */
979 skip_bits_long(&gb, 2 + 3 + 5 + 1 + 2*12);
980 skip_bits(&gb, 1); /* broadcast */
981 interlace = get_bits1(&gb);
982 skip_bits(&gb, 4); /* tfcntrflag, finterpflag, reserved, psf */
983 }
984 }
985 if (!seq_found) {
986 av_free(unescaped);
987 return AVERROR(ENOSYS);
988 }
989
990 init_put_bits(&pbc, buf, 7);
991 /* VC1DecSpecStruc */
992 put_bits(&pbc, 4, 12); /* profile - advanced */
993 put_bits(&pbc, 3, level);
994 put_bits(&pbc, 1, 0); /* reserved */
995 /* VC1AdvDecSpecStruc */
996 put_bits(&pbc, 3, level);
997 put_bits(&pbc, 1, 0); /* cbr */
998 put_bits(&pbc, 6, 0); /* reserved */
999 put_bits(&pbc, 1, !interlace); /* no interlace */
1000 put_bits(&pbc, 1, !packet_seq); /* no multiple seq */
1001 put_bits(&pbc, 1, !packet_entry); /* no multiple entry */
1002 put_bits(&pbc, 1, !slices); /* no slice code */
1003 put_bits(&pbc, 1, 0); /* no bframe */
1004 put_bits(&pbc, 1, 0); /* reserved */
1005
1006 /* framerate */
1007 if (track->st->avg_frame_rate.num > 0 && track->st->avg_frame_rate.den > 0)
1008 put_bits32(&pbc, track->st->avg_frame_rate.num / track->st->avg_frame_rate.den);
1009 else
1010 put_bits32(&pbc, 0xffffffff);
1011
1012 flush_put_bits(&pbc);
1013
1014 av_free(unescaped);
1015
1016 return 0;
1017 }
1018
1019 static int mov_write_dvc1_tag(AVIOContext *pb, MOVTrack *track)
1020 {
1021 uint8_t buf[7] = { 0 };
1022 int ret;
1023
1024 if ((ret = mov_write_dvc1_structs(track, buf)) < 0)
1025 return ret;
1026
1027 avio_wb32(pb, track->vos_len + 8 + sizeof(buf));
1028 ffio_wfourcc(pb, "dvc1");
1029 avio_write(pb, buf, sizeof(buf));
1030 avio_write(pb, track->vos_data, track->vos_len);
1031
1032 return 0;
1033 }
1034
1035 static int mov_write_glbl_tag(AVIOContext *pb, MOVTrack *track)
1036 {
1037 avio_wb32(pb, track->vos_len + 8);
1038 ffio_wfourcc(pb, "glbl");
1039 avio_write(pb, track->vos_data, track->vos_len);
1040 return 8 + track->vos_len;
1041 }
1042
1043 /**
1044 * Compute flags for 'lpcm' tag.
1045 * See CoreAudioTypes and AudioStreamBasicDescription at Apple.
1046 */
1047 static int mov_get_lpcm_flags(enum AVCodecID codec_id)
1048 {
1049 switch (codec_id) {
1050 case AV_CODEC_ID_PCM_F32BE:
1051 case AV_CODEC_ID_PCM_F64BE:
1052 return 11;
1053 case AV_CODEC_ID_PCM_F32LE:
1054 case AV_CODEC_ID_PCM_F64LE:
1055 return 9;
1056 case AV_CODEC_ID_PCM_U8:
1057 return 10;
1058 case AV_CODEC_ID_PCM_S16BE:
1059 case AV_CODEC_ID_PCM_S24BE:
1060 case AV_CODEC_ID_PCM_S32BE:
1061 return 14;
1062 case AV_CODEC_ID_PCM_S8:
1063 case AV_CODEC_ID_PCM_S16LE:
1064 case AV_CODEC_ID_PCM_S24LE:
1065 case AV_CODEC_ID_PCM_S32LE:
1066 return 12;
1067 default:
1068 return 0;
1069 }
1070 }
1071
1072 static int get_cluster_duration(MOVTrack *track, int cluster_idx)
1073 {
1074 int64_t next_dts;
1075
1076 if (cluster_idx >= track->entry)
1077 return 0;
1078
1079 if (cluster_idx + 1 == track->entry)
1080 next_dts = track->track_duration + track->start_dts;
1081 else
1082 next_dts = track->cluster[cluster_idx + 1].dts;
1083
1084 next_dts -= track->cluster[cluster_idx].dts;
1085
1086 av_assert0(next_dts >= 0);
1087 av_assert0(next_dts <= INT_MAX);
1088
1089 return next_dts;
1090 }
1091
1092 static int get_samples_per_packet(MOVTrack *track)
1093 {
1094 int i, first_duration;
1095
1096 // return track->par->frame_size;
1097
1098 /* use 1 for raw PCM */
1099 if (!track->audio_vbr)
1100 return 1;
1101
1102 /* check to see if duration is constant for all clusters */
1103 if (!track->entry)
1104 return 0;
1105 first_duration = get_cluster_duration(track, 0);
1106 for (i = 1; i < track->entry; i++) {
1107 if (get_cluster_duration(track, i) != first_duration)
1108 return 0;
1109 }
1110 return first_duration;
1111 }
1112
1113 static int mov_write_btrt_tag(AVIOContext *pb, MOVTrack *track)
1114 {
1115 int64_t pos = avio_tell(pb);
1116 struct mpeg4_bit_rate_values bit_rates = calculate_mpeg4_bit_rates(track);
1117 if (!bit_rates.max_bit_rate && !bit_rates.avg_bit_rate &&
1118 !bit_rates.buffer_size)
1119 // no useful data to be written, skip
1120 return 0;
1121
1122 avio_wb32(pb, 0); /* size */
1123 ffio_wfourcc(pb, "btrt");
1124
1125 avio_wb32(pb, bit_rates.buffer_size);
1126 avio_wb32(pb, bit_rates.max_bit_rate);
1127 avio_wb32(pb, bit_rates.avg_bit_rate);
1128
1129 return update_size(pb, pos);
1130 }
1131
1132 static int mov_write_audio_tag(AVFormatContext *s, AVIOContext *pb, MOVMuxContext *mov, MOVTrack *track)
1133 {
1134 int64_t pos = avio_tell(pb);
1135 int version = 0;
1136 uint32_t tag = track->tag;
1137 int ret = 0;
1138
1139 if (track->mode == MODE_MOV) {
1140 if (track->timescale > UINT16_MAX || !track->par->channels) {
1141 if (mov_get_lpcm_flags(track->par->codec_id))
1142 tag = AV_RL32("lpcm");
1143 version = 2;
1144 } else if (track->audio_vbr || mov_pcm_le_gt16(track->par->codec_id) ||
1145 mov_pcm_be_gt16(track->par->codec_id) ||
1146 track->par->codec_id == AV_CODEC_ID_ADPCM_MS ||
1147 track->par->codec_id == AV_CODEC_ID_ADPCM_IMA_WAV ||
1148 track->par->codec_id == AV_CODEC_ID_QDM2) {
1149 version = 1;
1150 }
1151 }
1152
1153 avio_wb32(pb, 0); /* size */
1154 if (mov->encryption_scheme != MOV_ENC_NONE) {
1155 ffio_wfourcc(pb, "enca");
1156 } else {
1157 avio_wl32(pb, tag); // store it byteswapped
1158 }
1159 avio_wb32(pb, 0); /* Reserved */
1160 avio_wb16(pb, 0); /* Reserved */
1161 avio_wb16(pb, 1); /* Data-reference index, XXX == 1 */
1162
1163 /* SoundDescription */
1164 avio_wb16(pb, version); /* Version */
1165 avio_wb16(pb, 0); /* Revision level */
1166 avio_wb32(pb, 0); /* Reserved */
1167
1168 if (version == 2) {
1169 avio_wb16(pb, 3);
1170 avio_wb16(pb, 16);
1171 avio_wb16(pb, 0xfffe);
1172 avio_wb16(pb, 0);
1173 avio_wb32(pb, 0x00010000);
1174 avio_wb32(pb, 72);
1175 avio_wb64(pb, av_double2int(track->par->sample_rate));
1176 avio_wb32(pb, track->par->channels);
1177 avio_wb32(pb, 0x7F000000);
1178 avio_wb32(pb, av_get_bits_per_sample(track->par->codec_id));
1179 avio_wb32(pb, mov_get_lpcm_flags(track->par->codec_id));
1180 avio_wb32(pb, track->sample_size);
1181 avio_wb32(pb, get_samples_per_packet(track));
1182 } else {
1183 if (track->mode == MODE_MOV) {
1184 avio_wb16(pb, track->par->channels);
1185 if (track->par->codec_id == AV_CODEC_ID_PCM_U8 ||
1186 track->par->codec_id == AV_CODEC_ID_PCM_S8)
1187 avio_wb16(pb, 8); /* bits per sample */
1188 else if (track->par->codec_id == AV_CODEC_ID_ADPCM_G726)
1189 avio_wb16(pb, track->par->bits_per_coded_sample);
1190 else
1191 avio_wb16(pb, 16);
1192 avio_wb16(pb, track->audio_vbr ? -2 : 0); /* compression ID */
1193 } else { /* reserved for mp4/3gp */
1194 if (track->par->codec_id == AV_CODEC_ID_FLAC ||
1195 track->par->codec_id == AV_CODEC_ID_ALAC ||
1196 track->par->codec_id == AV_CODEC_ID_OPUS) {
1197 avio_wb16(pb, track->par->channels);
1198 } else {
1199 avio_wb16(pb, 2);
1200 }
1201 if (track->par->codec_id == AV_CODEC_ID_FLAC ||
1202 track->par->codec_id == AV_CODEC_ID_ALAC) {
1203 avio_wb16(pb, track->par->bits_per_raw_sample);
1204 } else {
1205 avio_wb16(pb, 16);
1206 }
1207 avio_wb16(pb, 0);
1208 }
1209
1210 avio_wb16(pb, 0); /* packet size (= 0) */
1211 if (track->par->codec_id == AV_CODEC_ID_OPUS)
1212 avio_wb16(pb, 48000);
1213 else if (track->par->codec_id == AV_CODEC_ID_TRUEHD)
1214 avio_wb32(pb, track->par->sample_rate);
1215 else
1216 avio_wb16(pb, track->par->sample_rate <= UINT16_MAX ?
1217 track->par->sample_rate : 0);
1218
1219 if (track->par->codec_id != AV_CODEC_ID_TRUEHD)
1220 avio_wb16(pb, 0); /* Reserved */
1221 }
1222
1223 if (version == 1) { /* SoundDescription V1 extended info */
1224 if (mov_pcm_le_gt16(track->par->codec_id) ||
1225 mov_pcm_be_gt16(track->par->codec_id))
1226 avio_wb32(pb, 1); /* must be 1 for uncompressed formats */
1227 else
1228 avio_wb32(pb, track->par->frame_size); /* Samples per packet */
1229 avio_wb32(pb, track->sample_size / track->par->channels); /* Bytes per packet */
1230 avio_wb32(pb, track->sample_size); /* Bytes per frame */
1231 avio_wb32(pb, 2); /* Bytes per sample */
1232 }
1233
1234 if (track->mode == MODE_MOV &&
1235 (track->par->codec_id == AV_CODEC_ID_AAC ||
1236 track->par->codec_id == AV_CODEC_ID_AC3 ||
1237 track->par->codec_id == AV_CODEC_ID_EAC3 ||
1238 track->par->codec_id == AV_CODEC_ID_AMR_NB ||
1239 track->par->codec_id == AV_CODEC_ID_ALAC ||
1240 track->par->codec_id == AV_CODEC_ID_ADPCM_MS ||
1241 track->par->codec_id == AV_CODEC_ID_ADPCM_IMA_WAV ||
1242 track->par->codec_id == AV_CODEC_ID_QDM2 ||
1243 (mov_pcm_le_gt16(track->par->codec_id) && version==1) ||
1244 (mov_pcm_be_gt16(track->par->codec_id) && version==1)))
1245 ret = mov_write_wave_tag(s, pb, track);
1246 else if (track->tag == MKTAG('m','p','4','a'))
1247 ret = mov_write_esds_tag(pb, track);
1248 else if (track->par->codec_id == AV_CODEC_ID_AMR_NB)
1249 ret = mov_write_amr_tag(pb, track);
1250 else if (track->par->codec_id == AV_CODEC_ID_AC3)
1251 ret = mov_write_ac3_tag(s, pb, track);
1252 else if (track->par->codec_id == AV_CODEC_ID_EAC3)
1253 ret = mov_write_eac3_tag(s, pb, track);
1254 else if (track->par->codec_id == AV_CODEC_ID_ALAC)
1255 ret = mov_write_extradata_tag(pb, track);
1256 else if (track->par->codec_id == AV_CODEC_ID_WMAPRO)
1257 ret = mov_write_wfex_tag(s, pb, track);
1258 else if (track->par->codec_id == AV_CODEC_ID_FLAC)
1259 ret = mov_write_dfla_tag(pb, track);
1260 else if (track->par->codec_id == AV_CODEC_ID_OPUS)
1261 ret = mov_write_dops_tag(s, pb, track);
1262 else if (track->par->codec_id == AV_CODEC_ID_TRUEHD)
1263 ret = mov_write_dmlp_tag(s, pb, track);
1264 else if (track->vos_len > 0)
1265 ret = mov_write_glbl_tag(pb, track);
1266
1267 if (ret < 0)
1268 return ret;
1269
1270 if (track->mode == MODE_MOV && track->par->codec_type == AVMEDIA_TYPE_AUDIO
1271 && ((ret = mov_write_chan_tag(s, pb, track)) < 0)) {
1272 return ret;
1273 }
1274
1275 if (mov->encryption_scheme != MOV_ENC_NONE
1276 && ((ret = ff_mov_cenc_write_sinf_tag(track, pb, mov->encryption_kid)) < 0)) {
1277 return ret;
1278 }
1279
1280 if (track->mode == MODE_MP4 &&
1281 ((ret = mov_write_btrt_tag(pb, track)) < 0))
1282 return ret;
1283
1284 ret = update_size(pb, pos);
1285 return ret;
1286 }
1287
1288 static int mov_write_d263_tag(AVIOContext *pb)
1289 {
1290 avio_wb32(pb, 0xf); /* size */
1291 ffio_wfourcc(pb, "d263");
1292 ffio_wfourcc(pb, "FFMP");
1293 avio_w8(pb, 0); /* decoder version */
1294 /* FIXME use AVCodecContext level/profile, when encoder will set values */
1295 avio_w8(pb, 0xa); /* level */
1296 avio_w8(pb, 0); /* profile */
1297 return 0xf;
1298 }
1299
1300 static int mov_write_av1c_tag(AVIOContext *pb, MOVTrack *track)
1301 {
1302 int64_t pos = avio_tell(pb);
1303
1304 avio_wb32(pb, 0);
1305 ffio_wfourcc(pb, "av1C");
1306 ff_isom_write_av1c(pb, track->vos_data, track->vos_len);
1307 return update_size(pb, pos);
1308 }
1309
1310 static int mov_write_avcc_tag(AVIOContext *pb, MOVTrack *track)
1311 {
1312 int64_t pos = avio_tell(pb);
1313
1314 avio_wb32(pb, 0);
1315 ffio_wfourcc(pb, "avcC");
1316 ff_isom_write_avcc(pb, track->vos_data, track->vos_len);
1317 return update_size(pb, pos);
1318 }
1319
1320 static int mov_write_vpcc_tag(AVFormatContext *s, AVIOContext *pb, MOVTrack *track)
1321 {
1322 int64_t pos = avio_tell(pb);
1323
1324 avio_wb32(pb, 0);
1325 ffio_wfourcc(pb, "vpcC");
1326 avio_w8(pb, 1); /* version */
1327 avio_wb24(pb, 0); /* flags */
1328 ff_isom_write_vpcc(s, pb, track->par);
1329 return update_size(pb, pos);
1330 }
1331
1332 static int mov_write_hvcc_tag(AVIOContext *pb, MOVTrack *track)
1333 {
1334 int64_t pos = avio_tell(pb);
1335
1336 avio_wb32(pb, 0);
1337 ffio_wfourcc(pb, "hvcC");
1338 if (track->tag == MKTAG('h','v','c','1'))
1339 ff_isom_write_hvcc(pb, track->vos_data, track->vos_len, 1);
1340 else
1341 ff_isom_write_hvcc(pb, track->vos_data, track->vos_len, 0);
1342 return update_size(pb, pos);
1343 }
1344
1345 /* also used by all avid codecs (dv, imx, meridien) and their variants */
1346 static int mov_write_avid_tag(AVIOContext *pb, MOVTrack *track)
1347 {
1348 int interlaced;
1349 int cid;
1350 int display_width = track->par->width;
1351
1352 if (track->vos_data && track->vos_len > 0x29) {
1353 if (ff_dnxhd_parse_header_prefix(track->vos_data) != 0) {
1354 /* looks like a DNxHD bit stream */
1355 interlaced = (track->vos_data[5] & 2);
1356 cid = AV_RB32(track->vos_data + 0x28);
1357 } else {
1358 av_log(NULL, AV_LOG_WARNING, "Could not locate DNxHD bit stream in vos_data\n");
1359 return 0;
1360 }
1361 } else {
1362 av_log(NULL, AV_LOG_WARNING, "Could not locate DNxHD bit stream, vos_data too small\n");
1363 return 0;
1364 }
1365
1366 avio_wb32(pb, 24); /* size */
1367 ffio_wfourcc(pb, "ACLR");
1368 ffio_wfourcc(pb, "ACLR");
1369 ffio_wfourcc(pb, "0001");
1370 if (track->par->color_range == AVCOL_RANGE_MPEG || /* Legal range (16-235) */
1371 track->par->color_range == AVCOL_RANGE_UNSPECIFIED) {
1372 avio_wb32(pb, 1); /* Corresponds to 709 in official encoder */
1373 } else { /* Full range (0-255) */
1374 avio_wb32(pb, 2); /* Corresponds to RGB in official encoder */
1375 }
1376 avio_wb32(pb, 0); /* unknown */
1377
1378 if (track->tag == MKTAG('A','V','d','h')) {
1379 avio_wb32(pb, 32);
1380 ffio_wfourcc(pb, "ADHR");
1381 ffio_wfourcc(pb, "0001");
1382 avio_wb32(pb, cid);
1383 avio_wb32(pb, 0); /* unknown */
1384 avio_wb32(pb, 1); /* unknown */
1385 avio_wb32(pb, 0); /* unknown */
1386 avio_wb32(pb, 0); /* unknown */
1387 return 0;
1388 }
1389
1390 avio_wb32(pb, 24); /* size */
1391 ffio_wfourcc(pb, "APRG");
1392 ffio_wfourcc(pb, "APRG");
1393 ffio_wfourcc(pb, "0001");
1394 avio_wb32(pb, 1); /* unknown */
1395 avio_wb32(pb, 0); /* unknown */
1396
1397 avio_wb32(pb, 120); /* size */
1398 ffio_wfourcc(pb, "ARES");
1399 ffio_wfourcc(pb, "ARES");
1400 ffio_wfourcc(pb, "0001");
1401 avio_wb32(pb, cid); /* dnxhd cid, some id ? */
1402 if ( track->par->sample_aspect_ratio.num > 0
1403 && track->par->sample_aspect_ratio.den > 0)
1404 display_width = display_width * track->par->sample_aspect_ratio.num / track->par->sample_aspect_ratio.den;
1405 avio_wb32(pb, display_width);
1406 /* values below are based on samples created with quicktime and avid codecs */
1407 if (interlaced) {
1408 avio_wb32(pb, track->par->height / 2);
1409 avio_wb32(pb, 2); /* unknown */
1410 avio_wb32(pb, 0); /* unknown */
1411 avio_wb32(pb, 4); /* unknown */
1412 } else {
1413 avio_wb32(pb, track->par->height);
1414 avio_wb32(pb, 1); /* unknown */
1415 avio_wb32(pb, 0); /* unknown */
1416 if (track->par->height == 1080)
1417 avio_wb32(pb, 5); /* unknown */
1418 else
1419 avio_wb32(pb, 6); /* unknown */
1420 }
1421 /* padding */
1422 ffio_fill(pb, 0, 10 * 8);
1423
1424 return 0;
1425 }
1426
1427 static int mov_write_dpxe_tag(AVIOContext *pb, MOVTrack *track)
1428 {
1429 avio_wb32(pb, 12);
1430 ffio_wfourcc(pb, "DpxE");
1431 if (track->par->extradata_size >= 12 &&
1432 !memcmp(&track->par->extradata[4], "DpxE", 4)) {
1433 avio_wb32(pb, track->par->extradata[11]);
1434 } else {
1435 avio_wb32(pb, 1);
1436 }
1437 return 0;
1438 }
1439
1440 static int mov_get_dv_codec_tag(AVFormatContext *s, MOVTrack *track)
1441 {
1442 int tag;
1443
1444 if (track->par->width == 720) { /* SD */
1445 if (track->par->height == 480) { /* NTSC */
1446 if (track->par->format == AV_PIX_FMT_YUV422P) tag = MKTAG('d','v','5','n');
1447 else tag = MKTAG('d','v','c',' ');
1448 }else if (track->par->format == AV_PIX_FMT_YUV422P) tag = MKTAG('d','v','5','p');
1449 else if (track->par->format == AV_PIX_FMT_YUV420P) tag = MKTAG('d','v','c','p');
1450 else tag = MKTAG('d','v','p','p');
1451 } else if (track->par->height == 720) { /* HD 720 line */
1452 if (track->st->time_base.den == 50) tag = MKTAG('d','v','h','q');
1453 else tag = MKTAG('d','v','h','p');
1454 } else if (track->par->height == 1080) { /* HD 1080 line */
1455 if (track->st->time_base.den == 25) tag = MKTAG('d','v','h','5');
1456 else tag = MKTAG('d','v','h','6');
1457 } else {
1458 av_log(s, AV_LOG_ERROR, "unsupported height for dv codec\n");
1459 return 0;
1460 }
1461
1462 return tag;
1463 }
1464
1465 static int defined_frame_rate(AVFormatContext *s, AVStream *st)
1466 {
1467 AVRational rational_framerate = st->avg_frame_rate;
1468 int rate = 0;
1469 if (rational_framerate.den != 0)
1470 rate = av_q2d(rational_framerate);
1471 return rate;
1472 }
1473
1474 static int mov_get_mpeg2_xdcam_codec_tag(AVFormatContext *s, MOVTrack *track)
1475 {
1476 int tag = track->par->codec_tag;
1477 int interlaced = track->par->field_order > AV_FIELD_PROGRESSIVE;
1478 AVStream *st = track->st;
1479 int rate = defined_frame_rate(s, st);
1480
1481 if (!tag)
1482 tag = MKTAG('m', '2', 'v', '1'); //fallback tag
1483
1484 if (track->par->format == AV_PIX_FMT_YUV420P) {
1485 if (track->par->width == 1280 && track->par->height == 720) {
1486 if (!interlaced) {
1487 if (rate == 24) tag = MKTAG('x','d','v','4');
1488 else if (rate == 25) tag = MKTAG('x','d','v','5');
1489 else if (rate == 30) tag = MKTAG('x','d','v','1');
1490 else if (rate == 50) tag = MKTAG('x','d','v','a');
1491 else if (rate == 60) tag = MKTAG('x','d','v','9');
1492 }
1493 } else if (track->par->width == 1440 && track->par->height == 1080) {
1494 if (!interlaced) {
1495 if (rate == 24) tag = MKTAG('x','d','v','6');
1496 else if (rate == 25) tag = MKTAG('x','d','v','7');
1497 else if (rate == 30) tag = MKTAG('x','d','v','8');
1498 } else {
1499 if (rate == 25) tag = MKTAG('x','d','v','3');
1500 else if (rate == 30) tag = MKTAG('x','d','v','2');
1501 }
1502 } else if (track->par->width == 1920 && track->par->height == 1080) {
1503 if (!interlaced) {
1504 if (rate == 24) tag = MKTAG('x','d','v','d');
1505 else if (rate == 25) tag = MKTAG('x','d','v','e');
1506 else if (rate == 30) tag = MKTAG('x','d','v','f');
1507 } else {
1508 if (rate == 25) tag = MKTAG('x','d','v','c');
1509 else if (rate == 30) tag = MKTAG('x','d','v','b');
1510 }
1511 }
1512 } else if (track->par->format == AV_PIX_FMT_YUV422P) {
1513 if (track->par->width == 1280 && track->par->height == 720) {
1514 if (!interlaced) {
1515 if (rate == 24) tag = MKTAG('x','d','5','4');
1516 else if (rate == 25) tag = MKTAG('x','d','5','5');
1517 else if (rate == 30) tag = MKTAG('x','d','5','1');
1518 else if (rate == 50) tag = MKTAG('x','d','5','a');
1519 else if (rate == 60) tag = MKTAG('x','d','5','9');
1520 }
1521 } else if (track->par->width == 1920 && track->par->height == 1080) {
1522 if (!interlaced) {
1523 if (rate == 24) tag = MKTAG('x','d','5','d');
1524 else if (rate == 25) tag = MKTAG('x','d','5','e');
1525 else if (rate == 30) tag = MKTAG('x','d','5','f');
1526 } else {
1527 if (rate == 25) tag = MKTAG('x','d','5','c');
1528 else if (rate == 30) tag = MKTAG('x','d','5','b');
1529 }
1530 }
1531 }
1532
1533 return tag;
1534 }
1535
1536 static int mov_get_h264_codec_tag(AVFormatContext *s, MOVTrack *track)
1537 {
1538 int tag = track->par->codec_tag;
1539 int interlaced = track->par->field_order > AV_FIELD_PROGRESSIVE;
1540 AVStream *st = track->st;
1541 int rate = defined_frame_rate(s, st);
1542
1543 if (!tag)
1544 tag = MKTAG('a', 'v', 'c', 'i'); //fallback tag
1545
1546 if (track->par->format == AV_PIX_FMT_YUV420P10) {
1547 if (track->par->width == 960 && track->par->height == 720) {
1548 if (!interlaced) {
1549 if (rate == 24) tag = MKTAG('a','i','5','p');
1550 else if (rate == 25) tag = MKTAG('a','i','5','q');
1551 else if (rate == 30) tag = MKTAG('a','i','5','p');
1552 else if (rate == 50) tag = MKTAG('a','i','5','q');
1553 else if (rate == 60) tag = MKTAG('a','i','5','p');
1554 }
1555 } else if (track->par->width == 1440 && track->par->height == 1080) {
1556 if (!interlaced) {
1557 if (rate == 24) tag = MKTAG('a','i','5','3');
1558 else if (rate == 25) tag = MKTAG('a','i','5','2');
1559 else if (rate == 30) tag = MKTAG('a','i','5','3');
1560 } else {
1561 if (rate == 50) tag = MKTAG('a','i','5','5');
1562 else if (rate == 60) tag = MKTAG('a','i','5','6');
1563 }
1564 }
1565 } else if (track->par->format == AV_PIX_FMT_YUV422P10) {
1566 if (track->par->width == 1280 && track->par->height == 720) {
1567 if (!interlaced) {
1568 if (rate == 24) tag = MKTAG('a','i','1','p');
1569 else if (rate == 25) tag = MKTAG('a','i','1','q');
1570 else if (rate == 30) tag = MKTAG('a','i','1','p');
1571 else if (rate == 50) tag = MKTAG('a','i','1','q');
1572 else if (rate == 60) tag = MKTAG('a','i','1','p');
1573 }
1574 } else if (track->par->width == 1920 && track->par->height == 1080) {
1575 if (!interlaced) {
1576 if (rate == 24) tag = MKTAG('a','i','1','3');
1577 else if (rate == 25) tag = MKTAG('a','i','1','2');
1578 else if (rate == 30) tag = MKTAG('a','i','1','3');
1579 } else {
1580 if (rate == 25) tag = MKTAG('a','i','1','5');
1581 else if (rate == 50) tag = MKTAG('a','i','1','5');
1582 else if (rate == 60) tag = MKTAG('a','i','1','6');
1583 }
1584 } else if ( track->par->width == 4096 && track->par->height == 2160
1585 || track->par->width == 3840 && track->par->height == 2160
1586 || track->par->width == 2048 && track->par->height == 1080) {
1587 tag = MKTAG('a','i','v','x');
1588 }
1589 }
1590
1591 return tag;
1592 }
1593
1594 static const struct {
1595 enum AVPixelFormat pix_fmt;
1596 uint32_t tag;
1597 unsigned bps;
1598 } mov_pix_fmt_tags[] = {
1599 { AV_PIX_FMT_YUYV422, MKTAG('y','u','v','2'), 0 },
1600 { AV_PIX_FMT_YUYV422, MKTAG('y','u','v','s'), 0 },
1601 { AV_PIX_FMT_UYVY422, MKTAG('2','v','u','y'), 0 },
1602 { AV_PIX_FMT_RGB555BE,MKTAG('r','a','w',' '), 16 },
1603 { AV_PIX_FMT_RGB555LE,MKTAG('L','5','5','5'), 16 },
1604 { AV_PIX_FMT_RGB565LE,MKTAG('L','5','6','5'), 16 },
1605 { AV_PIX_FMT_RGB565BE,MKTAG('B','5','6','5'), 16 },
1606 { AV_PIX_FMT_GRAY16BE,MKTAG('b','1','6','g'), 16 },
1607 { AV_PIX_FMT_RGB24, MKTAG('r','a','w',' '), 24 },
1608 { AV_PIX_FMT_BGR24, MKTAG('2','4','B','G'), 24 },
1609 { AV_PIX_FMT_ARGB, MKTAG('r','a','w',' '), 32 },
1610 { AV_PIX_FMT_BGRA, MKTAG('B','G','R','A'), 32 },
1611 { AV_PIX_FMT_RGBA, MKTAG('R','G','B','A'), 32 },
1612 { AV_PIX_FMT_ABGR, MKTAG('A','B','G','R'), 32 },
1613 { AV_PIX_FMT_RGB48BE, MKTAG('b','4','8','r'), 48 },
1614 };
1615
1616 static int mov_get_dnxhd_codec_tag(AVFormatContext *s, MOVTrack *track)
1617 {
1618 int tag = MKTAG('A','V','d','n');
1619 if (track->par->profile != FF_PROFILE_UNKNOWN &&
1620 track->par->profile != FF_PROFILE_DNXHD)
1621 tag = MKTAG('A','V','d','h');
1622 return tag;
1623 }
1624
1625 static int mov_get_rawvideo_codec_tag(AVFormatContext *s, MOVTrack *track)
1626 {
1627 int tag = track->par->codec_tag;
1628 int i;
1629 enum AVPixelFormat pix_fmt;
1630
1631 for (i = 0; i < FF_ARRAY_ELEMS(mov_pix_fmt_tags); i++) {
1632 if (track->par->format == mov_pix_fmt_tags[i].pix_fmt) {
1633 tag = mov_pix_fmt_tags[i].tag;
1634 track->par->bits_per_coded_sample = mov_pix_fmt_tags[i].bps;
1635 if (track->par->codec_tag == mov_pix_fmt_tags[i].tag)
1636 break;
1637 }
1638 }
1639
1640 pix_fmt = avpriv_pix_fmt_find(PIX_FMT_LIST_MOV,
1641 track->par->bits_per_coded_sample);
1642 if (tag == MKTAG('r','a','w',' ') &&
1643 track->par->format != pix_fmt &&
1644 track->par->format != AV_PIX_FMT_GRAY8 &&
1645 track->par->format != AV_PIX_FMT_NONE)
1646 av_log(s, AV_LOG_ERROR, "%s rawvideo cannot be written to mov, output file will be unreadable\n",
1647 av_get_pix_fmt_name(track->par->format));
1648 return tag;
1649 }
1650
1651 static unsigned int mov_get_codec_tag(AVFormatContext *s, MOVTrack *track)
1652 {
1653 unsigned int tag = track->par->codec_tag;
1654
1655 // "rtp " is used to distinguish internally created RTP-hint tracks
1656 // (with rtp_ctx) from other tracks.
1657 if (tag == MKTAG('r','t','p',' '))
1658 tag = 0;
1659 if (!tag || (s->strict_std_compliance >= FF_COMPLIANCE_NORMAL &&
1660 (track->par->codec_id == AV_CODEC_ID_DVVIDEO ||
1661 track->par->codec_id == AV_CODEC_ID_RAWVIDEO ||
1662 track->par->codec_id == AV_CODEC_ID_H263 ||
1663 track->par->codec_id == AV_CODEC_ID_H264 ||
1664 track->par->codec_id == AV_CODEC_ID_DNXHD ||
1665 track->par->codec_id == AV_CODEC_ID_MPEG2VIDEO ||
1666 av_get_bits_per_sample(track->par->codec_id)))) { // pcm audio
1667 if (track->par->codec_id == AV_CODEC_ID_DVVIDEO)
1668 tag = mov_get_dv_codec_tag(s, track);
1669 else if (track->par->codec_id == AV_CODEC_ID_RAWVIDEO)
1670 tag = mov_get_rawvideo_codec_tag(s, track);
1671 else if (track->par->codec_id == AV_CODEC_ID_MPEG2VIDEO)
1672 tag = mov_get_mpeg2_xdcam_codec_tag(s, track);
1673 else if (track->par->codec_id == AV_CODEC_ID_H264)
1674 tag = mov_get_h264_codec_tag(s, track);
1675 else if (track->par->codec_id == AV_CODEC_ID_DNXHD)
1676 tag = mov_get_dnxhd_codec_tag(s, track);
1677 else if (track->par->codec_type == AVMEDIA_TYPE_VIDEO) {
1678 tag = ff_codec_get_tag(ff_codec_movvideo_tags, track->par->codec_id);
1679 if (!tag) { // if no mac fcc found, try with Microsoft tags
1680 tag = ff_codec_get_tag(ff_codec_bmp_tags, track->par->codec_id);
1681 if (tag)
1682 av_log(s, AV_LOG_WARNING, "Using MS style video codec tag, "
1683 "the file may be unplayable!\n");
1684 }
1685 } else if (track->par->codec_type == AVMEDIA_TYPE_AUDIO) {
1686 tag = ff_codec_get_tag(ff_codec_movaudio_tags, track->par->codec_id);
1687 if (!tag) { // if no mac fcc found, try with Microsoft tags
1688 int ms_tag = ff_codec_get_tag(ff_codec_wav_tags, track->par->codec_id);
1689 if (ms_tag) {
1690 tag = MKTAG('m', 's', ((ms_tag >> 8) & 0xff), (ms_tag & 0xff));
1691 av_log(s, AV_LOG_WARNING, "Using MS style audio codec tag, "
1692 "the file may be unplayable!\n");
1693 }
1694 }
1695 } else if (track->par->codec_type == AVMEDIA_TYPE_SUBTITLE)
1696 tag = ff_codec_get_tag(ff_codec_movsubtitle_tags, track->par->codec_id);
1697 }
1698
1699 return tag;
1700 }
1701
1702 static const AVCodecTag codec_cover_image_tags[] = {
1703 { AV_CODEC_ID_MJPEG, 0xD },
1704 { AV_CODEC_ID_PNG, 0xE },
1705 { AV_CODEC_ID_BMP, 0x1B },
1706 { AV_CODEC_ID_NONE, 0 },
1707 };
1708
1709 static unsigned int validate_codec_tag(const AVCodecTag *const *tags,
1710 unsigned int tag, int codec_id)
1711 {
1712 int i;
1713
1714 /**
1715 * Check that tag + id is in the table
1716 */
1717 for (i = 0; tags && tags[i]; i++) {
1718 const AVCodecTag *codec_tags = tags[i];
1719 while (codec_tags->id != AV_CODEC_ID_NONE) {
1720 if (ff_toupper4(codec_tags->tag) == ff_toupper4(tag) &&
1721 codec_tags->id == codec_id)
1722 return codec_tags->tag;
1723 codec_tags++;
1724 }
1725 }
1726 return 0;
1727 }
1728
1729 static unsigned int mov_find_codec_tag(AVFormatContext *s, MOVTrack *track)
1730 {
1731 if (is_cover_image(track->st))
1732 return ff_codec_get_tag(codec_cover_image_tags, track->par->codec_id);
1733
1734 if (track->mode == MODE_IPOD)
1735 if (!av_match_ext(s->url, "m4a") &&
1736 !av_match_ext(s->url, "m4v") &&
1737 !av_match_ext(s->url, "m4b"))
1738 av_log(s, AV_LOG_WARNING, "Warning, extension is not .m4a nor .m4v "
1739 "Quicktime/Ipod might not play the file\n");
1740
1741 if (track->mode == MODE_MOV) {
1742 return mov_get_codec_tag(s, track);
1743 } else
1744 return validate_codec_tag(s->oformat->codec_tag, track->par->codec_tag,
1745 track->par->codec_id);
1746 }
1747
1748 /** Write uuid atom.
1749 * Needed to make file play in iPods running newest firmware
1750 * goes after avcC atom in moov.trak.mdia.minf.stbl.stsd.avc1
1751 */
1752 static int mov_write_uuid_tag_ipod(AVIOContext *pb)
1753 {
1754 avio_wb32(pb, 28);
1755 ffio_wfourcc(pb, "uuid");
1756 avio_wb32(pb, 0x6b6840f2);
1757 avio_wb32(pb, 0x5f244fc5);
1758 avio_wb32(pb, 0xba39a51b);
1759 avio_wb32(pb, 0xcf0323f3);
1760 avio_wb32(pb, 0x0);
1761 return 28;
1762 }
1763
1764 static const uint16_t fiel_data[] = {
1765 0x0000, 0x0100, 0x0201, 0x0206, 0x0209, 0x020e
1766 };
1767
1768 static int mov_write_fiel_tag(AVIOContext *pb, MOVTrack *track, int field_order)
1769 {
1770 unsigned mov_field_order = 0;
1771 if (field_order < FF_ARRAY_ELEMS(fiel_data))
1772 mov_field_order = fiel_data[field_order];
1773 else
1774 return 0;
1775 avio_wb32(pb, 10);
1776 ffio_wfourcc(pb, "fiel");
1777 avio_wb16(pb, mov_field_order);
1778 return 10;
1779 }
1780
1781 static int mov_write_subtitle_tag(AVIOContext *pb, MOVTrack *track)
1782 {
1783 int ret = AVERROR_BUG;
1784 int64_t pos = avio_tell(pb);
1785 avio_wb32(pb, 0); /* size */
1786 avio_wl32(pb, track->tag); // store it byteswapped
1787 avio_wb32(pb, 0); /* Reserved */
1788 avio_wb16(pb, 0); /* Reserved */
1789 avio_wb16(pb, 1); /* Data-reference index */
1790
1791 if (track->par->codec_id == AV_CODEC_ID_DVD_SUBTITLE)
1792 mov_write_esds_tag(pb, track);
1793 else if (track->par->codec_id == AV_CODEC_ID_TTML) {
1794 switch (track->par->codec_tag) {
1795 case MOV_ISMV_TTML_TAG:
1796 // ISMV dfxp requires no extradata.
1797 break;
1798 case MOV_MP4_TTML_TAG:
1799 // As specified in 14496-30, XMLSubtitleSampleEntry
1800 // Namespace
1801 avio_put_str(pb, "http://www.w3.org/ns/ttml");
1802 // Empty schema_location
1803 avio_w8(pb, 0);
1804 // Empty auxiliary_mime_types
1805 avio_w8(pb, 0);
1806 break;
1807 default:
1808 av_log(NULL, AV_LOG_ERROR,
1809 "Unknown codec tag '%s' utilized for TTML stream with "
1810 "index %d (track id %d)!\n",
1811 av_fourcc2str(track->par->codec_tag), track->st->index,
1812 track->track_id);
1813 return AVERROR(EINVAL);
1814 }
1815 } else if (track->par->extradata_size)
1816 avio_write(pb, track->par->extradata, track->par->extradata_size);
1817
1818 if (track->mode == MODE_MP4 &&
1819 ((ret = mov_write_btrt_tag(pb, track)) < 0))
1820 return ret;
1821
1822 return update_size(pb, pos);
1823 }
1824
1825 static int mov_write_st3d_tag(AVFormatContext *s, AVIOContext *pb, AVStereo3D *stereo_3d)
1826 {
1827 int8_t stereo_mode;
1828
1829 if (stereo_3d->flags != 0) {
1830 av_log(s, AV_LOG_WARNING, "Unsupported stereo_3d flags %x. st3d not written.\n", stereo_3d->flags);
1831 return 0;
1832 }
1833
1834 switch (stereo_3d->type) {
1835 case AV_STEREO3D_2D:
1836 stereo_mode = 0;
1837 break;
1838 case AV_STEREO3D_TOPBOTTOM:
1839 stereo_mode = 1;
1840 break;
1841 case AV_STEREO3D_SIDEBYSIDE:
1842 stereo_mode = 2;
1843 break;
1844 default:
1845 av_log(s, AV_LOG_WARNING, "Unsupported stereo_3d type %s. st3d not written.\n", av_stereo3d_type_name(stereo_3d->type));
1846 return 0;
1847 }
1848 avio_wb32(pb, 13); /* size */
1849 ffio_wfourcc(pb, "st3d");
1850 avio_wb32(pb, 0); /* version = 0 & flags = 0 */
1851 avio_w8(pb, stereo_mode);
1852 return 13;
1853 }
1854
1855 static int mov_write_sv3d_tag(AVFormatContext *s, AVIOContext *pb, AVSphericalMapping *spherical_mapping)
1856 {
1857 int64_t sv3d_pos, svhd_pos, proj_pos;
1858 const char* metadata_source = s->flags & AVFMT_FLAG_BITEXACT ? "Lavf" : LIBAVFORMAT_IDENT;
1859
1860 if (spherical_mapping->projection != AV_SPHERICAL_EQUIRECTANGULAR &&
1861 spherical_mapping->projection != AV_SPHERICAL_EQUIRECTANGULAR_TILE &&
1862 spherical_mapping->projection != AV_SPHERICAL_CUBEMAP) {
1863 av_log(s, AV_LOG_WARNING, "Unsupported projection %d. sv3d not written.\n", spherical_mapping->projection);
1864 return 0;
1865 }
1866
1867 sv3d_pos = avio_tell(pb);
1868 avio_wb32(pb, 0); /* size */
1869 ffio_wfourcc(pb, "sv3d");
1870
1871 svhd_pos = avio_tell(pb);
1872 avio_wb32(pb, 0); /* size */
1873 ffio_wfourcc(pb, "svhd");
1874 avio_wb32(pb, 0); /* version = 0 & flags = 0 */
1875 avio_put_str(pb, metadata_source);
1876 update_size(pb, svhd_pos);
1877
1878 proj_pos = avio_tell(pb);
1879 avio_wb32(pb, 0); /* size */
1880 ffio_wfourcc(pb, "proj");
1881
1882 avio_wb32(pb, 24); /* size */
1883 ffio_wfourcc(pb, "prhd");
1884 avio_wb32(pb, 0); /* version = 0 & flags = 0 */
1885 avio_wb32(pb, spherical_mapping->yaw);
1886 avio_wb32(pb, spherical_mapping->pitch);
1887 avio_wb32(pb, spherical_mapping->roll);
1888
1889 switch (spherical_mapping->projection) {
1890 case AV_SPHERICAL_EQUIRECTANGULAR:
1891 case AV_SPHERICAL_EQUIRECTANGULAR_TILE:
1892 avio_wb32(pb, 28); /* size */
1893 ffio_wfourcc(pb, "equi");
1894 avio_wb32(pb, 0); /* version = 0 & flags = 0 */
1895 avio_wb32(pb, spherical_mapping->bound_top);
1896 avio_wb32(pb, spherical_mapping->bound_bottom);
1897 avio_wb32(pb, spherical_mapping->bound_left);
1898 avio_wb32(pb, spherical_mapping->bound_right);
1899 break;
1900 case AV_SPHERICAL_CUBEMAP:
1901 avio_wb32(pb, 20); /* size */
1902 ffio_wfourcc(pb, "cbmp");
1903 avio_wb32(pb, 0); /* version = 0 & flags = 0 */
1904 avio_wb32(pb, 0); /* layout */
1905 avio_wb32(pb, spherical_mapping->padding); /* padding */
1906 break;
1907 }
1908 update_size(pb, proj_pos);
1909
1910 return update_size(pb, sv3d_pos);
1911 }
1912
1913 static int mov_write_dvcc_dvvc_tag(AVFormatContext *s, AVIOContext *pb, AVDOVIDecoderConfigurationRecord *dovi)
1914 {
1915 uint8_t buf[ISOM_DVCC_DVVC_SIZE];
1916
1917 avio_wb32(pb, 32); /* size = 8 + 24 */
1918 if (dovi->dv_profile > 10)
1919 ffio_wfourcc(pb, "dvwC");
1920 else if (dovi->dv_profile > 7)
1921 ffio_wfourcc(pb, "dvvC");
1922 else
1923 ffio_wfourcc(pb, "dvcC");
1924
1925 ff_isom_put_dvcc_dvvc(s, buf, dovi);
1926 avio_write(pb, buf, sizeof(buf));
1927
1928 return 32; /* 8 + 24 */
1929 }
1930
1931 static int mov_write_clap_tag(AVIOContext *pb, MOVTrack *track)
1932 {
1933 avio_wb32(pb, 40);
1934 ffio_wfourcc(pb, "clap");
1935 avio_wb32(pb, track->par->width); /* apertureWidth_N */
1936 avio_wb32(pb, 1); /* apertureWidth_D (= 1) */
1937 avio_wb32(pb, track->height); /* apertureHeight_N */
1938 avio_wb32(pb, 1); /* apertureHeight_D (= 1) */
1939 avio_wb32(pb, 0); /* horizOff_N (= 0) */
1940 avio_wb32(pb, 1); /* horizOff_D (= 1) */
1941 avio_wb32(pb, 0); /* vertOff_N (= 0) */
1942 avio_wb32(pb, 1); /* vertOff_D (= 1) */
1943 return 40;
1944 }
1945
1946 static int mov_write_pasp_tag(AVIOContext *pb, MOVTrack *track)
1947 {
1948 AVRational sar;
1949 av_reduce(&sar.num, &sar.den, track->par->sample_aspect_ratio.num,
1950 track->par->sample_aspect_ratio.den, INT_MAX);
1951
1952 avio_wb32(pb, 16);
1953 ffio_wfourcc(pb, "pasp");
1954 avio_wb32(pb, sar.num);
1955 avio_wb32(pb, sar.den);
1956 return 16;
1957 }
1958
1959 static int mov_write_gama_tag(AVFormatContext *s, AVIOContext *pb, MOVTrack *track, double gamma)
1960 {
1961 uint32_t gama = 0;
1962 if (gamma <= 0.0) {
1963 gamma = avpriv_get_gamma_from_trc(track->par->color_trc);
1964 }
1965 av_log(s, AV_LOG_DEBUG, "gamma value %g\n", gamma);
1966
1967 if (gamma > 1e-6) {
1968 gama = (uint32_t)lrint((double)(1<<16) * gamma);
1969 av_log(s, AV_LOG_DEBUG, "writing gama value %"PRId32"\n", gama);
1970
1971 av_assert0(track->mode == MODE_MOV);
1972 avio_wb32(pb, 12);
1973 ffio_wfourcc(pb, "gama");
1974 avio_wb32(pb, gama);
1975 return 12;
1976 } else {
1977 av_log(s, AV_LOG_WARNING, "gamma value unknown, unable to write gama atom\n");
1978 }
1979 return 0;
1980 }
1981
1982 static int mov_write_colr_tag(AVIOContext *pb, MOVTrack *track, int prefer_icc)
1983 {
1984 int64_t pos = avio_tell(pb);
1985
1986 // Ref (MOV): https://developer.apple.com/library/mac/technotes/tn2162/_index.html#//apple_ref/doc/uid/DTS40013070-CH1-TNTAG9
1987 // Ref (MP4): ISO/IEC 14496-12:2012
1988
1989 const uint8_t *icc_profile;
1990 size_t icc_profile_size;
1991
1992 if (prefer_icc) {
1993 icc_profile = av_stream_get_side_data(track->st, AV_PKT_DATA_ICC_PROFILE, &icc_profile_size);
1994
1995 if (icc_profile) {
1996 avio_wb32(pb, 12 + icc_profile_size);
1997 ffio_wfourcc(pb, "colr");
1998 ffio_wfourcc(pb, "prof");
1999 avio_write(pb, icc_profile, icc_profile_size);
2000 return 12 + icc_profile_size;
2001 }
2002 else {
2003 av_log(NULL, AV_LOG_INFO, "no ICC profile found, will write nclx/nclc colour info instead\n");
2004 }
2005 }
2006
2007 /* We should only ever be called by MOV or MP4. */
2008 av_assert0(track->mode == MODE_MOV || track->mode == MODE_MP4);
2009
2010 avio_wb32(pb, 0); /* size */
2011 ffio_wfourcc(pb, "colr");
2012 if (track->mode == MODE_MP4)
2013 ffio_wfourcc(pb, "nclx");
2014 else
2015 ffio_wfourcc(pb, "nclc");
2016 // Do not try to guess the color info if it is AVCOL_PRI_UNSPECIFIED.
2017 // e.g., Dolby Vision for Apple devices should be set to AVCOL_PRI_UNSPECIFIED. See
2018 // https://developer.apple.com/av-foundation/High-Dynamic-Range-Metadata-for-Apple-Devices.pdf
2019 avio_wb16(pb, track->par->color_primaries);
2020 avio_wb16(pb, track->par->color_trc);
2021 avio_wb16(pb, track->par->color_space);
2022 if (track->mode == MODE_MP4) {
2023 int full_range = track->par->color_range == AVCOL_RANGE_JPEG;
2024 avio_w8(pb, full_range << 7);
2025 }
2026
2027 return update_size(pb, pos);
2028 }
2029
2030 static int mov_write_clli_tag(AVIOContext *pb, MOVTrack *track)
2031 {
2032 const uint8_t *side_data;
2033 const AVContentLightMetadata *content_light_metadata;
2034
2035 side_data = av_stream_get_side_data(track->st, AV_PKT_DATA_CONTENT_LIGHT_LEVEL, NULL);
2036 if (!side_data) {
2037 return 0;
2038 }
2039 content_light_metadata = (const AVContentLightMetadata*)side_data;
2040
2041 avio_wb32(pb, 12); // size
2042 ffio_wfourcc(pb, "clli");
2043 avio_wb16(pb, content_light_metadata->MaxCLL);
2044 avio_wb16(pb, content_light_metadata->MaxFALL);
2045 return 12;
2046 }
2047
2048 static inline int64_t rescale_mdcv(AVRational q, int b)
2049 {
2050 return av_rescale(q.num, b, q.den);
2051 }
2052
2053 static int mov_write_mdcv_tag(AVIOContext *pb, MOVTrack *track)
2054 {
2055 const int chroma_den = 50000;
2056 const int luma_den = 10000;
2057 const uint8_t *side_data;
2058 const AVMasteringDisplayMetadata *metadata;
2059
2060 side_data = av_stream_get_side_data(track->st, AV_PKT_DATA_MASTERING_DISPLAY_METADATA, NULL);
2061 metadata = (const AVMasteringDisplayMetadata*)side_data;
2062 if (!metadata || !metadata->has_primaries || !metadata->has_luminance) {
2063 return 0;
2064 }
2065
2066 avio_wb32(pb, 32); // size
2067 ffio_wfourcc(pb, "mdcv");
2068 avio_wb16(pb, rescale_mdcv(metadata->display_primaries[1][0], chroma_den));
2069 avio_wb16(pb, rescale_mdcv(metadata->display_primaries[1][1], chroma_den));
2070 avio_wb16(pb, rescale_mdcv(metadata->display_primaries[2][0], chroma_den));
2071 avio_wb16(pb, rescale_mdcv(metadata->display_primaries[2][1], chroma_den));
2072 avio_wb16(pb, rescale_mdcv(metadata->display_primaries[0][0], chroma_den));
2073 avio_wb16(pb, rescale_mdcv(metadata->display_primaries[0][1], chroma_den));
2074 avio_wb16(pb, rescale_mdcv(metadata->white_point[0], chroma_den));
2075 avio_wb16(pb, rescale_mdcv(metadata->white_point[1], chroma_den));
2076 avio_wb32(pb, rescale_mdcv(metadata->max_luminance, luma_den));
2077 avio_wb32(pb, rescale_mdcv(metadata->min_luminance, luma_den));
2078 return 32;
2079 }
2080
2081 static void find_compressor(char * compressor_name, int len, MOVTrack *track)
2082 {
2083 AVDictionaryEntry *encoder;
2084 int xdcam_res = (track->par->width == 1280 && track->par->height == 720)
2085 || (track->par->width == 1440 && track->par->height == 1080)
2086 || (track->par->width == 1920 && track->par->height == 1080);
2087
2088 if (track->mode == MODE_MOV &&
2089 (encoder = av_dict_get(track->st->metadata, "encoder", NULL, 0))) {
2090 av_strlcpy(compressor_name, encoder->value, 32);
2091 } else if (track->par->codec_id == AV_CODEC_ID_MPEG2VIDEO && xdcam_res) {
2092 int interlaced = track->par->field_order > AV_FIELD_PROGRESSIVE;
2093 AVStream *st = track->st;
2094 int rate = defined_frame_rate(NULL, st);
2095 av_strlcatf(compressor_name, len, "XDCAM");
2096 if (track->par->format == AV_PIX_FMT_YUV422P) {
2097 av_strlcatf(compressor_name, len, " HD422");
2098 } else if(track->par->width == 1440) {
2099 av_strlcatf(compressor_name, len, " HD");
2100 } else
2101 av_strlcatf(compressor_name, len, " EX");
2102
2103 av_strlcatf(compressor_name, len, " %d%c", track->par->height, interlaced ? 'i' : 'p');
2104
2105 av_strlcatf(compressor_name, len, "%d", rate * (interlaced + 1));
2106 }
2107 }
2108
2109 static int mov_write_video_tag(AVFormatContext *s, AVIOContext *pb, MOVMuxContext *mov, MOVTrack *track)
2110 {
2111 int ret = AVERROR_BUG;
2112 int64_t pos = avio_tell(pb);
2113 char compressor_name[32] = { 0 };
2114 int avid = 0;
2115
2116 int uncompressed_ycbcr = ((track->par->codec_id == AV_CODEC_ID_RAWVIDEO && track->par->format == AV_PIX_FMT_UYVY422)
2117 || (track->par->codec_id == AV_CODEC_ID_RAWVIDEO && track->par->format == AV_PIX_FMT_YUYV422)
2118 || track->par->codec_id == AV_CODEC_ID_V308
2119 || track->par->codec_id == AV_CODEC_ID_V408
2120 || track->par->codec_id == AV_CODEC_ID_V410
2121 || track->par->codec_id == AV_CODEC_ID_V210);
2122
2123 avio_wb32(pb, 0); /* size */
2124 if (mov->encryption_scheme != MOV_ENC_NONE) {
2125 ffio_wfourcc(pb, "encv");
2126 } else {
2127 avio_wl32(pb, track->tag); // store it byteswapped
2128 }
2129 avio_wb32(pb, 0); /* Reserved */
2130 avio_wb16(pb, 0); /* Reserved */
2131 avio_wb16(pb, 1); /* Data-reference index */
2132
2133 if (uncompressed_ycbcr) {
2134 avio_wb16(pb, 2); /* Codec stream version */
2135 } else {
2136 avio_wb16(pb, 0); /* Codec stream version */
2137 }
2138 avio_wb16(pb, 0); /* Codec stream revision (=0) */
2139 if (track->mode == MODE_MOV) {
2140 ffio_wfourcc(pb, "FFMP"); /* Vendor */
2141 if (track->par->codec_id == AV_CODEC_ID_RAWVIDEO || uncompressed_ycbcr) {
2142 avio_wb32(pb, 0); /* Temporal Quality */
2143 avio_wb32(pb, 0x400); /* Spatial Quality = lossless*/
2144 } else {
2145 avio_wb32(pb, 0x200); /* Temporal Quality = normal */
2146 avio_wb32(pb, 0x200); /* Spatial Quality = normal */
2147 }
2148 } else {
2149 ffio_fill(pb, 0, 3 * 4); /* Reserved */
2150 }
2151 avio_wb16(pb, track->par->width); /* Video width */
2152 avio_wb16(pb, track->height); /* Video height */
2153 avio_wb32(pb, 0x00480000); /* Horizontal resolution 72dpi */
2154 avio_wb32(pb, 0x00480000); /* Vertical resolution 72dpi */
2155 avio_wb32(pb, 0); /* Data size (= 0) */
2156 avio_wb16(pb, 1); /* Frame count (= 1) */
2157
2158 /* FIXME not sure, ISO 14496-1 draft where it shall be set to 0 */
2159 find_compressor(compressor_name, 32, track);
2160 avio_w8(pb, strlen(compressor_name));
2161 avio_write(pb, compressor_name, 31);
2162
2163 if (track->mode == MODE_MOV &&
2164 (track->par->codec_id == AV_CODEC_ID_V410 || track->par->codec_id == AV_CODEC_ID_V210))
2165 avio_wb16(pb, 0x18);
2166 else if (track->mode == MODE_MOV && track->par->bits_per_coded_sample)
2167 avio_wb16(pb, track->par->bits_per_coded_sample |
2168 (track->par->format == AV_PIX_FMT_GRAY8 ? 0x20 : 0));
2169 else
2170 avio_wb16(pb, 0x18); /* Reserved */
2171
2172 if (track->mode == MODE_MOV && track->par->format == AV_PIX_FMT_PAL8) {
2173 int pal_size, i;
2174 avio_wb16(pb, 0); /* Color table ID */
2175 avio_wb32(pb, 0); /* Color table seed */
2176 avio_wb16(pb, 0x8000); /* Color table flags */
2177 if (track->par->bits_per_coded_sample < 0 || track->par->bits_per_coded_sample > 8)
2178 return AVERROR(EINVAL);
2179 pal_size = 1 << track->par->bits_per_coded_sample;
2180 avio_wb16(pb, pal_size - 1); /* Color table size (zero-relative) */
2181 for (i = 0; i < pal_size; i++) {
2182 uint32_t rgb = track->palette[i];
2183 uint16_t r = (rgb >> 16) & 0xff;
2184 uint16_t g = (rgb >> 8) & 0xff;
2185 uint16_t b = rgb & 0xff;
2186 avio_wb16(pb, 0);
2187 avio_wb16(pb, (r << 8) | r);
2188 avio_wb16(pb, (g << 8) | g);
2189 avio_wb16(pb, (b << 8) | b);
2190 }
2191 } else
2192 avio_wb16(pb, 0xffff); /* Reserved */
2193
2194 if (track->tag == MKTAG('m','p','4','v'))
2195 mov_write_esds_tag(pb, track);
2196 else if (track->par->codec_id == AV_CODEC_ID_H263)
2197 mov_write_d263_tag(pb);
2198 else if (track->par->codec_id == AV_CODEC_ID_AVUI ||
2199 track->par->codec_id == AV_CODEC_ID_SVQ3) {
2200 mov_write_extradata_tag(pb, track);
2201 avio_wb32(pb, 0);
2202 } else if (track->par->codec_id == AV_CODEC_ID_DNXHD) {
2203 mov_write_avid_tag(pb, track);
2204 avid = 1;
2205 } else if (track->par->codec_id == AV_CODEC_ID_HEVC)
2206 mov_write_hvcc_tag(pb, track);
2207 else if (track->par->codec_id == AV_CODEC_ID_H264 && !TAG_IS_AVCI(track->tag)) {
2208 mov_write_avcc_tag(pb, track);
2209 if (track->mode == MODE_IPOD)
2210 mov_write_uuid_tag_ipod(pb);
2211 } else if (track->par->codec_id == AV_CODEC_ID_VP9) {
2212 mov_write_vpcc_tag(mov->fc, pb, track);
2213 } else if (track->par->codec_id == AV_CODEC_ID_AV1) {
2214 mov_write_av1c_tag(pb, track);
2215 } else if (track->par->codec_id == AV_CODEC_ID_VC1 && track->vos_len > 0)
2216 mov_write_dvc1_tag(pb, track);
2217 else if (track->par->codec_id == AV_CODEC_ID_VP6F ||
2218 track->par->codec_id == AV_CODEC_ID_VP6A) {
2219 /* Don't write any potential extradata here - the cropping
2220 * is signalled via the normal width/height fields. */
2221 } else if (track->par->codec_id == AV_CODEC_ID_R10K) {
2222 if (track->par->codec_tag == MKTAG('R','1','0','k'))
2223 mov_write_dpxe_tag(pb, track);
2224 } else if (track->vos_len > 0)
2225 mov_write_glbl_tag(pb, track);
2226
2227 if (track->par->codec_id != AV_CODEC_ID_H264 &&
2228 track->par->codec_id != AV_CODEC_ID_MPEG4 &&
2229 track->par->codec_id != AV_CODEC_ID_DNXHD) {
2230 int field_order = track->par->field_order;
2231
2232 if (field_order != AV_FIELD_UNKNOWN)
2233 mov_write_fiel_tag(pb, track, field_order);
2234 }
2235
2236 if (mov->flags & FF_MOV_FLAG_WRITE_GAMA) {
2237 if (track->mode == MODE_MOV)
2238 mov_write_gama_tag(s, pb, track, mov->gamma);
2239 else
2240 av_log(mov->fc, AV_LOG_WARNING, "Not writing 'gama' atom. Format is not MOV.\n");
2241 }
2242 if (track->mode == MODE_MOV || track->mode == MODE_MP4) {
2243 int has_color_info = track->par->color_primaries != AVCOL_PRI_UNSPECIFIED &&
2244 track->par->color_trc != AVCOL_TRC_UNSPECIFIED &&
2245 track->par->color_space != AVCOL_SPC_UNSPECIFIED;
2246 if (has_color_info || mov->flags & FF_MOV_FLAG_WRITE_COLR ||
2247 av_stream_get_side_data(track->st, AV_PKT_DATA_ICC_PROFILE, NULL)) {
2248 int prefer_icc = mov->flags & FF_MOV_FLAG_PREFER_ICC || !has_color_info;
2249 mov_write_colr_tag(pb, track, prefer_icc);
2250 } else if (mov->flags & FF_MOV_FLAG_WRITE_COLR) {
2251 av_log(mov->fc, AV_LOG_WARNING, "Not writing 'colr' atom. Format is not MOV or MP4.\n");
2252 }
2253 }
2254 if (track->mode == MODE_MOV || track->mode == MODE_MP4) {
2255 mov_write_clli_tag(pb, track);
2256 mov_write_mdcv_tag(pb, track);
2257 }
2258
2259 if (track->mode == MODE_MP4 && mov->fc->strict_std_compliance <= FF_COMPLIANCE_UNOFFICIAL) {
2260 AVStereo3D* stereo_3d = (AVStereo3D*) av_stream_get_side_data(track->st, AV_PKT_DATA_STEREO3D, NULL);
2261 AVSphericalMapping* spherical_mapping = (AVSphericalMapping*)av_stream_get_side_data(track->st, AV_PKT_DATA_SPHERICAL, NULL);
2262 AVDOVIDecoderConfigurationRecord *dovi = (AVDOVIDecoderConfigurationRecord *)
2263 av_stream_get_side_data(track->st, AV_PKT_DATA_DOVI_CONF, NULL);
2264
2265 if (stereo_3d)
2266 mov_write_st3d_tag(s, pb, stereo_3d);
2267 if (spherical_mapping)
2268 mov_write_sv3d_tag(mov->fc, pb, spherical_mapping);
2269 if (dovi)
2270 mov_write_dvcc_dvvc_tag(s, pb, dovi);
2271 }
2272
2273 if (track->par->sample_aspect_ratio.den && track->par->sample_aspect_ratio.num) {
2274 mov_write_pasp_tag(pb, track);
2275 }
2276
2277 if (uncompressed_ycbcr){
2278 mov_write_clap_tag(pb, track);
2279 }
2280
2281 if (mov->encryption_scheme != MOV_ENC_NONE) {
2282 ff_mov_cenc_write_sinf_tag(track, pb, mov->encryption_kid);
2283 }
2284
2285 if (track->mode == MODE_MP4 &&
2286 ((ret = mov_write_btrt_tag(pb, track)) < 0))
2287 return ret;
2288
2289 /* extra padding for avid stsd */
2290 /* https://developer.apple.com/library/mac/documentation/QuickTime/QTFF/QTFFChap2/qtff2.html#//apple_ref/doc/uid/TP40000939-CH204-61112 */
2291 if (avid)
2292 avio_wb32(pb, 0);
2293
2294 return update_size(pb, pos);
2295 }
2296
2297 static int mov_write_rtp_tag(AVIOContext *pb, MOVTrack *track)
2298 {
2299 int64_t pos = avio_tell(pb);
2300 avio_wb32(pb, 0); /* size */
2301 ffio_wfourcc(pb, "rtp ");
2302 avio_wb32(pb, 0); /* Reserved */
2303 avio_wb16(pb, 0); /* Reserved */
2304 avio_wb16(pb, 1); /* Data-reference index */
2305
2306 avio_wb16(pb, 1); /* Hint track version */
2307 avio_wb16(pb, 1); /* Highest compatible version */
2308 avio_wb32(pb, track->max_packet_size); /* Max packet size */
2309
2310 avio_wb32(pb, 12); /* size */
2311 ffio_wfourcc(pb, "tims");
2312 avio_wb32(pb, track->timescale);
2313
2314 return update_size(pb, pos);
2315 }
2316
2317 static int mov_write_source_reference_tag(AVIOContext *pb, MOVTrack *track, const char *reel_name)
2318 {
2319 uint64_t str_size =strlen(reel_name);
2320 int64_t pos = avio_tell(pb);
2321
2322 if (str_size >= UINT16_MAX){
2323 av_log(NULL, AV_LOG_ERROR, "reel_name length %"PRIu64" is too large\n", str_size);
2324 avio_wb16(pb, 0);
2325 return AVERROR(EINVAL);
2326 }
2327
2328 avio_wb32(pb, 0); /* size */
2329 ffio_wfourcc(pb, "name"); /* Data format */
2330 avio_wb16(pb, str_size); /* string size */
2331 avio_wb16(pb, track->language); /* langcode */
2332 avio_write(pb, reel_name, str_size); /* reel name */
2333 return update_size(pb,pos);
2334 }
2335
2336 static int mov_write_tmcd_tag(AVIOContext *pb, MOVTrack *track)
2337 {
2338 int64_t pos = avio_tell(pb);
2339 #if 1
2340 int frame_duration;
2341 int nb_frames;
2342 AVDictionaryEntry *t = NULL;
2343
2344 if (!track->st->avg_frame_rate.num || !track->st->avg_frame_rate.den) {
2345 av_log(NULL, AV_LOG_ERROR, "avg_frame_rate not set for tmcd track.\n");
2346 return AVERROR(EINVAL);
2347 } else {
2348 frame_duration = av_rescale(track->timescale, track->st->avg_frame_rate.den, track->st->avg_frame_rate.num);
2349 nb_frames = ROUNDED_DIV(track->st->avg_frame_rate.num, track->st->avg_frame_rate.den);
2350 }
2351
2352 if (nb_frames > 255) {
2353 av_log(NULL, AV_LOG_ERROR, "fps %d is too large\n", nb_frames);
2354 return AVERROR(EINVAL);
2355 }
2356
2357 avio_wb32(pb, 0); /* size */
2358 ffio_wfourcc(pb, "tmcd"); /* Data format */
2359 avio_wb32(pb, 0); /* Reserved */
2360 avio_wb32(pb, 1); /* Data reference index */
2361 avio_wb32(pb, 0); /* Flags */
2362 avio_wb32(pb, track->timecode_flags); /* Flags (timecode) */
2363 avio_wb32(pb, track->timescale); /* Timescale */
2364 avio_wb32(pb, frame_duration); /* Frame duration */
2365 avio_w8(pb, nb_frames); /* Number of frames */
2366 avio_w8(pb, 0); /* Reserved */
2367
2368 t = av_dict_get(track->st->metadata, "reel_name", NULL, 0);
2369 if (t && utf8len(t->value) && track->mode != MODE_MP4)
2370 mov_write_source_reference_tag(pb, track, t->value);
2371 else
2372 avio_wb16(pb, 0); /* zero size */
2373 #else
2374
2375 avio_wb32(pb, 0); /* size */
2376 ffio_wfourcc(pb, "tmcd"); /* Data format */
2377 avio_wb32(pb, 0); /* Reserved */
2378 avio_wb32(pb, 1); /* Data reference index */
2379 if (track->par->extradata_size)
2380 avio_write(pb, track->par->extradata, track->par->extradata_size);
2381 #endif
2382 return update_size(pb, pos);
2383 }
2384
2385 static int mov_write_gpmd_tag(AVIOContext *pb, const MOVTrack *track)
2386 {
2387 int64_t pos = avio_tell(pb);
2388 avio_wb32(pb, 0); /* size */
2389 ffio_wfourcc(pb, "gpmd");
2390 avio_wb32(pb, 0); /* Reserved */
2391 avio_wb16(pb, 0); /* Reserved */
2392 avio_wb16(pb, 1); /* Data-reference index */
2393 avio_wb32(pb, 0); /* Reserved */
2394 return update_size(pb, pos);
2395 }
2396
2397 static int mov_write_stsd_tag(AVFormatContext *s, AVIOContext *pb, MOVMuxContext *mov, MOVTrack *track)
2398 {
2399 int64_t pos = avio_tell(pb);
2400 int ret = 0;
2401 avio_wb32(pb, 0); /* size */
2402 ffio_wfourcc(pb, "stsd");
2403 avio_wb32(pb, 0); /* version & flags */
2404 avio_wb32(pb, 1); /* entry count */
2405 if (track->par->codec_type == AVMEDIA_TYPE_VIDEO)
2406 ret = mov_write_video_tag(s, pb, mov, track);
2407 else if (track->par->codec_type == AVMEDIA_TYPE_AUDIO)
2408 ret = mov_write_audio_tag(s, pb, mov, track);
2409 else if (track->par->codec_type == AVMEDIA_TYPE_SUBTITLE)
2410 ret = mov_write_subtitle_tag(pb, track);
2411 else if (track->par->codec_tag == MKTAG('r','t','p',' '))
2412 ret = mov_write_rtp_tag(pb, track);
2413 else if (track->par->codec_tag == MKTAG('t','m','c','d'))
2414 ret = mov_write_tmcd_tag(pb, track);
2415 else if (track->par->codec_tag == MKTAG('g','p','m','d'))
2416 ret = mov_write_gpmd_tag(pb, track);
2417
2418 if (ret < 0)
2419 return ret;
2420
2421 return update_size(pb, pos);
2422 }
2423
2424 static int mov_write_ctts_tag(AVFormatContext *s, AVIOContext *pb, MOVTrack *track)
2425 {
2426 MOVMuxContext *mov = s->priv_data;
2427 MOVCtts *ctts_entries;
2428 uint32_t entries = 0;
2429 uint32_t atom_size;
2430 int i;
2431
2432 ctts_entries = av_malloc_array((track->entry + 1), sizeof(*ctts_entries)); /* worst case */
2433 if (!ctts_entries)
2434 return AVERROR(ENOMEM);
2435 ctts_entries[0].count = 1;
2436 ctts_entries[0].duration = track->cluster[0].cts;
2437 for (i = 1; i < track->entry; i++) {
2438 if (track->cluster[i].cts == ctts_entries[entries].duration) {
2439 ctts_entries[entries].count++; /* compress */
2440 } else {
2441 entries++;
2442 ctts_entries[entries].duration = track->cluster[i].cts;
2443 ctts_entries[entries].count = 1;
2444 }
2445 }
2446 entries++; /* last one */
2447 atom_size = 16 + (entries * 8);
2448 avio_wb32(pb, atom_size); /* size */
2449 ffio_wfourcc(pb, "ctts");
2450 if (mov->flags & FF_MOV_FLAG_NEGATIVE_CTS_OFFSETS)
2451 avio_w8(pb, 1); /* version */
2452 else
2453 avio_w8(pb, 0); /* version */
2454 avio_wb24(pb, 0); /* flags */
2455 avio_wb32(pb, entries); /* entry count */
2456 for (i = 0; i < entries; i++) {
2457 avio_wb32(pb, ctts_entries[i].count);
2458 avio_wb32(pb, ctts_entries[i].duration);
2459 }
2460 av_free(ctts_entries);
2461 return atom_size;
2462 }
2463
2464 /* Time to sample atom */
2465 static int mov_write_stts_tag(AVIOContext *pb, MOVTrack *track)
2466 {
2467 MOVStts *stts_entries = NULL;
2468 uint32_t entries = -1;
2469 uint32_t atom_size;
2470 int i;
2471
2472 if (track->par->codec_type == AVMEDIA_TYPE_AUDIO && !track->audio_vbr) {
2473 stts_entries = av_malloc(sizeof(*stts_entries)); /* one entry */
2474 if (!stts_entries)
2475 return AVERROR(ENOMEM);
2476 stts_entries[0].count = track->sample_count;
2477 stts_entries[0].duration = 1;
2478 entries = 1;
2479 } else {
2480 if (track->entry) {
2481 stts_entries = av_malloc_array(track->entry, sizeof(*stts_entries)); /* worst case */
2482 if (!stts_entries)
2483 return AVERROR(ENOMEM);
2484 }
2485 for (i = 0; i < track->entry; i++) {
2486 int duration = get_cluster_duration(track, i);
2487 if (i && duration == stts_entries[entries].duration) {
2488 stts_entries[entries].count++; /* compress */
2489 } else {
2490 entries++;
2491 stts_entries[entries].duration = duration;
2492 stts_entries[entries].count = 1;
2493 }
2494 }
2495 entries++; /* last one */
2496 }
2497 atom_size = 16 + (entries * 8);
2498 avio_wb32(pb, atom_size); /* size */
2499 ffio_wfourcc(pb, "stts");
2500 avio_wb32(pb, 0); /* version & flags */
2501 avio_wb32(pb, entries); /* entry count */
2502 for (i = 0; i < entries; i++) {
2503 avio_wb32(pb, stts_entries[i].count);
2504 avio_wb32(pb, stts_entries[i].duration);
2505 }
2506 av_free(stts_entries);
2507 return atom_size;
2508 }
2509
2510 static int mov_write_dref_tag(AVIOContext *pb)
2511 {
2512 avio_wb32(pb, 28); /* size */
2513 ffio_wfourcc(pb, "dref");
2514 avio_wb32(pb, 0); /* version & flags */
2515 avio_wb32(pb, 1); /* entry count */
2516
2517 avio_wb32(pb, 0xc); /* size */
2518 //FIXME add the alis and rsrc atom
2519 ffio_wfourcc(pb, "url ");
2520 avio_wb32(pb, 1); /* version & flags */
2521
2522 return 28;
2523 }
2524
2525 static int mov_preroll_write_stbl_atoms(AVIOContext *pb, MOVTrack *track)
2526 {
2527 struct sgpd_entry {
2528 int count;
2529 int16_t roll_distance;
2530 int group_description_index;
2531 };
2532
2533 struct sgpd_entry *sgpd_entries = NULL;
2534 int entries = -1;
2535 int group = 0;
2536 int i, j;
2537
2538 const int OPUS_SEEK_PREROLL_MS = 80;
2539 int roll_samples = av_rescale_q(OPUS_SEEK_PREROLL_MS,
2540 (AVRational){1, 1000},
2541 (AVRational){1, 48000});
2542
2543 if (!track->entry)
2544 return 0;
2545
2546 sgpd_entries = av_malloc_array(track->entry, sizeof(*sgpd_entries));
2547 if (!sgpd_entries)
2548 return AVERROR(ENOMEM);
2549
2550 av_assert0(track->par->codec_id == AV_CODEC_ID_OPUS || track->par->codec_id == AV_CODEC_ID_AAC);
2551
2552 if (track->par->codec_id == AV_CODEC_ID_OPUS) {
2553 for (i = 0; i < track->entry; i++) {
2554 int roll_samples_remaining = roll_samples;
2555 int distance = 0;
2556 for (j = i - 1; j >= 0; j--) {
2557 roll_samples_remaining -= get_cluster_duration(track, j);
2558 distance++;
2559 if (roll_samples_remaining <= 0)
2560 break;
2561 }
2562 /* We don't have enough preceeding samples to compute a valid
2563 roll_distance here, so this sample can't be independently
2564 decoded. */
2565 if (roll_samples_remaining > 0)
2566 distance = 0;
2567 /* Verify distance is a maximum of 32 (2.5ms) packets. */
2568 if (distance > 32)
2569 return AVERROR_INVALIDDATA;
2570 if (i && distance == sgpd_entries[entries].roll_distance) {
2571 sgpd_entries[entries].count++;
2572 } else {
2573 entries++;
2574 sgpd_entries[entries].count = 1;
2575 sgpd_entries[entries].roll_distance = distance;
2576 sgpd_entries[entries].group_description_index = distance ? ++group : 0;
2577 }
2578 }
2579 } else {
2580 entries++;
2581 sgpd_entries[entries].count = track->sample_count;
2582 sgpd_entries[entries].roll_distance = 1;
2583 sgpd_entries[entries].group_description_index = ++group;
2584 }
2585 entries++;
2586
2587 if (!group) {
2588 av_free(sgpd_entries);
2589 return 0;
2590 }
2591
2592 /* Write sgpd tag */
2593 avio_wb32(pb, 24 + (group * 2)); /* size */
2594 ffio_wfourcc(pb, "sgpd");
2595 avio_wb32(pb, 1 << 24); /* fullbox */
2596 ffio_wfourcc(pb, "roll");
2597 avio_wb32(pb, 2); /* default_length */
2598 avio_wb32(pb, group); /* entry_count */
2599 for (i = 0; i < entries; i++) {
2600 if (sgpd_entries[i].group_description_index) {
2601 avio_wb16(pb, -sgpd_entries[i].roll_distance); /* roll_distance */
2602 }
2603 }
2604
2605 /* Write sbgp tag */
2606 avio_wb32(pb, 20 + (entries * 8)); /* size */
2607 ffio_wfourcc(pb, "sbgp");
2608 avio_wb32(pb, 0); /* fullbox */
2609 ffio_wfourcc(pb, "roll");
2610 avio_wb32(pb, entries); /* entry_count */
2611 for (i = 0; i < entries; i++) {
2612 avio_wb32(pb, sgpd_entries[i].count); /* sample_count */
2613 avio_wb32(pb, sgpd_entries[i].group_description_index); /* group_description_index */
2614 }
2615
2616 av_free(sgpd_entries);
2617 return 0;
2618 }
2619
2620 static int mov_write_stbl_tag(AVFormatContext *s, AVIOContext *pb, MOVMuxContext *mov, MOVTrack *track)
2621 {
2622 int64_t pos = avio_tell(pb);
2623 int ret = 0;
2624
2625 avio_wb32(pb, 0); /* size */
2626 ffio_wfourcc(pb, "stbl");
2627 if ((ret = mov_write_stsd_tag(s, pb, mov, track)) < 0)
2628 return ret;
2629 mov_write_stts_tag(pb, track);
2630 if ((track->par->codec_type == AVMEDIA_TYPE_VIDEO ||
2631 track->par->codec_id == AV_CODEC_ID_TRUEHD ||
2632 track->par->codec_id == AV_CODEC_ID_MPEGH_3D_AUDIO ||
2633 track->par->codec_tag == MKTAG('r','t','p',' ')) &&
2634 track->has_keyframes && track->has_keyframes < track->entry)
2635 mov_write_stss_tag(pb, track, MOV_SYNC_SAMPLE);
2636 if (track->par->codec_type == AVMEDIA_TYPE_VIDEO && track->has_disposable)
2637 mov_write_sdtp_tag(pb, track);
2638 if (track->mode == MODE_MOV && track->flags & MOV_TRACK_STPS)
2639 mov_write_stss_tag(pb, track, MOV_PARTIAL_SYNC_SAMPLE);
2640 if (track->par->codec_type == AVMEDIA_TYPE_VIDEO &&
2641 track->flags & MOV_TRACK_CTTS && track->entry) {
2642
2643 if ((ret = mov_write_ctts_tag(s, pb, track)) < 0)
2644 return ret;
2645 }
2646 mov_write_stsc_tag(pb, track);
2647 mov_write_stsz_tag(pb, track);
2648 mov_write_stco_tag(pb, track);
2649 if (track->cenc.aes_ctr) {
2650 ff_mov_cenc_write_stbl_atoms(&track->cenc, pb);
2651 }
2652 if (track->par->codec_id == AV_CODEC_ID_OPUS || track->par->codec_id == AV_CODEC_ID_AAC) {
2653 mov_preroll_write_stbl_atoms(pb, track);
2654 }
2655 return update_size(pb, pos);
2656 }
2657
2658 static int mov_write_dinf_tag(AVIOContext *pb)
2659 {
2660 int64_t pos = avio_tell(pb);
2661 avio_wb32(pb, 0); /* size */
2662 ffio_wfourcc(pb, "dinf");
2663 mov_write_dref_tag(pb);
2664 return update_size(pb, pos);
2665 }
2666
2667 static int mov_write_nmhd_tag(AVIOContext *pb)
2668 {
2669 avio_wb32(pb, 12);
2670 ffio_wfourcc(pb, "nmhd");
2671 avio_wb32(pb, 0);
2672 return 12;
2673 }
2674
2675 static int mov_write_sthd_tag(AVIOContext *pb)
2676 {
2677 avio_wb32(pb, 12);
2678 ffio_wfourcc(pb, "sthd");
2679 avio_wb32(pb, 0);
2680 return 12;
2681 }
2682
2683 static int mov_write_tcmi_tag(AVIOContext *pb, MOVTrack *track)
2684 {
2685 int64_t pos = avio_tell(pb);
2686 const char *font = "Lucida Grande";
2687 avio_wb32(pb, 0); /* size */
2688 ffio_wfourcc(pb, "tcmi"); /* timecode media information atom */
2689 avio_wb32(pb, 0); /* version & flags */
2690 avio_wb16(pb, 0); /* text font */
2691 avio_wb16(pb, 0); /* text face */
2692 avio_wb16(pb, 12); /* text size */
2693 avio_wb16(pb, 0); /* (unknown, not in the QT specs...) */
2694 avio_wb16(pb, 0x0000); /* text color (red) */
2695 avio_wb16(pb, 0x0000); /* text color (green) */
2696 avio_wb16(pb, 0x0000); /* text color (blue) */
2697 avio_wb16(pb, 0xffff); /* background color (red) */
2698 avio_wb16(pb, 0xffff); /* background color (green) */
2699 avio_wb16(pb, 0xffff); /* background color (blue) */
2700 avio_w8(pb, strlen(font)); /* font len (part of the pascal string) */
2701 avio_write(pb, font, strlen(font)); /* font name */
2702 return update_size(pb, pos);
2703 }
2704
2705 static int mov_write_gmhd_tag(AVIOContext *pb, MOVTrack *track)
2706 {
2707 int64_t pos = avio_tell(pb);
2708 avio_wb32(pb, 0); /* size */
2709 ffio_wfourcc(pb, "gmhd");
2710 avio_wb32(pb, 0x18); /* gmin size */
2711 ffio_wfourcc(pb, "gmin");/* generic media info */
2712 avio_wb32(pb, 0); /* version & flags */
2713 avio_wb16(pb, 0x40); /* graphics mode = */
2714 avio_wb16(pb, 0x8000); /* opColor (r?) */
2715 avio_wb16(pb, 0x8000); /* opColor (g?) */
2716 avio_wb16(pb, 0x8000); /* opColor (b?) */
2717 avio_wb16(pb, 0); /* balance */
2718 avio_wb16(pb, 0); /* reserved */
2719
2720 /*
2721 * This special text atom is required for
2722 * Apple Quicktime chapters. The contents
2723 * don't appear to be documented, so the
2724 * bytes are copied verbatim.
2725 */
2726 if (track->tag != MKTAG('c','6','0','8')) {
2727 avio_wb32(pb, 0x2C); /* size */
2728 ffio_wfourcc(pb, "text");
2729 avio_wb16(pb, 0x01);
2730 avio_wb32(pb, 0x00);
2731 avio_wb32(pb, 0x00);
2732 avio_wb32(pb, 0x00);
2733 avio_wb32(pb, 0x01);
2734 avio_wb32(pb, 0x00);
2735 avio_wb32(pb, 0x00);
2736 avio_wb32(pb, 0x00);
2737 avio_wb32(pb, 0x00004000);
2738 avio_wb16(pb, 0x0000);
2739 }
2740
2741 if (track->par->codec_tag == MKTAG('t','m','c','d')) {
2742 int64_t tmcd_pos = avio_tell(pb);
2743 avio_wb32(pb, 0); /* size */
2744 ffio_wfourcc(pb, "tmcd");
2745 mov_write_tcmi_tag(pb, track);
2746 update_size(pb, tmcd_pos);
2747 } else if (track->par->codec_tag == MKTAG('g','p','m','d')) {
2748 int64_t gpmd_pos = avio_tell(pb);
2749 avio_wb32(pb, 0); /* size */
2750 ffio_wfourcc(pb, "gpmd");
2751 avio_wb32(pb, 0); /* version */
2752 update_size(pb, gpmd_pos);
2753 }
2754 return update_size(pb, pos);
2755 }
2756
2757 static int mov_write_smhd_tag(AVIOContext *pb)
2758 {
2759 avio_wb32(pb, 16); /* size */
2760 ffio_wfourcc(pb, "smhd");
2761 avio_wb32(pb, 0); /* version & flags */
2762 avio_wb16(pb, 0); /* reserved (balance, normally = 0) */
2763 avio_wb16(pb, 0); /* reserved */
2764 return 16;
2765 }
2766
2767 static int mov_write_vmhd_tag(AVIOContext *pb)
2768 {
2769 avio_wb32(pb, 0x14); /* size (always 0x14) */
2770 ffio_wfourcc(pb, "vmhd");
2771 avio_wb32(pb, 0x01); /* version & flags */
2772 avio_wb64(pb, 0); /* reserved (graphics mode = copy) */
2773 return 0x14;
2774 }
2775
2776 static int is_clcp_track(MOVTrack *track)
2777 {
2778 return track->tag == MKTAG('c','7','0','8') ||
2779 track->tag == MKTAG('c','6','0','8');
2780 }
2781
2782 static int mov_write_hdlr_tag(AVFormatContext *s, AVIOContext *pb, MOVTrack *track)
2783 {
2784 MOVMuxContext *mov = s->priv_data;
2785 const char *hdlr, *descr = NULL, *hdlr_type = NULL;
2786 int64_t pos = avio_tell(pb);
2787 size_t descr_len;
2788
2789 hdlr = "dhlr";
2790 hdlr_type = "url ";
2791 descr = "DataHandler";
2792
2793 if (track) {
2794 hdlr = (track->mode == MODE_MOV) ? "mhlr" : "\0\0\0\0";
2795 if (track->par->codec_type == AVMEDIA_TYPE_VIDEO) {
2796 hdlr_type = "vide";
2797 descr = "VideoHandler";
2798 } else if (track->par->codec_type == AVMEDIA_TYPE_AUDIO) {
2799 hdlr_type = "soun";
2800 descr = "SoundHandler";
2801 } else if (track->par->codec_type == AVMEDIA_TYPE_SUBTITLE) {
2802 if (is_clcp_track(track)) {
2803 hdlr_type = "clcp";
2804 descr = "ClosedCaptionHandler";
2805 } else {
2806 if (track->tag == MKTAG('t','x','3','g')) {
2807 hdlr_type = "sbtl";
2808 } else if (track->tag == MKTAG('m','p','4','s')) {
2809 hdlr_type = "subp";
2810 } else if (track->tag == MOV_MP4_TTML_TAG) {
2811 hdlr_type = "subt";
2812 } else {
2813 hdlr_type = "text";
2814 }
2815 descr = "SubtitleHandler";
2816 }
2817 } else if (track->par->codec_tag == MKTAG('r','t','p',' ')) {
2818 hdlr_type = "hint";
2819 descr = "HintHandler";
2820 } else if (track->par->codec_tag == MKTAG('t','m','c','d')) {
2821 hdlr_type = "tmcd";
2822 descr = "TimeCodeHandler";
2823 } else if (track->par->codec_tag == MKTAG('g','p','m','d')) {
2824 hdlr_type = "meta";
2825 descr = "GoPro MET"; // GoPro Metadata
2826 } else {
2827 av_log(s, AV_LOG_WARNING,
2828 "Unknown hdlr_type for %s, writing dummy values\n",
2829 av_fourcc2str(track->par->codec_tag));
2830 }
2831 if (track->st) {
2832 // hdlr.name is used by some players to identify the content title
2833 // of the track. So if an alternate handler description is
2834 // specified, use it.
2835 AVDictionaryEntry *t;
2836 t = av_dict_get(track->st->metadata, "handler_name", NULL, 0);
2837 if (t && utf8len(t->value))
2838 descr = t->value;
2839 }
2840 }
2841
2842 if (mov->empty_hdlr_name) /* expressly allowed by QTFF and not prohibited in ISO 14496-12 8.4.3.3 */
2843 descr = "";
2844
2845 avio_wb32(pb, 0); /* size */
2846 ffio_wfourcc(pb, "hdlr");
2847 avio_wb32(pb, 0); /* Version & flags */
2848 avio_write(pb, hdlr, 4); /* handler */
2849 ffio_wfourcc(pb, hdlr_type); /* handler type */
2850 avio_wb32(pb, 0); /* reserved */
2851 avio_wb32(pb, 0); /* reserved */
2852 avio_wb32(pb, 0); /* reserved */
2853 descr_len = strlen(descr);
2854 if (!track || track->mode == MODE_MOV)
2855 avio_w8(pb, descr_len); /* pascal string */
2856 avio_write(pb, descr, descr_len); /* handler description */
2857 if (track && track->mode != MODE_MOV)
2858 avio_w8(pb, 0); /* c string */
2859 return update_size(pb, pos);
2860 }
2861
2862 static int mov_write_hmhd_tag(AVIOContext *pb)
2863 {
2864 /* This atom must be present, but leaving the values at zero
2865 * seems harmless. */
2866 avio_wb32(pb, 28); /* size */
2867 ffio_wfourcc(pb, "hmhd");
2868 avio_wb32(pb, 0); /* version, flags */
2869 avio_wb16(pb, 0); /* maxPDUsize */
2870 avio_wb16(pb, 0); /* avgPDUsize */
2871 avio_wb32(pb, 0); /* maxbitrate */
2872 avio_wb32(pb, 0); /* avgbitrate */
2873 avio_wb32(pb, 0); /* reserved */
2874 return 28;
2875 }
2876
2877 static int mov_write_minf_tag(AVFormatContext *s, AVIOContext *pb, MOVMuxContext *mov, MOVTrack *track)
2878 {
2879 int64_t pos = avio_tell(pb);
2880 int ret;
2881
2882 avio_wb32(pb, 0); /* size */
2883 ffio_wfourcc(pb, "minf");
2884 if (track->par->codec_type == AVMEDIA_TYPE_VIDEO)
2885 mov_write_vmhd_tag(pb);
2886 else if (track->par->codec_type == AVMEDIA_TYPE_AUDIO)
2887 mov_write_smhd_tag(pb);
2888 else if (track->par->codec_type == AVMEDIA_TYPE_SUBTITLE) {
2889 if (track->tag == MKTAG('t','e','x','t') || is_clcp_track(track)) {
2890 mov_write_gmhd_tag(pb, track);
2891 } else if (track->tag == MOV_MP4_TTML_TAG) {
2892 mov_write_sthd_tag(pb);
2893 } else {
2894 mov_write_nmhd_tag(pb);
2895 }
2896 } else if (track->tag == MKTAG('r','t','p',' ')) {
2897 mov_write_hmhd_tag(pb);
2898 } else if (track->tag == MKTAG('t','m','c','d')) {
2899 if (track->mode != MODE_MOV)
2900 mov_write_nmhd_tag(pb);
2901 else
2902 mov_write_gmhd_tag(pb, track);
2903 } else if (track->tag == MKTAG('g','p','m','d')) {
2904 mov_write_gmhd_tag(pb, track);
2905 }
2906 if (track->mode == MODE_MOV) /* ISO 14496-12 8.4.3.1 specifies hdlr only within mdia or meta boxes */
2907 mov_write_hdlr_tag(s, pb, NULL);
2908 mov_write_dinf_tag(pb);
2909 if ((ret = mov_write_stbl_tag(s, pb, mov, track)) < 0)
2910 return ret;
2911 return update_size(pb, pos);
2912 }
2913
2914 static void get_pts_range(MOVMuxContext *mov, MOVTrack *track,
2915 int64_t *start, int64_t *end)
2916 {
2917 if (track->tag == MKTAG('t','m','c','d') && mov->nb_meta_tmcd) {
2918 // tmcd tracks gets track_duration set in mov_write_moov_tag from
2919 // another track's duration, while the end_pts may be left at zero.
2920 // Calculate the pts duration for that track instead.
2921 get_pts_range(mov, &mov->tracks[track->src_track], start, end);
2922 *start = av_rescale(*start, track->timescale,
2923 mov->tracks[track->src_track].timescale);
2924 *end = av_rescale(*end, track->timescale,
2925 mov->tracks[track->src_track].timescale);
2926 return;
2927 }
2928 if (track->end_pts != AV_NOPTS_VALUE &&
2929 track->start_dts != AV_NOPTS_VALUE &&
2930 track->start_cts != AV_NOPTS_VALUE) {
2931 *start = track->start_dts + track->start_cts;
2932 *end = track->end_pts;
2933 return;
2934 }
2935 *start = 0;
2936 *end = track->track_duration;
2937 }
2938
2939 static int64_t calc_samples_pts_duration(MOVMuxContext *mov, MOVTrack *track)
2940 {
2941 int64_t start, end;
2942 get_pts_range(mov, track, &start, &end);
2943 return end - start;
2944 }
2945
2946 // Calculate the actual duration of the track, after edits.
2947 // If it starts with a pts < 0, that is removed by the edit list.
2948 // If it starts with a pts > 0, the edit list adds a delay before that.
2949 // Thus, with edit lists enabled, the post-edit output of the file is
2950 // starting with pts=0.
2951 static int64_t calc_pts_duration(MOVMuxContext *mov, MOVTrack *track)
2952 {
2953 int64_t start, end;
2954 get_pts_range(mov, track, &start, &end);
2955 if (mov->use_editlist != 0)
2956 start = 0;
2957 return end - start;
2958 }
2959
2960 static int mov_write_mdhd_tag(AVIOContext *pb, MOVMuxContext *mov,
2961 MOVTrack *track)
2962 {
2963 int64_t duration = calc_samples_pts_duration(mov, track);
2964 int version = duration < INT32_MAX ? 0 : 1;
2965
2966 if (track->mode == MODE_ISM)
2967 version = 1;
2968
2969 (version == 1) ? avio_wb32(pb, 44) : avio_wb32(pb, 32); /* size */
2970 ffio_wfourcc(pb, "mdhd");
2971 avio_w8(pb, version);
2972 avio_wb24(pb, 0); /* flags */
2973 if (version == 1) {
2974 avio_wb64(pb, track->time);
2975 avio_wb64(pb, track->time);
2976 } else {
2977 avio_wb32(pb, track->time); /* creation time */
2978 avio_wb32(pb, track->time); /* modification time */
2979 }
2980 avio_wb32(pb, track->timescale); /* time scale (sample rate for audio) */
2981 if (!track->entry && mov->mode == MODE_ISM)
2982 (version == 1) ? avio_wb64(pb, UINT64_C(0xffffffffffffffff)) : avio_wb32(pb, 0xffffffff);
2983 else if (!track->entry)
2984 (version == 1) ? avio_wb64(pb, 0) : avio_wb32(pb, 0);
2985 else
2986 (version == 1) ? avio_wb64(pb, duration) : avio_wb32(pb, duration); /* duration */
2987 avio_wb16(pb, track->language); /* language */
2988 avio_wb16(pb, 0); /* reserved (quality) */
2989
2990 if (version != 0 && track->mode == MODE_MOV) {
2991 av_log(NULL, AV_LOG_ERROR,
2992 "FATAL error, file duration too long for timebase, this file will not be\n"
2993 "playable with QuickTime. Choose a different timebase with "
2994 "-video_track_timescale or a different container format\n");
2995 }
2996
2997 return 32;
2998 }
2999
3000 static int mov_write_mdia_tag(AVFormatContext *s, AVIOContext *pb,
3001 MOVMuxContext *mov, MOVTrack *track)
3002 {
3003 int64_t pos = avio_tell(pb);
3004 int ret;
3005
3006 avio_wb32(pb, 0); /* size */
3007 ffio_wfourcc(pb, "mdia");
3008 mov_write_mdhd_tag(pb, mov, track);
3009 mov_write_hdlr_tag(s, pb, track);
3010 if ((ret = mov_write_minf_tag(s, pb, mov, track)) < 0)
3011 return ret;
3012 return update_size(pb, pos);
3013 }
3014
3015 /* transformation matrix
3016 |a b u|
3017 |c d v|
3018 |tx ty w| */
3019 static void write_matrix(AVIOContext *pb, int16_t a, int16_t b, int16_t c,
3020 int16_t d, int16_t tx, int16_t ty)
3021 {
3022 avio_wb32(pb, a << 16); /* 16.16 format */
3023 avio_wb32(pb, b << 16); /* 16.16 format */
3024 avio_wb32(pb, 0); /* u in 2.30 format */
3025 avio_wb32(pb, c << 16); /* 16.16 format */
3026 avio_wb32(pb, d << 16); /* 16.16 format */
3027 avio_wb32(pb, 0); /* v in 2.30 format */
3028 avio_wb32(pb, tx << 16); /* 16.16 format */
3029 avio_wb32(pb, ty << 16); /* 16.16 format */
3030 avio_wb32(pb, 1 << 30); /* w in 2.30 format */
3031 }
3032
3033 static int mov_write_tkhd_tag(AVIOContext *pb, MOVMuxContext *mov,
3034 MOVTrack *track, AVStream *st)
3035 {
3036 int64_t duration = av_rescale_rnd(calc_pts_duration(mov, track),
3037 mov->movie_timescale, track->timescale,
3038 AV_ROUND_UP);
3039 int version = duration < INT32_MAX ? 0 : 1;
3040 int flags = MOV_TKHD_FLAG_IN_MOVIE;
3041 int group = 0;
3042
3043 uint32_t *display_matrix = NULL;
3044 size_t display_matrix_size;
3045 int i;
3046
3047 if (st) {
3048 if (mov->per_stream_grouping)
3049 group = st->index;
3050 else
3051 group = st->codecpar->codec_type;
3052
3053 display_matrix = (uint32_t*)av_stream_get_side_data(st, AV_PKT_DATA_DISPLAYMATRIX,
3054 &display_matrix_size);
3055 if (display_matrix && display_matrix_size < 9 * sizeof(*display_matrix))
3056 display_matrix = NULL;
3057 }
3058
3059 if (track->flags & MOV_TRACK_ENABLED)
3060 flags |= MOV_TKHD_FLAG_ENABLED;
3061
3062 if (track->mode == MODE_ISM)
3063 version = 1;
3064
3065 (version == 1) ? avio_wb32(pb, 104) : avio_wb32(pb, 92); /* size */
3066 ffio_wfourcc(pb, "tkhd");
3067 avio_w8(pb, version);
3068 avio_wb24(pb, flags);
3069 if (version == 1) {
3070 avio_wb64(pb, track->time);
3071 avio_wb64(pb, track->time);
3072 } else {
3073 avio_wb32(pb, track->time); /* creation time */
3074 avio_wb32(pb, track->time); /* modification time */
3075 }
3076 avio_wb32(pb, track->track_id); /* track-id */
3077 avio_wb32(pb, 0); /* reserved */
3078 if (!track->entry && mov->mode == MODE_ISM)
3079 (version == 1) ? avio_wb64(pb, UINT64_C(0xffffffffffffffff)) : avio_wb32(pb, 0xffffffff);
3080 else if (!track->entry)
3081 (version == 1) ? avio_wb64(pb, 0) : avio_wb32(pb, 0);
3082 else
3083 (version == 1) ? avio_wb64(pb, duration) : avio_wb32(pb, duration);
3084
3085 avio_wb32(pb, 0); /* reserved */
3086 avio_wb32(pb, 0); /* reserved */
3087 avio_wb16(pb, 0); /* layer */
3088 avio_wb16(pb, group); /* alternate group) */
3089 /* Volume, only for audio */
3090 if (track->par->codec_type == AVMEDIA_TYPE_AUDIO)
3091 avio_wb16(pb, 0x0100);
3092 else
3093 avio_wb16(pb, 0);
3094 avio_wb16(pb, 0); /* reserved */
3095
3096 /* Matrix structure */
3097 if (display_matrix) {
3098 for (i = 0; i < 9; i++)
3099 avio_wb32(pb, display_matrix[i]);
3100 } else {
3101 write_matrix(pb, 1, 0, 0, 1, 0, 0);
3102 }
3103 /* Track width and height, for visual only */
3104 if (st && (track->par->codec_type == AVMEDIA_TYPE_VIDEO ||
3105 track->par->codec_type == AVMEDIA_TYPE_SUBTITLE)) {
3106 int64_t track_width_1616;
3107 if (track->mode == MODE_MOV) {
3108 track_width_1616 = track->par->width * 0x10000ULL;
3109 } else {
3110 track_width_1616 = av_rescale(st->sample_aspect_ratio.num,
3111 track->par->width * 0x10000LL,
3112 st->sample_aspect_ratio.den);
3113 if (!track_width_1616 ||
3114 track->height != track->par->height ||
3115 track_width_1616 > UINT32_MAX)
3116 track_width_1616 = track->par->width * 0x10000ULL;
3117 }
3118 if (track_width_1616 > UINT32_MAX) {
3119 av_log(mov->fc, AV_LOG_WARNING, "track width is too large\n");
3120 track_width_1616 = 0;
3121 }
3122 avio_wb32(pb, track_width_1616);
3123 if (track->height > 0xFFFF) {
3124 av_log(mov->fc, AV_LOG_WARNING, "track height is too large\n");
3125 avio_wb32(pb, 0);
3126 } else
3127 avio_wb32(pb, track->height * 0x10000U);
3128 } else {
3129 avio_wb32(pb, 0);
3130 avio_wb32(pb, 0);
3131 }
3132 return 0x5c;
3133 }
3134
3135 static int mov_write_tapt_tag(AVIOContext *pb, MOVTrack *track)
3136 {
3137 int32_t width = av_rescale(track->par->sample_aspect_ratio.num, track->par->width,
3138 track->par->sample_aspect_ratio.den);
3139
3140 int64_t pos = avio_tell(pb);
3141
3142 avio_wb32(pb, 0); /* size */
3143 ffio_wfourcc(pb, "tapt");
3144
3145 avio_wb32(pb, 20);
3146 ffio_wfourcc(pb, "clef");
3147 avio_wb32(pb, 0);
3148 avio_wb32(pb, width << 16);
3149 avio_wb32(pb, track->par->height << 16);
3150
3151 avio_wb32(pb, 20);
3152 ffio_wfourcc(pb, "prof");
3153 avio_wb32(pb, 0);
3154 avio_wb32(pb, width << 16);
3155 avio_wb32(pb, track->par->height << 16);
3156
3157 avio_wb32(pb, 20);
3158 ffio_wfourcc(pb, "enof");
3159 avio_wb32(pb, 0);
3160 avio_wb32(pb, track->par->width << 16);
3161 avio_wb32(pb, track->par->height << 16);
3162
3163 return update_size(pb, pos);
3164 }
3165
3166 // This box seems important for the psp playback ... without it the movie seems to hang
3167 static int mov_write_edts_tag(AVIOContext *pb, MOVMuxContext *mov,
3168 MOVTrack *track)
3169 {
3170 int64_t duration = av_rescale_rnd(calc_samples_pts_duration(mov, track),
3171 mov->movie_timescale, track->timescale,
3172 AV_ROUND_UP);
3173 int version = duration < INT32_MAX ? 0 : 1;
3174 int entry_size, entry_count, size;
3175 int64_t delay, start_ct = track->start_cts;
3176 int64_t start_dts = track->start_dts;
3177
3178 if (track->entry) {
3179 if (start_dts != track->cluster[0].dts || start_ct != track->cluster[0].cts) {
3180
3181 av_log(mov->fc, AV_LOG_DEBUG,
3182 "EDTS using dts:%"PRId64" cts:%d instead of dts:%"PRId64" cts:%"PRId64" tid:%d\n",
3183 track->cluster[0].dts, track->cluster[0].cts,
3184 start_dts, start_ct, track->track_id);
3185 start_dts = track->cluster[0].dts;
3186 start_ct = track->cluster[0].cts;
3187 }
3188 }
3189
3190 delay = av_rescale_rnd(start_dts + start_ct, mov->movie_timescale,
3191 track->timescale, AV_ROUND_DOWN);
3192 version |= delay < INT32_MAX ? 0 : 1;
3193
3194 entry_size = (version == 1) ? 20 : 12;
3195 entry_count = 1 + (delay > 0);
3196 size = 24 + entry_count * entry_size;
3197
3198 /* write the atom data */
3199 avio_wb32(pb, size);
3200 ffio_wfourcc(pb, "edts");
3201 avio_wb32(pb, size - 8);
3202 ffio_wfourcc(pb, "elst");
3203 avio_w8(pb, version);
3204 avio_wb24(pb, 0); /* flags */
3205
3206 avio_wb32(pb, entry_count);
3207 if (delay > 0) { /* add an empty edit to delay presentation */
3208 /* In the positive delay case, the delay includes the cts
3209 * offset, and the second edit list entry below trims out
3210 * the same amount from the actual content. This makes sure
3211 * that the offset last sample is included in the edit
3212 * list duration as well. */
3213 if (version == 1) {
3214 avio_wb64(pb, delay);
3215 avio_wb64(pb, -1);
3216 } else {
3217 avio_wb32(pb, delay);
3218 avio_wb32(pb, -1);
3219 }
3220 avio_wb32(pb, 0x00010000);
3221 } else {
3222 /* Avoid accidentally ending up with start_ct = -1 which has got a
3223 * special meaning. Normally start_ct should end up positive or zero
3224 * here, but use FFMIN in case dts is a small positive integer
3225 * rounded to 0 when represented in movie timescale units. */
3226 av_assert0(av_rescale_rnd(start_dts, mov->movie_timescale, track->timescale, AV_ROUND_DOWN) <= 0);
3227 start_ct = -FFMIN(start_dts, 0);
3228 /* Note, this delay is calculated from the pts of the first sample,
3229 * ensuring that we don't reduce the duration for cases with
3230 * dts<0 pts=0. */
3231 duration += delay;
3232 }
3233
3234 /* For fragmented files, we don't know the full length yet. Setting
3235 * duration to 0 allows us to only specify the offset, including
3236 * the rest of the content (from all future fragments) without specifying
3237 * an explicit duration. */
3238 if (mov->flags & FF_MOV_FLAG_FRAGMENT)
3239 duration = 0;
3240
3241 /* duration */
3242 if (version == 1) {
3243 avio_wb64(pb, duration);
3244 avio_wb64(pb, start_ct);
3245 } else {
3246 avio_wb32(pb, duration);
3247 avio_wb32(pb, start_ct);
3248 }
3249 avio_wb32(pb, 0x00010000);
3250 return size;
3251 }
3252
3253 static int mov_write_tref_tag(AVIOContext *pb, MOVTrack *track)
3254 {
3255 avio_wb32(pb, 20); // size
3256 ffio_wfourcc(pb, "tref");
3257 avio_wb32(pb, 12); // size (subatom)
3258 avio_wl32(pb, track->tref_tag);
3259 avio_wb32(pb, track->tref_id);
3260 return 20;
3261 }
3262
3263 // goes at the end of each track! ... Critical for PSP playback ("Incompatible data" without it)
3264 static int mov_write_uuid_tag_psp(AVIOContext *pb, MOVTrack *mov)
3265 {
3266 avio_wb32(pb, 0x34); /* size ... reports as 28 in mp4box! */
3267 ffio_wfourcc(pb, "uuid");
3268 ffio_wfourcc(pb, "USMT");
3269 avio_wb32(pb, 0x21d24fce);
3270 avio_wb32(pb, 0xbb88695c);
3271 avio_wb32(pb, 0xfac9c740);
3272 avio_wb32(pb, 0x1c); // another size here!
3273 ffio_wfourcc(pb, "MTDT");
3274 avio_wb32(pb, 0x00010012);
3275 avio_wb32(pb, 0x0a);
3276 avio_wb32(pb, 0x55c40000);
3277 avio_wb32(pb, 0x1);
3278 avio_wb32(pb, 0x0);
3279 return 0x34;
3280 }
3281
3282 static int mov_write_udta_sdp(AVIOContext *pb, MOVTrack *track)
3283 {
3284 AVFormatContext *ctx = track->rtp_ctx;
3285 char buf[1000] = "";
3286 int len;
3287
3288 ff_sdp_write_media(buf, sizeof(buf), ctx->streams[0], track->src_track,
3289 NULL, NULL, 0, 0, ctx);
3290 av_strlcatf(buf, sizeof(buf), "a=control:streamid=%d\r\n", track->track_id);
3291 len = strlen(buf);
3292
3293 avio_wb32(pb, len + 24);
3294 ffio_wfourcc(pb, "udta");
3295 avio_wb32(pb, len + 16);
3296 ffio_wfourcc(pb, "hnti");
3297 avio_wb32(pb, len + 8);
3298 ffio_wfourcc(pb, "sdp ");
3299 avio_write(pb, buf, len);
3300 return len + 24;
3301 }
3302
3303 static int mov_write_track_metadata(AVIOContext *pb, AVStream *st,
3304 const char *tag, const char *str)
3305 {
3306 int64_t pos = avio_tell(pb);
3307 AVDictionaryEntry *t = av_dict_get(st->metadata, str, NULL, 0);
3308 if (!t || !utf8len(t->value))
3309 return 0;
3310
3311 avio_wb32(pb, 0); /* size */
3312 ffio_wfourcc(pb, tag); /* type */
3313 avio_write(pb, t->value, strlen(t->value)); /* UTF8 string value */
3314 return update_size(pb, pos);
3315 }
3316
3317 static int mov_write_track_kind(AVIOContext *pb, const char *scheme_uri,
3318 const char *value)
3319 {
3320 int64_t pos = avio_tell(pb);
3321
3322 /* Box|FullBox basics */
3323 avio_wb32(pb, 0); /* size placeholder */
3324 ffio_wfourcc(pb, (const unsigned char *)"kind");
3325 avio_w8(pb, 0); /* version = 0 */
3326 avio_wb24(pb, 0); /* flags = 0 */
3327
3328 /* Required null-terminated scheme URI */
3329 avio_write(pb, (const unsigned char *)scheme_uri,
3330 strlen(scheme_uri));
3331 avio_w8(pb, 0);
3332
3333 /* Optional value string */
3334 if (value && value[0])
3335 avio_write(pb, (const unsigned char *)value,
3336 strlen(value));
3337
3338 avio_w8(pb, 0);
3339
3340 return update_size(pb, pos);
3341 }
3342
3343 static int mov_write_track_kinds(AVIOContext *pb, AVStream *st)
3344 {
3345 int ret = AVERROR_BUG;
3346
3347 for (int i = 0; ff_mov_track_kind_table[i].scheme_uri; i++) {
3348 const struct MP4TrackKindMapping map = ff_mov_track_kind_table[i];
3349
3350 for (int j = 0; map.value_maps[j].disposition; j++) {
3351 const struct MP4TrackKindValueMapping value_map = map.value_maps[j];
3352 if (!(st->disposition & value_map.disposition))
3353 continue;
3354
3355 if ((ret = mov_write_track_kind(pb, map.scheme_uri, value_map.value)) < 0)
3356 return ret;
3357 }
3358 }
3359
3360 return 0;
3361 }
3362
3363 static int mov_write_track_udta_tag(AVIOContext *pb, MOVMuxContext *mov,
3364 AVStream *st)
3365 {
3366 AVIOContext *pb_buf;
3367 int ret, size;
3368 uint8_t *buf;
3369
3370 if (!st)
3371 return 0;
3372
3373 ret = avio_open_dyn_buf(&pb_buf);
3374 if (ret < 0)
3375 return ret;
3376
3377 if (mov->mode & (MODE_MP4|MODE_MOV))
3378 mov_write_track_metadata(pb_buf, st, "name", "title");
3379
3380 if (mov->mode & MODE_MP4) {
3381 if ((ret = mov_write_track_kinds(pb_buf, st)) < 0)
3382 return ret;
3383 }
3384
3385 if ((size = avio_get_dyn_buf(pb_buf, &buf)) > 0) {
3386 avio_wb32(pb, size + 8);
3387 ffio_wfourcc(pb, "udta");
3388 avio_write(pb, buf, size);
3389 }
3390 ffio_free_dyn_buf(&pb_buf);
3391
3392 return 0;
3393 }
3394
3395 static int mov_write_trak_tag(AVFormatContext *s, AVIOContext *pb, MOVMuxContext *mov,
3396 MOVTrack *track, AVStream *st)
3397 {
3398 int64_t pos = avio_tell(pb);
3399 int entry_backup = track->entry;
3400 int chunk_backup = track->chunkCount;
3401 int ret;
3402
3403 /* If we want to have an empty moov, but some samples already have been
3404 * buffered (delay_moov), pretend that no samples have been written yet. */
3405 if (mov->flags & FF_MOV_FLAG_EMPTY_MOOV)
3406 track->chunkCount = track->entry = 0;
3407
3408 avio_wb32(pb, 0); /* size */
3409 ffio_wfourcc(pb, "trak");
3410 mov_write_tkhd_tag(pb, mov, track, st);
3411
3412 av_assert2(mov->use_editlist >= 0);
3413
3414 if (track->start_dts != AV_NOPTS_VALUE) {
3415 if (mov->use_editlist)
3416 mov_write_edts_tag(pb, mov, track); // PSP Movies and several other cases require edts box
3417 else if ((track->entry && track->cluster[0].dts) || track->mode == MODE_PSP || is_clcp_track(track))
3418 av_log(mov->fc, AV_LOG_WARNING,
3419 "Not writing any edit list even though one would have been required\n");
3420 }
3421
3422 if (track->tref_tag)
3423 mov_write_tref_tag(pb, track);
3424
3425 if ((ret = mov_write_mdia_tag(s, pb, mov, track)) < 0)
3426 return ret;
3427 if (track->mode == MODE_PSP)
3428 mov_write_uuid_tag_psp(pb, track); // PSP Movies require this uuid box
3429 if (track->tag == MKTAG('r','t','p',' '))
3430 mov_write_udta_sdp(pb, track);
3431 if (track->mode == MODE_MOV) {
3432 if (track->par->codec_type == AVMEDIA_TYPE_VIDEO) {
3433 double sample_aspect_ratio = av_q2d(st->sample_aspect_ratio);
3434 if (st->sample_aspect_ratio.num && 1.0 != sample_aspect_ratio) {
3435 mov_write_tapt_tag(pb, track);
3436 }
3437 }
3438 if (is_clcp_track(track) && st->sample_aspect_ratio.num) {
3439 mov_write_tapt_tag(pb, track);
3440 }
3441 }
3442 mov_write_track_udta_tag(pb, mov, st);
3443 track->entry = entry_backup;
3444 track->chunkCount = chunk_backup;
3445 return update_size(pb, pos);
3446 }
3447
3448 static int mov_write_iods_tag(AVIOContext *pb, MOVMuxContext *mov)
3449 {
3450 int i, has_audio = 0, has_video = 0;
3451 int64_t pos = avio_tell(pb);
3452 int audio_profile = mov->iods_audio_profile;
3453 int video_profile = mov->iods_video_profile;
3454 for (i = 0; i < mov->nb_streams; i++) {
3455 if (mov->tracks[i].entry > 0 || mov->flags & FF_MOV_FLAG_EMPTY_MOOV) {
3456 has_audio |= mov->tracks[i].par->codec_type == AVMEDIA_TYPE_AUDIO;
3457 has_video |= mov->tracks[i].par->codec_type == AVMEDIA_TYPE_VIDEO;
3458 }
3459 }
3460 if (audio_profile < 0)
3461 audio_profile = 0xFF - has_audio;
3462 if (video_profile < 0)
3463 video_profile = 0xFF - has_video;
3464 avio_wb32(pb, 0x0); /* size */
3465 ffio_wfourcc(pb, "iods");
3466 avio_wb32(pb, 0); /* version & flags */
3467 put_descr(pb, 0x10, 7);
3468 avio_wb16(pb, 0x004f);
3469 avio_w8(pb, 0xff);
3470 avio_w8(pb, 0xff);
3471 avio_w8(pb, audio_profile);
3472 avio_w8(pb, video_profile);
3473 avio_w8(pb, 0xff);
3474 return update_size(pb, pos);
3475 }
3476
3477 static int mov_write_trex_tag(AVIOContext *pb, MOVTrack *track)
3478 {
3479 avio_wb32(pb, 0x20); /* size */
3480 ffio_wfourcc(pb, "trex");
3481 avio_wb32(pb, 0); /* version & flags */
3482 avio_wb32(pb, track->track_id); /* track ID */
3483 avio_wb32(pb, 1); /* default sample description index */
3484 avio_wb32(pb, 0); /* default sample duration */
3485 avio_wb32(pb, 0); /* default sample size */
3486 avio_wb32(pb, 0); /* default sample flags */
3487 return 0;
3488 }
3489
3490 static int mov_write_mvex_tag(AVIOContext *pb, MOVMuxContext *mov)
3491 {
3492 int64_t pos = avio_tell(pb);
3493 int i;
3494 avio_wb32(pb, 0x0); /* size */
3495 ffio_wfourcc(pb, "mvex");
3496 for (i = 0; i < mov->nb_streams; i++)
3497 mov_write_trex_tag(pb, &mov->tracks[i]);
3498 return update_size(pb, pos);
3499 }
3500
3501 static int mov_write_mvhd_tag(AVIOContext *pb, MOVMuxContext *mov)
3502 {
3503 int max_track_id = 1, i;
3504 int64_t max_track_len = 0;
3505 int version;
3506
3507 for (i = 0; i < mov->nb_streams; i++) {
3508 if (mov->tracks[i].entry > 0 && mov->tracks[i].timescale) {
3509 int64_t max_track_len_temp = av_rescale_rnd(
3510 calc_pts_duration(mov, &mov->tracks[i]),
3511 mov->movie_timescale,
3512 mov->tracks[i].timescale,
3513 AV_ROUND_UP);
3514 if (max_track_len < max_track_len_temp)
3515 max_track_len = max_track_len_temp;
3516 if (max_track_id < mov->tracks[i].track_id)
3517 max_track_id = mov->tracks[i].track_id;
3518 }
3519 }
3520 /* If using delay_moov, make sure the output is the same as if no
3521 * samples had been written yet. */
3522 if (mov->flags & FF_MOV_FLAG_EMPTY_MOOV) {
3523 max_track_len = 0;
3524 max_track_id = 1;
3525 }
3526
3527 version = max_track_len < UINT32_MAX ? 0 : 1;
3528 avio_wb32(pb, version == 1 ? 120 : 108); /* size */
3529
3530 ffio_wfourcc(pb, "mvhd");
3531 avio_w8(pb, version);
3532 avio_wb24(pb, 0); /* flags */
3533 if (version == 1) {
3534 avio_wb64(pb, mov->time);
3535 avio_wb64(pb, mov->time);
3536 } else {
3537 avio_wb32(pb, mov->time); /* creation time */
3538 avio_wb32(pb, mov->time); /* modification time */
3539 }
3540 avio_wb32(pb, mov->movie_timescale);
3541 (version == 1) ? avio_wb64(pb, max_track_len) : avio_wb32(pb, max_track_len); /* duration of longest track */
3542
3543 avio_wb32(pb, 0x00010000); /* reserved (preferred rate) 1.0 = normal */
3544 avio_wb16(pb, 0x0100); /* reserved (preferred volume) 1.0 = normal */
3545 ffio_fill(pb, 0, 2 + 2 * 4); /* reserved */
3546
3547 /* Matrix structure */
3548 write_matrix(pb, 1, 0, 0, 1, 0, 0);
3549
3550 avio_wb32(pb, 0); /* reserved (preview time) */
3551 avio_wb32(pb, 0); /* reserved (preview duration) */
3552 avio_wb32(pb, 0); /* reserved (poster time) */
3553 avio_wb32(pb, 0); /* reserved (selection time) */
3554 avio_wb32(pb, 0); /* reserved (selection duration) */
3555 avio_wb32(pb, 0); /* reserved (current time) */
3556 avio_wb32(pb, max_track_id + 1); /* Next track id */
3557 return 0x6c;
3558 }
3559
3560 static int mov_write_itunes_hdlr_tag(AVIOContext *pb, MOVMuxContext *mov,
3561 AVFormatContext *s)
3562 {
3563 avio_wb32(pb, 33); /* size */
3564 ffio_wfourcc(pb, "hdlr");
3565 avio_wb32(pb, 0);
3566 avio_wb32(pb, 0);
3567 ffio_wfourcc(pb, "mdir");
3568 ffio_wfourcc(pb, "appl");
3569 avio_wb32(pb, 0);
3570 avio_wb32(pb, 0);
3571 avio_w8(pb, 0);
3572 return 33;
3573 }
3574
3575 /* helper function to write a data tag with the specified string as data */
3576 static int mov_write_string_data_tag(AVIOContext *pb, const char *data, int lang, int long_style)
3577 {
3578 size_t data_len = strlen(data);
3579 if (long_style) {
3580 int size = 16 + data_len;
3581 avio_wb32(pb, size); /* size */
3582 ffio_wfourcc(pb, "data");
3583 avio_wb32(pb, 1);
3584 avio_wb32(pb, 0);
3585 avio_write(pb, data, data_len);
3586 return size;
3587 } else {
3588 avio_wb16(pb, data_len); /* string length */
3589 if (!lang)
3590 lang = ff_mov_iso639_to_lang("und", 1);
3591 avio_wb16(pb, lang);
3592 avio_write(pb, data, data_len);
3593 return data_len + 4;
3594 }
3595 }
3596
3597 static int mov_write_string_tag(AVIOContext *pb, const char *name,
3598 const char *value, int lang, int long_style)
3599 {
3600 int size = 0;
3601 if (value && value[0]) {
3602 int64_t pos = avio_tell(pb);
3603 avio_wb32(pb, 0); /* size */
3604 ffio_wfourcc(pb, name);
3605 mov_write_string_data_tag(pb, value, lang, long_style);
3606 size = update_size(pb, pos);
3607 }
3608 return size;
3609 }
3610
3611 static AVDictionaryEntry *get_metadata_lang(AVFormatContext *s,
3612 const char *tag, int *lang)
3613 {
3614 int l, len, len2;
3615 AVDictionaryEntry *t, *t2 = NULL;
3616 char tag2[16];
3617
3618 *lang = 0;
3619
3620 if (!(t = av_dict_get(s->metadata, tag, NULL, 0)))
3621 return NULL;
3622
3623 len = strlen(t->key);
3624 snprintf(tag2, sizeof(tag2), "%s-", tag);
3625 while ((t2 = av_dict_get(s->metadata, tag2, t2, AV_DICT_IGNORE_SUFFIX))) {
3626 len2 = strlen(t2->key);
3627 if (len2 == len + 4 && !strcmp(t->value, t2->value)
3628 && (l = ff_mov_iso639_to_lang(&t2->key[len2 - 3], 1)) >= 0) {
3629 *lang = l;
3630 return t;
3631 }
3632 }
3633 return t;
3634 }
3635
3636 static int mov_write_string_metadata(AVFormatContext *s, AVIOContext *pb,
3637 const char *name, const char *tag,
3638 int long_style)
3639 {
3640 int lang;
3641 AVDictionaryEntry *t = get_metadata_lang(s, tag, &lang);
3642 if (!t)
3643 return 0;
3644 return mov_write_string_tag(pb, name, t->value, lang, long_style);
3645 }
3646
3647 /* iTunes bpm number */
3648 static int mov_write_tmpo_tag(AVIOContext *pb, AVFormatContext *s)
3649 {
3650 AVDictionaryEntry *t = av_dict_get(s->metadata, "tmpo", NULL, 0);
3651 int size = 0, tmpo = t ? atoi(t->value) : 0;
3652 if (tmpo) {
3653 size = 26;
3654 avio_wb32(pb, size);
3655 ffio_wfourcc(pb, "tmpo");
3656 avio_wb32(pb, size-8); /* size */
3657 ffio_wfourcc(pb, "data");
3658 avio_wb32(pb, 0x15); //type specifier
3659 avio_wb32(pb, 0);
3660 avio_wb16(pb, tmpo); // data
3661 }
3662 return size;
3663 }
3664
3665 /* 3GPP TS 26.244 */
3666 static int mov_write_loci_tag(AVFormatContext *s, AVIOContext *pb)
3667 {
3668 int lang;
3669 int64_t pos = avio_tell(pb);
3670 double latitude, longitude, altitude;
3671 int32_t latitude_fix, longitude_fix, altitude_fix;
3672 AVDictionaryEntry *t = get_metadata_lang(s, "location", &lang);
3673 const char *ptr, *place = "";
3674 char *end;
3675 static const char *astronomical_body = "earth";
3676 if (!t)
3677 return 0;
3678
3679 ptr = t->value;
3680 longitude = strtod(ptr, &end);
3681 if (end == ptr) {
3682 av_log(s, AV_LOG_WARNING, "malformed location metadata\n");
3683 return 0;
3684 }
3685 ptr = end;
3686 latitude = strtod(ptr, &end);
3687 if (end == ptr) {
3688 av_log(s, AV_LOG_WARNING, "malformed location metadata\n");
3689 return 0;
3690 }
3691 ptr = end;
3692 altitude = strtod(ptr, &end);
3693 /* If no altitude was present, the default 0 should be fine */
3694 if (*end == '/')
3695 place = end + 1;
3696
3697 latitude_fix = (int32_t) ((1 << 16) * latitude);
3698 longitude_fix = (int32_t) ((1 << 16) * longitude);
3699 altitude_fix = (int32_t) ((1 << 16) * altitude);
3700
3701 avio_wb32(pb, 0); /* size */
3702 ffio_wfourcc(pb, "loci"); /* type */
3703 avio_wb32(pb, 0); /* version + flags */
3704 avio_wb16(pb, lang);
3705 avio_write(pb, place, strlen(place) + 1);
3706 avio_w8(pb, 0); /* role of place (0 == shooting location, 1 == real location, 2 == fictional location) */
3707 avio_wb32(pb, latitude_fix);
3708 avio_wb32(pb, longitude_fix);
3709 avio_wb32(pb, altitude_fix);
3710 avio_write(pb, astronomical_body, strlen(astronomical_body) + 1);
3711 avio_w8(pb, 0); /* additional notes, null terminated string */
3712
3713 return update_size(pb, pos);
3714 }
3715
3716 /* iTunes track or disc number */
3717 static int mov_write_trkn_tag(AVIOContext *pb, MOVMuxContext *mov,
3718 AVFormatContext *s, int disc)
3719 {
3720 AVDictionaryEntry *t = av_dict_get(s->metadata,
3721 disc ? "disc" : "track",
3722 NULL, 0);
3723 int size = 0, track = t ? atoi(t->value) : 0;
3724 if (track) {
3725 int tracks = 0;
3726 char *slash = strchr(t->value, '/');
3727 if (slash)
3728 tracks = atoi(slash + 1);
3729 avio_wb32(pb, 32); /* size */
3730 ffio_wfourcc(pb, disc ? "disk" : "trkn");
3731 avio_wb32(pb, 24); /* size */
3732 ffio_wfourcc(pb, "data");
3733 avio_wb32(pb, 0); // 8 bytes empty
3734 avio_wb32(pb, 0);
3735 avio_wb16(pb, 0); // empty
3736 avio_wb16(pb, track); // track / disc number
3737 avio_wb16(pb, tracks); // total track / disc number
3738 avio_wb16(pb, 0); // empty
3739 size = 32;
3740 }
3741 return size;
3742 }
3743
3744 static int mov_write_int8_metadata(AVFormatContext *s, AVIOContext *pb,
3745 const char *name, const char *tag,
3746 int len)
3747 {
3748 AVDictionaryEntry *t = NULL;
3749 uint8_t num;
3750 int size = 24 + len;
3751
3752 if (len != 1 && len != 4)
3753 return -1;
3754
3755 if (!(t = av_dict_get(s->metadata, tag, NULL, 0)))
3756 return 0;
3757 num = atoi(t->value);
3758
3759 avio_wb32(pb, size);
3760 ffio_wfourcc(pb, name);
3761 avio_wb32(pb, size - 8);
3762 ffio_wfourcc(pb, "data");
3763 avio_wb32(pb, 0x15);
3764 avio_wb32(pb, 0);
3765 if (len==4) avio_wb32(pb, num);
3766 else avio_w8 (pb, num);
3767
3768 return size;
3769 }
3770
3771 static int mov_write_covr(AVIOContext *pb, AVFormatContext *s)
3772 {
3773 MOVMuxContext *mov = s->priv_data;
3774 int64_t pos = 0;
3775 int i;
3776
3777 for (i = 0; i < s->nb_streams; i++) {
3778 MOVTrack *trk = &mov->tracks[i];
3779
3780 if (!is_cover_image(trk->st) || trk->cover_image->size <= 0)
3781 continue;
3782
3783 if (!pos) {
3784 pos = avio_tell(pb);
3785 avio_wb32(pb, 0);
3786 ffio_wfourcc(pb, "covr");
3787 }
3788 avio_wb32(pb, 16 + trk->cover_image->size);
3789 ffio_wfourcc(pb, "data");
3790 avio_wb32(pb, trk->tag);
3791 avio_wb32(pb , 0);
3792 avio_write(pb, trk->cover_image->data, trk->cover_image->size);
3793 }
3794
3795 return pos ? update_size(pb, pos) : 0;
3796 }
3797
3798 /* iTunes meta data list */
3799 static int mov_write_ilst_tag(AVIOContext *pb, MOVMuxContext *mov,
3800 AVFormatContext *s)
3801 {
3802 int64_t pos = avio_tell(pb);
3803 avio_wb32(pb, 0); /* size */
3804 ffio_wfourcc(pb, "ilst");
3805 mov_write_string_metadata(s, pb, "\251nam", "title" , 1);
3806 mov_write_string_metadata(s, pb, "\251ART", "artist" , 1);
3807 mov_write_string_metadata(s, pb, "aART", "album_artist", 1);
3808 mov_write_string_metadata(s, pb, "\251wrt", "composer" , 1);
3809 mov_write_string_metadata(s, pb, "\251alb", "album" , 1);
3810 mov_write_string_metadata(s, pb, "\251day", "date" , 1);
3811 if (!mov_write_string_metadata(s, pb, "\251too", "encoding_tool", 1)) {
3812 if (!(s->flags & AVFMT_FLAG_BITEXACT))
3813 mov_write_string_tag(pb, "\251too", LIBAVFORMAT_IDENT, 0, 1);
3814 }
3815 mov_write_string_metadata(s, pb, "\251cmt", "comment" , 1);
3816 mov_write_string_metadata(s, pb, "\251gen", "genre" , 1);
3817 mov_write_string_metadata(s, pb, "cprt", "copyright", 1);
3818 mov_write_string_metadata(s, pb, "\251grp", "grouping" , 1);
3819 mov_write_string_metadata(s, pb, "\251lyr", "lyrics" , 1);
3820 mov_write_string_metadata(s, pb, "desc", "description",1);
3821 mov_write_string_metadata(s, pb, "ldes", "synopsis" , 1);
3822 mov_write_string_metadata(s, pb, "tvsh", "show" , 1);
3823 mov_write_string_metadata(s, pb, "tven", "episode_id",1);
3824 mov_write_string_metadata(s, pb, "tvnn", "network" , 1);
3825 mov_write_string_metadata(s, pb, "keyw", "keywords" , 1);
3826 mov_write_int8_metadata (s, pb, "tves", "episode_sort",4);
3827 mov_write_int8_metadata (s, pb, "tvsn", "season_number",4);
3828 mov_write_int8_metadata (s, pb, "stik", "media_type",1);
3829 mov_write_int8_metadata (s, pb, "hdvd", "hd_video", 1);
3830 mov_write_int8_metadata (s, pb, "pgap", "gapless_playback",1);
3831 mov_write_int8_metadata (s, pb, "cpil", "compilation", 1);
3832 mov_write_covr(pb, s);
3833 mov_write_trkn_tag(pb, mov, s, 0); // track number
3834 mov_write_trkn_tag(pb, mov, s, 1); // disc number
3835 mov_write_tmpo_tag(pb, s);
3836 return update_size(pb, pos);
3837 }
3838
3839 static int mov_write_mdta_hdlr_tag(AVIOContext *pb, MOVMuxContext *mov,
3840 AVFormatContext *s)
3841 {
3842 avio_wb32(pb, 33); /* size */
3843 ffio_wfourcc(pb, "hdlr");
3844 avio_wb32(pb, 0);
3845 avio_wb32(pb, 0);
3846 ffio_wfourcc(pb, "mdta");
3847 avio_wb32(pb, 0);
3848 avio_wb32(pb, 0);
3849 avio_wb32(pb, 0);
3850 avio_w8(pb, 0);
3851 return 33;
3852 }
3853
3854 static int mov_write_mdta_keys_tag(AVIOContext *pb, MOVMuxContext *mov,
3855 AVFormatContext *s)
3856 {
3857 AVDictionaryEntry *t = NULL;
3858 int64_t pos = avio_tell(pb);
3859 int64_t curpos, entry_pos;
3860 int count = 0;
3861
3862 avio_wb32(pb, 0); /* size */
3863 ffio_wfourcc(pb, "keys");
3864 avio_wb32(pb, 0);
3865 entry_pos = avio_tell(pb);
3866 avio_wb32(pb, 0); /* entry count */
3867
3868 while (t = av_dict_get(s->metadata, "", t, AV_DICT_IGNORE_SUFFIX)) {
3869 size_t key_len = strlen(t->key);
3870 avio_wb32(pb, key_len + 8);
3871 ffio_wfourcc(pb, "mdta");
3872 avio_write(pb, t->key, key_len);
3873 count += 1;
3874 }
3875 curpos = avio_tell(pb);
3876 avio_seek(pb, entry_pos, SEEK_SET);
3877 avio_wb32(pb, count); // rewrite entry count
3878 avio_seek(pb, curpos, SEEK_SET);
3879
3880 return update_size(pb, pos);
3881 }
3882
3883 static int mov_write_mdta_ilst_tag(AVIOContext *pb, MOVMuxContext *mov,
3884 AVFormatContext *s)
3885 {
3886 AVDictionaryEntry *t = NULL;
3887 int64_t pos = avio_tell(pb);
3888 int count = 1; /* keys are 1-index based */
3889
3890 avio_wb32(pb, 0); /* size */
3891 ffio_wfourcc(pb, "ilst");
3892
3893 while (t = av_dict_get(s->metadata, "", t, AV_DICT_IGNORE_SUFFIX)) {
3894 int64_t entry_pos = avio_tell(pb);
3895 avio_wb32(pb, 0); /* size */
3896 avio_wb32(pb, count); /* key */
3897 mov_write_string_data_tag(pb, t->value, 0, 1);
3898 update_size(pb, entry_pos);
3899 count += 1;
3900 }
3901 return update_size(pb, pos);
3902 }
3903
3904 /* meta data tags */
3905 static int mov_write_meta_tag(AVIOContext *pb, MOVMuxContext *mov,
3906 AVFormatContext *s)
3907 {
3908 int size = 0;
3909 int64_t pos = avio_tell(pb);
3910 avio_wb32(pb, 0); /* size */
3911 ffio_wfourcc(pb, "meta");
3912 avio_wb32(pb, 0);
3913 if (mov->flags & FF_MOV_FLAG_USE_MDTA) {
3914 mov_write_mdta_hdlr_tag(pb, mov, s);
3915 mov_write_mdta_keys_tag(pb, mov, s);
3916 mov_write_mdta_ilst_tag(pb, mov, s);
3917 }
3918 else {
3919 /* iTunes metadata tag */
3920 mov_write_itunes_hdlr_tag(pb, mov, s);
3921 mov_write_ilst_tag(pb, mov, s);
3922 }
3923 size = update_size(pb, pos);
3924 return size;
3925 }
3926
3927 static int mov_write_raw_metadata_tag(AVFormatContext *s, AVIOContext *pb,
3928 const char *name, const char *key)
3929 {
3930 int len;
3931 AVDictionaryEntry *t;
3932
3933 if (!(t = av_dict_get(s->metadata, key, NULL, 0)))
3934 return 0;
3935
3936 len = strlen(t->value);
3937 if (len > 0) {
3938 int size = len + 8;
3939 avio_wb32(pb, size);
3940 ffio_wfourcc(pb, name);
3941 avio_write(pb, t->value, len);
3942 return size;
3943 }
3944 return 0;
3945 }
3946
3947 static int ascii_to_wc(AVIOContext *pb, const uint8_t *b)
3948 {
3949 int val;
3950 while (*b) {
3951 GET_UTF8(val, *b++, return -1;)
3952 avio_wb16(pb, val);
3953 }
3954 avio_wb16(pb, 0x00);
3955 return 0;
3956 }
3957
3958 static uint16_t language_code(const char *str)
3959 {
3960 return (((str[0] - 0x60) & 0x1F) << 10) +
3961 (((str[1] - 0x60) & 0x1F) << 5) +
3962 (( str[2] - 0x60) & 0x1F);
3963 }
3964
3965 static int mov_write_3gp_udta_tag(AVIOContext *pb, AVFormatContext *s,
3966 const char *tag, const char *str)
3967 {
3968 int64_t pos = avio_tell(pb);
3969 AVDictionaryEntry *t = av_dict_get(s->metadata, str, NULL, 0);
3970 if (!t || !utf8len(t->value))
3971 return 0;
3972 avio_wb32(pb, 0); /* size */
3973 ffio_wfourcc(pb, tag); /* type */
3974 avio_wb32(pb, 0); /* version + flags */
3975 if (!strcmp(tag, "yrrc"))
3976 avio_wb16(pb, atoi(t->value));
3977 else {
3978 avio_wb16(pb, language_code("eng")); /* language */
3979 avio_write(pb, t->value, strlen(t->value) + 1); /* UTF8 string value */
3980 if (!strcmp(tag, "albm") &&
3981 (t = av_dict_get(s->metadata, "track", NULL, 0)))
3982 avio_w8(pb, atoi(t->value));
3983 }
3984 return update_size(pb, pos);
3985 }
3986
3987 static int mov_write_chpl_tag(AVIOContext *pb, AVFormatContext *s)
3988 {
3989 int64_t pos = avio_tell(pb);
3990 int i, nb_chapters = FFMIN(s->nb_chapters, 255);
3991
3992 avio_wb32(pb, 0); // size
3993 ffio_wfourcc(pb, "chpl");
3994 avio_wb32(pb, 0x01000000); // version + flags
3995 avio_wb32(pb, 0); // unknown
3996 avio_w8(pb, nb_chapters);
3997
3998 for (i = 0; i < nb_chapters; i++) {
3999 AVChapter *c = s->chapters[i];
4000 AVDictionaryEntry *t;
4001 avio_wb64(pb, av_rescale_q(c->start, c->time_base, (AVRational){1,10000000}));
4002
4003 if ((t = av_dict_get(c->metadata, "title", NULL, 0))) {
4004 int len = FFMIN(strlen(t->value), 255);
4005 avio_w8(pb, len);
4006 avio_write(pb, t->value, len);
4007 } else
4008 avio_w8(pb, 0);
4009 }
4010 return update_size(pb, pos);
4011 }
4012
4013 static int mov_write_udta_tag(AVIOContext *pb, MOVMuxContext *mov,
4014 AVFormatContext *s)
4015 {
4016 AVIOContext *pb_buf;
4017 int ret, size;
4018 uint8_t *buf;
4019
4020 ret = avio_open_dyn_buf(&pb_buf);
4021 if (ret < 0)
4022 return ret;
4023
4024 if (mov->mode & MODE_3GP) {
4025 mov_write_3gp_udta_tag(pb_buf, s, "perf", "artist");
4026 mov_write_3gp_udta_tag(pb_buf, s, "titl", "title");
4027 mov_write_3gp_udta_tag(pb_buf, s, "auth", "author");
4028 mov_write_3gp_udta_tag(pb_buf, s, "gnre", "genre");
4029 mov_write_3gp_udta_tag(pb_buf, s, "dscp", "comment");
4030 mov_write_3gp_udta_tag(pb_buf, s, "albm", "album");
4031 mov_write_3gp_udta_tag(pb_buf, s, "cprt", "copyright");
4032 mov_write_3gp_udta_tag(pb_buf, s, "yrrc", "date");
4033 mov_write_loci_tag(s, pb_buf);
4034 } else if (mov->mode == MODE_MOV && !(mov->flags & FF_MOV_FLAG_USE_MDTA)) { // the title field breaks gtkpod with mp4 and my suspicion is that stuff is not valid in mp4
4035 mov_write_string_metadata(s, pb_buf, "\251ART", "artist", 0);
4036 mov_write_string_metadata(s, pb_buf, "\251nam", "title", 0);
4037 mov_write_string_metadata(s, pb_buf, "\251aut", "author", 0);
4038 mov_write_string_metadata(s, pb_buf, "\251alb", "album", 0);
4039 mov_write_string_metadata(s, pb_buf, "\251day", "date", 0);
4040 mov_write_string_metadata(s, pb_buf, "\251swr", "encoder", 0);
4041 // currently ignored by mov.c
4042 mov_write_string_metadata(s, pb_buf, "\251des", "comment", 0);
4043 // add support for libquicktime, this atom is also actually read by mov.c
4044 mov_write_string_metadata(s, pb_buf, "\251cmt", "comment", 0);
4045 mov_write_string_metadata(s, pb_buf, "\251gen", "genre", 0);
4046 mov_write_string_metadata(s, pb_buf, "\251cpy", "copyright", 0);
4047 mov_write_string_metadata(s, pb_buf, "\251mak", "make", 0);
4048 mov_write_string_metadata(s, pb_buf, "\251mod", "model", 0);
4049 mov_write_string_metadata(s, pb_buf, "\251xyz", "location", 0);
4050 mov_write_string_metadata(s, pb_buf, "\251key", "keywords", 0);
4051 mov_write_raw_metadata_tag(s, pb_buf, "XMP_", "xmp");
4052 } else {
4053 /* iTunes meta data */
4054 mov_write_meta_tag(pb_buf, mov, s);
4055 mov_write_loci_tag(s, pb_buf);
4056 }
4057
4058 if (s->nb_chapters && !(mov->flags & FF_MOV_FLAG_DISABLE_CHPL))
4059 mov_write_chpl_tag(pb_buf, s);
4060
4061 if ((size = avio_get_dyn_buf(pb_buf, &buf)) > 0) {
4062 avio_wb32(pb, size + 8);
4063 ffio_wfourcc(pb, "udta");
4064 avio_write(pb, buf, size);
4065 }
4066 ffio_free_dyn_buf(&pb_buf);
4067
4068 return 0;
4069 }
4070
4071 static void mov_write_psp_udta_tag(AVIOContext *pb,
4072 const char *str, const char *lang, int type)
4073 {
4074 int len = utf8len(str) + 1;
4075 if (len <= 0)
4076 return;
4077 avio_wb16(pb, len * 2 + 10); /* size */
4078 avio_wb32(pb, type); /* type */
4079 avio_wb16(pb, language_code(lang)); /* language */
4080 avio_wb16(pb, 0x01); /* ? */
4081 ascii_to_wc(pb, str);
4082 }
4083
4084 static int mov_write_uuidusmt_tag(AVIOContext *pb, AVFormatContext *s)
4085 {
4086 AVDictionaryEntry *title = av_dict_get(s->metadata, "title", NULL, 0);
4087 int64_t pos, pos2;
4088
4089 if (title) {
4090 pos = avio_tell(pb);
4091 avio_wb32(pb, 0); /* size placeholder*/
4092 ffio_wfourcc(pb, "uuid");
4093 ffio_wfourcc(pb, "USMT");
4094 avio_wb32(pb, 0x21d24fce); /* 96 bit UUID */
4095 avio_wb32(pb, 0xbb88695c);
4096 avio_wb32(pb, 0xfac9c740);
4097
4098 pos2 = avio_tell(pb);
4099 avio_wb32(pb, 0); /* size placeholder*/
4100 ffio_wfourcc(pb, "MTDT");
4101 avio_wb16(pb, 4);
4102
4103 // ?
4104 avio_wb16(pb, 0x0C); /* size */
4105 avio_wb32(pb, 0x0B); /* type */
4106 avio_wb16(pb, language_code("und")); /* language */
4107 avio_wb16(pb, 0x0); /* ? */
4108 avio_wb16(pb, 0x021C); /* data */
4109
4110 if (!(s->flags & AVFMT_FLAG_BITEXACT))
4111 mov_write_psp_udta_tag(pb, LIBAVCODEC_IDENT, "eng", 0x04);
4112 mov_write_psp_udta_tag(pb, title->value, "eng", 0x01);
4113 mov_write_psp_udta_tag(pb, "2006/04/01 11:11:11", "und", 0x03);
4114
4115 update_size(pb, pos2);
4116 return update_size(pb, pos);
4117 }
4118
4119 return 0;
4120 }
4121
4122 static void build_chunks(MOVTrack *trk)
4123 {
4124 int i;
4125 MOVIentry *chunk = &trk->cluster[0];
4126 uint64_t chunkSize = chunk->size;
4127 chunk->chunkNum = 1;
4128 if (trk->chunkCount)
4129 return;
4130 trk->chunkCount = 1;
4131 for (i = 1; i<trk->entry; i++){
4132 if (chunk->pos + chunkSize == trk->cluster[i].pos &&
4133 chunkSize + trk->cluster[i].size < (1<<20)){
4134 chunkSize += trk->cluster[i].size;
4135 chunk->samples_in_chunk += trk->cluster[i].entries;
4136 } else {
4137 trk->cluster[i].chunkNum = chunk->chunkNum+1;
4138 chunk=&trk->cluster[i];
4139 chunkSize = chunk->size;
4140 trk->chunkCount++;
4141 }
4142 }
4143 }
4144
4145 /**
4146 * Assign track ids. If option "use_stream_ids_as_track_ids" is set,
4147 * the stream ids are used as track ids.
4148 *
4149 * This assumes mov->tracks and s->streams are in the same order and
4150 * there are no gaps in either of them (so mov->tracks[n] refers to
4151 * s->streams[n]).
4152 *
4153 * As an exception, there can be more entries in
4154 * s->streams than in mov->tracks, in which case new track ids are
4155 * generated (starting after the largest found stream id).
4156 */
4157 static int mov_setup_track_ids(MOVMuxContext *mov, AVFormatContext *s)
4158 {
4159 int i;
4160
4161 if (mov->track_ids_ok)
4162 return 0;
4163
4164 if (mov->use_stream_ids_as_track_ids) {
4165 int next_generated_track_id = 0;
4166 for (i = 0; i < s->nb_streams; i++) {
4167 if (s->streams[i]->id > next_generated_track_id)
4168 next_generated_track_id = s->streams[i]->id;
4169 }
4170
4171 for (i = 0; i < mov->nb_streams; i++) {
4172 if (mov->tracks[i].entry <= 0 && !(mov->flags & FF_MOV_FLAG_FRAGMENT))
4173 continue;
4174
4175 mov->tracks[i].track_id = i >= s->nb_streams ? ++next_generated_track_id : s->streams[i]->id;
4176 }
4177 } else {
4178 for (i = 0; i < mov->nb_streams; i++) {
4179 if (mov->tracks[i].entry <= 0 && !(mov->flags & FF_MOV_FLAG_FRAGMENT))
4180 continue;
4181
4182 mov->tracks[i].track_id = i + 1;
4183 }
4184 }
4185
4186 mov->track_ids_ok = 1;
4187
4188 return 0;
4189 }
4190
4191 static int mov_write_moov_tag(AVIOContext *pb, MOVMuxContext *mov,
4192 AVFormatContext *s)
4193 {
4194 int i;
4195 int64_t pos = avio_tell(pb);
4196 avio_wb32(pb, 0); /* size placeholder*/
4197 ffio_wfourcc(pb, "moov");
4198
4199 mov_setup_track_ids(mov, s);
4200
4201 for (i = 0; i < mov->nb_streams; i++) {
4202 if (mov->tracks[i].entry <= 0 && !(mov->flags & FF_MOV_FLAG_FRAGMENT))
4203 continue;
4204
4205 mov->tracks[i].time = mov->time;
4206
4207 if (mov->tracks[i].entry)
4208 build_chunks(&mov->tracks[i]);
4209 }
4210
4211 if (mov->chapter_track)
4212 for (i = 0; i < s->nb_streams; i++) {
4213 mov->tracks[i].tref_tag = MKTAG('c','h','a','p');
4214 mov->tracks[i].tref_id = mov->tracks[mov->chapter_track].track_id;
4215 }
4216 for (i = 0; i < mov->nb_streams; i++) {
4217 MOVTrack *track = &mov->tracks[i];
4218 if (track->tag == MKTAG('r','t','p',' ')) {
4219 track->tref_tag = MKTAG('h','i','n','t');
4220 track->tref_id = mov->tracks[track->src_track].track_id;
4221 } else if (track->par->codec_type == AVMEDIA_TYPE_AUDIO) {
4222 size_t size;
4223 int *fallback;
4224 fallback = (int*)av_stream_get_side_data(track->st,
4225 AV_PKT_DATA_FALLBACK_TRACK,
4226 &size);
4227 if (fallback != NULL && size == sizeof(int)) {
4228 if (*fallback >= 0 && *fallback < mov->nb_streams) {
4229 track->tref_tag = MKTAG('f','a','l','l');
4230 track->tref_id = mov->tracks[*fallback].track_id;
4231 }
4232 }
4233 }
4234 }
4235 for (i = 0; i < mov->nb_streams; i++) {
4236 if (mov->tracks[i].tag == MKTAG('t','m','c','d')) {
4237 int src_trk = mov->tracks[i].src_track;
4238 mov->tracks[src_trk].tref_tag = mov->tracks[i].tag;
4239 mov->tracks[src_trk].tref_id = mov->tracks[i].track_id;
4240 //src_trk may have a different timescale than the tmcd track
4241 mov->tracks[i].track_duration = av_rescale(mov->tracks[src_trk].track_duration,
4242 mov->tracks[i].timescale,
4243 mov->tracks[src_trk].timescale);
4244 }
4245 }
4246
4247 mov_write_mvhd_tag(pb, mov);
4248 if (mov->mode != MODE_MOV && !mov->iods_skip)
4249 mov_write_iods_tag(pb, mov);
4250 for (i = 0; i < mov->nb_streams; i++) {
4251 if (mov->tracks[i].entry > 0 || mov->flags & FF_MOV_FLAG_FRAGMENT) {
4252 int ret = mov_write_trak_tag(s, pb, mov, &(mov->tracks[i]), i < s->nb_streams ? s->streams[i] : NULL);
4253 if (ret < 0)
4254 return ret;
4255 }
4256 }
4257 if (mov->flags & FF_MOV_FLAG_FRAGMENT)
4258 mov_write_mvex_tag(pb, mov); /* QuickTime requires trak to precede this */
4259
4260 if (mov->mode == MODE_PSP)
4261 mov_write_uuidusmt_tag(pb, s);
4262 else
4263 mov_write_udta_tag(pb, mov, s);
4264
4265 return update_size(pb, pos);
4266 }
4267
4268 static void param_write_int(AVIOContext *pb, const char *name, int value)
4269 {
4270 avio_printf(pb, "<param name=\"%s\" value=\"%d\" valuetype=\"data\"/>\n", name, value);
4271 }
4272
4273 static void param_write_string(AVIOContext *pb, const char *name, const char *value)
4274 {
4275 avio_printf(pb, "<param name=\"%s\" value=\"%s\" valuetype=\"data\"/>\n", name, value);
4276 }
4277
4278 static void param_write_hex(AVIOContext *pb, const char *name, const uint8_t *value, int len)
4279 {
4280 char buf[150];
4281 len = FFMIN(sizeof(buf) / 2 - 1, len);
4282 ff_data_to_hex(buf, value, len, 0);
4283 avio_printf(pb, "<param name=\"%s\" value=\"%s\" valuetype=\"data\"/>\n", name, buf);
4284 }
4285
4286 static int mov_write_isml_manifest(AVIOContext *pb, MOVMuxContext *mov, AVFormatContext *s)
4287 {
4288 int64_t pos = avio_tell(pb);
4289 int i;
4290
4291 static const uint8_t uuid[] = {
4292 0xa5, 0xd4, 0x0b, 0x30, 0xe8, 0x14, 0x11, 0xdd,
4293 0xba, 0x2f, 0x08, 0x00, 0x20, 0x0c, 0x9a, 0x66
4294 };
4295
4296 avio_wb32(pb, 0);
4297 ffio_wfourcc(pb, "uuid");
4298 avio_write(pb, uuid, sizeof(uuid));
4299 avio_wb32(pb, 0);
4300
4301 avio_printf(pb, "<?xml version=\"1.0\" encoding=\"utf-8\"?>\n");
4302 avio_printf(pb, "<smil xmlns=\"http://www.w3.org/2001/SMIL20/Language\">\n");
4303 avio_printf(pb, "<head>\n");
4304 if (!(mov->fc->flags & AVFMT_FLAG_BITEXACT))
4305 avio_printf(pb, "<meta name=\"creator\" content=\"%s\" />\n",
4306 LIBAVFORMAT_IDENT);
4307 avio_printf(pb, "</head>\n");
4308 avio_printf(pb, "<body>\n");
4309 avio_printf(pb, "<switch>\n");
4310
4311 mov_setup_track_ids(mov, s);
4312
4313 for (i = 0; i < mov->nb_streams; i++) {
4314 MOVTrack *track = &mov->tracks[i];
4315 struct mpeg4_bit_rate_values bit_rates =
4316 calculate_mpeg4_bit_rates(track);
4317 const char *type;
4318 int track_id = track->track_id;
4319 char track_name_buf[32] = { 0 };
4320
4321 AVStream *st = track->st;
4322 AVDictionaryEntry *lang = av_dict_get(st->metadata, "language", NULL,0);
4323
4324 if (track->par->codec_type == AVMEDIA_TYPE_VIDEO && !is_cover_image(st)) {
4325 type = "video";
4326 } else if (track->par->codec_type == AVMEDIA_TYPE_AUDIO) {
4327 type = "audio";
4328 } else {
4329 continue;
4330 }
4331
4332 avio_printf(pb, "<%s systemBitrate=\"%"PRIu32"\">\n", type,
4333 bit_rates.avg_bit_rate);
4334 param_write_int(pb, "systemBitrate", bit_rates.avg_bit_rate);
4335 param_write_int(pb, "trackID", track_id);
4336 param_write_string(pb, "systemLanguage", lang ? lang->value : "und");
4337
4338 /* Build track name piece by piece: */
4339 /* 1. track type */
4340 av_strlcat(track_name_buf, type, sizeof(track_name_buf));
4341 /* 2. track language, if available */
4342 if (lang)
4343 av_strlcatf(track_name_buf, sizeof(track_name_buf),
4344 "_%s", lang->value);
4345 /* 3. special type suffix */
4346 /* "_cc" = closed captions, "_ad" = audio_description */
4347 if (st->disposition & AV_DISPOSITION_HEARING_IMPAIRED)
4348 av_strlcat(track_name_buf, "_cc", sizeof(track_name_buf));
4349 else if (st->disposition & AV_DISPOSITION_VISUAL_IMPAIRED)
4350 av_strlcat(track_name_buf, "_ad", sizeof(track_name_buf));
4351
4352 param_write_string(pb, "trackName", track_name_buf);
4353
4354 if (track->par->codec_type == AVMEDIA_TYPE_VIDEO) {
4355 if (track->par->codec_id == AV_CODEC_ID_H264) {
4356 uint8_t *ptr;
4357 int size = track->par->extradata_size;
4358 if (!ff_avc_write_annexb_extradata(track->par->extradata, &ptr,
4359 &size)) {
4360 param_write_hex(pb, "CodecPrivateData",
4361 ptr ? ptr : track->par->extradata,
4362 size);
4363 av_free(ptr);
4364 }
4365 param_write_string(pb, "FourCC", "H264");
4366 } else if (track->par->codec_id == AV_CODEC_ID_VC1) {
4367 param_write_string(pb, "FourCC", "WVC1");
4368 param_write_hex(pb, "CodecPrivateData", track->par->extradata,
4369 track->par->extradata_size);
4370 }
4371 param_write_int(pb, "MaxWidth", track->par->width);
4372 param_write_int(pb, "MaxHeight", track->par->height);
4373 param_write_int(pb, "DisplayWidth", track->par->width);
4374 param_write_int(pb, "DisplayHeight", track->par->height);
4375 } else {
4376 if (track->par->codec_id == AV_CODEC_ID_AAC) {
4377 switch (track->par->profile)
4378 {
4379 case FF_PROFILE_AAC_HE_V2:
4380 param_write_string(pb, "FourCC", "AACP");
4381 break;
4382 case FF_PROFILE_AAC_HE:
4383 param_write_string(pb, "FourCC", "AACH");
4384 break;
4385 default:
4386 param_write_string(pb, "FourCC", "AACL");
4387 }
4388 } else if (track->par->codec_id == AV_CODEC_ID_WMAPRO) {
4389 param_write_string(pb, "FourCC", "WMAP");
4390 }
4391 param_write_hex(pb, "CodecPrivateData", track->par->extradata,
4392 track->par->extradata_size);
4393 param_write_int(pb, "AudioTag", ff_codec_get_tag(ff_codec_wav_tags,
4394 track->par->codec_id));
4395 param_write_int(pb, "Channels", track->par->channels);
4396 param_write_int(pb, "SamplingRate", track->par->sample_rate);
4397 param_write_int(pb, "BitsPerSample", 16);
4398 param_write_int(pb, "PacketSize", track->par->block_align ?
4399 track->par->block_align : 4);
4400 }
4401 avio_printf(pb, "</%s>\n", type);
4402 }
4403 avio_printf(pb, "</switch>\n");
4404 avio_printf(pb, "</body>\n");
4405 avio_printf(pb, "</smil>\n");
4406
4407 return update_size(pb, pos);
4408 }
4409
4410 static int mov_write_mfhd_tag(AVIOContext *pb, MOVMuxContext *mov)
4411 {
4412 avio_wb32(pb, 16);
4413 ffio_wfourcc(pb, "mfhd");
4414 avio_wb32(pb, 0);
4415 avio_wb32(pb, mov->fragments);
4416 return 0;
4417 }
4418
4419 static uint32_t get_sample_flags(MOVTrack *track, MOVIentry *entry)
4420 {
4421 return entry->flags & MOV_SYNC_SAMPLE ? MOV_FRAG_SAMPLE_FLAG_DEPENDS_NO :
4422 (MOV_FRAG_SAMPLE_FLAG_DEPENDS_YES | MOV_FRAG_SAMPLE_FLAG_IS_NON_SYNC);
4423 }
4424
4425 static int mov_write_tfhd_tag(AVIOContext *pb, MOVMuxContext *mov,
4426 MOVTrack *track, int64_t moof_offset)
4427 {
4428 int64_t pos = avio_tell(pb);
4429 uint32_t flags = MOV_TFHD_DEFAULT_SIZE | MOV_TFHD_DEFAULT_DURATION |
4430 MOV_TFHD_BASE_DATA_OFFSET;
4431 if (!track->entry) {
4432 flags |= MOV_TFHD_DURATION_IS_EMPTY;
4433 } else {
4434 flags |= MOV_TFHD_DEFAULT_FLAGS;
4435 }
4436 if (mov->flags & FF_MOV_FLAG_OMIT_TFHD_OFFSET)
4437 flags &= ~MOV_TFHD_BASE_DATA_OFFSET;
4438 if (mov->flags & FF_MOV_FLAG_DEFAULT_BASE_MOOF) {
4439 flags &= ~MOV_TFHD_BASE_DATA_OFFSET;
4440 flags |= MOV_TFHD_DEFAULT_BASE_IS_MOOF;
4441 }
4442 /* CMAF requires all values to be explicit in tfhd atoms */
4443 if (mov->flags & FF_MOV_FLAG_CMAF)
4444 flags |= MOV_TFHD_STSD_ID;
4445
4446 /* Don't set a default sample size, the silverlight player refuses
4447 * to play files with that set. Don't set a default sample duration,
4448 * WMP freaks out if it is set. Don't set a base data offset, PIFF
4449 * file format says it MUST NOT be set. */
4450 if (track->mode == MODE_ISM)
4451 flags &= ~(MOV_TFHD_DEFAULT_SIZE | MOV_TFHD_DEFAULT_DURATION |
4452 MOV_TFHD_BASE_DATA_OFFSET | MOV_TFHD_STSD_ID);
4453
4454 avio_wb32(pb, 0); /* size placeholder */
4455 ffio_wfourcc(pb, "tfhd");
4456 avio_w8(pb, 0); /* version */
4457 avio_wb24(pb, flags);
4458
4459 avio_wb32(pb, track->track_id); /* track-id */
4460 if (flags & MOV_TFHD_BASE_DATA_OFFSET)
4461 avio_wb64(pb, moof_offset);
4462 if (flags & MOV_TFHD_STSD_ID) {
4463 avio_wb32(pb, 1);
4464 }
4465 if (flags & MOV_TFHD_DEFAULT_DURATION) {
4466 track->default_duration = get_cluster_duration(track, 0);
4467 avio_wb32(pb, track->default_duration);
4468 }
4469 if (flags & MOV_TFHD_DEFAULT_SIZE) {
4470 track->default_size = track->entry ? track->cluster[0].size : 1;
4471 avio_wb32(pb, track->default_size);
4472 } else
4473 track->default_size = -1;
4474
4475 if (flags & MOV_TFHD_DEFAULT_FLAGS) {
4476 /* Set the default flags based on the second sample, if available.
4477 * If the first sample is different, that can be signaled via a separate field. */
4478 if (track->entry > 1)
4479 track->default_sample_flags = get_sample_flags(track, &track->cluster[1]);
4480 else
4481 track->default_sample_flags =
4482 track->par->codec_type == AVMEDIA_TYPE_VIDEO ?
4483 (MOV_FRAG_SAMPLE_FLAG_DEPENDS_YES | MOV_FRAG_SAMPLE_FLAG_IS_NON_SYNC) :
4484 MOV_FRAG_SAMPLE_FLAG_DEPENDS_NO;
4485 avio_wb32(pb, track->default_sample_flags);
4486 }
4487
4488 return update_size(pb, pos);
4489 }
4490
4491 static int mov_write_trun_tag(AVIOContext *pb, MOVMuxContext *mov,
4492 MOVTrack *track, int moof_size,
4493 int first, int end)
4494 {
4495 int64_t pos = avio_tell(pb);
4496 uint32_t flags = MOV_TRUN_DATA_OFFSET;
4497 int i;
4498
4499 for (i = first; i < end; i++) {
4500 if (get_cluster_duration(track, i) != track->default_duration)
4501 flags |= MOV_TRUN_SAMPLE_DURATION;
4502 if (track->cluster[i].size != track->default_size)
4503 flags |= MOV_TRUN_SAMPLE_SIZE;
4504 if (i > first && get_sample_flags(track, &track->cluster[i]) != track->default_sample_flags)
4505 flags |= MOV_TRUN_SAMPLE_FLAGS;
4506 }
4507 if (!(flags & MOV_TRUN_SAMPLE_FLAGS) && track->entry > 0 &&
4508 get_sample_flags(track, &track->cluster[0]) != track->default_sample_flags)
4509 flags |= MOV_TRUN_FIRST_SAMPLE_FLAGS;
4510 if (track->flags & MOV_TRACK_CTTS)
4511 flags |= MOV_TRUN_SAMPLE_CTS;
4512
4513 avio_wb32(pb, 0); /* size placeholder */
4514 ffio_wfourcc(pb, "trun");
4515 if (mov->flags & FF_MOV_FLAG_NEGATIVE_CTS_OFFSETS)
4516 avio_w8(pb, 1); /* version */
4517 else
4518 avio_w8(pb, 0); /* version */
4519 avio_wb24(pb, flags);
4520
4521 avio_wb32(pb, end - first); /* sample count */
4522 if (mov->flags & FF_MOV_FLAG_OMIT_TFHD_OFFSET &&
4523 !(mov->flags & FF_MOV_FLAG_DEFAULT_BASE_MOOF) &&
4524 !mov->first_trun)
4525 avio_wb32(pb, 0); /* Later tracks follow immediately after the previous one */
4526 else
4527 avio_wb32(pb, moof_size + 8 + track->data_offset +
4528 track->cluster[first].pos); /* data offset */
4529 if (flags & MOV_TRUN_FIRST_SAMPLE_FLAGS)
4530 avio_wb32(pb, get_sample_flags(track, &track->cluster[first]));
4531
4532 for (i = first; i < end; i++) {
4533 if (flags & MOV_TRUN_SAMPLE_DURATION)
4534 avio_wb32(pb, get_cluster_duration(track, i));
4535 if (flags & MOV_TRUN_SAMPLE_SIZE)
4536 avio_wb32(pb, track->cluster[i].size);
4537 if (flags & MOV_TRUN_SAMPLE_FLAGS)
4538 avio_wb32(pb, get_sample_flags(track, &track->cluster[i]));
4539 if (flags & MOV_TRUN_SAMPLE_CTS)
4540 avio_wb32(pb, track->cluster[i].cts);
4541 }
4542
4543 mov->first_trun = 0;
4544 return update_size(pb, pos);
4545 }
4546
4547 static int mov_write_tfxd_tag(AVIOContext *pb, MOVTrack *track)
4548 {
4549 int64_t pos = avio_tell(pb);
4550 static const uint8_t uuid[] = {
4551 0x6d, 0x1d, 0x9b, 0x05, 0x42, 0xd5, 0x44, 0xe6,
4552 0x80, 0xe2, 0x14, 0x1d, 0xaf, 0xf7, 0x57, 0xb2
4553 };
4554
4555 avio_wb32(pb, 0); /* size placeholder */
4556 ffio_wfourcc(pb, "uuid");
4557 avio_write(pb, uuid, sizeof(uuid));
4558 avio_w8(pb, 1);
4559 avio_wb24(pb, 0);
4560 avio_wb64(pb, track->cluster[0].dts + track->cluster[0].cts);
4561 avio_wb64(pb, track->end_pts -
4562 (track->cluster[0].dts + track->cluster[0].cts));
4563
4564 return update_size(pb, pos);
4565 }
4566
4567 static int mov_write_tfrf_tag(AVIOContext *pb, MOVMuxContext *mov,
4568 MOVTrack *track, int entry)
4569 {
4570 int n = track->nb_frag_info - 1 - entry, i;
4571 int size = 8 + 16 + 4 + 1 + 16*n;
4572 static const uint8_t uuid[] = {
4573 0xd4, 0x80, 0x7e, 0xf2, 0xca, 0x39, 0x46, 0x95,
4574 0x8e, 0x54, 0x26, 0xcb, 0x9e, 0x46, 0xa7, 0x9f
4575 };
4576
4577 if (entry < 0)
4578 return 0;
4579
4580 avio_seek(pb, track->frag_info[entry].tfrf_offset, SEEK_SET);
4581 avio_wb32(pb, size);
4582 ffio_wfourcc(pb, "uuid");
4583 avio_write(pb, uuid, sizeof(uuid));
4584 avio_w8(pb, 1);
4585 avio_wb24(pb, 0);
4586 avio_w8(pb, n);
4587 for (i = 0; i < n; i++) {
4588 int index = entry + 1 + i;
4589 avio_wb64(pb, track->frag_info[index].time);
4590 avio_wb64(pb, track->frag_info[index].duration);
4591 }
4592 if (n < mov->ism_lookahead) {
4593 int free_size = 16 * (mov->ism_lookahead - n);
4594 avio_wb32(pb, free_size);
4595 ffio_wfourcc(pb, "free");
4596 ffio_fill(pb, 0, free_size - 8);
4597 }
4598
4599 return 0;
4600 }
4601
4602 static int mov_write_tfrf_tags(AVIOContext *pb, MOVMuxContext *mov,
4603 MOVTrack *track)
4604 {
4605 int64_t pos = avio_tell(pb);
4606 int i;
4607 for (i = 0; i < mov->ism_lookahead; i++) {
4608 /* Update the tfrf tag for the last ism_lookahead fragments,
4609 * nb_frag_info - 1 is the next fragment to be written. */
4610 mov_write_tfrf_tag(pb, mov, track, track->nb_frag_info - 2 - i);
4611 }
4612 avio_seek(pb, pos, SEEK_SET);
4613 return 0;
4614 }
4615
4616 static int mov_add_tfra_entries(AVIOContext *pb, MOVMuxContext *mov, int tracks,
4617 int size)
4618 {
4619 int i;
4620 for (i = 0; i < mov->nb_streams; i++) {
4621 MOVTrack *track = &mov->tracks[i];
4622 MOVFragmentInfo *info;
4623 if ((tracks >= 0 && i != tracks) || !track->entry)
4624 continue;
4625 track->nb_frag_info++;
4626 if (track->nb_frag_info >= track->frag_info_capacity) {
4627 unsigned new_capacity = track->nb_frag_info + MOV_FRAG_INFO_ALLOC_INCREMENT;
4628 if (av_reallocp_array(&track->frag_info,
4629 new_capacity,
4630 sizeof(*track->frag_info)))
4631 return AVERROR(ENOMEM);
4632 track->frag_info_capacity = new_capacity;
4633 }
4634 info = &track->frag_info[track->nb_frag_info - 1];
4635 info->offset = avio_tell(pb);
4636 info->size = size;
4637 // Try to recreate the original pts for the first packet
4638 // from the fields we have stored
4639 info->time = track->cluster[0].dts + track->cluster[0].cts;
4640 info->duration = track->end_pts -
4641 (track->cluster[0].dts + track->cluster[0].cts);
4642 // If the pts is less than zero, we will have trimmed
4643 // away parts of the media track using an edit list,
4644 // and the corresponding start presentation time is zero.
4645 if (info->time < 0) {
4646 info->duration += info->time;
4647 info->time = 0;
4648 }
4649 info->tfrf_offset = 0;
4650 mov_write_tfrf_tags(pb, mov, track);
4651 }
4652 return 0;
4653 }
4654
4655 static void mov_prune_frag_info(MOVMuxContext *mov, int tracks, int max)
4656 {
4657 int i;
4658 for (i = 0; i < mov->nb_streams; i++) {
4659 MOVTrack *track = &mov->tracks[i];
4660 if ((tracks >= 0 && i != tracks) || !track->entry)
4661 continue;
4662 if (track->nb_frag_info > max) {
4663 memmove(track->frag_info, track->frag_info + (track->nb_frag_info - max), max * sizeof(*track->frag_info));
4664 track->nb_frag_info = max;
4665 }
4666 }
4667 }
4668
4669 static int mov_write_tfdt_tag(AVIOContext *pb, MOVTrack *track)
4670 {
4671 int64_t pos = avio_tell(pb);
4672
4673 avio_wb32(pb, 0); /* size */
4674 ffio_wfourcc(pb, "tfdt");
4675 avio_w8(pb, 1); /* version */
4676 avio_wb24(pb, 0);
4677 avio_wb64(pb, track->cluster[0].dts - track->start_dts);
4678 return update_size(pb, pos);
4679 }
4680
4681 static int mov_write_traf_tag(AVIOContext *pb, MOVMuxContext *mov,
4682 MOVTrack *track, int64_t moof_offset,
4683 int moof_size)
4684 {
4685 int64_t pos = avio_tell(pb);
4686 int i, start = 0;
4687 avio_wb32(pb, 0); /* size placeholder */
4688 ffio_wfourcc(pb, "traf");
4689
4690 mov_write_tfhd_tag(pb, mov, track, moof_offset);
4691 if (mov->mode != MODE_ISM)
4692 mov_write_tfdt_tag(pb, track);
4693 for (i = 1; i < track->entry; i++) {
4694 if (track->cluster[i].pos != track->cluster[i - 1].pos + track->cluster[i - 1].size) {
4695 mov_write_trun_tag(pb, mov, track, moof_size, start, i);
4696 start = i;
4697 }
4698 }
4699 mov_write_trun_tag(pb, mov, track, moof_size, start, track->entry);
4700 if (mov->mode == MODE_ISM) {
4701 mov_write_tfxd_tag(pb, track);
4702
4703 if (mov->ism_lookahead) {
4704 int size = 16 + 4 + 1 + 16 * mov->ism_lookahead;
4705
4706 if (track->nb_frag_info > 0) {
4707 MOVFragmentInfo *info = &track->frag_info[track->nb_frag_info - 1];
4708 if (!info->tfrf_offset)
4709 info->tfrf_offset = avio_tell(pb);
4710 }
4711 avio_wb32(pb, 8 + size);
4712 ffio_wfourcc(pb, "free");
4713 ffio_fill(pb, 0, size);
4714 }
4715 }
4716
4717 return update_size(pb, pos);
4718 }
4719
4720 static int mov_write_moof_tag_internal(AVIOContext *pb, MOVMuxContext *mov,
4721 int tracks, int moof_size)
4722 {
4723 int64_t pos = avio_tell(pb);
4724 int i;
4725
4726 avio_wb32(pb, 0); /* size placeholder */
4727 ffio_wfourcc(pb, "moof");
4728 mov->first_trun = 1;
4729
4730 mov_write_mfhd_tag(pb, mov);
4731 for (i = 0; i < mov->nb_streams; i++) {
4732 MOVTrack *track = &mov->tracks[i];
4733 if (tracks >= 0 && i != tracks)
4734 continue;
4735 if (!track->entry)
4736 continue;
4737 mov_write_traf_tag(pb, mov, track, pos, moof_size);
4738 }
4739
4740 return update_size(pb, pos);
4741 }
4742
4743 static int mov_write_sidx_tag(AVIOContext *pb,
4744 MOVTrack *track, int ref_size, int total_sidx_size)
4745 {
4746 int64_t pos = avio_tell(pb), offset_pos, end_pos;
4747 int64_t presentation_time, duration, offset;
4748 unsigned starts_with_SAP;
4749 int i, entries;
4750
4751 if (track->entry) {
4752 entries = 1;
4753 presentation_time = track->cluster[0].dts + track->cluster[0].cts;
4754 duration = track->end_pts -
4755 (track->cluster[0].dts + track->cluster[0].cts);
4756 starts_with_SAP = track->cluster[0].flags & MOV_SYNC_SAMPLE;
4757
4758 // pts<0 should be cut away using edts
4759 if (presentation_time < 0) {
4760 duration += presentation_time;
4761 presentation_time = 0;
4762 }
4763 } else {
4764 entries = track->nb_frag_info;
4765 if (entries <= 0)
4766 return 0;
4767 presentation_time = track->frag_info[0].time;
4768 }
4769
4770 avio_wb32(pb, 0); /* size */
4771 ffio_wfourcc(pb, "sidx");
4772 avio_w8(pb, 1); /* version */
4773 avio_wb24(pb, 0);
4774 avio_wb32(pb, track->track_id); /* reference_ID */
4775 avio_wb32(pb, track->timescale); /* timescale */
4776 avio_wb64(pb, presentation_time); /* earliest_presentation_time */
4777 offset_pos = avio_tell(pb);
4778 avio_wb64(pb, 0); /* first_offset (offset to referenced moof) */
4779 avio_wb16(pb, 0); /* reserved */
4780
4781 avio_wb16(pb, entries); /* reference_count */
4782 for (i = 0; i < entries; i++) {
4783 if (!track->entry) {
4784 if (i > 1 && track->frag_info[i].offset != track->frag_info[i - 1].offset + track->frag_info[i - 1].size) {
4785 av_log(NULL, AV_LOG_ERROR, "Non-consecutive fragments, writing incorrect sidx\n");
4786 }
4787 duration = track->frag_info[i].duration;
4788 ref_size = track->frag_info[i].size;
4789 starts_with_SAP = 1;
4790 }
4791 avio_wb32(pb, (0 << 31) | (ref_size & 0x7fffffff)); /* reference_type (0 = media) | referenced_size */
4792 avio_wb32(pb, duration); /* subsegment_duration */
4793 avio_wb32(pb, (starts_with_SAP << 31) | (0 << 28) | 0); /* starts_with_SAP | SAP_type | SAP_delta_time */
4794 }
4795
4796 end_pos = avio_tell(pb);
4797 offset = pos + total_sidx_size - end_pos;
4798 avio_seek(pb, offset_pos, SEEK_SET);
4799 avio_wb64(pb, offset);
4800 avio_seek(pb, end_pos, SEEK_SET);
4801 return update_size(pb, pos);
4802 }
4803
4804 static int mov_write_sidx_tags(AVIOContext *pb, MOVMuxContext *mov,
4805 int tracks, int ref_size)
4806 {
4807 int i, round, ret;
4808 AVIOContext *avio_buf;
4809 int total_size = 0;
4810 for (round = 0; round < 2; round++) {
4811 // First run one round to calculate the total size of all
4812 // sidx atoms.
4813 // This would be much simpler if we'd only write one sidx
4814 // atom, for the first track in the moof.
4815 if (round == 0) {
4816 if ((ret = ffio_open_null_buf(&avio_buf)) < 0)
4817 return ret;
4818 } else {
4819 avio_buf = pb;
4820 }
4821 for (i = 0; i < mov->nb_streams; i++) {
4822 MOVTrack *track = &mov->tracks[i];
4823 if (tracks >= 0 && i != tracks)
4824 continue;
4825 // When writing a sidx for the full file, entry is 0, but
4826 // we want to include all tracks. ref_size is 0 in this case,
4827 // since we read it from frag_info instead.
4828 if (!track->entry && ref_size > 0)
4829 continue;
4830 total_size -= mov_write_sidx_tag(avio_buf, track, ref_size,
4831 total_size);
4832 }
4833 if (round == 0)
4834 total_size = ffio_close_null_buf(avio_buf);
4835 }
4836 return 0;
4837 }
4838
4839 static int mov_write_prft_tag(AVIOContext *pb, MOVMuxContext *mov, int tracks)
4840 {
4841 int64_t pos = avio_tell(pb), pts_us, ntp_ts;
4842 MOVTrack *first_track;
4843 int flags = 24;
4844
4845 /* PRFT should be associated with at most one track. So, choosing only the
4846 * first track. */
4847 if (tracks > 0)
4848 return 0;
4849 first_track = &(mov->tracks[0]);
4850
4851 if (!first_track->entry) {
4852 av_log(mov->fc, AV_LOG_WARNING, "Unable to write PRFT, no entries in the track\n");
4853 return 0;
4854 }
4855
4856 if (first_track->cluster[0].pts == AV_NOPTS_VALUE) {
4857 av_log(mov->fc, AV_LOG_WARNING, "Unable to write PRFT, first PTS is invalid\n");
4858 return 0;
4859 }
4860
4861 if (mov->write_prft == MOV_PRFT_SRC_WALLCLOCK) {
4862 if (first_track->cluster[0].prft.wallclock) {
4863 /* Round the NTP time to whole milliseconds. */
4864 ntp_ts = ff_get_formatted_ntp_time((first_track->cluster[0].prft.wallclock / 1000) * 1000 +
4865 NTP_OFFSET_US);
4866 flags = first_track->cluster[0].prft.flags;
4867 } else
4868 ntp_ts = ff_get_formatted_ntp_time(ff_ntp_time());
4869 } else if (mov->write_prft == MOV_PRFT_SRC_PTS) {
4870 pts_us = av_rescale_q(first_track->cluster[0].pts,
4871 first_track->st->time_base, AV_TIME_BASE_Q);
4872 ntp_ts = ff_get_formatted_ntp_time(pts_us + NTP_OFFSET_US);
4873 } else {
4874 av_log(mov->fc, AV_LOG_WARNING, "Unsupported PRFT box configuration: %d\n",
4875 mov->write_prft);
4876 return 0;
4877 }
4878
4879 avio_wb32(pb, 0); // Size place holder
4880 ffio_wfourcc(pb, "prft"); // Type
4881 avio_w8(pb, 1); // Version
4882 avio_wb24(pb, flags); // Flags
4883 avio_wb32(pb, first_track->track_id); // reference track ID
4884 avio_wb64(pb, ntp_ts); // NTP time stamp
4885 avio_wb64(pb, first_track->cluster[0].pts); //media time
4886 return update_size(pb, pos);
4887 }
4888
4889 static int mov_write_moof_tag(AVIOContext *pb, MOVMuxContext *mov, int tracks,
4890 int64_t mdat_size)
4891 {
4892 AVIOContext *avio_buf;
4893 int ret, moof_size;
4894
4895 if ((ret = ffio_open_null_buf(&avio_buf)) < 0)
4896 return ret;
4897 mov_write_moof_tag_internal(avio_buf, mov, tracks, 0);
4898 moof_size = ffio_close_null_buf(avio_buf);
4899
4900 if (mov->flags & FF_MOV_FLAG_DASH &&
4901 !(mov->flags & (FF_MOV_FLAG_GLOBAL_SIDX | FF_MOV_FLAG_SKIP_SIDX)))
4902 mov_write_sidx_tags(pb, mov, tracks, moof_size + 8 + mdat_size);
4903
4904 if (mov->write_prft > MOV_PRFT_NONE && mov->write_prft < MOV_PRFT_NB)
4905 mov_write_prft_tag(pb, mov, tracks);
4906
4907 if (mov->flags & FF_MOV_FLAG_GLOBAL_SIDX ||
4908 !(mov->flags & FF_MOV_FLAG_SKIP_TRAILER) ||
4909 mov->ism_lookahead) {
4910 if ((ret = mov_add_tfra_entries(pb, mov, tracks, moof_size + 8 + mdat_size)) < 0)
4911 return ret;
4912 if (!(mov->flags & FF_MOV_FLAG_GLOBAL_SIDX) &&
4913 mov->flags & FF_MOV_FLAG_SKIP_TRAILER) {
4914 mov_prune_frag_info(mov, tracks, mov->ism_lookahead + 1);
4915 }
4916 }
4917
4918 return mov_write_moof_tag_internal(pb, mov, tracks, moof_size);
4919 }
4920
4921 static int mov_write_tfra_tag(AVIOContext *pb, MOVTrack *track)
4922 {
4923 int64_t pos = avio_tell(pb);
4924 int i;
4925
4926 avio_wb32(pb, 0); /* size placeholder */
4927 ffio_wfourcc(pb, "tfra");
4928 avio_w8(pb, 1); /* version */
4929 avio_wb24(pb, 0);
4930
4931 avio_wb32(pb, track->track_id);
4932 avio_wb32(pb, 0); /* length of traf/trun/sample num */
4933 avio_wb32(pb, track->nb_frag_info);
4934 for (i = 0; i < track->nb_frag_info; i++) {
4935 avio_wb64(pb, track->frag_info[i].time);
4936 avio_wb64(pb, track->frag_info[i].offset + track->data_offset);
4937 avio_w8(pb, 1); /* traf number */
4938 avio_w8(pb, 1); /* trun number */
4939 avio_w8(pb, 1); /* sample number */
4940 }
4941
4942 return update_size(pb, pos);
4943 }
4944
4945 static int mov_write_mfra_tag(AVIOContext *pb, MOVMuxContext *mov)
4946 {
4947 AVIOContext *mfra_pb;
4948 int i, ret, sz;
4949 uint8_t *buf;
4950
4951 ret = avio_open_dyn_buf(&mfra_pb);
4952 if (ret < 0)
4953 return ret;
4954
4955 avio_wb32(mfra_pb, 0); /* size placeholder */
4956 ffio_wfourcc(mfra_pb, "mfra");
4957 /* An empty mfra atom is enough to indicate to the publishing point that
4958 * the stream has ended. */
4959 if (mov->flags & FF_MOV_FLAG_ISML)
4960 goto done_mfra;
4961
4962 for (i = 0; i < mov->nb_streams; i++) {
4963 MOVTrack *track = &mov->tracks[i];
4964 if (track->nb_frag_info)
4965 mov_write_tfra_tag(mfra_pb, track);
4966 }
4967
4968 avio_wb32(mfra_pb, 16);
4969 ffio_wfourcc(mfra_pb, "mfro");
4970 avio_wb32(mfra_pb, 0); /* version + flags */
4971 avio_wb32(mfra_pb, avio_tell(mfra_pb) + 4);
4972
4973 done_mfra:
4974
4975 sz = update_size(mfra_pb, 0);
4976 ret = avio_get_dyn_buf(mfra_pb, &buf);
4977 avio_write(pb, buf, ret);
4978 ffio_free_dyn_buf(&mfra_pb);
4979
4980 return sz;
4981 }
4982
4983 static int mov_write_mdat_tag(AVIOContext *pb, MOVMuxContext *mov)
4984 {
4985 avio_wb32(pb, 8); // placeholder for extended size field (64 bit)
4986 ffio_wfourcc(pb, mov->mode == MODE_MOV ? "wide" : "free");
4987
4988 mov->mdat_pos = avio_tell(pb);
4989 avio_wb32(pb, 0); /* size placeholder*/
4990 ffio_wfourcc(pb, "mdat");
4991 return 0;
4992 }
4993
4994 static void mov_write_ftyp_tag_internal(AVIOContext *pb, AVFormatContext *s,
4995 int has_h264, int has_video, int write_minor)
4996 {
4997 MOVMuxContext *mov = s->priv_data;
4998 int minor = 0x200;
4999
5000 if (mov->major_brand && strlen(mov->major_brand) >= 4)
5001 ffio_wfourcc(pb, mov->major_brand);
5002 else if (mov->mode == MODE_3GP) {
5003 ffio_wfourcc(pb, has_h264 ? "3gp6" : "3gp4");
5004 minor = has_h264 ? 0x100 : 0x200;
5005 } else if (mov->mode & MODE_3G2) {
5006 ffio_wfourcc(pb, has_h264 ? "3g2b" : "3g2a");
5007 minor = has_h264 ? 0x20000 : 0x10000;
5008 } else if (mov->mode == MODE_PSP)
5009 ffio_wfourcc(pb, "MSNV");
5010 else if (mov->mode == MODE_MP4 && mov->flags & FF_MOV_FLAG_FRAGMENT &&
5011 mov->flags & FF_MOV_FLAG_NEGATIVE_CTS_OFFSETS)
5012 ffio_wfourcc(pb, "iso6"); // Required when using signed CTS offsets in trun boxes
5013 else if (mov->mode == MODE_MP4 && mov->flags & FF_MOV_FLAG_DEFAULT_BASE_MOOF)
5014 ffio_wfourcc(pb, "iso5"); // Required when using default-base-is-moof
5015 else if (mov->mode == MODE_MP4 && mov->flags & FF_MOV_FLAG_NEGATIVE_CTS_OFFSETS)
5016 ffio_wfourcc(pb, "iso4");
5017 else if (mov->mode == MODE_MP4)
5018 ffio_wfourcc(pb, "isom");
5019 else if (mov->mode == MODE_IPOD)
5020 ffio_wfourcc(pb, has_video ? "M4V ":"M4A ");
5021 else if (mov->mode == MODE_ISM)
5022 ffio_wfourcc(pb, "isml");
5023 else if (mov->mode == MODE_F4V)
5024 ffio_wfourcc(pb, "f4v ");
5025 else
5026 ffio_wfourcc(pb, "qt ");
5027
5028 if (write_minor)
5029 avio_wb32(pb, minor);
5030 }
5031
5032 static int mov_write_ftyp_tag(AVIOContext *pb, AVFormatContext *s)
5033 {
5034 MOVMuxContext *mov = s->priv_data;
5035 int64_t pos = avio_tell(pb);
5036 int has_h264 = 0, has_av1 = 0, has_video = 0, has_dolby = 0;
5037 int i;
5038
5039 for (i = 0; i < s->nb_streams; i++) {
5040 AVStream *st = s->streams[i];
5041 if (is_cover_image(st))
5042 continue;
5043 if (st->codecpar->codec_type == AVMEDIA_TYPE_VIDEO)
5044 has_video = 1;
5045 if (st->codecpar->codec_id == AV_CODEC_ID_H264)
5046 has_h264 = 1;
5047 if (st->codecpar->codec_id == AV_CODEC_ID_AV1)
5048 has_av1 = 1;
5049 if (st->codecpar->codec_id == AV_CODEC_ID_AC3 ||
5050 st->codecpar->codec_id == AV_CODEC_ID_EAC3 ||
5051 st->codecpar->codec_id == AV_CODEC_ID_TRUEHD ||
5052 av_stream_get_side_data(st, AV_PKT_DATA_DOVI_CONF, NULL))
5053 has_dolby = 1;
5054 }
5055
5056 avio_wb32(pb, 0); /* size */
5057 ffio_wfourcc(pb, "ftyp");
5058
5059 // Write major brand
5060 mov_write_ftyp_tag_internal(pb, s, has_h264, has_video, 1);
5061 // Write the major brand as the first compatible brand as well
5062 mov_write_ftyp_tag_internal(pb, s, has_h264, has_video, 0);
5063
5064 // Write compatible brands, ensuring that we don't write the major brand as a
5065 // compatible brand a second time.
5066 if (mov->mode == MODE_ISM) {
5067 ffio_wfourcc(pb, "piff");
5068 } else if (mov->mode != MODE_MOV) {
5069 // We add tfdt atoms when fragmenting, signal this with the iso6 compatible
5070 // brand, if not already the major brand. This is compatible with users that
5071 // don't understand tfdt.
5072 if (mov->mode == MODE_MP4) {
5073 if (mov->flags & FF_MOV_FLAG_CMAF)
5074 ffio_wfourcc(pb, "cmfc");
5075 if (mov->flags & FF_MOV_FLAG_FRAGMENT && !(mov->flags & FF_MOV_FLAG_NEGATIVE_CTS_OFFSETS))
5076 ffio_wfourcc(pb, "iso6");
5077 if (has_av1)
5078 ffio_wfourcc(pb, "av01");
5079 if (has_dolby)
5080 ffio_wfourcc(pb, "dby1");
5081 } else {
5082 if (mov->flags & FF_MOV_FLAG_FRAGMENT)
5083 ffio_wfourcc(pb, "iso6");
5084 if (mov->flags & FF_MOV_FLAG_DEFAULT_BASE_MOOF)
5085 ffio_wfourcc(pb, "iso5");
5086 else if (mov->flags & FF_MOV_FLAG_NEGATIVE_CTS_OFFSETS)
5087 ffio_wfourcc(pb, "iso4");
5088 }
5089 // Brands prior to iso5 can't be signaled when using default-base-is-moof
5090 if (!(mov->flags & FF_MOV_FLAG_DEFAULT_BASE_MOOF)) {
5091 // write isom for mp4 only if it it's not the major brand already.
5092 if (mov->mode != MODE_MP4 || mov->flags & FF_MOV_FLAG_NEGATIVE_CTS_OFFSETS)
5093 ffio_wfourcc(pb, "isom");
5094 ffio_wfourcc(pb, "iso2");
5095 if (has_h264)
5096 ffio_wfourcc(pb, "avc1");
5097 }
5098 }
5099
5100 if (mov->mode == MODE_MP4)
5101 ffio_wfourcc(pb, "mp41");
5102
5103 if (mov->flags & FF_MOV_FLAG_DASH && mov->flags & FF_MOV_FLAG_GLOBAL_SIDX)
5104 ffio_wfourcc(pb, "dash");
5105
5106 return update_size(pb, pos);
5107 }
5108
5109 static int mov_write_uuidprof_tag(AVIOContext *pb, AVFormatContext *s)
5110 {
5111 AVStream *video_st = s->streams[0];
5112 AVCodecParameters *video_par = s->streams[0]->codecpar;
5113 AVCodecParameters *audio_par = s->streams[1]->codecpar;
5114 int audio_rate = audio_par->sample_rate;
5115 int64_t frame_rate = video_st->avg_frame_rate.den ?
5116 (video_st->avg_frame_rate.num * 0x10000LL) / video_st->avg_frame_rate.den :
5117 0;
5118 int audio_kbitrate = audio_par->bit_rate / 1000;
5119 int video_kbitrate = FFMIN(video_par->bit_rate / 1000, 800 - audio_kbitrate);
5120
5121 if (frame_rate < 0 || frame_rate > INT32_MAX) {
5122 av_log(s, AV_LOG_ERROR, "Frame rate %f outside supported range\n", frame_rate / (double)0x10000);
5123 return AVERROR(EINVAL);
5124 }
5125
5126 avio_wb32(pb, 0x94); /* size */
5127 ffio_wfourcc(pb, "uuid");
5128 ffio_wfourcc(pb, "PROF");
5129
5130 avio_wb32(pb, 0x21d24fce); /* 96 bit UUID */
5131 avio_wb32(pb, 0xbb88695c);
5132 avio_wb32(pb, 0xfac9c740);
5133
5134 avio_wb32(pb, 0x0); /* ? */
5135 avio_wb32(pb, 0x3); /* 3 sections ? */
5136
5137 avio_wb32(pb, 0x14); /* size */
5138 ffio_wfourcc(pb, "FPRF");
5139 avio_wb32(pb, 0x0); /* ? */
5140 avio_wb32(pb, 0x0); /* ? */
5141 avio_wb32(pb, 0x0); /* ? */
5142
5143 avio_wb32(pb, 0x2c); /* size */
5144 ffio_wfourcc(pb, "APRF"); /* audio */
5145 avio_wb32(pb, 0x0);
5146 avio_wb32(pb, 0x2); /* TrackID */
5147 ffio_wfourcc(pb, "mp4a");
5148 avio_wb32(pb, 0x20f);
5149 avio_wb32(pb, 0x0);
5150 avio_wb32(pb, audio_kbitrate);
5151 avio_wb32(pb, audio_kbitrate);
5152 avio_wb32(pb, audio_rate);
5153 avio_wb32(pb, audio_par->channels);
5154
5155 avio_wb32(pb, 0x34); /* size */
5156 ffio_wfourcc(pb, "VPRF"); /* video */
5157 avio_wb32(pb, 0x0);
5158 avio_wb32(pb, 0x1); /* TrackID */
5159 if (video_par->codec_id == AV_CODEC_ID_H264) {
5160 ffio_wfourcc(pb, "avc1");
5161 avio_wb16(pb, 0x014D);
5162 avio_wb16(pb, 0x0015);
5163 } else {
5164 ffio_wfourcc(pb, "mp4v");
5165 avio_wb16(pb, 0x0000);
5166 avio_wb16(pb, 0x0103);
5167 }
5168 avio_wb32(pb, 0x0);
5169 avio_wb32(pb, video_kbitrate);
5170 avio_wb32(pb, video_kbitrate);
5171 avio_wb32(pb, frame_rate);
5172 avio_wb32(pb, frame_rate);
5173 avio_wb16(pb, video_par->width);
5174 avio_wb16(pb, video_par->height);
5175 avio_wb32(pb, 0x010001); /* ? */
5176
5177 return 0;
5178 }
5179
5180 static int mov_write_identification(AVIOContext *pb, AVFormatContext *s)
5181 {
5182 MOVMuxContext *mov = s->priv_data;
5183 int i;
5184
5185 mov_write_ftyp_tag(pb,s);
5186 if (mov->mode == MODE_PSP) {
5187 int video_streams_nb = 0, audio_streams_nb = 0, other_streams_nb = 0;
5188 for (i = 0; i < s->nb_streams; i++) {
5189 AVStream *st = s->streams[i];
5190 if (is_cover_image(st))
5191 continue;
5192 if (st->codecpar->codec_type == AVMEDIA_TYPE_VIDEO)
5193 video_streams_nb++;
5194 else if (st->codecpar->codec_type == AVMEDIA_TYPE_AUDIO)
5195 audio_streams_nb++;
5196 else
5197 other_streams_nb++;
5198 }
5199
5200 if (video_streams_nb != 1 || audio_streams_nb != 1 || other_streams_nb) {
5201 av_log(s, AV_LOG_ERROR, "PSP mode need one video and one audio stream\n");
5202 return AVERROR(EINVAL);
5203 }
5204 return mov_write_uuidprof_tag(pb, s);
5205 }
5206 return 0;
5207 }
5208
5209 static int mov_parse_mpeg2_frame(AVPacket *pkt, uint32_t *flags)
5210 {
5211 uint32_t c = -1;
5212 int i, closed_gop = 0;
5213
5214 for (i = 0; i < pkt->size - 4; i++) {
5215 c = (c << 8) + pkt->data[i];
5216 if (c == 0x1b8) { // gop
5217 closed_gop = pkt->data[i + 4] >> 6 & 0x01;
5218 } else if (c == 0x100) { // pic
5219 int temp_ref = (pkt->data[i + 1] << 2) | (pkt->data[i + 2] >> 6);
5220 if (!temp_ref || closed_gop) // I picture is not reordered
5221 *flags = MOV_SYNC_SAMPLE;
5222 else
5223 *flags = MOV_PARTIAL_SYNC_SAMPLE;
5224 break;
5225 }
5226 }
5227 return 0;
5228 }
5229
5230 static void mov_parse_vc1_frame(AVPacket *pkt, MOVTrack *trk)
5231 {
5232 const uint8_t *start, *next, *end = pkt->data + pkt->size;
5233 int seq = 0, entry = 0;
5234 int key = pkt->flags & AV_PKT_FLAG_KEY;
5235 start = find_next_marker(pkt->data, end);
5236 for (next = start; next < end; start = next) {
5237 next = find_next_marker(start + 4, end);
5238 switch (AV_RB32(start)) {
5239 case VC1_CODE_SEQHDR:
5240 seq = 1;
5241 break;
5242 case VC1_CODE_ENTRYPOINT:
5243 entry = 1;
5244 break;
5245 case VC1_CODE_SLICE:
5246 trk->vc1_info.slices = 1;
5247 break;
5248 }
5249 }
5250 if (!trk->entry && trk->vc1_info.first_packet_seen)
5251 trk->vc1_info.first_frag_written = 1;
5252 if (!trk->entry && !trk->vc1_info.first_frag_written) {
5253 /* First packet in first fragment */
5254 trk->vc1_info.first_packet_seq = seq;
5255 trk->vc1_info.first_packet_entry = entry;
5256 trk->vc1_info.first_packet_seen = 1;
5257 } else if ((seq && !trk->vc1_info.packet_seq) ||
5258 (entry && !trk->vc1_info.packet_entry)) {
5259 int i;
5260 for (i = 0; i < trk->entry; i++)
5261 trk->cluster[i].flags &= ~MOV_SYNC_SAMPLE;
5262 trk->has_keyframes = 0;
5263 if (seq)
5264 trk->vc1_info.packet_seq = 1;
5265 if (entry)
5266 trk->vc1_info.packet_entry = 1;
5267 if (!trk->vc1_info.first_frag_written) {
5268 /* First fragment */
5269 if ((!seq || trk->vc1_info.first_packet_seq) &&
5270 (!entry || trk->vc1_info.first_packet_entry)) {
5271 /* First packet had the same headers as this one, readd the
5272 * sync sample flag. */
5273 trk->cluster[0].flags |= MOV_SYNC_SAMPLE;
5274 trk->has_keyframes = 1;
5275 }
5276 }
5277 }
5278 if (trk->vc1_info.packet_seq && trk->vc1_info.packet_entry)
5279 key = seq && entry;
5280 else if (trk->vc1_info.packet_seq)
5281 key = seq;
5282 else if (trk->vc1_info.packet_entry)
5283 key = entry;
5284 if (key) {
5285 trk->cluster[trk->entry].flags |= MOV_SYNC_SAMPLE;
5286 trk->has_keyframes++;
5287 }
5288 }
5289
5290 static void mov_parse_truehd_frame(AVPacket *pkt, MOVTrack *trk)
5291 {
5292 int length;
5293
5294 if (pkt->size < 8)
5295 return;
5296
5297 length = (AV_RB16(pkt->data) & 0xFFF) * 2;
5298 if (length < 8 || length > pkt->size)
5299 return;
5300
5301 if (AV_RB32(pkt->data + 4) == 0xF8726FBA) {
5302 trk->cluster[trk->entry].flags |= MOV_SYNC_SAMPLE;
5303 trk->has_keyframes++;
5304 }
5305
5306 return;
5307 }
5308
5309 static int mov_flush_fragment_interleaving(AVFormatContext *s, MOVTrack *track)
5310 {
5311 MOVMuxContext *mov = s->priv_data;
5312 int ret, buf_size;
5313 uint8_t *buf;
5314 int i, offset;
5315
5316 if (!track->mdat_buf)
5317 return 0;
5318 if (!mov->mdat_buf) {
5319 if ((ret = avio_open_dyn_buf(&mov->mdat_buf)) < 0)
5320 return ret;
5321 }
5322 buf_size = avio_get_dyn_buf(track->mdat_buf, &buf);
5323
5324 offset = avio_tell(mov->mdat_buf);
5325 avio_write(mov->mdat_buf, buf, buf_size);
5326 ffio_free_dyn_buf(&track->mdat_buf);
5327
5328 for (i = track->entries_flushed; i < track->entry; i++)
5329 track->cluster[i].pos += offset;
5330 track->entries_flushed = track->entry;
5331 return 0;
5332 }
5333
5334 static int mov_write_squashed_packet(AVFormatContext *s, MOVTrack *track)
5335 {
5336 MOVMuxContext *mov = s->priv_data;
5337 AVPacket *squashed_packet = mov->pkt;
5338 int ret = AVERROR_BUG;
5339
5340 switch (track->st->codecpar->codec_id) {
5341 case AV_CODEC_ID_TTML: {
5342 int had_packets = !!track->squashed_packet_queue.head;
5343
5344 if ((ret = ff_mov_generate_squashed_ttml_packet(s, track, squashed_packet)) < 0) {
5345 goto finish_squash;
5346 }
5347
5348 // We have generated a padding packet (no actual input packets in
5349 // queue) and its duration is zero. Skipping writing it.
5350 if (!had_packets && squashed_packet->duration == 0) {
5351 goto finish_squash;
5352 }
5353
5354 track->end_reliable = 1;
5355 break;
5356 }
5357 default:
5358 ret = AVERROR(EINVAL);
5359 goto finish_squash;
5360 }
5361
5362 squashed_packet->stream_index = track->st->index;
5363
5364 ret = mov_write_single_packet(s, squashed_packet);
5365
5366 finish_squash:
5367 av_packet_unref(squashed_packet);
5368
5369 return ret;
5370 }
5371
5372 static int mov_write_squashed_packets(AVFormatContext *s)
5373 {
5374 MOVMuxContext *mov = s->priv_data;
5375
5376 for (int i = 0; i < s->nb_streams; i++) {
5377 MOVTrack *track = &mov->tracks[i];
5378 int ret = AVERROR_BUG;
5379
5380 if (track->squash_fragment_samples_to_one && !track->entry) {
5381 if ((ret = mov_write_squashed_packet(s, track)) < 0) {
5382 av_log(s, AV_LOG_ERROR,
5383 "Failed to write squashed packet for %s stream with "
5384 "index %d and track id %d. Error: %s\n",
5385 avcodec_get_name(track->st->codecpar->codec_id),
5386 track->st->index, track->track_id,
5387 av_err2str(ret));
5388 return ret;
5389 }
5390 }
5391 }
5392
5393 return 0;
5394 }
5395
5396 static int mov_flush_fragment(AVFormatContext *s, int force)
5397 {
5398 MOVMuxContext *mov = s->priv_data;
5399 int i, first_track = -1;
5400 int64_t mdat_size = 0;
5401 int ret;
5402 int has_video = 0, starts_with_key = 0, first_video_track = 1;
5403
5404 if (!(mov->flags & FF_MOV_FLAG_FRAGMENT))
5405 return 0;
5406
5407 // Check if we have any tracks that require squashing.
5408 // In that case, we'll have to write the packet here.
5409 if ((ret = mov_write_squashed_packets(s)) < 0)
5410 return ret;
5411
5412 // Try to fill in the duration of the last packet in each stream
5413 // from queued packets in the interleave queues. If the flushing
5414 // of fragments was triggered automatically by an AVPacket, we
5415 // already have reliable info for the end of that track, but other
5416 // tracks may need to be filled in.
5417 for (i = 0; i < s->nb_streams; i++) {
5418 MOVTrack *track = &mov->tracks[i];
5419 if (!track->end_reliable) {
5420 const AVPacket *pkt = ff_interleaved_peek(s, i);
5421 if (pkt) {
5422 int64_t offset, dts, pts;
5423 ff_get_muxer_ts_offset(s, i, &offset);
5424 pts = pkt->pts + offset;
5425 dts = pkt->dts + offset;
5426 if (track->dts_shift != AV_NOPTS_VALUE)
5427 dts += track->dts_shift;
5428 track->track_duration = dts - track->start_dts;
5429 if (pts != AV_NOPTS_VALUE)
5430 track->end_pts = pts;
5431 else
5432 track->end_pts = dts;
5433 }
5434 }
5435 }
5436
5437 for (i = 0; i < mov->nb_streams; i++) {
5438 MOVTrack *track = &mov->tracks[i];
5439 if (track->entry <= 1)
5440 continue;
5441 // Sample durations are calculated as the diff of dts values,
5442 // but for the last sample in a fragment, we don't know the dts
5443 // of the first sample in the next fragment, so we have to rely
5444 // on what was set as duration in the AVPacket. Not all callers
5445 // set this though, so we might want to replace it with an
5446 // estimate if it currently is zero.
5447 if (get_cluster_duration(track, track->entry - 1) != 0)
5448 continue;
5449 // Use the duration (i.e. dts diff) of the second last sample for
5450 // the last one. This is a wild guess (and fatal if it turns out
5451 // to be too long), but probably the best we can do - having a zero
5452 // duration is bad as well.
5453 track->track_duration += get_cluster_duration(track, track->entry - 2);
5454 track->end_pts += get_cluster_duration(track, track->entry - 2);
5455 if (!mov->missing_duration_warned) {
5456 av_log(s, AV_LOG_WARNING,
5457 "Estimating the duration of the last packet in a "
5458 "fragment, consider setting the duration field in "
5459 "AVPacket instead.\n");
5460 mov->missing_duration_warned = 1;
5461 }
5462 }
5463
5464 if (!mov->moov_written) {
5465 int64_t pos = avio_tell(s->pb);
5466 uint8_t *buf;
5467 int buf_size, moov_size;
5468
5469 for (i = 0; i < mov->nb_streams; i++)
5470 if (!mov->tracks[i].entry && !is_cover_image(mov->tracks[i].st))
5471 break;
5472 /* Don't write the initial moov unless all tracks have data */
5473 if (i < mov->nb_streams && !force)
5474 return 0;
5475
5476 moov_size = get_moov_size(s);
5477 for (i = 0; i < mov->nb_streams; i++)
5478 mov->tracks[i].data_offset = pos + moov_size + 8;
5479
5480 avio_write_marker(s->pb, AV_NOPTS_VALUE, AVIO_DATA_MARKER_HEADER);
5481 if (mov->flags & FF_MOV_FLAG_DELAY_MOOV)
5482 mov_write_identification(s->pb, s);
5483 if ((ret = mov_write_moov_tag(s->pb, mov, s)) < 0)
5484 return ret;
5485
5486 if (mov->flags & FF_MOV_FLAG_DELAY_MOOV) {
5487 if (mov->flags & FF_MOV_FLAG_GLOBAL_SIDX)
5488 mov->reserved_header_pos = avio_tell(s->pb);
5489 avio_write_marker(s->pb, AV_NOPTS_VALUE, AVIO_DATA_MARKER_FLUSH_POINT);
5490 mov->moov_written = 1;
5491 return 0;
5492 }
5493
5494 buf_size = avio_get_dyn_buf(mov->mdat_buf, &buf);
5495 avio_wb32(s->pb, buf_size + 8);
5496 ffio_wfourcc(s->pb, "mdat");
5497 avio_write(s->pb, buf, buf_size);
5498 ffio_free_dyn_buf(&mov->mdat_buf);
5499
5500 if (mov->flags & FF_MOV_FLAG_GLOBAL_SIDX)
5501 mov->reserved_header_pos = avio_tell(s->pb);
5502
5503 mov->moov_written = 1;
5504 mov->mdat_size = 0;
5505 for (i = 0; i < mov->nb_streams; i++) {
5506 mov->tracks[i].entry = 0;
5507 mov->tracks[i].end_reliable = 0;
5508 }
5509 avio_write_marker(s->pb, AV_NOPTS_VALUE, AVIO_DATA_MARKER_FLUSH_POINT);
5510 return 0;
5511 }
5512
5513 if (mov->frag_interleave) {
5514 for (i = 0; i < mov->nb_streams; i++) {
5515 MOVTrack *track = &mov->tracks[i];
5516 int ret;
5517 if ((ret = mov_flush_fragment_interleaving(s, track)) < 0)
5518 return ret;
5519 }
5520
5521 if (!mov->mdat_buf)
5522 return 0;
5523 mdat_size = avio_tell(mov->mdat_buf);
5524 }
5525
5526 for (i = 0; i < mov->nb_streams; i++) {
5527 MOVTrack *track = &mov->tracks[i];
5528 if (mov->flags & FF_MOV_FLAG_SEPARATE_MOOF || mov->frag_interleave)
5529 track->data_offset = 0;
5530 else
5531 track->data_offset = mdat_size;
5532 if (track->par->codec_type == AVMEDIA_TYPE_VIDEO) {
5533 has_video = 1;
5534 if (first_video_track) {
5535 if (track->entry)
5536 starts_with_key = track->cluster[0].flags & MOV_SYNC_SAMPLE;
5537 first_video_track = 0;
5538 }
5539 }
5540 if (!track->entry)
5541 continue;
5542 if (track->mdat_buf)
5543 mdat_size += avio_tell(track->mdat_buf);
5544 if (first_track < 0)
5545 first_track = i;
5546 }
5547
5548 if (!mdat_size)
5549 return 0;
5550
5551 avio_write_marker(s->pb,
5552 av_rescale(mov->tracks[first_track].cluster[0].dts, AV_TIME_BASE, mov->tracks[first_track].timescale),
5553 (has_video ? starts_with_key : mov->tracks[first_track].cluster[0].flags & MOV_SYNC_SAMPLE) ? AVIO_DATA_MARKER_SYNC_POINT : AVIO_DATA_MARKER_BOUNDARY_POINT);
5554
5555 for (i = 0; i < mov->nb_streams; i++) {
5556 MOVTrack *track = &mov->tracks[i];
5557 int buf_size, write_moof = 1, moof_tracks = -1;
5558 uint8_t *buf;
5559
5560 if (mov->flags & FF_MOV_FLAG_SEPARATE_MOOF) {
5561 if (!track->entry)
5562 continue;
5563 mdat_size = avio_tell(track->mdat_buf);
5564 moof_tracks = i;
5565 } else {
5566 write_moof = i == first_track;
5567 }
5568
5569 if (write_moof) {
5570 avio_write_marker(s->pb, AV_NOPTS_VALUE, AVIO_DATA_MARKER_FLUSH_POINT);
5571
5572 mov_write_moof_tag(s->pb, mov, moof_tracks, mdat_size);
5573 mov->fragments++;
5574
5575 avio_wb32(s->pb, mdat_size + 8);
5576 ffio_wfourcc(s->pb, "mdat");
5577 }
5578
5579 track->entry = 0;
5580 track->entries_flushed = 0;
5581 track->end_reliable = 0;
5582 if (!mov->frag_interleave) {
5583 if (!track->mdat_buf)
5584 continue;
5585 buf_size = avio_close_dyn_buf(track->mdat_buf, &buf);
5586 track->mdat_buf = NULL;
5587 } else {
5588 if (!mov->mdat_buf)
5589 continue;
5590 buf_size = avio_close_dyn_buf(mov->mdat_buf, &buf);
5591 mov->mdat_buf = NULL;
5592 }
5593
5594 avio_write(s->pb, buf, buf_size);
5595 av_free(buf);
5596 }
5597
5598 mov->mdat_size = 0;
5599
5600 avio_write_marker(s->pb, AV_NOPTS_VALUE, AVIO_DATA_MARKER_FLUSH_POINT);
5601 return 0;
5602 }
5603
5604 static int mov_auto_flush_fragment(AVFormatContext *s, int force)
5605 {
5606 MOVMuxContext *mov = s->priv_data;
5607 int had_moov = mov->moov_written;
5608 int ret = mov_flush_fragment(s, force);
5609 if (ret < 0)
5610 return ret;
5611 // If using delay_moov, the first flush only wrote the moov,
5612 // not the actual moof+mdat pair, thus flush once again.
5613 if (!had_moov && mov->flags & FF_MOV_FLAG_DELAY_MOOV)
5614 ret = mov_flush_fragment(s, force);
5615 return ret;
5616 }
5617
5618 static int check_pkt(AVFormatContext *s, AVPacket *pkt)
5619 {
5620 MOVMuxContext *mov = s->priv_data;
5621 MOVTrack *trk = &mov->tracks[pkt->stream_index];
5622 int64_t ref;
5623 uint64_t duration;
5624
5625 if (trk->entry) {
5626 ref = trk->cluster[trk->entry - 1].dts;
5627 } else if ( trk->start_dts != AV_NOPTS_VALUE
5628 && !trk->frag_discont) {
5629 ref = trk->start_dts + trk->track_duration;
5630 } else
5631 ref = pkt->dts; // Skip tests for the first packet
5632
5633 if (trk->dts_shift != AV_NOPTS_VALUE) {
5634 /* With negative CTS offsets we have set an offset to the DTS,
5635 * reverse this for the check. */
5636 ref -= trk->dts_shift;
5637 }
5638
5639 duration = pkt->dts - ref;
5640 if (pkt->dts < ref || duration >= INT_MAX) {
5641 av_log(s, AV_LOG_ERROR, "Application provided duration: %"PRId64" / timestamp: %"PRId64" is out of range for mov/mp4 format\n",
5642 duration, pkt->dts
5643 );
5644
5645 pkt->dts = ref + 1;
5646 pkt->pts = AV_NOPTS_VALUE;
5647 }
5648
5649 if (pkt->duration < 0 || pkt->duration > INT_MAX) {
5650 av_log(s, AV_LOG_ERROR, "Application provided duration: %"PRId64" is invalid\n", pkt->duration);
5651 return AVERROR(EINVAL);
5652 }
5653 return 0;
5654 }
5655
5656 int ff_mov_write_packet(AVFormatContext *s, AVPacket *pkt)
5657 {
5658 MOVMuxContext *mov = s->priv_data;
5659 AVIOContext *pb = s->pb;
5660 MOVTrack *trk = &mov->tracks[pkt->stream_index];
5661 AVCodecParameters *par = trk->par;
5662 AVProducerReferenceTime *prft;
5663 unsigned int samples_in_chunk = 0;
5664 int size = pkt->size, ret = 0, offset = 0;
5665 size_t prft_size;
5666 uint8_t *reformatted_data = NULL;
5667
5668 ret = check_pkt(s, pkt);
5669 if (ret < 0)
5670 return ret;
5671
5672 if (mov->flags & FF_MOV_FLAG_FRAGMENT) {
5673 int ret;
5674 if (mov->moov_written || mov->flags & FF_MOV_FLAG_EMPTY_MOOV) {
5675 if (mov->frag_interleave && mov->fragments > 0) {
5676 if (trk->entry - trk->entries_flushed >= mov->frag_interleave) {
5677 if ((ret = mov_flush_fragment_interleaving(s, trk)) < 0)
5678 return ret;
5679 }
5680 }
5681
5682 if (!trk->mdat_buf) {
5683 if ((ret = avio_open_dyn_buf(&trk->mdat_buf)) < 0)
5684 return ret;
5685 }
5686 pb = trk->mdat_buf;
5687 } else {
5688 if (!mov->mdat_buf) {
5689 if ((ret = avio_open_dyn_buf(&mov->mdat_buf)) < 0)
5690 return ret;
5691 }
5692 pb = mov->mdat_buf;
5693 }
5694 }
5695
5696 if (par->codec_id == AV_CODEC_ID_AMR_NB) {
5697 /* We must find out how many AMR blocks there are in one packet */
5698 static const uint16_t packed_size[16] =
5699 {13, 14, 16, 18, 20, 21, 27, 32, 6, 0, 0, 0, 0, 0, 0, 1};
5700 int len = 0;
5701
5702 while (len < size && samples_in_chunk < 100) {
5703 len += packed_size[(pkt->data[len] >> 3) & 0x0F];
5704 samples_in_chunk++;
5705 }
5706 if (samples_in_chunk > 1) {
5707 av_log(s, AV_LOG_ERROR, "fatal error, input is not a single packet, implement a AVParser for it\n");
5708 return -1;
5709 }
5710 } else if (par->codec_id == AV_CODEC_ID_ADPCM_MS ||
5711 par->codec_id == AV_CODEC_ID_ADPCM_IMA_WAV) {
5712 samples_in_chunk = trk->par->frame_size;
5713 } else if (trk->sample_size)
5714 samples_in_chunk = size / trk->sample_size;
5715 else
5716 samples_in_chunk = 1;
5717
5718 if (samples_in_chunk < 1) {
5719 av_log(s, AV_LOG_ERROR, "fatal error, input packet contains no samples\n");
5720 return AVERROR_PATCHWELCOME;
5721 }
5722
5723 /* copy extradata if it exists */
5724 if (trk->vos_len == 0 && par->extradata_size > 0 &&
5725 !TAG_IS_AVCI(trk->tag) &&
5726 (par->codec_id != AV_CODEC_ID_DNXHD)) {
5727 trk->vos_len = par->extradata_size;
5728 trk->vos_data = av_malloc(trk->vos_len + AV_INPUT_BUFFER_PADDING_SIZE);
5729 if (!trk->vos_data) {
5730 ret = AVERROR(ENOMEM);
5731 goto err;
5732 }
5733 memcpy(trk->vos_data, par->extradata, trk->vos_len);
5734 memset(trk->vos_data + trk->vos_len, 0, AV_INPUT_BUFFER_PADDING_SIZE);
5735 }
5736
5737 if ((par->codec_id == AV_CODEC_ID_DNXHD ||
5738 par->codec_id == AV_CODEC_ID_H264 ||
5739 par->codec_id == AV_CODEC_ID_HEVC ||
5740 par->codec_id == AV_CODEC_ID_TRUEHD ||
5741 par->codec_id == AV_CODEC_ID_AC3) && !trk->vos_len &&
5742 !TAG_IS_AVCI(trk->tag)) {
5743 /* copy frame to create needed atoms */
5744 trk->vos_len = size;
5745 trk->vos_data = av_malloc(size + AV_INPUT_BUFFER_PADDING_SIZE);
5746 if (!trk->vos_data) {
5747 ret = AVERROR(ENOMEM);
5748 goto err;
5749 }
5750 memcpy(trk->vos_data, pkt->data, size);
5751 memset(trk->vos_data + size, 0, AV_INPUT_BUFFER_PADDING_SIZE);
5752 }
5753
5754 if (par->codec_id == AV_CODEC_ID_AAC && pkt->size > 2 &&
5755 (AV_RB16(pkt->data) & 0xfff0) == 0xfff0) {
5756 if (!s->streams[pkt->stream_index]->nb_frames) {
5757 av_log(s, AV_LOG_ERROR, "Malformed AAC bitstream detected: "
5758 "use the audio bitstream filter 'aac_adtstoasc' to fix it "
5759 "('-bsf:a aac_adtstoasc' option with ffmpeg)\n");
5760 return -1;
5761 }
5762 av_log(s, AV_LOG_WARNING, "aac bitstream error\n");
5763 }
5764 if (par->codec_id == AV_CODEC_ID_H264 && trk->vos_len > 0 && *(uint8_t *)trk->vos_data != 1 && !TAG_IS_AVCI(trk->tag)) {
5765 /* from x264 or from bytestream H.264 */
5766 /* NAL reformatting needed */
5767 if (trk->hint_track >= 0 && trk->hint_track < mov->nb_streams) {
5768 ret = ff_avc_parse_nal_units_buf(pkt->data, &reformatted_data,
5769 &size);
5770 if (ret < 0)
5771 return ret;
5772 avio_write(pb, reformatted_data, size);
5773 } else {
5774 if (trk->cenc.aes_ctr) {
5775 size = ff_mov_cenc_avc_parse_nal_units(&trk->cenc, pb, pkt->data, size);
5776 if (size < 0) {
5777 ret = size;
5778 goto err;
5779 }
5780 } else {
5781 size = ff_avc_parse_nal_units(pb, pkt->data, pkt->size);
5782 }
5783 }
5784 } else if (par->codec_id == AV_CODEC_ID_HEVC && trk->vos_len > 6 &&
5785 (AV_RB24(trk->vos_data) == 1 || AV_RB32(trk->vos_data) == 1)) {
5786 /* extradata is Annex B, assume the bitstream is too and convert it */
5787 if (trk->hint_track >= 0 && trk->hint_track < mov->nb_streams) {
5788 ret = ff_hevc_annexb2mp4_buf(pkt->data, &reformatted_data,
5789 &size, 0, NULL);
5790 if (ret < 0)
5791 return ret;
5792 avio_write(pb, reformatted_data, size);
5793 } else {
5794 if (trk->cenc.aes_ctr) {
5795 size = ff_mov_cenc_avc_parse_nal_units(&trk->cenc, pb, pkt->data, size);
5796 if (size < 0) {
5797 ret = size;
5798 goto err;
5799 }
5800 } else {
5801 size = ff_hevc_annexb2mp4(pb, pkt->data, pkt->size, 0, NULL);
5802 }
5803 }
5804 } else if (par->codec_id == AV_CODEC_ID_AV1) {
5805 if (trk->hint_track >= 0 && trk->hint_track < mov->nb_streams) {
5806 ret = ff_av1_filter_obus_buf(pkt->data, &reformatted_data,
5807 &size, &offset);
5808 if (ret < 0)
5809 return ret;
5810 avio_write(pb, reformatted_data, size);
5811 } else {
5812 size = ff_av1_filter_obus(pb, pkt->data, pkt->size);
5813 }
5814 #if CONFIG_AC3_PARSER
5815 } else if (par->codec_id == AV_CODEC_ID_EAC3) {
5816 size = handle_eac3(mov, pkt, trk);
5817 if (size < 0)
5818 return size;
5819 else if (!size)
5820 goto end;
5821 avio_write(pb, pkt->data, size);
5822 #endif
5823 } else if (par->codec_id == AV_CODEC_ID_EIA_608) {
5824 size = 8;
5825
5826 for (int i = 0; i < pkt->size; i += 3) {
5827 if (pkt->data[i] == 0xFC) {
5828 size += 2;
5829 }
5830 }
5831 avio_wb32(pb, size);
5832 ffio_wfourcc(pb, "cdat");
5833 for (int i = 0; i < pkt->size; i += 3) {
5834 if (pkt->data[i] == 0xFC) {
5835 avio_w8(pb, pkt->data[i + 1]);
5836 avio_w8(pb, pkt->data[i + 2]);
5837 }
5838 }
5839 } else {
5840 if (trk->cenc.aes_ctr) {
5841 if (par->codec_id == AV_CODEC_ID_H264 && par->extradata_size > 4) {
5842 int nal_size_length = (par->extradata[4] & 0x3) + 1;
5843 ret = ff_mov_cenc_avc_write_nal_units(s, &trk->cenc, nal_size_length, pb, pkt->data, size);
5844 } else if(par->codec_id == AV_CODEC_ID_HEVC && par->extradata_size > 21) {
5845 int nal_size_length = (par->extradata[21] & 0x3) + 1;
5846 ret = ff_mov_cenc_avc_write_nal_units(s, &trk->cenc, nal_size_length, pb, pkt->data, size);
5847 } else {
5848 ret = ff_mov_cenc_write_packet(&trk->cenc, pb, pkt->data, size);
5849 }
5850
5851 if (ret) {
5852 goto err;
5853 }
5854 } else {
5855 avio_write(pb, pkt->data, size);
5856 }
5857 }
5858
5859 if (trk->entry >= trk->cluster_capacity) {
5860 unsigned new_capacity = trk->entry + MOV_INDEX_CLUSTER_SIZE;
5861 void *cluster = av_realloc_array(trk->cluster, new_capacity, sizeof(*trk->cluster));
5862 if (!cluster) {
5863 ret = AVERROR(ENOMEM);
5864 goto err;
5865 }
5866 trk->cluster = cluster;
5867 trk->cluster_capacity = new_capacity;
5868 }
5869
5870 trk->cluster[trk->entry].pos = avio_tell(pb) - size;
5871 trk->cluster[trk->entry].samples_in_chunk = samples_in_chunk;
5872 trk->cluster[trk->entry].chunkNum = 0;
5873 trk->cluster[trk->entry].size = size;
5874 trk->cluster[trk->entry].entries = samples_in_chunk;
5875 trk->cluster[trk->entry].dts = pkt->dts;
5876 trk->cluster[trk->entry].pts = pkt->pts;
5877 if (!trk->squash_fragment_samples_to_one &&
5878 !trk->entry && trk->start_dts != AV_NOPTS_VALUE) {
5879 if (!trk->frag_discont) {
5880 /* First packet of a new fragment. We already wrote the duration
5881 * of the last packet of the previous fragment based on track_duration,
5882 * which might not exactly match our dts. Therefore adjust the dts
5883 * of this packet to be what the previous packets duration implies. */
5884 trk->cluster[trk->entry].dts = trk->start_dts + trk->track_duration;
5885 /* We also may have written the pts and the corresponding duration
5886 * in sidx/tfrf/tfxd tags; make sure the sidx pts and duration match up with
5887 * the next fragment. This means the cts of the first sample must
5888 * be the same in all fragments, unless end_pts was updated by
5889 * the packet causing the fragment to be written. */
5890 if ((mov->flags & FF_MOV_FLAG_DASH &&
5891 !(mov->flags & (FF_MOV_FLAG_GLOBAL_SIDX | FF_MOV_FLAG_SKIP_SIDX))) ||
5892 mov->mode == MODE_ISM)
5893 pkt->pts = pkt->dts + trk->end_pts - trk->cluster[trk->entry].dts;
5894 } else {
5895 /* New fragment, but discontinuous from previous fragments.
5896 * Pretend the duration sum of the earlier fragments is
5897 * pkt->dts - trk->start_dts. */
5898 trk->end_pts = AV_NOPTS_VALUE;
5899 trk->frag_discont = 0;
5900 }
5901 }
5902
5903 if (!trk->entry && trk->start_dts == AV_NOPTS_VALUE && !mov->use_editlist &&
5904 s->avoid_negative_ts == AVFMT_AVOID_NEG_TS_MAKE_ZERO) {
5905 /* Not using edit lists and shifting the first track to start from zero.
5906 * If the other streams start from a later timestamp, we won't be able
5907 * to signal the difference in starting time without an edit list.
5908 * Thus move the timestamp for this first sample to 0, increasing
5909 * its duration instead. */
5910 trk->cluster[trk->entry].dts = trk->start_dts = 0;
5911 }
5912 if (trk->start_dts == AV_NOPTS_VALUE) {
5913 trk->start_dts = pkt->dts;
5914 if (trk->frag_discont) {
5915 if (mov->use_editlist) {
5916 /* Pretend the whole stream started at pts=0, with earlier fragments
5917 * already written. If the stream started at pts=0, the duration sum
5918 * of earlier fragments would have been pkt->pts. */
5919 trk->start_dts = pkt->dts - pkt->pts;
5920 } else {
5921 /* Pretend the whole stream started at dts=0, with earlier fragments
5922 * already written, with a duration summing up to pkt->dts. */
5923 trk->start_dts = 0;
5924 }
5925 trk->frag_discont = 0;
5926 } else if (pkt->dts && mov->moov_written)
5927 av_log(s, AV_LOG_WARNING,
5928 "Track %d starts with a nonzero dts %"PRId64", while the moov "
5929 "already has been written. Set the delay_moov flag to handle "
5930 "this case.\n",
5931 pkt->stream_index, pkt->dts);
5932 }
5933 trk->track_duration = pkt->dts - trk->start_dts + pkt->duration;
5934 trk->last_sample_is_subtitle_end = 0;
5935
5936 if (pkt->pts == AV_NOPTS_VALUE) {
5937 av_log(s, AV_LOG_WARNING, "pts has no value\n");
5938 pkt->pts = pkt->dts;
5939 }
5940 if (pkt->dts != pkt->pts)
5941 trk->flags |= MOV_TRACK_CTTS;
5942 trk->cluster[trk->entry].cts = pkt->pts - pkt->dts;
5943 trk->cluster[trk->entry].flags = 0;
5944 if (trk->start_cts == AV_NOPTS_VALUE)
5945 trk->start_cts = pkt->pts - pkt->dts;
5946 if (trk->end_pts == AV_NOPTS_VALUE)
5947 trk->end_pts = trk->cluster[trk->entry].dts +
5948 trk->cluster[trk->entry].cts + pkt->duration;
5949 else
5950 trk->end_pts = FFMAX(trk->end_pts, trk->cluster[trk->entry].dts +
5951 trk->cluster[trk->entry].cts +
5952 pkt->duration);
5953
5954 if (par->codec_id == AV_CODEC_ID_VC1) {
5955 mov_parse_vc1_frame(pkt, trk);
5956 } else if (par->codec_id == AV_CODEC_ID_TRUEHD) {
5957 mov_parse_truehd_frame(pkt, trk);
5958 } else if (pkt->flags & AV_PKT_FLAG_KEY) {
5959 if (mov->mode == MODE_MOV && par->codec_id == AV_CODEC_ID_MPEG2VIDEO &&
5960 trk->entry > 0) { // force sync sample for the first key frame
5961 mov_parse_mpeg2_frame(pkt, &trk->cluster[trk->entry].flags);
5962 if (trk->cluster[trk->entry].flags & MOV_PARTIAL_SYNC_SAMPLE)
5963 trk->flags |= MOV_TRACK_STPS;
5964 } else {
5965 trk->cluster[trk->entry].flags = MOV_SYNC_SAMPLE;
5966 }
5967 if (trk->cluster[trk->entry].flags & MOV_SYNC_SAMPLE)
5968 trk->has_keyframes++;
5969 }
5970 if (pkt->flags & AV_PKT_FLAG_DISPOSABLE) {
5971 trk->cluster[trk->entry].flags |= MOV_DISPOSABLE_SAMPLE;
5972 trk->has_disposable++;
5973 }
5974
5975 prft = (AVProducerReferenceTime *)av_packet_get_side_data(pkt, AV_PKT_DATA_PRFT, &prft_size);
5976 if (prft && prft_size == sizeof(AVProducerReferenceTime))
5977 memcpy(&trk->cluster[trk->entry].prft, prft, prft_size);
5978 else
5979 memset(&trk->cluster[trk->entry].prft, 0, sizeof(AVProducerReferenceTime));
5980
5981 trk->entry++;
5982 trk->sample_count += samples_in_chunk;
5983 mov->mdat_size += size;
5984
5985 if (trk->hint_track >= 0 && trk->hint_track < mov->nb_streams)
5986 ff_mov_add_hinted_packet(s, pkt, trk->hint_track, trk->entry,
5987 reformatted_data ? reformatted_data + offset
5988 : NULL, size);
5989
5990 end:
5991 err:
5992
5993 if (pkt->data != reformatted_data)
5994 av_free(reformatted_data);
5995 return ret;
5996 }
5997
5998 static int mov_write_single_packet(AVFormatContext *s, AVPacket *pkt)
5999 {
6000 MOVMuxContext *mov = s->priv_data;
6001 MOVTrack *trk = &mov->tracks[pkt->stream_index];
6002 AVCodecParameters *par = trk->par;
6003 int64_t frag_duration = 0;
6004 int size = pkt->size;
6005
6006 int ret = check_pkt(s, pkt);
6007 if (ret < 0)
6008 return ret;
6009
6010 if (mov->flags & FF_MOV_FLAG_FRAG_DISCONT) {
6011 int i;
6012 for (i = 0; i < s->nb_streams; i++)
6013 mov->tracks[i].frag_discont = 1;
6014 mov->flags &= ~FF_MOV_FLAG_FRAG_DISCONT;
6015 }
6016
6017 if (mov->flags & FF_MOV_FLAG_NEGATIVE_CTS_OFFSETS) {
6018 if (trk->dts_shift == AV_NOPTS_VALUE)
6019 trk->dts_shift = pkt->pts - pkt->dts;
6020 pkt->dts += trk->dts_shift;
6021 }
6022
6023 if (trk->par->codec_id == AV_CODEC_ID_MP4ALS ||
6024 trk->par->codec_id == AV_CODEC_ID_AAC ||
6025 trk->par->codec_id == AV_CODEC_ID_AV1 ||
6026 trk->par->codec_id == AV_CODEC_ID_FLAC) {
6027 size_t side_size;
6028 uint8_t *side = av_packet_get_side_data(pkt, AV_PKT_DATA_NEW_EXTRADATA, &side_size);
6029 if (side && side_size > 0 && (side_size != par->extradata_size || memcmp(side, par->extradata, side_size))) {
6030 void *newextra = av_mallocz(side_size + AV_INPUT_BUFFER_PADDING_SIZE);
6031 if (!newextra)
6032 return AVERROR(ENOMEM);
6033 av_free(par->extradata);
6034 par->extradata = newextra;
6035 memcpy(par->extradata, side, side_size);
6036 par->extradata_size = side_size;
6037 if (!pkt->size) // Flush packet
6038 mov->need_rewrite_extradata = 1;
6039 }
6040 }
6041
6042 if (!pkt->size) {
6043 if (trk->start_dts == AV_NOPTS_VALUE && trk->frag_discont) {
6044 trk->start_dts = pkt->dts;
6045 if (pkt->pts != AV_NOPTS_VALUE)
6046 trk->start_cts = pkt->pts - pkt->dts;
6047 else
6048 trk->start_cts = 0;
6049 }
6050
6051 return 0; /* Discard 0 sized packets */
6052 }
6053
6054 if (trk->entry && pkt->stream_index < s->nb_streams)
6055 frag_duration = av_rescale_q(pkt->dts - trk->cluster[0].dts,
6056 s->streams[pkt->stream_index]->time_base,
6057 AV_TIME_BASE_Q);
6058 if ((mov->max_fragment_duration &&
6059 frag_duration >= mov->max_fragment_duration) ||
6060 (mov->max_fragment_size && mov->mdat_size + size >= mov->max_fragment_size) ||
6061 (mov->flags & FF_MOV_FLAG_FRAG_KEYFRAME &&
6062 par->codec_type == AVMEDIA_TYPE_VIDEO &&
6063 trk->entry && pkt->flags & AV_PKT_FLAG_KEY) ||
6064 (mov->flags & FF_MOV_FLAG_FRAG_EVERY_FRAME)) {
6065 if (frag_duration >= mov->min_fragment_duration) {
6066 if (trk->entry) {
6067 // Set the duration of this track to line up with the next
6068 // sample in this track. This avoids relying on AVPacket
6069 // duration, but only helps for this particular track, not
6070 // for the other ones that are flushed at the same time.
6071 //
6072 // If we have trk->entry == 0, no fragment will be written
6073 // for this track, and we can't adjust the track end here.
6074 trk->track_duration = pkt->dts - trk->start_dts;
6075 if (pkt->pts != AV_NOPTS_VALUE)
6076 trk->end_pts = pkt->pts;
6077 else
6078 trk->end_pts = pkt->dts;
6079 trk->end_reliable = 1;
6080 }
6081 mov_auto_flush_fragment(s, 0);
6082 }
6083 }
6084
6085 return ff_mov_write_packet(s, pkt);
6086 }
6087
6088 static int mov_write_subtitle_end_packet(AVFormatContext *s,
6089 int stream_index,
6090 int64_t dts) {
6091 MOVMuxContext *mov = s->priv_data;
6092 AVPacket *end = mov->pkt;
6093 uint8_t data[2] = {0};
6094 int ret;
6095
6096 end->size = sizeof(data);
6097 end->data = data;
6098 end->pts = dts;
6099 end->dts = dts;
6100 end->duration = 0;
6101 end->stream_index = stream_index;
6102
6103 ret = mov_write_single_packet(s, end);
6104 av_packet_unref(end);
6105
6106 return ret;
6107 }
6108
6109 static int mov_write_packet(AVFormatContext *s, AVPacket *pkt)
6110 {
6111 MOVMuxContext *mov = s->priv_data;
6112 MOVTrack *trk;
6113
6114 if (!pkt) {
6115 mov_flush_fragment(s, 1);
6116 return 1;
6117 }
6118
6119 trk = &mov->tracks[pkt->stream_index];
6120
6121 if (is_cover_image(trk->st)) {
6122 int ret;
6123
6124 if (trk->st->nb_frames >= 1) {
6125 if (trk->st->nb_frames == 1)
6126 av_log(s, AV_LOG_WARNING, "Got more than one picture in stream %d,"
6127 " ignoring.\n", pkt->stream_index);
6128 return 0;
6129 }
6130
6131 if ((ret = av_packet_ref(trk->cover_image, pkt)) < 0)
6132 return ret;
6133
6134 return 0;
6135 } else {
6136 int i;
6137
6138 if (!pkt->size)
6139 return mov_write_single_packet(s, pkt); /* Passthrough. */
6140
6141 /*
6142 * Subtitles require special handling.
6143 *
6144 * 1) For full complaince, every track must have a sample at
6145 * dts == 0, which is rarely true for subtitles. So, as soon
6146 * as we see any packet with dts > 0, write an empty subtitle
6147 * at dts == 0 for any subtitle track with no samples in it.
6148 *
6149 * 2) For each subtitle track, check if the current packet's
6150 * dts is past the duration of the last subtitle sample. If
6151 * so, we now need to write an end sample for that subtitle.
6152 *
6153 * This must be done conditionally to allow for subtitles that
6154 * immediately replace each other, in which case an end sample
6155 * is not needed, and is, in fact, actively harmful.
6156 *
6157 * 3) See mov_write_trailer for how the final end sample is
6158 * handled.
6159 */
6160 for (i = 0; i < mov->nb_streams; i++) {
6161 MOVTrack *trk = &mov->tracks[i];
6162 int ret;
6163
6164 if (trk->par->codec_id == AV_CODEC_ID_MOV_TEXT &&
6165 trk->track_duration < pkt->dts &&
6166 (trk->entry == 0 || !trk->last_sample_is_subtitle_end)) {
6167 ret = mov_write_subtitle_end_packet(s, i, trk->track_duration);
6168 if (ret < 0) return ret;
6169 trk->last_sample_is_subtitle_end = 1;
6170 }
6171 }
6172
6173 if (trk->squash_fragment_samples_to_one) {
6174 /*
6175 * If the track has to have its samples squashed into one sample,
6176 * we just take it into the track's queue.
6177 * This will then be utilized as the samples get written in either
6178 * mov_flush_fragment or when the mux is finalized in
6179 * mov_write_trailer.
6180 */
6181 int ret = AVERROR_BUG;
6182
6183 if (pkt->pts == AV_NOPTS_VALUE) {
6184 av_log(s, AV_LOG_ERROR,
6185 "Packets without a valid presentation timestamp are "
6186 "not supported with packet squashing!\n");
6187 return AVERROR(EINVAL);
6188 }
6189
6190 /* The following will reset pkt and is only allowed to be used
6191 * because we return immediately. afterwards. */
6192 if ((ret = avpriv_packet_list_put(&trk->squashed_packet_queue,
6193 pkt, NULL, 0)) < 0) {
6194 return ret;
6195 }
6196
6197 return 0;
6198 }
6199
6200
6201 if (trk->mode == MODE_MOV && trk->par->codec_type == AVMEDIA_TYPE_VIDEO) {
6202 AVPacket *opkt = pkt;
6203 int reshuffle_ret, ret;
6204 if (trk->is_unaligned_qt_rgb) {
6205 int64_t bpc = trk->par->bits_per_coded_sample != 15 ? trk->par->bits_per_coded_sample : 16;
6206 int expected_stride = ((trk->par->width * bpc + 15) >> 4)*2;
6207 reshuffle_ret = ff_reshuffle_raw_rgb(s, &pkt, trk->par, expected_stride);
6208 if (reshuffle_ret < 0)
6209 return reshuffle_ret;
6210 } else
6211 reshuffle_ret = 0;
6212 if (trk->par->format == AV_PIX_FMT_PAL8 && !trk->pal_done) {
6213 ret = ff_get_packet_palette(s, opkt, reshuffle_ret, trk->palette);
6214 if (ret < 0)
6215 goto fail;
6216 if (ret)
6217 trk->pal_done++;
6218 } else if (trk->par->codec_id == AV_CODEC_ID_RAWVIDEO &&
6219 (trk->par->format == AV_PIX_FMT_GRAY8 ||
6220 trk->par->format == AV_PIX_FMT_MONOBLACK)) {
6221 for (i = 0; i < pkt->size; i++)
6222 pkt->data[i] = ~pkt->data[i];
6223 }
6224 if (reshuffle_ret) {
6225 ret = mov_write_single_packet(s, pkt);
6226 fail:
6227 if (reshuffle_ret)
6228 av_packet_free(&pkt);
6229 return ret;
6230 }
6231 }
6232
6233 return mov_write_single_packet(s, pkt);
6234 }
6235 }
6236
6237 // QuickTime chapters involve an additional text track with the chapter names
6238 // as samples, and a tref pointing from the other tracks to the chapter one.
6239 static int mov_create_chapter_track(AVFormatContext *s, int tracknum)
6240 {
6241 AVIOContext *pb;
6242
6243 MOVMuxContext *mov = s->priv_data;
6244 MOVTrack *track = &mov->tracks[tracknum];
6245 AVPacket *pkt = mov->pkt;
6246 int i, len;
6247
6248 track->mode = mov->mode;
6249 track->tag = MKTAG('t','e','x','t');
6250 track->timescale = mov->movie_timescale;
6251 track->par = avcodec_parameters_alloc();
6252 if (!track->par)
6253 return AVERROR(ENOMEM);
6254 track->par->codec_type = AVMEDIA_TYPE_SUBTITLE;
6255 #if 0
6256 // These properties are required to make QT recognize the chapter track
6257 uint8_t chapter_properties[43] = { 0, 0, 0, 0, 0, 0, 0, 1, };
6258 if (ff_alloc_extradata(track->par, sizeof(chapter_properties)))
6259 return AVERROR(ENOMEM);
6260 memcpy(track->par->extradata, chapter_properties, sizeof(chapter_properties));
6261 #else
6262 if (avio_open_dyn_buf(&pb) >= 0) {
6263 int size;
6264 uint8_t *buf;
6265
6266 /* Stub header (usually for Quicktime chapter track) */
6267 // TextSampleEntry
6268 avio_wb32(pb, 0x01); // displayFlags
6269 avio_w8(pb, 0x00); // horizontal justification
6270 avio_w8(pb, 0x00); // vertical justification
6271 avio_w8(pb, 0x00); // bgColourRed
6272 avio_w8(pb, 0x00); // bgColourGreen
6273 avio_w8(pb, 0x00); // bgColourBlue
6274 avio_w8(pb, 0x00); // bgColourAlpha
6275 // BoxRecord
6276 avio_wb16(pb, 0x00); // defTextBoxTop
6277 avio_wb16(pb, 0x00); // defTextBoxLeft
6278 avio_wb16(pb, 0x00); // defTextBoxBottom
6279 avio_wb16(pb, 0x00); // defTextBoxRight
6280 // StyleRecord
6281 avio_wb16(pb, 0x00); // startChar
6282 avio_wb16(pb, 0x00); // endChar
6283 avio_wb16(pb, 0x01); // fontID
6284 avio_w8(pb, 0x00); // fontStyleFlags
6285 avio_w8(pb, 0x00); // fontSize
6286 avio_w8(pb, 0x00); // fgColourRed
6287 avio_w8(pb, 0x00); // fgColourGreen
6288 avio_w8(pb, 0x00); // fgColourBlue
6289 avio_w8(pb, 0x00); // fgColourAlpha
6290 // FontTableBox
6291 avio_wb32(pb, 0x0D); // box size
6292 ffio_wfourcc(pb, "ftab"); // box atom name
6293 avio_wb16(pb, 0x01); // entry count
6294 // FontRecord
6295 avio_wb16(pb, 0x01); // font ID
6296 avio_w8(pb, 0x00); // font name length
6297
6298 if ((size = avio_close_dyn_buf(pb, &buf)) > 0) {
6299 track->par->extradata = buf;
6300 track->par->extradata_size = size;
6301 } else {
6302 av_freep(&buf);
6303 }
6304 }
6305 #endif
6306
6307 pkt->stream_index = tracknum;
6308 pkt->flags = AV_PKT_FLAG_KEY;
6309
6310 for (i = 0; i < s->nb_chapters; i++) {
6311 AVChapter *c = s->chapters[i];
6312 AVDictionaryEntry *t;
6313
6314 int64_t end = av_rescale_q(c->end, c->time_base, (AVRational){1,mov->movie_timescale});
6315 pkt->pts = pkt->dts = av_rescale_q(c->start, c->time_base, (AVRational){1,mov->movie_timescale});
6316 pkt->duration = end - pkt->dts;
6317
6318 if ((t = av_dict_get(c->metadata, "title", NULL, 0))) {
6319 static const char encd[12] = {
6320 0x00, 0x00, 0x00, 0x0C,
6321 'e', 'n', 'c', 'd',
6322 0x00, 0x00, 0x01, 0x00 };
6323 len = strlen(t->value);
6324 pkt->size = len + 2 + 12;
6325 pkt->data = av_malloc(pkt->size);
6326 if (!pkt->data) {
6327 av_packet_unref(pkt);
6328 return AVERROR(ENOMEM);
6329 }
6330 AV_WB16(pkt->data, len);
6331 memcpy(pkt->data + 2, t->value, len);
6332 memcpy(pkt->data + len + 2, encd, sizeof(encd));
6333 ff_mov_write_packet(s, pkt);
6334 av_freep(&pkt->data);
6335 }
6336 }
6337
6338 av_packet_unref(mov->pkt);
6339
6340 return 0;
6341 }
6342
6343
6344 static int mov_check_timecode_track(AVFormatContext *s, AVTimecode *tc, int src_index, const char *tcstr)
6345 {
6346 int ret;
6347
6348 /* compute the frame number */
6349 ret = av_timecode_init_from_string(tc, s->streams[src_index]->avg_frame_rate, tcstr, s);
6350 return ret;
6351 }
6352
6353 static int mov_create_timecode_track(AVFormatContext *s, int index, int src_index, AVTimecode tc)
6354 {
6355 MOVMuxContext *mov = s->priv_data;
6356 MOVTrack *track = &mov->tracks[index];
6357 AVStream *src_st = s->streams[src_index];
6358 uint8_t data[4];
6359 AVPacket *pkt = mov->pkt;
6360 AVRational rate = src_st->avg_frame_rate;
6361 int ret;
6362
6363 /* tmcd track based on video stream */
6364 track->mode = mov->mode;
6365 track->tag = MKTAG('t','m','c','d');
6366 track->src_track = src_index;
6367 track->timescale = mov->tracks[src_index].timescale;
6368 if (tc.flags & AV_TIMECODE_FLAG_DROPFRAME)
6369 track->timecode_flags |= MOV_TIMECODE_FLAG_DROPFRAME;
6370
6371 /* set st to src_st for metadata access*/
6372 track->st = src_st;
6373
6374 /* encode context: tmcd data stream */
6375 track->par = avcodec_parameters_alloc();
6376 if (!track->par)
6377 return AVERROR(ENOMEM);
6378 track->par->codec_type = AVMEDIA_TYPE_DATA;
6379 track->par->codec_tag = track->tag;
6380 track->st->avg_frame_rate = rate;
6381
6382 /* the tmcd track just contains one packet with the frame number */
6383 pkt->data = data;
6384 pkt->stream_index = index;
6385 pkt->flags = AV_PKT_FLAG_KEY;
6386 pkt->size = 4;
6387 AV_WB32(pkt->data, tc.start);
6388 ret = ff_mov_write_packet(s, pkt);
6389 av_packet_unref(pkt);
6390 return ret;
6391 }
6392
6393 /*
6394 * st->disposition controls the "enabled" flag in the tkhd tag.
6395 * QuickTime will not play a track if it is not enabled. So make sure
6396 * that one track of each type (audio, video, subtitle) is enabled.
6397 *
6398 * Subtitles are special. For audio and video, setting "enabled" also
6399 * makes the track "default" (i.e. it is rendered when played). For
6400 * subtitles, an "enabled" subtitle is not rendered by default, but
6401 * if no subtitle is enabled, the subtitle menu in QuickTime will be
6402 * empty!
6403 */
6404 static void enable_tracks(AVFormatContext *s)
6405 {
6406 MOVMuxContext *mov = s->priv_data;
6407 int i;
6408 int enabled[AVMEDIA_TYPE_NB];
6409 int first[AVMEDIA_TYPE_NB];
6410
6411 for (i = 0; i < AVMEDIA_TYPE_NB; i++) {
6412 enabled[i] = 0;
6413 first[i] = -1;
6414 }
6415
6416 for (i = 0; i < s->nb_streams; i++) {
6417 AVStream *st = s->streams[i];
6418
6419 if (st->codecpar->codec_type <= AVMEDIA_TYPE_UNKNOWN ||
6420 st->codecpar->codec_type >= AVMEDIA_TYPE_NB ||
6421 is_cover_image(st))
6422 continue;
6423
6424 if (first[st->codecpar->codec_type] < 0)
6425 first[st->codecpar->codec_type] = i;
6426 if (st->disposition & AV_DISPOSITION_DEFAULT) {
6427 mov->tracks[i].flags |= MOV_TRACK_ENABLED;
6428 enabled[st->codecpar->codec_type]++;
6429 }
6430 }
6431
6432 for (i = 0; i < AVMEDIA_TYPE_NB; i++) {
6433 switch (i) {
6434 case AVMEDIA_TYPE_VIDEO:
6435 case AVMEDIA_TYPE_AUDIO:
6436 case AVMEDIA_TYPE_SUBTITLE:
6437 if (enabled[i] > 1)
6438 mov->per_stream_grouping = 1;
6439 if (!enabled[i] && first[i] >= 0)
6440 mov->tracks[first[i]].flags |= MOV_TRACK_ENABLED;
6441 break;
6442 }
6443 }
6444 }
6445
6446 static void mov_free(AVFormatContext *s)
6447 {
6448 MOVMuxContext *mov = s->priv_data;
6449 int i;
6450
6451 if (!mov->tracks)
6452 return;
6453
6454 if (mov->chapter_track) {
6455 avcodec_parameters_free(&mov->tracks[mov->chapter_track].par);
6456 }
6457
6458 for (i = 0; i < mov->nb_streams; i++) {
6459 MOVTrack *const track = &mov->tracks[i];
6460
6461 if (track->tag == MKTAG('r','t','p',' '))
6462 ff_mov_close_hinting(track);
6463 else if (track->tag == MKTAG('t','m','c','d') && mov->nb_meta_tmcd)
6464 av_freep(&track->par);
6465 av_freep(&track->cluster);
6466 av_freep(&track->frag_info);
6467 av_packet_free(&track->cover_image);
6468
6469 if (track->eac3_priv) {
6470 struct eac3_info *info = track->eac3_priv;
6471 av_packet_free(&info->pkt);
6472 av_freep(&track->eac3_priv);
6473 }
6474 if (track->vos_len)
6475 av_freep(&track->vos_data);
6476
6477 ff_mov_cenc_free(&track->cenc);
6478 ffio_free_dyn_buf(&track->mdat_buf);
6479
6480 avpriv_packet_list_free(&track->squashed_packet_queue);
6481 }
6482
6483 av_freep(&mov->tracks);
6484 ffio_free_dyn_buf(&mov->mdat_buf);
6485 }
6486
6487 static uint32_t rgb_to_yuv(uint32_t rgb)
6488 {
6489 uint8_t r, g, b;
6490 int y, cb, cr;
6491
6492 r = (rgb >> 16) & 0xFF;
6493 g = (rgb >> 8) & 0xFF;
6494 b = (rgb ) & 0xFF;
6495
6496 y = av_clip_uint8(( 16000 + 257 * r + 504 * g + 98 * b)/1000);
6497 cb = av_clip_uint8((128000 - 148 * r - 291 * g + 439 * b)/1000);
6498 cr = av_clip_uint8((128000 + 439 * r - 368 * g - 71 * b)/1000);
6499
6500 return (y << 16) | (cr << 8) | cb;
6501 }
6502
6503 static int mov_create_dvd_sub_decoder_specific_info(MOVTrack *track,
6504 AVStream *st)
6505 {
6506 int i, width = 720, height = 480;
6507 int have_palette = 0, have_size = 0;
6508 uint32_t palette[16];
6509 char *cur = st->codecpar->extradata;
6510
6511 while (cur && *cur) {
6512 if (strncmp("palette:", cur, 8) == 0) {
6513 int i, count;
6514 count = sscanf(cur + 8,
6515 "%06"PRIx32", %06"PRIx32", %06"PRIx32", %06"PRIx32", "
6516 "%06"PRIx32", %06"PRIx32", %06"PRIx32", %06"PRIx32", "
6517 "%06"PRIx32", %06"PRIx32", %06"PRIx32", %06"PRIx32", "
6518 "%06"PRIx32", %06"PRIx32", %06"PRIx32", %06"PRIx32"",
6519 &palette[ 0], &palette[ 1], &palette[ 2], &palette[ 3],
6520 &palette[ 4], &palette[ 5], &palette[ 6], &palette[ 7],
6521 &palette[ 8], &palette[ 9], &palette[10], &palette[11],
6522 &palette[12], &palette[13], &palette[14], &palette[15]);
6523
6524 for (i = 0; i < count; i++) {
6525 palette[i] = rgb_to_yuv(palette[i]);
6526 }
6527 have_palette = 1;
6528 } else if (!strncmp("size:", cur, 5)) {
6529 sscanf(cur + 5, "%dx%d", &width, &height);
6530 have_size = 1;
6531 }
6532 if (have_palette && have_size)
6533 break;
6534 cur += strcspn(cur, "\n\r");
6535 cur += strspn(cur, "\n\r");
6536 }
6537 if (have_palette) {
6538 track->vos_data = av_malloc(16*4 + AV_INPUT_BUFFER_PADDING_SIZE);
6539 if (!track->vos_data)
6540 return AVERROR(ENOMEM);
6541 for (i = 0; i < 16; i++) {
6542 AV_WB32(track->vos_data + i * 4, palette[i]);
6543 }
6544 memset(track->vos_data + 16*4, 0, AV_INPUT_BUFFER_PADDING_SIZE);
6545 track->vos_len = 16 * 4;
6546 }
6547 st->codecpar->width = width;
6548 st->codecpar->height = track->height = height;
6549
6550 return 0;
6551 }
6552
6553 static int mov_init(AVFormatContext *s)
6554 {
6555 MOVMuxContext *mov = s->priv_data;
6556 int i, ret;
6557
6558 mov->fc = s;
6559 mov->pkt = ffformatcontext(s)->pkt;
6560
6561 /* Default mode == MP4 */
6562 mov->mode = MODE_MP4;
6563
6564 #define IS_MODE(muxer, config) (CONFIG_ ## config ## _MUXER && !strcmp(#muxer, s->oformat->name))
6565 if (IS_MODE(3gp, TGP)) mov->mode = MODE_3GP;
6566 else if (IS_MODE(3g2, TG2)) mov->mode = MODE_3GP|MODE_3G2;
6567 else if (IS_MODE(mov, MOV)) mov->mode = MODE_MOV;
6568 else if (IS_MODE(psp, PSP)) mov->mode = MODE_PSP;
6569 else if (IS_MODE(ipod, IPOD)) mov->mode = MODE_IPOD;
6570 else if (IS_MODE(ismv, ISMV)) mov->mode = MODE_ISM;
6571 else if (IS_MODE(f4v, F4V)) mov->mode = MODE_F4V;
6572 #undef IS_MODE
6573
6574 if (mov->flags & FF_MOV_FLAG_DELAY_MOOV)
6575 mov->flags |= FF_MOV_FLAG_EMPTY_MOOV;
6576
6577 /* Set the FRAGMENT flag if any of the fragmentation methods are
6578 * enabled. */
6579 if (mov->max_fragment_duration || mov->max_fragment_size ||
6580 mov->flags & (FF_MOV_FLAG_EMPTY_MOOV |
6581 FF_MOV_FLAG_FRAG_KEYFRAME |
6582 FF_MOV_FLAG_FRAG_CUSTOM |
6583 FF_MOV_FLAG_FRAG_EVERY_FRAME))
6584 mov->flags |= FF_MOV_FLAG_FRAGMENT;
6585
6586 /* Set other implicit flags immediately */
6587 if (mov->mode == MODE_ISM)
6588 mov->flags |= FF_MOV_FLAG_EMPTY_MOOV | FF_MOV_FLAG_SEPARATE_MOOF |
6589 FF_MOV_FLAG_FRAGMENT | FF_MOV_FLAG_NEGATIVE_CTS_OFFSETS;
6590 if (mov->flags & FF_MOV_FLAG_DASH)
6591 mov->flags |= FF_MOV_FLAG_FRAGMENT | FF_MOV_FLAG_EMPTY_MOOV |
6592 FF_MOV_FLAG_DEFAULT_BASE_MOOF;
6593 if (mov->flags & FF_MOV_FLAG_CMAF)
6594 mov->flags |= FF_MOV_FLAG_FRAGMENT | FF_MOV_FLAG_EMPTY_MOOV |
6595 FF_MOV_FLAG_DEFAULT_BASE_MOOF | FF_MOV_FLAG_NEGATIVE_CTS_OFFSETS;
6596
6597 if (mov->flags & FF_MOV_FLAG_EMPTY_MOOV && s->flags & AVFMT_FLAG_AUTO_BSF) {
6598 av_log(s, AV_LOG_VERBOSE, "Empty MOOV enabled; disabling automatic bitstream filtering\n");
6599 s->flags &= ~AVFMT_FLAG_AUTO_BSF;
6600 }
6601
6602 if (mov->flags & FF_MOV_FLAG_GLOBAL_SIDX && mov->flags & FF_MOV_FLAG_SKIP_SIDX) {
6603 av_log(s, AV_LOG_WARNING, "Global SIDX enabled; Ignoring skip_sidx option\n");
6604 mov->flags &= ~FF_MOV_FLAG_SKIP_SIDX;
6605 }
6606
6607 if (mov->flags & FF_MOV_FLAG_FASTSTART) {
6608 mov->reserved_moov_size = -1;
6609 }
6610
6611 if (mov->use_editlist < 0) {
6612 mov->use_editlist = 1;
6613 if (mov->flags & FF_MOV_FLAG_FRAGMENT &&
6614 !(mov->flags & FF_MOV_FLAG_DELAY_MOOV)) {
6615 // If we can avoid needing an edit list by shifting the
6616 // tracks, prefer that over (trying to) write edit lists
6617 // in fragmented output.
6618 if (s->avoid_negative_ts == AVFMT_AVOID_NEG_TS_AUTO ||
6619 s->avoid_negative_ts == AVFMT_AVOID_NEG_TS_MAKE_ZERO)
6620 mov->use_editlist = 0;
6621 }
6622 if (mov->flags & FF_MOV_FLAG_CMAF) {
6623 // CMAF Track requires negative cts offsets without edit lists
6624 mov->use_editlist = 0;
6625 }
6626 }
6627 if (mov->flags & FF_MOV_FLAG_EMPTY_MOOV &&
6628 !(mov->flags & FF_MOV_FLAG_DELAY_MOOV) && mov->use_editlist)
6629 av_log(s, AV_LOG_WARNING, "No meaningful edit list will be written when using empty_moov without delay_moov\n");
6630
6631 if (mov->flags & FF_MOV_FLAG_CMAF && mov->use_editlist) {
6632 av_log(s, AV_LOG_WARNING, "Edit list enabled; Assuming writing CMAF Track File\n");
6633 mov->flags &= ~FF_MOV_FLAG_NEGATIVE_CTS_OFFSETS;
6634 }
6635 if (!mov->use_editlist && s->avoid_negative_ts == AVFMT_AVOID_NEG_TS_AUTO &&
6636 !(mov->flags & FF_MOV_FLAG_NEGATIVE_CTS_OFFSETS))
6637 s->avoid_negative_ts = AVFMT_AVOID_NEG_TS_MAKE_ZERO;
6638
6639 /* Clear the omit_tfhd_offset flag if default_base_moof is set;
6640 * if the latter is set that's enough and omit_tfhd_offset doesn't
6641 * add anything extra on top of that. */
6642 if (mov->flags & FF_MOV_FLAG_OMIT_TFHD_OFFSET &&
6643 mov->flags & FF_MOV_FLAG_DEFAULT_BASE_MOOF)
6644 mov->flags &= ~FF_MOV_FLAG_OMIT_TFHD_OFFSET;
6645
6646 if (mov->frag_interleave &&
6647 mov->flags & (FF_MOV_FLAG_OMIT_TFHD_OFFSET | FF_MOV_FLAG_SEPARATE_MOOF)) {
6648 av_log(s, AV_LOG_ERROR,
6649 "Sample interleaving in fragments is mutually exclusive with "
6650 "omit_tfhd_offset and separate_moof\n");
6651 return AVERROR(EINVAL);
6652 }
6653
6654 /* Non-seekable output is ok if using fragmentation. If ism_lookahead
6655 * is enabled, we don't support non-seekable output at all. */
6656 if (!(s->pb->seekable & AVIO_SEEKABLE_NORMAL) &&
6657 (!(mov->flags & FF_MOV_FLAG_FRAGMENT) || mov->ism_lookahead)) {
6658 av_log(s, AV_LOG_ERROR, "muxer does not support non seekable output\n");
6659 return AVERROR(EINVAL);
6660 }
6661
6662 mov->nb_streams = s->nb_streams;
6663 if (mov->mode & (MODE_MP4|MODE_MOV|MODE_IPOD) && s->nb_chapters)
6664 mov->chapter_track = mov->nb_streams++;
6665
6666 if (mov->flags & FF_MOV_FLAG_RTP_HINT) {
6667 for (i = 0; i < s->nb_streams; i++)
6668 if (rtp_hinting_needed(s->streams[i]))
6669 mov->nb_streams++;
6670 }
6671
6672 if ( mov->write_tmcd == -1 && (mov->mode == MODE_MOV || mov->mode == MODE_MP4)
6673 || mov->write_tmcd == 1) {
6674 AVDictionaryEntry *global_tcr = av_dict_get(s->metadata, "timecode",
6675 NULL, 0);
6676
6677 /* +1 tmcd track for each video stream with a timecode */
6678 for (i = 0; i < s->nb_streams; i++) {
6679 AVStream *st = s->streams[i];
6680 AVDictionaryEntry *t = global_tcr;
6681 if (st->codecpar->codec_type == AVMEDIA_TYPE_VIDEO &&
6682 (t || (t=av_dict_get(st->metadata, "timecode", NULL, 0)))) {
6683 AVTimecode tc;
6684 ret = mov_check_timecode_track(s, &tc, i, t->value);
6685 if (ret >= 0)
6686 mov->nb_meta_tmcd++;
6687 }
6688 }
6689
6690 /* check if there is already a tmcd track to remux */
6691 if (mov->nb_meta_tmcd) {
6692 for (i = 0; i < s->nb_streams; i++) {
6693 AVStream *st = s->streams[i];
6694 if (st->codecpar->codec_tag == MKTAG('t','m','c','d')) {
6695 av_log(s, AV_LOG_WARNING, "You requested a copy of the original timecode track "
6696 "so timecode metadata are now ignored\n");
6697 mov->nb_meta_tmcd = 0;
6698 }
6699 }
6700 }
6701
6702 mov->nb_streams += mov->nb_meta_tmcd;
6703 }
6704
6705 // Reserve an extra stream for chapters for the case where chapters
6706 // are written in the trailer
6707 mov->tracks = av_calloc(mov->nb_streams + 1, sizeof(*mov->tracks));
6708 if (!mov->tracks)
6709 return AVERROR(ENOMEM);
6710
6711 if (mov->encryption_scheme_str != NULL && strcmp(mov->encryption_scheme_str, "none") != 0) {
6712 if (strcmp(mov->encryption_scheme_str, "cenc-aes-ctr") == 0) {
6713 mov->encryption_scheme = MOV_ENC_CENC_AES_CTR;
6714
6715 if (mov->encryption_key_len != AES_CTR_KEY_SIZE) {
6716 av_log(s, AV_LOG_ERROR, "Invalid encryption key len %d expected %d\n",
6717 mov->encryption_key_len, AES_CTR_KEY_SIZE);
6718 return AVERROR(EINVAL);
6719 }
6720
6721 if (mov->encryption_kid_len != CENC_KID_SIZE) {
6722 av_log(s, AV_LOG_ERROR, "Invalid encryption kid len %d expected %d\n",
6723 mov->encryption_kid_len, CENC_KID_SIZE);
6724 return AVERROR(EINVAL);
6725 }
6726 } else {
6727 av_log(s, AV_LOG_ERROR, "unsupported encryption scheme %s\n",
6728 mov->encryption_scheme_str);
6729 return AVERROR(EINVAL);
6730 }
6731 }
6732
6733 for (i = 0; i < s->nb_streams; i++) {
6734 AVStream *st= s->streams[i];
6735 MOVTrack *track= &mov->tracks[i];
6736 AVDictionaryEntry *lang = av_dict_get(st->metadata, "language", NULL,0);
6737
6738 track->st = st;
6739 track->par = st->codecpar;
6740 track->language = ff_mov_iso639_to_lang(lang?lang->value:"und", mov->mode!=MODE_MOV);
6741 if (track->language < 0)
6742 track->language = 32767; // Unspecified Macintosh language code
6743 track->mode = mov->mode;
6744 track->tag = mov_find_codec_tag(s, track);
6745 if (!track->tag) {
6746 av_log(s, AV_LOG_ERROR, "Could not find tag for codec %s in stream #%d, "
6747 "codec not currently supported in container\n",
6748 avcodec_get_name(st->codecpar->codec_id), i);
6749 return AVERROR(EINVAL);
6750 }
6751 /* If hinting of this track is enabled by a later hint track,
6752 * this is updated. */
6753 track->hint_track = -1;
6754 track->start_dts = AV_NOPTS_VALUE;
6755 track->start_cts = AV_NOPTS_VALUE;
6756 track->end_pts = AV_NOPTS_VALUE;
6757 track->dts_shift = AV_NOPTS_VALUE;
6758 if (st->codecpar->codec_type == AVMEDIA_TYPE_VIDEO) {
6759 if (track->tag == MKTAG('m','x','3','p') || track->tag == MKTAG('m','x','3','n') ||
6760 track->tag == MKTAG('m','x','4','p') || track->tag == MKTAG('m','x','4','n') ||
6761 track->tag == MKTAG('m','x','5','p') || track->tag == MKTAG('m','x','5','n')) {
6762 if (st->codecpar->width != 720 || (st->codecpar->height != 608 && st->codecpar->height != 512)) {
6763 av_log(s, AV_LOG_ERROR, "D-10/IMX must use 720x608 or 720x512 video resolution\n");
6764 return AVERROR(EINVAL);
6765 }
6766 track->height = track->tag >> 24 == 'n' ? 486 : 576;
6767 }
6768 if (mov->video_track_timescale) {
6769 track->timescale = mov->video_track_timescale;
6770 if (mov->mode == MODE_ISM && mov->video_track_timescale != 10000000)
6771 av_log(s, AV_LOG_WARNING, "Warning: some tools, like mp4split, assume a timescale of 10000000 for ISMV.\n");
6772 } else {
6773 track->timescale = st->time_base.den;
6774 while(track->timescale < 10000)
6775 track->timescale *= 2;
6776 }
6777 if (st->codecpar->width > 65535 || st->codecpar->height > 65535) {
6778 av_log(s, AV_LOG_ERROR, "Resolution %dx%d too large for mov/mp4\n", st->codecpar->width, st->codecpar->height);
6779 return AVERROR(EINVAL);
6780 }
6781 if (track->mode == MODE_MOV && track->timescale > 100000)
6782 av_log(s, AV_LOG_WARNING,
6783 "WARNING codec timebase is very high. If duration is too long,\n"
6784 "file may not be playable by quicktime. Specify a shorter timebase\n"
6785 "or choose different container.\n");
6786 if (track->mode == MODE_MOV &&
6787 track->par->codec_id == AV_CODEC_ID_RAWVIDEO &&
6788 track->tag == MKTAG('r','a','w',' ')) {
6789 enum AVPixelFormat pix_fmt = track->par->format;
6790 if (pix_fmt == AV_PIX_FMT_NONE && track->par->bits_per_coded_sample == 1)
6791 pix_fmt = AV_PIX_FMT_MONOWHITE;
6792 track->is_unaligned_qt_rgb =
6793 pix_fmt == AV_PIX_FMT_RGB24 ||
6794 pix_fmt == AV_PIX_FMT_BGR24 ||
6795 pix_fmt == AV_PIX_FMT_PAL8 ||
6796 pix_fmt == AV_PIX_FMT_GRAY8 ||
6797 pix_fmt == AV_PIX_FMT_MONOWHITE ||
6798 pix_fmt == AV_PIX_FMT_MONOBLACK;
6799 }
6800 if (track->par->codec_id == AV_CODEC_ID_VP9 ||
6801 track->par->codec_id == AV_CODEC_ID_AV1) {
6802 if (track->mode != MODE_MP4) {
6803 av_log(s, AV_LOG_ERROR, "%s only supported in MP4.\n", avcodec_get_name(track->par->codec_id));
6804 return AVERROR(EINVAL);
6805 }
6806 } else if (track->par->codec_id == AV_CODEC_ID_VP8) {
6807 /* altref frames handling is not defined in the spec as of version v1.0,
6808 * so just forbid muxing VP8 streams altogether until a new version does */
6809 av_log(s, AV_LOG_ERROR, "VP8 muxing is currently not supported.\n");
6810 return AVERROR_PATCHWELCOME;
6811 }
6812 if (is_cover_image(st)) {
6813 track->cover_image = av_packet_alloc();
6814 if (!track->cover_image)
6815 return AVERROR(ENOMEM);
6816 }
6817 } else if (st->codecpar->codec_type == AVMEDIA_TYPE_AUDIO) {
6818 track->timescale = st->codecpar->sample_rate;
6819 if (!st->codecpar->frame_size && !av_get_bits_per_sample(st->codecpar->codec_id)) {
6820 av_log(s, AV_LOG_WARNING, "track %d: codec frame size is not set\n", i);
6821 track->audio_vbr = 1;
6822 }else if (st->codecpar->codec_id == AV_CODEC_ID_ADPCM_MS ||
6823 st->codecpar->codec_id == AV_CODEC_ID_ADPCM_IMA_WAV ||
6824 st->codecpar->codec_id == AV_CODEC_ID_ILBC){
6825 if (!st->codecpar->block_align) {
6826 av_log(s, AV_LOG_ERROR, "track %d: codec block align is not set for adpcm\n", i);
6827 return AVERROR(EINVAL);
6828 }
6829 track->sample_size = st->codecpar->block_align;
6830 }else if (st->codecpar->frame_size > 1){ /* assume compressed audio */
6831 track->audio_vbr = 1;
6832 }else{
6833 track->sample_size = (av_get_bits_per_sample(st->codecpar->codec_id) >> 3) * st->codecpar->channels;
6834 }
6835 if (st->codecpar->codec_id == AV_CODEC_ID_ILBC ||
6836 st->codecpar->codec_id == AV_CODEC_ID_ADPCM_IMA_QT) {
6837 track->audio_vbr = 1;
6838 }
6839 if (track->mode != MODE_MOV &&
6840 track->par->codec_id == AV_CODEC_ID_MP3 && track->timescale < 16000) {
6841 if (s->strict_std_compliance >= FF_COMPLIANCE_NORMAL) {
6842 av_log(s, AV_LOG_ERROR, "track %d: muxing mp3 at %dhz is not standard, to mux anyway set strict to -1\n",
6843 i, track->par->sample_rate);
6844 return AVERROR(EINVAL);
6845 } else {
6846 av_log(s, AV_LOG_WARNING, "track %d: muxing mp3 at %dhz is not standard in MP4\n",
6847 i, track->par->sample_rate);
6848 }
6849 }
6850 if (track->par->codec_id == AV_CODEC_ID_FLAC ||
6851 track->par->codec_id == AV_CODEC_ID_TRUEHD ||
6852 track->par->codec_id == AV_CODEC_ID_OPUS) {
6853 if (track->mode != MODE_MP4) {
6854 av_log(s, AV_LOG_ERROR, "%s only supported in MP4.\n", avcodec_get_name(track->par->codec_id));
6855 return AVERROR(EINVAL);
6856 }
6857 if (track->par->codec_id != AV_CODEC_ID_OPUS &&
6858 s->strict_std_compliance > FF_COMPLIANCE_EXPERIMENTAL) {
6859 av_log(s, AV_LOG_ERROR,
6860 "%s in MP4 support is experimental, add "
6861 "'-strict %d' if you want to use it.\n",
6862 avcodec_get_name(track->par->codec_id), FF_COMPLIANCE_EXPERIMENTAL);
6863 return AVERROR_EXPERIMENTAL;
6864 }
6865 }
6866 } else if (st->codecpar->codec_type == AVMEDIA_TYPE_SUBTITLE) {
6867 track->timescale = st->time_base.den;
6868
6869 if (track->par->codec_id == AV_CODEC_ID_TTML) {
6870 /* 14496-30 requires us to use a single sample per fragment
6871 for TTML, for which we define a per-track flag.
6872
6873 We set the flag in case we are receiving TTML paragraphs
6874 from the input, in other words in case we are not doing
6875 stream copy. */
6876 track->squash_fragment_samples_to_one =
6877 ff_is_ttml_stream_paragraph_based(track->par);
6878
6879 if (mov->flags & FF_MOV_FLAG_FRAGMENT &&
6880 track->squash_fragment_samples_to_one) {
6881 av_log(s, AV_LOG_ERROR,
6882 "Fragmentation is not currently supported for "
6883 "TTML in MP4/ISMV (track synchronization between "
6884 "subtitles and other media is not yet implemented)!\n");
6885 return AVERROR_PATCHWELCOME;
6886 }
6887
6888 if (track->mode != MODE_ISM &&
6889 track->par->codec_tag == MOV_ISMV_TTML_TAG &&
6890 s->strict_std_compliance > FF_COMPLIANCE_UNOFFICIAL) {
6891 av_log(s, AV_LOG_ERROR,
6892 "ISMV style TTML support with the 'dfxp' tag in "
6893 "non-ISMV formats is not officially supported. Add "
6894 "'-strict unofficial' if you want to use it.\n");
6895 return AVERROR_EXPERIMENTAL;
6896 }
6897 }
6898 } else if (st->codecpar->codec_type == AVMEDIA_TYPE_DATA) {
6899 track->timescale = st->time_base.den;
6900 } else {
6901 track->timescale = mov->movie_timescale;
6902 }
6903 if (!track->height)
6904 track->height = st->codecpar->height;
6905 /* The Protected Interoperable File Format (PIFF) standard, used by ISMV recommends but
6906 doesn't mandate a track timescale of 10,000,000. The muxer allows a custom timescale
6907 for video tracks, so if user-set, it isn't overwritten */
6908 if (mov->mode == MODE_ISM &&
6909 (st->codecpar->codec_type != AVMEDIA_TYPE_VIDEO ||
6910 (st->codecpar->codec_type == AVMEDIA_TYPE_VIDEO && !mov->video_track_timescale))) {
6911 track->timescale = 10000000;
6912 }
6913
6914 avpriv_set_pts_info(st, 64, 1, track->timescale);
6915
6916 if (mov->encryption_scheme == MOV_ENC_CENC_AES_CTR) {
6917 ret = ff_mov_cenc_init(&track->cenc, mov->encryption_key,
6918 (track->par->codec_id == AV_CODEC_ID_H264 || track->par->codec_id == AV_CODEC_ID_HEVC),
6919 s->flags & AVFMT_FLAG_BITEXACT);
6920 if (ret)
6921 return ret;
6922 }
6923 }
6924
6925 enable_tracks(s);
6926 return 0;
6927 }
6928
6929 static int mov_write_header(AVFormatContext *s)
6930 {
6931 AVIOContext *pb = s->pb;
6932 MOVMuxContext *mov = s->priv_data;
6933 int i, ret, hint_track = 0, tmcd_track = 0, nb_tracks = s->nb_streams;
6934
6935 if (mov->mode & (MODE_MP4|MODE_MOV|MODE_IPOD) && s->nb_chapters)
6936 nb_tracks++;
6937
6938 if (mov->flags & FF_MOV_FLAG_RTP_HINT) {
6939 hint_track = nb_tracks;
6940 for (i = 0; i < s->nb_streams; i++)
6941 if (rtp_hinting_needed(s->streams[i]))
6942 nb_tracks++;
6943 }
6944
6945 if (mov->nb_meta_tmcd)
6946 tmcd_track = nb_tracks;
6947
6948 for (i = 0; i < s->nb_streams; i++) {
6949 int j;
6950 AVStream *st= s->streams[i];
6951 MOVTrack *track= &mov->tracks[i];
6952
6953 /* copy extradata if it exists */
6954 if (st->codecpar->extradata_size) {
6955 if (st->codecpar->codec_id == AV_CODEC_ID_DVD_SUBTITLE)
6956 mov_create_dvd_sub_decoder_specific_info(track, st);
6957 else if (!TAG_IS_AVCI(track->tag) && st->codecpar->codec_id != AV_CODEC_ID_DNXHD) {
6958 track->vos_len = st->codecpar->extradata_size;
6959 track->vos_data = av_malloc(track->vos_len + AV_INPUT_BUFFER_PADDING_SIZE);
6960 if (!track->vos_data) {
6961 return AVERROR(ENOMEM);
6962 }
6963 memcpy(track->vos_data, st->codecpar->extradata, track->vos_len);
6964 memset(track->vos_data + track->vos_len, 0, AV_INPUT_BUFFER_PADDING_SIZE);
6965 }
6966 }
6967
6968 if (st->codecpar->codec_type != AVMEDIA_TYPE_AUDIO ||
6969 track->par->channel_layout != AV_CH_LAYOUT_MONO)
6970 continue;
6971
6972 for (j = 0; j < s->nb_streams; j++) {
6973 AVStream *stj= s->streams[j];
6974 MOVTrack *trackj= &mov->tracks[j];
6975 if (j == i)
6976 continue;
6977
6978 if (stj->codecpar->codec_type != AVMEDIA_TYPE_AUDIO ||
6979 trackj->par->channel_layout != AV_CH_LAYOUT_MONO ||
6980 trackj->language != track->language ||
6981 trackj->tag != track->tag
6982 )
6983 continue;
6984 track->multichannel_as_mono++;
6985 }
6986 }
6987
6988 if (!(mov->flags & FF_MOV_FLAG_DELAY_MOOV)) {
6989 if ((ret = mov_write_identification(pb, s)) < 0)
6990 return ret;
6991 }
6992
6993 if (mov->reserved_moov_size){
6994 mov->reserved_header_pos = avio_tell(pb);
6995 if (mov->reserved_moov_size > 0)
6996 avio_skip(pb, mov->reserved_moov_size);
6997 }
6998
6999 if (mov->flags & FF_MOV_FLAG_FRAGMENT) {
7000 /* If no fragmentation options have been set, set a default. */
7001 if (!(mov->flags & (FF_MOV_FLAG_FRAG_KEYFRAME |
7002 FF_MOV_FLAG_FRAG_CUSTOM |
7003 FF_MOV_FLAG_FRAG_EVERY_FRAME)) &&
7004 !mov->max_fragment_duration && !mov->max_fragment_size)
7005 mov->flags |= FF_MOV_FLAG_FRAG_KEYFRAME;
7006 } else {
7007 if (mov->flags & FF_MOV_FLAG_FASTSTART)
7008 mov->reserved_header_pos = avio_tell(pb);
7009 mov_write_mdat_tag(pb, mov);
7010 }
7011
7012 ff_parse_creation_time_metadata(s, &mov->time, 1);
7013 if (mov->time)
7014 mov->time += 0x7C25B080; // 1970 based -> 1904 based
7015
7016 if (mov->chapter_track)
7017 if ((ret = mov_create_chapter_track(s, mov->chapter_track)) < 0)
7018 return ret;
7019
7020 if (mov->flags & FF_MOV_FLAG_RTP_HINT) {
7021 for (i = 0; i < s->nb_streams; i++) {
7022 if (rtp_hinting_needed(s->streams[i])) {
7023 if ((ret = ff_mov_init_hinting(s, hint_track, i)) < 0)
7024 return ret;
7025 hint_track++;
7026 }
7027 }
7028 }
7029
7030 if (mov->nb_meta_tmcd) {
7031 const AVDictionaryEntry *t, *global_tcr = av_dict_get(s->metadata,
7032 "timecode", NULL, 0);
7033 /* Initialize the tmcd tracks */
7034 for (i = 0; i < s->nb_streams; i++) {
7035 AVStream *st = s->streams[i];
7036 t = global_tcr;
7037
7038 if (st->codecpar->codec_type == AVMEDIA_TYPE_VIDEO) {
7039 AVTimecode tc;
7040 if (!t)
7041 t = av_dict_get(st->metadata, "timecode", NULL, 0);
7042 if (!t)
7043 continue;
7044 if (mov_check_timecode_track(s, &tc, i, t->value) < 0)
7045 continue;
7046 if ((ret = mov_create_timecode_track(s, tmcd_track, i, tc)) < 0)
7047 return ret;
7048 tmcd_track++;
7049 }
7050 }
7051 }
7052
7053 avio_flush(pb);
7054
7055 if (mov->flags & FF_MOV_FLAG_ISML)
7056 mov_write_isml_manifest(pb, mov, s);
7057
7058 if (mov->flags & FF_MOV_FLAG_EMPTY_MOOV &&
7059 !(mov->flags & FF_MOV_FLAG_DELAY_MOOV)) {
7060 if ((ret = mov_write_moov_tag(pb, mov, s)) < 0)
7061 return ret;
7062 mov->moov_written = 1;
7063 if (mov->flags & FF_MOV_FLAG_GLOBAL_SIDX)
7064 mov->reserved_header_pos = avio_tell(pb);
7065 }
7066
7067 return 0;
7068 }
7069
7070 static int get_moov_size(AVFormatContext *s)
7071 {
7072 int ret;
7073 AVIOContext *moov_buf;
7074 MOVMuxContext *mov = s->priv_data;
7075
7076 if ((ret = ffio_open_null_buf(&moov_buf)) < 0)
7077 return ret;
7078 if ((ret = mov_write_moov_tag(moov_buf, mov, s)) < 0)
7079 return ret;
7080 return ffio_close_null_buf(moov_buf);
7081 }
7082
7083 static int get_sidx_size(AVFormatContext *s)
7084 {
7085 int ret;
7086 AVIOContext *buf;
7087 MOVMuxContext *mov = s->priv_data;
7088
7089 if ((ret = ffio_open_null_buf(&buf)) < 0)
7090 return ret;
7091 mov_write_sidx_tags(buf, mov, -1, 0);
7092 return ffio_close_null_buf(buf);
7093 }
7094
7095 /*
7096 * This function gets the moov size if moved to the top of the file: the chunk
7097 * offset table can switch between stco (32-bit entries) to co64 (64-bit
7098 * entries) when the moov is moved to the beginning, so the size of the moov
7099 * would change. It also updates the chunk offset tables.
7100 */
7101 static int compute_moov_size(AVFormatContext *s)
7102 {
7103 int i, moov_size, moov_size2;
7104 MOVMuxContext *mov = s->priv_data;
7105
7106 moov_size = get_moov_size(s);
7107 if (moov_size < 0)
7108 return moov_size;
7109
7110 for (i = 0; i < mov->nb_streams; i++)
7111 mov->tracks[i].data_offset += moov_size;
7112
7113 moov_size2 = get_moov_size(s);
7114 if (moov_size2 < 0)
7115 return moov_size2;
7116
7117 /* if the size changed, we just switched from stco to co64 and need to
7118 * update the offsets */
7119 if (moov_size2 != moov_size)
7120 for (i = 0; i < mov->nb_streams; i++)
7121 mov->tracks[i].data_offset += moov_size2 - moov_size;
7122
7123 return moov_size2;
7124 }
7125
7126 static int compute_sidx_size(AVFormatContext *s)
7127 {
7128 int i, sidx_size;
7129 MOVMuxContext *mov = s->priv_data;
7130
7131 sidx_size = get_sidx_size(s);
7132 if (sidx_size < 0)
7133 return sidx_size;
7134
7135 for (i = 0; i < mov->nb_streams; i++)
7136 mov->tracks[i].data_offset += sidx_size;
7137
7138 return sidx_size;
7139 }
7140
7141 static int shift_data(AVFormatContext *s)
7142 {
7143 int moov_size;
7144 MOVMuxContext *mov = s->priv_data;
7145
7146 if (mov->flags & FF_MOV_FLAG_FRAGMENT)
7147 moov_size = compute_sidx_size(s);
7148 else
7149 moov_size = compute_moov_size(s);
7150 if (moov_size < 0)
7151 return moov_size;
7152
7153 return ff_format_shift_data(s, mov->reserved_header_pos, moov_size);
7154 }
7155
7156 static int mov_write_trailer(AVFormatContext *s)
7157 {
7158 MOVMuxContext *mov = s->priv_data;
7159 AVIOContext *pb = s->pb;
7160 int res = 0;
7161 int i;
7162 int64_t moov_pos;
7163
7164 if (mov->need_rewrite_extradata) {
7165 for (i = 0; i < s->nb_streams; i++) {
7166 MOVTrack *track = &mov->tracks[i];
7167 AVCodecParameters *par = track->par;
7168
7169 track->vos_len = par->extradata_size;
7170 av_freep(&track->vos_data);
7171 track->vos_data = av_malloc(track->vos_len + AV_INPUT_BUFFER_PADDING_SIZE);
7172 if (!track->vos_data)
7173 return AVERROR(ENOMEM);
7174 memcpy(track->vos_data, par->extradata, track->vos_len);
7175 memset(track->vos_data + track->vos_len, 0, AV_INPUT_BUFFER_PADDING_SIZE);
7176 }
7177 mov->need_rewrite_extradata = 0;
7178 }
7179
7180 /*
7181 * Before actually writing the trailer, make sure that there are no
7182 * dangling subtitles, that need a terminating sample.
7183 */
7184 for (i = 0; i < mov->nb_streams; i++) {
7185 MOVTrack *trk = &mov->tracks[i];
7186 if (trk->par->codec_id == AV_CODEC_ID_MOV_TEXT &&
7187 !trk->last_sample_is_subtitle_end) {
7188 mov_write_subtitle_end_packet(s, i, trk->track_duration);
7189 trk->last_sample_is_subtitle_end = 1;
7190 }
7191 }
7192
7193 // Check if we have any tracks that require squashing.
7194 // In that case, we'll have to write the packet here.
7195 if ((res = mov_write_squashed_packets(s)) < 0)
7196 return res;
7197
7198 // If there were no chapters when the header was written, but there
7199 // are chapters now, write them in the trailer. This only works
7200 // when we are not doing fragments.
7201 if (!mov->chapter_track && !(mov->flags & FF_MOV_FLAG_FRAGMENT)) {
7202 if (mov->mode & (MODE_MP4|MODE_MOV|MODE_IPOD) && s->nb_chapters) {
7203 mov->chapter_track = mov->nb_streams++;
7204 if ((res = mov_create_chapter_track(s, mov->chapter_track)) < 0)
7205 return res;
7206 }
7207 }
7208
7209 if (!(mov->flags & FF_MOV_FLAG_FRAGMENT)) {
7210 moov_pos = avio_tell(pb);
7211
7212 /* Write size of mdat tag */
7213 if (mov->mdat_size + 8 <= UINT32_MAX) {
7214 avio_seek(pb, mov->mdat_pos, SEEK_SET);
7215 avio_wb32(pb, mov->mdat_size + 8);
7216 } else {
7217 /* overwrite 'wide' placeholder atom */
7218 avio_seek(pb, mov->mdat_pos - 8, SEEK_SET);
7219 /* special value: real atom size will be 64 bit value after
7220 * tag field */
7221 avio_wb32(pb, 1);
7222 ffio_wfourcc(pb, "mdat");
7223 avio_wb64(pb, mov->mdat_size + 16);
7224 }
7225 avio_seek(pb, mov->reserved_moov_size > 0 ? mov->reserved_header_pos : moov_pos, SEEK_SET);
7226
7227 if (mov->flags & FF_MOV_FLAG_FASTSTART) {
7228 av_log(s, AV_LOG_INFO, "Starting second pass: moving the moov atom to the beginning of the file\n");
7229 res = shift_data(s);
7230 if (res < 0)
7231 return res;
7232 avio_seek(pb, mov->reserved_header_pos, SEEK_SET);
7233 if ((res = mov_write_moov_tag(pb, mov, s)) < 0)
7234 return res;
7235 } else if (mov->reserved_moov_size > 0) {
7236 int64_t size;
7237 if ((res = mov_write_moov_tag(pb, mov, s)) < 0)
7238 return res;
7239 size = mov->reserved_moov_size - (avio_tell(pb) - mov->reserved_header_pos);
7240 if (size < 8){
7241 av_log(s, AV_LOG_ERROR, "reserved_moov_size is too small, needed %"PRId64" additional\n", 8-size);
7242 return AVERROR(EINVAL);
7243 }
7244 avio_wb32(pb, size);
7245 ffio_wfourcc(pb, "free");
7246 ffio_fill(pb, 0, size - 8);
7247 avio_seek(pb, moov_pos, SEEK_SET);
7248 } else {
7249 if ((res = mov_write_moov_tag(pb, mov, s)) < 0)
7250 return res;
7251 }
7252 res = 0;
7253 } else {
7254 mov_auto_flush_fragment(s, 1);
7255 for (i = 0; i < mov->nb_streams; i++)
7256 mov->tracks[i].data_offset = 0;
7257 if (mov->flags & FF_MOV_FLAG_GLOBAL_SIDX) {
7258 int64_t end;
7259 av_log(s, AV_LOG_INFO, "Starting second pass: inserting sidx atoms\n");
7260 res = shift_data(s);
7261 if (res < 0)
7262 return res;
7263 end = avio_tell(pb);
7264 avio_seek(pb, mov->reserved_header_pos, SEEK_SET);
7265 mov_write_sidx_tags(pb, mov, -1, 0);
7266 avio_seek(pb, end, SEEK_SET);
7267 }
7268 if (!(mov->flags & FF_MOV_FLAG_SKIP_TRAILER)) {
7269 avio_write_marker(s->pb, AV_NOPTS_VALUE, AVIO_DATA_MARKER_TRAILER);
7270 res = mov_write_mfra_tag(pb, mov);
7271 if (res < 0)
7272 return res;
7273 }
7274 }
7275
7276 return res;
7277 }
7278
7279 static int mov_check_bitstream(AVFormatContext *s, AVStream *st,
7280 const AVPacket *pkt)
7281 {
7282 int ret = 1;
7283
7284 if (st->codecpar->codec_id == AV_CODEC_ID_AAC) {
7285 if (pkt->size > 2 && (AV_RB16(pkt->data) & 0xfff0) == 0xfff0)
7286 ret = ff_stream_add_bitstream_filter(st, "aac_adtstoasc", NULL);
7287 } else if (st->codecpar->codec_id == AV_CODEC_ID_VP9) {
7288 ret = ff_stream_add_bitstream_filter(st, "vp9_superframe", NULL);
7289 }
7290
7291 return ret;
7292 }
7293
7294 #if CONFIG_TGP_MUXER || CONFIG_TG2_MUXER
7295 static const AVCodecTag codec_3gp_tags[] = {
7296 { AV_CODEC_ID_H263, MKTAG('s','2','6','3') },
7297 { AV_CODEC_ID_H264, MKTAG('a','v','c','1') },
7298 { AV_CODEC_ID_MPEG4, MKTAG('m','p','4','v') },
7299 { AV_CODEC_ID_AAC, MKTAG('m','p','4','a') },
7300 { AV_CODEC_ID_AMR_NB, MKTAG('s','a','m','r') },
7301 { AV_CODEC_ID_AMR_WB, MKTAG('s','a','w','b') },
7302 { AV_CODEC_ID_MOV_TEXT, MKTAG('t','x','3','g') },
7303 { AV_CODEC_ID_NONE, 0 },
7304 };
7305 static const AVCodecTag *const codec_3gp_tags_list[] = { codec_3gp_tags, NULL };
7306 #endif
7307
7308 static const AVCodecTag codec_mp4_tags[] = {
7309 { AV_CODEC_ID_MPEG4, MKTAG('m', 'p', '4', 'v') },
7310 { AV_CODEC_ID_H264, MKTAG('a', 'v', 'c', '1') },
7311 { AV_CODEC_ID_H264, MKTAG('a', 'v', 'c', '3') },
7312 { AV_CODEC_ID_HEVC, MKTAG('h', 'e', 'v', '1') },
7313 { AV_CODEC_ID_HEVC, MKTAG('h', 'v', 'c', '1') },
7314 { AV_CODEC_ID_MPEG2VIDEO, MKTAG('m', 'p', '4', 'v') },
7315 { AV_CODEC_ID_MPEG1VIDEO, MKTAG('m', 'p', '4', 'v') },
7316 { AV_CODEC_ID_MJPEG, MKTAG('m', 'p', '4', 'v') },
7317 { AV_CODEC_ID_PNG, MKTAG('m', 'p', '4', 'v') },
7318 { AV_CODEC_ID_JPEG2000, MKTAG('m', 'p', '4', 'v') },
7319 { AV_CODEC_ID_VC1, MKTAG('v', 'c', '-', '1') },
7320 { AV_CODEC_ID_DIRAC, MKTAG('d', 'r', 'a', 'c') },
7321 { AV_CODEC_ID_TSCC2, MKTAG('m', 'p', '4', 'v') },
7322 { AV_CODEC_ID_VP9, MKTAG('v', 'p', '0', '9') },
7323 { AV_CODEC_ID_AV1, MKTAG('a', 'v', '0', '1') },
7324 { AV_CODEC_ID_AAC, MKTAG('m', 'p', '4', 'a') },
7325 { AV_CODEC_ID_ALAC, MKTAG('a', 'l', 'a', 'c') },
7326 { AV_CODEC_ID_MP4ALS, MKTAG('m', 'p', '4', 'a') },
7327 { AV_CODEC_ID_MP3, MKTAG('m', 'p', '4', 'a') },
7328 { AV_CODEC_ID_MP2, MKTAG('m', 'p', '4', 'a') },
7329 { AV_CODEC_ID_AC3, MKTAG('a', 'c', '-', '3') },
7330 { AV_CODEC_ID_EAC3, MKTAG('e', 'c', '-', '3') },
7331 { AV_CODEC_ID_DTS, MKTAG('m', 'p', '4', 'a') },
7332 { AV_CODEC_ID_TRUEHD, MKTAG('m', 'l', 'p', 'a') },
7333 { AV_CODEC_ID_FLAC, MKTAG('f', 'L', 'a', 'C') },
7334 { AV_CODEC_ID_OPUS, MKTAG('O', 'p', 'u', 's') },
7335 { AV_CODEC_ID_VORBIS, MKTAG('m', 'p', '4', 'a') },
7336 { AV_CODEC_ID_QCELP, MKTAG('m', 'p', '4', 'a') },
7337 { AV_CODEC_ID_EVRC, MKTAG('m', 'p', '4', 'a') },
7338 { AV_CODEC_ID_DVD_SUBTITLE, MKTAG('m', 'p', '4', 's') },
7339 { AV_CODEC_ID_MOV_TEXT, MKTAG('t', 'x', '3', 'g') },
7340 { AV_CODEC_ID_BIN_DATA, MKTAG('g', 'p', 'm', 'd') },
7341 { AV_CODEC_ID_MPEGH_3D_AUDIO, MKTAG('m', 'h', 'm', '1') },
7342 { AV_CODEC_ID_TTML, MOV_MP4_TTML_TAG },
7343 { AV_CODEC_ID_TTML, MOV_ISMV_TTML_TAG },
7344 { AV_CODEC_ID_NONE, 0 },
7345 };
7346 #if CONFIG_MP4_MUXER || CONFIG_PSP_MUXER
7347 static const AVCodecTag *const mp4_codec_tags_list[] = { codec_mp4_tags, NULL };
7348 #endif
7349
7350 static const AVCodecTag codec_ism_tags[] = {
7351 { AV_CODEC_ID_WMAPRO , MKTAG('w', 'm', 'a', ' ') },
7352 { AV_CODEC_ID_TTML , MOV_ISMV_TTML_TAG },
7353 { AV_CODEC_ID_NONE , 0 },
7354 };
7355
7356 static const AVCodecTag codec_ipod_tags[] = {
7357 { AV_CODEC_ID_H264, MKTAG('a','v','c','1') },
7358 { AV_CODEC_ID_MPEG4, MKTAG('m','p','4','v') },
7359 { AV_CODEC_ID_AAC, MKTAG('m','p','4','a') },
7360 { AV_CODEC_ID_ALAC, MKTAG('a','l','a','c') },
7361 { AV_CODEC_ID_AC3, MKTAG('a','c','-','3') },
7362 { AV_CODEC_ID_MOV_TEXT, MKTAG('t','x','3','g') },
7363 { AV_CODEC_ID_MOV_TEXT, MKTAG('t','e','x','t') },
7364 { AV_CODEC_ID_NONE, 0 },
7365 };
7366
7367 static const AVCodecTag codec_f4v_tags[] = {
7368 { AV_CODEC_ID_MP3, MKTAG('.','m','p','3') },
7369 { AV_CODEC_ID_AAC, MKTAG('m','p','4','a') },
7370 { AV_CODEC_ID_H264, MKTAG('a','v','c','1') },
7371 { AV_CODEC_ID_VP6A, MKTAG('V','P','6','A') },
7372 { AV_CODEC_ID_VP6F, MKTAG('V','P','6','F') },
7373 { AV_CODEC_ID_NONE, 0 },
7374 };
7375
7376 #if CONFIG_MOV_MUXER
7377 const AVOutputFormat ff_mov_muxer = {
7378 .name = "mov",
7379 .long_name = NULL_IF_CONFIG_SMALL("QuickTime / MOV"),
7380 .extensions = "mov",
7381 .priv_data_size = sizeof(MOVMuxContext),
7382 .audio_codec = AV_CODEC_ID_AAC,
7383 .video_codec = CONFIG_LIBX264_ENCODER ?
7384 AV_CODEC_ID_H264 : AV_CODEC_ID_MPEG4,
7385 .init = mov_init,
7386 .write_header = mov_write_header,
7387 .write_packet = mov_write_packet,
7388 .write_trailer = mov_write_trailer,
7389 .deinit = mov_free,
7390 .flags = AVFMT_GLOBALHEADER | AVFMT_ALLOW_FLUSH | AVFMT_TS_NEGATIVE,
7391 .codec_tag = (const AVCodecTag* const []){
7392 ff_codec_movvideo_tags, ff_codec_movaudio_tags, ff_codec_movsubtitle_tags, 0
7393 },
7394 .check_bitstream = mov_check_bitstream,
7395 .priv_class = &mov_isobmff_muxer_class,
7396 };
7397 #endif
7398 #if CONFIG_TGP_MUXER
7399 const AVOutputFormat ff_tgp_muxer = {
7400 .name = "3gp",
7401 .long_name = NULL_IF_CONFIG_SMALL("3GP (3GPP file format)"),
7402 .extensions = "3gp",
7403 .priv_data_size = sizeof(MOVMuxContext),
7404 .audio_codec = AV_CODEC_ID_AMR_NB,
7405 .video_codec = AV_CODEC_ID_H263,
7406 .init = mov_init,
7407 .write_header = mov_write_header,
7408 .write_packet = mov_write_packet,
7409 .write_trailer = mov_write_trailer,
7410 .deinit = mov_free,
7411 .flags = AVFMT_GLOBALHEADER | AVFMT_ALLOW_FLUSH | AVFMT_TS_NEGATIVE,
7412 .codec_tag = codec_3gp_tags_list,
7413 .check_bitstream = mov_check_bitstream,
7414 .priv_class = &mov_isobmff_muxer_class,
7415 };
7416 #endif
7417 #if CONFIG_MP4_MUXER
7418 const AVOutputFormat ff_mp4_muxer = {
7419 .name = "mp4",
7420 .long_name = NULL_IF_CONFIG_SMALL("MP4 (MPEG-4 Part 14)"),
7421 .mime_type = "video/mp4",
7422 .extensions = "mp4",
7423 .priv_data_size = sizeof(MOVMuxContext),
7424 .audio_codec = AV_CODEC_ID_AAC,
7425 .video_codec = CONFIG_LIBX264_ENCODER ?
7426 AV_CODEC_ID_H264 : AV_CODEC_ID_MPEG4,
7427 .init = mov_init,
7428 .write_header = mov_write_header,
7429 .write_packet = mov_write_packet,
7430 .write_trailer = mov_write_trailer,
7431 .deinit = mov_free,
7432 .flags = AVFMT_GLOBALHEADER | AVFMT_ALLOW_FLUSH | AVFMT_TS_NEGATIVE,
7433 .codec_tag = mp4_codec_tags_list,
7434 .check_bitstream = mov_check_bitstream,
7435 .priv_class = &mov_isobmff_muxer_class,
7436 };
7437 #endif
7438 #if CONFIG_PSP_MUXER
7439 const AVOutputFormat ff_psp_muxer = {
7440 .name = "psp",
7441 .long_name = NULL_IF_CONFIG_SMALL("PSP MP4 (MPEG-4 Part 14)"),
7442 .extensions = "mp4,psp",
7443 .priv_data_size = sizeof(MOVMuxContext),
7444 .audio_codec = AV_CODEC_ID_AAC,
7445 .video_codec = CONFIG_LIBX264_ENCODER ?
7446 AV_CODEC_ID_H264 : AV_CODEC_ID_MPEG4,
7447 .init = mov_init,
7448 .write_header = mov_write_header,
7449 .write_packet = mov_write_packet,
7450 .write_trailer = mov_write_trailer,
7451 .deinit = mov_free,
7452 .flags = AVFMT_GLOBALHEADER | AVFMT_ALLOW_FLUSH | AVFMT_TS_NEGATIVE,
7453 .codec_tag = mp4_codec_tags_list,
7454 .check_bitstream = mov_check_bitstream,
7455 .priv_class = &mov_isobmff_muxer_class,
7456 };
7457 #endif
7458 #if CONFIG_TG2_MUXER
7459 const AVOutputFormat ff_tg2_muxer = {
7460 .name = "3g2",
7461 .long_name = NULL_IF_CONFIG_SMALL("3GP2 (3GPP2 file format)"),
7462 .extensions = "3g2",
7463 .priv_data_size = sizeof(MOVMuxContext),
7464 .audio_codec = AV_CODEC_ID_AMR_NB,
7465 .video_codec = AV_CODEC_ID_H263,
7466 .init = mov_init,
7467 .write_header = mov_write_header,
7468 .write_packet = mov_write_packet,
7469 .write_trailer = mov_write_trailer,
7470 .deinit = mov_free,
7471 .flags = AVFMT_GLOBALHEADER | AVFMT_ALLOW_FLUSH | AVFMT_TS_NEGATIVE,
7472 .codec_tag = codec_3gp_tags_list,
7473 .check_bitstream = mov_check_bitstream,
7474 .priv_class = &mov_isobmff_muxer_class,
7475 };
7476 #endif
7477 #if CONFIG_IPOD_MUXER
7478 const AVOutputFormat ff_ipod_muxer = {
7479 .name = "ipod",
7480 .long_name = NULL_IF_CONFIG_SMALL("iPod H.264 MP4 (MPEG-4 Part 14)"),
7481 .mime_type = "video/mp4",
7482 .extensions = "m4v,m4a,m4b",
7483 .priv_data_size = sizeof(MOVMuxContext),
7484 .audio_codec = AV_CODEC_ID_AAC,
7485 .video_codec = AV_CODEC_ID_H264,
7486 .init = mov_init,
7487 .write_header = mov_write_header,
7488 .write_packet = mov_write_packet,
7489 .write_trailer = mov_write_trailer,
7490 .deinit = mov_free,
7491 .flags = AVFMT_GLOBALHEADER | AVFMT_ALLOW_FLUSH | AVFMT_TS_NEGATIVE,
7492 .codec_tag = (const AVCodecTag* const []){ codec_ipod_tags, 0 },
7493 .check_bitstream = mov_check_bitstream,
7494 .priv_class = &mov_isobmff_muxer_class,
7495 };
7496 #endif
7497 #if CONFIG_ISMV_MUXER
7498 const AVOutputFormat ff_ismv_muxer = {
7499 .name = "ismv",
7500 .long_name = NULL_IF_CONFIG_SMALL("ISMV/ISMA (Smooth Streaming)"),
7501 .mime_type = "video/mp4",
7502 .extensions = "ismv,isma",
7503 .priv_data_size = sizeof(MOVMuxContext),
7504 .audio_codec = AV_CODEC_ID_AAC,
7505 .video_codec = AV_CODEC_ID_H264,
7506 .init = mov_init,
7507 .write_header = mov_write_header,
7508 .write_packet = mov_write_packet,
7509 .write_trailer = mov_write_trailer,
7510 .deinit = mov_free,
7511 .flags = AVFMT_GLOBALHEADER | AVFMT_ALLOW_FLUSH | AVFMT_TS_NEGATIVE,
7512 .codec_tag = (const AVCodecTag* const []){
7513 codec_mp4_tags, codec_ism_tags, 0 },
7514 .check_bitstream = mov_check_bitstream,
7515 .priv_class = &mov_isobmff_muxer_class,
7516 };
7517 #endif
7518 #if CONFIG_F4V_MUXER
7519 const AVOutputFormat ff_f4v_muxer = {
7520 .name = "f4v",
7521 .long_name = NULL_IF_CONFIG_SMALL("F4V Adobe Flash Video"),
7522 .mime_type = "application/f4v",
7523 .extensions = "f4v",
7524 .priv_data_size = sizeof(MOVMuxContext),
7525 .audio_codec = AV_CODEC_ID_AAC,
7526 .video_codec = AV_CODEC_ID_H264,
7527 .init = mov_init,
7528 .write_header = mov_write_header,
7529 .write_packet = mov_write_packet,
7530 .write_trailer = mov_write_trailer,
7531 .deinit = mov_free,
7532 .flags = AVFMT_GLOBALHEADER | AVFMT_ALLOW_FLUSH,
7533 .codec_tag = (const AVCodecTag* const []){ codec_f4v_tags, 0 },
7534 .check_bitstream = mov_check_bitstream,
7535 .priv_class = &mov_isobmff_muxer_class,
7536 };
7537 #endif