FFmpeg
Loading...
Searching...
No Matches
movenc.c
Go to the documentation of this file.
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 "config_components.h"
25
26#include <math.h>
27#include <stdint.h>
28#include <inttypes.h>
29
30#include "movenc.h"
31#include "avformat.h"
32#include "avio_internal.h"
33#include "dovi_isom.h"
34#include "riff.h"
35#include "avio.h"
36#include "iamf_writer.h"
37#include "isom.h"
38#include "av1.h"
39#include "avc.h"
40#include "evc.h"
41#include "apv.h"
42#include "lcevc.h"
45#include "libavcodec/flac.h"
47#include "libavcodec/get_bits.h"
48
49#include "libavcodec/internal.h"
50#include "libavcodec/put_bits.h"
52#include "libavcodec/raw.h"
53#include "internal.h"
54#include "libavutil/avstring.h"
56#include "libavutil/csp.h"
57#include "libavutil/intfloat.h"
59#include "libavutil/mem.h"
60#include "libavutil/opt.h"
61#include "libavutil/dict.h"
62#include "libavutil/pixdesc.h"
63#include "libavutil/stereo3d.h"
64#include "libavutil/timecode.h"
65#include "libavutil/dovi_meta.h"
66#include "libavutil/uuid.h"
67#include "hevc.h"
68#include "rtpenc.h"
69#include "nal.h"
70#include "mov_chan.h"
71#include "movenc_ttml.h"
72#include "mux.h"
73#include "rawutils.h"
74#include "ttmlenc.h"
75#include "version.h"
76#include "vpcc.h"
77#include "vvc.h"
78
79static const AVOption options[] = {
80 { "brand", "Override major brand", offsetof(MOVMuxContext, major_brand), AV_OPT_TYPE_STRING, {.str = NULL}, .flags = AV_OPT_FLAG_ENCODING_PARAM },
81 { "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},
82 { "encryption_key", "The media encryption key (hex)", offsetof(MOVMuxContext, encryption_key), AV_OPT_TYPE_BINARY, .flags = AV_OPT_FLAG_ENCODING_PARAM },
83 { "encryption_kid", "The media encryption key identifier (hex)", offsetof(MOVMuxContext, encryption_kid), AV_OPT_TYPE_BINARY, .flags = AV_OPT_FLAG_ENCODING_PARAM },
84 { "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 },
85 { "frag_duration", "Maximum fragment duration", offsetof(MOVMuxContext, max_fragment_duration), AV_OPT_TYPE_INT, {.i64 = 0}, 0, INT_MAX, AV_OPT_FLAG_ENCODING_PARAM},
86 { "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 },
87 { "frag_size", "Maximum fragment size", offsetof(MOVMuxContext, max_fragment_size), AV_OPT_TYPE_INT, {.i64 = 0}, 0, INT_MAX, AV_OPT_FLAG_ENCODING_PARAM},
88 { "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},
89 { "iods_audio_profile", "iods audio profile atom.", offsetof(MOVMuxContext, iods_audio_profile), AV_OPT_TYPE_INT, {.i64 = -1}, -1, 255, AV_OPT_FLAG_ENCODING_PARAM},
90 { "iods_video_profile", "iods video profile atom.", offsetof(MOVMuxContext, iods_video_profile), AV_OPT_TYPE_INT, {.i64 = -1}, -1, 255, AV_OPT_FLAG_ENCODING_PARAM},
91 { "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},
92 { "movflags", "MOV muxer flags", offsetof(MOVMuxContext, flags), AV_OPT_TYPE_FLAGS, {.i64 = 0}, INT_MIN, INT_MAX, AV_OPT_FLAG_ENCODING_PARAM, .unit = "movflags" },
93 { "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, .unit = "movflags" },
94 { "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, .unit = "movflags" },
95 { "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, .unit = "movflags" },
96 { "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, .unit = "movflags" },
97 { "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, .unit = "movflags" },
98 { "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, .unit = "movflags" },
99 { "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, .unit = "movflags" },
100 { "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, .unit = "movflags" },
101 { "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, .unit = "movflags" },
102 { "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, .unit = "movflags" },
103 { "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, .unit = "movflags" },
104 { "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, .unit = "movflags" },
105 { "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, .unit = "movflags" },
106 { "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, .unit = 0 },
107 { "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, .unit = "movflags" },
108 { "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, .unit = "movflags" },
109 { "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, .unit = "movflags" },
110 { "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, .unit = "movflags" },
111 { "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, .unit = "movflags" },
112 { "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, .unit = "movflags" },
113 { "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, .unit = "movflags" },
114 { "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, .unit = "movflags" },
115 { "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, .unit = "movflags" },
116 { "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, .unit = "movflags" },
117 { "hybrid_fragmented", "For recoverability, write a fragmented file that is converted to non-fragmented at the end.", 0, AV_OPT_TYPE_CONST, {.i64 = FF_MOV_FLAG_HYBRID_FRAGMENTED}, INT_MIN, INT_MAX, AV_OPT_FLAG_ENCODING_PARAM, .unit = "movflags" },
118 { "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},
119 { "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},
120 { "movie_timescale", "set movie timescale", offsetof(MOVMuxContext, movie_timescale), AV_OPT_TYPE_INT, {.i64 = 0}, 0, INT_MAX, AV_OPT_FLAG_ENCODING_PARAM},
122 { "skip_iods", "Skip writing iods atom.", offsetof(MOVMuxContext, iods_skip), AV_OPT_TYPE_BOOL, {.i64 = 1}, 0, 1, AV_OPT_FLAG_ENCODING_PARAM},
123 { "use_editlist", "use edit list", offsetof(MOVMuxContext, use_editlist), AV_OPT_TYPE_BOOL, {.i64 = -1}, -1, 1, AV_OPT_FLAG_ENCODING_PARAM},
124 { "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},
125 { "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},
126 { "write_btrt", "force or disable writing btrt", offsetof(MOVMuxContext, write_btrt), AV_OPT_TYPE_BOOL, {.i64 = -1}, -1, 1, AV_OPT_FLAG_ENCODING_PARAM},
127 { "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, .unit = "prft"},
128 { "pts", NULL, 0, AV_OPT_TYPE_CONST, {.i64 = MOV_PRFT_SRC_PTS}, 0, 0, AV_OPT_FLAG_ENCODING_PARAM, .unit = "prft"},
129 { "wallclock", NULL, 0, AV_OPT_TYPE_CONST, {.i64 = MOV_PRFT_SRC_WALLCLOCK}, 0, 0, AV_OPT_FLAG_ENCODING_PARAM, .unit = "prft"},
130 { "write_tmcd", "force or disable writing tmcd", offsetof(MOVMuxContext, write_tmcd), AV_OPT_TYPE_BOOL, {.i64 = -1}, -1, 1, AV_OPT_FLAG_ENCODING_PARAM},
131 { NULL },
132};
133
135 .class_name = "mov/mp4/tgp/psp/tg2/ipod/ismv/f4v muxer",
136 .item_name = av_default_item_name,
137 .option = options,
138 .version = LIBAVUTIL_VERSION_INT,
139};
140
141static int get_moov_size(AVFormatContext *s);
143
144static int utf8len(const uint8_t *b)
145{
146 int len = 0;
147 int val;
148 while (*b) {
149 GET_UTF8(val, *b++, return -1;)
150 len++;
151 }
152 return len;
153}
154
155//FIXME support 64 bit variant with wide placeholders
157{
158 int64_t curpos = avio_tell(pb);
159 avio_seek(pb, pos, SEEK_SET);
160 avio_wb32(pb, curpos - pos); /* rewrite size */
161 avio_seek(pb, curpos, SEEK_SET);
162
163 return curpos - pos;
164}
165
167{
168 int64_t curpos = avio_tell(pb);
169 avio_seek(pb, pos, SEEK_SET);
170 avio_wb32(pb, curpos - pos); /* rewrite size */
171 avio_skip(pb, 4);
172 avio_w8(pb, version); /* rewrite version */
173 avio_seek(pb, curpos, SEEK_SET);
174
175 return curpos - pos;
176}
177
178static int co64_required(const MOVTrack *track)
179{
180 if (track->entry > 0 && track->cluster[track->entry - 1].pos + track->data_offset > UINT32_MAX)
181 return 1;
182 return 0;
183}
184
185static int is_cover_image(const AVStream *st)
186{
187 /* Eg. AV_DISPOSITION_ATTACHED_PIC | AV_DISPOSITION_TIMED_THUMBNAILS
188 * is encoded as sparse video track */
189 return st && st->disposition == AV_DISPOSITION_ATTACHED_PIC;
190}
191
192static int rtp_hinting_needed(const AVStream *st)
193{
194 /* Add hint tracks for each real audio and video stream */
195 if (is_cover_image(st))
196 return 0;
197 return st->codecpar->codec_type == AVMEDIA_TYPE_VIDEO ||
199}
200
201/* Chunk offset atom */
203{
204 int i;
205 int mode64 = co64_required(track); // use 32 bit size variant if possible
206 int64_t pos = avio_tell(pb);
207 avio_wb32(pb, 0); /* size */
208 if (mode64)
209 ffio_wfourcc(pb, "co64");
210 else
211 ffio_wfourcc(pb, "stco");
212 avio_wb32(pb, 0); /* version & flags */
213 avio_wb32(pb, track->chunkCount); /* entry count */
214 for (i = 0; i < track->entry; i++) {
215 if (!track->cluster[i].chunkNum)
216 continue;
217 if (mode64 == 1)
218 avio_wb64(pb, track->cluster[i].pos + track->data_offset);
219 else
220 avio_wb32(pb, track->cluster[i].pos + track->data_offset);
221 }
222 return update_size(pb, pos);
223}
224
225/* Sample size atom */
227{
228 int equalChunks = 1;
229 int i, j, entries = 0, tst = -1, oldtst = -1;
230
231 int64_t pos = avio_tell(pb);
232 avio_wb32(pb, 0); /* size */
233 ffio_wfourcc(pb, "stsz");
234 avio_wb32(pb, 0); /* version & flags */
235
236 for (i = 0; i < track->entry; i++) {
237 tst = track->cluster[i].size / track->cluster[i].entries;
238 if (oldtst != -1 && tst != oldtst)
239 equalChunks = 0;
240 oldtst = tst;
241 entries += track->cluster[i].entries;
242 }
243 if (equalChunks && track->entry) {
244 int sSize = track->entry ? track->cluster[0].size / track->cluster[0].entries : 0;
245 sSize = FFMAX(1, sSize); // adpcm mono case could make sSize == 0
246 avio_wb32(pb, sSize); // sample size
247 avio_wb32(pb, entries); // sample count
248 } else {
249 avio_wb32(pb, 0); // sample size
250 avio_wb32(pb, entries); // sample count
251 for (i = 0; i < track->entry; i++) {
252 for (j = 0; j < track->cluster[i].entries; j++) {
253 avio_wb32(pb, track->cluster[i].size /
254 track->cluster[i].entries);
255 }
256 }
257 }
258 return update_size(pb, pos);
259}
260
261/* Sample to chunk atom */
263{
264 int index = 0, oldidx = -1, oldval = -1, i;
265 int64_t entryPos, curpos;
266
267 int64_t pos = avio_tell(pb);
268 avio_wb32(pb, 0); /* size */
269 ffio_wfourcc(pb, "stsc");
270 avio_wb32(pb, 0); // version & flags
271 entryPos = avio_tell(pb);
272 avio_wb32(pb, track->chunkCount); // entry count
273 for (i = 0; i < track->entry; i++) {
274 if ((oldval != track->cluster[i].samples_in_chunk ||
275 oldidx != track->cluster[i].stsd_index) && track->cluster[i].chunkNum) {
276 avio_wb32(pb, track->cluster[i].chunkNum); // first chunk
277 avio_wb32(pb, track->cluster[i].samples_in_chunk); // samples per chunk
278 avio_wb32(pb, track->cluster[i].stsd_index + 1); // sample description index
279 oldval = track->cluster[i].samples_in_chunk;
280 oldidx = track->cluster[i].stsd_index;
281 index++;
282 }
283 }
284 curpos = avio_tell(pb);
285 avio_seek(pb, entryPos, SEEK_SET);
286 avio_wb32(pb, index); // rewrite size
287 avio_seek(pb, curpos, SEEK_SET);
288
289 return update_size(pb, pos);
290}
291
292/* Sync sample atom */
293static int mov_write_stss_tag(AVIOContext *pb, MOVTrack *track, uint32_t flag)
294{
295 int64_t curpos, entryPos;
296 int i, index = 0;
297 int64_t pos = avio_tell(pb);
298 avio_wb32(pb, 0); // size
299 ffio_wfourcc(pb, flag == MOV_SYNC_SAMPLE ? "stss" : "stps");
300 avio_wb32(pb, 0); // version & flags
301 entryPos = avio_tell(pb);
302 avio_wb32(pb, track->entry); // entry count
303 for (i = 0; i < track->entry; i++) {
304 if (track->cluster[i].flags & flag) {
305 avio_wb32(pb, i + 1);
306 index++;
307 }
308 }
309 curpos = avio_tell(pb);
310 avio_seek(pb, entryPos, SEEK_SET);
311 avio_wb32(pb, index); // rewrite size
312 avio_seek(pb, curpos, SEEK_SET);
313 return update_size(pb, pos);
314}
315
316/* Sample dependency atom */
318{
319 int i;
320 uint8_t leading, dependent, reference, redundancy;
321 int64_t pos = avio_tell(pb);
322 avio_wb32(pb, 0); // size
323 ffio_wfourcc(pb, "sdtp");
324 avio_wb32(pb, 0); // version & flags
325 for (i = 0; i < track->entry; i++) {
326 dependent = MOV_SAMPLE_DEPENDENCY_YES;
327 leading = reference = redundancy = MOV_SAMPLE_DEPENDENCY_UNKNOWN;
328 if (track->cluster[i].flags & MOV_DISPOSABLE_SAMPLE) {
329 reference = MOV_SAMPLE_DEPENDENCY_NO;
330 }
331 if (track->cluster[i].flags & MOV_SYNC_SAMPLE) {
332 dependent = MOV_SAMPLE_DEPENDENCY_NO;
333 }
334 avio_w8(pb, (leading << 6) | (dependent << 4) |
335 (reference << 2) | redundancy);
336 }
337 return update_size(pb, pos);
338}
339
340#if CONFIG_IAMFENC
341static int mov_write_iacb_tag(AVFormatContext *s, AVIOContext *pb, MOVTrack *track)
342{
343 AVIOContext *dyn_bc;
344 int64_t pos = avio_tell(pb);
345 uint8_t *dyn_buf = NULL;
346 int dyn_size;
347 int ret = avio_open_dyn_buf(&dyn_bc);
348 if (ret < 0)
349 return ret;
350
351 avio_wb32(pb, 0);
352 ffio_wfourcc(pb, "iacb");
353 avio_w8(pb, 1); // configurationVersion
354
355 ret = ff_iamf_write_descriptors(track->iamf, dyn_bc, s);
356 if (ret < 0) {
357 ffio_free_dyn_buf(&dyn_bc);
358 return ret;
359 }
360
361 dyn_size = avio_close_dyn_buf(dyn_bc, &dyn_buf);
362 ffio_write_leb(pb, dyn_size);
363 avio_write(pb, dyn_buf, dyn_size);
364 av_free(dyn_buf);
365
366 return update_size(pb, pos);
367}
368#endif
369
371{
372 avio_wb32(pb, 0x11); /* size */
373 if (track->mode == MODE_MOV) ffio_wfourcc(pb, "samr");
374 else ffio_wfourcc(pb, "damr");
375 ffio_wfourcc(pb, "FFMP");
376 avio_w8(pb, 0); /* decoder version */
377
378 avio_wb16(pb, 0x81FF); /* Mode set (all modes for AMR_NB) */
379 avio_w8(pb, 0x00); /* Mode change period (no restriction) */
380 avio_w8(pb, 0x01); /* Frames per sample */
381 return 0x11;
382}
383
384struct eac3_info {
386 uint8_t eof;
387 uint8_t ec3_done;
388 uint8_t num_blocks;
389
390 /* Layout of the EC3SpecificBox */
391 /* maximum bitrate */
392 uint16_t data_rate;
394 /* number of independent substreams */
395 uint8_t num_ind_sub;
396 struct {
397 /* sample rate code (see ff_ac3_sample_rate_tab) 2 bits */
398 uint8_t fscod;
399 /* bit stream identification 5 bits */
400 uint8_t bsid;
401 /* one bit reserved */
402 /* audio service mixing (not supported yet) 1 bit */
403 /* bit stream mode 3 bits */
404 uint8_t bsmod;
405 /* audio coding mode 3 bits */
406 uint8_t acmod;
407 /* sub woofer on 1 bit */
408 uint8_t lfeon;
409 /* 3 bits reserved */
410 /* number of dependent substreams associated with this substream 4 bits */
411 uint8_t num_dep_sub;
412 /* channel locations of the dependent substream(s), if any, 9 bits */
413 uint16_t chan_loc;
414 /* if there is no dependent substream, then one bit reserved instead */
415 } substream[1]; /* TODO: support 8 independent substreams */
416 /* indicates the decoding complexity, 8 bits */
418};
419
421{
422 struct eac3_info *info = track->eac3_priv;
423 PutBitContext pbc;
424 uint8_t buf[3];
425
426 if (!info || !info->ec3_done) {
428 "Cannot write moov atom before AC3 packets."
429 " Set the delay_moov flag to fix this.\n");
430 return AVERROR(EINVAL);
431 }
432
433 if (info->substream[0].bsid > 8) {
435 "RealAudio AC-3/DolbyNet with bsid %d is not defined by the "
436 "ISOBMFF specification in ETSI TS 102 366!\n",
437 info->substream[0].bsid);
438 return AVERROR(EINVAL);
439 }
440
441 if (info->ac3_bit_rate_code < 0) {
443 "No valid AC3 bit rate code for data rate of %d!\n",
444 info->data_rate);
445 return AVERROR(EINVAL);
446 }
447
448 avio_wb32(pb, 11);
449 ffio_wfourcc(pb, "dac3");
450
451 init_put_bits(&pbc, buf, sizeof(buf));
452 put_bits(&pbc, 2, info->substream[0].fscod);
453 put_bits(&pbc, 5, info->substream[0].bsid);
454 put_bits(&pbc, 3, info->substream[0].bsmod);
455 put_bits(&pbc, 3, info->substream[0].acmod);
456 put_bits(&pbc, 1, info->substream[0].lfeon);
457 put_bits(&pbc, 5, info->ac3_bit_rate_code); // bit_rate_code
458 put_bits(&pbc, 5, 0); // reserved
459
460 flush_put_bits(&pbc);
461 avio_write(pb, buf, sizeof(buf));
462
463 return 11;
464}
465
467{
468 AC3HeaderInfo *hdr = NULL;
469 struct eac3_info *info;
470 int num_blocks, ret;
471
472 if (!track->eac3_priv) {
473 if (!(track->eac3_priv = av_mallocz(sizeof(*info))))
474 return AVERROR(ENOMEM);
475
476 ((struct eac3_info *)track->eac3_priv)->ac3_bit_rate_code = -1;
477 }
478 info = track->eac3_priv;
479
480 if (!info->pkt && !(info->pkt = av_packet_alloc()))
481 return AVERROR(ENOMEM);
482
483 if (info->eof) {
484 av_assert1(!info->pkt->size);
485 ret = pkt->size;
486 goto end;
487 }
488
489 if ((ret = avpriv_ac3_parse_header(&hdr, pkt->data, pkt->size)) < 0) {
490 if (ret == AVERROR(ENOMEM))
491 goto end;
492
493 /* drop the packets until we see a good one */
494 if (!track->entry) {
495 av_log(mov->fc, AV_LOG_WARNING, "Dropping invalid packet from start of the stream\n");
496 ret = 0;
497 } else
499 goto end;
500 }
501
502 info->data_rate = FFMAX(info->data_rate, hdr->bit_rate / 1000);
504 hdr->ac3_bit_rate_code);
506
507 num_blocks = hdr->num_blocks;
508
509 if (!info->ec3_done) {
510 /* AC-3 substream must be the first one */
511 if (hdr->bitstream_id <= 10 && hdr->substreamid != 0) {
512 ret = AVERROR(EINVAL);
513 goto end;
514 }
515
516 /* this should always be the case, given that our AC-3 parser
517 * concatenates dependent frames to their independent parent */
520 /* substream ids must be incremental */
521 if (hdr->substreamid > info->num_ind_sub + 1) {
522 ret = AVERROR(EINVAL);
523 goto end;
524 }
525
526 if (hdr->substreamid == info->num_ind_sub + 1) {
527 //info->num_ind_sub++;
528 avpriv_request_sample(mov->fc, "Multiple independent substreams");
530 goto end;
531 } else if (hdr->substreamid < info->num_ind_sub ||
532 hdr->substreamid == 0 && info->substream[0].bsid) {
533 info->ec3_done = 1;
534 goto concatenate;
535 }
536 } else {
537 if (hdr->substreamid != 0) {
538 avpriv_request_sample(mov->fc, "Multiple non EAC3 independent substreams");
540 goto end;
541 }
542 }
543
544 /* fill the info needed for the "dec3" atom */
545 info->substream[hdr->substreamid].fscod = hdr->sr_code;
546 info->substream[hdr->substreamid].bsid = hdr->bitstream_id;
547 info->substream[hdr->substreamid].bsmod = hdr->bitstream_mode;
548 info->substream[hdr->substreamid].acmod = hdr->channel_mode;
549 info->substream[hdr->substreamid].lfeon = hdr->lfe_on;
550
551 if (track->par->codec_id == AV_CODEC_ID_AC3) {
552 // with AC-3 we only require the information of a single packet,
553 // so we can finish as soon as the basic values of the bit stream
554 // have been set to the track's informational structure.
555 info->ec3_done = 1;
556 goto concatenate;
557 }
558
559 /* Parse dependent substream(s), if any */
560 if (pkt->size != hdr->frame_size) {
561 int cumul_size = hdr->frame_size;
562 int parent = hdr->substreamid;
563
564 while (cumul_size != pkt->size) {
565 ret = avpriv_ac3_parse_header(&hdr, pkt->data + cumul_size, pkt->size - cumul_size);
566 if (ret < 0)
567 goto end;
569 ret = AVERROR(EINVAL);
570 goto end;
571 }
572 info->substream[parent].num_dep_sub++;
573 ret /= 8;
574
575 /* get the dependent stream channel map, if exists */
576 if (hdr->channel_map_present) {
577 /* chanmap is a 16-bit field read MSB-first, so flag index
578 * i sits at bit (15 - i), matching the indexing of
579 * ff_eac3_custom_channel_map_locations. chan_loc bits 0-7
580 * carry flag indices 5-12, i.e. chanmap bit (10 - j).
581 * The mapping is not contiguous at the top: index 13
582 * (Lts/Rts) has no chan_loc bit and is skipped, and
583 * chan_loc bit 8 carries LFE2, which is index 14 and so
584 * chanmap bit 1. */
585 for (int j = 0; j < 8; j++) {
586 if ((hdr->channel_map >> (10 - j)) & 1)
587 info->substream[parent].chan_loc |= 1 << j;
588 }
589 if ((hdr->channel_map >> 1) & 1)
590 info->substream[parent].chan_loc |= 1 << 8;
591 } else {
592 info->substream[parent].chan_loc |= hdr->channel_mode;
593 }
594 cumul_size += hdr->frame_size;
595 }
596 }
597 }
598
599concatenate:
600 if (!info->num_blocks && num_blocks == 6) {
601 ret = pkt->size;
602 goto end;
603 }
604 else if (info->num_blocks + num_blocks > 6) {
606 goto end;
607 }
608
609 if (!info->num_blocks) {
610 ret = av_packet_ref(info->pkt, pkt);
611 if (!ret)
612 info->num_blocks = num_blocks;
613 goto end;
614 } else {
615 const AVPacketSideData *sd;
616 int64_t duration = pkt->duration;
617 if ((ret = av_grow_packet(info->pkt, pkt->size)) < 0)
618 goto end;
619 sd = av_packet_side_data_get(pkt->side_data, pkt->side_data_elems, AV_PKT_DATA_SKIP_SAMPLES);
620 if (sd && sd->size >= 10) {
621 uint8_t *buf = av_packet_new_side_data(info->pkt, AV_PKT_DATA_SKIP_SAMPLES, sd->size);
622 if (buf)
623 memcpy(buf, sd->data, sd->size);
624 if (track->par->frame_size)
625 duration = FFMAX(av_rescale_q(track->par->frame_size, (AVRational){ 1, track->par->sample_rate },
626 track->st->time_base), duration);
627 }
628 memcpy(info->pkt->data + info->pkt->size - pkt->size, pkt->data, pkt->size);
629 info->num_blocks += num_blocks;
630 info->pkt->duration += duration;
631 if (info->num_blocks != 6)
632 goto end;
634 av_packet_move_ref(pkt, info->pkt);
635 info->num_blocks = 0;
636 }
637 ret = pkt->size;
638
639end:
640 av_free(hdr);
641
642 return ret;
643}
644
646{
647 PutBitContext pbc;
648 uint8_t *buf;
649 struct eac3_info *info;
650 int size, i;
651
652 if (!track->eac3_priv) {
654 "Cannot write moov atom before EAC3 packets parsed.\n");
655 return AVERROR(EINVAL);
656 }
657
658 info = track->eac3_priv;
659 size = 2 + (4 * (info->num_ind_sub + 1)) + (2 * !!info->complexity_index_type_a);
660 buf = av_malloc(size);
661 if (!buf) {
662 return AVERROR(ENOMEM);
663 }
664
665 init_put_bits(&pbc, buf, size);
666 put_bits(&pbc, 13, info->data_rate);
667 put_bits(&pbc, 3, info->num_ind_sub);
668 for (i = 0; i <= info->num_ind_sub; i++) {
669 put_bits(&pbc, 2, info->substream[i].fscod);
670 put_bits(&pbc, 5, info->substream[i].bsid);
671 put_bits(&pbc, 1, 0); /* reserved */
672 put_bits(&pbc, 1, 0); /* asvc */
673 put_bits(&pbc, 3, info->substream[i].bsmod);
674 put_bits(&pbc, 3, info->substream[i].acmod);
675 put_bits(&pbc, 1, info->substream[i].lfeon);
676 put_bits(&pbc, 3, 0); /* reserved */
677 put_bits(&pbc, 4, info->substream[i].num_dep_sub);
678 if (!info->substream[i].num_dep_sub) {
679 put_bits(&pbc, 1, 0); /* reserved */
680 } else {
681 put_bits(&pbc, 9, info->substream[i].chan_loc);
682 }
683 }
684 if (info->complexity_index_type_a) {
685 put_bits(&pbc, 7, 0); /* reserved */
686 put_bits(&pbc, 1, 1); // flag_eac3_extension_type_a
687 put_bits(&pbc, 8, info->complexity_index_type_a);
688 }
689 flush_put_bits(&pbc);
690 size = put_bytes_output(&pbc);
691
692 avio_wb32(pb, size + 8);
693 ffio_wfourcc(pb, "dec3");
694 avio_write(pb, buf, size);
695
696 av_free(buf);
697
698 return size;
699}
700
701/**
702 * This function writes extradata "as is".
703 * Extradata must be formatted like a valid atom (with size and tag).
704 */
706{
707 avio_write(pb, track->extradata[track->last_stsd_index], track->extradata_size[track->last_stsd_index]);
708 return track->extradata_size[track->last_stsd_index];
709}
710
712{
713 avio_wb32(pb, 10);
714 ffio_wfourcc(pb, "enda");
715 avio_wb16(pb, 1); /* little endian */
716 return 10;
717}
718
720{
721 avio_wb32(pb, 10);
722 ffio_wfourcc(pb, "enda");
723 avio_wb16(pb, 0); /* big endian */
724 return 10;
725}
726
727static void put_descr(AVIOContext *pb, int tag, unsigned int size)
728{
729 int i = 3;
730 avio_w8(pb, tag);
731 for (; i > 0; i--)
732 avio_w8(pb, (size >> (7 * i)) | 0x80);
733 avio_w8(pb, size & 0x7F);
734}
735
736static unsigned compute_avg_bitrate(MOVTrack *track)
737{
738 uint64_t size = 0;
739 int i;
740 if (!track->track_duration)
741 return 0;
742 for (i = 0; i < track->entry; i++)
743 size += track->cluster[i].size;
744 return size * 8 * track->timescale / track->track_duration;
745}
746
748 uint32_t buffer_size; ///< Size of the decoding buffer for the elementary stream in bytes.
749 uint32_t max_bit_rate; ///< Maximum rate in bits/second over any window of one second.
750 uint32_t avg_bit_rate; ///< Average rate in bits/second over the entire presentation.
751};
752
754{
755 const AVPacketSideData *sd = track->st ?
759 AVCPBProperties *props = sd ? (AVCPBProperties *)sd->data : NULL;
760 struct mpeg4_bit_rate_values bit_rates = { 0 };
761
762 bit_rates.avg_bit_rate = compute_avg_bitrate(track);
763 if (!bit_rates.avg_bit_rate) {
764 // if the average bit rate cannot be calculated at this point, such as
765 // in the case of fragmented MP4, utilize the following values as
766 // fall-back in priority order:
767 //
768 // 1. average bit rate property
769 // 2. bit rate (usually average over the whole clip)
770 // 3. maximum bit rate property
771
772 if (props && props->avg_bitrate) {
773 bit_rates.avg_bit_rate = props->avg_bitrate;
774 } else if (track->par->bit_rate) {
775 bit_rates.avg_bit_rate = track->par->bit_rate;
776 } else if (props && props->max_bitrate) {
777 bit_rates.avg_bit_rate = props->max_bitrate;
778 }
779 }
780
781 // (FIXME should be max rate in any 1 sec window)
782 bit_rates.max_bit_rate = FFMAX(track->par->bit_rate,
783 bit_rates.avg_bit_rate);
784
785 // utilize values from properties if we have them available
786 if (props) {
787 // no avg_bitrate signals that the track is VBR
788 if (!props->avg_bitrate)
789 bit_rates.avg_bit_rate = props->avg_bitrate;
790 bit_rates.max_bit_rate = FFMAX(bit_rates.max_bit_rate,
791 props->max_bitrate);
792 bit_rates.buffer_size = props->buffer_size / 8;
793 }
794
795 return bit_rates;
796}
797
798static int mov_write_esds_tag(AVIOContext *pb, MOVTrack *track) // Basic
799{
800 struct mpeg4_bit_rate_values bit_rates = calculate_mpeg4_bit_rates(track);
801 int64_t pos = avio_tell(pb);
802 int decoder_specific_info_len = track->extradata_size[track->last_stsd_index] ?
803 5 + track->extradata_size[track->last_stsd_index] : 0;
804
805 avio_wb32(pb, 0); // size
806 ffio_wfourcc(pb, "esds");
807 avio_wb32(pb, 0); // Version
808
809 // ES descriptor
810 put_descr(pb, 0x03, 3 + 5+13 + decoder_specific_info_len + 5+1);
811 avio_wb16(pb, track->track_id);
812 avio_w8(pb, 0x00); // flags (= no flags)
813
814 // DecoderConfig descriptor
815 put_descr(pb, 0x04, 13 + decoder_specific_info_len);
816
817 // Object type indication
818 if ((track->par->codec_id == AV_CODEC_ID_MP2 ||
819 track->par->codec_id == AV_CODEC_ID_MP3) &&
820 track->par->sample_rate > 24000)
821 avio_w8(pb, 0x6B); // 11172-3
822 else
824
825 // the following fields is made of 6 bits to identify the streamtype (4 for video, 5 for audio)
826 // plus 1 bit to indicate upstream and 1 bit set to 1 (reserved)
828 avio_w8(pb, (0x38 << 2) | 1); // flags (= NeroSubpicStream)
829 else if (track->par->codec_type == AVMEDIA_TYPE_AUDIO)
830 avio_w8(pb, 0x15); // flags (= Audiostream)
831 else
832 avio_w8(pb, 0x11); // flags (= Visualstream)
833
834 avio_wb24(pb, bit_rates.buffer_size); // Buffersize DB
835 avio_wb32(pb, bit_rates.max_bit_rate); // maxbitrate
836 avio_wb32(pb, bit_rates.avg_bit_rate);
837
838 if (track->extradata_size[track->last_stsd_index]) {
839 // DecoderSpecific info descriptor
840 put_descr(pb, 0x05, track->extradata_size[track->last_stsd_index]);
841 avio_write(pb, track->extradata[track->last_stsd_index],
842 track->extradata_size[track->last_stsd_index]);
843 }
844
845 // SL descriptor
846 put_descr(pb, 0x06, 1);
847 avio_w8(pb, 0x02);
848 return update_size(pb, pos);
849}
850
858
866
868{
869 int ret;
870 int64_t pos = avio_tell(pb);
871 avio_wb32(pb, 0);
872 avio_wl32(pb, track->tag); // store it byteswapped
873 track->par->codec_tag = av_bswap16(track->tag >> 16);
874 if ((ret = ff_put_wav_header(s, pb, track->par, 0)) < 0)
875 return ret;
876 return update_size(pb, pos);
877}
878
880{
881 int ret;
882 int64_t pos = avio_tell(pb);
883 avio_wb32(pb, 0);
884 ffio_wfourcc(pb, "wfex");
886 return ret;
887 return update_size(pb, pos);
888}
889
891{
892 int64_t pos = avio_tell(pb);
893 avio_wb32(pb, 0);
894 ffio_wfourcc(pb, "dfLa");
895 avio_w8(pb, 0); /* version */
896 avio_wb24(pb, 0); /* flags */
897
898 /* Expect the encoder to pass a METADATA_BLOCK_TYPE_STREAMINFO. */
900 return AVERROR_INVALIDDATA;
901
902 /* TODO: Write other METADATA_BLOCK_TYPEs if the encoder makes them available. */
903 avio_w8(pb, 1 << 7 | FLAC_METADATA_TYPE_STREAMINFO); /* LastMetadataBlockFlag << 7 | BlockType */
904 avio_wb24(pb, track->extradata_size[track->last_stsd_index]); /* Length */
905 avio_write(pb, track->extradata[track->last_stsd_index], track->extradata_size[track->last_stsd_index]); /* BlockData[Length] */
906
907 return update_size(pb, pos);
908}
909
911{
912 int64_t pos = avio_tell(pb);
914 avio_wb32(pb, 0);
915 ffio_wfourcc(pb, "dOps");
916 avio_w8(pb, 0); /* Version */
917 if (track->extradata_size[track->last_stsd_index] < 19) {
918 av_log(s, AV_LOG_ERROR, "invalid extradata size\n");
919 return AVERROR_INVALIDDATA;
920 }
921 /* extradata contains an Ogg OpusHead, other than byte-ordering and
922 OpusHead's preceding magic/version, OpusSpecificBox is currently
923 identical. */
924 channels = AV_RB8(track->extradata[track->last_stsd_index] + 9);
925 channel_map = AV_RB8(track->extradata[track->last_stsd_index] + 18);
926
927 avio_w8(pb, channels); /* OuputChannelCount */
928 avio_wb16(pb, AV_RL16(track->extradata[track->last_stsd_index] + 10)); /* PreSkip */
929 avio_wb32(pb, AV_RL32(track->extradata[track->last_stsd_index] + 12)); /* InputSampleRate */
930 avio_wb16(pb, AV_RL16(track->extradata[track->last_stsd_index] + 16)); /* OutputGain */
931 avio_w8(pb, channel_map); /* ChannelMappingFamily */
932 /* Write the rest of the header out without byte-swapping. */
933 if (channel_map) {
934 if (track->extradata_size[track->last_stsd_index] < 21 + channels) {
935 av_log(s, AV_LOG_ERROR, "invalid extradata size\n");
936 return AVERROR_INVALIDDATA;
937 }
938 avio_write(pb, track->extradata[track->last_stsd_index] + 19, 2 + channels); /* ChannelMappingTable */
939 }
940
941 return update_size(pb, pos);
942}
943
945{
946 int64_t pos = avio_tell(pb);
947 int length;
948 avio_wb32(pb, 0);
949 ffio_wfourcc(pb, "dmlp");
950
951 if (track->extradata_size[track->last_stsd_index] < 20) {
953 "Cannot write moov atom before TrueHD packets."
954 " Set the delay_moov flag to fix this.\n");
955 return AVERROR(EINVAL);
956 }
957
958 length = (AV_RB16(track->extradata[track->last_stsd_index]) & 0xFFF) * 2;
959 if (length < 20 || length > track->extradata_size[track->last_stsd_index])
960 return AVERROR_INVALIDDATA;
961
962 // Only TrueHD is supported
963 if (AV_RB32(track->extradata[track->last_stsd_index] + 4) != 0xF8726FBA)
964 return AVERROR_INVALIDDATA;
965
966 avio_wb32(pb, AV_RB32(track->extradata[track->last_stsd_index] + 8)); /* format_info */
967 avio_wb16(pb, AV_RB16(track->extradata[track->last_stsd_index] + 18) << 1); /* peak_data_rate */
968 avio_wb32(pb, 0); /* reserved */
969
970 return update_size(pb, pos);
971}
972
974{
975 int64_t pos = avio_tell(pb);
976 int layout = 0;
977
978 if (!track->extradata_size[track->last_stsd_index] ||
979 track->extradata_size[track->last_stsd_index] > UINT16_MAX) {
981 "Invalid extradata size %d for MPEGH-H stream.\n",
982 track->extradata_size[track->last_stsd_index]);
983 return AVERROR(EINVAL);
984 }
985
986 avio_wb32(pb, 0);
987 ffio_wfourcc(pb, "mhaC");
988
989 avio_w8(pb, 1); // ConfigurationVersion
990 avio_w8(pb, track->par->profile * 5 + track->par->level);
991
992 for (size_t i = 0; i < FF_ARRAY_ELEMS(ff_mpa_cicp_channel_layout_masks); i++) {
994 AVChannelLayout ch_layout;
996 if (!av_channel_layout_compare(&track->par->ch_layout, &ch_layout)) {
997 layout = i;
998 break;
999 }
1000 }
1001 }
1002
1003 avio_w8(pb, layout);
1004 avio_wb16(pb, track->extradata_size[track->last_stsd_index]);
1005 avio_write(pb, track->extradata[track->last_stsd_index],
1006 track->extradata_size[track->last_stsd_index]);
1007
1008 return update_size(pb, pos);
1009}
1010
1012{
1013 const AVDictionaryEntry *str = av_dict_get(track->st->metadata, "SA3D", NULL, 0);
1014 AVChannelLayout ch_layout = { 0 };
1015 int64_t pos;
1016 int ambisonic_order, ambi_channels, non_diegetic_channels;
1017 int i, ret;
1018
1019 if (!str)
1020 return 0;
1021
1022 ret = av_channel_layout_from_string(&ch_layout, str->value);
1023 if (ret < 0) {
1024 if (ret == AVERROR(EINVAL)) {
1025invalid:
1026 av_log(s, AV_LOG_ERROR, "Invalid SA3D layout: \"%s\"\n", str->value);
1027 ret = 0;
1028 }
1029 av_channel_layout_uninit(&ch_layout);
1030 return ret;
1031 }
1032
1033 if (track->st->codecpar->ch_layout.nb_channels != ch_layout.nb_channels)
1034 goto invalid;
1035
1036 ambisonic_order = av_channel_layout_ambisonic_order(&ch_layout);
1037 if (ambisonic_order < 0)
1038 goto invalid;
1039
1040 ambi_channels = (ambisonic_order + 1LL) * (ambisonic_order + 1LL);
1041 non_diegetic_channels = ch_layout.nb_channels - ambi_channels;
1042 if (non_diegetic_channels &&
1043 (non_diegetic_channels != 2 ||
1045 goto invalid;
1046
1047 av_log(s, AV_LOG_VERBOSE, "Inserting SA3D box with layout: \"%s\"\n", str->value);
1048
1049 pos = avio_tell(pb);
1050
1051 avio_wb32(pb, 0); // Size
1052 ffio_wfourcc(pb, "SA3D");
1053 avio_w8(pb, 0); // version
1054 avio_w8(pb, (!!non_diegetic_channels) << 7); // head_locked_stereo and ambisonic_type
1055 avio_wb32(pb, ambisonic_order); // ambisonic_order
1056 avio_w8(pb, 0); // ambisonic_channel_ordering
1057 avio_w8(pb, 0); // ambisonic_normalization
1058 avio_wb32(pb, ch_layout.nb_channels); // num_channels
1059 for (i = 0; i < ambi_channels; i++)
1061 for (; i < ch_layout.nb_channels; i++)
1062 avio_wb32(pb, av_channel_layout_channel_from_index(&ch_layout, i) + ambi_channels);
1063
1064 av_channel_layout_uninit(&ch_layout);
1065
1066 return update_size(pb, pos);
1067}
1068
1070{
1071 uint32_t layout_tag, bitmap, *channel_desc;
1072 int64_t pos = avio_tell(pb);
1073 int num_desc, ret;
1074
1075 if (track->multichannel_as_mono)
1076 return 0;
1077
1078 ret = ff_mov_get_channel_layout_tag(track->par, &layout_tag,
1079 &bitmap, &channel_desc);
1080
1081 if (ret < 0) {
1082 if (ret == AVERROR(ENOSYS)) {
1083 av_log(s, AV_LOG_WARNING, "not writing 'chan' tag due to "
1084 "lack of channel information\n");
1085 ret = 0;
1086 }
1087
1088 return ret;
1089 }
1090
1091 /* no predefined tag found + ch_layout in AV_CHANNEL_ORDER_NATIVE
1092 * but bitstream channels not actually in native order */
1093 if (layout_tag == MOV_CH_LAYOUT_UNKNOWN)
1094 return 0;
1095
1096 if (layout_tag == MOV_CH_LAYOUT_MONO && track->mono_as_fc > 0) {
1097 av_assert0(!channel_desc);
1098 channel_desc = av_malloc(sizeof(*channel_desc));
1099 if (!channel_desc)
1100 return AVERROR(ENOMEM);
1101
1102 layout_tag = 0;
1103 bitmap = 0;
1104 *channel_desc = 3; // channel label "Center"
1105 }
1106
1107 num_desc = layout_tag ? 0 : track->par->ch_layout.nb_channels;
1108
1109 avio_wb32(pb, 0); // Size
1110 ffio_wfourcc(pb, "chan"); // Type
1111 avio_w8(pb, 0); // Version
1112 avio_wb24(pb, 0); // Flags
1113 avio_wb32(pb, layout_tag); // mChannelLayoutTag
1114 avio_wb32(pb, bitmap); // mChannelBitmap
1115 avio_wb32(pb, num_desc); // mNumberChannelDescriptions
1116
1117 for (int i = 0; i < num_desc; i++) {
1118 avio_wb32(pb, channel_desc[i]); // mChannelLabel
1119 avio_wb32(pb, 0); // mChannelFlags
1120 avio_wl32(pb, 0); // mCoordinates[0]
1121 avio_wl32(pb, 0); // mCoordinates[1]
1122 avio_wl32(pb, 0); // mCoordinates[2]
1123 }
1124
1125 av_free(channel_desc);
1126
1127 return update_size(pb, pos);
1128}
1129
1131{
1132 int64_t pos = avio_tell(pb);
1133
1134 avio_wb32(pb, 0); /* size */
1135 ffio_wfourcc(pb, "wave");
1136
1137 if (track->par->codec_id != AV_CODEC_ID_QDM2) {
1138 avio_wb32(pb, 12); /* size */
1139 ffio_wfourcc(pb, "frma");
1140 avio_wl32(pb, track->tag);
1141 }
1142
1143 if (track->par->codec_id == AV_CODEC_ID_AAC) {
1144 /* useless atom needed by mplayer, ipod, not needed by quicktime */
1145 avio_wb32(pb, 12); /* size */
1146 ffio_wfourcc(pb, "mp4a");
1147 avio_wb32(pb, 0);
1148 mov_write_esds_tag(pb, track);
1149 } else if (mov_pcm_le_gt16(track->par->codec_id)) {
1151 } else if (mov_pcm_be_gt16(track->par->codec_id)) {
1153 } else if (track->par->codec_id == AV_CODEC_ID_AMR_NB) {
1154 mov_write_amr_tag(pb, track);
1155 } else if (track->par->codec_id == AV_CODEC_ID_AC3) {
1156 mov_write_ac3_tag(s, pb, track);
1157 } else if (track->par->codec_id == AV_CODEC_ID_EAC3) {
1158 mov_write_eac3_tag(s, pb, track);
1159 } else if (track->par->codec_id == AV_CODEC_ID_ALAC ||
1160 track->par->codec_id == AV_CODEC_ID_QDM2) {
1161 mov_write_extradata_tag(pb, track);
1162 } else if (track->par->codec_id == AV_CODEC_ID_ADPCM_MS ||
1164 mov_write_ms_tag(s, pb, track);
1165 }
1166
1167 avio_wb32(pb, 8); /* size */
1168 avio_wb32(pb, 0); /* null tag */
1169
1170 return update_size(pb, pos);
1171}
1172
1173static int mov_write_dvc1_structs(MOVTrack *track, uint8_t *buf)
1174{
1175 uint8_t *unescaped;
1176 const uint8_t *start, *next, *end = track->extradata[track->last_stsd_index] +
1177 track->extradata_size[track->last_stsd_index];
1178 int unescaped_size, seq_found = 0;
1179 int level = 0, interlace = 0;
1180 int packet_seq = track->vc1_info.packet_seq;
1181 int packet_entry = track->vc1_info.packet_entry;
1182 int slices = track->vc1_info.slices;
1183 PutBitContext pbc;
1184
1185 if (track->start_dts == AV_NOPTS_VALUE) {
1186 /* No packets written yet, vc1_info isn't authoritative yet. */
1187 /* Assume inline sequence and entry headers. */
1188 packet_seq = packet_entry = 1;
1190 "moov atom written before any packets, unable to write correct "
1191 "dvc1 atom. Set the delay_moov flag to fix this.\n");
1192 }
1193
1195 if (!unescaped)
1196 return AVERROR(ENOMEM);
1197 start = find_next_marker(track->extradata[track->last_stsd_index], end);
1198 for (next = start; next < end; start = next) {
1199 GetBitContext gb;
1200 int size;
1201 next = find_next_marker(start + 4, end);
1202 size = next - start - 4;
1203 if (size <= 0)
1204 continue;
1205 unescaped_size = vc1_unescape_buffer(start + 4, size, unescaped);
1206 init_get_bits(&gb, unescaped, 8 * unescaped_size);
1207 if (AV_RB32(start) == VC1_CODE_SEQHDR) {
1208 int profile = get_bits(&gb, 2);
1209 if (profile != PROFILE_ADVANCED) {
1210 av_free(unescaped);
1211 return AVERROR(ENOSYS);
1212 }
1213 seq_found = 1;
1214 level = get_bits(&gb, 3);
1215 /* chromaformat, frmrtq_postproc, bitrtq_postproc, postprocflag,
1216 * width, height */
1217 skip_bits_long(&gb, 2 + 3 + 5 + 1 + 2*12);
1218 skip_bits(&gb, 1); /* broadcast */
1219 interlace = get_bits1(&gb);
1220 skip_bits(&gb, 4); /* tfcntrflag, finterpflag, reserved, psf */
1221 }
1222 }
1223 if (!seq_found) {
1224 av_free(unescaped);
1225 return AVERROR(ENOSYS);
1226 }
1227
1228 init_put_bits(&pbc, buf, 7);
1229 /* VC1DecSpecStruc */
1230 put_bits(&pbc, 4, 12); /* profile - advanced */
1231 put_bits(&pbc, 3, level);
1232 put_bits(&pbc, 1, 0); /* reserved */
1233 /* VC1AdvDecSpecStruc */
1234 put_bits(&pbc, 3, level);
1235 put_bits(&pbc, 1, 0); /* cbr */
1236 put_bits(&pbc, 6, 0); /* reserved */
1237 put_bits(&pbc, 1, !interlace); /* no interlace */
1238 put_bits(&pbc, 1, !packet_seq); /* no multiple seq */
1239 put_bits(&pbc, 1, !packet_entry); /* no multiple entry */
1240 put_bits(&pbc, 1, !slices); /* no slice code */
1241 put_bits(&pbc, 1, 0); /* no bframe */
1242 put_bits(&pbc, 1, 0); /* reserved */
1243
1244 /* framerate */
1245 if (track->st->avg_frame_rate.num > 0 && track->st->avg_frame_rate.den > 0)
1246 put_bits32(&pbc, track->st->avg_frame_rate.num / track->st->avg_frame_rate.den);
1247 else
1248 put_bits32(&pbc, 0xffffffff);
1249
1250 flush_put_bits(&pbc);
1251
1252 av_free(unescaped);
1253
1254 return 0;
1255}
1256
1258{
1259 uint8_t buf[7] = { 0 };
1260 int ret;
1261
1262 if ((ret = mov_write_dvc1_structs(track, buf)) < 0)
1263 return ret;
1264
1265 avio_wb32(pb, track->extradata_size[track->last_stsd_index] + 8 + sizeof(buf));
1266 ffio_wfourcc(pb, "dvc1");
1267 avio_write(pb, buf, sizeof(buf));
1268 avio_write(pb, track->extradata[track->last_stsd_index],
1269 track->extradata_size[track->last_stsd_index]);
1270
1271 return 0;
1272}
1273
1275{
1276 avio_wb32(pb, track->extradata_size[track->last_stsd_index] + 8);
1277 ffio_wfourcc(pb, "glbl");
1278 avio_write(pb, track->extradata[track->last_stsd_index],
1279 track->extradata_size[track->last_stsd_index]);
1280 return 8 + track->extradata_size[track->last_stsd_index];
1281}
1282
1283/**
1284 * Compute flags for 'lpcm' tag.
1285 * See CoreAudioTypes and AudioStreamBasicDescription at Apple.
1286 */
1288{
1289 switch (codec_id) {
1292 return 11;
1295 return 9;
1296 case AV_CODEC_ID_PCM_U8:
1297 return 10;
1301 return 14;
1302 case AV_CODEC_ID_PCM_S8:
1306 return 12;
1307 default:
1308 return 0;
1309 }
1310}
1311
1312static int get_cluster_duration(MOVTrack *track, int cluster_idx)
1313{
1314 int64_t next_dts;
1315
1316 if (cluster_idx >= track->entry)
1317 return 0;
1318
1319 if (cluster_idx + 1 == track->entry)
1320 next_dts = track->track_duration + track->start_dts;
1321 else
1322 next_dts = track->cluster[cluster_idx + 1].dts;
1323
1324 next_dts -= track->cluster[cluster_idx].dts;
1325
1326 av_assert0(next_dts >= 0);
1327 av_assert0(next_dts <= INT_MAX);
1328
1329 return next_dts;
1330}
1331
1333{
1334 int i, first_duration;
1335
1336 /* use 1 for raw PCM */
1337 if (!track->audio_vbr)
1338 return 1;
1339
1340 /* check to see if duration is constant for all clusters */
1341 if (!track->entry)
1342 return 0;
1343 first_duration = get_cluster_duration(track, 0);
1344 for (i = 1; i < track->entry; i++) {
1345 if (get_cluster_duration(track, i) != first_duration)
1346 return 0;
1347 }
1348 return first_duration;
1349}
1350
1352{
1353 int64_t pos = avio_tell(pb);
1354 struct mpeg4_bit_rate_values bit_rates = calculate_mpeg4_bit_rates(track);
1355 if (!bit_rates.max_bit_rate && !bit_rates.avg_bit_rate &&
1356 !bit_rates.buffer_size)
1357 // no useful data to be written, skip
1358 return 0;
1359
1360 avio_wb32(pb, 0); /* size */
1361 ffio_wfourcc(pb, "btrt");
1362
1363 avio_wb32(pb, bit_rates.buffer_size);
1364 avio_wb32(pb, bit_rates.max_bit_rate);
1365 avio_wb32(pb, bit_rates.avg_bit_rate);
1366
1367 return update_size(pb, pos);
1368}
1369
1371{
1372 int64_t pos = avio_tell(pb);
1373 int config = 0;
1374 int ret;
1375 uint8_t *speaker_pos = NULL;
1376 const AVChannelLayout *layout = &track->par->ch_layout;
1377
1379 if (ret || !config) {
1380 config = 0;
1381 speaker_pos = av_malloc(layout->nb_channels);
1382 if (!speaker_pos)
1383 return AVERROR(ENOMEM);
1385 speaker_pos, layout->nb_channels);
1386 if (ret) {
1387 char buf[128] = {0};
1388
1389 av_freep(&speaker_pos);
1390 av_channel_layout_describe(layout, buf, sizeof(buf));
1391 av_log(s, AV_LOG_ERROR, "unsupported channel layout %s\n", buf);
1392 return ret;
1393 }
1394 }
1395
1396 avio_wb32(pb, 0); /* size */
1397 ffio_wfourcc(pb, "chnl");
1398 avio_wb32(pb, 0); /* version & flags */
1399
1400 avio_w8(pb, 1); /* stream_structure */
1401 avio_w8(pb, config);
1402 if (config) {
1403 avio_wb64(pb, 0);
1404 } else {
1405 avio_write(pb, speaker_pos, layout->nb_channels);
1406 av_freep(&speaker_pos);
1407 }
1408
1409 return update_size(pb, pos);
1410}
1411
1413{
1414 int64_t pos = avio_tell(pb);
1415 int format_flags;
1416 int sample_size;
1417
1418 avio_wb32(pb, 0); /* size */
1419 ffio_wfourcc(pb, "pcmC");
1420 avio_wb32(pb, 0); /* version & flags */
1421
1422 /* 0x01: indicates little-endian format */
1423 format_flags = (track->par->codec_id == AV_CODEC_ID_PCM_F32LE ||
1424 track->par->codec_id == AV_CODEC_ID_PCM_F64LE ||
1425 track->par->codec_id == AV_CODEC_ID_PCM_S16LE ||
1426 track->par->codec_id == AV_CODEC_ID_PCM_S24LE ||
1428 avio_w8(pb, format_flags);
1429 sample_size = track->par->bits_per_raw_sample;
1430 if (!sample_size)
1431 sample_size = av_get_exact_bits_per_sample(track->par->codec_id);
1432 av_assert0(sample_size);
1433 avio_w8(pb, sample_size);
1434
1435 return update_size(pb, pos);
1436}
1437
1439{
1440 int64_t pos = avio_tell(pb);
1441 avio_wb32(pb, 0); /* size */
1442 ffio_wfourcc(pb, "srat");
1443 avio_wb32(pb, 0); /* version & flags */
1444
1445 avio_wb32(pb, track->par->sample_rate);
1446
1447 return update_size(pb, pos);
1448}
1449
1451{
1452 int64_t pos = avio_tell(pb);
1453 int version = 0;
1454 uint32_t tag = track->tag;
1455 int ret = 0;
1456
1457 if (track->mode == MODE_MOV) {
1458 if (track->par->sample_rate > UINT16_MAX || !track->par->ch_layout.nb_channels ||
1459 track->par->codec_id == AV_CODEC_ID_EAC3 ||
1460 track->par->ch_layout.nb_channels > 2) {
1461 if (mov_get_lpcm_flags(track->par->codec_id))
1462 tag = AV_RL32("lpcm");
1463 version = 2;
1464 } else if (track->audio_vbr || mov_pcm_le_gt16(track->par->codec_id) ||
1465 mov_pcm_be_gt16(track->par->codec_id) ||
1466 track->par->codec_id == AV_CODEC_ID_ADPCM_MS ||
1468 track->par->codec_id == AV_CODEC_ID_QDM2) {
1469 version = 1;
1470 }
1471 } else if (track->mode == MODE_MP4) {
1472 if (track->par->sample_rate > UINT16_MAX &&
1474 version = 1;
1475 }
1476
1477 avio_wb32(pb, 0); /* size */
1478 if (mov->encryption_scheme != MOV_ENC_NONE) {
1479 ffio_wfourcc(pb, "enca");
1480 } else {
1481 avio_wl32(pb, tag); // store it byteswapped
1482 }
1483 avio_wb32(pb, 0); /* Reserved */
1484 avio_wb16(pb, 0); /* Reserved */
1485 avio_wb16(pb, 1); /* Data-reference index, XXX == 1 */
1486
1487 /* SoundDescription */
1488 avio_wb16(pb, version); /* Version */
1489 avio_wb16(pb, 0); /* Revision level */
1490 avio_wb32(pb, 0); /* Reserved */
1491
1492 if (version == 2) {
1493 avio_wb16(pb, 3);
1494 avio_wb16(pb, 16);
1495 avio_wb16(pb, 0xfffe);
1496 avio_wb16(pb, 0);
1497 avio_wb32(pb, 0x00010000);
1498 avio_wb32(pb, 72);
1499 avio_wb64(pb, av_double2int(track->par->sample_rate));
1500 avio_wb32(pb, track->par->ch_layout.nb_channels);
1501 avio_wb32(pb, 0x7F000000);
1504 avio_wb32(pb, track->sample_size);
1506 } else {
1507 unsigned sample_rate = track->par->sample_rate;
1508
1509 if (track->mode == MODE_MOV) {
1510 avio_wb16(pb, track->par->ch_layout.nb_channels);
1511 if (track->par->codec_id == AV_CODEC_ID_PCM_U8 ||
1512 track->par->codec_id == AV_CODEC_ID_PCM_S8)
1513 avio_wb16(pb, 8); /* bits per sample */
1514 else if (track->par->codec_id == AV_CODEC_ID_ADPCM_G726)
1515 avio_wb16(pb, track->par->bits_per_coded_sample);
1516 else
1517 avio_wb16(pb, 16);
1518 avio_wb16(pb, track->audio_vbr ? -2 : 0); /* compression ID */
1519 } else { /* reserved for mp4/3gp */
1520 avio_wb16(pb, track->tag == MKTAG('i', 'a', 'm', 'f') ?
1521 0 : track->par->ch_layout.nb_channels);
1522 if (track->par->codec_id == AV_CODEC_ID_FLAC ||
1523 track->par->codec_id == AV_CODEC_ID_ALAC) {
1524 avio_wb16(pb, track->par->bits_per_raw_sample);
1525 } else {
1526 avio_wb16(pb, 16);
1527 }
1528 avio_wb16(pb, 0);
1529
1530 while (sample_rate > UINT16_MAX)
1531 sample_rate >>= 1;
1532 }
1533
1534 avio_wb16(pb, 0); /* packet size (= 0) */
1535 if (track->tag == MKTAG('i','a','m','f'))
1536 avio_wb16(pb, 0); /* samplerate must be 0 for IAMF */
1537 else if (track->par->codec_id == AV_CODEC_ID_OPUS)
1538 avio_wb16(pb, 48000);
1539 else if (track->par->codec_id == AV_CODEC_ID_TRUEHD)
1540 avio_wb32(pb, track->par->sample_rate);
1541 else
1542 avio_wb16(pb, sample_rate);
1543
1544 if (track->par->codec_id != AV_CODEC_ID_TRUEHD)
1545 avio_wb16(pb, 0); /* Reserved */
1546 }
1547
1548 if (track->mode == MODE_MOV && version == 1) { /* SoundDescription V1 extended info */
1549 if (mov_pcm_le_gt16(track->par->codec_id) ||
1550 mov_pcm_be_gt16(track->par->codec_id))
1551 avio_wb32(pb, 1); /* must be 1 for uncompressed formats */
1552 else
1553 avio_wb32(pb, track->par->frame_size); /* Samples per packet */
1554 avio_wb32(pb, track->sample_size / track->par->ch_layout.nb_channels); /* Bytes per packet */
1555 avio_wb32(pb, track->sample_size); /* Bytes per frame */
1556 avio_wb32(pb, 2); /* Bytes per sample */
1557 }
1558
1559 if (track->mode == MODE_MOV &&
1560 (track->par->codec_id == AV_CODEC_ID_AAC ||
1561 track->par->codec_id == AV_CODEC_ID_AC3 ||
1562 track->par->codec_id == AV_CODEC_ID_EAC3 ||
1563 track->par->codec_id == AV_CODEC_ID_AMR_NB ||
1564 track->par->codec_id == AV_CODEC_ID_ALAC ||
1565 track->par->codec_id == AV_CODEC_ID_ADPCM_MS ||
1567 track->par->codec_id == AV_CODEC_ID_QDM2 ||
1568 (mov_pcm_le_gt16(track->par->codec_id) && version==1) ||
1569 (mov_pcm_be_gt16(track->par->codec_id) && version==1)))
1570 ret = mov_write_wave_tag(s, pb, track);
1571 else if (track->tag == MKTAG('m','p','4','a'))
1572 ret = mov_write_esds_tag(pb, track);
1573#if CONFIG_IAMFENC
1574 else if (track->tag == MKTAG('i','a','m','f'))
1575 ret = mov_write_iacb_tag(mov->fc, pb, track);
1576#endif
1577 else if (track->par->codec_id == AV_CODEC_ID_AMR_NB)
1578 ret = mov_write_amr_tag(pb, track);
1579 else if (track->par->codec_id == AV_CODEC_ID_AC3)
1580 ret = mov_write_ac3_tag(s, pb, track);
1581 else if (track->par->codec_id == AV_CODEC_ID_EAC3)
1582 ret = mov_write_eac3_tag(s, pb, track);
1583 else if (track->par->codec_id == AV_CODEC_ID_ALAC)
1584 ret = mov_write_extradata_tag(pb, track);
1585 else if (track->par->codec_id == AV_CODEC_ID_WMAPRO)
1586 ret = mov_write_wfex_tag(s, pb, track);
1587 else if (track->par->codec_id == AV_CODEC_ID_FLAC)
1588 ret = mov_write_dfla_tag(pb, track);
1589 else if (track->par->codec_id == AV_CODEC_ID_OPUS)
1590 ret = mov_write_dops_tag(s, pb, track);
1591 else if (track->par->codec_id == AV_CODEC_ID_TRUEHD)
1592 ret = mov_write_dmlp_tag(s, pb, track);
1593 else if (track->par->codec_id == AV_CODEC_ID_MPEGH_3D_AUDIO)
1594 ret = mov_write_mhac_tag(s, pb, track);
1595 else if (tag == MOV_MP4_IPCM_TAG || tag == MOV_MP4_FPCM_TAG) {
1596 if (track->par->sample_rate > UINT16_MAX)
1597 mov_write_srat_tag(pb, track);
1598 if (track->par->ch_layout.nb_channels > 1)
1599 ret = mov_write_chnl_tag(s, pb, track);
1600 if (ret < 0)
1601 return ret;
1602 ret = mov_write_pcmc_tag(s, pb, track);
1603 } else if (track->extradata_size[track->last_stsd_index] > 0)
1604 ret = mov_write_glbl_tag(pb, track);
1605
1606 if (ret < 0)
1607 return ret;
1608
1609 if (track->mode == MODE_MP4 && track->par->codec_type == AVMEDIA_TYPE_AUDIO
1610 && ((ret = mov_write_SA3D_tag(s, pb, track)) < 0)) {
1611 return ret;
1612 }
1613
1614 if (track->mode == MODE_MOV && track->par->codec_type == AVMEDIA_TYPE_AUDIO
1615 && ((ret = mov_write_chan_tag(s, pb, track)) < 0)) {
1616 return ret;
1617 }
1618
1620 && ((ret = ff_mov_cenc_write_sinf_tag(track, pb, mov->encryption_kid)) < 0)) {
1621 return ret;
1622 }
1623
1624 if (mov->write_btrt &&
1625 ((ret = mov_write_btrt_tag(pb, track)) < 0))
1626 return ret;
1627
1628 if (track->mode == MODE_MP4)
1629 track->entry_version = version;
1630
1631 ret = update_size(pb, pos);
1632 return ret;
1633}
1634
1636{
1637 avio_wb32(pb, 0xf); /* size */
1638 ffio_wfourcc(pb, "d263");
1639 ffio_wfourcc(pb, "FFMP");
1640 avio_w8(pb, 0); /* decoder version */
1641 /* FIXME use AVCodecContext level/profile, when encoder will set values */
1642 avio_w8(pb, 0xa); /* level */
1643 avio_w8(pb, 0); /* profile */
1644 return 0xf;
1645}
1646
1648{
1649 int64_t pos = avio_tell(pb);
1650
1651 avio_wb32(pb, 0);
1652 ffio_wfourcc(pb, "av1C");
1653 ff_isom_write_av1c(pb, track->extradata[track->last_stsd_index],
1654 track->extradata_size[track->last_stsd_index], track->mode != MODE_AVIF);
1655 return update_size(pb, pos);
1656}
1657
1659{
1660 int64_t pos = avio_tell(pb);
1661
1662 avio_wb32(pb, 0);
1663 ffio_wfourcc(pb, "avcC");
1664 ff_isom_write_avcc(pb, track->extradata[track->last_stsd_index],
1665 track->extradata_size[track->last_stsd_index]);
1666 return update_size(pb, pos);
1667}
1668
1669/* AVS3 Intelligent Media Coding
1670 * Information Technology - Intelligent Media Coding
1671 * Part 6: Intelligent Media Format
1672 */
1673static int mov_write_av3c(AVIOContext *pb, const uint8_t *data, int len)
1674{
1675 if (len < 4)
1676 return AVERROR_INVALIDDATA;
1677
1678 if (data[0] == 1) {
1679 // In Avs3DecoderConfigurationRecord format
1680 avio_write(pb, data, len);
1681 return 0;
1682 }
1683
1684 avio_w8(pb, 1); // version
1685 avio_wb16(pb, len); // sequence_header_length
1686 avio_write(pb, data, len); // sequence_header
1687 avio_w8(pb, 0xFC); // Only support library_dependency_idc = 0
1688
1689 return 0;
1690}
1691
1693{
1694 int64_t pos = avio_tell(pb);
1695 avio_wb32(pb, 0);
1696 ffio_wfourcc(pb, "av3c");
1697 mov_write_av3c(pb, track->extradata[track->last_stsd_index],
1698 track->extradata_size[track->last_stsd_index]);
1699 return update_size(pb, pos);
1700}
1701
1703{
1704 int64_t pos = avio_tell(pb);
1705
1706 avio_wb32(pb, 0);
1707 ffio_wfourcc(pb, "vpcC");
1708 ff_isom_write_vpcc(s, pb, track->extradata[track->last_stsd_index],
1709 track->extradata_size[track->last_stsd_index], track->par);
1710 return update_size(pb, pos);
1711}
1712
1714{
1715 int64_t pos = avio_tell(pb);
1716
1717 avio_wb32(pb, 0);
1718 ffio_wfourcc(pb, "hvcC");
1719 if (track->tag == MKTAG('h','v','c','1'))
1720 ff_isom_write_hvcc(pb, track->extradata[track->last_stsd_index],
1721 track->extradata_size[track->last_stsd_index], 1, s);
1722 else
1723 ff_isom_write_hvcc(pb, track->extradata[track->last_stsd_index],
1724 track->extradata_size[track->last_stsd_index], 0, s);
1725 return update_size(pb, pos);
1726}
1727
1729{
1730 int64_t pos = avio_tell(pb);
1731 int ret;
1732
1733 avio_wb32(pb, 0);
1734 ffio_wfourcc(pb, "lhvC");
1735 if (track->tag == MKTAG('h','v','c','1'))
1736 ret = ff_isom_write_lhvc(pb, track->extradata[track->last_stsd_index],
1737 track->extradata_size[track->last_stsd_index], 1, s);
1738 else
1739 ret = ff_isom_write_lhvc(pb, track->extradata[track->last_stsd_index],
1740 track->extradata_size[track->last_stsd_index], 0, s);
1741
1742 if (ret < 0) {
1743 avio_seek(pb, pos, SEEK_SET);
1744 return ret;
1745 }
1746
1747 return update_size(pb, pos);
1748}
1749
1751{
1752 int64_t pos = avio_tell(pb);
1753
1754 avio_wb32(pb, 0);
1755 ffio_wfourcc(pb, "evcC");
1756
1757 if (track->tag == MKTAG('e','v','c','1'))
1758 ff_isom_write_evcc(pb, track->extradata[track->last_stsd_index],
1759 track->extradata_size[track->last_stsd_index], 1);
1760 else
1761 ff_isom_write_evcc(pb, track->extradata[track->last_stsd_index],
1762 track->extradata_size[track->last_stsd_index], 0);
1763
1764 return update_size(pb, pos);
1765}
1766
1768{
1769 int64_t pos = avio_tell(pb);
1770
1771 avio_wb32(pb, 0);
1772 ffio_wfourcc(pb, "lvcC");
1773
1774 ff_isom_write_lvcc(pb, track->extradata[track->last_stsd_index],
1775 track->extradata_size[track->last_stsd_index], s);
1776
1777 return update_size(pb, pos);
1778}
1779
1781{
1782 int64_t pos = avio_tell(pb);
1783
1784 avio_wb32(pb, 0);
1785 ffio_wfourcc(pb, "vvcC");
1786
1787 avio_w8 (pb, 0); /* version */
1788 avio_wb24(pb, 0); /* flags */
1789
1790 if (track->tag == MKTAG('v','v','c','1'))
1791 ff_isom_write_vvcc(pb, track->extradata[track->last_stsd_index],
1792 track->extradata_size[track->last_stsd_index], 1);
1793 else
1794 ff_isom_write_vvcc(pb, track->extradata[track->last_stsd_index],
1795 track->extradata_size[track->last_stsd_index], 0);
1796 return update_size(pb, pos);
1797}
1798
1800{
1801 int64_t pos = avio_tell(pb);
1802
1803 avio_wb32(pb, 0);
1804 ffio_wfourcc(pb, "apvC");
1805
1806 avio_w8 (pb, 0); /* version */
1807 avio_wb24(pb, 0); /* flags */
1808
1809 ff_isom_write_apvc(pb, track->apv, s);
1810
1811 return update_size(pb, pos);
1812}
1813
1814/* also used by all avid codecs (dv, imx, meridien) and their variants */
1815/* https://community.avid.com/forums/t/136517.aspx */
1817{
1818 int interlaced;
1819 int cid;
1820 int display_width = track->par->width;
1821 const uint8_t *extradata;
1822
1823 if (track->extradata[track->last_stsd_index] && track->extradata_size[track->last_stsd_index] > 0x29) {
1824 if (ff_dnxhd_parse_header_prefix(track->extradata[track->last_stsd_index]) != 0) {
1825 /* looks like a DNxHD bit stream */
1826 extradata = track->extradata[track->last_stsd_index];
1827 } else {
1828 av_log(NULL, AV_LOG_WARNING, "Could not locate DNxHD bit stream in vos_data\n");
1829 return 0;
1830 }
1831 } else {
1832 av_log(NULL, AV_LOG_WARNING, "Could not locate DNxHD bit stream, vos_data too small\n");
1833 return 0;
1834 }
1835
1836 cid = AV_RB32(extradata + 0x28);
1837
1838 avio_wb32(pb, 24); /* size */
1839 ffio_wfourcc(pb, "ACLR");
1840 ffio_wfourcc(pb, "ACLR");
1841 ffio_wfourcc(pb, "0001");
1842 // 1: CCIR (supercolors will be dropped, 16 will be displayed as black)
1843 // 2: FullRange (0 will be displayed as black, 16 will be displayed as dark grey)
1844 if (track->par->color_range == AVCOL_RANGE_MPEG || /* Legal range (16-235) */
1846 avio_wb32(pb, 1);
1847 } else {
1848 avio_wb32(pb, 2);
1849 }
1850 avio_wb32(pb, 0); /* reserved */
1851
1852 if (track->tag == MKTAG('A','V','d','h')) {
1853 int alp = extradata[0x07] & 1;
1854 int pma = (extradata[0x07] >> 2) & 1;
1855 int sbd = (extradata[0x21] >> 5) & 3;
1856 int ssc = (extradata[0x2C] >> 5) & 3;
1857 int clv = (extradata[0x2C] >> 1) & 3;
1858 int clf = extradata[0x2C] & 1;
1859
1860 avio_wb32(pb, 32);
1861 ffio_wfourcc(pb, "ADHR");
1862 ffio_wfourcc(pb, "0001");
1863 avio_wb32(pb, cid); // Compression ID
1864 // 0: 4:2:2 Sub Sampling
1865 // 1: 4:2:0 Sub Sampling
1866 // 2: 4:4:4 Sub Sampling
1867 avio_wb32(pb, ssc); // Sub Sampling Control
1868 // 1: 8-bits per sample
1869 // 2: 10-bits per sample
1870 // 3: 12-bits per sample
1871 avio_wb32(pb, sbd); // Sample Bit Depth
1872 // 0: Bitstream is encoded using the YCBCR format rules and tables
1873 // 1: Bitstream is encoded using the RGB format rules and tables – only Compression IDs 1256, 1270
1874 avio_wb16(pb, clf); // Color Format
1875 // 0: ITU-R BT.709
1876 // 1: ITU-R BT.2020
1877 // 2: ITU-R BT.2020 C
1878 // 3: Out-of-band
1879 avio_wb16(pb, clv); // Color Volume
1880 // 0: Alpha channel not present
1881 // 1: Alpha channel present
1882 avio_wb16(pb, alp); // Alpha Present
1883 // 0: Alpha has not been applied to video channels
1884 // 1: Alpha has been applied to the video channels prior to encoding
1885 avio_wb16(pb, pma); // Pre-Multiplied Alpha
1886 return 0;
1887 }
1888
1889 interlaced = extradata[5] & 2;
1890
1891 avio_wb32(pb, 24); /* size */
1892 ffio_wfourcc(pb, "APRG");
1893 ffio_wfourcc(pb, "APRG");
1894 ffio_wfourcc(pb, "0001");
1895 // 1 for progressive or 2 for interlaced
1896 if (interlaced)
1897 avio_wb32(pb, 2);
1898 else
1899 avio_wb32(pb, 1);
1900 avio_wb32(pb, 0); /* reserved */
1901
1902 avio_wb32(pb, 120); /* size */
1903 ffio_wfourcc(pb, "ARES");
1904 ffio_wfourcc(pb, "ARES");
1905 ffio_wfourcc(pb, "0001");
1906 avio_wb32(pb, cid); /* cid */
1907 if ( track->par->sample_aspect_ratio.num > 0
1908 && track->par->sample_aspect_ratio.den > 0)
1909 display_width = display_width * track->par->sample_aspect_ratio.num / track->par->sample_aspect_ratio.den;
1910 avio_wb32(pb, display_width); // field width
1911 if (interlaced) {
1912 avio_wb32(pb, track->par->height / 2); // field height
1913 avio_wb32(pb, 2); // num fields
1914 avio_wb32(pb, 0); // num black lines (must be 0)
1915 // 4: HD1080i
1916 // 5: HD1080P
1917 // 6: HD720P
1918 avio_wb32(pb, 4); // video format
1919 } else {
1920 avio_wb32(pb, track->par->height);
1921 avio_wb32(pb, 1); // num fields
1922 avio_wb32(pb, 0);
1923 if (track->par->height == 1080)
1924 avio_wb32(pb, 5);
1925 else
1926 avio_wb32(pb, 6);
1927 }
1928 /* padding */
1929 ffio_fill(pb, 0, 10 * 8);
1930
1931 return 0;
1932}
1933
1935{
1936 avio_wb32(pb, 12);
1937 ffio_wfourcc(pb, "DpxE");
1938 if (track->extradata_size[track->last_stsd_index] >= 12 &&
1939 !memcmp(&track->extradata[track->last_stsd_index][4], "DpxE", 4)) {
1940 avio_wb32(pb, track->extradata[track->last_stsd_index][11]);
1941 } else {
1942 avio_wb32(pb, 1);
1943 }
1944 return 0;
1945}
1946
1948{
1949 int tag;
1950
1951 if (track->par->width == 720) { /* SD */
1952 if (track->par->height == 480) { /* NTSC */
1953 if (track->par->format == AV_PIX_FMT_YUV422P) tag = MKTAG('d','v','5','n');
1954 else tag = MKTAG('d','v','c',' ');
1955 }else if (track->par->format == AV_PIX_FMT_YUV422P) tag = MKTAG('d','v','5','p');
1956 else if (track->par->format == AV_PIX_FMT_YUV420P) tag = MKTAG('d','v','c','p');
1957 else tag = MKTAG('d','v','p','p');
1958 } else if (track->par->height == 720) { /* HD 720 line */
1959 if (track->st->time_base.den == 50) tag = MKTAG('d','v','h','q');
1960 else tag = MKTAG('d','v','h','p');
1961 } else if (track->par->height == 1080) { /* HD 1080 line */
1962 if (track->st->time_base.den == 25) tag = MKTAG('d','v','h','5');
1963 else tag = MKTAG('d','v','h','6');
1964 } else {
1965 av_log(s, AV_LOG_ERROR, "unsupported height for dv codec\n");
1966 return 0;
1967 }
1968
1969 return tag;
1970}
1971
1973{
1974 AVRational rational_framerate = st->avg_frame_rate;
1975 int rate = 0;
1976 if (rational_framerate.den != 0)
1977 rate = av_q2d(rational_framerate);
1978 return rate;
1979}
1980
1982{
1983 int tag = track->par->codec_tag;
1985 AVStream *st = track->st;
1986 int rate = defined_frame_rate(s, st);
1987
1988 if (!tag)
1989 tag = MKTAG('m', '2', 'v', '1'); //fallback tag
1990
1991 if (track->par->format == AV_PIX_FMT_YUV420P) {
1992 if (track->par->width == 1280 && track->par->height == 720) {
1993 if (!interlaced) {
1994 if (rate == 24) tag = MKTAG('x','d','v','4');
1995 else if (rate == 25) tag = MKTAG('x','d','v','5');
1996 else if (rate == 30) tag = MKTAG('x','d','v','1');
1997 else if (rate == 50) tag = MKTAG('x','d','v','a');
1998 else if (rate == 60) tag = MKTAG('x','d','v','9');
1999 }
2000 } else if (track->par->width == 1440 && track->par->height == 1080) {
2001 if (!interlaced) {
2002 if (rate == 24) tag = MKTAG('x','d','v','6');
2003 else if (rate == 25) tag = MKTAG('x','d','v','7');
2004 else if (rate == 30) tag = MKTAG('x','d','v','8');
2005 } else {
2006 if (rate == 25) tag = MKTAG('x','d','v','3');
2007 else if (rate == 30) tag = MKTAG('x','d','v','2');
2008 }
2009 } else if (track->par->width == 1920 && track->par->height == 1080) {
2010 if (!interlaced) {
2011 if (rate == 24) tag = MKTAG('x','d','v','d');
2012 else if (rate == 25) tag = MKTAG('x','d','v','e');
2013 else if (rate == 30) tag = MKTAG('x','d','v','f');
2014 } else {
2015 if (rate == 25) tag = MKTAG('x','d','v','c');
2016 else if (rate == 30) tag = MKTAG('x','d','v','b');
2017 }
2018 }
2019 } else if (track->par->format == AV_PIX_FMT_YUV422P) {
2020 if (track->par->width == 1280 && track->par->height == 720) {
2021 if (!interlaced) {
2022 if (rate == 24) tag = MKTAG('x','d','5','4');
2023 else if (rate == 25) tag = MKTAG('x','d','5','5');
2024 else if (rate == 30) tag = MKTAG('x','d','5','1');
2025 else if (rate == 50) tag = MKTAG('x','d','5','a');
2026 else if (rate == 60) tag = MKTAG('x','d','5','9');
2027 }
2028 } else if (track->par->width == 1920 && track->par->height == 1080) {
2029 if (!interlaced) {
2030 if (rate == 24) tag = MKTAG('x','d','5','d');
2031 else if (rate == 25) tag = MKTAG('x','d','5','e');
2032 else if (rate == 30) tag = MKTAG('x','d','5','f');
2033 } else {
2034 if (rate == 25) tag = MKTAG('x','d','5','c');
2035 else if (rate == 30) tag = MKTAG('x','d','5','b');
2036 }
2037 }
2038 }
2039
2040 return tag;
2041}
2042
2044{
2045 int tag = track->par->codec_tag;
2047 AVStream *st = track->st;
2048 int rate = defined_frame_rate(s, st);
2049
2050 if (!tag)
2051 tag = MKTAG('a', 'v', 'c', 'i'); //fallback tag
2052
2053 if (track->par->profile == AV_PROFILE_UNKNOWN ||
2054 !(track->par->profile & AV_PROFILE_H264_INTRA))
2055 return tag;
2056
2057 if (track->par->format == AV_PIX_FMT_YUV420P10) {
2058 if (track->par->width == 960 && track->par->height == 720) {
2059 if (!interlaced) {
2060 if (rate == 24) tag = MKTAG('a','i','5','p');
2061 else if (rate == 25) tag = MKTAG('a','i','5','q');
2062 else if (rate == 30) tag = MKTAG('a','i','5','p');
2063 else if (rate == 50) tag = MKTAG('a','i','5','q');
2064 else if (rate == 60) tag = MKTAG('a','i','5','p');
2065 }
2066 } else if (track->par->width == 1440 && track->par->height == 1080) {
2067 if (!interlaced) {
2068 if (rate == 24) tag = MKTAG('a','i','5','3');
2069 else if (rate == 25) tag = MKTAG('a','i','5','2');
2070 else if (rate == 30) tag = MKTAG('a','i','5','3');
2071 } else {
2072 if (rate == 50) tag = MKTAG('a','i','5','5');
2073 else if (rate == 60) tag = MKTAG('a','i','5','6');
2074 }
2075 }
2076 } else if (track->par->format == AV_PIX_FMT_YUV422P10) {
2077 if (track->par->width == 1280 && track->par->height == 720) {
2078 if (!interlaced) {
2079 if (rate == 24) tag = MKTAG('a','i','1','p');
2080 else if (rate == 25) tag = MKTAG('a','i','1','q');
2081 else if (rate == 30) tag = MKTAG('a','i','1','p');
2082 else if (rate == 50) tag = MKTAG('a','i','1','q');
2083 else if (rate == 60) tag = MKTAG('a','i','1','p');
2084 }
2085 } else if (track->par->width == 1920 && track->par->height == 1080) {
2086 if (!interlaced) {
2087 if (rate == 24) tag = MKTAG('a','i','1','3');
2088 else if (rate == 25) tag = MKTAG('a','i','1','2');
2089 else if (rate == 30) tag = MKTAG('a','i','1','3');
2090 } else {
2091 if (rate == 25) tag = MKTAG('a','i','1','5');
2092 else if (rate == 50) tag = MKTAG('a','i','1','5');
2093 else if (rate == 60) tag = MKTAG('a','i','1','6');
2094 }
2095 } else if ( track->par->width == 4096 && track->par->height == 2160
2096 || track->par->width == 3840 && track->par->height == 2160
2097 || track->par->width == 2048 && track->par->height == 1080) {
2098 tag = MKTAG('a','i','v','x');
2099 }
2100 }
2101
2102 return tag;
2103}
2104
2106{
2107 int tag = track->par->codec_tag;
2108
2109 if (!tag)
2110 tag = MKTAG('e', 'v', 'c', '1');
2111
2112 return tag;
2113}
2114
2116{
2117 int tag = track->par->codec_tag;
2118
2119 if (!tag)
2120 tag = MKTAG('a', 'p', 'v', '1');
2121
2122 return tag;
2123}
2124
2125
2126static const struct {
2128 uint32_t tag;
2129 unsigned bps;
2130} mov_pix_fmt_tags[] = {
2131 { AV_PIX_FMT_YUYV422, MKTAG('y','u','v','2'), 0 },
2132 { AV_PIX_FMT_YUYV422, MKTAG('y','u','v','s'), 0 },
2133 { AV_PIX_FMT_UYVY422, MKTAG('2','v','u','y'), 0 },
2134 { AV_PIX_FMT_VYU444, MKTAG('v','3','0','8'), 0 },
2135 { AV_PIX_FMT_UYVA, MKTAG('v','4','0','8'), 0 },
2136 { AV_PIX_FMT_V30XLE, MKTAG('v','4','1','0'), 0 },
2137 { AV_PIX_FMT_RGB555BE,MKTAG('r','a','w',' '), 16 },
2138 { AV_PIX_FMT_RGB555LE,MKTAG('L','5','5','5'), 16 },
2139 { AV_PIX_FMT_RGB565LE,MKTAG('L','5','6','5'), 16 },
2140 { AV_PIX_FMT_RGB565BE,MKTAG('B','5','6','5'), 16 },
2141 { AV_PIX_FMT_GRAY16BE,MKTAG('b','1','6','g'), 16 },
2142 { AV_PIX_FMT_RGB24, MKTAG('r','a','w',' '), 24 },
2143 { AV_PIX_FMT_BGR24, MKTAG('2','4','B','G'), 24 },
2144 { AV_PIX_FMT_ARGB, MKTAG('r','a','w',' '), 32 },
2145 { AV_PIX_FMT_BGRA, MKTAG('B','G','R','A'), 32 },
2146 { AV_PIX_FMT_RGBA, MKTAG('R','G','B','A'), 32 },
2147 { AV_PIX_FMT_ABGR, MKTAG('A','B','G','R'), 32 },
2148 { AV_PIX_FMT_RGB48BE, MKTAG('b','4','8','r'), 48 },
2150
2152{
2153 int tag = MKTAG('A','V','d','n');
2154 if (track->par->profile != AV_PROFILE_UNKNOWN &&
2155 track->par->profile != AV_PROFILE_DNXHD)
2156 tag = MKTAG('A','V','d','h');
2157 return tag;
2158}
2159
2161{
2162 int tag = track->par->codec_tag;
2163 int i;
2165
2166 for (i = 0; i < FF_ARRAY_ELEMS(mov_pix_fmt_tags); i++) {
2167 if (track->par->format == mov_pix_fmt_tags[i].pix_fmt) {
2168 tag = mov_pix_fmt_tags[i].tag;
2170 if (track->par->codec_tag == mov_pix_fmt_tags[i].tag)
2171 break;
2172 }
2173 }
2174
2176 track->par->bits_per_coded_sample);
2177 if (tag == MKTAG('r','a','w',' ') &&
2178 track->par->format != pix_fmt &&
2179 track->par->format != AV_PIX_FMT_GRAY8 &&
2180 track->par->format != AV_PIX_FMT_NONE)
2181 av_log(s, AV_LOG_ERROR, "%s rawvideo cannot be written to mov, output file will be unreadable\n",
2182 av_get_pix_fmt_name(track->par->format));
2183 return tag;
2184}
2185
2186static unsigned int mov_get_codec_tag(AVFormatContext *s, MOVTrack *track)
2187{
2188 unsigned int tag = track->par->codec_tag;
2189
2190 // "rtp " is used to distinguish internally created RTP-hint tracks
2191 // (with rtp_ctx) from other tracks.
2192 if (tag == MKTAG('r','t','p',' '))
2193 tag = 0;
2194 if (!tag || (s->strict_std_compliance >= FF_COMPLIANCE_NORMAL &&
2195 (track->par->codec_id == AV_CODEC_ID_DVVIDEO ||
2196 track->par->codec_id == AV_CODEC_ID_RAWVIDEO ||
2197 track->par->codec_id == AV_CODEC_ID_H263 ||
2198 track->par->codec_id == AV_CODEC_ID_H264 ||
2199 track->par->codec_id == AV_CODEC_ID_DNXHD ||
2200 track->par->codec_id == AV_CODEC_ID_MPEG2VIDEO ||
2201 av_get_bits_per_sample(track->par->codec_id)))) { // pcm audio
2202 if (track->par->codec_id == AV_CODEC_ID_DVVIDEO)
2203 tag = mov_get_dv_codec_tag(s, track);
2204 else if (track->par->codec_id == AV_CODEC_ID_RAWVIDEO)
2206 else if (track->par->codec_id == AV_CODEC_ID_MPEG2VIDEO)
2208 else if (track->par->codec_id == AV_CODEC_ID_H264)
2209 tag = mov_get_h264_codec_tag(s, track);
2210 else if (track->par->codec_id == AV_CODEC_ID_EVC)
2211 tag = mov_get_evc_codec_tag(s, track);
2212 else if (track->par->codec_id == AV_CODEC_ID_APV)
2213 tag = mov_get_apv_codec_tag(s, track);
2214 else if (track->par->codec_id == AV_CODEC_ID_DNXHD)
2215 tag = mov_get_dnxhd_codec_tag(s, track);
2216 else if (track->par->codec_type == AVMEDIA_TYPE_VIDEO) {
2218 if (!tag) { // if no mac fcc found, try with Microsoft tags
2220 if (tag)
2221 av_log(s, AV_LOG_WARNING, "Using MS style video codec tag, "
2222 "the file may be unplayable!\n");
2223 }
2224 } else if (track->par->codec_type == AVMEDIA_TYPE_AUDIO) {
2226 if (!tag) { // if no mac fcc found, try with Microsoft tags
2227 int ms_tag = ff_codec_get_tag(ff_codec_wav_tags, track->par->codec_id);
2228 if (ms_tag) {
2229 tag = MKTAG('m', 's', ((ms_tag >> 8) & 0xff), (ms_tag & 0xff));
2230 av_log(s, AV_LOG_WARNING, "Using MS style audio codec tag, "
2231 "the file may be unplayable!\n");
2232 }
2233 }
2234 } else if (track->par->codec_type == AVMEDIA_TYPE_SUBTITLE)
2236 }
2237
2238 return tag;
2239}
2240
2242 { AV_CODEC_ID_MJPEG, 0xD },
2243 { AV_CODEC_ID_PNG, 0xE },
2244 { AV_CODEC_ID_BMP, 0x1B },
2245 { AV_CODEC_ID_NONE, 0 },
2246};
2247
2248static unsigned int validate_codec_tag(const AVCodecTag *const *tags,
2249 unsigned int tag, int codec_id)
2250{
2251 int i;
2252
2253 /**
2254 * Check that tag + id is in the table
2255 */
2256 for (i = 0; tags && tags[i]; i++) {
2257 const AVCodecTag *codec_tags = tags[i];
2258 while (codec_tags->id != AV_CODEC_ID_NONE) {
2259 if (ff_toupper4(codec_tags->tag) == ff_toupper4(tag) &&
2260 codec_tags->id == codec_id)
2261 return codec_tags->tag;
2262 codec_tags++;
2263 }
2264 }
2265 return 0;
2266}
2267
2268static unsigned int mov_find_codec_tag(AVFormatContext *s, MOVTrack *track)
2269{
2270 if (is_cover_image(track->st))
2272
2273 if (track->mode == MODE_IPOD)
2274 if (!av_match_ext(s->url, "m4a") &&
2275 !av_match_ext(s->url, "m4v") &&
2276 !av_match_ext(s->url, "m4b"))
2277 av_log(s, AV_LOG_WARNING, "Warning, extension is not .m4a nor .m4v "
2278 "Quicktime/Ipod might not play the file\n");
2279
2280 if (track->mode == MODE_MOV) {
2281 return mov_get_codec_tag(s, track);
2282 } else
2283 return validate_codec_tag(s->oformat->codec_tag, track->par->codec_tag,
2284 track->par->codec_id);
2285}
2286
2287/** Write uuid atom.
2288 * Needed to make file play in iPods running newest firmware
2289 * goes after avcC atom in moov.trak.mdia.minf.stbl.stsd.avc1
2290 */
2292{
2293 avio_wb32(pb, 28);
2294 ffio_wfourcc(pb, "uuid");
2295 avio_wb32(pb, 0x6b6840f2);
2296 avio_wb32(pb, 0x5f244fc5);
2297 avio_wb32(pb, 0xba39a51b);
2298 avio_wb32(pb, 0xcf0323f3);
2299 avio_wb32(pb, 0x0);
2300 return 28;
2301}
2302
2303static const uint16_t fiel_data[] = {
2304 0x0000, 0x0100, 0x0201, 0x0206, 0x0209, 0x020e
2305};
2306
2307static int mov_write_fiel_tag(AVIOContext *pb, MOVTrack *track, int field_order)
2308{
2309 unsigned mov_field_order = 0;
2310 if (field_order < FF_ARRAY_ELEMS(fiel_data))
2311 mov_field_order = fiel_data[field_order];
2312 else
2313 return 0;
2314 avio_wb32(pb, 10);
2315 ffio_wfourcc(pb, "fiel");
2316 avio_wb16(pb, mov_field_order);
2317 return 10;
2318}
2319
2321{
2322 MOVMuxContext *mov = s->priv_data;
2323 int ret = AVERROR_BUG;
2324 int64_t pos = avio_tell(pb);
2325 avio_wb32(pb, 0); /* size */
2326 avio_wl32(pb, track->tag); // store it byteswapped
2327 avio_wb32(pb, 0); /* Reserved */
2328 avio_wb16(pb, 0); /* Reserved */
2329 avio_wb16(pb, 1); /* Data-reference index */
2330
2331 if (track->par->codec_id == AV_CODEC_ID_DVD_SUBTITLE)
2332 mov_write_esds_tag(pb, track);
2333 else if (track->par->codec_id == AV_CODEC_ID_TTML) {
2334 switch (track->par->codec_tag) {
2335 case MOV_ISMV_TTML_TAG:
2336 // ISMV dfxp requires no extradata.
2337 break;
2338 case MOV_MP4_TTML_TAG:
2339 // As specified in 14496-30, XMLSubtitleSampleEntry
2340 // Namespace
2341 avio_put_str(pb, "http://www.w3.org/ns/ttml");
2342 // Empty schema_location
2343 avio_w8(pb, 0);
2344 // Empty auxiliary_mime_types
2345 avio_w8(pb, 0);
2346 break;
2347 default:
2349 "Unknown codec tag '%s' utilized for TTML stream with "
2350 "index %d (track id %d)!\n",
2351 av_fourcc2str(track->par->codec_tag), track->st->index,
2352 track->track_id);
2353 return AVERROR(EINVAL);
2354 }
2355 } else if (track->extradata_size[track->last_stsd_index])
2356 avio_write(pb, track->extradata[track->last_stsd_index], track->extradata_size[track->last_stsd_index]);
2357
2358 if (mov->write_btrt &&
2359 ((ret = mov_write_btrt_tag(pb, track)) < 0))
2360 return ret;
2361
2362 return update_size(pb, pos);
2363}
2364
2366{
2367 int8_t stereo_mode;
2368
2369 if (stereo_3d->flags != 0) {
2370 av_log(s, AV_LOG_WARNING, "Unsupported stereo_3d flags %x. st3d not written.\n", stereo_3d->flags);
2371 return 0;
2372 }
2373
2374 switch (stereo_3d->type) {
2375 case AV_STEREO3D_2D:
2376 stereo_mode = 0;
2377 break;
2379 stereo_mode = 1;
2380 break;
2382 stereo_mode = 2;
2383 break;
2384 default:
2385 av_log(s, AV_LOG_WARNING, "Unsupported stereo_3d type %s. st3d not written.\n", av_stereo3d_type_name(stereo_3d->type));
2386 return 0;
2387 }
2388 avio_wb32(pb, 13); /* size */
2389 ffio_wfourcc(pb, "st3d");
2390 avio_wb32(pb, 0); /* version = 0 & flags = 0 */
2391 avio_w8(pb, stereo_mode);
2392 return 13;
2393}
2394
2396{
2397 int64_t sv3d_pos, svhd_pos, proj_pos;
2398 const char* metadata_source = s->flags & AVFMT_FLAG_BITEXACT ? "Lavf" : LIBAVFORMAT_IDENT;
2399
2400 if (spherical_mapping->projection != AV_SPHERICAL_EQUIRECTANGULAR &&
2401 spherical_mapping->projection != AV_SPHERICAL_EQUIRECTANGULAR_TILE &&
2402 spherical_mapping->projection != AV_SPHERICAL_CUBEMAP) {
2403 av_log(s, AV_LOG_WARNING, "Unsupported projection %d. sv3d not written.\n", spherical_mapping->projection);
2404 return 0;
2405 }
2406
2407 sv3d_pos = avio_tell(pb);
2408 avio_wb32(pb, 0); /* size */
2409 ffio_wfourcc(pb, "sv3d");
2410
2411 svhd_pos = avio_tell(pb);
2412 avio_wb32(pb, 0); /* size */
2413 ffio_wfourcc(pb, "svhd");
2414 avio_wb32(pb, 0); /* version = 0 & flags = 0 */
2415 avio_put_str(pb, metadata_source);
2416 update_size(pb, svhd_pos);
2417
2418 proj_pos = avio_tell(pb);
2419 avio_wb32(pb, 0); /* size */
2420 ffio_wfourcc(pb, "proj");
2421
2422 avio_wb32(pb, 24); /* size */
2423 ffio_wfourcc(pb, "prhd");
2424 avio_wb32(pb, 0); /* version = 0 & flags = 0 */
2425 avio_wb32(pb, spherical_mapping->yaw);
2426 avio_wb32(pb, spherical_mapping->pitch);
2427 avio_wb32(pb, spherical_mapping->roll);
2428
2429 switch (spherical_mapping->projection) {
2432 avio_wb32(pb, 28); /* size */
2433 ffio_wfourcc(pb, "equi");
2434 avio_wb32(pb, 0); /* version = 0 & flags = 0 */
2435 avio_wb32(pb, spherical_mapping->bound_top);
2436 avio_wb32(pb, spherical_mapping->bound_bottom);
2437 avio_wb32(pb, spherical_mapping->bound_left);
2438 avio_wb32(pb, spherical_mapping->bound_right);
2439 break;
2441 avio_wb32(pb, 20); /* size */
2442 ffio_wfourcc(pb, "cbmp");
2443 avio_wb32(pb, 0); /* version = 0 & flags = 0 */
2444 avio_wb32(pb, 0); /* layout */
2445 avio_wb32(pb, spherical_mapping->padding); /* padding */
2446 break;
2447 }
2448 update_size(pb, proj_pos);
2449
2450 return update_size(pb, sv3d_pos);
2451}
2452
2454{
2455 return av_rescale(q.num, b, q.den);
2456}
2457
2459 const AVStereo3D *stereo3d)
2460{
2461 if (!stereo3d->horizontal_field_of_view.num)
2462 return;
2463
2464 avio_wb32(pb, 12); /* size */
2465 ffio_wfourcc(pb, "hfov");
2467}
2468
2470 const AVSphericalMapping *spherical_mapping)
2471{
2472 avio_wb32(pb, 24); /* size */
2473 ffio_wfourcc(pb, "proj");
2474 avio_wb32(pb, 16); /* size */
2475 ffio_wfourcc(pb, "prji");
2476 avio_wb32(pb, 0); /* version + flags */
2477
2478 switch (spherical_mapping->projection) {
2480 ffio_wfourcc(pb, "rect");
2481 break;
2483 ffio_wfourcc(pb, "equi");
2484 break;
2486 ffio_wfourcc(pb, "hequ");
2487 break;
2489 ffio_wfourcc(pb, "fish");
2490 break;
2491 default:
2492 av_assert0(0);
2493 }
2494}
2495
2497 const AVStereo3D *stereo3d)
2498{
2499 int64_t pos = avio_tell(pb);
2500 int view = 0;
2501
2502 avio_wb32(pb, 0); /* size */
2503 ffio_wfourcc(pb, "eyes");
2504
2505 // stri is mandatory
2506 avio_wb32(pb, 13); /* size */
2507 ffio_wfourcc(pb, "stri");
2508 avio_wb32(pb, 0); /* version + flags */
2509 switch (stereo3d->view) {
2511 view |= 1 << 0;
2512 break;
2514 view |= 1 << 1;
2515 break;
2517 view |= (1 << 0) | (1 << 1);
2518 break;
2519 }
2520 view |= !!(stereo3d->flags & AV_STEREO3D_FLAG_INVERT) << 3;
2521 avio_w8(pb, view);
2522
2523 // hero is optional
2524 if (stereo3d->primary_eye != AV_PRIMARY_EYE_NONE) {
2525 avio_wb32(pb, 13); /* size */
2526 ffio_wfourcc(pb, "hero");
2527 avio_wb32(pb, 0); /* version + flags */
2528 avio_w8(pb, stereo3d->primary_eye);
2529 }
2530
2531 // it's not clear if cams is mandatory or optional
2532 if (stereo3d->baseline) {
2533 avio_wb32(pb, 24); /* size */
2534 ffio_wfourcc(pb, "cams");
2535 avio_wb32(pb, 16); /* size */
2536 ffio_wfourcc(pb, "blin");
2537 avio_wb32(pb, 0); /* version + flags */
2538 avio_wb32(pb, stereo3d->baseline);
2539 }
2540
2541 // it's not clear if cmfy is mandatory or optional
2542 if (stereo3d->horizontal_disparity_adjustment.num) {
2543 avio_wb32(pb, 24); /* size */
2544 ffio_wfourcc(pb, "cmfy");
2545 avio_wb32(pb, 16); /* size */
2546 ffio_wfourcc(pb, "dadj");
2547 avio_wb32(pb, 0); /* version + flags */
2549 }
2550
2551 return update_size(pb, pos);
2552}
2553
2555 const AVStereo3D *stereo3d,
2556 const AVSphericalMapping *spherical_mapping)
2557{
2558 int64_t pos;
2559
2560 if (spherical_mapping &&
2561 spherical_mapping->projection != AV_SPHERICAL_RECTILINEAR &&
2562 spherical_mapping->projection != AV_SPHERICAL_EQUIRECTANGULAR &&
2563 spherical_mapping->projection != AV_SPHERICAL_HALF_EQUIRECTANGULAR &&
2564 spherical_mapping->projection != AV_SPHERICAL_FISHEYE) {
2565 av_log(s, AV_LOG_WARNING, "Unsupported projection %d. proj not written.\n",
2566 spherical_mapping->projection);
2567 spherical_mapping = NULL;
2568 }
2569
2570 if (stereo3d && (stereo3d->type == AV_STEREO3D_2D ||
2571 (!(stereo3d->flags & AV_STEREO3D_FLAG_INVERT) &&
2572 stereo3d->view == AV_STEREO3D_VIEW_UNSPEC &&
2573 stereo3d->primary_eye == AV_PRIMARY_EYE_NONE &&
2574 !stereo3d->baseline &&
2575 !stereo3d->horizontal_disparity_adjustment.num))) {
2576 av_log(s, AV_LOG_WARNING, "Unsupported stereo 3d metadata. eyes not written.\n");
2577 stereo3d = NULL;
2578 }
2579
2580 if (!spherical_mapping && !stereo3d)
2581 return 0;
2582
2583 pos = avio_tell(pb);
2584 avio_wb32(pb, 0); /* size */
2585 ffio_wfourcc(pb, "vexu");
2586
2587 if (spherical_mapping)
2588 mov_write_vexu_proj_tag(s, pb, spherical_mapping);
2589
2590 if (stereo3d)
2591 mov_write_eyes_tag(s, pb, stereo3d);
2592
2593 return update_size(pb, pos);
2594}
2595
2597{
2598 uint8_t buf[ISOM_DVCC_DVVC_SIZE];
2599
2600 avio_wb32(pb, 32); /* size = 8 + 24 */
2601 if (dovi->dv_profile > 10)
2602 ffio_wfourcc(pb, "dvwC");
2603 else if (dovi->dv_profile > 7)
2604 ffio_wfourcc(pb, "dvvC");
2605 else
2606 ffio_wfourcc(pb, "dvcC");
2607
2608 ff_isom_put_dvcc_dvvc(s, buf, dovi);
2609 avio_write(pb, buf, sizeof(buf));
2610
2611 return 32; /* 8 + 24 */
2612}
2613
2615{
2616 avio_wb32(pb, 8 + sd->size);
2617 ffio_wfourcc(pb, "hvcE");
2618 avio_write(pb, sd->data, sd->size);
2619 return 8 + sd->size;
2620}
2621
2623 uint32_t top, uint32_t bottom,
2624 uint32_t left, uint32_t right)
2625{
2626 uint32_t cropped_width = track->par->width - left - right;
2627 uint32_t cropped_height = track->height - top - bottom;
2628 AVRational horizOff =
2629 av_sub_q((AVRational) { track->par->width - cropped_width, 2 },
2630 (AVRational) { left, 1 });
2631 AVRational vertOff =
2632 av_sub_q((AVRational) { track->height - cropped_height, 2 },
2633 (AVRational) { top, 1 });
2634
2635 avio_wb32(pb, 40);
2636 ffio_wfourcc(pb, "clap");
2637 avio_wb32(pb, cropped_width); /* apertureWidthN */
2638 avio_wb32(pb, 1); /* apertureWidthD */
2639 avio_wb32(pb, cropped_height); /* apertureHeightN */
2640 avio_wb32(pb, 1); /* apertureHeightD */
2641
2642 avio_wb32(pb, -horizOff.num);
2643 avio_wb32(pb, horizOff.den);
2644 avio_wb32(pb, -vertOff.num);
2645 avio_wb32(pb, vertOff.den);
2646
2647 return 40;
2648}
2649
2651{
2652 AVRational sar;
2653 av_reduce(&sar.num, &sar.den, track->par->sample_aspect_ratio.num,
2654 track->par->sample_aspect_ratio.den, INT_MAX);
2655
2656 avio_wb32(pb, 16);
2657 ffio_wfourcc(pb, "pasp");
2658 avio_wb32(pb, sar.num);
2659 avio_wb32(pb, sar.den);
2660 return 16;
2661}
2662
2663static int mov_write_gama_tag(AVFormatContext *s, AVIOContext *pb, MOVTrack *track, double gamma)
2664{
2665 uint32_t gama = 0;
2666 if (gamma <= 0.0)
2668 av_log(s, AV_LOG_DEBUG, "gamma value %g\n", gamma);
2669
2670 if (gamma > 1e-6) {
2671 gama = (uint32_t)lrint((double)(1<<16) * gamma);
2672 av_log(s, AV_LOG_DEBUG, "writing gama value %"PRId32"\n", gama);
2673
2674 av_assert0(track->mode == MODE_MOV);
2675 avio_wb32(pb, 12);
2676 ffio_wfourcc(pb, "gama");
2677 avio_wb32(pb, gama);
2678 return 12;
2679 } else {
2680 av_log(s, AV_LOG_WARNING, "gamma value unknown, unable to write gama atom\n");
2681 }
2682 return 0;
2683}
2684
2685static int mov_write_colr_tag(AVIOContext *pb, MOVTrack *track, int prefer_icc)
2686{
2687 int64_t pos = avio_tell(pb);
2688
2689 // Ref (MOV): https://developer.apple.com/library/mac/technotes/tn2162/_index.html#//apple_ref/doc/uid/DTS40013070-CH1-TNTAG9
2690 // Ref (MP4): ISO/IEC 14496-12:2012
2691
2692 if (prefer_icc) {
2696
2697 if (sd) {
2698 avio_wb32(pb, 12 + sd->size);
2699 ffio_wfourcc(pb, "colr");
2700 ffio_wfourcc(pb, "prof");
2701 avio_write(pb, sd->data, sd->size);
2702 return 12 + sd->size;
2703 }
2704 else {
2705 av_log(NULL, AV_LOG_INFO, "no ICC profile found, will write nclx/nclc colour info instead\n");
2706 }
2707 }
2708
2709 /* We should only ever be called for MOV, MP4 and AVIF. */
2710 av_assert0(track->mode == MODE_MOV || track->mode == MODE_MP4 ||
2711 track->mode == MODE_AVIF);
2712
2713 avio_wb32(pb, 0); /* size */
2714 ffio_wfourcc(pb, "colr");
2715 if (track->mode == MODE_MP4 || track->mode == MODE_AVIF)
2716 ffio_wfourcc(pb, "nclx");
2717 else
2718 ffio_wfourcc(pb, "nclc");
2719 // Do not try to guess the color info if it is AVCOL_PRI_UNSPECIFIED.
2720 // e.g., Dolby Vision for Apple devices should be set to AVCOL_PRI_UNSPECIFIED. See
2721 // https://developer.apple.com/av-foundation/High-Dynamic-Range-Metadata-for-Apple-Devices.pdf
2722 avio_wb16(pb, track->par->color_primaries);
2723 avio_wb16(pb, track->par->color_trc);
2724 avio_wb16(pb, track->par->color_space);
2725 if (track->mode == MODE_MP4 || track->mode == MODE_AVIF) {
2726 int full_range = track->par->color_range == AVCOL_RANGE_JPEG;
2727 avio_w8(pb, full_range << 7);
2728 }
2729
2730 return update_size(pb, pos);
2731}
2732
2734{
2735 const AVPacketSideData *side_data;
2736 const AVContentLightMetadata *content_light_metadata;
2737
2741 if (!side_data) {
2742 return 0;
2743 }
2744 content_light_metadata = (const AVContentLightMetadata*)side_data->data;
2745
2746 avio_wb32(pb, 12); // size
2747 ffio_wfourcc(pb, "clli");
2748 avio_wb16(pb, content_light_metadata->MaxCLL);
2749 avio_wb16(pb, content_light_metadata->MaxFALL);
2750 return 12;
2751}
2752
2754{
2755 const int chroma_den = 50000;
2756 const int luma_den = 10000;
2757 const AVPacketSideData *side_data;
2759
2763 if (side_data)
2764 metadata = (const AVMasteringDisplayMetadata*)side_data->data;
2765 if (!metadata || !metadata->has_primaries || !metadata->has_luminance) {
2766 return 0;
2767 }
2768
2769 avio_wb32(pb, 32); // size
2770 ffio_wfourcc(pb, "mdcv");
2771 avio_wb16(pb, rescale_rational(metadata->display_primaries[1][0], chroma_den));
2772 avio_wb16(pb, rescale_rational(metadata->display_primaries[1][1], chroma_den));
2773 avio_wb16(pb, rescale_rational(metadata->display_primaries[2][0], chroma_den));
2774 avio_wb16(pb, rescale_rational(metadata->display_primaries[2][1], chroma_den));
2775 avio_wb16(pb, rescale_rational(metadata->display_primaries[0][0], chroma_den));
2776 avio_wb16(pb, rescale_rational(metadata->display_primaries[0][1], chroma_den));
2777 avio_wb16(pb, rescale_rational(metadata->white_point[0], chroma_den));
2778 avio_wb16(pb, rescale_rational(metadata->white_point[1], chroma_den));
2779 avio_wb32(pb, rescale_rational(metadata->max_luminance, luma_den));
2780 avio_wb32(pb, rescale_rational(metadata->min_luminance, luma_den));
2781 return 32;
2782}
2783
2785{
2786 const int illuminance_den = 10000;
2787 const int ambient_den = 50000;
2788 const AVPacketSideData *side_data;
2789 const AVAmbientViewingEnvironment *ambient;
2790
2791
2795
2796 if (!side_data)
2797 return 0;
2798
2799 ambient = (const AVAmbientViewingEnvironment*)side_data->data;
2800 if (!ambient || !ambient->ambient_illuminance.num)
2801 return 0;
2802
2803 avio_wb32(pb, 16); // size
2804 ffio_wfourcc(pb, "amve");
2805 avio_wb32(pb, rescale_rational(ambient->ambient_illuminance, illuminance_den));
2806 avio_wb16(pb, rescale_rational(ambient->ambient_light_x, ambient_den));
2807 avio_wb16(pb, rescale_rational(ambient->ambient_light_y, ambient_den));
2808 return 16;
2809}
2810
2811static void find_compressor(char * compressor_name, int len, MOVTrack *track)
2812{
2813 AVDictionaryEntry *encoder;
2814 int xdcam_res = (track->par->width == 1280 && track->par->height == 720)
2815 || (track->par->width == 1440 && track->par->height == 1080)
2816 || (track->par->width == 1920 && track->par->height == 1080);
2817
2818 if ((track->mode == MODE_AVIF ||
2819 track->mode == MODE_MOV ||
2820 track->mode == MODE_MP4) &&
2821 (encoder = av_dict_get(track->st->metadata, "encoder", NULL, 0))) {
2822 av_strlcpy(compressor_name, encoder->value, 32);
2823 } else if (track->par->codec_id == AV_CODEC_ID_MPEG2VIDEO && xdcam_res) {
2825 AVStream *st = track->st;
2826 int rate = defined_frame_rate(NULL, st);
2827 av_strlcatf(compressor_name, len, "XDCAM");
2828 if (track->par->format == AV_PIX_FMT_YUV422P) {
2829 av_strlcatf(compressor_name, len, " HD422");
2830 } else if(track->par->width == 1440) {
2831 av_strlcatf(compressor_name, len, " HD");
2832 } else
2833 av_strlcatf(compressor_name, len, " EX");
2834
2835 av_strlcatf(compressor_name, len, " %d%c", track->par->height, interlaced ? 'i' : 'p');
2836
2837 av_strlcatf(compressor_name, len, "%d", rate * (interlaced + 1));
2838 }
2839}
2840
2842{
2843 int64_t pos = avio_tell(pb);
2844 // Write sane defaults:
2845 // all_ref_pics_intra = 0 : all samples can use any type of reference.
2846 // intra_pred_used = 1 : intra prediction may or may not be used.
2847 // max_ref_per_pic = 15 : reserved value to indicate that any number of
2848 // reference images can be used.
2849 uint8_t ccstValue = (0 << 7) | /* all_ref_pics_intra */
2850 (1 << 6) | /* intra_pred_used */
2851 (15 << 2); /* max_ref_per_pic */
2852 avio_wb32(pb, 0); /* size */
2853 ffio_wfourcc(pb, "ccst");
2854 avio_wb32(pb, 0); /* Version & flags */
2855 avio_w8(pb, ccstValue);
2856 avio_wb24(pb, 0); /* reserved */
2857 return update_size(pb, pos);
2858}
2859
2860static int mov_write_aux_tag(AVIOContext *pb, const char *aux_type)
2861{
2862 int64_t pos = avio_tell(pb);
2863 avio_wb32(pb, 0); /* size */
2864 ffio_wfourcc(pb, aux_type);
2865 avio_wb32(pb, 0); /* Version & flags */
2866 avio_write(pb, "urn:mpeg:mpegB:cicp:systems:auxiliary:alpha\0", 44);
2867 return update_size(pb, pos);
2868}
2869
2871{
2872 int ret = AVERROR_BUG;
2873 int64_t pos = avio_tell(pb);
2874 const AVPacketSideData *sd;
2875 char compressor_name[32] = { 0 };
2876 int avid = 0;
2877
2878 int uncompressed_ycbcr = ((track->par->codec_id == AV_CODEC_ID_RAWVIDEO && track->par->format == AV_PIX_FMT_UYVY422)
2879 || (track->par->codec_id == AV_CODEC_ID_RAWVIDEO && track->par->format == AV_PIX_FMT_YUYV422)
2880 || (track->par->codec_id == AV_CODEC_ID_RAWVIDEO && track->par->format == AV_PIX_FMT_VYU444)
2881 || (track->par->codec_id == AV_CODEC_ID_RAWVIDEO && track->par->format == AV_PIX_FMT_UYVA)
2882 || (track->par->codec_id == AV_CODEC_ID_RAWVIDEO && track->par->format == AV_PIX_FMT_V30XLE)
2883 || track->par->codec_id == AV_CODEC_ID_V210);
2884
2885 avio_wb32(pb, 0); /* size */
2886 if (mov->encryption_scheme != MOV_ENC_NONE) {
2887 ffio_wfourcc(pb, "encv");
2888 } else {
2889 avio_wl32(pb, track->tag); // store it byteswapped
2890 }
2891 avio_wb32(pb, 0); /* Reserved */
2892 avio_wb16(pb, 0); /* Reserved */
2893 avio_wb16(pb, 1); /* Data-reference index */
2894
2895 if (uncompressed_ycbcr) {
2896 avio_wb16(pb, 2); /* Codec stream version */
2897 } else {
2898 avio_wb16(pb, 0); /* Codec stream version */
2899 }
2900 avio_wb16(pb, 0); /* Codec stream revision (=0) */
2901 if (track->mode == MODE_MOV) {
2902 ffio_wfourcc(pb, "FFMP"); /* Vendor */
2903 if (track->par->codec_id == AV_CODEC_ID_RAWVIDEO || uncompressed_ycbcr) {
2904 avio_wb32(pb, 0); /* Temporal Quality */
2905 avio_wb32(pb, 0x400); /* Spatial Quality = lossless*/
2906 } else {
2907 avio_wb32(pb, 0x200); /* Temporal Quality = normal */
2908 avio_wb32(pb, 0x200); /* Spatial Quality = normal */
2909 }
2910 } else {
2911 ffio_fill(pb, 0, 3 * 4); /* Reserved */
2912 }
2913 avio_wb16(pb, track->par->width); /* Video width */
2914 avio_wb16(pb, track->height); /* Video height */
2915 avio_wb32(pb, 0x00480000); /* Horizontal resolution 72dpi */
2916 avio_wb32(pb, 0x00480000); /* Vertical resolution 72dpi */
2917 avio_wb32(pb, 0); /* Data size (= 0) */
2918 avio_wb16(pb, 1); /* Frame count (= 1) */
2919
2920 find_compressor(compressor_name, 32, track);
2921 avio_w8(pb, strlen(compressor_name));
2922 avio_write(pb, compressor_name, 31);
2923
2924 if (track->mode == MODE_MOV && track->par->codec_id == AV_CODEC_ID_V210)
2925 avio_wb16(pb, 0x18);
2926 else if (track->mode == MODE_MOV && track->par->bits_per_coded_sample)
2927 avio_wb16(pb, track->par->bits_per_coded_sample |
2928 (track->par->format == AV_PIX_FMT_GRAY8 ? 0x20 : 0));
2929 else
2930 avio_wb16(pb, 0x18); /* Reserved */
2931
2932 if (track->mode == MODE_MOV && track->par->format == AV_PIX_FMT_PAL8) {
2933 int pal_size, i;
2934 avio_wb16(pb, 0); /* Color table ID */
2935 avio_wb32(pb, 0); /* Color table seed */
2936 avio_wb16(pb, 0x8000); /* Color table flags */
2937 if (track->par->bits_per_coded_sample < 0 || track->par->bits_per_coded_sample > 8)
2938 return AVERROR(EINVAL);
2939 pal_size = 1 << track->par->bits_per_coded_sample;
2940 avio_wb16(pb, pal_size - 1); /* Color table size (zero-relative) */
2941 for (i = 0; i < pal_size; i++) {
2942 uint32_t rgb = track->palette[i];
2943 uint16_t r = (rgb >> 16) & 0xff;
2944 uint16_t g = (rgb >> 8) & 0xff;
2945 uint16_t b = rgb & 0xff;
2946 avio_wb16(pb, 0);
2947 avio_wb16(pb, (r << 8) | r);
2948 avio_wb16(pb, (g << 8) | g);
2949 avio_wb16(pb, (b << 8) | b);
2950 }
2951 } else
2952 avio_wb16(pb, 0xffff); /* Reserved */
2953
2954 if (track->tag == MKTAG('m','p','4','v'))
2955 mov_write_esds_tag(pb, track);
2956 else if (track->par->codec_id == AV_CODEC_ID_H263)
2958 else if (track->par->codec_id == AV_CODEC_ID_AVUI ||
2959 track->par->codec_id == AV_CODEC_ID_SVQ3) {
2960 mov_write_extradata_tag(pb, track);
2961 avio_wb32(pb, 0);
2962 } else if (track->par->codec_id == AV_CODEC_ID_DNXHD) {
2963 mov_write_avid_tag(pb, track);
2964 avid = 1;
2965 } else if (track->par->codec_id == AV_CODEC_ID_HEVC) {
2966 mov_write_hvcc_tag(mov->fc, pb, track);
2968 ret = mov_write_lhvc_tag(mov->fc, pb, track);
2969 if (ret < 0)
2970 av_log(mov->fc, AV_LOG_WARNING, "Not writing 'lhvC' atom for multilayer stream.\n");
2971 }
2972 } else if (track->par->codec_id == AV_CODEC_ID_VVC)
2973 mov_write_vvcc_tag(pb, track);
2974 else if (track->par->codec_id == AV_CODEC_ID_H264 && !TAG_IS_AVCI(track->tag)) {
2975 mov_write_avcc_tag(pb, track);
2976 if (track->mode == MODE_IPOD)
2978 }
2979 else if (track->par->codec_id ==AV_CODEC_ID_EVC) {
2980 mov_write_evcc_tag(pb, track);
2981 } else if (track->par->codec_id == AV_CODEC_ID_LCEVC) {
2982 mov_write_lvcc_tag(mov->fc, pb, track);
2983 } else if (track->par->codec_id ==AV_CODEC_ID_APV) {
2984 mov_write_apvc_tag(mov->fc, pb, track);
2985 } else if (track->par->codec_id == AV_CODEC_ID_VP9) {
2986 mov_write_vpcc_tag(mov->fc, pb, track);
2987 } else if (track->par->codec_id == AV_CODEC_ID_AV1) {
2988 mov_write_av1c_tag(pb, track);
2989 } else if (track->par->codec_id == AV_CODEC_ID_VC1 && track->extradata_size[track->last_stsd_index] > 0)
2990 mov_write_dvc1_tag(pb, track);
2991 else if (track->par->codec_id == AV_CODEC_ID_VP6F ||
2992 track->par->codec_id == AV_CODEC_ID_VP6A) {
2993 /* Don't write any potential extradata here - the cropping
2994 * is signalled via the normal width/height fields. */
2995 } else if (track->par->codec_id == AV_CODEC_ID_R10K) {
2996 if (track->par->codec_tag == MKTAG('R','1','0','k'))
2997 mov_write_dpxe_tag(pb, track);
2998 } else if (track->par->codec_id == AV_CODEC_ID_AVS3) {
2999 mov_write_av3c_tag(pb, track);
3000 } else if (track->extradata_size[track->last_stsd_index] > 0)
3001 mov_write_glbl_tag(pb, track);
3002
3003 if (track->par->codec_id != AV_CODEC_ID_H264 &&
3004 track->par->codec_id != AV_CODEC_ID_MPEG4 &&
3005 track->par->codec_id != AV_CODEC_ID_DNXHD) {
3006 int field_order = track->par->field_order;
3007
3008 if (field_order != AV_FIELD_UNKNOWN)
3009 mov_write_fiel_tag(pb, track, field_order);
3010 }
3011
3012 if (mov->flags & FF_MOV_FLAG_WRITE_GAMA) {
3013 if (track->mode == MODE_MOV)
3014 mov_write_gama_tag(s, pb, track, mov->gamma);
3015 else
3016 av_log(mov->fc, AV_LOG_WARNING, "Not writing 'gama' atom. Format is not MOV.\n");
3017 }
3018 if (track->mode == MODE_MOV || track->mode == MODE_MP4 || track->mode == MODE_AVIF) {
3019 int has_color_info = track->par->color_primaries != AVCOL_PRI_UNSPECIFIED &&
3020 track->par->color_trc != AVCOL_TRC_UNSPECIFIED &&
3022 if (has_color_info || mov->flags & FF_MOV_FLAG_WRITE_COLR ||
3025 int prefer_icc = mov->flags & FF_MOV_FLAG_PREFER_ICC || !has_color_info;
3026 mov_write_colr_tag(pb, track, prefer_icc);
3027 }
3028 } else if (mov->flags & FF_MOV_FLAG_WRITE_COLR) {
3029 av_log(mov->fc, AV_LOG_WARNING, "Not writing 'colr' atom. Format is not MOV or MP4 or AVIF.\n");
3030 }
3031
3032 if (track->mode == MODE_MOV || track->mode == MODE_MP4) {
3033 mov_write_clli_tag(pb, track);
3034 mov_write_mdcv_tag(pb, track);
3035 mov_write_amve_tag(pb, track);
3036 }
3037
3038 if (track->mode == MODE_MP4) {
3042 const AVPacketSideData *spherical_mapping = av_packet_side_data_get(track->st->codecpar->coded_side_data,
3045 if (stereo_3d && mov->fc->strict_std_compliance <= FF_COMPLIANCE_UNOFFICIAL)
3046 mov_write_st3d_tag(s, pb, (AVStereo3D*)stereo_3d->data);
3047 else if (stereo_3d)
3048 av_log(s, AV_LOG_WARNING, "Writing supported 'st3d' metadata requires -strict unofficial.\n");
3049 if (spherical_mapping && mov->fc->strict_std_compliance <= FF_COMPLIANCE_UNOFFICIAL)
3050 mov_write_sv3d_tag(mov->fc, pb, (AVSphericalMapping*)spherical_mapping->data);
3051 else if (spherical_mapping)
3052 av_log(s, AV_LOG_WARNING, "Writing supported 'sv3d' metadata requires -strict unofficial.\n");
3053 }
3054
3055 if (track->mode == MODE_MOV || (track->mode == MODE_MP4 &&
3057 const AVStereo3D *stereo3d = NULL;
3058 const AVSphericalMapping *spherical_mapping = NULL;
3059
3063 if (sd)
3064 stereo3d = (AVStereo3D *)sd->data;
3065
3069 if (sd)
3070 spherical_mapping = (AVSphericalMapping *)sd->data;
3071
3072 if (stereo3d || spherical_mapping)
3073 mov_write_vexu_tag(s, pb, stereo3d, spherical_mapping);
3074 if (stereo3d)
3075 mov_write_hfov_tag(s, pb, stereo3d);
3076 }
3077
3078 if (track->mode == MODE_MP4) {
3082 if (dovi && mov->fc->strict_std_compliance <= FF_COMPLIANCE_UNOFFICIAL) {
3084 } else if (dovi) {
3085 av_log(mov->fc, AV_LOG_WARNING, "Not writing 'dvcC'/'dvvC' box. Requires -strict unofficial.\n");
3086 }
3087
3091 if (hvce && mov->fc->strict_std_compliance <= FF_COMPLIANCE_UNOFFICIAL) {
3092 mov_write_hvce_tag(pb, hvce);
3093 } else if (hvce) {
3094 av_log(mov->fc, AV_LOG_WARNING, "Not writing 'hvcE' box. Requires -strict unofficial.\n");
3095 }
3096 }
3097
3098 if (track->par->sample_aspect_ratio.den && track->par->sample_aspect_ratio.num) {
3099 mov_write_pasp_tag(pb, track);
3100 }
3101
3105 if (sd && sd->size >= sizeof(uint32_t) * 4) {
3106 uint64_t top = AV_RL32(sd->data + 0);
3107 uint64_t bottom = AV_RL32(sd->data + 4);
3108 uint64_t left = AV_RL32(sd->data + 8);
3109 uint64_t right = AV_RL32(sd->data + 12);
3110
3111 if ((left + right) >= track->par->width ||
3112 (top + bottom) >= track->height) {
3113 av_log(s, AV_LOG_ERROR, "Invalid cropping dimensions in stream side data\n");
3114 return AVERROR(EINVAL);
3115 }
3116 if (top || bottom || left || right)
3117 mov_write_clap_tag(pb, track, top, bottom, left, right);
3118 } else if (uncompressed_ycbcr)
3119 mov_write_clap_tag(pb, track, 0, 0, 0, 0);
3120
3121 if (mov->encryption_scheme != MOV_ENC_NONE) {
3123 }
3124
3125 if (mov->write_btrt &&
3126 ((ret = mov_write_btrt_tag(pb, track)) < 0))
3127 return ret;
3128
3129 /* extra padding for avid stsd */
3130 /* https://developer.apple.com/library/mac/documentation/QuickTime/QTFF/QTFFChap2/qtff2.html#//apple_ref/doc/uid/TP40000939-CH204-61112 */
3131 if (avid)
3132 avio_wb32(pb, 0);
3133
3134 if (track->mode == MODE_AVIF) {
3136 if (mov->nb_streams > 0 && track == &mov->tracks[1])
3137 mov_write_aux_tag(pb, "auxi");
3138 }
3139
3140 return update_size(pb, pos);
3141}
3142
3144{
3145 int64_t pos = avio_tell(pb);
3146 avio_wb32(pb, 0); /* size */
3147 ffio_wfourcc(pb, "rtp ");
3148 avio_wb32(pb, 0); /* Reserved */
3149 avio_wb16(pb, 0); /* Reserved */
3150 avio_wb16(pb, 1); /* Data-reference index */
3151
3152 avio_wb16(pb, 1); /* Hint track version */
3153 avio_wb16(pb, 1); /* Highest compatible version */
3154 avio_wb32(pb, track->max_packet_size); /* Max packet size */
3155
3156 avio_wb32(pb, 12); /* size */
3157 ffio_wfourcc(pb, "tims");
3158 avio_wb32(pb, track->timescale);
3159
3160 return update_size(pb, pos);
3161}
3162
3163static int mov_write_source_reference_tag(AVIOContext *pb, MOVTrack *track, const char *reel_name)
3164{
3165 uint64_t str_size =strlen(reel_name);
3166 int64_t pos = avio_tell(pb);
3167
3168 if (str_size >= UINT16_MAX){
3169 av_log(NULL, AV_LOG_ERROR, "reel_name length %"PRIu64" is too large\n", str_size);
3170 avio_wb16(pb, 0);
3171 return AVERROR(EINVAL);
3172 }
3173
3174 avio_wb32(pb, 0); /* size */
3175 ffio_wfourcc(pb, "name"); /* Data format */
3176 avio_wb16(pb, str_size); /* string size */
3177 avio_wb16(pb, track->language); /* langcode */
3178 avio_write(pb, reel_name, str_size); /* reel name */
3179 return update_size(pb,pos);
3180}
3181
3183{
3184 int64_t pos = avio_tell(pb);
3185#if 1
3186 int frame_duration;
3187 int nb_frames;
3189
3190 if (!track->st->avg_frame_rate.num || !track->st->avg_frame_rate.den) {
3191 av_log(NULL, AV_LOG_ERROR, "avg_frame_rate not set for tmcd track.\n");
3192 return AVERROR(EINVAL);
3193 } else {
3194 frame_duration = av_rescale(track->timescale, track->st->avg_frame_rate.den, track->st->avg_frame_rate.num);
3195 nb_frames = ROUNDED_DIV(track->st->avg_frame_rate.num, track->st->avg_frame_rate.den);
3196 }
3197
3198 if (nb_frames > 255) {
3199 av_log(NULL, AV_LOG_ERROR, "fps %d is too large\n", nb_frames);
3200 return AVERROR(EINVAL);
3201 }
3202
3203 avio_wb32(pb, 0); /* size */
3204 ffio_wfourcc(pb, "tmcd"); /* Data format */
3205 avio_wb32(pb, 0); /* Reserved */
3206 avio_wb32(pb, 1); /* Data reference index */
3207 avio_wb32(pb, 0); /* Flags */
3208 avio_wb32(pb, track->timecode_flags); /* Flags (timecode) */
3209 avio_wb32(pb, track->timescale); /* Timescale */
3210 avio_wb32(pb, frame_duration); /* Frame duration */
3211 avio_w8(pb, nb_frames); /* Number of frames */
3212 avio_w8(pb, 0); /* Reserved */
3213
3214 t = av_dict_get(track->st->metadata, "reel_name", NULL, 0);
3215 if (t && utf8len(t->value) && track->mode != MODE_MP4)
3217 else
3218 avio_wb16(pb, 0); /* zero size */
3219#else
3220
3221 avio_wb32(pb, 0); /* size */
3222 ffio_wfourcc(pb, "tmcd"); /* Data format */
3223 avio_wb32(pb, 0); /* Reserved */
3224 avio_wb32(pb, 1); /* Data reference index */
3225 if (track->par->extradata_size)
3226 avio_write(pb, track->par->extradata, track->par->extradata_size);
3227#endif
3228 return update_size(pb, pos);
3229}
3230
3231static int mov_write_gpmd_tag(AVIOContext *pb, const MOVTrack *track)
3232{
3233 int64_t pos = avio_tell(pb);
3234 avio_wb32(pb, 0); /* size */
3235 ffio_wfourcc(pb, "gpmd");
3236 avio_wb32(pb, 0); /* Reserved */
3237 avio_wb16(pb, 0); /* Reserved */
3238 avio_wb16(pb, 1); /* Data-reference index */
3239 avio_wb32(pb, 0); /* Reserved */
3240 return update_size(pb, pos);
3241}
3242
3244{
3245 int64_t pos = avio_tell(pb);
3246 int ret = 0;
3247 avio_wb32(pb, 0); /* size */
3248 ffio_wfourcc(pb, "stsd");
3249 avio_wb32(pb, 0); /* version & flags */
3250 avio_wb32(pb, track->stsd_count);
3251
3252 int stsd_index_back = track->last_stsd_index;
3253 for (track->last_stsd_index = 0;
3254 track->last_stsd_index < track->stsd_count;
3255 track->last_stsd_index++) {
3256 if (track->par->codec_type == AVMEDIA_TYPE_VIDEO)
3257 ret = mov_write_video_tag(s, pb, mov, track);
3258 else if (track->par->codec_type == AVMEDIA_TYPE_AUDIO)
3259 ret = mov_write_audio_tag(s, pb, mov, track);
3260 else if (track->par->codec_type == AVMEDIA_TYPE_SUBTITLE)
3261 ret = mov_write_subtitle_tag(s, pb, track);
3262 else if (track->par->codec_tag == MKTAG('r','t','p',' '))
3263 ret = mov_write_rtp_tag(pb, track);
3264 else if (track->par->codec_tag == MKTAG('t','m','c','d'))
3265 ret = mov_write_tmcd_tag(pb, track);
3266 else if (track->par->codec_tag == MKTAG('g','p','m','d'))
3267 ret = mov_write_gpmd_tag(pb, track);
3268
3269 if (ret < 0)
3270 return ret;
3271 }
3272
3273 track->last_stsd_index = stsd_index_back;
3274
3275 return update_size_and_version(pb, pos, track->entry_version);
3276}
3277
3279{
3280 MOVMuxContext *mov = s->priv_data;
3281 MOVCtts *ctts_entries;
3282 uint32_t entries = 0;
3283 uint32_t atom_size;
3284 int i;
3285
3286 ctts_entries = av_malloc_array((track->entry + 1), sizeof(*ctts_entries)); /* worst case */
3287 if (!ctts_entries)
3288 return AVERROR(ENOMEM);
3289 ctts_entries[0].count = 1;
3290 ctts_entries[0].offset = track->cluster[0].cts;
3291 for (i = 1; i < track->entry; i++) {
3292 if (track->cluster[i].cts == ctts_entries[entries].offset) {
3293 ctts_entries[entries].count++; /* compress */
3294 } else {
3295 entries++;
3296 ctts_entries[entries].offset = track->cluster[i].cts;
3297 ctts_entries[entries].count = 1;
3298 }
3299 }
3300 entries++; /* last one */
3301 atom_size = 16 + (entries * 8);
3302 avio_wb32(pb, atom_size); /* size */
3303 ffio_wfourcc(pb, "ctts");
3305 avio_w8(pb, 1); /* version */
3306 else
3307 avio_w8(pb, 0); /* version */
3308 avio_wb24(pb, 0); /* flags */
3309 avio_wb32(pb, entries); /* entry count */
3310 for (i = 0; i < entries; i++) {
3311 avio_wb32(pb, ctts_entries[i].count);
3312 avio_wb32(pb, ctts_entries[i].offset);
3313 }
3314 av_free(ctts_entries);
3315 return atom_size;
3316}
3317
3318/* Time to sample atom */
3320{
3321 MOVStts *stts_entries = NULL;
3322 uint32_t entries = -1;
3323 uint32_t atom_size;
3324 int i;
3325
3326 if (track->par->codec_type == AVMEDIA_TYPE_AUDIO && !track->audio_vbr) {
3327 stts_entries = av_malloc(sizeof(*stts_entries)); /* one entry */
3328 if (!stts_entries)
3329 return AVERROR(ENOMEM);
3330 stts_entries[0].count = track->sample_count;
3331 stts_entries[0].duration = 1;
3332 entries = 1;
3333 } else {
3334 if (track->entry) {
3335 stts_entries = av_malloc_array(track->entry, sizeof(*stts_entries)); /* worst case */
3336 if (!stts_entries)
3337 return AVERROR(ENOMEM);
3338 }
3339 for (i = 0; i < track->entry; i++) {
3340 int duration = get_cluster_duration(track, i);
3341#if CONFIG_IAMFENC
3342 if (track->iamf && track->par->codec_id == AV_CODEC_ID_OPUS)
3343 duration = av_rescale(duration, 48000, track->par->sample_rate);
3344#endif
3345 if (i && duration == stts_entries[entries].duration) {
3346 stts_entries[entries].count++; /* compress */
3347 } else {
3348 entries++;
3349 stts_entries[entries].duration = duration;
3350 stts_entries[entries].count = 1;
3351 }
3352 }
3353 entries++; /* last one */
3354 }
3355 atom_size = 16 + (entries * 8);
3356 avio_wb32(pb, atom_size); /* size */
3357 ffio_wfourcc(pb, "stts");
3358 avio_wb32(pb, 0); /* version & flags */
3359 avio_wb32(pb, entries); /* entry count */
3360 for (i = 0; i < entries; i++) {
3361 avio_wb32(pb, stts_entries[i].count);
3362 avio_wb32(pb, stts_entries[i].duration);
3363 }
3364 av_free(stts_entries);
3365 return atom_size;
3366}
3367
3369{
3370 avio_wb32(pb, 28); /* size */
3371 ffio_wfourcc(pb, "dref");
3372 avio_wb32(pb, 0); /* version & flags */
3373 avio_wb32(pb, 1); /* entry count */
3374
3375 avio_wb32(pb, 0xc); /* size */
3376 //FIXME add the alis and rsrc atom
3377 ffio_wfourcc(pb, "url ");
3378 avio_wb32(pb, 1); /* version & flags */
3379
3380 return 28;
3381}
3382
3384{
3385 struct sgpd_entry {
3386 int count;
3387 int16_t roll_distance;
3388 int group_description_index;
3389 };
3390
3391 struct sgpd_entry *sgpd_entries = NULL;
3392 int entries = -1;
3393 int group = 0;
3394 int i, j;
3395
3396 const int OPUS_SEEK_PREROLL_MS = 80;
3397 int roll_samples = av_rescale_q(OPUS_SEEK_PREROLL_MS,
3398 (AVRational){1, 1000},
3399 (AVRational){1, 48000});
3400
3401 if (!track->entry)
3402 return 0;
3403
3404 sgpd_entries = av_malloc_array(track->entry, sizeof(*sgpd_entries));
3405 if (!sgpd_entries)
3406 return AVERROR(ENOMEM);
3407
3409
3410 if (track->par->codec_id == AV_CODEC_ID_OPUS) {
3411 for (i = 0; i < track->entry; i++) {
3412 int roll_samples_remaining = roll_samples;
3413 int distance = 0;
3414 for (j = i - 1; j >= 0; j--) {
3415 roll_samples_remaining -= get_cluster_duration(track, j);
3416 distance++;
3417 if (roll_samples_remaining <= 0)
3418 break;
3419 }
3420 /* We don't have enough preceding samples to compute a valid
3421 roll_distance here, so this sample can't be independently
3422 decoded. */
3423 if (roll_samples_remaining > 0)
3424 distance = 0;
3425 /* Verify distance is a maximum of 32 (2.5ms) packets. */
3426 if (distance > 32) {
3427 av_freep(&sgpd_entries);
3428 return AVERROR_INVALIDDATA;
3429 }
3430 if (i && distance == sgpd_entries[entries].roll_distance) {
3431 sgpd_entries[entries].count++;
3432 } else {
3433 entries++;
3434 sgpd_entries[entries].count = 1;
3435 sgpd_entries[entries].roll_distance = distance;
3436 sgpd_entries[entries].group_description_index = distance ? ++group : 0;
3437 }
3438 }
3439 } else {
3440 entries++;
3441 sgpd_entries[entries].count = track->sample_count;
3442 sgpd_entries[entries].roll_distance = 1;
3443 sgpd_entries[entries].group_description_index = ++group;
3444 }
3445 entries++;
3446
3447 if (!group) {
3448 av_free(sgpd_entries);
3449 return 0;
3450 }
3451
3452 /* Write sgpd tag */
3453 avio_wb32(pb, 24 + (group * 2)); /* size */
3454 ffio_wfourcc(pb, "sgpd");
3455 avio_wb32(pb, 1 << 24); /* fullbox */
3456 ffio_wfourcc(pb, "roll");
3457 avio_wb32(pb, 2); /* default_length */
3458 avio_wb32(pb, group); /* entry_count */
3459 for (i = 0; i < entries; i++) {
3460 if (sgpd_entries[i].group_description_index) {
3461 avio_wb16(pb, -sgpd_entries[i].roll_distance); /* roll_distance */
3462 }
3463 }
3464
3465 /* Write sbgp tag */
3466 avio_wb32(pb, 20 + (entries * 8)); /* size */
3467 ffio_wfourcc(pb, "sbgp");
3468 avio_wb32(pb, 0); /* fullbox */
3469 ffio_wfourcc(pb, "roll");
3470 avio_wb32(pb, entries); /* entry_count */
3471 for (i = 0; i < entries; i++) {
3472 avio_wb32(pb, sgpd_entries[i].count); /* sample_count */
3473 avio_wb32(pb, sgpd_entries[i].group_description_index); /* group_description_index */
3474 }
3475
3476 av_free(sgpd_entries);
3477 return 0;
3478}
3479
3481{
3482 int64_t pos = avio_tell(pb);
3483 int ret = 0;
3484
3485 avio_wb32(pb, 0); /* size */
3486 ffio_wfourcc(pb, "stbl");
3487 if ((ret = mov_write_stsd_tag(s, pb, mov, track)) < 0)
3488 return ret;
3489 mov_write_stts_tag(pb, track);
3490 if ((track->par->codec_type == AVMEDIA_TYPE_VIDEO ||
3491 track->par->codec_id == AV_CODEC_ID_TRUEHD ||
3493 (track->par->codec_id == AV_CODEC_ID_AAC && track->par->profile == AV_PROFILE_AAC_USAC) ||
3494 track->par->codec_tag == MKTAG('r','t','p',' ')) &&
3495 track->has_keyframes && track->has_keyframes < track->entry)
3497 if (track->par->codec_type == AVMEDIA_TYPE_VIDEO && track->has_disposable && track->entry)
3498 mov_write_sdtp_tag(pb, track);
3499 if (track->mode == MODE_MOV && track->flags & MOV_TRACK_STPS)
3501 if (track->par->codec_type == AVMEDIA_TYPE_VIDEO &&
3502 track->flags & MOV_TRACK_CTTS && track->entry) {
3503
3504 if ((ret = mov_write_ctts_tag(s, pb, track)) < 0)
3505 return ret;
3506 }
3507 mov_write_stsc_tag(pb, track);
3508 mov_write_stsz_tag(pb, track);
3509 mov_write_stco_tag(pb, track);
3510 if (track->cenc.aes_ctr && !(mov->flags & FF_MOV_FLAG_FRAGMENT)) {
3511 ff_mov_cenc_write_stbl_atoms(&track->cenc, pb, 0);
3512 }
3513 if (track->par->codec_id == AV_CODEC_ID_OPUS || track->par->codec_id == AV_CODEC_ID_AAC) {
3515 }
3516 return update_size(pb, pos);
3517}
3518
3520{
3521 int64_t pos = avio_tell(pb);
3522 avio_wb32(pb, 0); /* size */
3523 ffio_wfourcc(pb, "dinf");
3525 return update_size(pb, pos);
3526}
3527
3529{
3530 avio_wb32(pb, 12);
3531 ffio_wfourcc(pb, "nmhd");
3532 avio_wb32(pb, 0);
3533 return 12;
3534}
3535
3537{
3538 avio_wb32(pb, 12);
3539 ffio_wfourcc(pb, "sthd");
3540 avio_wb32(pb, 0);
3541 return 12;
3542}
3543
3545{
3546 int64_t pos = avio_tell(pb);
3547 const char *font = "Lucida Grande";
3548 avio_wb32(pb, 0); /* size */
3549 ffio_wfourcc(pb, "tcmi"); /* timecode media information atom */
3550 avio_wb32(pb, 0); /* version & flags */
3551 avio_wb16(pb, 0); /* text font */
3552 avio_wb16(pb, 0); /* text face */
3553 avio_wb16(pb, 12); /* text size */
3554 avio_wb16(pb, 0); /* (unknown, not in the QT specs...) */
3555 avio_wb16(pb, 0x0000); /* text color (red) */
3556 avio_wb16(pb, 0x0000); /* text color (green) */
3557 avio_wb16(pb, 0x0000); /* text color (blue) */
3558 avio_wb16(pb, 0xffff); /* background color (red) */
3559 avio_wb16(pb, 0xffff); /* background color (green) */
3560 avio_wb16(pb, 0xffff); /* background color (blue) */
3561 avio_w8(pb, strlen(font)); /* font len (part of the pascal string) */
3562 avio_write(pb, font, strlen(font)); /* font name */
3563 return update_size(pb, pos);
3564}
3565
3567{
3568 int64_t pos = avio_tell(pb);
3569 avio_wb32(pb, 0); /* size */
3570 ffio_wfourcc(pb, "gmhd");
3571 avio_wb32(pb, 0x18); /* gmin size */
3572 ffio_wfourcc(pb, "gmin");/* generic media info */
3573 avio_wb32(pb, 0); /* version & flags */
3574 avio_wb16(pb, 0x40); /* graphics mode = */
3575 avio_wb16(pb, 0x8000); /* opColor (r?) */
3576 avio_wb16(pb, 0x8000); /* opColor (g?) */
3577 avio_wb16(pb, 0x8000); /* opColor (b?) */
3578 avio_wb16(pb, 0); /* balance */
3579 avio_wb16(pb, 0); /* reserved */
3580
3581 /*
3582 * This special text atom is required for
3583 * Apple Quicktime chapters. The contents
3584 * don't appear to be documented, so the
3585 * bytes are copied verbatim.
3586 */
3587 if (track->tag != MKTAG('c','6','0','8')) {
3588 avio_wb32(pb, 0x2C); /* size */
3589 ffio_wfourcc(pb, "text");
3590 avio_wb16(pb, 0x01);
3591 avio_wb32(pb, 0x00);
3592 avio_wb32(pb, 0x00);
3593 avio_wb32(pb, 0x00);
3594 avio_wb32(pb, 0x01);
3595 avio_wb32(pb, 0x00);
3596 avio_wb32(pb, 0x00);
3597 avio_wb32(pb, 0x00);
3598 avio_wb32(pb, 0x00004000);
3599 avio_wb16(pb, 0x0000);
3600 }
3601
3602 if (track->par->codec_tag == MKTAG('t','m','c','d')) {
3603 int64_t tmcd_pos = avio_tell(pb);
3604 avio_wb32(pb, 0); /* size */
3605 ffio_wfourcc(pb, "tmcd");
3606 mov_write_tcmi_tag(pb, track);
3607 update_size(pb, tmcd_pos);
3608 } else if (track->par->codec_tag == MKTAG('g','p','m','d')) {
3609 int64_t gpmd_pos = avio_tell(pb);
3610 avio_wb32(pb, 0); /* size */
3611 ffio_wfourcc(pb, "gpmd");
3612 avio_wb32(pb, 0); /* version */
3613 update_size(pb, gpmd_pos);
3614 }
3615 return update_size(pb, pos);
3616}
3617
3619{
3620 avio_wb32(pb, 16); /* size */
3621 ffio_wfourcc(pb, "smhd");
3622 avio_wb32(pb, 0); /* version & flags */
3623 avio_wb16(pb, 0); /* reserved (balance, normally = 0) */
3624 avio_wb16(pb, 0); /* reserved */
3625 return 16;
3626}
3627
3628static uint16_t mov_graphics_mode(MOVTrack *track)
3629{
3630 if (track->mode != MODE_MOV)
3631 return 0; /* ISO/IEC 14496-12 doesn't define any other modes */
3632
3633 switch (track->par->alpha_mode) {
3634 default: return MOV_GRAPHICS_MODE_COPY;
3637 }
3638}
3639
3641{
3642 avio_wb32(pb, 0x14); /* size (always 0x14) */
3643 ffio_wfourcc(pb, "vmhd");
3644 avio_wb32(pb, 0x01); /* version & flags */
3645 avio_wb16(pb, mov_graphics_mode(track));
3646 for (int i = 0; i < 3; i++)
3647 avio_wb16(pb, 0); /* opcolor */
3648 return 0x14;
3649}
3650
3651static int is_clcp_track(MOVTrack *track)
3652{
3653 return track->tag == MKTAG('c','7','0','8') ||
3654 track->tag == MKTAG('c','6','0','8');
3655}
3656
3658{
3659 MOVMuxContext *mov = s->priv_data;
3660 const char *hdlr, *descr = NULL, *hdlr_type = NULL;
3661 int64_t pos = avio_tell(pb);
3662 size_t descr_len;
3663
3664 hdlr = "dhlr";
3665 hdlr_type = "url ";
3666 descr = "DataHandler";
3667
3668 if (track) {
3669 hdlr = (track->mode == MODE_MOV) ? "mhlr" : "\0\0\0\0";
3670 if (track->par->codec_type == AVMEDIA_TYPE_VIDEO) {
3671 if (track->mode == MODE_AVIF) {
3672 hdlr_type = (track == &mov->tracks[0]) ? "pict" : "auxv";
3673 descr = "PictureHandler";
3674 } else {
3675 hdlr_type = "vide";
3676 descr = "VideoHandler";
3677 }
3678 } else if (track->par->codec_type == AVMEDIA_TYPE_AUDIO) {
3679 hdlr_type = "soun";
3680 descr = "SoundHandler";
3681 } else if (track->par->codec_type == AVMEDIA_TYPE_SUBTITLE) {
3682 if (is_clcp_track(track)) {
3683 hdlr_type = "clcp";
3684 descr = "ClosedCaptionHandler";
3685 } else {
3686 if (track->tag == MKTAG('t','x','3','g')) {
3687 hdlr_type = "sbtl";
3688 } else if (track->tag == MKTAG('m','p','4','s')) {
3689 hdlr_type = "subp";
3690 } else if (track->tag == MOV_MP4_TTML_TAG) {
3691 hdlr_type = "subt";
3692 } else {
3693 hdlr_type = "text";
3694 }
3695 descr = "SubtitleHandler";
3696 }
3697 } else if (track->par->codec_tag == MKTAG('r','t','p',' ')) {
3698 hdlr_type = "hint";
3699 descr = "HintHandler";
3700 } else if (track->par->codec_tag == MKTAG('t','m','c','d')) {
3701 hdlr_type = "tmcd";
3702 descr = "TimeCodeHandler";
3703 } else if (track->par->codec_tag == MKTAG('g','p','m','d')) {
3704 hdlr_type = "meta";
3705 descr = "GoPro MET"; // GoPro Metadata
3706 } else {
3708 "Unknown hdlr_type for %s, writing dummy values\n",
3709 av_fourcc2str(track->par->codec_tag));
3710 }
3711 if (track->st) {
3712 // hdlr.name is used by some players to identify the content title
3713 // of the track. So if an alternate handler description is
3714 // specified, use it.
3716 t = av_dict_get(track->st->metadata, "handler_name", NULL, 0);
3717 if (t && utf8len(t->value))
3718 descr = t->value;
3719 }
3720 }
3721
3722 if (mov->empty_hdlr_name) /* expressly allowed by QTFF and not prohibited in ISO 14496-12 8.4.3.3 */
3723 descr = "";
3724
3725 avio_wb32(pb, 0); /* size */
3726 ffio_wfourcc(pb, "hdlr");
3727 avio_wb32(pb, 0); /* Version & flags */
3728 avio_write(pb, hdlr, 4); /* handler */
3729 ffio_wfourcc(pb, hdlr_type); /* handler type */
3730 avio_wb32(pb, 0); /* reserved */
3731 avio_wb32(pb, 0); /* reserved */
3732 avio_wb32(pb, 0); /* reserved */
3733 descr_len = strlen(descr);
3734 if (!track || track->mode == MODE_MOV)
3735 avio_w8(pb, descr_len); /* pascal string */
3736 avio_write(pb, descr, descr_len); /* handler description */
3737 if (track && track->mode != MODE_MOV)
3738 avio_w8(pb, 0); /* c string */
3739 return update_size(pb, pos);
3740}
3741
3742static int mov_write_pitm_tag(AVIOContext *pb, int item_id)
3743{
3744 int64_t pos = avio_tell(pb);
3745 avio_wb32(pb, 0); /* size */
3746 ffio_wfourcc(pb, "pitm");
3747 avio_wb32(pb, 0); /* Version & flags */
3748 avio_wb16(pb, item_id); /* item_id */
3749 return update_size(pb, pos);
3750}
3751
3753{
3754 int64_t pos = avio_tell(pb);
3755 avio_wb32(pb, 0); /* size */
3756 ffio_wfourcc(pb, "iloc");
3757 avio_wb32(pb, 0); /* Version & flags */
3758 avio_w8(pb, (4 << 4) + 4); /* offset_size(4) and length_size(4) */
3759 avio_w8(pb, 0); /* base_offset_size(4) and reserved(4) */
3760 avio_wb16(pb, mov->nb_streams); /* item_count */
3761
3762 for (int i = 0; i < mov->nb_streams; i++) {
3763 avio_wb16(pb, i + 1); /* item_id */
3764 avio_wb16(pb, 0); /* data_reference_index */
3765 avio_wb16(pb, 1); /* extent_count */
3766 mov->avif_extent_pos[i] = avio_tell(pb);
3767 avio_wb32(pb, 0); /* extent_offset (written later) */
3768 // For animated AVIF, we simply write the first packet's size.
3769 avio_wb32(pb, mov->avif_extent_length[i]); /* extent_length */
3770 }
3771
3772 return update_size(pb, pos);
3773}
3774
3776{
3777 int64_t iinf_pos = avio_tell(pb);
3778 avio_wb32(pb, 0); /* size */
3779 ffio_wfourcc(pb, "iinf");
3780 avio_wb32(pb, 0); /* Version & flags */
3781 avio_wb16(pb, mov->nb_streams); /* entry_count */
3782
3783 for (int i = 0; i < mov->nb_streams; i++) {
3784 int64_t infe_pos = avio_tell(pb);
3785 avio_wb32(pb, 0); /* size */
3786 ffio_wfourcc(pb, "infe");
3787 avio_w8(pb, 0x2); /* Version */
3788 avio_wb24(pb, 0); /* flags */
3789 avio_wb16(pb, i + 1); /* item_id */
3790 avio_wb16(pb, 0); /* item_protection_index */
3791 avio_write(pb, "av01", 4); /* item_type */
3792 avio_write(pb, !i ? "Color\0" : "Alpha\0", 6); /* item_name */
3793 update_size(pb, infe_pos);
3794 }
3795
3796 return update_size(pb, iinf_pos);
3797}
3798
3799
3801{
3802 int64_t auxl_pos;
3803 int64_t iref_pos = avio_tell(pb);
3804 avio_wb32(pb, 0); /* size */
3805 ffio_wfourcc(pb, "iref");
3806 avio_wb32(pb, 0); /* Version & flags */
3807
3808 auxl_pos = avio_tell(pb);
3809 avio_wb32(pb, 0); /* size */
3810 ffio_wfourcc(pb, "auxl");
3811 avio_wb16(pb, 2); /* from_item_ID */
3812 avio_wb16(pb, 1); /* reference_count */
3813 avio_wb16(pb, 1); /* to_item_ID */
3814 update_size(pb, auxl_pos);
3815
3816 return update_size(pb, iref_pos);
3817}
3818
3820 int stream_index)
3821{
3822 int64_t pos = avio_tell(pb);
3823 avio_wb32(pb, 0); /* size */
3824 ffio_wfourcc(pb, "ispe");
3825 avio_wb32(pb, 0); /* Version & flags */
3826 avio_wb32(pb, s->streams[stream_index]->codecpar->width); /* image_width */
3827 avio_wb32(pb, s->streams[stream_index]->codecpar->height); /* image_height */
3828 return update_size(pb, pos);
3829}
3830
3832 int stream_index)
3833{
3834 int64_t pos = avio_tell(pb);
3835 const AVPixFmtDescriptor *pixdesc =
3836 av_pix_fmt_desc_get(s->streams[stream_index]->codecpar->format);
3837 avio_wb32(pb, 0); /* size */
3838 ffio_wfourcc(pb, "pixi");
3839 avio_wb32(pb, 0); /* Version & flags */
3840 avio_w8(pb, pixdesc->nb_components); /* num_channels */
3841 for (int i = 0; i < pixdesc->nb_components; ++i) {
3842 avio_w8(pb, pixdesc->comp[i].depth); /* bits_per_channel */
3843 }
3844 return update_size(pb, pos);
3845}
3846
3848{
3849 int64_t pos = avio_tell(pb);
3850 avio_wb32(pb, 0); /* size */
3851 ffio_wfourcc(pb, "ipco");
3852 for (int i = 0; i < mov->nb_streams; i++) {
3853 mov_write_ispe_tag(pb, mov, s, i);
3854 mov_write_pixi_tag(pb, mov, s, i);
3855 mov_write_av1c_tag(pb, &mov->tracks[i]);
3856 if (!i)
3857 mov_write_colr_tag(pb, &mov->tracks[0], 0);
3858 else
3859 mov_write_aux_tag(pb, "auxC");
3860 }
3861 return update_size(pb, pos);
3862}
3863
3865{
3866 int64_t pos = avio_tell(pb);
3867 avio_wb32(pb, 0); /* size */
3868 ffio_wfourcc(pb, "ipma");
3869 avio_wb32(pb, 0); /* Version & flags */
3870 avio_wb32(pb, mov->nb_streams); /* entry_count */
3871
3872 for (int i = 0, index = 1; i < mov->nb_streams; i++) {
3873 avio_wb16(pb, i + 1); /* item_ID */
3874 avio_w8(pb, 4); /* association_count */
3875
3876 // ispe association.
3877 avio_w8(pb, index++); /* essential and property_index */
3878 // pixi association.
3879 avio_w8(pb, index++); /* essential and property_index */
3880 // av1C association.
3881 avio_w8(pb, 0x80 | index++); /* essential and property_index */
3882 // colr/auxC association.
3883 avio_w8(pb, index++); /* essential and property_index */
3884 }
3885 return update_size(pb, pos);
3886}
3887
3889{
3890 int64_t pos = avio_tell(pb);
3891 avio_wb32(pb, 0); /* size */
3892 ffio_wfourcc(pb, "iprp");
3893 mov_write_ipco_tag(pb, mov, s);
3894 mov_write_ipma_tag(pb, mov, s);
3895 return update_size(pb, pos);
3896}
3897
3899{
3900 /* This atom must be present, but leaving the values at zero
3901 * seems harmless. */
3902 avio_wb32(pb, 28); /* size */
3903 ffio_wfourcc(pb, "hmhd");
3904 avio_wb32(pb, 0); /* version, flags */
3905 avio_wb16(pb, 0); /* maxPDUsize */
3906 avio_wb16(pb, 0); /* avgPDUsize */
3907 avio_wb32(pb, 0); /* maxbitrate */
3908 avio_wb32(pb, 0); /* avgbitrate */
3909 avio_wb32(pb, 0); /* reserved */
3910 return 28;
3911}
3912
3914{
3915 int64_t pos = avio_tell(pb);
3916 int ret;
3917
3918 avio_wb32(pb, 0); /* size */
3919 ffio_wfourcc(pb, "minf");
3920 if (track->par->codec_type == AVMEDIA_TYPE_VIDEO)
3921 mov_write_vmhd_tag(pb, track);
3922 else if (track->par->codec_type == AVMEDIA_TYPE_AUDIO)
3924 else if (track->par->codec_type == AVMEDIA_TYPE_SUBTITLE) {
3925 if (track->tag == MKTAG('t','e','x','t') || is_clcp_track(track)) {
3926 mov_write_gmhd_tag(pb, track);
3927 } else if (track->tag == MOV_MP4_TTML_TAG) {
3929 } else {
3931 }
3932 } else if (track->tag == MKTAG('r','t','p',' ')) {
3934 } else if (track->tag == MKTAG('t','m','c','d')) {
3935 if (track->mode != MODE_MOV)
3937 else
3938 mov_write_gmhd_tag(pb, track);
3939 } else if (track->tag == MKTAG('g','p','m','d')) {
3940 mov_write_gmhd_tag(pb, track);
3941 }
3942 if (track->mode == MODE_MOV) /* ISO 14496-12 8.4.3.1 specifies hdlr only within mdia or meta boxes */
3945 if ((ret = mov_write_stbl_tag(s, pb, mov, track)) < 0)
3946 return ret;
3947 return update_size(pb, pos);
3948}
3949
3950static void get_pts_range(MOVMuxContext *mov, MOVTrack *track,
3951 int64_t *start, int64_t *end, int elst, int mdhd)
3952{
3953 if (track->tag == MKTAG('t','m','c','d') && mov->nb_meta_tmcd && track->nb_src_track) {
3954 // tmcd tracks gets track_duration set in mov_write_moov_tag from
3955 // another track's duration, while the end_pts may be left at zero.
3956 // Calculate the pts duration for that track instead.
3957 get_pts_range(mov, &mov->tracks[*track->src_track], start, end, elst, mdhd);
3958 *start = av_rescale(*start, track->timescale,
3959 mov->tracks[*track->src_track].timescale);
3960 *end = av_rescale(*end, track->timescale,
3961 mov->tracks[*track->src_track].timescale);
3962 return;
3963 }
3964 if (!mdhd && track->end_pts != AV_NOPTS_VALUE &&
3965 track->start_dts != AV_NOPTS_VALUE &&
3966 track->start_cts != AV_NOPTS_VALUE) {
3967 *start = track->start_dts + track->start_cts;
3968 *end = elst ? track->elst_end_pts : track->end_pts;
3969 return;
3970 }
3971 *start = 0;
3972 *end = track->track_duration;
3973}
3974
3976{
3977 int64_t start, end;
3978 get_pts_range(mov, track, &start, &end, 0, 1);
3979 return end - start;
3980}
3981
3982// Calculate the actual duration of the track, after edits.
3983// If it starts with a pts < 0, that is removed by the edit list.
3984// If it starts with a pts > 0, the edit list adds a delay before that.
3985// Thus, with edit lists enabled, the post-edit output of the file is
3986// starting with pts=0.
3988{
3989 int64_t start, end;
3990 get_pts_range(mov, track, &start, &end, 0, 0);
3991 if (mov->use_editlist != 0)
3992 start = 0;
3993 return end - start;
3994}
3995
3997{
3998 int64_t start, end;
3999 get_pts_range(mov, track, &start, &end, 1, 0);
4000 return end - start;
4001}
4002
4004{
4005 if (track && track->mode == MODE_ISM)
4006 return 1;
4007 if (duration < INT32_MAX)
4008 return 0;
4009 return 1;
4010}
4011
4013 MOVTrack *track)
4014{
4016 int version = mov_mdhd_mvhd_tkhd_version(mov, track, duration);
4017
4018 (version == 1) ? avio_wb32(pb, 44) : avio_wb32(pb, 32); /* size */
4019 ffio_wfourcc(pb, "mdhd");
4020 avio_w8(pb, version);
4021 avio_wb24(pb, 0); /* flags */
4022 if (version == 1) {
4023 avio_wb64(pb, track->time);
4024 avio_wb64(pb, track->time);
4025 } else {
4026 avio_wb32(pb, track->time); /* creation time */
4027 avio_wb32(pb, track->time); /* modification time */
4028 }
4029 avio_wb32(pb, track->timescale); /* time scale (sample rate for audio) */
4030 if (!track->entry && mov->mode == MODE_ISM)
4031 (version == 1) ? avio_wb64(pb, UINT64_C(0xffffffffffffffff)) : avio_wb32(pb, 0xffffffff);
4032 else if (!track->entry)
4033 (version == 1) ? avio_wb64(pb, 0) : avio_wb32(pb, 0);
4034 else
4035 (version == 1) ? avio_wb64(pb, duration) : avio_wb32(pb, duration); /* duration */
4036 avio_wb16(pb, track->language); /* language */
4037 avio_wb16(pb, 0); /* reserved (quality) */
4038
4039 if (version != 0 && track->mode == MODE_MOV) {
4041 "FATAL error, file duration too long for timebase, this file will not be\n"
4042 "playable with QuickTime. Choose a different timebase with "
4043 "-video_track_timescale or a different container format\n");
4044 }
4045
4046 return 32;
4047}
4048
4050 MOVMuxContext *mov, MOVTrack *track)
4051{
4052 int64_t pos = avio_tell(pb);
4053 int ret;
4054
4055 avio_wb32(pb, 0); /* size */
4056 ffio_wfourcc(pb, "mdia");
4057 mov_write_mdhd_tag(pb, mov, track);
4058 mov_write_hdlr_tag(s, pb, track);
4059 if ((ret = mov_write_minf_tag(s, pb, mov, track)) < 0)
4060 return ret;
4061 return update_size(pb, pos);
4062}
4063
4064/* transformation matrix
4065 |a b u|
4066 |c d v|
4067 |tx ty w| */
4068static void write_matrix(AVIOContext *pb, int16_t a, int16_t b, int16_t c,
4069 int16_t d, int16_t tx, int16_t ty)
4070{
4071 avio_wb32(pb, a << 16); /* 16.16 format */
4072 avio_wb32(pb, b << 16); /* 16.16 format */
4073 avio_wb32(pb, 0); /* u in 2.30 format */
4074 avio_wb32(pb, c << 16); /* 16.16 format */
4075 avio_wb32(pb, d << 16); /* 16.16 format */
4076 avio_wb32(pb, 0); /* v in 2.30 format */
4077 avio_wb32(pb, tx << 16); /* 16.16 format */
4078 avio_wb32(pb, ty << 16); /* 16.16 format */
4079 avio_wb32(pb, 1 << 30); /* w in 2.30 format */
4080}
4081
4083 MOVTrack *track, AVStream *st)
4084{
4086 mov->movie_timescale, track->timescale,
4087 AV_ROUND_UP);
4088 int version;
4090 int group = 0;
4091
4092 uint32_t *display_matrix = NULL;
4093 int i;
4094
4095 if (mov->mode == MODE_AVIF)
4096 if (!mov->avif_loop_count)
4097 duration = INT64_MAX;
4098 else
4099 duration *= mov->avif_loop_count;
4100
4101 if (st) {
4102 const AVPacketSideData *sd;
4103 if (mov->per_stream_grouping)
4104 group = st->index;
4105 else
4106 group = st->codecpar->codec_type;
4107
4111 if (sd && sd->size == 9 * sizeof(*display_matrix))
4112 display_matrix = (uint32_t *)sd->data;
4113 }
4114
4115 if (track->flags & MOV_TRACK_ENABLED)
4117
4119
4120 (version == 1) ? avio_wb32(pb, 104) : avio_wb32(pb, 92); /* size */
4121 ffio_wfourcc(pb, "tkhd");
4122 avio_w8(pb, version);
4123 avio_wb24(pb, flags);
4124 if (version == 1) {
4125 avio_wb64(pb, track->time);
4126 avio_wb64(pb, track->time);
4127 } else {
4128 avio_wb32(pb, track->time); /* creation time */
4129 avio_wb32(pb, track->time); /* modification time */
4130 }
4131 avio_wb32(pb, track->track_id); /* track-id */
4132 avio_wb32(pb, 0); /* reserved */
4133 if (!track->entry && mov->mode == MODE_ISM)
4134 (version == 1) ? avio_wb64(pb, UINT64_C(0xffffffffffffffff)) : avio_wb32(pb, 0xffffffff);
4135 else if (!track->entry)
4136 (version == 1) ? avio_wb64(pb, 0) : avio_wb32(pb, 0);
4137 else
4138 (version == 1) ? avio_wb64(pb, duration) : avio_wb32(pb, duration);
4139
4140 avio_wb32(pb, 0); /* reserved */
4141 avio_wb32(pb, 0); /* reserved */
4142 avio_wb16(pb, 0); /* layer */
4143 avio_wb16(pb, group); /* alternate group) */
4144 /* Volume, only for audio */
4145 if (track->par->codec_type == AVMEDIA_TYPE_AUDIO)
4146 avio_wb16(pb, 0x0100);
4147 else
4148 avio_wb16(pb, 0);
4149 avio_wb16(pb, 0); /* reserved */
4150
4151 /* Matrix structure */
4152 if (display_matrix) {
4153 for (i = 0; i < 9; i++)
4154 avio_wb32(pb, display_matrix[i]);
4155 } else {
4156 write_matrix(pb, 1, 0, 0, 1, 0, 0);
4157 }
4158 /* Track width and height, for visual only */
4159 if (st && (track->par->codec_type == AVMEDIA_TYPE_VIDEO ||
4160 track->par->codec_type == AVMEDIA_TYPE_SUBTITLE)) {
4161 int64_t track_width_1616;
4162 if (track->mode == MODE_MOV || track->mode == MODE_AVIF) {
4163 track_width_1616 = track->par->width * 0x10000ULL;
4164 } else {
4165 track_width_1616 = av_rescale(st->sample_aspect_ratio.num,
4166 track->par->width * 0x10000LL,
4168 if (!track_width_1616 ||
4169 track->height != track->par->height ||
4170 track_width_1616 > UINT32_MAX)
4171 track_width_1616 = track->par->width * 0x10000ULL;
4172 }
4173 if (track_width_1616 > UINT32_MAX) {
4174 av_log(mov->fc, AV_LOG_WARNING, "track width is too large\n");
4175 track_width_1616 = 0;
4176 }
4177 avio_wb32(pb, track_width_1616);
4178 if (track->height > 0xFFFF) {
4179 av_log(mov->fc, AV_LOG_WARNING, "track height is too large\n");
4180 avio_wb32(pb, 0);
4181 } else
4182 avio_wb32(pb, track->height * 0x10000U);
4183 } else {
4184 avio_wb32(pb, 0);
4185 avio_wb32(pb, 0);
4186 }
4187 return 0x5c;
4188}
4189
4191{
4193 track->par->sample_aspect_ratio.den);
4194
4195 int64_t pos = avio_tell(pb);
4196
4197 avio_wb32(pb, 0); /* size */
4198 ffio_wfourcc(pb, "tapt");
4199
4200 avio_wb32(pb, 20);
4201 ffio_wfourcc(pb, "clef");
4202 avio_wb32(pb, 0);
4203 avio_wb32(pb, width << 16);
4204 avio_wb32(pb, track->par->height << 16);
4205
4206 avio_wb32(pb, 20);
4207 ffio_wfourcc(pb, "prof");
4208 avio_wb32(pb, 0);
4209 avio_wb32(pb, width << 16);
4210 avio_wb32(pb, track->par->height << 16);
4211
4212 avio_wb32(pb, 20);
4213 ffio_wfourcc(pb, "enof");
4214 avio_wb32(pb, 0);
4215 avio_wb32(pb, track->par->width << 16);
4216 avio_wb32(pb, track->par->height << 16);
4217
4218 return update_size(pb, pos);
4219}
4220
4221// This box is written in the following cases:
4222// * Seems important for the psp playback. Without it the movie seems to hang.
4223// * Used for specifying the looping behavior of animated AVIF (as specified
4224// in Section 9.6 of the HEIF specification ISO/IEC 23008-12).
4226 MOVTrack *track)
4227{
4229 mov->movie_timescale, track->timescale,
4230 AV_ROUND_UP);
4231 int version = duration < INT32_MAX ? 0 : 1;
4232 int entry_size, entry_count, size;
4233 int64_t delay, start_ct = track->start_cts;
4234 int64_t start_dts = track->start_dts;
4235 int flags = 0;
4236
4237 if (track->entry) {
4238 if (start_dts != track->cluster[0].dts || (start_ct != track->cluster[0].cts && track->cluster[0].dts >= 0)) {
4239
4240 av_log(mov->fc, AV_LOG_DEBUG,
4241 "EDTS using dts:%"PRId64" cts:%d instead of dts:%"PRId64" cts:%"PRId64" tid:%d\n",
4242 track->cluster[0].dts, track->cluster[0].cts,
4243 start_dts, start_ct, track->track_id);
4244 start_dts = track->cluster[0].dts;
4245 start_ct = track->cluster[0].cts;
4246 }
4247 }
4248
4249 delay = av_rescale_rnd(start_dts + start_ct, mov->movie_timescale,
4250 track->timescale, AV_ROUND_DOWN);
4251
4252 if (mov->mode == MODE_AVIF) {
4253 delay = 0;
4254 // Section 9.6.3 of ISO/IEC 23008-12: flags specifies repetition of the
4255 // edit list as follows: (flags & 1) equal to 0 specifies that the edit
4256 // list is not repeated, while (flags & 1) equal to 1 specifies that the
4257 // edit list is repeated.
4258 flags = mov->avif_loop_count != 1;
4259 start_ct = 0;
4260 }
4261
4262 version |= delay < INT32_MAX ? 0 : 1;
4263
4264 entry_size = (version == 1) ? 20 : 12;
4265 entry_count = 1 + (delay > 0);
4266 size = 24 + entry_count * entry_size;
4267
4268 /* write the atom data */
4269 avio_wb32(pb, size);
4270 ffio_wfourcc(pb, "edts");
4271 avio_wb32(pb, size - 8);
4272 ffio_wfourcc(pb, "elst");
4273 avio_w8(pb, version);
4274 avio_wb24(pb, flags); /* flags */
4275
4276 avio_wb32(pb, entry_count);
4277 if (delay > 0) { /* add an empty edit to delay presentation */
4278 /* In the positive delay case, the delay includes the cts
4279 * offset, and the second edit list entry below trims out
4280 * the same amount from the actual content. This makes sure
4281 * that the offset last sample is included in the edit
4282 * list duration as well. */
4283 if (version == 1) {
4284 avio_wb64(pb, delay);
4285 avio_wb64(pb, -1);
4286 } else {
4287 avio_wb32(pb, delay);
4288 avio_wb32(pb, -1);
4289 }
4290 avio_wb32(pb, 0x00010000);
4291 } else if (mov->mode != MODE_AVIF) {
4292 /* Avoid accidentally ending up with start_ct = -1 which has got a
4293 * special meaning. Normally start_ct should end up positive or zero
4294 * here, but use FFMIN in case dts is a small positive integer
4295 * rounded to 0 when represented in movie timescale units. */
4296 av_assert0(av_rescale_rnd(start_dts, mov->movie_timescale, track->timescale, AV_ROUND_DOWN) <= 0);
4297 start_ct = -FFMIN(start_dts, 0);
4298
4299#if CONFIG_IAMFENC
4300 if (track->iamf && track->par->codec_id == AV_CODEC_ID_OPUS)
4301 start_ct = av_rescale(start_ct, 48000, track->par->sample_rate);
4302#endif
4303 /* Note, this delay is calculated from the pts of the first sample,
4304 * ensuring that we don't reduce the duration for cases with
4305 * dts<0 pts=0. */
4306 duration += delay;
4307 }
4308
4309 /* For fragmented files, we don't know the full length yet. Setting
4310 * duration to 0 allows us to only specify the offset, including
4311 * the rest of the content (from all future fragments) without specifying
4312 * an explicit duration.
4313 *
4314 * For hybrid_fragmented during mov_write_trailer (mov->moov_written != 0),
4315 * don't reset duration to zero.
4316 */
4317 if (mov->flags & FF_MOV_FLAG_FRAGMENT &&
4319 duration = 0;
4320
4321 /* duration */
4322 if (version == 1) {
4323 avio_wb64(pb, duration);
4324 avio_wb64(pb, start_ct);
4325 } else {
4326 avio_wb32(pb, duration);
4327 avio_wb32(pb, start_ct);
4328 }
4329 avio_wb32(pb, 0x00010000);
4330 return size;
4331}
4332
4334{
4335 int64_t pos = avio_tell(pb);
4336 avio_wb32(pb, 0); // size placeholder
4337 ffio_wfourcc(pb, "tref");
4338
4339 for (int i = 0; i < track->nb_tref_tags; i++) {
4340 MovTag *tag = &track->tref_tags[i];
4341 avio_wb32(pb, 8 + tag->nb_id * sizeof(*tag->id)); // size (subatom)
4342 avio_wl32(pb, tag->name);
4343 for (int j = 0; j < tag->nb_id; j++)
4344 avio_wb32(pb, tag->id[j]);
4345 }
4346 return update_size(pb, pos);
4347}
4348
4349// goes at the end of each track! ... Critical for PSP playback ("Incompatible data" without it)
4351{
4352 avio_wb32(pb, 0x34); /* size ... reports as 28 in mp4box! */
4353 ffio_wfourcc(pb, "uuid");
4354 ffio_wfourcc(pb, "USMT");
4355 avio_wb32(pb, 0x21d24fce);
4356 avio_wb32(pb, 0xbb88695c);
4357 avio_wb32(pb, 0xfac9c740);
4358 avio_wb32(pb, 0x1c); // another size here!
4359 ffio_wfourcc(pb, "MTDT");
4360 avio_wb32(pb, 0x00010012);
4361 avio_wb32(pb, 0x0a);
4362 avio_wb32(pb, 0x55c40000);
4363 avio_wb32(pb, 0x1);
4364 avio_wb32(pb, 0x0);
4365 return 0x34;
4366}
4367
4369{
4370 AVFormatContext *ctx = track->rtp_ctx;
4371 char buf[1000] = "";
4372 int len;
4373
4374 av_assert0(track->nb_src_track);
4375 ff_sdp_write_media(buf, sizeof(buf), ctx->streams[0], *track->src_track,
4376 NULL, NULL, 0, 0, ctx);
4377 av_strlcatf(buf, sizeof(buf), "a=control:streamid=%d\r\n", track->track_id);
4378 len = strlen(buf);
4379
4380 avio_wb32(pb, len + 24);
4381 ffio_wfourcc(pb, "udta");
4382 avio_wb32(pb, len + 16);
4383 ffio_wfourcc(pb, "hnti");
4384 avio_wb32(pb, len + 8);
4385 ffio_wfourcc(pb, "sdp ");
4386 avio_write(pb, buf, len);
4387 return len + 24;
4388}
4389
4391 const char *tag, const char *str)
4392{
4393 int64_t pos = avio_tell(pb);
4394 AVDictionaryEntry *t = av_dict_get(st->metadata, str, NULL, 0);
4395 if (!t || !utf8len(t->value))
4396 return 0;
4397
4398 avio_wb32(pb, 0); /* size */
4399 ffio_wfourcc(pb, tag); /* type */
4400 avio_write(pb, t->value, strlen(t->value)); /* UTF8 string value */
4401 return update_size(pb, pos);
4402}
4403
4404static int mov_write_track_kind(AVIOContext *pb, const char *scheme_uri,
4405 const char *value)
4406{
4407 int64_t pos = avio_tell(pb);
4408
4409 /* Box|FullBox basics */
4410 avio_wb32(pb, 0); /* size placeholder */
4411 ffio_wfourcc(pb, (const unsigned char *)"kind");
4412 avio_w8(pb, 0); /* version = 0 */
4413 avio_wb24(pb, 0); /* flags = 0 */
4414
4415 /* Required null-terminated scheme URI */
4416 avio_write(pb, (const unsigned char *)scheme_uri,
4417 strlen(scheme_uri));
4418 avio_w8(pb, 0);
4419
4420 /* Optional value string */
4421 if (value && value[0])
4422 avio_write(pb, (const unsigned char *)value,
4423 strlen(value));
4424
4425 avio_w8(pb, 0);
4426
4427 return update_size(pb, pos);
4428}
4429
4431{
4432 int ret = AVERROR_BUG;
4433
4434 for (int i = 0; ff_mov_track_kind_table[i].scheme_uri; i++) {
4436
4437 for (int j = 0; map.value_maps[j].disposition; j++) {
4438 const struct MP4TrackKindValueMapping value_map = map.value_maps[j];
4439 if (!(st->disposition & value_map.disposition))
4440 continue;
4441
4442 if ((ret = mov_write_track_kind(pb, map.scheme_uri, value_map.value)) < 0)
4443 return ret;
4444 }
4445 }
4446
4447 return 0;
4448}
4449
4451 AVStream *st)
4452{
4453 AVIOContext *pb_buf;
4454 int ret, size;
4455 uint8_t *buf;
4456
4457 if (!st)
4458 return 0;
4459
4460 ret = avio_open_dyn_buf(&pb_buf);
4461 if (ret < 0)
4462 return ret;
4463
4464 if (mov->mode & (MODE_MP4|MODE_MOV))
4465 mov_write_track_metadata(pb_buf, st, "name", "title");
4466
4467 if (mov->mode & MODE_MP4) {
4468 if ((ret = mov_write_track_kinds(pb_buf, st)) < 0)
4469 goto end;
4470 }
4471
4472 if ((size = avio_get_dyn_buf(pb_buf, &buf)) > 0) {
4473 avio_wb32(pb, size + 8);
4474 ffio_wfourcc(pb, "udta");
4475 avio_write(pb, buf, size);
4476 }
4477end:
4478 ffio_free_dyn_buf(&pb_buf);
4479
4480 return ret;
4481}
4482
4484 MOVTrack *track, AVStream *st)
4485{
4486 int64_t pos = avio_tell(pb);
4487 int entry_backup = track->entry;
4488 int chunk_backup = track->chunkCount;
4489 int ret;
4490
4491 /* If we want to have an empty moov, but some samples already have been
4492 * buffered (delay_moov), pretend that no samples have been written yet. */
4493 if (mov->flags & FF_MOV_FLAG_EMPTY_MOOV)
4494 track->chunkCount = track->entry = 0;
4495
4496 avio_wb32(pb, 0); /* size */
4497 ffio_wfourcc(pb, "trak");
4498 mov_write_tkhd_tag(pb, mov, track, st);
4499
4500 av_assert2(mov->use_editlist >= 0);
4501
4502 if (track->start_dts != AV_NOPTS_VALUE) {
4503 if (mov->use_editlist)
4504 mov_write_edts_tag(pb, mov, track); // PSP Movies and several other cases require edts box
4505 else if ((track->entry && track->cluster[0].dts) || track->mode == MODE_PSP || is_clcp_track(track))
4506 av_log(mov->fc, AV_LOG_WARNING,
4507 "Not writing any edit list even though one would have been required\n");
4508 }
4509
4510 if (mov->is_animated_avif)
4511 mov_write_edts_tag(pb, mov, track);
4512
4513 if (track->nb_tref_tags)
4514 mov_write_tref_tag(pb, track);
4515
4516 if ((ret = mov_write_mdia_tag(s, pb, mov, track)) < 0)
4517 return ret;
4518 if (track->mode == MODE_PSP)
4519 mov_write_uuid_tag_psp(pb, track); // PSP Movies require this uuid box
4520 if (track->tag == MKTAG('r','t','p',' '))
4521 mov_write_udta_sdp(pb, track);
4522 if (track->mode == MODE_MOV) {
4523 if (track->par->codec_type == AVMEDIA_TYPE_VIDEO) {
4524 double sample_aspect_ratio = av_q2d(st->sample_aspect_ratio);
4525 if (st->sample_aspect_ratio.num && 1.0 != sample_aspect_ratio) {
4526 mov_write_tapt_tag(pb, track);
4527 }
4528 }
4529 if (is_clcp_track(track) && st->sample_aspect_ratio.num) {
4530 mov_write_tapt_tag(pb, track);
4531 }
4532 }
4533 mov_write_track_udta_tag(pb, mov, st);
4534 track->entry = entry_backup;
4535 track->chunkCount = chunk_backup;
4536 return update_size(pb, pos);
4537}
4538
4540{
4541 int i, has_audio = 0, has_video = 0;
4542 int64_t pos = avio_tell(pb);
4543 int audio_profile = mov->iods_audio_profile;
4544 int video_profile = mov->iods_video_profile;
4545 for (i = 0; i < mov->nb_tracks; i++) {
4546 if (mov->tracks[i].entry > 0 || mov->flags & FF_MOV_FLAG_EMPTY_MOOV) {
4547 has_audio |= mov->tracks[i].par->codec_type == AVMEDIA_TYPE_AUDIO;
4548 has_video |= mov->tracks[i].par->codec_type == AVMEDIA_TYPE_VIDEO;
4549 }
4550 }
4551 if (audio_profile < 0)
4552 audio_profile = 0xFF - has_audio;
4553 if (video_profile < 0)
4554 video_profile = 0xFF - has_video;
4555 avio_wb32(pb, 0x0); /* size */
4556 ffio_wfourcc(pb, "iods");
4557 avio_wb32(pb, 0); /* version & flags */
4558 put_descr(pb, 0x10, 7);
4559 avio_wb16(pb, 0x004f);
4560 avio_w8(pb, 0xff);
4561 avio_w8(pb, 0xff);
4562 avio_w8(pb, audio_profile);
4563 avio_w8(pb, video_profile);
4564 avio_w8(pb, 0xff);
4565 return update_size(pb, pos);
4566}
4567
4569{
4570 avio_wb32(pb, 0x20); /* size */
4571 ffio_wfourcc(pb, "trex");
4572 avio_wb32(pb, 0); /* version & flags */
4573 avio_wb32(pb, track->track_id); /* track ID */
4574 avio_wb32(pb, 1); /* default sample description index */
4575 avio_wb32(pb, 0); /* default sample duration */
4576 avio_wb32(pb, 0); /* default sample size */
4577 avio_wb32(pb, 0); /* default sample flags */
4578 return 0;
4579}
4580
4582{
4583 int64_t pos = avio_tell(pb);
4584 int i;
4585 avio_wb32(pb, 0x0); /* size */
4586 ffio_wfourcc(pb, "mvex");
4587 for (i = 0; i < mov->nb_tracks; i++)
4588 mov_write_trex_tag(pb, &mov->tracks[i]);
4589 return update_size(pb, pos);
4590}
4591
4593{
4594 int max_track_id = 1, i;
4595 int64_t max_track_len = 0;
4596 int version;
4597 int timescale;
4598
4599 for (i = 0; i < mov->nb_tracks; i++) {
4600 if (mov->tracks[i].entry > 0 && mov->tracks[i].timescale) {
4601 int64_t max_track_len_temp = av_rescale_rnd(
4602 calc_pts_duration(mov, &mov->tracks[i]),
4603 mov->movie_timescale,
4604 mov->tracks[i].timescale,
4605 AV_ROUND_UP);
4606 if (max_track_len < max_track_len_temp)
4607 max_track_len = max_track_len_temp;
4608 if (max_track_id < mov->tracks[i].track_id)
4609 max_track_id = mov->tracks[i].track_id;
4610 }
4611 }
4612 /* If using delay_moov, make sure the output is the same as if no
4613 * samples had been written yet. */
4614 if (mov->flags & FF_MOV_FLAG_EMPTY_MOOV) {
4615 max_track_len = 0;
4616 max_track_id = 1;
4617 }
4618
4619 version = mov_mdhd_mvhd_tkhd_version(mov, NULL, max_track_len);
4620 avio_wb32(pb, version == 1 ? 120 : 108); /* size */
4621
4622 ffio_wfourcc(pb, "mvhd");
4623 avio_w8(pb, version);
4624 avio_wb24(pb, 0); /* flags */
4625 if (version == 1) {
4626 avio_wb64(pb, mov->time);
4627 avio_wb64(pb, mov->time);
4628 } else {
4629 avio_wb32(pb, mov->time); /* creation time */
4630 avio_wb32(pb, mov->time); /* modification time */
4631 }
4632
4633 timescale = mov->movie_timescale;
4634 if (mov->mode == MODE_AVIF && !timescale)
4635 timescale = mov->tracks[0].timescale;
4636
4637 avio_wb32(pb, timescale);
4638 (version == 1) ? avio_wb64(pb, max_track_len) : avio_wb32(pb, max_track_len); /* duration of longest track */
4639
4640 avio_wb32(pb, 0x00010000); /* reserved (preferred rate) 1.0 = normal */
4641 avio_wb16(pb, 0x0100); /* reserved (preferred volume) 1.0 = normal */
4642 ffio_fill(pb, 0, 2 + 2 * 4); /* reserved */
4643
4644 /* Matrix structure */
4645 write_matrix(pb, 1, 0, 0, 1, 0, 0);
4646
4647 avio_wb32(pb, 0); /* reserved (preview time) */
4648 avio_wb32(pb, 0); /* reserved (preview duration) */
4649 avio_wb32(pb, 0); /* reserved (poster time) */
4650 avio_wb32(pb, 0); /* reserved (selection time) */
4651 avio_wb32(pb, 0); /* reserved (selection duration) */
4652 avio_wb32(pb, 0); /* reserved (current time) */
4653 avio_wb32(pb, max_track_id + 1); /* Next track id */
4654 return 0x6c;
4655}
4656
4659{
4660 avio_wb32(pb, 33); /* size */
4661 ffio_wfourcc(pb, "hdlr");
4662 avio_wb32(pb, 0);
4663 avio_wb32(pb, 0);
4664 ffio_wfourcc(pb, "mdir");
4665 ffio_wfourcc(pb, "appl");
4666 avio_wb32(pb, 0);
4667 avio_wb32(pb, 0);
4668 avio_w8(pb, 0);
4669 return 33;
4670}
4671
4672/* helper function to write a data tag with the specified string as data */
4673static int mov_write_string_data_tag(AVIOContext *pb, const char *data, int lang, int long_style)
4674{
4675 size_t data_len = strlen(data);
4676 if (long_style) {
4677 int size = 16 + data_len;
4678 avio_wb32(pb, size); /* size */
4679 ffio_wfourcc(pb, "data");
4680 avio_wb32(pb, 1);
4681 avio_wb32(pb, 0);
4682 avio_write(pb, data, data_len);
4683 return size;
4684 } else {
4685 avio_wb16(pb, data_len); /* string length */
4686 if (!lang)
4687 lang = ff_mov_iso639_to_lang("und", 1);
4688 avio_wb16(pb, lang);
4689 avio_write(pb, data, data_len);
4690 return data_len + 4;
4691 }
4692}
4693
4694static int mov_write_string_tag(AVIOContext *pb, const char *name,
4695 const char *value, int lang, int long_style)
4696{
4697 int size = 0;
4698 if (value && value[0]) {
4699 int64_t pos = avio_tell(pb);
4700 avio_wb32(pb, 0); /* size */
4701 ffio_wfourcc(pb, name);
4702 mov_write_string_data_tag(pb, value, lang, long_style);
4703 size = update_size(pb, pos);
4704 }
4705 return size;
4706}
4707
4708static int mov_write_freeform_tag(AVIOContext *pb, const char *mean,
4709 const char *name, const char *data)
4710{
4711 if (!data || !data[0])
4712 return 0;
4713
4714 static const char stub_flags[4] = {0, 0, 0, 0};
4715
4716 int64_t entry_pos = avio_tell(pb);
4717 avio_wb32(pb, 0); /* size */
4718 ffio_wfourcc(pb, "----"); /* freeform */
4719
4720 size_t mean_len = strlen(mean);
4721 avio_wb32(pb, 12 + mean_len);
4722 ffio_wfourcc(pb, "mean");
4723 avio_write(pb, &stub_flags[0], sizeof(stub_flags));
4724 avio_write(pb, mean, mean_len);
4725
4726 size_t name_len = strlen(name);
4727 avio_wb32(pb, 12 + name_len);
4728 ffio_wfourcc(pb, "name");
4729 avio_write(pb, &stub_flags[0], sizeof(stub_flags));
4730 avio_write(pb, name, name_len);
4731
4733
4734 return update_size(pb, entry_pos);
4735}
4736
4738 const char *tag, int *lang)
4739{
4740 int l, len, len2;
4741 AVDictionaryEntry *t, *t2 = NULL;
4742 char tag2[16];
4743
4744 *lang = 0;
4745
4746 if (!(t = av_dict_get(s->metadata, tag, NULL, 0)))
4747 return NULL;
4748
4749 len = strlen(t->key);
4750 snprintf(tag2, sizeof(tag2), "%s-", tag);
4751 while ((t2 = av_dict_get(s->metadata, tag2, t2, AV_DICT_IGNORE_SUFFIX))) {
4752 len2 = strlen(t2->key);
4753 if (len2 == len + 4 && !strcmp(t->value, t2->value)
4754 && (l = ff_mov_iso639_to_lang(&t2->key[len2 - 3], 1)) >= 0) {
4755 *lang = l;
4756 return t;
4757 }
4758 }
4759 return t;
4760}
4761
4763 const char *name, const char *tag,
4764 int long_style)
4765{
4766 int lang;
4768 if (!t)
4769 return 0;
4770 return mov_write_string_tag(pb, name, t->value, lang, long_style);
4771}
4772
4774 const char *mean, const char *name,
4775 const char *tag)
4776{
4777 AVDictionaryEntry *t = av_dict_get(s->metadata, tag, NULL, 0);
4778 if (!t)
4779 return 0;
4780 return mov_write_freeform_tag(pb, mean, name, t->value);
4781}
4782
4783/* iTunes bpm number */
4785{
4786 AVDictionaryEntry *t = av_dict_get(s->metadata, "tmpo", NULL, 0);
4787 int size = 0, tmpo = t ? atoi(t->value) : 0;
4788 if (tmpo) {
4789 size = 26;
4790 avio_wb32(pb, size);
4791 ffio_wfourcc(pb, "tmpo");
4792 avio_wb32(pb, size-8); /* size */
4793 ffio_wfourcc(pb, "data");
4794 avio_wb32(pb, 0x15); //type specifier
4795 avio_wb32(pb, 0);
4796 avio_wb16(pb, tmpo); // data
4797 }
4798 return size;
4799}
4800
4801/* 3GPP TS 26.244 */
4803{
4804 int lang;
4805 int64_t pos = avio_tell(pb);
4806 double latitude, longitude, altitude;
4807 int32_t latitude_fix, longitude_fix, altitude_fix;
4808 AVDictionaryEntry *t = get_metadata_lang(s, "location", &lang);
4809 const char *ptr, *place = "";
4810 char *end;
4811 static const char *astronomical_body = "earth";
4812 if (!t)
4813 return 0;
4814
4815 ptr = t->value;
4816 latitude = strtod(ptr, &end);
4817 if (end == ptr) {
4818 av_log(s, AV_LOG_WARNING, "malformed location metadata\n");
4819 return 0;
4820 }
4821 ptr = end;
4822 longitude = strtod(ptr, &end);
4823 if (end == ptr) {
4824 av_log(s, AV_LOG_WARNING, "malformed location metadata\n");
4825 return 0;
4826 }
4827 ptr = end;
4828 altitude = strtod(ptr, &end);
4829 /* If no altitude was present, the default 0 should be fine */
4830 if (*end == '/')
4831 place = end + 1;
4832
4833 latitude_fix = (int32_t) ((1 << 16) * latitude);
4834 longitude_fix = (int32_t) ((1 << 16) * longitude);
4835 altitude_fix = (int32_t) ((1 << 16) * altitude);
4836
4837 avio_wb32(pb, 0); /* size */
4838 ffio_wfourcc(pb, "loci"); /* type */
4839 avio_wb32(pb, 0); /* version + flags */
4840 avio_wb16(pb, lang);
4841 avio_write(pb, place, strlen(place) + 1);
4842 avio_w8(pb, 0); /* role of place (0 == shooting location, 1 == real location, 2 == fictional location) */
4843 avio_wb32(pb, longitude_fix);
4844 avio_wb32(pb, latitude_fix);
4845 avio_wb32(pb, altitude_fix);
4846 avio_write(pb, astronomical_body, strlen(astronomical_body) + 1);
4847 avio_w8(pb, 0); /* additional notes, null terminated string */
4848
4849 return update_size(pb, pos);
4850}
4851
4852/* iTunes track or disc number */
4854 AVFormatContext *s, int disc)
4855{
4856 AVDictionaryEntry *t = av_dict_get(s->metadata,
4857 disc ? "disc" : "track",
4858 NULL, 0);
4859 int size = 0, track = t ? atoi(t->value) : 0;
4860 if (track) {
4861 int tracks = 0;
4862 char *slash = strchr(t->value, '/');
4863 if (slash)
4864 tracks = atoi(slash + 1);
4865 avio_wb32(pb, 32); /* size */
4866 ffio_wfourcc(pb, disc ? "disk" : "trkn");
4867 avio_wb32(pb, 24); /* size */
4868 ffio_wfourcc(pb, "data");
4869 avio_wb32(pb, 0); // 8 bytes empty
4870 avio_wb32(pb, 0);
4871 avio_wb16(pb, 0); // empty
4872 avio_wb16(pb, track); // track / disc number
4873 avio_wb16(pb, tracks); // total track / disc number
4874 avio_wb16(pb, 0); // empty
4875 size = 32;
4876 }
4877 return size;
4878}
4879
4881 const char *name, const char *tag,
4882 int len)
4883{
4885 uint8_t num;
4886 int size = 24 + len;
4887
4888 if (len != 1 && len != 4)
4889 return -1;
4890
4891 if (!(t = av_dict_get(s->metadata, tag, NULL, 0)))
4892 return 0;
4893 num = atoi(t->value);
4894
4895 avio_wb32(pb, size);
4896 ffio_wfourcc(pb, name);
4897 avio_wb32(pb, size - 8);
4898 ffio_wfourcc(pb, "data");
4899 avio_wb32(pb, 0x15);
4900 avio_wb32(pb, 0);
4901 if (len==4) avio_wb32(pb, num);
4902 else avio_w8 (pb, num);
4903
4904 return size;
4905}
4906
4908{
4909 MOVMuxContext *mov = s->priv_data;
4910 int64_t pos = 0;
4911
4912 for (int i = 0; i < mov->nb_streams; i++) {
4913 MOVTrack *trk = &mov->tracks[i];
4914
4915 if (!is_cover_image(trk->st) || trk->cover_image->size <= 0)
4916 continue;
4917
4918 if (!pos) {
4919 pos = avio_tell(pb);
4920 avio_wb32(pb, 0);
4921 ffio_wfourcc(pb, "covr");
4922 }
4923 avio_wb32(pb, 16 + trk->cover_image->size);
4924 ffio_wfourcc(pb, "data");
4925 avio_wb32(pb, trk->tag);
4926 avio_wb32(pb , 0);
4927 avio_write(pb, trk->cover_image->data, trk->cover_image->size);
4928 }
4929
4930 return pos ? update_size(pb, pos) : 0;
4931}
4932
4933/* iTunes meta data list */
4936{
4937 int64_t pos = avio_tell(pb);
4938 avio_wb32(pb, 0); /* size */
4939 ffio_wfourcc(pb, "ilst");
4940 mov_write_string_metadata(s, pb, "\251nam", "title" , 1);
4941 mov_write_string_metadata(s, pb, "\251ART", "artist" , 1);
4942 mov_write_string_metadata(s, pb, "aART", "album_artist", 1);
4943 mov_write_string_metadata(s, pb, "\251wrt", "composer" , 1);
4944 mov_write_string_metadata(s, pb, "\251alb", "album" , 1);
4945 mov_write_string_metadata(s, pb, "\251day", "date" , 1);
4946 if (!mov_write_string_metadata(s, pb, "\251too", "encoding_tool", 1)) {
4947 if (!(s->flags & AVFMT_FLAG_BITEXACT))
4948 mov_write_string_tag(pb, "\251too", LIBAVFORMAT_IDENT, 0, 1);
4949 }
4950 mov_write_string_metadata(s, pb, "\251cmt", "comment" , 1);
4951 mov_write_string_metadata(s, pb, "\251gen", "genre" , 1);
4952 mov_write_string_metadata(s, pb, "cprt", "copyright", 1);
4953 mov_write_string_metadata(s, pb, "\251grp", "grouping" , 1);
4954 mov_write_string_metadata(s, pb, "\251lyr", "lyrics" , 1);
4955 mov_write_string_metadata(s, pb, "desc", "description",1);
4956 mov_write_string_metadata(s, pb, "ldes", "synopsis" , 1);
4957 mov_write_string_metadata(s, pb, "tvsh", "show" , 1);
4958 mov_write_string_metadata(s, pb, "tven", "episode_id",1);
4959 mov_write_string_metadata(s, pb, "tvnn", "network" , 1);
4960 mov_write_string_metadata(s, pb, "keyw", "keywords" , 1);
4961 mov_write_int8_metadata (s, pb, "tves", "episode_sort",4);
4962 mov_write_int8_metadata (s, pb, "tvsn", "season_number",4);
4963 mov_write_int8_metadata (s, pb, "stik", "media_type",1);
4964 mov_write_int8_metadata (s, pb, "hdvd", "hd_video", 1);
4965 mov_write_int8_metadata (s, pb, "pgap", "gapless_playback",1);
4966 mov_write_int8_metadata (s, pb, "cpil", "compilation", 1);
4967 mov_write_covr(pb, s);
4968 mov_write_trkn_tag(pb, mov, s, 0); // track number
4969 mov_write_trkn_tag(pb, mov, s, 1); // disc number
4970 mov_write_tmpo_tag(pb, s);
4971 mov_write_custom_metadata(s, pb, "com.apple.iTunes", "DISCSUBTITLE", "disc_subtitle");
4972 return update_size(pb, pos);
4973}
4974
4977{
4978 avio_wb32(pb, 33); /* size */
4979 ffio_wfourcc(pb, "hdlr");
4980 avio_wb32(pb, 0);
4981 avio_wb32(pb, 0);
4982 ffio_wfourcc(pb, "mdta");
4983 avio_wb32(pb, 0);
4984 avio_wb32(pb, 0);
4985 avio_wb32(pb, 0);
4986 avio_w8(pb, 0);
4987 return 33;
4988}
4989
4992{
4993 const AVDictionaryEntry *t = NULL;
4994 int64_t pos = avio_tell(pb);
4995 int64_t curpos, entry_pos;
4996 int count = 0;
4997
4998 avio_wb32(pb, 0); /* size */
4999 ffio_wfourcc(pb, "keys");
5000 avio_wb32(pb, 0);
5001 entry_pos = avio_tell(pb);
5002 avio_wb32(pb, 0); /* entry count */
5003
5004 while (t = av_dict_iterate(s->metadata, t)) {
5005 size_t key_len = strlen(t->key);
5006 avio_wb32(pb, key_len + 8);
5007 ffio_wfourcc(pb, "mdta");
5008 avio_write(pb, t->key, key_len);
5009 count += 1;
5010 }
5011 curpos = avio_tell(pb);
5012 avio_seek(pb, entry_pos, SEEK_SET);
5013 avio_wb32(pb, count); // rewrite entry count
5014 avio_seek(pb, curpos, SEEK_SET);
5015
5016 return update_size(pb, pos);
5017}
5018
5021{
5022 const AVDictionaryEntry *t = NULL;
5023 int64_t pos = avio_tell(pb);
5024 int count = 1; /* keys are 1-index based */
5025
5026 avio_wb32(pb, 0); /* size */
5027 ffio_wfourcc(pb, "ilst");
5028
5029 while (t = av_dict_iterate(s->metadata, t)) {
5030 int64_t entry_pos = avio_tell(pb);
5031 avio_wb32(pb, 0); /* size */
5032 avio_wb32(pb, count); /* key */
5033 mov_write_string_data_tag(pb, t->value, 0, 1);
5034 update_size(pb, entry_pos);
5035 count += 1;
5036 }
5037 return update_size(pb, pos);
5038}
5039
5040/* meta data tags */
5043{
5044 int size = 0;
5045 int64_t pos = avio_tell(pb);
5046 avio_wb32(pb, 0); /* size */
5047 ffio_wfourcc(pb, "meta");
5048 avio_wb32(pb, 0);
5049 if (mov->flags & FF_MOV_FLAG_USE_MDTA) {
5050 mov_write_mdta_hdlr_tag(pb, mov, s);
5051 mov_write_mdta_keys_tag(pb, mov, s);
5052 mov_write_mdta_ilst_tag(pb, mov, s);
5053 } else if (mov->mode == MODE_AVIF) {
5054 mov_write_hdlr_tag(s, pb, &mov->tracks[0]);
5055 // We always write the primary item id as 1 since only one track is
5056 // supported for AVIF.
5057 mov_write_pitm_tag(pb, 1);
5058 mov_write_iloc_tag(pb, mov, s);
5059 mov_write_iinf_tag(pb, mov, s);
5060 if (mov->nb_streams > 1)
5061 mov_write_iref_tag(pb, mov, s);
5062 mov_write_iprp_tag(pb, mov, s);
5063 } else {
5064 /* iTunes metadata tag */
5065 mov_write_itunes_hdlr_tag(pb, mov, s);
5066 mov_write_ilst_tag(pb, mov, s);
5067 }
5068 size = update_size(pb, pos);
5069 return size;
5070}
5071
5073 const char *name, const char *key)
5074{
5075 int len;
5077
5078 if (!(t = av_dict_get(s->metadata, key, NULL, 0)))
5079 return 0;
5080
5081 len = strlen(t->value);
5082 if (len > 0) {
5083 int size = len + 8;
5084 avio_wb32(pb, size);
5085 ffio_wfourcc(pb, name);
5086 avio_write(pb, t->value, len);
5087 return size;
5088 }
5089 return 0;
5090}
5091
5092static int ascii_to_wc(AVIOContext *pb, const uint8_t *b)
5093{
5094 int val;
5095 while (*b) {
5096 GET_UTF8(val, *b++, return -1;)
5097 avio_wb16(pb, val);
5098 }
5099 avio_wb16(pb, 0x00);
5100 return 0;
5101}
5102
5103static uint16_t language_code(const char *str)
5104{
5105 return (((str[0] - 0x60) & 0x1F) << 10) +
5106 (((str[1] - 0x60) & 0x1F) << 5) +
5107 (( str[2] - 0x60) & 0x1F);
5108}
5109
5111 const char *tag, const char *str)
5112{
5113 int64_t pos = avio_tell(pb);
5114 AVDictionaryEntry *t = av_dict_get(s->metadata, str, NULL, 0);
5115 if (!t || !utf8len(t->value))
5116 return 0;
5117 avio_wb32(pb, 0); /* size */
5118 ffio_wfourcc(pb, tag); /* type */
5119 avio_wb32(pb, 0); /* version + flags */
5120 if (!strcmp(tag, "yrrc"))
5121 avio_wb16(pb, atoi(t->value));
5122 else {
5123 avio_wb16(pb, language_code("eng")); /* language */
5124 avio_write(pb, t->value, strlen(t->value) + 1); /* UTF8 string value */
5125 if (!strcmp(tag, "albm") &&
5126 (t = av_dict_get(s->metadata, "track", NULL, 0)))
5127 avio_w8(pb, atoi(t->value));
5128 }
5129 return update_size(pb, pos);
5130}
5131
5133{
5134 int64_t pos = avio_tell(pb);
5135 int i, nb_chapters = FFMIN(s->nb_chapters, 255);
5136
5137 avio_wb32(pb, 0); // size
5138 ffio_wfourcc(pb, "chpl");
5139 avio_wb32(pb, 0x01000000); // version + flags
5140 avio_wb32(pb, 0); // unknown
5141 avio_w8(pb, nb_chapters);
5142
5143 for (i = 0; i < nb_chapters; i++) {
5144 AVChapter *c = s->chapters[i];
5146 avio_wb64(pb, av_rescale_q(c->start, c->time_base, (AVRational){1,10000000}));
5147
5148 if ((t = av_dict_get(c->metadata, "title", NULL, 0))) {
5149 int len = FFMIN(strlen(t->value), 255);
5150 avio_w8(pb, len);
5151 avio_write(pb, t->value, len);
5152 } else
5153 avio_w8(pb, 0);
5154 }
5155 return update_size(pb, pos);
5156}
5157
5160{
5161 AVIOContext *pb_buf;
5162 int ret, size;
5163 uint8_t *buf;
5164
5165 ret = avio_open_dyn_buf(&pb_buf);
5166 if (ret < 0)
5167 return ret;
5168
5169 if (mov->mode & MODE_3GP) {
5170 mov_write_3gp_udta_tag(pb_buf, s, "perf", "artist");
5171 mov_write_3gp_udta_tag(pb_buf, s, "titl", "title");
5172 mov_write_3gp_udta_tag(pb_buf, s, "auth", "author");
5173 mov_write_3gp_udta_tag(pb_buf, s, "gnre", "genre");
5174 mov_write_3gp_udta_tag(pb_buf, s, "dscp", "comment");
5175 mov_write_3gp_udta_tag(pb_buf, s, "albm", "album");
5176 mov_write_3gp_udta_tag(pb_buf, s, "cprt", "copyright");
5177 mov_write_3gp_udta_tag(pb_buf, s, "yrrc", "date");
5178 mov_write_loci_tag(s, pb_buf);
5179 } 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
5180 mov_write_string_metadata(s, pb_buf, "\251ART", "artist", 0);
5181 mov_write_string_metadata(s, pb_buf, "\251nam", "title", 0);
5182 mov_write_string_metadata(s, pb_buf, "\251aut", "author", 0);
5183 mov_write_string_metadata(s, pb_buf, "\251alb", "album", 0);
5184 mov_write_string_metadata(s, pb_buf, "\251day", "date", 0);
5185 mov_write_string_metadata(s, pb_buf, "\251swr", "encoder", 0);
5186 // currently ignored by mov.c
5187 mov_write_string_metadata(s, pb_buf, "\251des", "comment", 0);
5188 // add support for libquicktime, this atom is also actually read by mov.c
5189 mov_write_string_metadata(s, pb_buf, "\251cmt", "comment", 0);
5190 mov_write_string_metadata(s, pb_buf, "\251gen", "genre", 0);
5191 mov_write_string_metadata(s, pb_buf, "\251cpy", "copyright", 0);
5192 mov_write_string_metadata(s, pb_buf, "\251mak", "make", 0);
5193 mov_write_string_metadata(s, pb_buf, "\251mod", "model", 0);
5194 mov_write_string_metadata(s, pb_buf, "\251xyz", "location", 0);
5195 mov_write_string_metadata(s, pb_buf, "\251key", "keywords", 0);
5196 mov_write_raw_metadata_tag(s, pb_buf, "XMP_", "xmp");
5197 } else {
5198 /* iTunes meta data */
5199 mov_write_meta_tag(pb_buf, mov, s);
5200 mov_write_loci_tag(s, pb_buf);
5201 }
5202
5203 if (s->nb_chapters && !(mov->flags & FF_MOV_FLAG_DISABLE_CHPL))
5204 mov_write_chpl_tag(pb_buf, s);
5205
5206 if ((size = avio_get_dyn_buf(pb_buf, &buf)) > 0) {
5207 avio_wb32(pb, size + 8);
5208 ffio_wfourcc(pb, "udta");
5209 avio_write(pb, buf, size);
5210 }
5211 ffio_free_dyn_buf(&pb_buf);
5212
5213 return 0;
5214}
5215
5217 const char *str, const char *lang, int type)
5218{
5219 int len = utf8len(str) + 1;
5220 if (len <= 0)
5221 return;
5222 avio_wb16(pb, len * 2 + 10); /* size */
5223 avio_wb32(pb, type); /* type */
5224 avio_wb16(pb, language_code(lang)); /* language */
5225 avio_wb16(pb, 0x01); /* ? */
5226 ascii_to_wc(pb, str);
5227}
5228
5230{
5231 AVDictionaryEntry *title = av_dict_get(s->metadata, "title", NULL, 0);
5232 int64_t pos, pos2;
5233
5234 if (title) {
5235 pos = avio_tell(pb);
5236 avio_wb32(pb, 0); /* size placeholder*/
5237 ffio_wfourcc(pb, "uuid");
5238 ffio_wfourcc(pb, "USMT");
5239 avio_wb32(pb, 0x21d24fce); /* 96 bit UUID */
5240 avio_wb32(pb, 0xbb88695c);
5241 avio_wb32(pb, 0xfac9c740);
5242
5243 pos2 = avio_tell(pb);
5244 avio_wb32(pb, 0); /* size placeholder*/
5245 ffio_wfourcc(pb, "MTDT");
5246 avio_wb16(pb, 4);
5247
5248 // ?
5249 avio_wb16(pb, 0x0C); /* size */
5250 avio_wb32(pb, 0x0B); /* type */
5251 avio_wb16(pb, language_code("und")); /* language */
5252 avio_wb16(pb, 0x0); /* ? */
5253 avio_wb16(pb, 0x021C); /* data */
5254
5255 if (!(s->flags & AVFMT_FLAG_BITEXACT))
5256 mov_write_psp_udta_tag(pb, LIBAVFORMAT_IDENT, "eng", 0x04);
5257 mov_write_psp_udta_tag(pb, title->value, "eng", 0x01);
5258 mov_write_psp_udta_tag(pb, "2006/04/01 11:11:11", "und", 0x03);
5259
5260 update_size(pb, pos2);
5261 return update_size(pb, pos);
5262 }
5263
5264 return 0;
5265}
5266
5268{
5273 if (!sd)
5274 return 0;
5275
5277 for (AVEncryptionInitInfo *copy = info; copy; copy = copy->next) {
5278 int64_t pos;
5279
5280 if (!copy->data_size && !copy->num_key_ids)
5281 continue;
5282
5283 pos = avio_tell(pb);
5284 avio_wb32(pb, 0); /* size placeholder */
5285 ffio_wfourcc(pb, "pssh");
5286 avio_w8(pb, 1); /* version */
5287 avio_wb24(pb, 0);
5288 for (int i = 0; i < copy->system_id_size; i++)
5289 avio_w8(pb, copy->system_id[i]);
5290 avio_wb32(pb, copy->num_key_ids);
5291 for (int i = 0; i < copy->num_key_ids; i++)
5292 for (int j = 0; j < copy->key_id_size; j++)
5293 avio_w8(pb, copy->key_ids[i][j]);
5294 avio_wb32(pb, copy->data_size);
5295 avio_write(pb, copy->data, copy->data_size);
5296 update_size(pb, pos);
5297 }
5298
5300
5301 return 0;
5302}
5303
5304static void build_chunks(MOVTrack *trk)
5305{
5306 int i;
5307 MOVIentry *chunk = &trk->cluster[0];
5308 uint64_t chunkSize = chunk->size;
5309 chunk->chunkNum = 1;
5310 if (trk->chunkCount)
5311 return;
5312 trk->chunkCount = 1;
5313 for (i = 1; i<trk->entry; i++){
5314 if (chunk->pos + chunkSize == trk->cluster[i].pos &&
5315 chunk->stsd_index == trk->cluster[i].stsd_index &&
5316 chunkSize + trk->cluster[i].size < (1<<20)){
5317 chunkSize += trk->cluster[i].size;
5318 chunk->samples_in_chunk += trk->cluster[i].entries;
5319 } else {
5320 trk->cluster[i].chunkNum = chunk->chunkNum+1;
5321 chunk=&trk->cluster[i];
5322 chunkSize = chunk->size;
5323 trk->chunkCount++;
5324 }
5325 }
5326}
5327
5328/**
5329 * Assign track ids. If option "use_stream_ids_as_track_ids" is set,
5330 * the stream ids are used as track ids.
5331 *
5332 * This assumes mov->tracks and s->streams are in the same order and
5333 * there are no gaps in either of them (so mov->tracks[n] refers to
5334 * s->streams[n]).
5335 *
5336 * As an exception, there can be more entries in
5337 * s->streams than in mov->tracks, in which case new track ids are
5338 * generated (starting after the largest found stream id).
5339 */
5341{
5342 int i;
5343
5344 if (mov->track_ids_ok)
5345 return 0;
5346
5347 if (mov->use_stream_ids_as_track_ids) {
5348 int next_generated_track_id = 0;
5349 for (i = 0; i < mov->nb_streams; i++) {
5350 AVStream *st = mov->tracks[i].st;
5351 if (st->id > next_generated_track_id)
5352 next_generated_track_id = st->id;
5353 }
5354
5355 for (i = 0; i < mov->nb_tracks; i++) {
5356 if (mov->tracks[i].entry <= 0 && !(mov->flags & FF_MOV_FLAG_FRAGMENT))
5357 continue;
5358
5359 mov->tracks[i].track_id = i >= mov->nb_streams ? ++next_generated_track_id : mov->tracks[i].st->id;
5360 }
5361 } else {
5362 int last_track_id = 0;
5363 for (i = 0; i < mov->nb_tracks; i++) {
5364 if (mov->tracks[i].entry <= 0 && !(mov->flags & FF_MOV_FLAG_FRAGMENT))
5365 continue;
5366
5367 last_track_id =
5368 mov->tracks[i].track_id = (mov->tracks[i].st
5369 ? FFMAX(mov->tracks[i].st->index, last_track_id)
5370 : FFMAX(i, last_track_id)) + 1;
5371 }
5372 }
5373
5374 mov->track_ids_ok = 1;
5375
5376 return 0;
5377}
5378
5379static int mov_find_tref_id(MOVMuxContext *mov, const MovTag *tag, uint32_t id)
5380{
5381 for (int i = 0; i < tag->nb_id; i++) {
5382 if (tag->id[i] == id)
5383 return 1;
5384 }
5385 return 0;
5386}
5387
5388static int mov_add_tref_id(MOVMuxContext *mov, MovTag *tag, uint32_t id)
5389{
5390 int ret = mov_find_tref_id(mov, tag, id);
5391
5392 if (!ret) {
5393 uint32_t *tmp = av_realloc_array(tag->id, tag->nb_id + 1, sizeof(*tag->id));
5394 if (!tmp)
5395 return AVERROR(ENOMEM);
5396 tag->id = tmp;
5397 tag->id[tag->nb_id++] = id;
5398 }
5399
5400 return 0;
5401}
5402
5403static MovTag *mov_find_tref_tag(MOVMuxContext *mov, const MOVTrack *trk, uint32_t name)
5404{
5405 for (int i = 0; i < trk->nb_tref_tags; i++) {
5406 MovTag *entry = &trk->tref_tags[i];
5407
5408 if (entry->name == name)
5409 return entry;
5410 }
5411 return NULL;
5412}
5413
5415{
5416 MovTag *tag = mov_find_tref_tag(mov, trk, name);
5417
5418 if (!tag) {
5420 sizeof(*trk->tref_tags));
5421 if (!tmp)
5422 return NULL;
5423 trk->tref_tags = tmp;
5424 tag = &trk->tref_tags[trk->nb_tref_tags++];
5425 *tag = (MovTag){ .name = name };
5426 }
5427
5428 return tag;
5429}
5430
5433{
5434 int i;
5435 int64_t pos = avio_tell(pb);
5436 avio_wb32(pb, 0); /* size placeholder*/
5437 ffio_wfourcc(pb, "moov");
5438
5439 mov_setup_track_ids(mov, s);
5440
5441 for (i = 0; i < mov->nb_tracks; i++) {
5442 if (mov->tracks[i].entry <= 0 && !(mov->flags & FF_MOV_FLAG_FRAGMENT))
5443 continue;
5444
5445 mov->tracks[i].time = mov->time;
5446
5447 if (mov->tracks[i].entry)
5448 build_chunks(&mov->tracks[i]);
5449 }
5450
5451 if (mov->chapter_track)
5452 for (i = 0; i < mov->nb_streams; i++) {
5453 MovTag *tag = mov_add_tref_tag(mov, &mov->tracks[i], MKTAG('c','h','a','p'));
5454 if (!tag)
5455 return AVERROR(ENOMEM);
5456
5457 int ret = mov_add_tref_id(mov, tag, mov->tracks[mov->chapter_track].track_id);
5458 if (ret < 0)
5459 return ret;
5460 }
5461 for (i = 0; i < mov->nb_tracks; i++) {
5462 MOVTrack *track = &mov->tracks[i];
5463 if (track->tag == MKTAG('r','t','p',' ')) {
5464 MovTag *tag = mov_add_tref_tag(mov, track, MKTAG('h','i','n','t'));
5465 if (!tag)
5466 return AVERROR(ENOMEM);
5467
5468 av_assert0(track->nb_src_track);
5469 int ret = mov_add_tref_id(mov, tag, mov->tracks[*track->src_track].track_id);
5470 if (ret < 0)
5471 return ret;
5472 } else if (track->tag == MKTAG('l','v','c','1') && track->nb_src_track) {
5473 MovTag *tag = mov_add_tref_tag(mov, track, MKTAG('s','b','a','s'));
5474 if (!tag)
5475 return AVERROR(ENOMEM);
5476
5477 int ret = mov_add_tref_id(mov, tag, mov->tracks[*track->src_track].track_id);
5478 if (ret < 0)
5479 return ret;
5480 } else {
5481 if (track->par->codec_type == AVMEDIA_TYPE_AUDIO) {
5485 if (sd && sd->size == sizeof(int)) {
5486 int *fallback = (int *)sd->data;
5487 if (*fallback >= 0 && *fallback < mov->nb_tracks) {
5488 MovTag *tag = mov_add_tref_tag(mov, track, MKTAG('f','a','l','l'));
5489 if (!tag)
5490 return AVERROR(ENOMEM);
5491
5492 int ret = mov_add_tref_id(mov, tag, mov->tracks[*fallback].track_id);
5493 if (ret < 0)
5494 return ret;
5495 }
5496 }
5497 }
5498 for (int j = 0; j < track->nb_src_track; j++) {
5499 int src_trk = track->src_track[j];
5500 MovTag *tag = mov_add_tref_tag(mov, &mov->tracks[src_trk], track->tag);
5501 if (!tag)
5502 return AVERROR(ENOMEM);
5503 int ret = mov_add_tref_id(mov, tag, track->track_id);
5504 if (ret < 0)
5505 return ret;
5506 }
5507 if (mov->nb_meta_tmcd && track->nb_src_track) {
5508 /* Derive the duration from the first source track, matching
5509 * the convention used by get_pts_range() and the rtp/lvc1
5510 * branches above. The source may use a different timescale. */
5511 int src_trk = track->src_track[0];
5512 track->track_duration = av_rescale(mov->tracks[src_trk].track_duration,
5513 track->timescale,
5514 mov->tracks[src_trk].timescale);
5515 }
5516 }
5517 }
5518
5519 mov_write_mvhd_tag(pb, mov);
5520 if (mov->mode != MODE_MOV && mov->mode != MODE_AVIF && !mov->iods_skip)
5521 mov_write_iods_tag(pb, mov);
5522 for (i = 0; i < mov->nb_tracks; i++) {
5523 if (mov->tracks[i].entry > 0 || mov->flags & FF_MOV_FLAG_FRAGMENT ||
5524 mov->mode == MODE_AVIF) {
5525 int ret = mov_write_trak_tag(s, pb, mov, &(mov->tracks[i]), i < mov->nb_streams ? mov->tracks[i].st : NULL);
5526 if (ret < 0)
5527 return ret;
5528 }
5529 }
5530 /* Don't write mvex for hybrid_fragmented during mov_write_trailer
5531 * (mov->moov_written != 0)
5532 */
5533 if (mov->flags & FF_MOV_FLAG_FRAGMENT &&
5535 mov_write_mvex_tag(pb, mov); /* QuickTime requires trak to precede this */
5536
5537 if (mov->mode == MODE_PSP)
5539 else if (mov->mode != MODE_AVIF)
5540 mov_write_udta_tag(pb, mov, s);
5541 for (i = 0; i < mov->nb_streams; i++)
5542 mov_write_pssh_tag(pb, mov->tracks[i].st);
5543
5544 return update_size(pb, pos);
5545}
5546
5547static void param_write_int(AVIOContext *pb, const char *name, int value)
5548{
5549 avio_printf(pb, "<param name=\"%s\" value=\"%d\" valuetype=\"data\"/>\n", name, value);
5550}
5551
5552static void param_write_string(AVIOContext *pb, const char *name, const char *value)
5553{
5554 avio_printf(pb, "<param name=\"%s\" value=\"%s\" valuetype=\"data\"/>\n", name, value);
5555}
5556
5557static void param_write_hex(AVIOContext *pb, const char *name, const uint8_t *value, int len)
5558{
5559 char buf[150];
5560 len = FFMIN(sizeof(buf) / 2 - 1, len);
5561 ff_data_to_hex(buf, value, len, 0);
5562 avio_printf(pb, "<param name=\"%s\" value=\"%s\" valuetype=\"data\"/>\n", name, buf);
5563}
5564
5566{
5567 int64_t pos = avio_tell(pb);
5568 int i;
5569
5570 static const AVUUID uuid = {
5571 0xa5, 0xd4, 0x0b, 0x30, 0xe8, 0x14, 0x11, 0xdd,
5572 0xba, 0x2f, 0x08, 0x00, 0x20, 0x0c, 0x9a, 0x66
5573 };
5574
5575 avio_wb32(pb, 0);
5576 ffio_wfourcc(pb, "uuid");
5577 avio_write(pb, uuid, AV_UUID_LEN);
5578 avio_wb32(pb, 0);
5579
5580 avio_printf(pb, "<?xml version=\"1.0\" encoding=\"utf-8\"?>\n");
5581 avio_printf(pb, "<smil xmlns=\"http://www.w3.org/2001/SMIL20/Language\">\n");
5582 avio_printf(pb, "<head>\n");
5583 if (!(mov->fc->flags & AVFMT_FLAG_BITEXACT))
5584 avio_printf(pb, "<meta name=\"creator\" content=\"%s\" />\n",
5586 avio_printf(pb, "</head>\n");
5587 avio_printf(pb, "<body>\n");
5588 avio_printf(pb, "<switch>\n");
5589
5590 mov_setup_track_ids(mov, s);
5591
5592 for (i = 0; i < mov->nb_tracks; i++) {
5593 MOVTrack *track = &mov->tracks[i];
5594 struct mpeg4_bit_rate_values bit_rates =
5596 const char *type;
5597 int track_id = track->track_id;
5598 char track_name_buf[32] = { 0 };
5599
5600 AVStream *st = track->st;
5601 AVDictionaryEntry *lang = av_dict_get(st->metadata, "language", NULL,0);
5602
5603 if (track->par->codec_type == AVMEDIA_TYPE_VIDEO && !is_cover_image(st)) {
5604 type = "video";
5605 } else if (track->par->codec_type == AVMEDIA_TYPE_AUDIO) {
5606 type = "audio";
5607 } else {
5608 continue;
5609 }
5610
5611 avio_printf(pb, "<%s systemBitrate=\"%"PRIu32"\">\n", type,
5612 bit_rates.avg_bit_rate);
5613 param_write_int(pb, "systemBitrate", bit_rates.avg_bit_rate);
5614 param_write_int(pb, "trackID", track_id);
5615 param_write_string(pb, "systemLanguage", lang ? lang->value : "und");
5616
5617 /* Build track name piece by piece: */
5618 /* 1. track type */
5619 av_strlcat(track_name_buf, type, sizeof(track_name_buf));
5620 /* 2. track language, if available */
5621 if (lang)
5622 av_strlcatf(track_name_buf, sizeof(track_name_buf),
5623 "_%s", lang->value);
5624 /* 3. special type suffix */
5625 /* "_cc" = closed captions, "_ad" = audio_description */
5627 av_strlcat(track_name_buf, "_cc", sizeof(track_name_buf));
5629 av_strlcat(track_name_buf, "_ad", sizeof(track_name_buf));
5630
5631 param_write_string(pb, "trackName", track_name_buf);
5632
5633 if (track->par->codec_type == AVMEDIA_TYPE_VIDEO) {
5634 if (track->par->codec_id == AV_CODEC_ID_H264) {
5635 uint8_t *ptr;
5636 int size = track->extradata_size[track->last_stsd_index];
5638 &size)) {
5639 param_write_hex(pb, "CodecPrivateData",
5640 ptr ? ptr : track->extradata[track->last_stsd_index],
5641 size);
5642 av_free(ptr);
5643 }
5644 param_write_string(pb, "FourCC", "H264");
5645 } else if (track->par->codec_id == AV_CODEC_ID_VC1) {
5646 param_write_string(pb, "FourCC", "WVC1");
5647 param_write_hex(pb, "CodecPrivateData", track->extradata[track->last_stsd_index],
5648 track->extradata_size[track->last_stsd_index]);
5649 }
5650 param_write_int(pb, "MaxWidth", track->par->width);
5651 param_write_int(pb, "MaxHeight", track->par->height);
5652 param_write_int(pb, "DisplayWidth", track->par->width);
5653 param_write_int(pb, "DisplayHeight", track->par->height);
5654 } else {
5655 if (track->par->codec_id == AV_CODEC_ID_AAC) {
5656 switch (track->par->profile) {
5658 param_write_string(pb, "FourCC", "AACP");
5659 break;
5660 case AV_PROFILE_AAC_HE:
5661 param_write_string(pb, "FourCC", "AACH");
5662 break;
5663 default:
5664 param_write_string(pb, "FourCC", "AACL");
5665 }
5666 } else if (track->par->codec_id == AV_CODEC_ID_WMAPRO) {
5667 param_write_string(pb, "FourCC", "WMAP");
5668 }
5669 param_write_hex(pb, "CodecPrivateData", track->extradata[track->last_stsd_index],
5670 track->extradata_size[track->last_stsd_index]);
5672 track->par->codec_id));
5673 param_write_int(pb, "Channels", track->par->ch_layout.nb_channels);
5674 param_write_int(pb, "SamplingRate", track->tag == MKTAG('i','a','m','f') ?
5675 0 : track->par->sample_rate);
5676 param_write_int(pb, "BitsPerSample", 16);
5677 param_write_int(pb, "PacketSize", track->par->block_align ?
5678 track->par->block_align : 4);
5679 }
5680 avio_printf(pb, "</%s>\n", type);
5681 }
5682 avio_printf(pb, "</switch>\n");
5683 avio_printf(pb, "</body>\n");
5684 avio_printf(pb, "</smil>\n");
5685
5686 return update_size(pb, pos);
5687}
5688
5690{
5691 avio_wb32(pb, 16);
5692 ffio_wfourcc(pb, "mfhd");
5693 avio_wb32(pb, 0);
5694 avio_wb32(pb, mov->fragments);
5695 return 0;
5696}
5697
5703
5705 MOVTrack *track, int64_t moof_offset)
5706{
5707 int64_t pos = avio_tell(pb);
5710 if (!track->entry) {
5712 } else {
5714 }
5720 }
5721 /* CMAF requires all values to be explicit in tfhd atoms */
5722 if (mov->flags & FF_MOV_FLAG_CMAF)
5724
5725 /* Don't set a default sample size, the silverlight player refuses
5726 * to play files with that set. Don't set a default sample duration,
5727 * WMP freaks out if it is set. Don't set a base data offset, PIFF
5728 * file format says it MUST NOT be set. */
5729 if (track->mode == MODE_ISM)
5732
5733 avio_wb32(pb, 0); /* size placeholder */
5734 ffio_wfourcc(pb, "tfhd");
5735 avio_w8(pb, 0); /* version */
5736 avio_wb24(pb, flags);
5737
5738 avio_wb32(pb, track->track_id); /* track-id */
5740 avio_wb64(pb, moof_offset);
5741 if (flags & MOV_TFHD_STSD_ID) {
5742 avio_wb32(pb, 1);
5743 }
5745 track->default_duration = get_cluster_duration(track, 0);
5746 avio_wb32(pb, track->default_duration);
5747 }
5749 track->default_size = track->entry ? track->cluster[0].size : 1;
5750 avio_wb32(pb, track->default_size);
5751 } else
5752 track->default_size = -1;
5753
5755 /* Set the default flags based on the second sample, if available.
5756 * If the first sample is different, that can be signaled via a separate field. */
5757 if (track->entry > 1)
5758 track->default_sample_flags = get_sample_flags(track, &track->cluster[1]);
5759 else
5760 track->default_sample_flags =
5761 track->par->codec_type == AVMEDIA_TYPE_VIDEO ?
5764 avio_wb32(pb, track->default_sample_flags);
5765 }
5766
5767 return update_size(pb, pos);
5768}
5769
5771 MOVTrack *track, int moof_size,
5772 int first, int end)
5773{
5774 int64_t pos = avio_tell(pb);
5775 uint32_t flags = MOV_TRUN_DATA_OFFSET;
5776 int i;
5777
5778 for (i = first; i < end; i++) {
5779 if (get_cluster_duration(track, i) != track->default_duration)
5781 if (track->cluster[i].size != track->default_size)
5783 if (i > first && get_sample_flags(track, &track->cluster[i]) != track->default_sample_flags)
5785 }
5786 if (!(flags & MOV_TRUN_SAMPLE_FLAGS) && track->entry > first &&
5787 get_sample_flags(track, &track->cluster[first]) != track->default_sample_flags)
5789 if (track->flags & MOV_TRACK_CTTS)
5791
5792 avio_wb32(pb, 0); /* size placeholder */
5793 ffio_wfourcc(pb, "trun");
5795 avio_w8(pb, 1); /* version */
5796 else
5797 avio_w8(pb, 0); /* version */
5798 avio_wb24(pb, flags);
5799
5800 avio_wb32(pb, end - first); /* sample count */
5803 !mov->first_trun)
5804 avio_wb32(pb, 0); /* Later tracks follow immediately after the previous one */
5805 else
5806 avio_wb32(pb, moof_size + 8 + track->data_offset +
5807 track->cluster[first].pos); /* data offset */
5809 avio_wb32(pb, get_sample_flags(track, &track->cluster[first]));
5810
5811 for (i = first; i < end; i++) {
5813 avio_wb32(pb, get_cluster_duration(track, i));
5815 avio_wb32(pb, track->cluster[i].size);
5817 avio_wb32(pb, get_sample_flags(track, &track->cluster[i]));
5819 avio_wb32(pb, track->cluster[i].cts);
5820 }
5821
5822 mov->first_trun = 0;
5823 return update_size(pb, pos);
5824}
5825
5827{
5828 int64_t pos = avio_tell(pb);
5829 static const uint8_t uuid[] = {
5830 0x6d, 0x1d, 0x9b, 0x05, 0x42, 0xd5, 0x44, 0xe6,
5831 0x80, 0xe2, 0x14, 0x1d, 0xaf, 0xf7, 0x57, 0xb2
5832 };
5833
5834 avio_wb32(pb, 0); /* size placeholder */
5835 ffio_wfourcc(pb, "uuid");
5836 avio_write(pb, uuid, AV_UUID_LEN);
5837 avio_w8(pb, 1);
5838 avio_wb24(pb, 0);
5839 avio_wb64(pb, track->cluster[0].dts + track->cluster[0].cts);
5840 avio_wb64(pb, track->end_pts -
5841 (track->cluster[0].dts + track->cluster[0].cts));
5842
5843 return update_size(pb, pos);
5844}
5845
5847 MOVTrack *track, int entry)
5848{
5849 int n = track->nb_frag_info - 1 - entry, i;
5850 int size = 8 + 16 + 4 + 1 + 16*n;
5851 static const uint8_t uuid[] = {
5852 0xd4, 0x80, 0x7e, 0xf2, 0xca, 0x39, 0x46, 0x95,
5853 0x8e, 0x54, 0x26, 0xcb, 0x9e, 0x46, 0xa7, 0x9f
5854 };
5855
5856 if (entry < 0)
5857 return 0;
5858
5859 avio_seek(pb, track->frag_info[entry].tfrf_offset, SEEK_SET);
5860 avio_wb32(pb, size);
5861 ffio_wfourcc(pb, "uuid");
5862 avio_write(pb, uuid, AV_UUID_LEN);
5863 avio_w8(pb, 1);
5864 avio_wb24(pb, 0);
5865 avio_w8(pb, n);
5866 for (i = 0; i < n; i++) {
5867 int index = entry + 1 + i;
5868 avio_wb64(pb, track->frag_info[index].time);
5869 avio_wb64(pb, track->frag_info[index].duration);
5870 }
5871 if (n < mov->ism_lookahead) {
5872 int free_size = 16 * (mov->ism_lookahead - n);
5873 avio_wb32(pb, free_size);
5874 ffio_wfourcc(pb, "free");
5875 ffio_fill(pb, 0, free_size - 8);
5876 }
5877
5878 return 0;
5879}
5880
5882 MOVTrack *track)
5883{
5884 int64_t pos = avio_tell(pb);
5885 int i;
5886 for (i = 0; i < mov->ism_lookahead; i++) {
5887 /* Update the tfrf tag for the last ism_lookahead fragments,
5888 * nb_frag_info - 1 is the next fragment to be written. */
5889 mov_write_tfrf_tag(pb, mov, track, track->nb_frag_info - 2 - i);
5890 }
5891 avio_seek(pb, pos, SEEK_SET);
5892 return 0;
5893}
5894
5895static int mov_add_tfra_entries(AVIOContext *pb, MOVMuxContext *mov, int tracks,
5896 int size)
5897{
5898 int i;
5899 for (i = 0; i < mov->nb_tracks; i++) {
5900 MOVTrack *track = &mov->tracks[i];
5901 MOVFragmentInfo *info;
5902 if ((tracks >= 0 && i != tracks) || !track->entry)
5903 continue;
5904 track->nb_frag_info++;
5905 if (track->nb_frag_info >= track->frag_info_capacity) {
5906 unsigned new_capacity = track->nb_frag_info + MOV_FRAG_INFO_ALLOC_INCREMENT;
5907 if (av_reallocp_array(&track->frag_info,
5908 new_capacity,
5909 sizeof(*track->frag_info)))
5910 return AVERROR(ENOMEM);
5911 track->frag_info_capacity = new_capacity;
5912 }
5913 info = &track->frag_info[track->nb_frag_info - 1];
5914 info->offset = avio_tell(pb);
5915 info->size = size;
5916 // Try to recreate the original pts for the first packet
5917 // from the fields we have stored
5918 info->time = track->cluster[0].dts + track->cluster[0].cts;
5919 info->duration = track->end_pts -
5920 (track->cluster[0].dts + track->cluster[0].cts);
5921 // If the pts is less than zero, we will have trimmed
5922 // away parts of the media track using an edit list,
5923 // and the corresponding start presentation time is zero.
5924 if (info->time < 0) {
5925 info->duration += info->time;
5926 info->time = 0;
5927 }
5928 info->tfrf_offset = 0;
5929 mov_write_tfrf_tags(pb, mov, track);
5930 }
5931 return 0;
5932}
5933
5934static void mov_prune_frag_info(MOVMuxContext *mov, int tracks, int max)
5935{
5936 int i;
5937 for (i = 0; i < mov->nb_tracks; i++) {
5938 MOVTrack *track = &mov->tracks[i];
5939 if ((tracks >= 0 && i != tracks) || !track->entry)
5940 continue;
5941 if (track->nb_frag_info > max) {
5942 memmove(track->frag_info, track->frag_info + (track->nb_frag_info - max), max * sizeof(*track->frag_info));
5943 track->nb_frag_info = max;
5944 }
5945 }
5946}
5947
5949{
5950 int64_t pos = avio_tell(pb);
5951
5952 avio_wb32(pb, 0); /* size */
5953 ffio_wfourcc(pb, "tfdt");
5954 avio_w8(pb, 1); /* version */
5955 avio_wb24(pb, 0);
5956 avio_wb64(pb, track->cluster[0].dts - track->start_dts);
5957 return update_size(pb, pos);
5958}
5959
5961 MOVTrack *track, int64_t moof_offset,
5962 int moof_size)
5963{
5964 int64_t pos = avio_tell(pb);
5965 int i, start = 0;
5966 avio_wb32(pb, 0); /* size placeholder */
5967 ffio_wfourcc(pb, "traf");
5968
5969 mov_write_tfhd_tag(pb, mov, track, moof_offset);
5970 if (mov->mode != MODE_ISM)
5971 mov_write_tfdt_tag(pb, track);
5972 for (i = 1; i < track->entry; i++) {
5973 if (track->cluster[i].pos != track->cluster[i - 1].pos + track->cluster[i - 1].size) {
5974 mov_write_trun_tag(pb, mov, track, moof_size, start, i);
5975 start = i;
5976 }
5977 }
5978 mov_write_trun_tag(pb, mov, track, moof_size, start, track->entry);
5979 if (mov->mode == MODE_ISM) {
5980 mov_write_tfxd_tag(pb, track);
5981
5982 if (mov->ism_lookahead) {
5983 int size = 16 + 4 + 1 + 16 * mov->ism_lookahead;
5984
5985 if (track->nb_frag_info > 0) {
5986 MOVFragmentInfo *info = &track->frag_info[track->nb_frag_info - 1];
5987 if (!info->tfrf_offset)
5988 info->tfrf_offset = avio_tell(pb);
5989 }
5990 avio_wb32(pb, 8 + size);
5991 ffio_wfourcc(pb, "free");
5992 ffio_fill(pb, 0, size);
5993 }
5994 }
5995
5996 if (track->cenc.aes_ctr && (mov->flags & FF_MOV_FLAG_FRAGMENT))
5997 ff_mov_cenc_write_stbl_atoms(&track->cenc, pb, moof_offset);
5998
5999 return update_size(pb, pos);
6000}
6001
6003 int tracks, int moof_size)
6004{
6005 int64_t pos = avio_tell(pb);
6006 int i;
6007
6008 avio_wb32(pb, 0); /* size placeholder */
6009 ffio_wfourcc(pb, "moof");
6010 mov->first_trun = 1;
6011
6012 mov_write_mfhd_tag(pb, mov);
6013 for (i = 0; i < mov->nb_tracks; i++) {
6014 MOVTrack *track = &mov->tracks[i];
6015 if (tracks >= 0 && i != tracks)
6016 continue;
6017 if (!track->entry)
6018 continue;
6019 if (track->cenc.aes_ctr && (mov->flags & FF_MOV_FLAG_FRAGMENT))
6020 mov_write_pssh_tag(pb, track->st);
6021 mov_write_traf_tag(pb, mov, track, pos, moof_size);
6022 }
6023
6024 return update_size(pb, pos);
6025}
6026
6028 MOVTrack *track, int ref_size, int total_sidx_size)
6029{
6030 int64_t pos = avio_tell(pb), offset_pos, end_pos;
6031 int64_t presentation_time, duration, offset;
6032 unsigned starts_with_SAP;
6033 int i, entries;
6034
6035 if (track->entry) {
6036 entries = 1;
6037 presentation_time = track->cluster[0].dts + track->cluster[0].cts;
6038 duration = track->end_pts -
6039 (track->cluster[0].dts + track->cluster[0].cts);
6040 starts_with_SAP = track->cluster[0].flags & MOV_SYNC_SAMPLE;
6041
6042 // pts<0 should be cut away using edts
6043 if (presentation_time < 0) {
6044 duration += presentation_time;
6045 presentation_time = 0;
6046 }
6047 } else {
6048 entries = track->nb_frag_info;
6049 if (entries <= 0)
6050 return 0;
6051 presentation_time = track->frag_info[0].time;
6052 }
6053
6054 avio_wb32(pb, 0); /* size */
6055 ffio_wfourcc(pb, "sidx");
6056 avio_w8(pb, 1); /* version */
6057 avio_wb24(pb, 0);
6058 avio_wb32(pb, track->track_id); /* reference_ID */
6059 avio_wb32(pb, track->timescale); /* timescale */
6060 avio_wb64(pb, presentation_time); /* earliest_presentation_time */
6061 offset_pos = avio_tell(pb);
6062 avio_wb64(pb, 0); /* first_offset (offset to referenced moof) */
6063 avio_wb16(pb, 0); /* reserved */
6064
6065 avio_wb16(pb, entries); /* reference_count */
6066 for (i = 0; i < entries; i++) {
6067 if (!track->entry) {
6068 if (i > 1 && track->frag_info[i].offset != track->frag_info[i - 1].offset + track->frag_info[i - 1].size) {
6069 av_log(NULL, AV_LOG_ERROR, "Non-consecutive fragments, writing incorrect sidx\n");
6070 }
6071 duration = track->frag_info[i].duration;
6072 ref_size = track->frag_info[i].size;
6073 starts_with_SAP = 1;
6074 }
6075 avio_wb32(pb, (0 << 31) | (ref_size & 0x7fffffff)); /* reference_type (0 = media) | referenced_size */
6076 avio_wb32(pb, duration); /* subsegment_duration */
6077 avio_wb32(pb, (starts_with_SAP << 31) | (0 << 28) | 0); /* starts_with_SAP | SAP_type | SAP_delta_time */
6078 }
6079
6080 end_pos = avio_tell(pb);
6081 offset = pos + total_sidx_size - end_pos;
6082 avio_seek(pb, offset_pos, SEEK_SET);
6083 avio_wb64(pb, offset);
6084 avio_seek(pb, end_pos, SEEK_SET);
6085 return update_size(pb, pos);
6086}
6087
6089 int tracks, int ref_size)
6090{
6091 int i, round, ret;
6092 AVIOContext *avio_buf;
6093 int total_size = 0;
6094 for (round = 0; round < 2; round++) {
6095 // First run one round to calculate the total size of all
6096 // sidx atoms.
6097 // This would be much simpler if we'd only write one sidx
6098 // atom, for the first track in the moof.
6099 if (round == 0) {
6100 if ((ret = ffio_open_null_buf(&avio_buf)) < 0)
6101 return ret;
6102 } else {
6103 avio_buf = pb;
6104 }
6105 for (i = 0; i < mov->nb_tracks; i++) {
6106 MOVTrack *track = &mov->tracks[i];
6107 if (tracks >= 0 && i != tracks)
6108 continue;
6109 // When writing a sidx for the full file, entry is 0, but
6110 // we want to include all tracks. ref_size is 0 in this case,
6111 // since we read it from frag_info instead.
6112 if (!track->entry && ref_size > 0)
6113 continue;
6114 total_size -= mov_write_sidx_tag(avio_buf, track, ref_size,
6115 total_size);
6116 }
6117 if (round == 0) {
6118 total_size = ffio_close_null_buf(avio_buf);
6119 if (total_size < 0)
6120 return total_size;
6121 }
6122 }
6123 return 0;
6124}
6125
6126static int mov_write_prft_tag(AVIOContext *pb, MOVMuxContext *mov, int tracks)
6127{
6128 int64_t pos = avio_tell(pb), pts_us, ntp_ts;
6129 MOVTrack *first_track;
6130 int flags = 24;
6131
6132 /* PRFT should be associated with at most one track. So, choosing only the
6133 * first track. */
6134 if (tracks > 0)
6135 return 0;
6136 first_track = &(mov->tracks[0]);
6137
6138 if (!first_track->entry) {
6139 av_log(mov->fc, AV_LOG_WARNING, "Unable to write PRFT, no entries in the track\n");
6140 return 0;
6141 }
6142
6143 if (first_track->cluster[0].pts == AV_NOPTS_VALUE) {
6144 av_log(mov->fc, AV_LOG_WARNING, "Unable to write PRFT, first PTS is invalid\n");
6145 return 0;
6146 }
6147
6148 if (mov->write_prft == MOV_PRFT_SRC_WALLCLOCK) {
6149 if (first_track->cluster[0].prft.wallclock) {
6150 /* Round the NTP time to whole milliseconds. */
6151 ntp_ts = ff_get_formatted_ntp_time((first_track->cluster[0].prft.wallclock / 1000) * 1000 +
6153 flags = first_track->cluster[0].prft.flags;
6154 } else
6156 } else if (mov->write_prft == MOV_PRFT_SRC_PTS) {
6157 pts_us = av_rescale_q(first_track->cluster[0].pts,
6158 first_track->st->time_base, AV_TIME_BASE_Q);
6159 ntp_ts = ff_get_formatted_ntp_time(pts_us + NTP_OFFSET_US);
6160 } else {
6161 av_log(mov->fc, AV_LOG_WARNING, "Unsupported PRFT box configuration: %d\n",
6162 mov->write_prft);
6163 return 0;
6164 }
6165
6166 avio_wb32(pb, 0); // Size place holder
6167 ffio_wfourcc(pb, "prft"); // Type
6168 avio_w8(pb, 1); // Version
6169 avio_wb24(pb, flags); // Flags
6170 avio_wb32(pb, first_track->track_id); // reference track ID
6171 avio_wb64(pb, ntp_ts); // NTP time stamp
6172 avio_wb64(pb, first_track->cluster[0].pts); //media time
6173 return update_size(pb, pos);
6174}
6175
6176static int mov_write_moof_tag(AVIOContext *pb, MOVMuxContext *mov, int tracks,
6177 int64_t mdat_size)
6178{
6179 AVIOContext *avio_buf;
6180 int ret, moof_size;
6181
6182 if ((ret = ffio_open_null_buf(&avio_buf)) < 0)
6183 return ret;
6184 mov_write_moof_tag_internal(avio_buf, mov, tracks, 0);
6185 moof_size = ffio_close_null_buf(avio_buf);
6186 if (moof_size < 0)
6187 return moof_size;
6188
6189 if (mov->flags & FF_MOV_FLAG_DASH &&
6191 mov_write_sidx_tags(pb, mov, tracks, moof_size + 8 + mdat_size);
6192
6193 if (mov->write_prft > MOV_PRFT_NONE && mov->write_prft < MOV_PRFT_NB)
6194 mov_write_prft_tag(pb, mov, tracks);
6195
6196 if (mov->flags & FF_MOV_FLAG_GLOBAL_SIDX ||
6197 !(mov->flags & FF_MOV_FLAG_SKIP_TRAILER) ||
6198 mov->ism_lookahead) {
6199 if ((ret = mov_add_tfra_entries(pb, mov, tracks, moof_size + 8 + mdat_size)) < 0)
6200 return ret;
6201 if (!(mov->flags & FF_MOV_FLAG_GLOBAL_SIDX) &&
6203 mov_prune_frag_info(mov, tracks, mov->ism_lookahead + 1);
6204 }
6205 }
6206
6207 return mov_write_moof_tag_internal(pb, mov, tracks, moof_size);
6208}
6209
6211{
6212 int64_t pos = avio_tell(pb);
6213 int i;
6214
6215 avio_wb32(pb, 0); /* size placeholder */
6216 ffio_wfourcc(pb, "tfra");
6217 avio_w8(pb, 1); /* version */
6218 avio_wb24(pb, 0);
6219
6220 avio_wb32(pb, track->track_id);
6221 avio_wb32(pb, 0); /* length of traf/trun/sample num */
6222 avio_wb32(pb, track->nb_frag_info);
6223 for (i = 0; i < track->nb_frag_info; i++) {
6224 avio_wb64(pb, track->frag_info[i].time);
6225 avio_wb64(pb, track->frag_info[i].offset + track->data_offset);
6226 avio_w8(pb, 1); /* traf number */
6227 avio_w8(pb, 1); /* trun number */
6228 avio_w8(pb, 1); /* sample number */
6229 }
6230
6231 return update_size(pb, pos);
6232}
6233
6235{
6236 AVIOContext *mfra_pb;
6237 int i, ret, sz;
6238 uint8_t *buf;
6239
6240 ret = avio_open_dyn_buf(&mfra_pb);
6241 if (ret < 0)
6242 return ret;
6243
6244 avio_wb32(mfra_pb, 0); /* size placeholder */
6245 ffio_wfourcc(mfra_pb, "mfra");
6246 /* An empty mfra atom is enough to indicate to the publishing point that
6247 * the stream has ended. */
6248 if (mov->flags & FF_MOV_FLAG_ISML)
6249 goto done_mfra;
6250
6251 for (i = 0; i < mov->nb_tracks; i++) {
6252 MOVTrack *track = &mov->tracks[i];
6253 if (track->nb_frag_info)
6254 mov_write_tfra_tag(mfra_pb, track);
6255 }
6256
6257 avio_wb32(mfra_pb, 16);
6258 ffio_wfourcc(mfra_pb, "mfro");
6259 avio_wb32(mfra_pb, 0); /* version + flags */
6260 avio_wb32(mfra_pb, avio_tell(mfra_pb) + 4);
6261
6262done_mfra:
6263
6264 sz = update_size(mfra_pb, 0);
6265 ret = avio_get_dyn_buf(mfra_pb, &buf);
6266 avio_write(pb, buf, ret);
6267 ffio_free_dyn_buf(&mfra_pb);
6268
6269 return sz;
6270}
6271
6273{
6274 avio_wb32(pb, 8); // placeholder for extended size field (64 bit)
6275 ffio_wfourcc(pb, mov->mode == MODE_MOV ? "wide" : "free");
6276
6277 mov->mdat_pos = avio_tell(pb);
6278 avio_wb32(pb, 0); /* size placeholder*/
6279 ffio_wfourcc(pb, "mdat");
6280 return 0;
6281}
6282
6284 int has_h264, int has_video, int write_minor)
6285{
6286 MOVMuxContext *mov = s->priv_data;
6287 int minor = 0x200;
6288
6289 if (mov->major_brand && strlen(mov->major_brand) >= 4)
6290 ffio_wfourcc(pb, mov->major_brand);
6291 else if (mov->mode == MODE_3GP) {
6292 ffio_wfourcc(pb, has_h264 ? "3gp6" : "3gp4");
6293 minor = has_h264 ? 0x100 : 0x200;
6294 } else if (mov->mode == MODE_AVIF) {
6295 ffio_wfourcc(pb, mov->is_animated_avif ? "avis" : "avif");
6296 minor = 0;
6297 } else if (mov->mode & MODE_3G2) {
6298 ffio_wfourcc(pb, has_h264 ? "3g2b" : "3g2a");
6299 minor = has_h264 ? 0x20000 : 0x10000;
6300 } else if (mov->mode == MODE_PSP)
6301 ffio_wfourcc(pb, "MSNV");
6302 else if (mov->mode == MODE_MP4 && mov->flags & FF_MOV_FLAG_FRAGMENT &&
6304 ffio_wfourcc(pb, "iso6"); // Required when using signed CTS offsets in trun boxes
6305 else if (mov->mode == MODE_MP4 && mov->flags & FF_MOV_FLAG_DEFAULT_BASE_MOOF)
6306 ffio_wfourcc(pb, "iso5"); // Required when using default-base-is-moof
6307 else if (mov->mode == MODE_MP4 && mov->flags & FF_MOV_FLAG_NEGATIVE_CTS_OFFSETS)
6308 ffio_wfourcc(pb, "iso4");
6309 else if (mov->mode == MODE_MP4)
6310 ffio_wfourcc(pb, "isom");
6311 else if (mov->mode == MODE_IPOD)
6312 ffio_wfourcc(pb, has_video ? "M4V ":"M4A ");
6313 else if (mov->mode == MODE_ISM)
6314 ffio_wfourcc(pb, "isml");
6315 else if (mov->mode == MODE_F4V)
6316 ffio_wfourcc(pb, "f4v ");
6317 else
6318 ffio_wfourcc(pb, "qt ");
6319
6320 if (write_minor)
6321 avio_wb32(pb, minor);
6322}
6323
6325{
6326 MOVMuxContext *mov = s->priv_data;
6327 int64_t pos = avio_tell(pb);
6328 int has_h264 = 0, has_av1 = 0, has_video = 0, has_dolby = 0, has_id3 = 0;
6329 int has_iamf = 0;
6330
6331#if CONFIG_IAMFENC
6332 for (int i = 0; i < s->nb_stream_groups; i++) {
6333 const AVStreamGroup *stg = s->stream_groups[i];
6334
6337 has_iamf = 1;
6338 break;
6339 }
6340 }
6341#endif
6342 for (int i = 0; i < mov->nb_streams; i++) {
6343 AVStream *st = mov->tracks[i].st;
6344 if (is_cover_image(st))
6345 continue;
6347 has_video = 1;
6349 has_h264 = 1;
6350 if (st->codecpar->codec_id == AV_CODEC_ID_AV1)
6351 has_av1 = 1;
6352 if (st->codecpar->codec_id == AV_CODEC_ID_AC3 ||
6358 has_dolby = 1;
6360 has_id3 = 1;
6361 }
6362
6363 avio_wb32(pb, 0); /* size */
6364 ffio_wfourcc(pb, "ftyp");
6365
6366 // Write major brand
6367 mov_write_ftyp_tag_internal(pb, s, has_h264, has_video, 1);
6368 // Write the major brand as the first compatible brand as well
6369 mov_write_ftyp_tag_internal(pb, s, has_h264, has_video, 0);
6370
6371 // Write compatible brands, ensuring that we don't write the major brand as a
6372 // compatible brand a second time.
6373 if (mov->mode == MODE_ISM) {
6374 ffio_wfourcc(pb, "piff");
6375 } else if (mov->mode == MODE_AVIF) {
6376 const AVPixFmtDescriptor *pix_fmt_desc =
6377 av_pix_fmt_desc_get(s->streams[0]->codecpar->format);
6378 const int depth = pix_fmt_desc->comp[0].depth;
6379 if (mov->is_animated_avif) {
6380 // For animated AVIF, major brand is "avis". Add "avif" as a
6381 // compatible brand.
6382 ffio_wfourcc(pb, "avif");
6383 ffio_wfourcc(pb, "msf1");
6384 ffio_wfourcc(pb, "iso8");
6385 }
6386 ffio_wfourcc(pb, "mif1");
6387 ffio_wfourcc(pb, "miaf");
6388 if (depth == 8 || depth == 10) {
6389 // MA1B and MA1A brands are based on AV1 profile. Short hand for
6390 // computing that is based on chroma subsampling type. 420 chroma
6391 // subsampling is MA1B. 444 chroma subsampling is MA1A.
6392 if (!pix_fmt_desc->log2_chroma_w && !pix_fmt_desc->log2_chroma_h) {
6393 // 444 chroma subsampling.
6394 ffio_wfourcc(pb, "MA1A");
6395 } else {
6396 // 420 chroma subsampling.
6397 ffio_wfourcc(pb, "MA1B");
6398 }
6399 }
6400 } else if (mov->mode != MODE_MOV) {
6401 // We add tfdt atoms when fragmenting, signal this with the iso6 compatible
6402 // brand, if not already the major brand. This is compatible with users that
6403 // don't understand tfdt.
6404 if (mov->mode == MODE_MP4) {
6405 if (mov->flags & FF_MOV_FLAG_CMAF)
6406 ffio_wfourcc(pb, "cmfc");
6408 ffio_wfourcc(pb, "iso6");
6409 if (has_av1)
6410 ffio_wfourcc(pb, "av01");
6411 if (has_dolby)
6412 ffio_wfourcc(pb, "dby1");
6413 if (has_iamf)
6414 ffio_wfourcc(pb, "iamf");
6415 } else {
6416 if (mov->flags & FF_MOV_FLAG_FRAGMENT)
6417 ffio_wfourcc(pb, "iso6");
6419 ffio_wfourcc(pb, "iso5");
6421 ffio_wfourcc(pb, "iso4");
6422 }
6423 // Brands prior to iso5 can't be signaled when using default-base-is-moof
6424 if (!(mov->flags & FF_MOV_FLAG_DEFAULT_BASE_MOOF)) {
6425 // write isom for mp4 only if it it's not the major brand already.
6427 ffio_wfourcc(pb, "isom");
6428 ffio_wfourcc(pb, "iso2");
6429 if (has_h264)
6430 ffio_wfourcc(pb, "avc1");
6431 }
6432 }
6433
6434 if (mov->mode == MODE_MP4)
6435 ffio_wfourcc(pb, "mp41");
6436
6438 ffio_wfourcc(pb, "dash");
6439
6440 if (has_id3)
6441 ffio_wfourcc(pb, "aid3");
6442
6443 return update_size(pb, pos);
6444}
6445
6447{
6448 AVStream *video_st = s->streams[0];
6449 AVCodecParameters *video_par = s->streams[0]->codecpar;
6450 AVCodecParameters *audio_par = s->streams[1]->codecpar;
6451 int audio_rate = audio_par->sample_rate;
6452 int64_t frame_rate = video_st->avg_frame_rate.den ?
6453 (video_st->avg_frame_rate.num * 0x10000LL) / video_st->avg_frame_rate.den :
6454 0;
6455 int audio_kbitrate = audio_par->bit_rate / 1000;
6456 int video_kbitrate = FFMIN(video_par->bit_rate / 1000, 800 - audio_kbitrate);
6457
6458 if (frame_rate < 0 || frame_rate > INT32_MAX) {
6459 av_log(s, AV_LOG_ERROR, "Frame rate %f outside supported range\n", frame_rate / (double)0x10000);
6460 return AVERROR(EINVAL);
6461 }
6462
6463 avio_wb32(pb, 0x94); /* size */
6464 ffio_wfourcc(pb, "uuid");
6465 ffio_wfourcc(pb, "PROF");
6466
6467 avio_wb32(pb, 0x21d24fce); /* 96 bit UUID */
6468 avio_wb32(pb, 0xbb88695c);
6469 avio_wb32(pb, 0xfac9c740);
6470
6471 avio_wb32(pb, 0x0); /* ? */
6472 avio_wb32(pb, 0x3); /* 3 sections ? */
6473
6474 avio_wb32(pb, 0x14); /* size */
6475 ffio_wfourcc(pb, "FPRF");
6476 avio_wb32(pb, 0x0); /* ? */
6477 avio_wb32(pb, 0x0); /* ? */
6478 avio_wb32(pb, 0x0); /* ? */
6479
6480 avio_wb32(pb, 0x2c); /* size */
6481 ffio_wfourcc(pb, "APRF"); /* audio */
6482 avio_wb32(pb, 0x0);
6483 avio_wb32(pb, 0x2); /* TrackID */
6484 ffio_wfourcc(pb, "mp4a");
6485 avio_wb32(pb, 0x20f);
6486 avio_wb32(pb, 0x0);
6487 avio_wb32(pb, audio_kbitrate);
6488 avio_wb32(pb, audio_kbitrate);
6489 avio_wb32(pb, audio_rate);
6490 avio_wb32(pb, audio_par->ch_layout.nb_channels);
6491
6492 avio_wb32(pb, 0x34); /* size */
6493 ffio_wfourcc(pb, "VPRF"); /* video */
6494 avio_wb32(pb, 0x0);
6495 avio_wb32(pb, 0x1); /* TrackID */
6496 if (video_par->codec_id == AV_CODEC_ID_H264) {
6497 ffio_wfourcc(pb, "avc1");
6498 avio_wb16(pb, 0x014D);
6499 avio_wb16(pb, 0x0015);
6500 } else {
6501 ffio_wfourcc(pb, "mp4v");
6502 avio_wb16(pb, 0x0000);
6503 avio_wb16(pb, 0x0103);
6504 }
6505 avio_wb32(pb, 0x0);
6506 avio_wb32(pb, video_kbitrate);
6507 avio_wb32(pb, video_kbitrate);
6508 avio_wb32(pb, frame_rate);
6509 avio_wb32(pb, frame_rate);
6510 avio_wb16(pb, video_par->width);
6511 avio_wb16(pb, video_par->height);
6512 avio_wb32(pb, 0x010001); /* ? */
6513
6514 return 0;
6515}
6516
6518{
6519 MOVMuxContext *mov = s->priv_data;
6520 int i;
6521
6523 if (mov->mode == MODE_PSP) {
6524 int video_streams_nb = 0, audio_streams_nb = 0, other_streams_nb = 0;
6525 for (i = 0; i < mov->nb_streams; i++) {
6526 AVStream *st = mov->tracks[i].st;
6527 if (is_cover_image(st))
6528 continue;
6530 video_streams_nb++;
6531 else if (st->codecpar->codec_type == AVMEDIA_TYPE_AUDIO)
6532 audio_streams_nb++;
6533 else
6534 other_streams_nb++;
6535 }
6536
6537 if (video_streams_nb != 1 || audio_streams_nb != 1 || other_streams_nb) {
6538 av_log(s, AV_LOG_ERROR, "PSP mode need one video and one audio stream\n");
6539 return AVERROR(EINVAL);
6540 }
6541 return mov_write_uuidprof_tag(pb, s);
6542 }
6543 return 0;
6544}
6545
6547{
6548 uint32_t c = -1;
6549 int i, closed_gop = 0;
6550
6551 for (i = 0; i < pkt->size - 4; i++) {
6552 c = (c << 8) + pkt->data[i];
6553 if (c == 0x1b8) { // gop
6554 closed_gop = pkt->data[i + 4] >> 6 & 0x01;
6555 } else if (c == 0x100) { // pic
6556 int temp_ref = (pkt->data[i + 1] << 2) | (pkt->data[i + 2] >> 6);
6557 if (!temp_ref || closed_gop) // I picture is not reordered
6559 else
6561 break;
6562 }
6563 }
6564 return 0;
6565}
6566
6568{
6569 const uint8_t *start, *next, *end = pkt->data + pkt->size;
6570 int seq = 0, entry = 0;
6571 int key = pkt->flags & AV_PKT_FLAG_KEY;
6572 start = find_next_marker(pkt->data, end);
6573 for (next = start; next < end; start = next) {
6574 next = find_next_marker(start + 4, end);
6575 switch (AV_RB32(start)) {
6576 case VC1_CODE_SEQHDR:
6577 seq = 1;
6578 break;
6580 entry = 1;
6581 break;
6582 case VC1_CODE_SLICE:
6583 trk->vc1_info.slices = 1;
6584 break;
6585 }
6586 }
6587 if (!trk->entry && trk->vc1_info.first_packet_seen)
6589 if (!trk->entry && !trk->vc1_info.first_frag_written) {
6590 /* First packet in first fragment */
6591 trk->vc1_info.first_packet_seq = seq;
6593 trk->vc1_info.first_packet_seen = 1;
6594 } else if ((seq && !trk->vc1_info.packet_seq) ||
6595 (entry && !trk->vc1_info.packet_entry)) {
6596 int i;
6597 for (i = 0; i < trk->entry; i++)
6598 trk->cluster[i].flags &= ~MOV_SYNC_SAMPLE;
6599 trk->has_keyframes = 0;
6600 if (seq)
6601 trk->vc1_info.packet_seq = 1;
6602 if (entry)
6603 trk->vc1_info.packet_entry = 1;
6604 if (!trk->vc1_info.first_frag_written) {
6605 /* First fragment */
6606 if ((!seq || trk->vc1_info.first_packet_seq) &&
6607 (!entry || trk->vc1_info.first_packet_entry)) {
6608 /* First packet had the same headers as this one, readd the
6609 * sync sample flag. */
6610 trk->cluster[0].flags |= MOV_SYNC_SAMPLE;
6611 trk->has_keyframes = 1;
6612 }
6613 }
6614 }
6615 if (trk->vc1_info.packet_seq && trk->vc1_info.packet_entry)
6616 key = seq && entry;
6617 else if (trk->vc1_info.packet_seq)
6618 key = seq;
6619 else if (trk->vc1_info.packet_entry)
6620 key = entry;
6621 if (key) {
6622 trk->cluster[trk->entry].flags |= MOV_SYNC_SAMPLE;
6623 trk->has_keyframes++;
6624 }
6625}
6626
6628{
6629 int length;
6630
6631 if (pkt->size < 8)
6632 return;
6633
6634 length = (AV_RB16(pkt->data) & 0xFFF) * 2;
6635 if (length < 8 || length > pkt->size)
6636 return;
6637
6638 if (AV_RB32(pkt->data + 4) == 0xF8726FBA) {
6639 trk->cluster[trk->entry].flags |= MOV_SYNC_SAMPLE;
6640 trk->has_keyframes++;
6641 }
6642
6643 return;
6644}
6645
6647{
6648 MOVMuxContext *mov = s->priv_data;
6649 int ret, buf_size;
6650 uint8_t *buf;
6651 int i, offset;
6652
6653 if (!track->mdat_buf)
6654 return 0;
6655 if (!mov->mdat_buf) {
6656 if ((ret = avio_open_dyn_buf(&mov->mdat_buf)) < 0)
6657 return ret;
6658 }
6659 buf_size = avio_get_dyn_buf(track->mdat_buf, &buf);
6660
6661 offset = avio_tell(mov->mdat_buf);
6662 avio_write(mov->mdat_buf, buf, buf_size);
6664
6665 for (i = track->entries_flushed; i < track->entry; i++)
6666 track->cluster[i].pos += offset;
6667 track->entries_flushed = track->entry;
6668 return 0;
6669}
6670
6672{
6673 MOVMuxContext *mov = s->priv_data;
6674 AVPacket *squashed_packet = mov->pkt;
6675 int ret = AVERROR_BUG;
6676
6677 switch (track->st->codecpar->codec_id) {
6678 case AV_CODEC_ID_TTML: {
6679 int had_packets = !!track->squashed_packet_queue.head;
6680
6681 if ((ret = ff_mov_generate_squashed_ttml_packet(s, track, squashed_packet)) < 0) {
6682 goto finish_squash;
6683 }
6684
6685 // We have generated a padding packet (no actual input packets in
6686 // queue) and its duration is zero. Skipping writing it.
6687 if (!had_packets && squashed_packet->duration == 0) {
6688 goto finish_squash;
6689 }
6690
6691 track->end_reliable = 1;
6692 break;
6693 }
6694 default:
6695 ret = AVERROR(EINVAL);
6696 goto finish_squash;
6697 }
6698
6699 squashed_packet->stream_index = track->st->index;
6700
6701 ret = mov_write_single_packet(s, squashed_packet);
6702
6703finish_squash:
6704 av_packet_unref(squashed_packet);
6705
6706 return ret;
6707}
6708
6710{
6711 MOVMuxContext *mov = s->priv_data;
6712
6713 for (int i = 0; i < mov->nb_streams; i++) {
6714 MOVTrack *track = &mov->tracks[i];
6715 int ret = AVERROR_BUG;
6716
6717 if (track->squash_fragment_samples_to_one && !track->entry) {
6718 if ((ret = mov_write_squashed_packet(s, track)) < 0) {
6720 "Failed to write squashed packet for %s stream with "
6721 "index %d and track id %d. Error: %s\n",
6723 track->st->index, track->track_id,
6724 av_err2str(ret));
6725 return ret;
6726 }
6727 }
6728 }
6729
6730 return 0;
6731}
6732
6734 int64_t ref_pos)
6735{
6736 int i;
6737 if (!track->entry)
6738 return 0;
6740 for (i = 0; i < track->entry; i++)
6741 track->cluster[i].pos += ref_pos + track->data_offset;
6742 if (track->cluster_written == 0) {
6743 // First flush. Chunking for this fragment may already have been
6744 // done, either if we didn't use empty_moov, or if we did use
6745 // delay_moov. In either case, reset chunking here.
6746 for (i = 0; i < track->entry; i++) {
6747 track->cluster[i].chunkNum = 0;
6748 track->cluster[i].samples_in_chunk = track->cluster[i].entries;
6749 }
6750 }
6752 track->entry_written + track->entry,
6753 sizeof(*track->cluster)))
6754 return AVERROR(ENOMEM);
6755 memcpy(&track->cluster_written[track->entry_written],
6756 track->cluster, track->entry * sizeof(*track->cluster));
6757 track->entry_written += track->entry;
6758 }
6759 track->entry = 0;
6760 track->entries_flushed = 0;
6761 track->end_reliable = 0;
6762 return 0;
6763}
6764
6765static int mov_flush_fragment(AVFormatContext *s, int force)
6766{
6767 MOVMuxContext *mov = s->priv_data;
6768 int i, first_track = -1;
6769 int64_t mdat_size = 0, mdat_start = 0;
6770 int ret;
6771 int has_video = 0, starts_with_key = 0, first_video_track = 1;
6772
6773 if (!(mov->flags & FF_MOV_FLAG_FRAGMENT))
6774 return 0;
6775
6776 // Check if we have any tracks that require squashing.
6777 // In that case, we'll have to write the packet here.
6778 if ((ret = mov_write_squashed_packets(s)) < 0)
6779 return ret;
6780
6781 // Try to fill in the duration of the last packet in each stream
6782 // from queued packets in the interleave queues. If the flushing
6783 // of fragments was triggered automatically by an AVPacket, we
6784 // already have reliable info for the end of that track, but other
6785 // tracks may need to be filled in.
6786 for (i = 0; i < mov->nb_streams; i++) {
6787 MOVTrack *track = &mov->tracks[i];
6788 if (!track->end_reliable) {
6789 const AVPacket *pkt = ff_interleaved_peek(s, i);
6790 if (pkt) {
6791 int64_t offset, dts, pts;
6793 pts = pkt->pts + offset;
6794 dts = pkt->dts + offset;
6795 if (track->dts_shift != AV_NOPTS_VALUE)
6796 dts += track->dts_shift;
6797 track->track_duration = dts - track->start_dts;
6798 if (pts != AV_NOPTS_VALUE)
6799 track->end_pts = pts;
6800 else
6801 track->end_pts = dts;
6802 if (!(pkt->flags & AV_PKT_FLAG_DISCARD))
6803 track->elst_end_pts = track->end_pts;
6804 }
6805 }
6806 }
6807
6808 for (i = 0; i < mov->nb_tracks; i++) {
6809 MOVTrack *track = &mov->tracks[i];
6810 if (track->entry <= 1)
6811 continue;
6812 // Sample durations are calculated as the diff of dts values,
6813 // but for the last sample in a fragment, we don't know the dts
6814 // of the first sample in the next fragment, so we have to rely
6815 // on what was set as duration in the AVPacket. Not all callers
6816 // set this though, so we might want to replace it with an
6817 // estimate if it currently is zero.
6818 if (get_cluster_duration(track, track->entry - 1) != 0)
6819 continue;
6820 // Use the duration (i.e. dts diff) of the second last sample for
6821 // the last one. This is a wild guess (and fatal if it turns out
6822 // to be too long), but probably the best we can do - having a zero
6823 // duration is bad as well.
6824 track->track_duration += get_cluster_duration(track, track->entry - 2);
6825 track->end_pts += get_cluster_duration(track, track->entry - 2);
6826 if (!mov->missing_duration_warned) {
6828 "Estimating the duration of the last packet in a "
6829 "fragment, consider setting the duration field in "
6830 "AVPacket instead.\n");
6831 mov->missing_duration_warned = 1;
6832 }
6833 }
6834
6835 if (!mov->moov_written) {
6836 int64_t pos = avio_tell(s->pb);
6837 uint8_t *buf;
6838 int buf_size, moov_size;
6839
6840 for (i = 0; i < mov->nb_tracks; i++)
6841 if (!mov->tracks[i].entry && !is_cover_image(mov->tracks[i].st))
6842 break;
6843 /* Don't write the initial moov unless all tracks have data */
6844 if (i < mov->nb_tracks && !force)
6845 return 0;
6846
6847 moov_size = get_moov_size(s);
6848 for (i = 0; i < mov->nb_tracks; i++)
6849 mov->tracks[i].data_offset = pos + moov_size + 8;
6850
6852 if (mov->flags & FF_MOV_FLAG_DELAY_MOOV &&
6855 if ((ret = mov_write_moov_tag(s->pb, mov, s)) < 0)
6856 return ret;
6857
6858 if (mov->flags & FF_MOV_FLAG_DELAY_MOOV) {
6859 if (mov->flags & FF_MOV_FLAG_GLOBAL_SIDX)
6860 mov->reserved_header_pos = avio_tell(s->pb);
6862 mov->moov_written = 1;
6863 return 0;
6864 }
6865
6866 if (mov->mdat_buf) {
6867 buf_size = avio_get_dyn_buf(mov->mdat_buf, &buf);
6868 avio_wb32(s->pb, buf_size + 8);
6869 ffio_wfourcc(s->pb, "mdat");
6870 avio_write(s->pb, buf, buf_size);
6872 }
6873
6874 if (mov->flags & FF_MOV_FLAG_GLOBAL_SIDX)
6875 mov->reserved_header_pos = avio_tell(s->pb);
6876
6877 mov->moov_written = 1;
6878 mov->mdat_size = 0;
6879 for (i = 0; i < mov->nb_tracks; i++)
6880 mov_finish_fragment(mov, &mov->tracks[i], 0);
6882 return 0;
6883 }
6884
6885 if (mov->frag_interleave) {
6886 for (i = 0; i < mov->nb_tracks; i++) {
6887 MOVTrack *track = &mov->tracks[i];
6888 int ret;
6889 if ((ret = mov_flush_fragment_interleaving(s, track)) < 0)
6890 return ret;
6891 }
6892
6893 if (!mov->mdat_buf)
6894 return 0;
6895 mdat_size = avio_tell(mov->mdat_buf);
6896 }
6897
6898 for (i = 0; i < mov->nb_tracks; i++) {
6899 MOVTrack *track = &mov->tracks[i];
6901 track->data_offset = 0;
6902 else
6903 track->data_offset = mdat_size;
6904 if (track->par->codec_type == AVMEDIA_TYPE_VIDEO) {
6905 has_video = 1;
6906 if (first_video_track) {
6907 if (track->entry)
6908 starts_with_key = track->cluster[0].flags & MOV_SYNC_SAMPLE;
6909 first_video_track = 0;
6910 }
6911 }
6912 if (!track->entry)
6913 continue;
6914 if (track->mdat_buf)
6915 mdat_size += avio_tell(track->mdat_buf);
6916 if (first_track < 0)
6917 first_track = i;
6918 }
6919
6920 if (!mdat_size)
6921 return 0;
6922
6923 avio_write_marker(s->pb,
6924 av_rescale(mov->tracks[first_track].cluster[0].dts, AV_TIME_BASE, mov->tracks[first_track].timescale),
6925 (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);
6926
6927 for (i = first_track; i < mov->nb_tracks; i++) {
6928 MOVTrack *track = &mov->tracks[i];
6929 int buf_size, write_moof = 1, moof_tracks = -1;
6930 uint8_t *buf;
6931
6932 if (!track->entry)
6933 continue;
6934 if (mov->flags & FF_MOV_FLAG_SEPARATE_MOOF) {
6935 mdat_size = avio_tell(track->mdat_buf);
6936 moof_tracks = i;
6937 } else {
6938 write_moof = i == first_track;
6939 }
6940
6941 if (write_moof) {
6943
6944 mov_write_moof_tag(s->pb, mov, moof_tracks, mdat_size);
6945 mov->fragments++;
6946
6947 if (track->cenc.aes_ctr)
6948 ff_mov_cenc_flush(&track->cenc);
6949
6950 avio_wb32(s->pb, mdat_size + 8);
6951 ffio_wfourcc(s->pb, "mdat");
6952 mdat_start = avio_tell(s->pb);
6953 }
6954
6955 mov_finish_fragment(mov, &mov->tracks[i], mdat_start);
6956 if (!mov->frag_interleave) {
6957 if (!track->mdat_buf)
6958 continue;
6959 buf_size = avio_get_dyn_buf(track->mdat_buf, &buf);
6960 avio_write(s->pb, buf, buf_size);
6962 } else {
6963 if (!mov->mdat_buf)
6964 continue;
6965 buf_size = avio_get_dyn_buf(mov->mdat_buf, &buf);
6966 avio_write(s->pb, buf, buf_size);
6968 }
6969 }
6970
6971 mov->mdat_size = 0;
6972
6974 return 0;
6975}
6976
6978{
6979 MOVMuxContext *mov = s->priv_data;
6980 int had_moov = mov->moov_written;
6981 int ret = mov_flush_fragment(s, force);
6982 if (ret < 0)
6983 return ret;
6984 // If using delay_moov, the first flush only wrote the moov,
6985 // not the actual moof+mdat pair, thus flush once again.
6986 if (!had_moov && mov->flags & FF_MOV_FLAG_DELAY_MOOV)
6987 ret = mov_flush_fragment(s, force);
6988 return ret;
6989}
6990
6992{
6993 int64_t ref;
6994 uint64_t duration;
6995
6996 if (trk->entry) {
6997 ref = trk->cluster[trk->entry - 1].dts;
6998 } else if ( trk->start_dts != AV_NOPTS_VALUE
6999 && !trk->frag_discont) {
7000 ref = trk->start_dts + trk->track_duration;
7001 } else
7002 ref = pkt->dts; // Skip tests for the first packet
7003
7004 if (trk->dts_shift != AV_NOPTS_VALUE) {
7005 /* With negative CTS offsets we have set an offset to the DTS,
7006 * reverse this for the check. */
7007 ref -= trk->dts_shift;
7008 }
7009
7010 duration = pkt->dts - ref;
7011 if (pkt->dts < ref || duration >= INT_MAX) {
7012 av_log(s, AV_LOG_WARNING, "Packet duration: %"PRId64" / dts: %"PRId64" in stream %d is out of range\n",
7013 duration, pkt->dts, pkt->stream_index);
7014
7015 pkt->dts = ref + 1;
7016 pkt->pts = AV_NOPTS_VALUE;
7017 }
7018
7019 if (pkt->duration < 0 || pkt->duration > INT_MAX) {
7020 av_log(s, AV_LOG_ERROR, "Application provided duration: %"PRId64" in stream %d is invalid\n", pkt->duration, pkt->stream_index);
7021 return AVERROR(EINVAL);
7022 }
7023 return 0;
7024}
7025
7027 const AVPacket *pkt, AVRational src_time_base)
7028{
7029 MOVMuxContext *mov = s->priv_data;
7030 AVStream *st;
7031 MOVTrack *track;
7032 int64_t offset, dts, pts, candidate_duration;
7033
7034 if (!(mov->flags & FF_MOV_FLAG_FRAGMENT) ||
7035 stream_index < 0 || stream_index >= s->nb_streams ||
7036 pkt->dts == AV_NOPTS_VALUE)
7037 return 0;
7038
7039 st = s->streams[stream_index];
7040 track = st->priv_data;
7041 if (!track->entry || track->start_dts == AV_NOPTS_VALUE)
7042 return 0;
7043
7044 if (ff_get_muxer_ts_offset(s, stream_index, &offset) < 0)
7045 return 0;
7046
7047 dts = av_rescale_q(pkt->dts, src_time_base, st->time_base) + offset;
7048 pts = pkt->pts == AV_NOPTS_VALUE
7050 : av_rescale_q(pkt->pts, src_time_base, st->time_base) + offset;
7051 if (track->dts_shift != AV_NOPTS_VALUE)
7052 dts += track->dts_shift;
7053
7054 candidate_duration = dts - track->start_dts;
7055 if (dts <= track->cluster[track->entry - 1].dts ||
7056 candidate_duration < 0 || candidate_duration >= track->track_duration)
7057 return 0;
7058
7059 track->track_duration = candidate_duration;
7060 track->end_pts = pts != AV_NOPTS_VALUE ? pts : dts;
7061 if (!(pkt->flags & AV_PKT_FLAG_DISCARD))
7062 track->elst_end_pts = track->end_pts;
7063 track->end_reliable = 1;
7064
7065 return 1;
7066}
7067
7069{
7070 MOVMuxContext *mov = s->priv_data;
7071 AVIOContext *pb = s->pb;
7072 MOVTrack *trk;
7073 AVCodecParameters *par;
7075 unsigned int samples_in_chunk = 0;
7077 int size = pkt->size, ret = 0, offset = 0;
7078 size_t prft_size;
7079 uint8_t *reformatted_data = NULL;
7080
7081 if (pkt->stream_index < s->nb_streams)
7082 trk = s->streams[pkt->stream_index]->priv_data;
7083 else // Timecode or chapter
7084 trk = &mov->tracks[pkt->stream_index];
7085 par = trk->par;
7086
7087 ret = check_pkt(s, trk, pkt);
7088 if (ret < 0)
7089 return ret;
7090
7091 if (pkt->pts != AV_NOPTS_VALUE &&
7092 (uint64_t)pkt->dts - pkt->pts != (int32_t)((uint64_t)pkt->dts - pkt->pts)) {
7093 av_log(s, AV_LOG_WARNING, "pts/dts pair unsupported\n");
7094 return AVERROR_PATCHWELCOME;
7095 }
7096
7097 if (mov->flags & FF_MOV_FLAG_FRAGMENT || mov->mode == MODE_AVIF) {
7098 int ret;
7099 if (mov->moov_written || mov->flags & FF_MOV_FLAG_EMPTY_MOOV) {
7100 if (mov->frag_interleave && mov->fragments > 0) {
7101 if (trk->entry - trk->entries_flushed >= mov->frag_interleave) {
7102 if ((ret = mov_flush_fragment_interleaving(s, trk)) < 0)
7103 return ret;
7104 }
7105 }
7106
7107 if (!trk->mdat_buf) {
7108 if ((ret = avio_open_dyn_buf(&trk->mdat_buf)) < 0)
7109 return ret;
7110 }
7111 pb = trk->mdat_buf;
7112 } else {
7113 if (!mov->mdat_buf) {
7114 if ((ret = avio_open_dyn_buf(&mov->mdat_buf)) < 0)
7115 return ret;
7116 }
7117 pb = mov->mdat_buf;
7118 }
7119 }
7120
7121 if (par->codec_id == AV_CODEC_ID_AMR_NB) {
7122 /* We must find out how many AMR blocks there are in one packet */
7123 static const uint16_t packed_size[16] =
7124 {13, 14, 16, 18, 20, 21, 27, 32, 6, 0, 0, 0, 0, 0, 0, 1};
7125 int len = 0;
7126
7127 while (len < size && samples_in_chunk < 100) {
7128 len += packed_size[(pkt->data[len] >> 3) & 0x0F];
7129 samples_in_chunk++;
7130 }
7131 if (samples_in_chunk > 1) {
7132 av_log(s, AV_LOG_ERROR, "fatal error, input is not a single packet, implement a AVParser for it\n");
7133 return -1;
7134 }
7135 } else if (par->codec_id == AV_CODEC_ID_ADPCM_MS ||
7137 samples_in_chunk = trk->par->frame_size;
7138 } else if (trk->sample_size)
7139 samples_in_chunk = size / trk->sample_size;
7140 else
7141 samples_in_chunk = 1;
7142
7143 if (samples_in_chunk < 1) {
7144 av_log(s, AV_LOG_ERROR, "fatal error, input packet contains no samples\n");
7145 return AVERROR_PATCHWELCOME;
7146 }
7147
7148 /* copy extradata if it exists */
7149 if (trk->extradata_size[0] == 0 && par->extradata_size > 0 &&
7150 !TAG_IS_AVCI(trk->tag) &&
7151 (par->codec_id != AV_CODEC_ID_DNXHD)) {
7152 trk->extradata[0] = av_memdup(par->extradata, par->extradata_size);
7153 if (!trk->extradata[0]) {
7154 ret = AVERROR(ENOMEM);
7155 goto err;
7156 }
7157 trk->extradata_size[0] = par->extradata_size;
7158 }
7159
7160 if ((par->codec_id == AV_CODEC_ID_DNXHD ||
7161 par->codec_id == AV_CODEC_ID_H264 ||
7162 par->codec_id == AV_CODEC_ID_HEVC ||
7163 par->codec_id == AV_CODEC_ID_VVC ||
7164 par->codec_id == AV_CODEC_ID_VP9 ||
7165 par->codec_id == AV_CODEC_ID_EVC ||
7166 par->codec_id == AV_CODEC_ID_LCEVC ||
7167 par->codec_id == AV_CODEC_ID_TRUEHD) && !trk->extradata_size[0] &&
7168 !TAG_IS_AVCI(trk->tag)) {
7169 /* copy frame to create needed atoms */
7170 trk->extradata_size[0] = size;
7172 if (!trk->extradata[0]) {
7173 ret = AVERROR(ENOMEM);
7174 goto err;
7175 }
7176 memcpy(trk->extradata[0], pkt->data, size);
7177 memset(trk->extradata[0] + size, 0, AV_INPUT_BUFFER_PADDING_SIZE);
7178 }
7179
7180 const AVPacketSideData *sd = av_packet_side_data_get(pkt->side_data, pkt->side_data_elems, AV_PKT_DATA_NEW_EXTRADATA);
7181 if (pkt->size && sd && sd->size > 0) {
7182 int i;
7183 for (i = 0; i < trk->stsd_count; i++) {
7184 if (trk->extradata_size[i] == sd->size && !memcmp(trk->extradata[i], sd->data, sd->size))
7185 break;
7186 }
7187
7188 if (i < trk->stsd_count)
7189 trk->last_stsd_index = i;
7190 else if (trk->stsd_count <= INT_MAX - 1) {
7191 int new_count = trk->stsd_count + 1;
7192 uint8_t **extradata = av_realloc_array(trk->extradata, new_count, sizeof(*trk->extradata));
7193 if (!extradata)
7194 return AVERROR(ENOMEM);
7195 trk->extradata = extradata;
7196
7197 int *extradata_size = av_realloc_array(trk->extradata_size, new_count, sizeof(*trk->extradata_size));
7198 if (!extradata_size)
7199 return AVERROR(ENOMEM);
7200 trk->extradata_size = extradata_size;
7201
7202 trk->extradata[trk->stsd_count] = av_memdup(sd->data, sd->size);
7203 if (!trk->extradata[trk->stsd_count])
7204 return AVERROR(ENOMEM);
7205
7206 trk->extradata_size[trk->stsd_count] = sd->size;
7207 trk->last_stsd_index = trk->stsd_count;
7208 trk->stsd_count = new_count;
7209 } else
7210 return AVERROR(ENOMEM);
7211 }
7212
7213 if (par->codec_id == AV_CODEC_ID_AAC && pkt->size > 2 &&
7214 (AV_RB16(pkt->data) & 0xfff0) == 0xfff0) {
7215 if (!trk->st->nb_frames) {
7216 av_log(s, AV_LOG_ERROR, "Malformed AAC bitstream detected: "
7217 "use the audio bitstream filter 'aac_adtstoasc' to fix it "
7218 "('-bsf:a aac_adtstoasc' option with ffmpeg)\n");
7219 return -1;
7220 }
7221 av_log(s, AV_LOG_WARNING, "aac bitstream error\n");
7222 }
7223 if (par->codec_id == AV_CODEC_ID_H264 && trk->extradata_size[trk->last_stsd_index] > 0 &&
7224 *(uint8_t *)trk->extradata[trk->last_stsd_index] != 1 && !TAG_IS_AVCI(trk->tag)) {
7225 /* from x264 or from bytestream H.264 */
7226 /* NAL reformatting needed */
7227 if (trk->hint_track >= 0 && trk->hint_track < mov->nb_tracks) {
7228 ret = ff_nal_parse_units_buf(pkt->data, &reformatted_data,
7229 &size);
7230 if (ret < 0)
7231 return ret;
7232 avio_write(pb, reformatted_data, size);
7233 } else {
7234 if (trk->cenc.aes_ctr) {
7235 size = ff_mov_cenc_avc_parse_nal_units(&trk->cenc, pb, pkt->data, size);
7236 if (size < 0) {
7237 ret = size;
7238 goto err;
7239 }
7240 } else {
7241 size = ff_nal_parse_units(pb, pkt->data, pkt->size);
7242 }
7243 }
7244 } else if (par->codec_id == AV_CODEC_ID_HEVC && trk->extradata_size[trk->last_stsd_index] > 6 &&
7245 (AV_RB24(trk->extradata[trk->last_stsd_index]) == 1 || AV_RB32(trk->extradata[trk->last_stsd_index]) == 1)) {
7246 /* extradata is Annex B, assume the bitstream is too and convert it */
7247 int filter_ps = (trk->tag == MKTAG('h','v','c','1'));
7248 if (trk->hint_track >= 0 && trk->hint_track < mov->nb_tracks) {
7249 ret = ff_hevc_annexb2mp4_buf(pkt->data, &reformatted_data,
7250 &size, filter_ps, NULL);
7251 if (ret < 0)
7252 return ret;
7253 avio_write(pb, reformatted_data, size);
7254 } else {
7255 if (trk->cenc.aes_ctr) {
7256 size = ff_mov_cenc_avc_parse_nal_units(&trk->cenc, pb, pkt->data, size);
7257 if (size < 0) {
7258 ret = size;
7259 goto err;
7260 }
7261 } else {
7262 size = ff_hevc_annexb2mp4(pb, pkt->data, pkt->size, filter_ps, NULL);
7263 }
7264 }
7265 } else if (par->codec_id == AV_CODEC_ID_VVC && trk->extradata_size[trk->last_stsd_index] > 6 &&
7266 (AV_RB24(trk->extradata[trk->last_stsd_index]) == 1 || AV_RB32(trk->extradata[trk->last_stsd_index]) == 1)) {
7267 /* extradata is Annex B, assume the bitstream is too and convert it */
7268 if (trk->hint_track >= 0 && trk->hint_track < mov->nb_tracks) {
7269 ret = ff_vvc_annexb2mp4_buf(pkt->data, &reformatted_data,
7270 &size, 0, NULL);
7271 if (ret < 0)
7272 return ret;
7273 avio_write(pb, reformatted_data, size);
7274 } else {
7275 size = ff_vvc_annexb2mp4(pb, pkt->data, pkt->size, 0, NULL);
7276 }
7277 } else if (par->codec_id == AV_CODEC_ID_LCEVC && trk->extradata_size[trk->last_stsd_index] > 0 &&
7278 *(uint8_t *)trk->extradata[trk->last_stsd_index] != 1) {
7279 /* extradata is Annex B, assume the bitstream is too and convert it */
7280 if (trk->hint_track >= 0 && trk->hint_track < mov->nb_tracks) {
7281 ret = ff_nal_parse_units_buf(pkt->data, &reformatted_data, &size);
7282 if (ret < 0)
7283 return ret;
7284 avio_write(pb, reformatted_data, size);
7285 } else {
7286 if (trk->cenc.aes_ctr) {
7287 size = ff_mov_cenc_avc_parse_nal_units(&trk->cenc, pb, pkt->data, size);
7288 if (size < 0) {
7289 ret = size;
7290 goto err;
7291 }
7292 } else {
7293 size = ff_nal_parse_units(pb, pkt->data, pkt->size);
7294 }
7295 }
7296 } else if (par->codec_id == AV_CODEC_ID_AV1 && !trk->cenc.aes_ctr) {
7297 if (trk->hint_track >= 0 && trk->hint_track < mov->nb_tracks) {
7298 ret = ff_av1_filter_obus_buf(pkt->data, &reformatted_data,
7299 &size, &offset);
7300 if (ret < 0)
7301 return ret;
7302 avio_write(pb, reformatted_data, size);
7303 } else {
7304 size = ff_av1_filter_obus(pb, pkt->data, pkt->size);
7305 if (trk->mode == MODE_AVIF && !mov->avif_extent_length[pkt->stream_index]) {
7306 mov->avif_extent_length[pkt->stream_index] = size;
7307 }
7308 }
7309
7310 } else if (par->codec_id == AV_CODEC_ID_AC3 ||
7311 par->codec_id == AV_CODEC_ID_EAC3) {
7312 size = handle_eac3(mov, pkt, trk);
7313 if (size < 0)
7314 return size;
7315 else if (!size)
7316 goto end;
7317 avio_write(pb, pkt->data, size);
7318 } else if (par->codec_id == AV_CODEC_ID_EIA_608) {
7319 size = 8;
7320
7321 for (int i = 0; i < pkt->size; i += 3) {
7322 if (pkt->data[i] == 0xFC) {
7323 size += 2;
7324 }
7325 }
7326 avio_wb32(pb, size);
7327 ffio_wfourcc(pb, "cdat");
7328 for (int i = 0; i < pkt->size; i += 3) {
7329 if (pkt->data[i] == 0xFC) {
7330 avio_w8(pb, pkt->data[i + 1]);
7331 avio_w8(pb, pkt->data[i + 2]);
7332 }
7333 }
7334 } else if (par->codec_id == AV_CODEC_ID_APV) {
7335 ff_isom_parse_apvc(trk->apv, pkt, s);
7336 avio_wb32(s->pb, pkt->size);
7337 size += 4;
7338
7339 avio_write(s->pb, pkt->data, pkt->size);
7340 } else {
7341 if (trk->cenc.aes_ctr) {
7342 uint8_t *extradata = trk->extradata[trk->last_stsd_index];
7343 int extradata_size = trk->extradata_size[trk->last_stsd_index];
7344 if (par->codec_id == AV_CODEC_ID_H264 && extradata_size > 4) {
7345 int nal_size_length = (extradata[4] & 0x3) + 1;
7346 ret = ff_mov_cenc_avc_write_nal_units(s, &trk->cenc, nal_size_length, pb, pkt->data, size);
7347 } else if(par->codec_id == AV_CODEC_ID_HEVC && extradata_size > 21) {
7348 int nal_size_length = (extradata[21] & 0x3) + 1;
7349 ret = ff_mov_cenc_avc_write_nal_units(s, &trk->cenc, nal_size_length, pb, pkt->data, size);
7350 } else if(par->codec_id == AV_CODEC_ID_VVC) {
7352 } else if(par->codec_id == AV_CODEC_ID_AV1) {
7353 av_assert0(size == pkt->size);
7354 ret = ff_mov_cenc_av1_write_obus(s, &trk->cenc, pb, pkt);
7355 if (ret > 0) {
7356 size = ret;
7357 ret = 0;
7358 }
7359 } else {
7360 ret = ff_mov_cenc_write_packet(&trk->cenc, pb, pkt->data, size);
7361 }
7362
7363 if (ret) {
7364 goto err;
7365 }
7366 } else {
7367 avio_write(pb, pkt->data, size);
7368 }
7369 }
7370
7371 if (trk->entry >= trk->cluster_capacity) {
7372 unsigned new_capacity = trk->entry + MOV_INDEX_CLUSTER_SIZE;
7373 void *cluster = av_realloc_array(trk->cluster, new_capacity, sizeof(*trk->cluster));
7374 if (!cluster) {
7375 ret = AVERROR(ENOMEM);
7376 goto err;
7377 }
7378 trk->cluster = cluster;
7379 trk->cluster_capacity = new_capacity;
7380 }
7381
7382 trk->cluster[trk->entry].pos = avio_tell(pb) - size;
7383 trk->cluster[trk->entry].stsd_index = trk->last_stsd_index;
7384 trk->cluster[trk->entry].samples_in_chunk = samples_in_chunk;
7385 trk->cluster[trk->entry].chunkNum = 0;
7386 trk->cluster[trk->entry].size = size;
7387 trk->cluster[trk->entry].entries = samples_in_chunk;
7388 trk->cluster[trk->entry].dts = pkt->dts;
7389 trk->cluster[trk->entry].pts = pkt->pts;
7391 !trk->entry && trk->start_dts != AV_NOPTS_VALUE) {
7392 if (!trk->frag_discont) {
7393 /* First packet of a new fragment. We already wrote the duration
7394 * of the last packet of the previous fragment based on track_duration,
7395 * which might not exactly match our dts. Therefore adjust the dts
7396 * of this packet to be what the previous packets duration implies. */
7397 trk->cluster[trk->entry].dts = trk->start_dts + trk->track_duration;
7398 /* We also may have written the pts and the corresponding duration
7399 * in sidx/tfrf/tfxd tags; make sure the sidx pts and duration match up with
7400 * the next fragment. This means the cts of the first sample must
7401 * be the same in all fragments, unless end_pts was updated by
7402 * the packet causing the fragment to be written. */
7403 if ((mov->flags & FF_MOV_FLAG_DASH &&
7405 mov->mode == MODE_ISM)
7406 pkt->pts = pkt->dts + trk->end_pts - trk->cluster[trk->entry].dts;
7407 } else {
7408 /* New fragment, but discontinuous from previous fragments.
7409 * Pretend the duration sum of the earlier fragments is
7410 * pkt->dts - trk->start_dts. */
7411 trk->end_pts = trk->elst_end_pts = AV_NOPTS_VALUE;
7412 trk->frag_discont = 0;
7413 }
7414 }
7415
7416 if (!trk->entry && trk->start_dts == AV_NOPTS_VALUE && !mov->use_editlist &&
7417 s->avoid_negative_ts == AVFMT_AVOID_NEG_TS_MAKE_ZERO) {
7418 /* Not using edit lists and shifting the first track to start from zero.
7419 * If the other streams start from a later timestamp, we won't be able
7420 * to signal the difference in starting time without an edit list.
7421 * Thus move the timestamp for this first sample to 0, increasing
7422 * its duration instead. */
7423 trk->cluster[trk->entry].dts = trk->start_dts = 0;
7424 }
7425 if (trk->start_dts == AV_NOPTS_VALUE) {
7426 trk->start_dts = pkt->dts;
7427 if (trk->frag_discont) {
7428 if (mov->use_editlist) {
7429 /* Pretend the whole stream started at pts=0, with earlier fragments
7430 * already written. If the stream started at pts=0, the duration sum
7431 * of earlier fragments would have been pkt->pts. */
7432 trk->start_dts = pkt->dts - pkt->pts;
7433 } else {
7434 /* Pretend the whole stream started at dts=0, with earlier fragments
7435 * already written, with a duration summing up to pkt->dts. */
7436 trk->start_dts = 0;
7437 }
7438 trk->frag_discont = 0;
7439 } else if (pkt->dts && mov->moov_written)
7441 "Track %d starts with a nonzero dts %"PRId64", while the moov "
7442 "already has been written. Set the delay_moov flag to handle "
7443 "this case.\n",
7444 pkt->stream_index, pkt->dts);
7445 }
7446
7447 sd = av_packet_side_data_get(pkt->side_data, pkt->side_data_elems, AV_PKT_DATA_SKIP_SAMPLES);
7448 if (sd && sd->size >= 10 && trk->par->frame_size) {
7449 duration = FFMAX(av_rescale_q(trk->par->frame_size, (AVRational){ 1, trk->par->sample_rate },
7450 trk->st->time_base), pkt->duration);
7451 if (mov->use_editlist)
7452 pkt->duration = duration;
7453 duration -= av_rescale_q(AV_RL32(sd->data + 4), (AVRational){ 1, trk->par->sample_rate },
7454 trk->st->time_base);
7455 if (duration < 0)
7456 return AVERROR_INVALIDDATA;
7457 } else
7458 duration = pkt->duration;
7459
7460 trk->track_duration = pkt->dts - trk->start_dts + pkt->duration;
7462
7463 if (pkt->pts == AV_NOPTS_VALUE) {
7464 av_log(s, AV_LOG_WARNING, "pts has no value\n");
7465 pkt->pts = pkt->dts;
7466 }
7467 if (pkt->dts != pkt->pts)
7468 trk->flags |= MOV_TRACK_CTTS;
7469 trk->cluster[trk->entry].cts = pkt->pts - pkt->dts;
7470 trk->cluster[trk->entry].flags = 0;
7471 if (trk->start_cts == AV_NOPTS_VALUE || (pkt->dts <= 0 && trk->start_cts > pkt->pts - pkt->dts))
7472 trk->start_cts = pkt->pts - pkt->dts;
7473 if (trk->end_pts == AV_NOPTS_VALUE)
7474 trk->end_pts = trk->cluster[trk->entry].dts +
7475 trk->cluster[trk->entry].cts + duration;
7476 else
7477 trk->end_pts = FFMAX(trk->end_pts, trk->cluster[trk->entry].dts +
7478 trk->cluster[trk->entry].cts +
7479 duration);
7480 if (!(pkt->flags & AV_PKT_FLAG_DISCARD))
7481 trk->elst_end_pts = trk->end_pts;
7482
7483 if (par->codec_id == AV_CODEC_ID_VC1) {
7485 } else if (par->codec_id == AV_CODEC_ID_TRUEHD) {
7487 } else if (pkt->flags & AV_PKT_FLAG_KEY) {
7488 if (mov->mode == MODE_MOV && par->codec_id == AV_CODEC_ID_MPEG2VIDEO &&
7489 trk->entry > 0) { // force sync sample for the first key frame
7491 if (trk->cluster[trk->entry].flags & MOV_PARTIAL_SYNC_SAMPLE)
7492 trk->flags |= MOV_TRACK_STPS;
7493 } else {
7494 trk->cluster[trk->entry].flags = MOV_SYNC_SAMPLE;
7495 }
7496 if (trk->cluster[trk->entry].flags & MOV_SYNC_SAMPLE)
7497 trk->has_keyframes++;
7498 }
7499 if (pkt->flags & AV_PKT_FLAG_DISPOSABLE) {
7501 trk->has_disposable++;
7502 }
7503
7505 if (prft && prft_size == sizeof(AVProducerReferenceTime))
7506 memcpy(&trk->cluster[trk->entry].prft, prft, prft_size);
7507 else
7508 memset(&trk->cluster[trk->entry].prft, 0, sizeof(AVProducerReferenceTime));
7509
7510 trk->entry++;
7511 trk->sample_count += samples_in_chunk;
7512 mov->mdat_size += size;
7513
7514 if (trk->hint_track >= 0 && trk->hint_track < mov->nb_tracks)
7516 reformatted_data ? reformatted_data + offset
7517 : NULL, size);
7518
7519end:
7520err:
7521
7522 if (pkt->data != reformatted_data)
7523 av_free(reformatted_data);
7524 return ret;
7525}
7526
7528{
7529 MOVMuxContext *mov = s->priv_data;
7530 MOVTrack *trk = s->streams[pkt->stream_index]->priv_data;
7531 AVCodecParameters *par = trk->par;
7532 int64_t frag_duration = 0;
7533 int size = pkt->size;
7534
7535 int ret = check_pkt(s, trk, pkt);
7536 if (ret < 0)
7537 return ret;
7538
7539 if (mov->flags & FF_MOV_FLAG_FRAG_DISCONT) {
7540 for (int i = 0; i < mov->nb_streams; i++)
7541 mov->tracks[i].frag_discont = 1;
7543 }
7544
7546 if (trk->dts_shift == AV_NOPTS_VALUE)
7547 trk->dts_shift = pkt->pts - pkt->dts;
7548 pkt->dts += trk->dts_shift;
7549 }
7550
7551 if (trk->par->codec_id == AV_CODEC_ID_MP4ALS ||
7552 trk->par->codec_id == AV_CODEC_ID_AAC ||
7553 trk->par->codec_id == AV_CODEC_ID_AV1 ||
7554 trk->par->codec_id == AV_CODEC_ID_FLAC) {
7555 size_t side_size;
7556 uint8_t *side = av_packet_get_side_data(pkt, AV_PKT_DATA_NEW_EXTRADATA, &side_size);
7557 /* Overwrite extradata only on flush packets or when no extradata was available during init */
7558 if (side_size > 0 && (!pkt->size || !trk->extradata_size[trk->last_stsd_index])) {
7559 void *newextra = av_malloc(side_size + AV_INPUT_BUFFER_PADDING_SIZE);
7560 if (!newextra)
7561 return AVERROR(ENOMEM);
7562 memset((uint8_t*)newextra + side_size, 0, AV_INPUT_BUFFER_PADDING_SIZE);
7563 memcpy(newextra, side, side_size);
7564 av_free(trk->extradata[trk->last_stsd_index]);
7565 trk->extradata[trk->last_stsd_index] = newextra;
7566 trk->extradata_size[trk->last_stsd_index] = side_size;
7567 }
7568 }
7569
7570 if (!pkt->size) {
7571 if (trk->start_dts == AV_NOPTS_VALUE && trk->frag_discont) {
7572 trk->start_dts = pkt->dts;
7573 if (pkt->pts != AV_NOPTS_VALUE)
7574 trk->start_cts = pkt->pts - pkt->dts;
7575 else
7576 trk->start_cts = 0;
7577 }
7578
7579 return 0; /* Discard 0 sized packets */
7580 }
7581
7582 if (trk->entry && pkt->stream_index < mov->nb_streams)
7583 frag_duration = av_rescale_q(pkt->dts - trk->cluster[0].dts,
7584 s->streams[pkt->stream_index]->time_base,
7586 if ((mov->max_fragment_duration &&
7587 frag_duration >= mov->max_fragment_duration) ||
7588 (mov->max_fragment_size && mov->mdat_size + size >= mov->max_fragment_size) ||
7591 trk->entry && pkt->flags & AV_PKT_FLAG_KEY) ||
7593 if (frag_duration >= mov->min_fragment_duration) {
7594 if (trk->entry) {
7595 // Set the duration of this track to line up with the next
7596 // sample in this track. This avoids relying on AVPacket
7597 // duration, but only helps for this particular track, not
7598 // for the other ones that are flushed at the same time.
7599 //
7600 // If we have trk->entry == 0, no fragment will be written
7601 // for this track, and we can't adjust the track end here.
7602 trk->track_duration = pkt->dts - trk->start_dts;
7603 if (pkt->pts != AV_NOPTS_VALUE)
7604 trk->end_pts = pkt->pts;
7605 else
7606 trk->end_pts = pkt->dts;
7607 if (!(pkt->flags & AV_PKT_FLAG_DISCARD))
7608 trk->elst_end_pts = trk->end_pts;
7609 trk->end_reliable = 1;
7610 }
7612 }
7613 }
7614
7615 return ff_mov_write_packet(s, pkt);
7616}
7617
7619 int stream_index,
7620 int64_t dts) {
7621 MOVMuxContext *mov = s->priv_data;
7622 AVPacket *end = mov->pkt;
7623 uint8_t data[2] = {0};
7624 int ret;
7625
7626 end->size = sizeof(data);
7627 end->data = data;
7628 end->pts = dts;
7629 end->dts = dts;
7630 end->duration = 0;
7631 end->stream_index = stream_index;
7632
7634 av_packet_unref(end);
7635
7636 return ret;
7637}
7638
7639#if CONFIG_IAMFENC
7640static int mov_build_iamf_packet(AVFormatContext *s, MOVTrack *trk, AVPacket *pkt)
7641{
7642 uint8_t *data;
7643 int ret;
7644
7645 if (pkt->stream_index == trk->first_iamf_idx) {
7647 if (ret < 0)
7648 return ret;
7649 }
7650
7652 s->streams[pkt->stream_index]->id, pkt);
7653 if (ret < 0)
7654 return ret;
7655
7656 if (pkt->stream_index != trk->last_iamf_idx)
7657 return AVERROR(EAGAIN);
7658
7660 trk->iamf_buf = NULL;
7661 if (!ret) {
7662 if (pkt->size) {
7663 // Either all or none of the packets for a single
7664 // IA Sample may be empty.
7665 av_log(s, AV_LOG_ERROR, "Unexpected packet from "
7666 "stream #%d\n", pkt->stream_index);
7668 }
7669 av_free(data);
7670 return ret;
7671 }
7672
7673 av_buffer_unref(&pkt->buf);
7674 pkt->buf = av_buffer_create(data, ret, NULL, NULL, 0);
7675 if (!pkt->buf) {
7676 av_free(data);
7677 return AVERROR(ENOMEM);
7678 }
7679 pkt->data = data;
7680 pkt->size = ret;
7681 pkt->stream_index = trk->first_iamf_idx;
7682
7683 return avio_open_dyn_buf(&trk->iamf_buf);
7684}
7685#endif
7686
7688{
7689 int64_t pos = avio_tell(pb);
7690 const char *scheme_id_uri = "https://aomedia.org/emsg/ID3";
7691 const char *value = "";
7692
7693 av_assert0(st->time_base.num == 1);
7694
7698
7699 avio_wb32(pb, 0); /* size */
7700 ffio_wfourcc(pb, "emsg");
7701 avio_w8(pb, 1); /* version */
7702 avio_wb24(pb, 0);
7703 avio_wb32(pb, st->time_base.den); /* timescale */
7704 avio_wb64(pb, pkt->pts); /* presentation_time */
7705 avio_wb32(pb, 0xFFFFFFFFU); /* event_duration */
7706 avio_wb32(pb, 0); /* id */
7707 /* null terminated UTF8 strings */
7708 avio_write(pb, scheme_id_uri, strlen(scheme_id_uri) + 1);
7709 avio_write(pb, value, strlen(value) + 1);
7710 avio_write(pb, pkt->data, pkt->size);
7711
7712 return update_size(pb, pos);
7713}
7714
7716{
7717 MOVMuxContext *mov = s->priv_data;
7718 MOVTrack *trk;
7719
7720 if (!pkt) {
7722 return 1;
7723 }
7724
7725 if (s->streams[pkt->stream_index]->codecpar->codec_id == AV_CODEC_ID_TIMED_ID3) {
7726 mov_write_emsg_tag(s->pb, s->streams[pkt->stream_index], pkt);
7727 return 0;
7728 }
7729
7730 trk = s->streams[pkt->stream_index]->priv_data;
7731
7732#if CONFIG_IAMFENC
7733 if (trk->iamf) {
7734 int ret = mov_build_iamf_packet(s, trk, pkt);
7735 if (ret < 0) {
7736 if (ret == AVERROR(EAGAIN))
7737 return 0;
7738 av_log(s, AV_LOG_ERROR, "Error assembling an IAMF packet "
7739 "for stream #%d\n", trk->st->index);
7740 return ret;
7741 }
7742 }
7743#endif
7744
7745 if (is_cover_image(trk->st)) {
7746 int ret;
7747
7748 if (trk->st->nb_frames >= 1) {
7749 if (trk->st->nb_frames == 1)
7750 av_log(s, AV_LOG_WARNING, "Got more than one picture in stream %d,"
7751 " ignoring.\n", pkt->stream_index);
7752 return 0;
7753 }
7754
7755 if ((ret = av_packet_ref(trk->cover_image, pkt)) < 0)
7756 return ret;
7757
7758 return 0;
7759 } else {
7760 int i;
7761
7762 if (!pkt->size)
7763 return mov_write_single_packet(s, pkt); /* Passthrough. */
7764
7765 /*
7766 * Subtitles require special handling.
7767 *
7768 * 1) For full compliance, every track must have a sample at
7769 * dts == 0, which is rarely true for subtitles. So, as soon
7770 * as we see any packet with dts > 0, write an empty subtitle
7771 * at dts == 0 for any subtitle track with no samples in it.
7772 *
7773 * 2) For each subtitle track, check if the current packet's
7774 * dts is past the duration of the last subtitle sample. If
7775 * so, we now need to write an end sample for that subtitle.
7776 *
7777 * This must be done conditionally to allow for subtitles that
7778 * immediately replace each other, in which case an end sample
7779 * is not needed, and is, in fact, actively harmful.
7780 *
7781 * 3) See mov_write_trailer for how the final end sample is
7782 * handled.
7783 */
7784 for (i = 0; i < mov->nb_tracks; i++) {
7785 MOVTrack *trk = &mov->tracks[i];
7786 int ret;
7787
7788 if (trk->par->codec_id == AV_CODEC_ID_MOV_TEXT &&
7789 trk->track_duration < pkt->dts &&
7790 (trk->entry == 0 || !trk->last_sample_is_subtitle_end)) {
7792 if (ret < 0) return ret;
7794 }
7795 }
7796
7798 /*
7799 * If the track has to have its samples squashed into one sample,
7800 * we just take it into the track's queue.
7801 * This will then be utilized as the samples get written in either
7802 * mov_flush_fragment or when the mux is finalized in
7803 * mov_write_trailer.
7804 */
7805 int ret = AVERROR_BUG;
7806
7807 if (pkt->pts == AV_NOPTS_VALUE) {
7809 "Packets without a valid presentation timestamp are "
7810 "not supported with packet squashing!\n");
7811 return AVERROR(EINVAL);
7812 }
7813
7814 /* The following will reset pkt and is only allowed to be used
7815 * because we return immediately. afterwards. */
7817 pkt, NULL, 0)) < 0) {
7818 return ret;
7819 }
7820
7821 return 0;
7822 }
7823
7824
7825 if (trk->mode == MODE_MOV && trk->par->codec_type == AVMEDIA_TYPE_VIDEO) {
7826 AVPacket *opkt = pkt;
7827 int reshuffle_ret, ret;
7828 if (trk->is_unaligned_qt_rgb) {
7829 int64_t bpc = trk->par->bits_per_coded_sample != 15 ? trk->par->bits_per_coded_sample : 16;
7830 int expected_stride = ((trk->par->width * bpc + 15) >> 4)*2;
7831 reshuffle_ret = ff_reshuffle_raw_rgb(s, &pkt, trk->par, expected_stride);
7832 if (reshuffle_ret < 0)
7833 return reshuffle_ret;
7834 } else
7835 reshuffle_ret = 0;
7836 if (trk->par->format == AV_PIX_FMT_PAL8 && !trk->pal_done) {
7837 ret = ff_get_packet_palette(s, opkt, reshuffle_ret, trk->palette);
7838 if (ret < 0)
7839 goto fail;
7840 if (ret)
7841 trk->pal_done++;
7842 } else if (trk->par->codec_id == AV_CODEC_ID_RAWVIDEO &&
7843 (trk->par->format == AV_PIX_FMT_GRAY8 ||
7844 trk->par->format == AV_PIX_FMT_MONOBLACK)) {
7846 if (ret < 0)
7847 goto fail;
7848 for (i = 0; i < pkt->size; i++)
7849 pkt->data[i] = ~pkt->data[i];
7850 }
7851 if (reshuffle_ret) {
7853fail:
7854 if (reshuffle_ret)
7856 return ret;
7857 }
7858 }
7859
7860 return mov_write_single_packet(s, pkt);
7861 }
7862}
7863
7864// QuickTime chapters involve an additional text track with the chapter names
7865// as samples, and a tref pointing from the other tracks to the chapter one.
7867{
7868 static const uint8_t stub_header[] = {
7869 // TextSampleEntry
7870 0x00, 0x00, 0x00, 0x01, // displayFlags
7871 0x00, 0x00, // horizontal + vertical justification
7872 0x00, 0x00, 0x00, 0x00, // bgColourRed/Green/Blue/Alpha
7873 // BoxRecord
7874 0x00, 0x00, 0x00, 0x00, // defTextBoxTop/Left
7875 0x00, 0x00, 0x00, 0x00, // defTextBoxBottom/Right
7876 // StyleRecord
7877 0x00, 0x00, 0x00, 0x00, // startChar + endChar
7878 0x00, 0x01, // fontID
7879 0x00, 0x00, // fontStyleFlags + fontSize
7880 0x00, 0x00, 0x00, 0x00, // fgColourRed/Green/Blue/Alpha
7881 // FontTableBox
7882 0x00, 0x00, 0x00, 0x0D, // box size
7883 'f', 't', 'a', 'b', // box atom name
7884 0x00, 0x01, // entry count
7885 // FontRecord
7886 0x00, 0x01, // font ID
7887 0x00, // font name length
7888 };
7889 MOVMuxContext *mov = s->priv_data;
7890 MOVTrack *track = &mov->tracks[tracknum];
7891 AVPacket *pkt = mov->pkt;
7892 int i, len;
7893 int ret;
7894
7895 track->mode = mov->mode;
7896 track->tag = MKTAG('t','e','x','t');
7897 track->timescale = mov->movie_timescale;
7898 track->par = avcodec_parameters_alloc();
7899 if (!track->par)
7900 return AVERROR(ENOMEM);
7902 ret = ff_alloc_extradata(track->par, sizeof(stub_header));
7903 if (ret < 0)
7904 return ret;
7905 memcpy(track->par->extradata, stub_header, sizeof(stub_header));
7906
7907 if (track->extradata == NULL) {
7908 track->stsd_count = 1;
7909 track->extradata = av_calloc(1, sizeof(*track->extradata));
7910 track->extradata_size = av_calloc(1, sizeof(*track->extradata_size));
7911 if (!track->extradata || !track->extradata_size)
7912 return AVERROR(ENOMEM);
7913 }
7914
7915 track->extradata[0] = av_memdup(stub_header, sizeof(stub_header));
7916 if (!track->extradata[0])
7917 return AVERROR(ENOMEM);
7918 track->extradata_size[0] = sizeof(stub_header);
7919
7920 pkt->stream_index = tracknum;
7921 pkt->flags = AV_PKT_FLAG_KEY;
7922
7923 for (i = 0; i < s->nb_chapters; i++) {
7924 AVChapter *c = s->chapters[i];
7926
7927 int64_t end = av_rescale_q(c->end, c->time_base, (AVRational){1,mov->movie_timescale});
7928 pkt->pts = pkt->dts = av_rescale_q(c->start, c->time_base, (AVRational){1,mov->movie_timescale});
7929 pkt->duration = end - pkt->dts;
7930
7931 if ((t = av_dict_get(c->metadata, "title", NULL, 0))) {
7932 static const char encd[12] = {
7933 0x00, 0x00, 0x00, 0x0C,
7934 'e', 'n', 'c', 'd',
7935 0x00, 0x00, 0x01, 0x00 };
7936 len = strlen(t->value);
7937 pkt->size = len + 2 + 12;
7938 pkt->data = av_malloc(pkt->size);
7939 if (!pkt->data) {
7941 return AVERROR(ENOMEM);
7942 }
7943 AV_WB16(pkt->data, len);
7944 memcpy(pkt->data + 2, t->value, len);
7945 memcpy(pkt->data + len + 2, encd, sizeof(encd));
7947 av_freep(&pkt->data);
7948 }
7949 }
7950
7951 av_packet_unref(mov->pkt);
7952
7953 return 0;
7954}
7955
7956
7957static int mov_check_timecode_track(AVFormatContext *s, AVTimecode *tc, AVStream *src_st, const char *tcstr)
7958{
7959 int ret;
7960
7961 /* compute the frame number */
7962 ret = av_timecode_init_from_string(tc, src_st->avg_frame_rate, tcstr, s);
7963 return ret;
7964}
7965
7966static int mov_create_timecode_track(AVFormatContext *s, int index, int src_index, AVTimecode tc)
7967{
7968 MOVMuxContext *mov = s->priv_data;
7969 MOVTrack *track = &mov->tracks[index];
7970 AVStream *src_st = mov->tracks[src_index].st;
7971 uint8_t data[4];
7972 AVPacket *pkt = mov->pkt;
7973 AVRational rate = src_st->avg_frame_rate;
7974 int ret;
7975
7976 /* tmcd track based on video stream */
7977 track->mode = mov->mode;
7978 track->tag = MKTAG('t','m','c','d');
7979 track->src_track = av_malloc(sizeof(*track->src_track));
7980 if (!track->src_track)
7981 return AVERROR(ENOMEM);
7982 *track->src_track = src_index;
7983 track->nb_src_track = 1;
7985 track->timescale = tc.fps * 1000;
7986 else if (tc.rate.den == 1001)
7987 track->timescale = tc.rate.num;
7988 else
7989 track->timescale = tc.fps;
7992
7993 /* set st to src_st for metadata access*/
7994 track->st = src_st;
7995
7996 /* encode context: tmcd data stream */
7997 track->par = avcodec_parameters_alloc();
7998 if (!track->par)
7999 return AVERROR(ENOMEM);
8001 track->par->codec_tag = track->tag;
8002 track->st->avg_frame_rate = rate;
8003
8004 /* the tmcd track just contains one packet with the frame number */
8005 pkt->data = data;
8006 pkt->stream_index = index;
8007 pkt->flags = AV_PKT_FLAG_KEY;
8008 pkt->pts = pkt->dts = av_rescale_q(tc.start, av_inv_q(rate), (AVRational){ 1, track->timescale });
8009 pkt->size = 4;
8010 AV_WB32(pkt->data, tc.start);
8013 return ret;
8014}
8015
8016/*
8017 * st->disposition controls the "enabled" flag in the tkhd tag.
8018 * QuickTime will not play a track if it is not enabled. So make sure
8019 * that one track of each type (audio, video, subtitle) is enabled.
8020 *
8021 * Subtitles are special. For audio and video, setting "enabled" also
8022 * makes the track "default" (i.e. it is rendered when played). For
8023 * subtitles, an "enabled" subtitle is not rendered by default, but
8024 * if no subtitle is enabled, the subtitle menu in QuickTime will be
8025 * empty!
8026 */
8028{
8029 MOVMuxContext *mov = s->priv_data;
8030 int i;
8031 int enabled[AVMEDIA_TYPE_NB];
8032 int first[AVMEDIA_TYPE_NB];
8033
8034 for (i = 0; i < AVMEDIA_TYPE_NB; i++) {
8035 enabled[i] = 0;
8036 first[i] = -1;
8037 }
8038
8039 for (i = 0; i < mov->nb_streams; i++) {
8040 AVStream *st = mov->tracks[i].st;
8041
8044 is_cover_image(st))
8045 continue;
8046
8047 if (first[st->codecpar->codec_type] < 0)
8048 first[st->codecpar->codec_type] = i;
8051 enabled[st->codecpar->codec_type]++;
8052 }
8053 }
8054
8055 for (i = 0; i < AVMEDIA_TYPE_NB; i++) {
8056 switch (i) {
8057 case AVMEDIA_TYPE_VIDEO:
8058 case AVMEDIA_TYPE_AUDIO:
8060 if (enabled[i] > 1)
8061 mov->per_stream_grouping = 1;
8062 if (!enabled[i] && first[i] >= 0)
8063 mov->tracks[first[i]].flags |= MOV_TRACK_ENABLED;
8064 break;
8065 }
8066 }
8067}
8068
8070{
8071 MOVMuxContext *mov = s->priv_data;
8072
8073 for (int i = 0; i < s->nb_streams; i++)
8074 s->streams[i]->priv_data = NULL;
8075
8076 if (!mov->tracks)
8077 return;
8078
8079 if (mov->chapter_track) {
8081 }
8082
8083 for (int i = 0; i < mov->nb_tracks; i++) {
8084 MOVTrack *const track = &mov->tracks[i];
8085
8086 if (track->tag == MKTAG('r','t','p',' '))
8087 ff_mov_close_hinting(track);
8088 else if (track->tag == MKTAG('t','m','c','d') && mov->nb_meta_tmcd)
8089 av_freep(&track->par);
8090 av_freep(&track->cluster);
8091 av_freep(&track->cluster_written);
8092 av_freep(&track->frag_info);
8093 av_packet_free(&track->cover_image);
8094
8095 if (track->eac3_priv) {
8096 struct eac3_info *info = track->eac3_priv;
8097 av_packet_free(&info->pkt);
8098 av_freep(&track->eac3_priv);
8099 }
8100 for (int j = 0; j < track->stsd_count; j++)
8101 av_freep(&track->extradata[j]);
8102 av_freep(&track->extradata);
8103 av_freep(&track->extradata_size);
8104
8105 for (int i = 0; i < track->nb_tref_tags; i++)
8106 av_freep(&track->tref_tags[i].id);
8107 av_freep(&track->tref_tags);
8108 av_freep(&track->src_track);
8109
8110 ff_mov_cenc_free(&track->cenc);
8111 ffio_free_dyn_buf(&track->mdat_buf);
8112
8113#if CONFIG_IAMFENC
8114 ffio_free_dyn_buf(&track->iamf_buf);
8115 if (track->iamf)
8117 av_freep(&track->iamf);
8118#endif
8119 ff_isom_close_apvc(&track->apv);
8120
8122 }
8123
8124 av_freep(&mov->tracks);
8126}
8127
8128static uint32_t rgb_to_yuv(uint32_t rgb)
8129{
8130 uint8_t r, g, b;
8131 int y, cb, cr;
8132
8133 r = (rgb >> 16) & 0xFF;
8134 g = (rgb >> 8) & 0xFF;
8135 b = (rgb ) & 0xFF;
8136
8137 y = av_clip_uint8(( 16000 + 257 * r + 504 * g + 98 * b)/1000);
8138 cb = av_clip_uint8((128000 - 148 * r - 291 * g + 439 * b)/1000);
8139 cr = av_clip_uint8((128000 + 439 * r - 368 * g - 71 * b)/1000);
8140
8141 return (y << 16) | (cr << 8) | cb;
8142}
8143
8145 AVStream *st)
8146{
8147 int i, width = 720, height = 480;
8148 int have_palette = 0, have_size = 0;
8149 uint32_t palette[16];
8150 char *cur = st->codecpar->extradata;
8151
8152 while (cur && *cur) {
8153 if (strncmp("palette:", cur, 8) == 0) {
8154 int i, count;
8155 count = sscanf(cur + 8,
8156 "%06"PRIx32", %06"PRIx32", %06"PRIx32", %06"PRIx32", "
8157 "%06"PRIx32", %06"PRIx32", %06"PRIx32", %06"PRIx32", "
8158 "%06"PRIx32", %06"PRIx32", %06"PRIx32", %06"PRIx32", "
8159 "%06"PRIx32", %06"PRIx32", %06"PRIx32", %06"PRIx32"",
8160 &palette[ 0], &palette[ 1], &palette[ 2], &palette[ 3],
8161 &palette[ 4], &palette[ 5], &palette[ 6], &palette[ 7],
8162 &palette[ 8], &palette[ 9], &palette[10], &palette[11],
8163 &palette[12], &palette[13], &palette[14], &palette[15]);
8164
8165 for (i = 0; i < count; i++) {
8166 palette[i] = rgb_to_yuv(palette[i]);
8167 }
8168 have_palette = 1;
8169 } else if (!strncmp("size:", cur, 5)) {
8170 sscanf(cur + 5, "%dx%d", &width, &height);
8171 have_size = 1;
8172 }
8173 if (have_palette && have_size)
8174 break;
8175 cur += strcspn(cur, "\n\r");
8176 cur += strspn(cur, "\n\r");
8177 }
8178 if (have_palette) {
8180 if (!track->extradata[track->last_stsd_index])
8181 return AVERROR(ENOMEM);
8182 for (i = 0; i < 16; i++) {
8183 AV_WB32(track->extradata[track->last_stsd_index] + i * 4, palette[i]);
8184 }
8185 memset(track->extradata[track->last_stsd_index] + 16*4, 0, AV_INPUT_BUFFER_PADDING_SIZE);
8186 track->extradata_size[track->last_stsd_index] = 16 * 4;
8187 }
8188 st->codecpar->width = width;
8189 st->codecpar->height = track->height = height;
8190
8191 return 0;
8192}
8193
8194#if CONFIG_IAMFENC
8195static int mov_init_iamf_track(AVFormatContext *s)
8196{
8197 MOVMuxContext *mov = s->priv_data;
8198 MOVTrack *track;
8199 IAMFContext *iamf;
8200 int first_iamf_idx = INT_MAX, last_iamf_idx = 0;
8201 int nb_audio_elements = 0, nb_mix_presentations = 0;
8202 int ret;
8203
8204 for (int i = 0; i < s->nb_stream_groups; i++) {
8205 const AVStreamGroup *stg = s->stream_groups[i];
8206
8208 nb_audio_elements++;
8210 nb_mix_presentations++;
8211 }
8212
8213 if (!nb_audio_elements && !nb_mix_presentations)
8214 return 0;
8215
8216 if (nb_audio_elements < 1 || nb_audio_elements > 2 || nb_mix_presentations < 1) {
8217 av_log(s, AV_LOG_ERROR, "There must be >= 1 and <= 2 IAMF_AUDIO_ELEMENT and at least "
8218 "one IAMF_MIX_PRESENTATION stream groups to write a IMAF track\n");
8219 return AVERROR(EINVAL);
8220 }
8221
8222 iamf = av_mallocz(sizeof(*iamf));
8223 if (!iamf)
8224 return AVERROR(ENOMEM);
8225
8226
8227 for (int i = 0; i < s->nb_stream_groups; i++) {
8228 const AVStreamGroup *stg = s->stream_groups[i];
8229 switch(stg->type) {
8231 for (int j = 0; j < stg->nb_entries; j++) {
8232 first_iamf_idx = FFMIN(stg->entries[j]->stream->index, first_iamf_idx);
8233 last_iamf_idx = FFMAX(stg->entries[j]->stream->index, last_iamf_idx);
8234 }
8235
8236 ret = ff_iamf_add_audio_element(iamf, stg, s);
8237 break;
8239 ret = ff_iamf_add_mix_presentation(iamf, stg, s);
8240 break;
8241 default:
8242 av_assert0(0);
8243 }
8244 if (ret < 0) {
8246 av_free(iamf);
8247 return ret;
8248 }
8249 }
8250
8251 track = &mov->tracks[first_iamf_idx];
8252 track->iamf = iamf;
8253 track->first_iamf_idx = first_iamf_idx;
8254 track->last_iamf_idx = last_iamf_idx;
8255 track->tag = MKTAG('i','a','m','f');
8256
8257 for (int i = 0; i < s->nb_stream_groups; i++) {
8258 AVStreamGroup *stg = s->stream_groups[i];
8260 continue;
8261 for (int j = 0; j < stg->nb_entries; j++)
8262 stg->entries[j]->stream->priv_data = track;
8263 }
8264
8265 ret = avio_open_dyn_buf(&track->iamf_buf);
8266 if (ret < 0)
8267 return ret;
8268
8269 return 0;
8270}
8271#endif
8272
8274{
8275 MOVMuxContext *mov = s->priv_data;
8276 int has_iamf = 0;
8277 int i, ret;
8278
8279 mov->fc = s;
8280 mov->pkt = ffformatcontext(s)->pkt;
8281
8282 /* Default mode == MP4 */
8283 mov->mode = MODE_MP4;
8284
8285#define IS_MODE(muxer, config) (CONFIG_ ## config ## _MUXER && !strcmp(#muxer, s->oformat->name))
8286 if (IS_MODE(3gp, TGP)) mov->mode = MODE_3GP;
8287 else if (IS_MODE(3g2, TG2)) mov->mode = MODE_3GP|MODE_3G2;
8288 else if (IS_MODE(mov, MOV)) mov->mode = MODE_MOV;
8289 else if (IS_MODE(psp, PSP)) mov->mode = MODE_PSP;
8290 else if (IS_MODE(ipod, IPOD)) mov->mode = MODE_IPOD;
8291 else if (IS_MODE(ismv, ISMV)) mov->mode = MODE_ISM;
8292 else if (IS_MODE(f4v, F4V)) mov->mode = MODE_F4V;
8293 else if (IS_MODE(avif, AVIF)) mov->mode = MODE_AVIF;
8294#undef IS_MODE
8295
8296 if (mov->flags & FF_MOV_FLAG_DELAY_MOOV)
8298
8299 if (mov->mode == MODE_AVIF)
8301
8302 /* Set the FRAGMENT flag if any of the fragmentation methods are
8303 * enabled. */
8304 if (mov->max_fragment_duration || mov->max_fragment_size ||
8310
8313 av_log(s, AV_LOG_ERROR, "Setting both hybrid_fragmented and faststart is not supported.\n");
8314 return AVERROR(EINVAL);
8315 }
8316
8317 /* Set other implicit flags immediately */
8320
8321 if (mov->mode == MODE_ISM)
8324 if (mov->flags & FF_MOV_FLAG_DASH)
8327 if (mov->flags & FF_MOV_FLAG_CMAF)
8330
8331 if (mov->flags & FF_MOV_FLAG_EMPTY_MOOV && s->flags & AVFMT_FLAG_AUTO_BSF) {
8332 av_log(s, AV_LOG_VERBOSE, "Empty MOOV enabled; disabling automatic bitstream filtering\n");
8333 s->flags &= ~AVFMT_FLAG_AUTO_BSF;
8334 }
8335
8337 av_log(s, AV_LOG_WARNING, "Global SIDX enabled; Ignoring skip_sidx option\n");
8339 }
8340
8341 if (mov->flags & FF_MOV_FLAG_FASTSTART) {
8342 mov->reserved_moov_size = -1;
8343 }
8344
8345 if (mov->use_editlist < 0) {
8346 mov->use_editlist = 1;
8347 if (mov->flags & FF_MOV_FLAG_FRAGMENT &&
8348 !(mov->flags & FF_MOV_FLAG_DELAY_MOOV)) {
8349 // If we can avoid needing an edit list by shifting the
8350 // tracks, prefer that over (trying to) write edit lists
8351 // in fragmented output.
8352 if (s->avoid_negative_ts == AVFMT_AVOID_NEG_TS_AUTO ||
8353 s->avoid_negative_ts == AVFMT_AVOID_NEG_TS_MAKE_ZERO)
8354 mov->use_editlist = 0;
8355 }
8356 }
8357 if (mov->flags & FF_MOV_FLAG_EMPTY_MOOV &&
8358 !(mov->flags & FF_MOV_FLAG_DELAY_MOOV) && mov->use_editlist)
8359 av_log(s, AV_LOG_WARNING, "No meaningful edit list will be written when using empty_moov without delay_moov\n");
8360
8361 if (mov->flags & FF_MOV_FLAG_CMAF && mov->use_editlist)
8363
8364 if (!mov->use_editlist && s->avoid_negative_ts == AVFMT_AVOID_NEG_TS_AUTO &&
8366 s->avoid_negative_ts = AVFMT_AVOID_NEG_TS_MAKE_ZERO;
8367
8368 /* Clear the omit_tfhd_offset flag if default_base_moof is set;
8369 * if the latter is set that's enough and omit_tfhd_offset doesn't
8370 * add anything extra on top of that. */
8374
8375 if (mov->frag_interleave &&
8378 "Sample interleaving in fragments is mutually exclusive with "
8379 "omit_tfhd_offset and separate_moof\n");
8380 return AVERROR(EINVAL);
8381 }
8382
8383 /* Non-seekable output is ok if using fragmentation. If ism_lookahead
8384 * is enabled, we don't support non-seekable output at all. */
8385 if (!(s->pb->seekable & AVIO_SEEKABLE_NORMAL) &&
8386 (!(mov->flags & FF_MOV_FLAG_FRAGMENT) || mov->ism_lookahead ||
8387 mov->mode == MODE_AVIF)) {
8388 av_log(s, AV_LOG_ERROR, "muxer does not support non seekable output\n");
8389 return AVERROR(EINVAL);
8390 }
8391
8392 /* AVIF output must have at most two video streams (one for YUV and one for
8393 * alpha). */
8394 if (mov->mode == MODE_AVIF) {
8395 if (s->nb_streams > 2) {
8396 av_log(s, AV_LOG_ERROR, "AVIF output requires exactly one or two streams\n");
8397 return AVERROR(EINVAL);
8398 }
8399 if (s->streams[0]->codecpar->codec_type != AVMEDIA_TYPE_VIDEO ||
8400 (s->nb_streams > 1 && s->streams[1]->codecpar->codec_type != AVMEDIA_TYPE_VIDEO)) {
8401 av_log(s, AV_LOG_ERROR, "AVIF output supports only video streams\n");
8402 return AVERROR(EINVAL);
8403 }
8404 if (!av_pix_fmt_desc_get(s->streams[0]->codecpar->format)) {
8405 av_log(s, AV_LOG_ERROR, "AVIF output requires a known pixel format\n");
8406 return AVERROR(EINVAL);
8407 }
8408 if (s->nb_streams > 1) {
8409 const AVPixFmtDescriptor *pixdesc =
8410 av_pix_fmt_desc_get(s->streams[1]->codecpar->format);
8411 if (!pixdesc || pixdesc->nb_components != 1) {
8412 av_log(s, AV_LOG_ERROR, "Second stream for AVIF (alpha) output must have exactly one plane\n");
8413 return AVERROR(EINVAL);
8414 }
8415 }
8416 s->streams[0]->disposition |= AV_DISPOSITION_DEFAULT;
8417 }
8418
8419 for (i = 0; i < s->nb_stream_groups; i++) {
8420 AVStreamGroup *stg = s->stream_groups[i];
8421
8422 for (int j = 0; j < stg->nb_entries; j++) {
8423 if (stg->entries[j]->type != AV_STREAM_GROUP_ENTRY_STREAM) {
8424 av_log(s, AV_LOG_ERROR, "Unsupported Stream Group entry #%d "
8425 "in Stream Group id %"PRId64"\n",
8426 i, stg->id);
8427 return AVERROR(EINVAL);
8428 }
8429 }
8430
8431 if (stg->type == AV_STREAM_GROUP_PARAMS_LCEVC) {
8432 if (stg->nb_entries != 2) {
8433 av_log(s, AV_LOG_ERROR, "Exactly two Streams are supported for Stream Groups of type LCEVC\n");
8434 return AVERROR(EINVAL);
8435 }
8437 if (lcevc->el_index > 1)
8438 return AVERROR(EINVAL);
8439 AVStream *st = stg->entries[lcevc->el_index]->stream;
8440 if (st->codecpar->codec_id != AV_CODEC_ID_LCEVC) {
8441 av_log(s, AV_LOG_ERROR, "Stream #%u is not an LCEVC stream\n", lcevc->el_index);
8442 return AVERROR(EINVAL);
8443 }
8444 }
8445
8446#if CONFIG_IAMFENC
8448 continue;
8449
8450 for (int j = 0; j < stg->nb_entries; j++) {
8451 AVStream *st = stg->entries[j]->stream;
8452
8453 if (st->priv_data) {
8454 av_log(s, AV_LOG_ERROR, "Stream %d is present in more than one Stream Group of type "
8455 "IAMF Audio Element\n", j);
8456 return AVERROR(EINVAL);
8457 }
8458 st->priv_data = st;
8459 }
8460 has_iamf = 1;
8461
8462 if (!mov->nb_tracks) // We support one track for the entire IAMF structure
8463 mov->nb_tracks++;
8464#endif
8465 }
8466
8467 for (i = 0; i < s->nb_streams; i++) {
8468 AVStream *st = s->streams[i];
8469 if (st->priv_data)
8470 continue;
8471 // Don't produce a track in the output file for timed ID3 streams.
8473 // Leave priv_data set to NULL for these AVStreams that don't
8474 // have a corresponding track.
8475 continue;
8476 }
8477 st->priv_data = st;
8478 mov->nb_tracks++;
8479 }
8480
8481 mov->nb_streams = mov->nb_tracks;
8482
8483 if (mov->mode & (MODE_MP4|MODE_MOV|MODE_IPOD) && s->nb_chapters)
8484 mov->chapter_track = mov->nb_tracks++;
8485
8486 if (mov->flags & FF_MOV_FLAG_RTP_HINT) {
8487 for (i = 0; i < s->nb_streams; i++)
8488 if (rtp_hinting_needed(s->streams[i]))
8489 mov->nb_tracks++;
8490 }
8491
8492 if (mov->write_btrt < 0) {
8493 mov->write_btrt = mov->mode == MODE_MP4;
8494 }
8495
8496 if ( mov->write_tmcd == -1 && (mov->mode == MODE_MOV || mov->mode == MODE_MP4)
8497 || mov->write_tmcd == 1) {
8498 AVDictionaryEntry *global_tcr = av_dict_get(s->metadata, "timecode",
8499 NULL, 0);
8500
8501 /* +1 tmcd track for each video stream with a timecode */
8502 for (i = 0; i < s->nb_streams; i++) {
8503 AVStream *st = s->streams[i];
8504 AVDictionaryEntry *t = global_tcr;
8506 (t || (t=av_dict_get(st->metadata, "timecode", NULL, 0)))) {
8507 AVTimecode tc;
8508 ret = mov_check_timecode_track(s, &tc, st, t->value);
8509 if (ret >= 0)
8510 mov->nb_meta_tmcd++;
8511 }
8512 }
8513
8514 /* check if there is already a tmcd track to remux */
8515 if (mov->nb_meta_tmcd) {
8516 for (i = 0; i < s->nb_streams; i++) {
8517 AVStream *st = s->streams[i];
8518 if (st->codecpar->codec_tag == MKTAG('t','m','c','d')) {
8519 av_log(s, AV_LOG_WARNING, "You requested a copy of the original timecode track "
8520 "so timecode metadata are now ignored\n");
8521 mov->nb_meta_tmcd = 0;
8522 }
8523 }
8524 }
8525
8526 mov->nb_tracks += mov->nb_meta_tmcd;
8527 }
8528
8529 // Reserve an extra stream for chapters for the case where chapters
8530 // are written in the trailer
8531 mov->tracks = av_calloc(mov->nb_tracks + 1, sizeof(*mov->tracks));
8532 if (!mov->tracks)
8533 return AVERROR(ENOMEM);
8534
8535 for (i = 0; i < mov->nb_tracks; i++) {
8536 MOVTrack *track = &mov->tracks[i];
8537
8538 track->stsd_count = 1;
8539 track->extradata = av_calloc(track->stsd_count, sizeof(*track->extradata));
8540 track->extradata_size = av_calloc(track->stsd_count, sizeof(*track->extradata_size));
8541 if (!track->extradata || !track->extradata_size)
8542 return AVERROR(ENOMEM);
8543 }
8544
8545 if (mov->encryption_scheme_str != NULL && strcmp(mov->encryption_scheme_str, "none") != 0) {
8546 if (strcmp(mov->encryption_scheme_str, "cenc-aes-ctr") == 0) {
8548
8550 av_log(s, AV_LOG_ERROR, "Invalid encryption key len %d expected %d\n",
8552 return AVERROR(EINVAL);
8553 }
8554
8555 if (mov->encryption_kid_len != CENC_KID_SIZE) {
8556 av_log(s, AV_LOG_ERROR, "Invalid encryption kid len %d expected %d\n",
8558 return AVERROR(EINVAL);
8559 }
8560 } else {
8561 av_log(s, AV_LOG_ERROR, "unsupported encryption scheme %s\n",
8563 return AVERROR(EINVAL);
8564 }
8565 }
8566
8567#if CONFIG_IAMFENC
8568 ret = mov_init_iamf_track(s);
8569 if (ret < 0)
8570 return ret;
8571#endif
8572
8573 for (int j = 0, i = 0; j < s->nb_streams; j++) {
8574 AVStream *st = s->streams[j];
8575
8576 if (st != st->priv_data) {
8577 if (has_iamf)
8578 i += has_iamf--;
8579 continue;
8580 }
8581 st->priv_data = &mov->tracks[i++];
8582 }
8583
8584 AVRational movie_timescale = (AVRational) { 0, 1 };
8585 for (i = 0; i < s->nb_streams; i++) {
8586 AVStream *st= s->streams[i];
8587 MOVTrack *track = st->priv_data;
8588
8589 if (!track)
8590 continue;
8591
8592 if (!track->st) {
8593 track->st = st;
8594 track->par = st->codecpar;
8595 }
8596
8597 movie_timescale = av_gcd_q(movie_timescale, st->time_base, INT_MAX, (AVRational){1,0});
8598 }
8599 if (!movie_timescale.den)
8600 movie_timescale = MOV_TIMESCALE_Q;
8601
8602 if (!mov->movie_timescale)
8603 mov->movie_timescale = FFMAX(movie_timescale.den, MOV_TIMESCALE);
8604
8605 for (i = 0; i < s->nb_streams; i++) {
8606 AVStream *st= s->streams[i];
8607 MOVTrack *track = st->priv_data;
8608 AVDictionaryEntry *lang = av_dict_get(st->metadata, "language", NULL,0);
8609
8610 if (!track)
8611 continue;
8612
8613 track->language = ff_mov_iso639_to_lang(lang?lang->value:"und", mov->mode!=MODE_MOV);
8614 if (track->language < 0)
8615 track->language = 32767; // Unspecified Macintosh language code
8616 track->mode = mov->mode;
8617 if (!track->tag)
8618 track->tag = mov_find_codec_tag(s, track);
8619 if (!track->tag) {
8620 av_log(s, AV_LOG_ERROR, "Could not find tag for codec %s in stream #%d, "
8621 "codec not currently supported in container\n",
8623 return AVERROR(EINVAL);
8624 }
8625 /* If hinting of this track is enabled by a later hint track,
8626 * this is updated. */
8627 track->hint_track = -1;
8628 track->start_dts = AV_NOPTS_VALUE;
8629 track->start_cts = AV_NOPTS_VALUE;
8630 track->end_pts = AV_NOPTS_VALUE;
8631 track->dts_shift = AV_NOPTS_VALUE;
8633 if (track->tag == MKTAG('m','x','3','p') || track->tag == MKTAG('m','x','3','n') ||
8634 track->tag == MKTAG('m','x','4','p') || track->tag == MKTAG('m','x','4','n') ||
8635 track->tag == MKTAG('m','x','5','p') || track->tag == MKTAG('m','x','5','n')) {
8636 if (st->codecpar->width != 720 || (st->codecpar->height != 608 && st->codecpar->height != 512)) {
8637 av_log(s, AV_LOG_ERROR, "D-10/IMX must use 720x608 or 720x512 video resolution\n");
8638 return AVERROR(EINVAL);
8639 }
8640 track->height = track->tag >> 24 == 'n' ? 486 : 576;
8641 }
8642 if (mov->video_track_timescale) {
8643 track->timescale = mov->video_track_timescale;
8644 if (mov->mode == MODE_ISM && mov->video_track_timescale != 10000000)
8645 av_log(s, AV_LOG_WARNING, "Warning: some tools, like mp4split, assume a timescale of 10000000 for ISMV.\n");
8646 } else {
8647 track->timescale = st->time_base.den;
8648 while(track->timescale < 10000)
8649 track->timescale *= 2;
8650 }
8651 if (st->codecpar->width > 65535 || st->codecpar->height > 65535) {
8652 av_log(s, AV_LOG_ERROR, "Resolution %dx%d too large for mov/mp4\n", st->codecpar->width, st->codecpar->height);
8653 return AVERROR(EINVAL);
8654 }
8655 if (track->mode == MODE_MOV && track->timescale > 100000)
8657 "WARNING codec timebase is very high. If duration is too long,\n"
8658 "file may not be playable by quicktime. Specify a shorter timebase\n"
8659 "or choose different container.\n");
8660 if (track->mode == MODE_MOV &&
8661 track->par->codec_id == AV_CODEC_ID_RAWVIDEO &&
8662 track->tag == MKTAG('r','a','w',' ')) {
8663 enum AVPixelFormat pix_fmt = track->par->format;
8664 if (pix_fmt == AV_PIX_FMT_NONE && track->par->bits_per_coded_sample == 1)
8666 track->is_unaligned_qt_rgb =
8673 }
8674 if (track->par->codec_id == AV_CODEC_ID_VP9 && track->mode != MODE_MP4) {
8675 av_log(s, AV_LOG_ERROR, "%s only supported in MP4.\n", avcodec_get_name(track->par->codec_id));
8676 return AVERROR(EINVAL);
8677 } else if (track->par->codec_id == AV_CODEC_ID_AV1 &&
8678 track->mode != MODE_MP4 && track->mode != MODE_AVIF) {
8679 av_log(s, AV_LOG_ERROR, "%s only supported in MP4 and AVIF.\n", avcodec_get_name(track->par->codec_id));
8680 return AVERROR(EINVAL);
8681 } else if (track->par->codec_id == AV_CODEC_ID_VP8) {
8682 /* altref frames handling is not defined in the spec as of version v1.0,
8683 * so just forbid muxing VP8 streams altogether until a new version does */
8684 av_log(s, AV_LOG_ERROR, "VP8 muxing is currently not supported.\n");
8685 return AVERROR_PATCHWELCOME;
8686 } else if (track->par->codec_id == AV_CODEC_ID_APV) {
8687 ret = ff_isom_init_apvc(&track->apv, s);
8688 if (ret < 0)
8689 return ret;
8690 }
8691 if (is_cover_image(st)) {
8692 track->cover_image = av_packet_alloc();
8693 if (!track->cover_image)
8694 return AVERROR(ENOMEM);
8695 }
8696 } else if (st->codecpar->codec_type == AVMEDIA_TYPE_AUDIO) {
8697 track->timescale = st->codecpar->sample_rate;
8699 av_log(s, AV_LOG_WARNING, "track %d: codec frame size is not set\n", i);
8700 track->audio_vbr = 1;
8701 }else if (st->codecpar->codec_id == AV_CODEC_ID_ADPCM_MS ||
8704 if (!st->codecpar->block_align) {
8705 av_log(s, AV_LOG_ERROR, "track %d: codec block align is not set for adpcm\n", i);
8706 return AVERROR(EINVAL);
8707 }
8708 track->sample_size = st->codecpar->block_align;
8709 }else if (st->codecpar->frame_size > 1){ /* assume compressed audio */
8710 track->audio_vbr = 1;
8711 }else{
8712 track->sample_size = (av_get_bits_per_sample(st->codecpar->codec_id) >> 3) *
8714 }
8715 if (st->codecpar->codec_id == AV_CODEC_ID_ILBC ||
8717 track->audio_vbr = 1;
8718 }
8719 if (track->mode != MODE_MOV &&
8720 track->par->codec_id == AV_CODEC_ID_MP3 && track->timescale < 16000) {
8721 if (s->strict_std_compliance >= FF_COMPLIANCE_NORMAL) {
8722 av_log(s, AV_LOG_ERROR, "track %d: muxing mp3 at %dhz is not standard, to mux anyway set strict to -1\n",
8723 i, track->par->sample_rate);
8724 return AVERROR(EINVAL);
8725 } else {
8726 av_log(s, AV_LOG_WARNING, "track %d: muxing mp3 at %dhz is not standard in MP4\n",
8727 i, track->par->sample_rate);
8728 }
8729 }
8730 if (track->par->codec_id == AV_CODEC_ID_FLAC ||
8731 track->par->codec_id == AV_CODEC_ID_TRUEHD ||
8732 track->par->codec_id == AV_CODEC_ID_OPUS) {
8733 if (track->mode != MODE_MP4) {
8734 av_log(s, AV_LOG_ERROR, "%s only supported in MP4.\n", avcodec_get_name(track->par->codec_id));
8735 return AVERROR(EINVAL);
8736 }
8737 if (track->par->codec_id == AV_CODEC_ID_TRUEHD &&
8738 s->strict_std_compliance > FF_COMPLIANCE_EXPERIMENTAL) {
8740 "%s in MP4 support is experimental, add "
8741 "'-strict %d' if you want to use it.\n",
8743 return AVERROR_EXPERIMENTAL;
8744 }
8745 }
8746 } else if (st->codecpar->codec_type == AVMEDIA_TYPE_SUBTITLE) {
8747 track->timescale = st->time_base.den;
8748
8749 if (track->par->codec_id == AV_CODEC_ID_TTML) {
8750 /* 14496-30 requires us to use a single sample per fragment
8751 for TTML, for which we define a per-track flag.
8752
8753 We set the flag in case we are receiving TTML paragraphs
8754 from the input, in other words in case we are not doing
8755 stream copy. */
8758
8759 if (track->mode != MODE_ISM &&
8760 track->par->codec_tag == MOV_ISMV_TTML_TAG &&
8761 s->strict_std_compliance > FF_COMPLIANCE_UNOFFICIAL) {
8763 "ISMV style TTML support with the 'dfxp' tag in "
8764 "non-ISMV formats is not officially supported. Add "
8765 "'-strict unofficial' if you want to use it.\n");
8766 return AVERROR_EXPERIMENTAL;
8767 }
8768 }
8769 } else if (st->codecpar->codec_type == AVMEDIA_TYPE_DATA) {
8770 track->timescale = st->time_base.den;
8771 if (track->tag == MKTAG('t','m','c','d') &&
8772 st->codecpar->extradata_size >= 8)
8773 track->timecode_flags = AV_RB32(st->codecpar->extradata + 4);
8774 } else {
8775 track->timescale = mov->movie_timescale;
8776 }
8777 if (!track->height)
8778 track->height = st->codecpar->height;
8779 /* The Protected Interoperable File Format (PIFF) standard, used by ISMV recommends but
8780 doesn't mandate a track timescale of 10,000,000. The muxer allows a custom timescale
8781 for video tracks, so if user-set, it isn't overwritten */
8782 if (mov->mode == MODE_ISM &&
8785 track->timescale = 10000000;
8786 }
8787
8788 avpriv_set_pts_info(st, 64, 1, track->timescale);
8789
8791 ret = ff_mov_cenc_init(&track->cenc, mov->encryption_key,
8792 (track->par->codec_id == AV_CODEC_ID_H264 || track->par->codec_id == AV_CODEC_ID_HEVC ||
8793 track->par->codec_id == AV_CODEC_ID_VVC || track->par->codec_id == AV_CODEC_ID_AV1),
8794 track->par->codec_id, s->flags & AVFMT_FLAG_BITEXACT);
8795 if (ret)
8796 return ret;
8797 }
8798 }
8799
8800 for (i = 0; i < s->nb_stream_groups; i++) {
8801 AVStreamGroup *stg = s->stream_groups[i];
8802
8803 switch (stg->type) {
8806 AVStream *st = stg->entries[lcevc->el_index]->stream;
8807 MOVTrack *track = st->priv_data;
8808
8809 for (int j = 0; j < mov->nb_tracks; j++) {
8810 MOVTrack *trk = &mov->tracks[j];
8811
8812 if (trk->st == stg->entries[!lcevc->el_index]->stream) {
8813 track->src_track = av_malloc(sizeof(*track->src_track));
8814 if (!track->src_track)
8815 return AVERROR(ENOMEM);
8816 *track->src_track = j;
8817 track->nb_src_track = 1;
8818 break;
8819 }
8820 }
8821
8822 track->par->width = lcevc->width;
8823 track->par->height = track->height = lcevc->height;
8824 break;
8825 }
8827 const AVStreamGroupTREF *tref = stg->params.tref;
8828 MOVTrack *track;
8829
8830 if (tref->metadata_index >= stg->nb_entries)
8831 return AVERROR(EINVAL);
8832
8833 track = stg->entries[tref->metadata_index]->stream->priv_data;
8834 for (int j = 0; j < stg->nb_entries; j++) {
8835 const AVStream *st2 = stg->entries[j]->stream;
8836 int index = -1;
8837
8838 if (j == tref->metadata_index)
8839 continue;
8840
8841 for (int k = 0; k < mov->nb_tracks; k++) {
8842 if (mov->tracks[k].st != st2)
8843 continue;
8844 index = k;
8845 break;
8846 }
8847 if (index < 0)
8848 return AVERROR(EINVAL);
8849
8850 int *tmp = av_realloc(track->src_track,
8851 (track->nb_src_track + 1) * sizeof(*track->src_track));
8852 if (!tmp)
8853 return AVERROR(ENOMEM);
8854 track->src_track = tmp;
8855 track->src_track[track->nb_src_track++] = index;
8856 }
8857 break;
8858 }
8859 default:
8860 break;
8861 }
8862 }
8863
8864 /* fill src_track for tmcd tracks not covered by stream groups or
8865 * created by this muxer, retaining the old behavior of src_track
8866 * being arbitrarily 0. */
8867 for (i = 0; i < s->nb_streams; i++) {
8868 AVStream *st = s->streams[i];
8869 MOVTrack *track = st->priv_data;
8870 if (st->codecpar->codec_tag != MKTAG('t','m','c','d') ||
8871 track->nb_src_track)
8872 continue;
8873
8874 track->src_track = av_malloc(sizeof(*track->src_track));
8875 if (!track->src_track)
8876 return AVERROR(ENOMEM);
8877 *track->src_track = 0;
8878 track->nb_src_track = 1;
8879 }
8880
8882 return 0;
8883}
8884
8886{
8887 AVIOContext *pb = s->pb;
8888 MOVMuxContext *mov = s->priv_data;
8889 int ret, hint_track = 0, tmcd_track = 0, nb_tracks = mov->nb_streams;
8890
8891 if (mov->mode & (MODE_MP4|MODE_MOV|MODE_IPOD) && s->nb_chapters)
8892 nb_tracks++;
8893
8894 if (mov->flags & FF_MOV_FLAG_RTP_HINT) {
8895 hint_track = nb_tracks;
8896 for (int i = 0; i < mov->nb_streams; i++) {
8897 if (rtp_hinting_needed(mov->tracks[i].st))
8898 nb_tracks++;
8899 }
8900 }
8901
8902 if (mov->nb_meta_tmcd)
8903 tmcd_track = nb_tracks;
8904
8905 for (int i = 0; i < mov->nb_streams; i++) {
8906 MOVTrack *track = &mov->tracks[i];
8907 AVStream *st = track->st;
8908
8909 /* copy extradata if it exists */
8910 if (st->codecpar->extradata_size) {
8913 else if (!TAG_IS_AVCI(track->tag) && st->codecpar->codec_id != AV_CODEC_ID_DNXHD) {
8915 track->extradata[track->last_stsd_index] =
8917 if (!track->extradata[track->last_stsd_index]) {
8918 return AVERROR(ENOMEM);
8919 }
8920 memcpy(track->extradata[track->last_stsd_index],
8921 st->codecpar->extradata, track->extradata_size[track->last_stsd_index]);
8922 memset(track->extradata[track->last_stsd_index] + track->extradata_size[track->last_stsd_index],
8924 }
8925 }
8926
8930 continue;
8931
8932 for (int j = 0; j < mov->nb_streams; j++) {
8933 AVStream *stj= mov->tracks[j].st;
8934 MOVTrack *trackj= &mov->tracks[j];
8935 if (j == i)
8936 continue;
8937
8938 if (stj->codecpar->codec_type == AVMEDIA_TYPE_AUDIO &&
8939 (trackj->par->ch_layout.nb_channels != 1 ||
8942 )
8943 track->mono_as_fc = -1;
8944
8945 if (stj->codecpar->codec_type == AVMEDIA_TYPE_AUDIO &&
8948 trackj->par->ch_layout.nb_channels == 1 && track->mono_as_fc >= 0
8949 )
8950 track->mono_as_fc++;
8951
8952 if (stj->codecpar->codec_type != AVMEDIA_TYPE_AUDIO ||
8955 trackj->language != track->language ||
8956 trackj->tag != track->tag
8957 )
8958 continue;
8959 track->multichannel_as_mono++;
8960 }
8961 }
8962
8963 if (!(mov->flags & FF_MOV_FLAG_DELAY_MOOV) ||
8965 if ((ret = mov_write_identification(pb, s)) < 0)
8966 return ret;
8967 }
8968
8969 if (mov->reserved_moov_size){
8970 mov->reserved_header_pos = avio_tell(pb);
8971 if (mov->reserved_moov_size > 0)
8972 avio_skip(pb, mov->reserved_moov_size);
8973 }
8974
8975 if (mov->flags & FF_MOV_FLAG_FRAGMENT) {
8976 /* If no fragmentation options have been set, set a default. */
8977 if (!(mov->flags & (FF_MOV_FLAG_FRAG_KEYFRAME |
8983 avio_wb32(pb, 8); // placeholder for extended size field (64 bit)
8984 ffio_wfourcc(pb, mov->mode == MODE_MOV ? "wide" : "free");
8985 mov->mdat_pos = avio_tell(pb);
8986 // The free/wide header that later will be converted into an
8987 // mdat, covering the initial moov and all the fragments.
8988 avio_wb32(pb, 0);
8989 ffio_wfourcc(pb, mov->mode == MODE_MOV ? "wide" : "free");
8990 // Write an ftyp atom, hidden in a free/wide. This is neither
8991 // exposed while the file is written, as fragmented, nor when the
8992 // file is finalized into non-fragmented form. However, this allows
8993 // accessing a pristine, sequential ftyp+moov init segment, even
8994 // after the file is finalized. It also allows dumping the whole
8995 // contents of the mdat box, to get the fragmented form of the
8996 // file.
8997 if ((ret = mov_write_identification(pb, s)) < 0)
8998 return ret;
8999 update_size(pb, mov->mdat_pos);
9000 }
9001 } else if (mov->mode != MODE_AVIF) {
9002 if (mov->flags & FF_MOV_FLAG_FASTSTART)
9003 mov->reserved_header_pos = avio_tell(pb);
9004 mov_write_mdat_tag(pb, mov);
9005 }
9006
9008 if (mov->time)
9009 mov->time += 0x7C25B080; // 1970 based -> 1904 based
9010
9011 if (mov->chapter_track)
9012 if ((ret = mov_create_chapter_track(s, mov->chapter_track)) < 0)
9013 return ret;
9014
9015 if (mov->flags & FF_MOV_FLAG_RTP_HINT) {
9016 for (int i = 0; i < mov->nb_streams; i++) {
9017 if (rtp_hinting_needed(mov->tracks[i].st)) {
9018 if ((ret = ff_mov_init_hinting(s, hint_track, i)) < 0)
9019 return ret;
9020 hint_track++;
9021 }
9022 }
9023 }
9024
9025 if (mov->nb_meta_tmcd) {
9026 const AVDictionaryEntry *t, *global_tcr = av_dict_get(s->metadata,
9027 "timecode", NULL, 0);
9028 /* Initialize the tmcd tracks */
9029 for (int i = 0; i < mov->nb_streams; i++) {
9030 AVStream *st = mov->tracks[i].st;
9031 t = global_tcr;
9032
9034 AVTimecode tc;
9035 if (!t)
9036 t = av_dict_get(st->metadata, "timecode", NULL, 0);
9037 if (!t)
9038 continue;
9039 if (mov_check_timecode_track(s, &tc, st, t->value) < 0)
9040 continue;
9041 if ((ret = mov_create_timecode_track(s, tmcd_track, i, tc)) < 0)
9042 return ret;
9043 tmcd_track++;
9044 }
9045 }
9046 }
9047
9048 avio_flush(pb);
9049
9050 if (mov->flags & FF_MOV_FLAG_ISML)
9051 mov_write_isml_manifest(pb, mov, s);
9052
9053 if (mov->flags & FF_MOV_FLAG_EMPTY_MOOV &&
9054 !(mov->flags & FF_MOV_FLAG_DELAY_MOOV)) {
9055 if ((ret = mov_write_moov_tag(pb, mov, s)) < 0)
9056 return ret;
9057 mov->moov_written = 1;
9058 if (mov->flags & FF_MOV_FLAG_GLOBAL_SIDX)
9059 mov->reserved_header_pos = avio_tell(pb);
9060 }
9061
9062 return 0;
9063}
9064
9066{
9067 int ret;
9068 AVIOContext *moov_buf;
9069 MOVMuxContext *mov = s->priv_data;
9070
9071 if ((ret = ffio_open_null_buf(&moov_buf)) < 0)
9072 return ret;
9073 if ((ret = mov_write_moov_tag(moov_buf, mov, s)) < 0)
9074 return ret;
9075 return ffio_close_null_buf(moov_buf);
9076}
9077
9079{
9080 int ret;
9081 AVIOContext *buf;
9082 MOVMuxContext *mov = s->priv_data;
9083
9084 if ((ret = ffio_open_null_buf(&buf)) < 0)
9085 return ret;
9086 mov_write_sidx_tags(buf, mov, -1, 0);
9087 return ffio_close_null_buf(buf);
9088}
9089
9090/*
9091 * This function gets the moov size if moved to the top of the file: the chunk
9092 * offset table can switch between stco (32-bit entries) to co64 (64-bit
9093 * entries) when the moov is moved to the beginning, so the size of the moov
9094 * would change. It also updates the chunk offset tables.
9095 */
9097{
9098 int i, moov_size, moov_size2;
9099 MOVMuxContext *mov = s->priv_data;
9100
9101 moov_size = get_moov_size(s);
9102 if (moov_size < 0)
9103 return moov_size;
9104
9105 for (i = 0; i < mov->nb_tracks; i++)
9106 mov->tracks[i].data_offset += moov_size;
9107
9108 moov_size2 = get_moov_size(s);
9109 if (moov_size2 < 0)
9110 return moov_size2;
9111
9112 /* if the size changed, we just switched from stco to co64 and need to
9113 * update the offsets */
9114 if (moov_size2 != moov_size)
9115 for (i = 0; i < mov->nb_tracks; i++)
9116 mov->tracks[i].data_offset += moov_size2 - moov_size;
9117
9118 return moov_size2;
9119}
9120
9122{
9123 int i, sidx_size;
9124 MOVMuxContext *mov = s->priv_data;
9125
9126 sidx_size = get_sidx_size(s);
9127 if (sidx_size < 0)
9128 return sidx_size;
9129
9130 for (i = 0; i < mov->nb_tracks; i++)
9131 mov->tracks[i].data_offset += sidx_size;
9132
9133 return sidx_size;
9134}
9135
9137{
9138 int moov_size;
9139 MOVMuxContext *mov = s->priv_data;
9140
9141 if (mov->flags & FF_MOV_FLAG_FRAGMENT)
9142 moov_size = compute_sidx_size(s);
9143 else
9144 moov_size = compute_moov_size(s);
9145 if (moov_size < 0)
9146 return moov_size;
9147
9148 return ff_format_shift_data(s, mov->reserved_header_pos, moov_size);
9149}
9150
9152{
9153 MOVMuxContext *mov = s->priv_data;
9154 AVIOContext *pb = s->pb;
9155
9156 /* Write size of mdat tag */
9157 if (mov->mdat_size + 8 <= UINT32_MAX) {
9158 avio_seek(pb, mov->mdat_pos, SEEK_SET);
9159 avio_wb32(pb, mov->mdat_size + 8);
9161 ffio_wfourcc(pb, "mdat"); // overwrite the original free/wide into a mdat
9162 } else {
9163 /* overwrite 'wide' placeholder atom */
9164 avio_seek(pb, mov->mdat_pos - 8, SEEK_SET);
9165 /* special value: real atom size will be 64 bit value after
9166 * tag field */
9167 avio_wb32(pb, 1);
9168 ffio_wfourcc(pb, "mdat");
9169 avio_wb64(pb, mov->mdat_size + 16);
9170 }
9171}
9172
9174{
9175 MOVMuxContext *mov = s->priv_data;
9176 AVIOContext *pb = s->pb;
9177 int res = 0;
9178 int i;
9179 int64_t moov_pos;
9180
9181 /*
9182 * Before actually writing the trailer, make sure that there are no
9183 * dangling subtitles, that need a terminating sample.
9184 */
9185 for (i = 0; i < mov->nb_tracks; i++) {
9186 MOVTrack *trk = &mov->tracks[i];
9187 if (trk->par->codec_id == AV_CODEC_ID_MOV_TEXT &&
9191 }
9192 }
9193
9194 //Also check for a buffered EAC3 packet
9195 for (i = 0; i < mov->nb_tracks; i++) {
9196 MOVTrack *trk = &mov->tracks[i];
9197 if (trk->par->codec_id != AV_CODEC_ID_EAC3)
9198 continue;
9199 struct eac3_info *info = trk->eac3_priv;
9200 if (!info || !info->pkt || !info->pkt->size)
9201 continue;
9202
9203 av_packet_move_ref(mov->pkt, info->pkt);
9204 info->eof = 1;
9205 res = mov_write_single_packet(s, mov->pkt);
9206 if (res < 0)
9207 return res;
9208
9209 av_packet_unref(mov->pkt);
9210 }
9211
9212 // Check if we have any tracks that require squashing.
9213 // In that case, we'll have to write the packet here.
9214 if ((res = mov_write_squashed_packets(s)) < 0)
9215 return res;
9216
9217 // If there were no chapters when the header was written, but there
9218 // are chapters now, write them in the trailer. This only works
9219 // when we are not doing fragments.
9220 if (!mov->chapter_track && !(mov->flags & FF_MOV_FLAG_FRAGMENT)) {
9221 if (mov->mode & (MODE_MP4|MODE_MOV|MODE_IPOD) && s->nb_chapters) {
9222 mov->chapter_track = mov->nb_tracks++;
9223 if ((res = mov_create_chapter_track(s, mov->chapter_track)) < 0)
9224 return res;
9225 }
9226 }
9227
9228 if (!(mov->flags & FF_MOV_FLAG_FRAGMENT) ||
9232 mov->mdat_size = avio_tell(pb) - mov->mdat_pos - 8;
9233 for (i = 0; i < mov->nb_tracks; i++) {
9234 MOVTrack *track = &mov->tracks[i];
9235 track->data_offset = 0;
9236 av_free(track->cluster);
9237 track->cluster = track->cluster_written;
9238 track->entry = track->entry_written;
9239 track->cluster_written = NULL;
9240 track->entry_written = 0;
9241 track->chunkCount = 0; // Force build_chunks to rebuild the list of chunks
9242 }
9243 // Clear the empty_moov flag, as we do want the moov to include
9244 // all the samples at this point.
9246 }
9247
9248 moov_pos = avio_tell(pb);
9249
9252
9253 avio_seek(pb, mov->reserved_moov_size > 0 ? mov->reserved_header_pos : moov_pos, SEEK_SET);
9254
9255 if (mov->flags & FF_MOV_FLAG_FASTSTART) {
9256 av_log(s, AV_LOG_INFO, "Starting second pass: moving the moov atom to the beginning of the file\n");
9257 res = shift_data(s);
9258 if (res < 0)
9259 return res;
9260 avio_seek(pb, mov->reserved_header_pos, SEEK_SET);
9261 if ((res = mov_write_moov_tag(pb, mov, s)) < 0)
9262 return res;
9263 } else if (mov->reserved_moov_size > 0) {
9264 int64_t size;
9265 if ((res = mov_write_moov_tag(pb, mov, s)) < 0)
9266 return res;
9268 if (size < 8){
9269 av_log(s, AV_LOG_ERROR, "reserved_moov_size is too small, needed %"PRId64" additional\n", 8-size);
9270 return AVERROR(EINVAL);
9271 }
9272 avio_wb32(pb, size);
9273 ffio_wfourcc(pb, "free");
9274 ffio_fill(pb, 0, size - 8);
9275 avio_seek(pb, moov_pos, SEEK_SET);
9276 } else {
9277 if ((res = mov_write_moov_tag(pb, mov, s)) < 0)
9278 return res;
9279 }
9280
9282 // With hybrid fragmentation, only write the mdat size (hiding
9283 // the original moov and all the fragments within the mdat)
9284 // after we've successfully written the complete moov, to avoid
9285 // risk for an unreadable file if writing the final moov fails.
9287 }
9288
9289 res = 0;
9290 } else {
9292 for (i = 0; i < mov->nb_tracks; i++)
9293 mov->tracks[i].data_offset = 0;
9294 if (mov->flags & FF_MOV_FLAG_GLOBAL_SIDX) {
9295 int64_t end;
9296 av_log(s, AV_LOG_INFO, "Starting second pass: inserting sidx atoms\n");
9297 res = shift_data(s);
9298 if (res < 0)
9299 return res;
9300 end = avio_tell(pb);
9301 avio_seek(pb, mov->reserved_header_pos, SEEK_SET);
9302 mov_write_sidx_tags(pb, mov, -1, 0);
9303 avio_seek(pb, end, SEEK_SET);
9304 }
9305 if (!(mov->flags & FF_MOV_FLAG_SKIP_TRAILER)) {
9307 res = mov_write_mfra_tag(pb, mov);
9308 if (res < 0)
9309 return res;
9310 }
9311 }
9312
9313 return res;
9314}
9315
9317 const AVPacket *pkt)
9318{
9319 int ret = 1;
9320
9321 if (st->codecpar->codec_id == AV_CODEC_ID_AAC) {
9322 if (pkt->size > 2 && (AV_RB16(pkt->data) & 0xfff0) == 0xfff0)
9323 ret = ff_stream_add_bitstream_filter(st, "aac_adtstoasc", NULL);
9324 } else if (st->codecpar->codec_id == AV_CODEC_ID_VP9) {
9325 ret = ff_stream_add_bitstream_filter(st, "vp9_superframe", NULL);
9326 }
9327
9328 return ret;
9329}
9330
9331#if CONFIG_AVIF_MUXER
9332static int avif_write_trailer(AVFormatContext *s)
9333{
9334 AVIOContext *pb = s->pb;
9335 MOVMuxContext *mov = s->priv_data;
9336 int64_t pos_backup, extent_offsets[2];
9337 uint8_t *buf;
9338 int buf_size, moov_size;
9339
9340 if (mov->moov_written) return 0;
9341
9342 mov->is_animated_avif = s->streams[0]->nb_frames > 1;
9343 if (mov->is_animated_avif && mov->nb_streams > 1) {
9344 // For animated avif with alpha channel, we need to write a tref tag
9345 // with type "auxl".
9346 MovTag *tag = mov_add_tref_tag(mov, &mov->tracks[1], MKTAG('a', 'u', 'x', 'l'));
9347 if (!tag)
9348 return AVERROR(ENOMEM);
9349
9350 int ret = mov_add_tref_id(mov, tag, 1);
9351 if (ret < 0)
9352 return ret;
9353 }
9355 mov_write_meta_tag(pb, mov, s);
9356
9357 moov_size = get_moov_size(s);
9358 for (int i = 0; i < mov->nb_tracks; i++)
9359 mov->tracks[i].data_offset = avio_tell(pb) + moov_size + 8;
9360
9361 if (mov->is_animated_avif) {
9362 int ret;
9363 if ((ret = mov_write_moov_tag(pb, mov, s)) < 0)
9364 return ret;
9365 }
9366
9367 buf_size = avio_get_dyn_buf(mov->mdat_buf, &buf);
9368 avio_wb32(pb, buf_size + 8);
9369 ffio_wfourcc(pb, "mdat");
9370
9371 // The offset for the YUV planes is the starting position of mdat.
9372 extent_offsets[0] = avio_tell(pb);
9373 // The offset for alpha plane is YUV offset + YUV size.
9374 extent_offsets[1] = extent_offsets[0] + mov->avif_extent_length[0];
9375
9376 avio_write(pb, buf, buf_size);
9377
9378 // write extent offsets.
9379 pos_backup = avio_tell(pb);
9380 for (int i = 0; i < mov->nb_streams; i++) {
9381 if (extent_offsets[i] != (uint32_t)extent_offsets[i]) {
9382 av_log(s, AV_LOG_ERROR, "extent offset does not fit in 32 bits\n");
9383 return AVERROR_INVALIDDATA;
9384 }
9385 avio_seek(pb, mov->avif_extent_pos[i], SEEK_SET);
9386 avio_wb32(pb, extent_offsets[i]); /* rewrite offset */
9387 }
9388 avio_seek(pb, pos_backup, SEEK_SET);
9389
9390 return 0;
9391}
9392#endif
9393
9394#if CONFIG_TGP_MUXER || CONFIG_TG2_MUXER
9395static const AVCodecTag codec_3gp_tags[] = {
9396 { AV_CODEC_ID_H263, MKTAG('s','2','6','3') },
9397 { AV_CODEC_ID_H264, MKTAG('a','v','c','1') },
9398 { AV_CODEC_ID_MPEG4, MKTAG('m','p','4','v') },
9399 { AV_CODEC_ID_AAC, MKTAG('m','p','4','a') },
9400 { AV_CODEC_ID_AMR_NB, MKTAG('s','a','m','r') },
9401 { AV_CODEC_ID_AMR_WB, MKTAG('s','a','w','b') },
9402 { AV_CODEC_ID_MOV_TEXT, MKTAG('t','x','3','g') },
9403 { AV_CODEC_ID_NONE, 0 },
9404};
9405static const AVCodecTag *const codec_3gp_tags_list[] = { codec_3gp_tags, NULL };
9406#endif
9407
9408static const AVCodecTag codec_mp4_tags[] = {
9409 { AV_CODEC_ID_MPEG4, MKTAG('m', 'p', '4', 'v') },
9410 { AV_CODEC_ID_H264, MKTAG('a', 'v', 'c', '1') },
9411 { AV_CODEC_ID_H264, MKTAG('a', 'v', 'c', '3') },
9412 { AV_CODEC_ID_HEVC, MKTAG('h', 'e', 'v', '1') },
9413 { AV_CODEC_ID_HEVC, MKTAG('h', 'v', 'c', '1') },
9414 { AV_CODEC_ID_HEVC, MKTAG('d', 'v', 'h', '1') },
9415 { AV_CODEC_ID_VVC, MKTAG('v', 'v', 'c', '1') },
9416 { AV_CODEC_ID_VVC, MKTAG('v', 'v', 'i', '1') },
9417 { AV_CODEC_ID_EVC, MKTAG('e', 'v', 'c', '1') },
9418 { AV_CODEC_ID_LCEVC, MKTAG('l', 'v', 'c', '1') },
9419 { AV_CODEC_ID_APV, MKTAG('a', 'p', 'v', '1') },
9420 { AV_CODEC_ID_MPEG2VIDEO, MKTAG('m', 'p', '4', 'v') },
9421 { AV_CODEC_ID_MPEG1VIDEO, MKTAG('m', 'p', '4', 'v') },
9422 { AV_CODEC_ID_MJPEG, MKTAG('m', 'p', '4', 'v') },
9423 { AV_CODEC_ID_PNG, MKTAG('m', 'p', '4', 'v') },
9424 { AV_CODEC_ID_JPEG2000, MKTAG('m', 'p', '4', 'v') },
9425 { AV_CODEC_ID_VC1, MKTAG('v', 'c', '-', '1') },
9426 { AV_CODEC_ID_DIRAC, MKTAG('d', 'r', 'a', 'c') },
9427 { AV_CODEC_ID_TSCC2, MKTAG('m', 'p', '4', 'v') },
9428 { AV_CODEC_ID_VP9, MKTAG('v', 'p', '0', '9') },
9429 { AV_CODEC_ID_AV1, MKTAG('a', 'v', '0', '1') },
9430 { AV_CODEC_ID_AV1, MKTAG('d', 'a', 'v', '1') },
9431 { AV_CODEC_ID_AAC, MKTAG('m', 'p', '4', 'a') },
9432 { AV_CODEC_ID_APPLE_APAC, MKTAG('a', 'p', 'a', 'c') },
9433 { AV_CODEC_ID_ALAC, MKTAG('a', 'l', 'a', 'c') },
9434 { AV_CODEC_ID_MP4ALS, MKTAG('m', 'p', '4', 'a') },
9435 { AV_CODEC_ID_MP3, MKTAG('m', 'p', '4', 'a') },
9436 { AV_CODEC_ID_MP2, MKTAG('m', 'p', '4', 'a') },
9437 { AV_CODEC_ID_AC3, MKTAG('a', 'c', '-', '3') },
9438 { AV_CODEC_ID_EAC3, MKTAG('e', 'c', '-', '3') },
9439 { AV_CODEC_ID_DTS, MKTAG('m', 'p', '4', 'a') },
9440 { AV_CODEC_ID_TRUEHD, MKTAG('m', 'l', 'p', 'a') },
9441 { AV_CODEC_ID_FLAC, MKTAG('f', 'L', 'a', 'C') },
9442 { AV_CODEC_ID_OPUS, MKTAG('O', 'p', 'u', 's') },
9443 { AV_CODEC_ID_VORBIS, MKTAG('m', 'p', '4', 'a') },
9444 { AV_CODEC_ID_QCELP, MKTAG('m', 'p', '4', 'a') },
9445 { AV_CODEC_ID_EVRC, MKTAG('m', 'p', '4', 'a') },
9446 { AV_CODEC_ID_DVD_SUBTITLE, MKTAG('m', 'p', '4', 's') },
9447 { AV_CODEC_ID_MOV_TEXT, MKTAG('t', 'x', '3', 'g') },
9448 { AV_CODEC_ID_BIN_DATA, MKTAG('g', 'p', 'm', 'd') },
9449 { AV_CODEC_ID_MPEGH_3D_AUDIO, MKTAG('m', 'h', 'm', '1') },
9452 { AV_CODEC_ID_FFV1, MKTAG('F', 'F', 'V', '1') },
9453
9454 /* ISO/IEC 23003-5 integer formats */
9461 /* ISO/IEC 23003-5 floating-point formats */
9466
9467 { AV_CODEC_ID_AVS3, MKTAG('a', 'v', 's', '3') },
9468
9469 { AV_CODEC_ID_NONE, 0 },
9470};
9471#if CONFIG_MP4_MUXER || CONFIG_PSP_MUXER
9472static const AVCodecTag *const mp4_codec_tags_list[] = { codec_mp4_tags, NULL };
9473#endif
9474
9475static const AVCodecTag codec_ism_tags[] = {
9476 { AV_CODEC_ID_WMAPRO , MKTAG('w', 'm', 'a', ' ') },
9478 { AV_CODEC_ID_NONE , 0 },
9479};
9480
9481static const AVCodecTag codec_ipod_tags[] = {
9482 { AV_CODEC_ID_H264, MKTAG('a','v','c','1') },
9483 { AV_CODEC_ID_MPEG4, MKTAG('m','p','4','v') },
9484 { AV_CODEC_ID_AAC, MKTAG('m','p','4','a') },
9485 { AV_CODEC_ID_ALAC, MKTAG('a','l','a','c') },
9486 { AV_CODEC_ID_AC3, MKTAG('a','c','-','3') },
9487 { AV_CODEC_ID_MOV_TEXT, MKTAG('t','x','3','g') },
9488 { AV_CODEC_ID_MOV_TEXT, MKTAG('t','e','x','t') },
9489 { AV_CODEC_ID_NONE, 0 },
9490};
9491
9492static const AVCodecTag codec_f4v_tags[] = {
9493 { AV_CODEC_ID_MP3, MKTAG('.','m','p','3') },
9494 { AV_CODEC_ID_AAC, MKTAG('m','p','4','a') },
9495 { AV_CODEC_ID_H264, MKTAG('a','v','c','1') },
9496 { AV_CODEC_ID_VP6A, MKTAG('V','P','6','A') },
9497 { AV_CODEC_ID_VP6F, MKTAG('V','P','6','F') },
9498 { AV_CODEC_ID_NONE, 0 },
9499};
9500
9501#if CONFIG_AVIF_MUXER
9502
9503static const AVOption avif_options[] = {
9504 { "movie_timescale", "set movie timescale", offsetof(MOVMuxContext, movie_timescale), AV_OPT_TYPE_INT, {.i64 = MOV_TIMESCALE}, 1, INT_MAX, AV_OPT_FLAG_ENCODING_PARAM},
9505 { "loop", "Number of times to loop animated AVIF: 0 - infinite loop", offsetof(MOVMuxContext, avif_loop_count), AV_OPT_TYPE_INT, {.i64 = 0}, 0, INT_MAX, AV_OPT_FLAG_ENCODING_PARAM, .unit = 0 },
9506 { NULL },
9507};
9508static const AVCodecTag codec_avif_tags[] = {
9509 { AV_CODEC_ID_AV1, MKTAG('a','v','0','1') },
9510 { AV_CODEC_ID_NONE, 0 },
9511};
9512static const AVCodecTag *const codec_avif_tags_list[] = { codec_avif_tags, NULL };
9513
9514static const AVClass mov_avif_muxer_class = {
9515 .class_name = "avif muxer",
9516 .item_name = av_default_item_name,
9517 .option = avif_options,
9518 .version = LIBAVUTIL_VERSION_INT,
9519};
9520#endif
9521
9522#if CONFIG_MOV_MUXER
9524 .p.name = "mov",
9525 .p.long_name = NULL_IF_CONFIG_SMALL("QuickTime / MOV"),
9526 .p.extensions = "mov",
9527 .priv_data_size = sizeof(MOVMuxContext),
9528 .p.audio_codec = AV_CODEC_ID_AAC,
9529 .p.video_codec = CONFIG_LIBX264_ENCODER ?
9531 .init = mov_init,
9535 .deinit = mov_free,
9537 .p.codec_tag = (const AVCodecTag* const []){
9539 },
9540 .check_bitstream = mov_check_bitstream,
9541 .p.priv_class = &mov_isobmff_muxer_class,
9542 .flags_internal = FF_OFMT_FLAG_ALLOW_FLUSH,
9543};
9544#endif
9545#if CONFIG_TGP_MUXER
9547 .p.name = "3gp",
9548 .p.long_name = NULL_IF_CONFIG_SMALL("3GP (3GPP file format)"),
9549 .p.extensions = "3gp",
9550 .priv_data_size = sizeof(MOVMuxContext),
9551 .p.audio_codec = AV_CODEC_ID_AMR_NB,
9552 .p.video_codec = AV_CODEC_ID_H263,
9553 .init = mov_init,
9554 .write_header = mov_write_header,
9555 .write_packet = mov_write_packet,
9556 .write_trailer = mov_write_trailer,
9557 .deinit = mov_free,
9559 .p.codec_tag = codec_3gp_tags_list,
9560 .check_bitstream = mov_check_bitstream,
9561 .p.priv_class = &mov_isobmff_muxer_class,
9562 .flags_internal = FF_OFMT_FLAG_ALLOW_FLUSH,
9563};
9564#endif
9565#if CONFIG_MP4_MUXER
9567 .p.name = "mp4",
9568 .p.long_name = NULL_IF_CONFIG_SMALL("MP4 (MPEG-4 Part 14)"),
9569 .p.mime_type = "video/mp4",
9570 .p.extensions = "mp4",
9571 .priv_data_size = sizeof(MOVMuxContext),
9572 .p.audio_codec = AV_CODEC_ID_AAC,
9573 .p.video_codec = CONFIG_LIBX264_ENCODER ?
9575 .init = mov_init,
9579 .deinit = mov_free,
9581 .p.codec_tag = mp4_codec_tags_list,
9583 .p.priv_class = &mov_isobmff_muxer_class,
9584 .flags_internal = FF_OFMT_FLAG_ALLOW_FLUSH,
9585};
9586#endif
9587#if CONFIG_PSP_MUXER
9589 .p.name = "psp",
9590 .p.long_name = NULL_IF_CONFIG_SMALL("PSP MP4 (MPEG-4 Part 14)"),
9591 .p.extensions = "mp4,psp",
9592 .priv_data_size = sizeof(MOVMuxContext),
9593 .p.audio_codec = AV_CODEC_ID_AAC,
9594 .p.video_codec = CONFIG_LIBX264_ENCODER ?
9596 .init = mov_init,
9600 .deinit = mov_free,
9602 .p.codec_tag = mp4_codec_tags_list,
9604 .p.priv_class = &mov_isobmff_muxer_class,
9605 .flags_internal = FF_OFMT_FLAG_ALLOW_FLUSH,
9606};
9607#endif
9608#if CONFIG_TG2_MUXER
9610 .p.name = "3g2",
9611 .p.long_name = NULL_IF_CONFIG_SMALL("3GP2 (3GPP2 file format)"),
9612 .p.extensions = "3g2",
9613 .priv_data_size = sizeof(MOVMuxContext),
9614 .p.audio_codec = AV_CODEC_ID_AMR_NB,
9615 .p.video_codec = AV_CODEC_ID_H263,
9616 .init = mov_init,
9617 .write_header = mov_write_header,
9618 .write_packet = mov_write_packet,
9619 .write_trailer = mov_write_trailer,
9620 .deinit = mov_free,
9622 .p.codec_tag = codec_3gp_tags_list,
9623 .check_bitstream = mov_check_bitstream,
9624 .p.priv_class = &mov_isobmff_muxer_class,
9625 .flags_internal = FF_OFMT_FLAG_ALLOW_FLUSH,
9626};
9627#endif
9628#if CONFIG_IPOD_MUXER
9630 .p.name = "ipod",
9631 .p.long_name = NULL_IF_CONFIG_SMALL("iPod H.264 MP4 (MPEG-4 Part 14)"),
9632 .p.mime_type = "video/mp4",
9633 .p.extensions = "m4v,m4a,m4b",
9634 .priv_data_size = sizeof(MOVMuxContext),
9635 .p.audio_codec = AV_CODEC_ID_AAC,
9636 .p.video_codec = AV_CODEC_ID_H264,
9637 .init = mov_init,
9638 .write_header = mov_write_header,
9639 .write_packet = mov_write_packet,
9640 .write_trailer = mov_write_trailer,
9641 .deinit = mov_free,
9643 .p.codec_tag = (const AVCodecTag* const []){ codec_ipod_tags, 0 },
9644 .check_bitstream = mov_check_bitstream,
9645 .p.priv_class = &mov_isobmff_muxer_class,
9646 .flags_internal = FF_OFMT_FLAG_ALLOW_FLUSH,
9647};
9648#endif
9649#if CONFIG_ISMV_MUXER
9651 .p.name = "ismv",
9652 .p.long_name = NULL_IF_CONFIG_SMALL("ISMV/ISMA (Smooth Streaming)"),
9653 .p.mime_type = "video/mp4",
9654 .p.extensions = "ismv,isma",
9655 .priv_data_size = sizeof(MOVMuxContext),
9656 .p.audio_codec = AV_CODEC_ID_AAC,
9657 .p.video_codec = AV_CODEC_ID_H264,
9658 .init = mov_init,
9659 .write_header = mov_write_header,
9660 .write_packet = mov_write_packet,
9661 .write_trailer = mov_write_trailer,
9662 .deinit = mov_free,
9664 .p.codec_tag = (const AVCodecTag* const []){
9666 .check_bitstream = mov_check_bitstream,
9667 .p.priv_class = &mov_isobmff_muxer_class,
9668 .flags_internal = FF_OFMT_FLAG_ALLOW_FLUSH,
9669};
9670#endif
9671#if CONFIG_F4V_MUXER
9673 .p.name = "f4v",
9674 .p.long_name = NULL_IF_CONFIG_SMALL("F4V Adobe Flash Video"),
9675 .p.mime_type = "application/f4v",
9676 .p.extensions = "f4v",
9677 .priv_data_size = sizeof(MOVMuxContext),
9678 .p.audio_codec = AV_CODEC_ID_AAC,
9679 .p.video_codec = AV_CODEC_ID_H264,
9680 .init = mov_init,
9681 .write_header = mov_write_header,
9682 .write_packet = mov_write_packet,
9683 .write_trailer = mov_write_trailer,
9684 .deinit = mov_free,
9685 .p.flags = AVFMT_GLOBALHEADER,
9686 .p.codec_tag = (const AVCodecTag* const []){ codec_f4v_tags, 0 },
9687 .check_bitstream = mov_check_bitstream,
9688 .p.priv_class = &mov_isobmff_muxer_class,
9689 .flags_internal = FF_OFMT_FLAG_ALLOW_FLUSH,
9690};
9691#endif
9692#if CONFIG_AVIF_MUXER
9694 .p.name = "avif",
9695 .p.long_name = NULL_IF_CONFIG_SMALL("AVIF"),
9696 .p.mime_type = "image/avif",
9697 .p.extensions = "avif",
9698 .priv_data_size = sizeof(MOVMuxContext),
9699 .p.video_codec = AV_CODEC_ID_AV1,
9700 .init = mov_init,
9701 .write_header = mov_write_header,
9702 .write_packet = mov_write_packet,
9703 .write_trailer = avif_write_trailer,
9704 .deinit = mov_free,
9705 .p.flags = AVFMT_GLOBALHEADER,
9706 .p.codec_tag = codec_avif_tags_list,
9707 .p.priv_class = &mov_avif_muxer_class,
9708 .flags_internal = FF_OFMT_FLAG_ALLOW_FLUSH,
9709};
9710#endif
int avpriv_ac3_parse_header(AC3HeaderInfo **phdr, const uint8_t *buf, size_t size)
Definition ac3_parser.c:491
@ EAC3_FRAME_TYPE_DEPENDENT
Definition ac3defs.h:112
@ EAC3_FRAME_TYPE_INDEPENDENT
Definition ac3defs.h:111
@ EAC3_FRAME_TYPE_AC3_CONVERT
Definition ac3defs.h:113
static double val(void *priv, double ch)
Definition aeval.c:77
const FFOutputFormat ff_avif_muxer
const FFOutputFormat ff_psp_muxer
const FFOutputFormat ff_tg2_muxer
const FFOutputFormat ff_mp4_muxer
const FFOutputFormat ff_f4v_muxer
const FFOutputFormat ff_mov_muxer
const FFOutputFormat ff_ipod_muxer
const FFOutputFormat ff_ismv_muxer
const FFOutputFormat ff_tgp_muxer
#define entry
static AVStream * video_st
static AVFormatContext * ctx
channels
Definition aptx.h:31
static const uint8_t channel_map[8][8]
int32_t
int ff_av1_filter_obus_buf(const uint8_t *in, uint8_t **out, int *size, int *offset)
Filter out AV1 OBUs not meant to be present in ISOBMFF sample data and return the result in a data bu...
Definition av1.c:88
int ff_isom_write_av1c(AVIOContext *pb, const uint8_t *buf, int size, int write_seq_header)
Writes AV1 extradata (Sequence Header and Metadata OBUs) to the provided AVIOContext.
Definition av1.c:399
int ff_av1_filter_obus(AVIOContext *pb, const uint8_t *buf, int size)
Filter out AV1 OBUs not meant to be present in ISOBMFF sample data and write the resulting bitstream ...
Definition av1.c:83
#define av_assert2(cond)
assert() equivalent, that does lie in speed critical code.
Definition avassert.h:68
#define av_assert1(cond)
assert() equivalent, that does not lie in speed critical code.
Definition avassert.h:58
#define av_assert0(cond)
assert() equivalent, that is always enabled.
Definition avassert.h:42
int ff_isom_write_avcc(AVIOContext *pb, const uint8_t *data, int len)
Definition avc.c:32
int ff_avc_write_annexb_extradata(const uint8_t *in, uint8_t **buf, int *size)
Definition avc.c:145
void avpriv_set_pts_info(AVStream *st, int pts_wrap_bits, unsigned int pts_num, unsigned int pts_den)
Set the time base and wrapping info for a given stream.
Definition avformat.c:863
Main libavformat public API header.
@ AV_STREAM_GROUP_ENTRY_STREAM
Definition avformat.h:1172
#define AVFMT_FLAG_BITEXACT
When muxing, try to avoid writing any random/volatile data to the output.
Definition avformat.h:1569
#define AV_DISPOSITION_HEARING_IMPAIRED
The stream is intended for hearing impaired audiences.
Definition avformat.h:678
@ AV_STREAM_GROUP_PARAMS_TREF
Definition avformat.h:1163
@ AV_STREAM_GROUP_PARAMS_IAMF_MIX_PRESENTATION
Definition avformat.h:1160
@ AV_STREAM_GROUP_PARAMS_IAMF_AUDIO_ELEMENT
Definition avformat.h:1159
@ AV_STREAM_GROUP_PARAMS_LCEVC
Definition avformat.h:1162
#define AVFMT_VARIABLE_FPS
Format allows variable fps.
Definition avformat.h:503
#define AV_DISPOSITION_MULTILAYER
The video stream contains multiple layers, e.g.
Definition avformat.h:738
#define AVFMT_TS_NEGATIVE
Format allows muxing negative timestamps.
Definition avformat.h:512
#define AVFMT_AVOID_NEG_TS_AUTO
Enabled when required by target format.
Definition avformat.h:1806
#define AVFMT_FLAG_AUTO_BSF
Add bitstream filters as requested by the muxer.
Definition avformat.h:1572
#define AV_DISPOSITION_VISUAL_IMPAIRED
The stream is intended for visually impaired audiences.
Definition avformat.h:682
#define AVFMT_GLOBALHEADER
Format wants global header.
Definition avformat.h:499
#define AV_DISPOSITION_ATTACHED_PIC
The stream is stored in the file as an attached picture/"cover art" (e.g.
Definition avformat.h:694
#define AVFMT_AVOID_NEG_TS_MAKE_ZERO
Shift timestamps so that they start at 0.
Definition avformat.h:1809
#define AV_DISPOSITION_DEFAULT
The stream should be chosen by default among other streams of the same type, unless the user has expl...
Definition avformat.h:641
Buffered I/O operations.
void avio_write_marker(AVIOContext *s, int64_t time, enum AVIODataMarkerType type)
Mark the written bytestream as a specific type.
Definition aviobuf.c:464
int64_t avio_seek(AVIOContext *s, int64_t offset, int whence)
fseek() equivalent for AVIOContext.
Definition aviobuf.c:236
#define AVIO_SEEKABLE_NORMAL
Seeking works like for a local file.
Definition avio.h:41
void avio_wl32(AVIOContext *s, unsigned int val)
Definition aviobuf.c:360
int avio_put_str(AVIOContext *s, const char *str)
Write a NULL-terminated string.
Definition aviobuf.c:376
void avio_w8(AVIOContext *s, int b)
Definition aviobuf.c:184
void avio_wb32(AVIOContext *s, unsigned int val)
Definition aviobuf.c:368
void avio_wb16(AVIOContext *s, unsigned int val)
Definition aviobuf.c:446
@ AVIO_DATA_MARKER_BOUNDARY_POINT
A point in the output bytestream where a demuxer can start parsing (for non self synchronizing bytest...
Definition avio.h:127
@ AVIO_DATA_MARKER_TRAILER
Trailer data, which doesn't contain actual content, but only for finalizing the output file.
Definition avio.h:139
@ AVIO_DATA_MARKER_HEADER
Header data; this needs to be present for the stream to be decodeable.
Definition avio.h:114
@ AVIO_DATA_MARKER_FLUSH_POINT
A point in the output bytestream where the underlying AVIOContext might flush the buffer depending on...
Definition avio.h:145
@ AVIO_DATA_MARKER_SYNC_POINT
A point in the output bytestream where a decoder can start decoding (i.e.
Definition avio.h:121
static av_always_inline int64_t avio_tell(AVIOContext *s)
ftell() equivalent for AVIOContext.
Definition avio.h:507
int avio_printf(AVIOContext *s, const char *fmt,...) av_printf_format(2
Writes a formatted string to the context.
void avio_wb24(AVIOContext *s, unsigned int val)
Definition aviobuf.c:458
int avio_close_dyn_buf(AVIOContext *s, uint8_t **pbuffer)
Return the written size and a pointer to the buffer.
Definition aviobuf.c:1369
void avio_wb64(AVIOContext *s, uint64_t val)
Definition aviobuf.c:434
int64_t avio_skip(AVIOContext *s, int64_t offset)
Skip given number of bytes forward.
Definition aviobuf.c:321
void avio_write(AVIOContext *s, const unsigned char *buf, int size)
Definition aviobuf.c:206
void avio_flush(AVIOContext *s)
Force flushing of buffered data.
Definition aviobuf.c:228
int avio_open_dyn_buf(AVIOContext **s)
Open a write only memory stream.
Definition aviobuf.c:1324
int avio_get_dyn_buf(AVIOContext *s, uint8_t **pbuffer)
Return the written size and a pointer to the buffer.
Definition aviobuf.c:1336
void ffio_free_dyn_buf(AVIOContext **s)
Free a dynamic buffer.
Definition aviobuf.c:1397
static av_always_inline void ffio_wfourcc(AVIOContext *pb, const uint8_t *s)
void ffio_reset_dyn_buf(AVIOContext *s)
Reset a dynamic buffer.
Definition aviobuf.c:1358
void ffio_write_leb(AVIOContext *s, unsigned val)
Definition aviobuf.c:906
int ffio_open_null_buf(AVIOContext **s)
Open a write-only fake memory stream.
Definition aviobuf.c:1421
void ffio_fill(AVIOContext *s, int b, int64_t count)
Definition aviobuf.c:192
int ffio_close_null_buf(AVIOContext *s)
Close a null buffer.
Definition aviobuf.c:1431
size_t av_strlcatf(char *dst, size_t size, const char *fmt,...)
Definition avstring.c:103
static int BS_FUNC left(const BSCTX *bc)
Return the number of the bits left in a buffer.
static int FUNC metadata(CodedBitstreamContext *ctx, RWContext *rw, APVRawMetadata *current)
#define flag(name)
Definition cbs_h264.c:60
#define flags(name, subs,...)
Definition cbs_h264.c:74
#define i(width, name, range_min, range_max)
Definition cbs_h264.c:63
#define s(width, name)
Definition cbs_vp9.c:198
Public libavutil channel layout APIs header.
static void deinit(AVFormatContext *s)
Definition chromaprint.c:53
AVCodecParameters * avcodec_parameters_alloc(void)
Definition codec_par.c:57
void avcodec_parameters_free(AVCodecParameters **ppar)
Definition codec_par.c:67
#define GET_UTF8(val, GET_BYTE, ERROR)
Convert a UTF-8 character (up to 4 bytes) to its 32-bit UCS-4 encoded form.
Definition common.h:477
#define ROUNDED_DIV(a, b)
Definition common.h:58
#define av_clip_uint8
Definition common.h:106
#define NULL
Definition coverity.c:32
long long int64_t
Definition coverity.c:34
Colorspace value utility functions for libavutil.
#define max(a, b)
#define FF_COMPLIANCE_UNOFFICIAL
Allow unofficial extensions.
Definition defs.h:61
#define AV_PROFILE_AAC_HE
Definition defs.h:72
#define FF_COMPLIANCE_EXPERIMENTAL
Allow nonstandardized experimental things.
Definition defs.h:62
#define AV_PROFILE_UNKNOWN
Definition defs.h:65
#define FF_COMPLIANCE_NORMAL
Definition defs.h:60
#define AV_PROFILE_AAC_HE_V2
Definition defs.h:73
#define AV_PROFILE_H264_INTRA
Definition defs.h:122
@ AV_FIELD_UNKNOWN
Definition defs.h:226
@ AV_FIELD_PROGRESSIVE
Definition defs.h:227
#define AV_PROFILE_AAC_USAC
Definition defs.h:76
#define AV_PROFILE_DNXHD
Definition defs.h:89
static AVPacket * pkt
static enum AVPixelFormat pix_fmt
Public dictionary API.
static av_always_inline uint64_t ff_dnxhd_parse_header_prefix(const uint8_t *buf)
Definition dnxhddata.h:85
void ff_isom_put_dvcc_dvvc(void *logctx, uint8_t out[ISOM_DVCC_DVVC_SIZE], const AVDOVIDecoderConfigurationRecord *dovi)
Definition dovi_isom.c:89
#define ISOM_DVCC_DVVC_SIZE
Definition dovi_isom.h:29
DOVI configuration.
enum AVCodecID id
Definition dts2pts.c:607
int(* init)(AVBSFContext *ctx)
Definition dts2pts.c:608
AVEncryptionInitInfo * av_encryption_init_info_get_side_data(const uint8_t *side_data, size_t side_data_size)
Creates a copy of the AVEncryptionInitInfo that is contained in the given side data.
void av_encryption_init_info_free(AVEncryptionInitInfo *info)
Frees the given encryption init info object.
double value
Definition eval.c:102
int ff_isom_write_evcc(AVIOContext *pb, const uint8_t *data, int size, int ps_array_completeness)
Writes EVC sample metadata to the provided AVIOContext.
Definition evc.c:298
static int write_packet(Muxer *mux, OutputStream *ost, AVPacket *pkt)
Definition ffmpeg_mux.c:203
const char * key
static int64_t duration
Definition ffplay.c:359
int ret
Definition ffplay.c:391
static unsigned int nb_streams
Definition ffprobe.c:390
static void write_header(FFV1Context *f)
Definition ffv1enc.c:384
FLAC (Free Lossless Audio Codec) common stuff.
@ FLAC_METADATA_TYPE_STREAMINFO
Definition flac.h:46
#define FLAC_STREAMINFO_SIZE
Definition flac.h:32
bitstream reader API header.
static void skip_bits_long(GetBitContext *s, int n)
Skips the specified number of bits.
Definition get_bits.h:280
static unsigned int get_bits1(GetBitContext *s)
Definition get_bits.h:391
static void skip_bits(GetBitContext *s, int n)
Definition get_bits.h:383
static unsigned int get_bits(GetBitContext *s, int n)
Read 1-25 bits.
Definition get_bits.h:337
static int init_get_bits(GetBitContext *s, const uint8_t *buffer, int bit_size)
Initialize GetBitContext.
Definition get_bits.h:517
#define fail
Definition test.h:479
#define AV_OPT_FLAG_ENCODING_PARAM
A generic parameter which can be set by the user for muxing or encoding.
Definition opt.h:351
@ AV_OPT_TYPE_CONST
Special option type for declaring named constants.
Definition opt.h:298
@ AV_OPT_TYPE_BINARY
Underlying C type is a uint8_t* that is either NULL or points to an array allocated with the av_mallo...
Definition opt.h:285
@ AV_OPT_TYPE_FLAGS
Underlying C type is unsigned int.
Definition opt.h:254
@ AV_OPT_TYPE_INT
Underlying C type is int.
Definition opt.h:258
@ AV_OPT_TYPE_FLOAT
Underlying C type is float.
Definition opt.h:270
@ AV_OPT_TYPE_BOOL
Underlying C type is int.
Definition opt.h:326
@ AV_OPT_TYPE_STRING
Underlying C type is a uint8_t* that is either NULL or points to a C string allocated with the av_mal...
Definition opt.h:275
#define AV_CH_LAYOUT_STEREO
int av_get_bits_per_sample(enum AVCodecID codec_id)
Return codec bits per sample.
Definition utils.c:557
const char * avcodec_get_name(enum AVCodecID id)
Get the name of a codec.
Definition utils.c:421
AVCodecID
Identify the syntax and semantics of the bitstream.
Definition codec_id.h:47
int av_get_exact_bits_per_sample(enum AVCodecID codec_id)
Return codec bits per sample.
Definition utils.c:461
@ AV_CODEC_ID_DIRAC
Definition codec_id.h:166
@ AV_CODEC_ID_PCM_F32LE
Definition codec_id.h:353
@ AV_CODEC_ID_PCM_S24BE
Definition codec_id.h:345
@ AV_CODEC_ID_AVS3
Definition codec_id.h:245
@ AV_CODEC_ID_VORBIS
Definition codec_id.h:462
@ AV_CODEC_ID_V210
Definition codec_id.h:177
@ AV_CODEC_ID_TIMED_ID3
Definition codec_id.h:610
@ AV_CODEC_ID_PNG
Definition codec_id.h:111
@ AV_CODEC_ID_VP6F
Definition codec_id.h:142
@ AV_CODEC_ID_EAC3
Definition codec_id.h:497
@ AV_CODEC_ID_RAWVIDEO
Definition codec_id.h:63
@ AV_CODEC_ID_PCM_U8
Definition codec_id.h:337
@ AV_CODEC_ID_APV
Definition codec_id.h:323
@ AV_CODEC_ID_LCEVC
Definition codec_id.h:613
@ AV_CODEC_ID_PCM_S16LE
Definition codec_id.h:332
@ AV_CODEC_ID_DVD_SUBTITLE
Definition codec_id.h:570
@ AV_CODEC_ID_TTML
Definition codec_id.h:594
@ AV_CODEC_ID_PCM_F32BE
Definition codec_id.h:352
@ AV_CODEC_ID_MP4ALS
Definition codec_id.h:502
@ AV_CODEC_ID_SVQ3
Definition codec_id.h:73
@ AV_CODEC_ID_H264
Definition codec_id.h:77
@ AV_CODEC_ID_NONE
Definition codec_id.h:48
@ AV_CODEC_ID_EVRC
Definition codec_id.h:528
@ AV_CODEC_ID_JPEG2000
Definition codec_id.h:138
@ AV_CODEC_ID_PCM_S16BE
Definition codec_id.h:333
@ AV_CODEC_ID_PCM_S24LE
Definition codec_id.h:344
@ AV_CODEC_ID_VVC
Definition codec_id.h:247
@ AV_CODEC_ID_FFV1
Definition codec_id.h:83
@ AV_CODEC_ID_PCM_S32LE
Definition codec_id.h:340
@ AV_CODEC_ID_PCM_S8
Definition codec_id.h:336
@ AV_CODEC_ID_AV1
Definition codec_id.h:275
@ AV_CODEC_ID_ADPCM_MS
Definition codec_id.h:378
@ AV_CODEC_ID_VC1
Definition codec_id.h:120
@ AV_CODEC_ID_VP8
Definition codec_id.h:190
@ AV_CODEC_ID_MPEGH_3D_AUDIO
Definition codec_id.h:548
@ AV_CODEC_ID_PCM_F64LE
Definition codec_id.h:355
@ AV_CODEC_ID_ALAC
Definition codec_id.h:473
@ AV_CODEC_ID_EIA_608
Definition codec_id.h:580
@ AV_CODEC_ID_AMR_NB
Definition codec_id.h:438
@ AV_CODEC_ID_VP6A
Definition codec_id.h:156
@ AV_CODEC_ID_MP2
Definition codec_id.h:457
@ AV_CODEC_ID_DVVIDEO
Definition codec_id.h:74
@ AV_CODEC_ID_ADPCM_IMA_QT
Definition codec_id.h:372
@ AV_CODEC_ID_DTS
Definition codec_id.h:461
@ AV_CODEC_ID_HEVC
Definition codec_id.h:223
@ AV_CODEC_ID_BIN_DATA
Definition codec_id.h:611
@ AV_CODEC_ID_ADPCM_G726
Definition codec_id.h:383
@ AV_CODEC_ID_AAC
Definition codec_id.h:459
@ AV_CODEC_ID_TRUEHD
Definition codec_id.h:501
@ AV_CODEC_ID_FLAC
Definition codec_id.h:469
@ AV_CODEC_ID_BMP
Definition codec_id.h:128
@ AV_CODEC_ID_PCM_F64BE
Definition codec_id.h:354
@ AV_CODEC_ID_H263
Definition codec_id.h:54
@ AV_CODEC_ID_QCELP
Definition codec_id.h:481
@ AV_CODEC_ID_AMR_WB
Definition codec_id.h:439
@ AV_CODEC_ID_AC3
Definition codec_id.h:460
@ AV_CODEC_ID_TSCC2
Definition codec_id.h:213
@ AV_CODEC_ID_QDM2
Definition codec_id.h:476
@ AV_CODEC_ID_PCM_S32BE
Definition codec_id.h:341
@ AV_CODEC_ID_DNXHD
Definition codec_id.h:149
@ AV_CODEC_ID_MPEG4
Definition codec_id.h:62
@ AV_CODEC_ID_MJPEG
Definition codec_id.h:57
@ AV_CODEC_ID_ADPCM_IMA_WAV
Definition codec_id.h:373
@ AV_CODEC_ID_R10K
Definition codec_id.h:195
@ AV_CODEC_ID_EVC
Definition codec_id.h:316
@ AV_CODEC_ID_APPLE_APAC
Definition codec_id.h:566
@ AV_CODEC_ID_AVUI
Definition codec_id.h:252
@ AV_CODEC_ID_ILBC
Definition codec_id.h:516
@ AV_CODEC_ID_MP3
preferred ID for decoding MPEG audio layer 1, 2 or 3
Definition codec_id.h:458
@ AV_CODEC_ID_VP9
Definition codec_id.h:217
@ AV_CODEC_ID_MPEG1VIDEO
Definition codec_id.h:51
@ AV_CODEC_ID_OPUS
Definition codec_id.h:517
@ AV_CODEC_ID_MPEG2VIDEO
preferred ID for MPEG-1/2 video decoding
Definition codec_id.h:52
@ AV_CODEC_ID_WMAPRO
Definition codec_id.h:494
@ AV_CODEC_ID_MOV_TEXT
Definition codec_id.h:575
#define AV_INPUT_BUFFER_PADDING_SIZE
Required number of additionally allocated bytes at the end of the input bitstream for decoding.
Definition defs.h:40
const AVPacketSideData * av_packet_side_data_get(const AVPacketSideData *sd, int nb_sd, enum AVPacketSideDataType type)
Get side information from a side data array.
Definition packet.c:571
@ AV_PKT_DATA_HEVC_CONF
Dolby Vision enhancement-layer HEVC decoder configuration.
Definition packet.h:384
@ AV_PKT_DATA_AMBIENT_VIEWING_ENVIRONMENT
Ambient viewing environment metadata, as defined by H.274.
Definition packet.h:327
@ AV_PKT_DATA_SKIP_SAMPLES
Recommends skipping the specified number of samples.
Definition packet.h:153
@ AV_PKT_DATA_PRFT
Producer Reference Time data corresponding to the AVProducerReferenceTime struct, usually exported by...
Definition packet.h:265
@ AV_PKT_DATA_ICC_PROFILE
ICC profile data consisting of an opaque octet buffer following the format described by ISO 15076-1.
Definition packet.h:271
@ AV_PKT_DATA_MASTERING_DISPLAY_METADATA
Mastering display metadata (based on SMPTE-2086:2014).
Definition packet.h:219
@ AV_PKT_DATA_SPHERICAL
This side data should be associated with a video stream and corresponds to the AVSphericalMapping str...
Definition packet.h:225
@ AV_PKT_DATA_DISPLAYMATRIX
This side data contains a 3x3 transformation matrix describing an affine transformation that needs to...
Definition packet.h:105
@ AV_PKT_DATA_ENCRYPTION_INIT_INFO
This side data is encryption initialization data.
Definition packet.h:246
@ AV_PKT_DATA_CPB_PROPERTIES
This side data corresponds to the AVCPBProperties struct.
Definition packet.h:142
@ AV_PKT_DATA_NEW_EXTRADATA
The AV_PKT_DATA_NEW_EXTRADATA is used to notify the codec or the format that the extradata buffer was...
Definition packet.h:56
@ AV_PKT_DATA_STEREO3D
This side data should be associated with a video stream and contains Stereoscopic 3D information in f...
Definition packet.h:111
@ AV_PKT_DATA_FRAME_CROPPING
The number of pixels to discard from the top/bottom/left/right border of the decoded frame to obtain ...
Definition packet.h:340
@ AV_PKT_DATA_CONTENT_LIGHT_LEVEL
Content light level (based on CTA-861.3).
Definition packet.h:232
@ AV_PKT_DATA_FALLBACK_TRACK
This side data contains an integer value representing the stream index of a "fallback" track.
Definition packet.h:137
@ AV_PKT_DATA_DOVI_CONF
DOVI configuration ref: dolby-vision-bitstreams-within-the-iso-base-media-file-format-v2....
Definition packet.h:280
void av_packet_free(AVPacket **pkt)
Free the packet, if the packet is reference counted, it will be unreferenced first.
Definition packet.c:74
#define AV_PKT_FLAG_DISCARD
Flag is used to discard packets which are required to maintain valid decoder state but are not requir...
Definition packet.h:664
void av_packet_unref(AVPacket *pkt)
Wipe the packet.
Definition packet.c:435
uint8_t * av_packet_new_side_data(AVPacket *pkt, enum AVPacketSideDataType type, size_t size)
Allocate new information of a packet.
Definition packet.c:231
int av_grow_packet(AVPacket *pkt, int grow_by)
Increase packet size, correctly zeroing padding.
Definition packet.c:121
#define AV_PKT_FLAG_KEY
The packet contains a keyframe.
Definition packet.h:657
#define AV_PKT_FLAG_DISPOSABLE
Flag is used to indicate packets that contain frames that can be discarded by the decoder.
Definition packet.h:676
void av_packet_move_ref(AVPacket *dst, AVPacket *src)
Move every field in src to dst and reset src.
Definition packet.c:492
int av_packet_make_writable(AVPacket *pkt)
Create a writable reference for the data described by a given packet, avoiding data copy if possible.
Definition packet.c:517
uint8_t * av_packet_get_side_data(const AVPacket *pkt, enum AVPacketSideDataType type, size_t *size)
Get side information from packet.
Definition packet.c:252
AVPacket * av_packet_alloc(void)
Allocate an AVPacket and set its fields to default values.
Definition packet.c:63
int av_packet_ref(AVPacket *dst, const AVPacket *src)
Setup a new reference to the data described by a given packet.
Definition packet.c:443
int av_match_ext(const char *filename, const char *extensions)
Return a positive value if the given filename has one of the given extensions, 0 otherwise.
Definition format.c:41
#define AES_CTR_KEY_SIZE
Definition aes_ctr.h:35
int av_channel_layout_from_string(AVChannelLayout *channel_layout, const char *str)
Initialize a channel layout from a given string description.
int av_channel_layout_ambisonic_order(const AVChannelLayout *channel_layout)
Return the order if the layout is n-th order standard-order ambisonic.
int av_channel_layout_compare(const AVChannelLayout *chl, const AVChannelLayout *chl1)
Check whether two channel layouts are semantically the same, i.e.
#define AV_CHANNEL_LAYOUT_MONO
enum AVChannel av_channel_layout_channel_from_index(const AVChannelLayout *channel_layout, unsigned int idx)
Get the channel with the given index in a channel layout.
void av_channel_layout_uninit(AVChannelLayout *channel_layout)
Free any allocated data in the channel layout and reset the channel count to 0.
int av_channel_layout_from_mask(AVChannelLayout *channel_layout, uint64_t mask)
Initialize a native channel layout from a bitmask indicating which channels are present.
int av_channel_layout_describe(const AVChannelLayout *channel_layout, char *buf, size_t buf_size)
Get a human-readable string describing the channel layout properties.
uint64_t av_channel_layout_subset(const AVChannelLayout *channel_layout, uint64_t mask)
Find out what channels from a given set are present in a channel layout, without regard for their pos...
@ AV_CHAN_AMBISONIC_BASE
Range of channels between AV_CHAN_AMBISONIC_BASE and AV_CHAN_AMBISONIC_END represent Ambisonic compon...
void av_buffer_unref(AVBufferRef **buf)
Free a given reference and automatically free the buffer if there are no more references to it.
Definition buffer.c:140
AVBufferRef * av_buffer_create(uint8_t *data, size_t size, void(*free)(void *opaque, uint8_t *data), void *opaque, int flags)
Create an AVBuffer from an existing array.
Definition buffer.c:56
AVDictionaryEntry * av_dict_get(const AVDictionary *m, const char *key, const AVDictionaryEntry *prev, int flags)
Get a dictionary entry with matching key.
Definition dict.c:61
#define AV_DICT_IGNORE_SUFFIX
Return first entry in a dictionary whose first part corresponds to the search key,...
Definition dict.h:75
const AVDictionaryEntry * av_dict_iterate(const AVDictionary *m, const AVDictionaryEntry *prev)
Iterate over a dictionary.
Definition dict.c:43
#define AVERROR_EXPERIMENTAL
Requested feature is flagged experimental. Set strict_std_compliance if you really want to use it.
Definition error.h:74
#define AVERROR_PATCHWELCOME
Not yet implemented in FFmpeg, patches welcome.
Definition error.h:64
#define AVERROR_BUG
Internal bug, also see AVERROR_BUG2.
Definition error.h:52
#define AVERROR_INVALIDDATA
Invalid data found when processing input.
Definition error.h:61
#define av_err2str(errnum)
Convenience macro, the return value should be used only directly in function arguments but never stan...
Definition error.h:122
#define AVERROR(e)
Definition error.h:45
#define AV_LOG_DEBUG
Stuff which is only useful for libav* developers.
Definition log.h:231
#define AV_LOG_WARNING
Something somehow does not look correct.
Definition log.h:216
#define AV_LOG_VERBOSE
Detailed information.
Definition log.h:226
#define AV_LOG_INFO
Standard information.
Definition log.h:221
#define AV_LOG_ERROR
Something went wrong and cannot losslessly be recovered.
Definition log.h:210
const char * av_default_item_name(void *ptr)
Return the context name.
Definition log.c:241
double av_csp_approximate_eotf_gamma(enum AVColorTransferCharacteristic trc)
Determine a suitable EOTF 'gamma' value to match the supplied AVColorTransferCharacteristic.
Definition csp.c:187
int av_reduce(int *dst_num, int *dst_den, int64_t num, int64_t den, int64_t max)
Reduce a fraction.
Definition rational.c:35
AVRational av_gcd_q(AVRational a, AVRational b, int max_den, AVRational def)
Return the best rational so that a and b are multiple of it.
Definition rational.c:188
static double av_q2d(AVRational a)
Convert an AVRational to a double.
Definition rational.h:104
static av_always_inline AVRational av_inv_q(AVRational q)
Invert a rational.
Definition rational.h:159
AVRational av_sub_q(AVRational b, AVRational c)
Subtract one rational from another.
Definition rational.c:101
int64_t av_rescale(int64_t a, int64_t b, int64_t c)
Rescale a 64-bit integer with rounding to nearest.
int64_t av_rescale_rnd(int64_t a, int64_t b, int64_t c, enum AVRounding rnd)
Rescale a 64-bit integer with specified rounding.
Definition mathematics.c:58
int64_t av_rescale_q(int64_t a, AVRational bq, AVRational cq)
Rescale a 64-bit integer by 2 rational numbers.
@ AV_ROUND_DOWN
Round toward -infinity.
@ AV_ROUND_UP
Round toward +infinity.
void * av_realloc_array(void *ptr, size_t nmemb, size_t size)
Definition mem.c:318
void * av_memdup(const void *p, size_t size)
Duplicate a buffer with av_malloc().
Definition mem.c:408
int av_reallocp_array(void *ptr, size_t nmemb, size_t size)
Allocate, reallocate an array through a pointer to a pointer.
Definition mem.c:326
#define av_fourcc2str(fourcc)
Definition avutil.h:323
@ AVMEDIA_TYPE_AUDIO
Definition avutil.h:201
@ AVMEDIA_TYPE_NB
Definition avutil.h:205
@ AVMEDIA_TYPE_SUBTITLE
Definition avutil.h:203
@ AVMEDIA_TYPE_VIDEO
Definition avutil.h:200
@ AVMEDIA_TYPE_DATA
Opaque data information usually continuous.
Definition avutil.h:202
@ AVMEDIA_TYPE_UNKNOWN
Usually treated as AVMEDIA_TYPE_DATA.
Definition avutil.h:199
size_t av_strlcat(char *dst, const char *src, size_t size)
Append the string src to the string dst, but to a total length of no more than size - 1 bytes,...
Definition avstring.c:95
size_t av_strlcpy(char *dst, const char *src, size_t size)
Copy the string src to dst, but no more than size - 1 bytes, and null-terminate dst.
Definition avstring.c:85
#define AV_NOPTS_VALUE
Undefined timestamp value.
Definition avutil.h:247
#define AV_TIME_BASE
Internal time base represented as integer.
Definition avutil.h:253
#define AV_TIME_BASE_Q
Internal time base represented as fractional value.
Definition avutil.h:263
#define LIBAVUTIL_VERSION_INT
Definition version.h:85
@ AV_SPHERICAL_RECTILINEAR
Video frame displays on a flat, rectangular 2D surface.
Definition spherical.h:78
@ AV_SPHERICAL_EQUIRECTANGULAR
Video represents a sphere mapped on a flat surface using equirectangular projection.
Definition spherical.h:52
@ AV_SPHERICAL_EQUIRECTANGULAR_TILE
Video represents a portion of a sphere mapped on a flat surface using equirectangular projection.
Definition spherical.h:68
@ AV_SPHERICAL_CUBEMAP
Video frame is split into 6 faces of a cube, and arranged on a 3x2 layout.
Definition spherical.h:61
@ AV_SPHERICAL_HALF_EQUIRECTANGULAR
Video frame displays as a 180 degree equirectangular projection.
Definition spherical.h:73
@ AV_SPHERICAL_FISHEYE
Fisheye projection (Apple).
Definition spherical.h:84
const char * av_stereo3d_type_name(unsigned int type)
Provide a human-readable name of a given stereo3d type.
Definition stereo3d.c:93
#define AV_STEREO3D_FLAG_INVERT
Inverted views, Right/Bottom represents the left view.
Definition stereo3d.h:194
@ AV_STEREO3D_2D
Video is not stereoscopic (and metadata has to be there).
Definition stereo3d.h:52
@ AV_STEREO3D_TOPBOTTOM
Views are on top of each other.
Definition stereo3d.h:76
@ AV_STEREO3D_SIDEBYSIDE
Views are next to each other.
Definition stereo3d.h:64
@ AV_PRIMARY_EYE_NONE
Neither eye.
Definition stereo3d.h:178
@ AV_STEREO3D_VIEW_RIGHT
Frame contains only the right view.
Definition stereo3d.h:163
@ AV_STEREO3D_VIEW_PACKED
Frame contains two packed views.
Definition stereo3d.h:153
@ AV_STEREO3D_VIEW_LEFT
Frame contains only the left view.
Definition stereo3d.h:158
@ AV_STEREO3D_VIEW_UNSPEC
Content is unspecified.
Definition stereo3d.h:168
int index
Definition gxfenc.c:90
int a
int ff_isom_write_lhvc(AVIOContext *pb, const uint8_t *data, int size, int ps_array_completeness, void *logctx)
Writes L-HEVC extradata (parameter sets with nuh_layer_id > 0, as a LHEVCDecoderConfigurationRecord) ...
Definition hevc.c:1408
int ff_hevc_annexb2mp4_buf(const uint8_t *buf_in, uint8_t **buf_out, int *size, int filter_ps, int *ps_count)
Writes Annex B formatted HEVC NAL units to a data buffer.
Definition hevc.c:1252
int ff_hevc_annexb2mp4(AVIOContext *pb, const uint8_t *buf_in, int size, int filter_ps, int *ps_count)
Writes Annex B formatted HEVC NAL units to the provided AVIOContext.
Definition hevc.c:1204
int ff_isom_write_hvcc(AVIOContext *pb, const uint8_t *data, int size, int ps_array_completeness, void *logctx)
Writes HEVC extradata (parameter sets and declarative SEI NAL units with nuh_layer_id == 0,...
Definition hevc.c:1401
const VDPAUPixFmtMap * map
int ff_iamf_write_descriptors(const IAMFContext *iamf, AVIOContext *pb, void *log_ctx)
int ff_iamf_write_audio_frame(const IAMFContext *iamf, AVIOContext *pb, unsigned audio_substream_id, const AVPacket *pkt)
int ff_iamf_add_mix_presentation(IAMFContext *iamf, const AVStreamGroup *stg, void *log_ctx)
int ff_iamf_add_audio_element(IAMFContext *iamf, const AVStreamGroup *stg, void *log_ctx)
int ff_iamf_write_parameter_blocks(const IAMFContext *iamf, AVIOContext *pb, const AVPacket *pkt, void *log_ctx)
#define r
Definition input.c:42
#define b
Definition input.c:43
static av_always_inline uint64_t av_double2int(double f)
Reinterpret a double as a 64-bit integer.
Definition intfloat.h:70
#define AV_WB32(p, v)
#define AV_RB8(x)
#define AV_RL32(p)
#define AV_RB32(p)
#define AV_RL16(p)
#define AV_WB16(p, v)
#define AV_RB24(x)
#define AV_RB16(p)
const AVCodecTag ff_mp4_obj_type[]
Definition isom.c:34
int ff_mov_iso639_to_lang(const char lang[4], int mp4)
Definition isom.c:234
const struct MP4TrackKindMapping ff_mov_track_kind_table[]
Definition isom.c:465
const AVCodecTag ff_codec_movsubtitle_tags[]
Definition isom.c:75
#define MOV_TRUN_SAMPLE_DURATION
Definition isom.h:425
#define MOV_GRAPHICS_MODE_COPY
Definition isom.h:452
#define MOV_TRUN_SAMPLE_CTS
Definition isom.h:428
#define MOV_TKHD_FLAG_ENABLED
Definition isom.h:440
#define MOV_TFHD_DEFAULT_BASE_IS_MOOF
Definition isom.h:421
const AVCodecTag ff_codec_movaudio_tags[]
Definition isom_tags.c:307
#define MOV_FRAG_SAMPLE_FLAG_DEPENDS_YES
Definition isom.h:438
const AVCodecTag ff_codec_movvideo_tags[]
Definition isom_tags.c:29
#define MOV_TFHD_DEFAULT_SIZE
Definition isom.h:418
#define MOV_ISMV_TTML_TAG
Definition isom.h:502
#define MOV_FRAG_SAMPLE_FLAG_DEPENDS_NO
Definition isom.h:437
#define TAG_IS_AVCI(tag)
Definition isom.h:462
#define MOV_TRUN_FIRST_SAMPLE_FLAGS
Definition isom.h:424
#define MOV_GRAPHICS_MODE_PREMUL_BLACK_ALPHA
Definition isom.h:458
#define MOV_MP4_FPCM_TAG
Definition isom.h:504
#define MOV_FRAG_SAMPLE_FLAG_IS_NON_SYNC
Definition isom.h:431
#define MOV_SAMPLE_DEPENDENCY_UNKNOWN
Definition isom.h:447
#define MOV_TFHD_STSD_ID
Definition isom.h:416
#define MOV_TRUN_SAMPLE_FLAGS
Definition isom.h:427
#define MOV_MP4_TTML_TAG
Definition isom.h:503
#define MOV_TFHD_DEFAULT_FLAGS
Definition isom.h:419
#define MOV_SAMPLE_DEPENDENCY_YES
Definition isom.h:448
#define MOV_TRUN_DATA_OFFSET
Definition isom.h:423
#define MOV_TFHD_BASE_DATA_OFFSET
Definition isom.h:415
#define MOV_MP4_IPCM_TAG
Definition isom.h:505
#define MOV_TFHD_DURATION_IS_EMPTY
Definition isom.h:420
#define MOV_TKHD_FLAG_IN_MOVIE
Definition isom.h:441
#define MOV_TRUN_SAMPLE_SIZE
Definition isom.h:426
#define MOV_SAMPLE_DEPENDENCY_NO
Definition isom.h:449
#define MOV_GRAPHICS_MODE_STRAIGHT_ALPHA
Definition isom.h:456
#define MOV_TFHD_DEFAULT_DURATION
Definition isom.h:417
static void put_bits(Jpeg2000EncoderContext *s, int val, int n)
put n times val bit
Definition j2kenc.c:154
uint32_t type
Definition jpegmpfenc.c:80
int ff_isom_write_lvcc(AVIOContext *pb, const uint8_t *data, int len, void *logctx)
Definition lcevc.c:264
unsigned offset
Definition libaomenc.c:763
common internal api header.
unsigned int ff_toupper4(unsigned int x)
Definition to_upper4.h:29
void ff_isom_write_apvc(AVIOContext *pb, const APVDecoderConfigurationRecord *apvc, void *logctx)
Definition apv.c:80
int ff_isom_init_apvc(APVDecoderConfigurationRecord **papvc, void *logctx)
Definition apv.c:352
void ff_isom_close_apvc(APVDecoderConfigurationRecord **papvc)
Definition apv.c:375
int ff_isom_parse_apvc(APVDecoderConfigurationRecord *apvc, const AVPacket *pkt, void *logctx)
Definition apv.c:252
internal header for HEVC (de)muxer utilities
void ff_iamf_uninit_context(IAMFContext *c)
Definition iamf.c:172
unsigned int ff_codec_get_tag(const AVCodecTag *tags, enum AVCodecID id)
Definition utils.c:133
int ff_sdp_write_media(char *buff, int size, const AVStream *st, int idx, const char *dest_addr, const char *dest_type, int port, int ttl, AVFormatContext *fmt)
Append the media-specific SDP fragment for the media stream c to the buffer buff.
Definition sdp.c:956
uint64_t ff_ntp_time(void)
Get the current time since NTP epoch in microseconds.
Definition utils.c:257
char * ff_data_to_hex(char *buf, const uint8_t *src, int size, int lowercase)
Write hexadecimal string corresponding to given binary data.
Definition utils.c:473
uint64_t ff_get_formatted_ntp_time(uint64_t ntp_time_us)
Get the NTP time stamp formatted as per the RFC-5905.
Definition utils.c:262
int ff_alloc_extradata(AVCodecParameters *par, int size)
Allocate extradata with additional AV_INPUT_BUFFER_PADDING_SIZE at end which is always set to 0.
Definition utils.c:237
static av_always_inline FFFormatContext * ffformatcontext(AVFormatContext *s)
Definition internal.h:135
#define NTP_OFFSET_US
Definition internal.h:427
const AVPacket * ff_interleaved_peek(AVFormatContext *s, int stream)
Find the next packet in the interleaving queue for the given stream.
Definition mux.c:1081
static int check_bitstream(AVFormatContext *s, FFStream *sti, AVPacket *pkt)
Definition mux.c:1094
int ff_stream_add_bitstream_filter(AVStream *st, const char *name, const char *args)
Add a bitstream filter to a stream.
Definition mux.c:1332
int ff_get_muxer_ts_offset(AVFormatContext *s, int stream_index, int64_t *offset)
Definition mux.c:1065
void ff_packet_list_free(PacketList *list)
Wipe the list and unref all the packets in it.
int ff_packet_list_put(PacketList *list, AVPacket *pkt, int(*copy)(AVPacket *dst, const AVPacket *src), int flags)
Append an AVPacket to the list.
Definition packet_list.c:40
static unsigned int ff_is_ttml_stream_paragraph_based(const AVCodecParameters *codecpar)
Definition ttmlenc.h:28
Libavformat version macros.
#define LIBAVFORMAT_IDENT
Definition version.h:45
internal header for H.266/VVC (de)muxer utilities
#define NULL_IF_CONFIG_SMALL(x)
Return NULL if CONFIG_SMALL is true, otherwise the argument without modification.
Definition internal.h:97
Stereoscopic video.
version
Definition libkvazaar.c:313
#define FFMIN(a, b)
Definition macros.h:49
#define MKTAG(a, b, c, d)
Definition macros.h:55
#define FFMAX(a, b)
Definition macros.h:47
uint64_t layout
void * av_calloc(size_t nmemb, size_t size)
Definition mem.c:370
Memory handling functions.
int ff_mov_get_channel_positions_from_layout(const AVChannelLayout *layout, uint8_t *position, int position_num)
Get ISO/IEC 23001-8 OutputChannelPosition from AVChannelLayout.
Definition mov_chan.c:741
int ff_mov_get_channel_layout_tag(const AVCodecParameters *par, uint32_t *layout, uint32_t *bitmap, uint32_t **pchannel_desc)
Get the channel layout tag for the specified codec id and channel layout.
Definition mov_chan.c:476
int ff_mov_get_channel_config_from_layout(const AVChannelLayout *layout, int *config)
Get ISO/IEC 23001-8 ChannelConfiguration from AVChannelLayout.
Definition mov_chan.c:705
@ MOV_CH_LAYOUT_MONO
Definition mov_chan.h:56
#define MOV_CH_LAYOUT_UNKNOWN
Definition mov_chan.h:52
static int mov_write_stsd_tag(AVFormatContext *s, AVIOContext *pb, MOVMuxContext *mov, MOVTrack *track)
Definition movenc.c:3243
static int mov_write_stco_tag(AVIOContext *pb, MOVTrack *track)
Definition movenc.c:202
static int mov_write_av3c(AVIOContext *pb, const uint8_t *data, int len)
Definition movenc.c:1673
static int mov_write_trex_tag(AVIOContext *pb, MOVTrack *track)
Definition movenc.c:4568
static int get_moov_size(AVFormatContext *s)
Definition movenc.c:9065
static unsigned compute_avg_bitrate(MOVTrack *track)
Definition movenc.c:736
static int mov_write_sidx_tag(AVIOContext *pb, MOVTrack *track, int ref_size, int total_sidx_size)
Definition movenc.c:6027
static const AVCodecTag codec_cover_image_tags[]
Definition movenc.c:2241
static int mov_write_header(AVFormatContext *s)
Definition movenc.c:8885
static int mov_write_sdtp_tag(AVIOContext *pb, MOVTrack *track)
Definition movenc.c:317
static const AVCodecTag codec_ism_tags[]
Definition movenc.c:9475
static MovTag * mov_add_tref_tag(MOVMuxContext *mov, MOVTrack *trk, uint32_t name)
Definition movenc.c:5414
static int utf8len(const uint8_t *b)
Definition movenc.c:144
static AVDictionaryEntry * get_metadata_lang(AVFormatContext *s, const char *tag, int *lang)
Definition movenc.c:4737
static int mov_write_stbl_tag(AVFormatContext *s, AVIOContext *pb, MOVMuxContext *mov, MOVTrack *track)
Definition movenc.c:3480
static int mov_write_ac3_tag(AVFormatContext *s, AVIOContext *pb, MOVTrack *track)
Definition movenc.c:420
static int mov_write_hvcc_tag(AVFormatContext *s, AVIOContext *pb, MOVTrack *track)
Definition movenc.c:1713
static int mov_write_stsz_tag(AVIOContext *pb, MOVTrack *track)
Definition movenc.c:226
int ff_mov_set_fragment_end_hint(AVFormatContext *s, int stream_index, const AVPacket *pkt, AVRational src_time_base)
Definition movenc.c:7026
static int mov_write_iref_tag(AVIOContext *pb, MOVMuxContext *mov, AVFormatContext *s)
Definition movenc.c:3800
static uint16_t mov_graphics_mode(MOVTrack *track)
Definition movenc.c:3628
static int mov_write_uuid_tag_psp(AVIOContext *pb, MOVTrack *mov)
Definition movenc.c:4350
static int mov_write_evcc_tag(AVIOContext *pb, MOVTrack *track)
Definition movenc.c:1750
static int mov_write_raw_metadata_tag(AVFormatContext *s, AVIOContext *pb, const char *name, const char *key)
Definition movenc.c:5072
static int mov_write_dfla_tag(AVIOContext *pb, MOVTrack *track)
Definition movenc.c:890
static int mov_write_dinf_tag(AVIOContext *pb)
Definition movenc.c:3519
static int mov_write_dpxe_tag(AVIOContext *pb, MOVTrack *track)
Definition movenc.c:1934
#define IS_MODE(muxer, config)
static void write_matrix(AVIOContext *pb, int16_t a, int16_t b, int16_t c, int16_t d, int16_t tx, int16_t ty)
Definition movenc.c:4068
static int mov_write_traf_tag(AVIOContext *pb, MOVMuxContext *mov, MOVTrack *track, int64_t moof_offset, int moof_size)
Definition movenc.c:5960
uint32_t tag
Definition movenc.c:2128
static int mov_write_emsg_tag(AVIOContext *pb, AVStream *st, AVPacket *pkt)
Definition movenc.c:7687
static int mov_flush_fragment_interleaving(AVFormatContext *s, MOVTrack *track)
Definition movenc.c:6646
static int mov_get_mpeg2_xdcam_codec_tag(AVFormatContext *s, MOVTrack *track)
Definition movenc.c:1981
static int mov_write_iinf_tag(AVIOContext *pb, MOVMuxContext *mov, AVFormatContext *s)
Definition movenc.c:3775
static int mov_write_mdhd_tag(AVIOContext *pb, MOVMuxContext *mov, MOVTrack *track)
Definition movenc.c:4012
static int mov_create_chapter_track(AVFormatContext *s, int tracknum)
Definition movenc.c:7866
static int mov_mdhd_mvhd_tkhd_version(MOVMuxContext *mov, MOVTrack *track, int64_t duration)
Definition movenc.c:4003
static int mov_add_tfra_entries(AVIOContext *pb, MOVMuxContext *mov, int tracks, int size)
Definition movenc.c:5895
static int mov_write_mhac_tag(AVFormatContext *s, AVIOContext *pb, MOVTrack *track)
Definition movenc.c:973
static int shift_data(AVFormatContext *s)
Definition movenc.c:9136
static int mov_write_av3c_tag(AVIOContext *pb, MOVTrack *track)
Definition movenc.c:1692
static int64_t update_size_and_version(AVIOContext *pb, int64_t pos, int version)
Definition movenc.c:166
static int mov_write_wfex_tag(AVFormatContext *s, AVIOContext *pb, MOVTrack *track)
Definition movenc.c:879
static int mov_write_chan_tag(AVFormatContext *s, AVIOContext *pb, MOVTrack *track)
Definition movenc.c:1069
unsigned bps
Definition movenc.c:2129
static int mov_write_gama_tag(AVFormatContext *s, AVIOContext *pb, MOVTrack *track, double gamma)
Definition movenc.c:2663
static int mov_write_amve_tag(AVIOContext *pb, MOVTrack *track)
Definition movenc.c:2784
static const AVCodecTag codec_ipod_tags[]
Definition movenc.c:9481
static int mov_write_eac3_tag(AVFormatContext *s, AVIOContext *pb, MOVTrack *track)
Definition movenc.c:645
static int co64_required(const MOVTrack *track)
Definition movenc.c:178
static int mov_write_sthd_tag(AVIOContext *pb)
Definition movenc.c:3536
static int mov_write_aux_tag(AVIOContext *pb, const char *aux_type)
Definition movenc.c:2860
static int mov_write_pasp_tag(AVIOContext *pb, MOVTrack *track)
Definition movenc.c:2650
static int compute_moov_size(AVFormatContext *s)
Definition movenc.c:9096
static int mov_write_loci_tag(AVFormatContext *s, AVIOContext *pb)
Definition movenc.c:4802
static int mov_write_tfra_tag(AVIOContext *pb, MOVTrack *track)
Definition movenc.c:6210
static int ascii_to_wc(AVIOContext *pb, const uint8_t *b)
Definition movenc.c:5092
static int mov_write_sidx_tags(AVIOContext *pb, MOVMuxContext *mov, int tracks, int ref_size)
Definition movenc.c:6088
static int mov_write_vexu_tag(AVFormatContext *s, AVIOContext *pb, const AVStereo3D *stereo3d, const AVSphericalMapping *spherical_mapping)
Definition movenc.c:2554
static MovTag * mov_find_tref_tag(MOVMuxContext *mov, const MOVTrack *trk, uint32_t name)
Definition movenc.c:5403
static const AVClass mov_isobmff_muxer_class
Definition movenc.c:134
static int mov_preroll_write_stbl_atoms(AVIOContext *pb, MOVTrack *track)
Definition movenc.c:3383
static void mov_write_ftyp_tag_internal(AVIOContext *pb, AVFormatContext *s, int has_h264, int has_video, int write_minor)
Definition movenc.c:6283
static int mov_write_dmlp_tag(AVFormatContext *s, AVIOContext *pb, MOVTrack *track)
Definition movenc.c:944
static int mov_write_vvcc_tag(AVIOContext *pb, MOVTrack *track)
Definition movenc.c:1780
static int mov_write_iprp_tag(AVIOContext *pb, MOVMuxContext *mov, AVFormatContext *s)
Definition movenc.c:3888
static int mov_write_tmcd_tag(AVIOContext *pb, MOVTrack *track)
Definition movenc.c:3182
static int mov_create_timecode_track(AVFormatContext *s, int index, int src_index, AVTimecode tc)
Definition movenc.c:7966
static int mov_create_dvd_sub_decoder_specific_info(MOVTrack *track, AVStream *st)
Definition movenc.c:8144
static int mov_write_prft_tag(AVIOContext *pb, MOVMuxContext *mov, int tracks)
Definition movenc.c:6126
static int mov_write_glbl_tag(AVIOContext *pb, MOVTrack *track)
Definition movenc.c:1274
static int mov_write_ipco_tag(AVIOContext *pb, MOVMuxContext *mov, AVFormatContext *s)
Definition movenc.c:3847
static void mov_write_mdat_size(AVFormatContext *s)
Definition movenc.c:9151
static uint32_t get_sample_flags(MOVTrack *track, MOVIentry *entry)
Definition movenc.c:5698
static void enable_tracks(AVFormatContext *s)
Definition movenc.c:8027
static int mov_write_minf_tag(AVFormatContext *s, AVIOContext *pb, MOVMuxContext *mov, MOVTrack *track)
Definition movenc.c:3913
static int mov_pcm_le_gt16(enum AVCodecID codec_id)
Definition movenc.c:851
static int mov_write_tfrf_tag(AVIOContext *pb, MOVMuxContext *mov, MOVTrack *track, int entry)
Definition movenc.c:5846
static int mov_write_avcc_tag(AVIOContext *pb, MOVTrack *track)
Definition movenc.c:1658
static int mov_write_extradata_tag(AVIOContext *pb, MOVTrack *track)
This function writes extradata "as is".
Definition movenc.c:705
static int mov_write_covr(AVIOContext *pb, AVFormatContext *s)
Definition movenc.c:4907
static int mov_write_srat_tag(AVIOContext *pb, MOVTrack *track)
Definition movenc.c:1438
static int mov_write_smhd_tag(AVIOContext *pb)
Definition movenc.c:3618
static int mov_write_clap_tag(AVIOContext *pb, MOVTrack *track, uint32_t top, uint32_t bottom, uint32_t left, uint32_t right)
Definition movenc.c:2622
static int mov_finish_fragment(MOVMuxContext *mov, MOVTrack *track, int64_t ref_pos)
Definition movenc.c:6733
static int mov_write_mdta_keys_tag(AVIOContext *pb, MOVMuxContext *mov, AVFormatContext *s)
Definition movenc.c:4990
static void find_compressor(char *compressor_name, int len, MOVTrack *track)
Definition movenc.c:2811
static void mov_parse_truehd_frame(AVPacket *pkt, MOVTrack *trk)
Definition movenc.c:6627
static int mov_write_tkhd_tag(AVIOContext *pb, MOVMuxContext *mov, MOVTrack *track, AVStream *st)
Definition movenc.c:4082
static int mov_write_amr_tag(AVIOContext *pb, MOVTrack *track)
Definition movenc.c:370
static int mov_write_sv3d_tag(AVFormatContext *s, AVIOContext *pb, AVSphericalMapping *spherical_mapping)
Definition movenc.c:2395
static int mov_get_h264_codec_tag(AVFormatContext *s, MOVTrack *track)
Definition movenc.c:2043
static int mov_get_dnxhd_codec_tag(AVFormatContext *s, MOVTrack *track)
Definition movenc.c:2151
static uint32_t rgb_to_yuv(uint32_t rgb)
Definition movenc.c:8128
static int mov_write_lhvc_tag(AVFormatContext *s, AVIOContext *pb, MOVTrack *track)
Definition movenc.c:1728
static struct mpeg4_bit_rate_values calculate_mpeg4_bit_rates(MOVTrack *track)
Definition movenc.c:753
static int mov_auto_flush_fragment(AVFormatContext *s, int force)
Definition movenc.c:6977
static int mov_write_moof_tag(AVIOContext *pb, MOVMuxContext *mov, int tracks, int64_t mdat_size)
Definition movenc.c:6176
static int mov_write_moof_tag_internal(AVIOContext *pb, MOVMuxContext *mov, int tracks, int moof_size)
Definition movenc.c:6002
static int mov_write_edts_tag(AVIOContext *pb, MOVMuxContext *mov, MOVTrack *track)
Definition movenc.c:4225
static int mov_write_enda_tag_be(AVIOContext *pb)
Definition movenc.c:719
static int mov_write_track_metadata(AVIOContext *pb, AVStream *st, const char *tag, const char *str)
Definition movenc.c:4390
static void param_write_hex(AVIOContext *pb, const char *name, const uint8_t *value, int len)
Definition movenc.c:5557
static int mov_write_ilst_tag(AVIOContext *pb, MOVMuxContext *mov, AVFormatContext *s)
Definition movenc.c:4934
static void mov_prune_frag_info(MOVMuxContext *mov, int tracks, int max)
Definition movenc.c:5934
static int mov_write_d263_tag(AVIOContext *pb)
Definition movenc.c:1635
static int mov_write_tmpo_tag(AVIOContext *pb, AVFormatContext *s)
Definition movenc.c:4784
static int mov_write_iloc_tag(AVIOContext *pb, MOVMuxContext *mov, AVFormatContext *s)
Definition movenc.c:3752
static int mov_write_int8_metadata(AVFormatContext *s, AVIOContext *pb, const char *name, const char *tag, int len)
Definition movenc.c:4880
static int mov_check_timecode_track(AVFormatContext *s, AVTimecode *tc, AVStream *src_st, const char *tcstr)
Definition movenc.c:7957
static int mov_write_ms_tag(AVFormatContext *s, AVIOContext *pb, MOVTrack *track)
Definition movenc.c:867
static uint16_t language_code(const char *str)
Definition movenc.c:5103
static int mov_write_custom_metadata(AVFormatContext *s, AVIOContext *pb, const char *mean, const char *name, const char *tag)
Definition movenc.c:4773
static int mov_write_tref_tag(AVIOContext *pb, MOVTrack *track)
Definition movenc.c:4333
static void param_write_string(AVIOContext *pb, const char *name, const char *value)
Definition movenc.c:5552
static int mov_write_esds_tag(AVIOContext *pb, MOVTrack *track)
Definition movenc.c:798
static int mov_write_avid_tag(AVIOContext *pb, MOVTrack *track)
Definition movenc.c:1816
static int mov_write_ispe_tag(AVIOContext *pb, MOVMuxContext *mov, AVFormatContext *s, int stream_index)
Definition movenc.c:3819
static int64_t update_size(AVIOContext *pb, int64_t pos)
Definition movenc.c:156
static int mov_write_ipma_tag(AVIOContext *pb, MOVMuxContext *mov, AVFormatContext *s)
Definition movenc.c:3864
static int64_t calc_elst_duration(MOVMuxContext *mov, MOVTrack *track)
Definition movenc.c:3996
static int mov_add_tref_id(MOVMuxContext *mov, MovTag *tag, uint32_t id)
Definition movenc.c:5388
static int mov_write_moov_tag(AVIOContext *pb, MOVMuxContext *mov, AVFormatContext *s)
Definition movenc.c:5431
static int64_t calc_pts_duration(MOVMuxContext *mov, MOVTrack *track)
Definition movenc.c:3987
static int mov_write_dvc1_tag(AVIOContext *pb, MOVTrack *track)
Definition movenc.c:1257
static int mov_write_tfrf_tags(AVIOContext *pb, MOVMuxContext *mov, MOVTrack *track)
Definition movenc.c:5881
static int mov_write_chpl_tag(AVIOContext *pb, AVFormatContext *s)
Definition movenc.c:5132
static int mov_write_audio_tag(AVFormatContext *s, AVIOContext *pb, MOVMuxContext *mov, MOVTrack *track)
Definition movenc.c:1450
static int mov_write_string_tag(AVIOContext *pb, const char *name, const char *value, int lang, int long_style)
Definition movenc.c:4694
static int mov_write_rtp_tag(AVIOContext *pb, MOVTrack *track)
Definition movenc.c:3143
static int mov_write_dref_tag(AVIOContext *pb)
Definition movenc.c:3368
static int mov_write_hdlr_tag(AVFormatContext *s, AVIOContext *pb, MOVTrack *track)
Definition movenc.c:3657
static int mov_write_iods_tag(AVIOContext *pb, MOVMuxContext *mov)
Definition movenc.c:4539
static int mov_write_3gp_udta_tag(AVIOContext *pb, AVFormatContext *s, const char *tag, const char *str)
Definition movenc.c:5110
static int mov_find_tref_id(MOVMuxContext *mov, const MovTag *tag, uint32_t id)
Definition movenc.c:5379
static int mov_write_subtitle_end_packet(AVFormatContext *s, int stream_index, int64_t dts)
Definition movenc.c:7618
static int mov_write_gmhd_tag(AVIOContext *pb, MOVTrack *track)
Definition movenc.c:3566
static int mov_write_dvcc_dvvc_tag(AVFormatContext *s, AVIOContext *pb, AVDOVIDecoderConfigurationRecord *dovi)
Definition movenc.c:2596
static int mov_write_pssh_tag(AVIOContext *pb, AVStream *st)
Definition movenc.c:5267
static int mov_init(AVFormatContext *s)
Definition movenc.c:8273
static void param_write_int(AVIOContext *pb, const char *name, int value)
Definition movenc.c:5547
static int mov_write_string_metadata(AVFormatContext *s, AVIOContext *pb, const char *name, const char *tag, int long_style)
Definition movenc.c:4762
static int mov_get_evc_codec_tag(AVFormatContext *s, MOVTrack *track)
Definition movenc.c:2105
static int mov_write_mdta_hdlr_tag(AVIOContext *pb, MOVMuxContext *mov, AVFormatContext *s)
Definition movenc.c:4975
static int mov_write_mvhd_tag(AVIOContext *pb, MOVMuxContext *mov)
Definition movenc.c:4592
static int mov_write_track_kind(AVIOContext *pb, const char *scheme_uri, const char *value)
Definition movenc.c:4404
static void mov_write_psp_udta_tag(AVIOContext *pb, const char *str, const char *lang, int type)
Definition movenc.c:5216
static unsigned int mov_find_codec_tag(AVFormatContext *s, MOVTrack *track)
Definition movenc.c:2268
static const uint16_t fiel_data[]
Definition movenc.c:2303
static int mov_write_apvc_tag(AVFormatContext *s, AVIOContext *pb, MOVTrack *track)
Definition movenc.c:1799
static int mov_write_lvcc_tag(AVFormatContext *s, AVIOContext *pb, MOVTrack *track)
Definition movenc.c:1767
static int mov_write_dops_tag(AVFormatContext *s, AVIOContext *pb, MOVTrack *track)
Definition movenc.c:910
static int mov_write_tcmi_tag(AVIOContext *pb, MOVTrack *track)
Definition movenc.c:3544
static int64_t rescale_rational(AVRational q, int b)
Definition movenc.c:2453
static int mov_write_mfhd_tag(AVIOContext *pb, MOVMuxContext *mov)
Definition movenc.c:5689
static int mov_write_tfhd_tag(AVIOContext *pb, MOVMuxContext *mov, MOVTrack *track, int64_t moof_offset)
Definition movenc.c:5704
static int mov_write_stts_tag(AVIOContext *pb, MOVTrack *track)
Definition movenc.c:3319
static int mov_write_mfra_tag(AVIOContext *pb, MOVMuxContext *mov)
Definition movenc.c:6234
static int mov_write_clli_tag(AVIOContext *pb, MOVTrack *track)
Definition movenc.c:2733
static int mov_write_mdat_tag(AVIOContext *pb, MOVMuxContext *mov)
Definition movenc.c:6272
static int mov_write_chnl_tag(AVFormatContext *s, AVIOContext *pb, MOVTrack *track)
Definition movenc.c:1370
static int mov_write_vmhd_tag(AVIOContext *pb, MOVTrack *track)
Definition movenc.c:3640
static int mov_write_pcmc_tag(AVFormatContext *s, AVIOContext *pb, MOVTrack *track)
Definition movenc.c:1412
static int mov_write_vpcc_tag(AVFormatContext *s, AVIOContext *pb, MOVTrack *track)
Definition movenc.c:1702
static int mov_write_video_tag(AVFormatContext *s, AVIOContext *pb, MOVMuxContext *mov, MOVTrack *track)
Definition movenc.c:2870
static int mov_write_gpmd_tag(AVIOContext *pb, const MOVTrack *track)
Definition movenc.c:3231
static int check_pkt(AVFormatContext *s, MOVTrack *trk, AVPacket *pkt)
Definition movenc.c:6991
static int mov_write_uuidprof_tag(AVIOContext *pb, AVFormatContext *s)
Definition movenc.c:6446
static int mov_write_pitm_tag(AVIOContext *pb, int item_id)
Definition movenc.c:3742
static int mov_write_identification(AVIOContext *pb, AVFormatContext *s)
Definition movenc.c:6517
static int mov_write_ctts_tag(AVFormatContext *s, AVIOContext *pb, MOVTrack *track)
Definition movenc.c:3278
static int mov_write_trkn_tag(AVIOContext *pb, MOVMuxContext *mov, AVFormatContext *s, int disc)
Definition movenc.c:4853
static int mov_write_wave_tag(AVFormatContext *s, AVIOContext *pb, MOVTrack *track)
Definition movenc.c:1130
static int mov_write_udta_sdp(AVIOContext *pb, MOVTrack *track)
Definition movenc.c:4368
static int mov_write_mdia_tag(AVFormatContext *s, AVIOContext *pb, MOVMuxContext *mov, MOVTrack *track)
Definition movenc.c:4049
static const AVCodecTag codec_f4v_tags[]
Definition movenc.c:9492
static int is_clcp_track(MOVTrack *track)
Definition movenc.c:3651
static int mov_write_trak_tag(AVFormatContext *s, AVIOContext *pb, MOVMuxContext *mov, MOVTrack *track, AVStream *st)
Definition movenc.c:4483
static int compute_sidx_size(AVFormatContext *s)
Definition movenc.c:9121
static int mov_write_itunes_hdlr_tag(AVIOContext *pb, MOVMuxContext *mov, AVFormatContext *s)
Definition movenc.c:4657
static int mov_write_dvc1_structs(MOVTrack *track, uint8_t *buf)
Definition movenc.c:1173
static int mov_write_track_kinds(AVIOContext *pb, AVStream *st)
Definition movenc.c:4430
static int handle_eac3(MOVMuxContext *mov, AVPacket *pkt, MOVTrack *track)
Definition movenc.c:466
static int mov_write_ftyp_tag(AVIOContext *pb, AVFormatContext *s)
Definition movenc.c:6324
static int get_sidx_size(AVFormatContext *s)
Definition movenc.c:9078
static int mov_write_stsc_tag(AVIOContext *pb, MOVTrack *track)
Definition movenc.c:262
static int get_samples_per_packet(MOVTrack *track)
Definition movenc.c:1332
static int mov_write_udta_tag(AVIOContext *pb, MOVMuxContext *mov, AVFormatContext *s)
Definition movenc.c:5158
static int mov_pcm_be_gt16(enum AVCodecID codec_id)
Definition movenc.c:859
static int mov_write_trailer(AVFormatContext *s)
Definition movenc.c:9173
static int mov_write_btrt_tag(AVIOContext *pb, MOVTrack *track)
Definition movenc.c:1351
static int rtp_hinting_needed(const AVStream *st)
Definition movenc.c:192
static int mov_write_nmhd_tag(AVIOContext *pb)
Definition movenc.c:3528
static int mov_get_lpcm_flags(enum AVCodecID codec_id)
Compute flags for 'lpcm' tag.
Definition movenc.c:1287
static int mov_write_pixi_tag(AVIOContext *pb, MOVMuxContext *mov, AVFormatContext *s, int stream_index)
Definition movenc.c:3831
static int mov_get_rawvideo_codec_tag(AVFormatContext *s, MOVTrack *track)
Definition movenc.c:2160
static int mov_write_squashed_packet(AVFormatContext *s, MOVTrack *track)
Definition movenc.c:6671
static int mov_write_ccst_tag(AVIOContext *pb)
Definition movenc.c:2841
static int mov_write_tapt_tag(AVIOContext *pb, MOVTrack *track)
Definition movenc.c:4190
static int defined_frame_rate(AVFormatContext *s, AVStream *st)
Definition movenc.c:1972
static void mov_free(AVFormatContext *s)
Definition movenc.c:8069
static int mov_write_uuid_tag_ipod(AVIOContext *pb)
Write uuid atom.
Definition movenc.c:2291
static void put_descr(AVIOContext *pb, int tag, unsigned int size)
Definition movenc.c:727
int ff_mov_write_packet(AVFormatContext *s, AVPacket *pkt)
Definition movenc.c:7068
static int mov_write_tfdt_tag(AVIOContext *pb, MOVTrack *track)
Definition movenc.c:5948
static int mov_setup_track_ids(MOVMuxContext *mov, AVFormatContext *s)
Assign track ids.
Definition movenc.c:5340
static const struct @225371303101201053203360341351022255162073206032 mov_pix_fmt_tags[]
static int mov_write_string_data_tag(AVIOContext *pb, const char *data, int lang, int long_style)
Definition movenc.c:4673
static void mov_parse_vc1_frame(AVPacket *pkt, MOVTrack *trk)
Definition movenc.c:6567
static int mov_write_tfxd_tag(AVIOContext *pb, MOVTrack *track)
Definition movenc.c:5826
static int mov_flush_fragment(AVFormatContext *s, int force)
Definition movenc.c:6765
static int mov_write_single_packet(AVFormatContext *s, AVPacket *pkt)
Definition movenc.c:7527
static int mov_write_squashed_packets(AVFormatContext *s)
Definition movenc.c:6709
static int mov_write_eyes_tag(AVFormatContext *s, AVIOContext *pb, const AVStereo3D *stereo3d)
Definition movenc.c:2496
static unsigned int validate_codec_tag(const AVCodecTag *const *tags, unsigned int tag, int codec_id)
Definition movenc.c:2248
static void build_chunks(MOVTrack *trk)
Definition movenc.c:5304
static void get_pts_range(MOVMuxContext *mov, MOVTrack *track, int64_t *start, int64_t *end, int elst, int mdhd)
Definition movenc.c:3950
static int mov_write_mvex_tag(AVIOContext *pb, MOVMuxContext *mov)
Definition movenc.c:4581
static void mov_write_vexu_proj_tag(AVFormatContext *s, AVIOContext *pb, const AVSphericalMapping *spherical_mapping)
Definition movenc.c:2469
static int mov_write_st3d_tag(AVFormatContext *s, AVIOContext *pb, AVStereo3D *stereo_3d)
Definition movenc.c:2365
static unsigned int mov_get_codec_tag(AVFormatContext *s, MOVTrack *track)
Definition movenc.c:2186
static int mov_write_av1c_tag(AVIOContext *pb, MOVTrack *track)
Definition movenc.c:1647
static int mov_check_bitstream(AVFormatContext *s, AVStream *st, const AVPacket *pkt)
Definition movenc.c:9316
static int mov_write_source_reference_tag(AVIOContext *pb, MOVTrack *track, const char *reel_name)
Definition movenc.c:3163
static int get_cluster_duration(MOVTrack *track, int cluster_idx)
Definition movenc.c:1312
static int mov_write_enda_tag(AVIOContext *pb)
Definition movenc.c:711
static int64_t calc_samples_pts_duration(MOVMuxContext *mov, MOVTrack *track)
Definition movenc.c:3975
static int mov_write_fiel_tag(AVIOContext *pb, MOVTrack *track, int field_order)
Definition movenc.c:2307
static int mov_write_colr_tag(AVIOContext *pb, MOVTrack *track, int prefer_icc)
Definition movenc.c:2685
static int mov_write_mdta_ilst_tag(AVIOContext *pb, MOVMuxContext *mov, AVFormatContext *s)
Definition movenc.c:5019
static void mov_write_hfov_tag(AVFormatContext *s, AVIOContext *pb, const AVStereo3D *stereo3d)
Definition movenc.c:2458
static int mov_write_track_udta_tag(AVIOContext *pb, MOVMuxContext *mov, AVStream *st)
Definition movenc.c:4450
static int mov_parse_mpeg2_frame(AVPacket *pkt, uint32_t *flags)
Definition movenc.c:6546
static int mov_write_freeform_tag(AVIOContext *pb, const char *mean, const char *name, const char *data)
Definition movenc.c:4708
static int mov_write_SA3D_tag(AVFormatContext *s, AVIOContext *pb, MOVTrack *track)
Definition movenc.c:1011
static int mov_write_packet(AVFormatContext *s, AVPacket *pkt)
Definition movenc.c:7715
static int mov_write_meta_tag(AVIOContext *pb, MOVMuxContext *mov, AVFormatContext *s)
Definition movenc.c:5041
static int mov_write_mdcv_tag(AVIOContext *pb, MOVTrack *track)
Definition movenc.c:2753
static const AVCodecTag codec_mp4_tags[]
Definition movenc.c:9408
static int mov_get_apv_codec_tag(AVFormatContext *s, MOVTrack *track)
Definition movenc.c:2115
static int mov_write_subtitle_tag(AVFormatContext *s, AVIOContext *pb, MOVTrack *track)
Definition movenc.c:2320
static int mov_write_uuidusmt_tag(AVIOContext *pb, AVFormatContext *s)
Definition movenc.c:5229
static int mov_write_isml_manifest(AVIOContext *pb, MOVMuxContext *mov, AVFormatContext *s)
Definition movenc.c:5565
static int mov_get_dv_codec_tag(AVFormatContext *s, MOVTrack *track)
Definition movenc.c:1947
static int is_cover_image(const AVStream *st)
Definition movenc.c:185
static int mov_write_trun_tag(AVIOContext *pb, MOVMuxContext *mov, MOVTrack *track, int moof_size, int first, int end)
Definition movenc.c:5770
static int mov_write_hvce_tag(AVIOContext *pb, const AVPacketSideData *sd)
Definition movenc.c:2614
static int mov_write_stss_tag(AVIOContext *pb, MOVTrack *track, uint32_t flag)
Definition movenc.c:293
static int mov_write_hmhd_tag(AVIOContext *pb)
Definition movenc.c:3898
#define FF_MOV_FLAG_NEGATIVE_CTS_OFFSETS
Definition movenc.h:297
#define FF_MOV_FLAG_GLOBAL_SIDX
Definition movenc.h:292
int ff_mov_add_hinted_packet(AVFormatContext *s, AVPacket *pkt, int track_index, int sample, uint8_t *sample_data, int sample_size)
Definition movenchint.c:405
#define FF_MOV_FLAG_FRAG_EVERY_FRAME
Definition movenc.h:298
#define FF_MOV_FLAG_DASH
Definition movenc.h:289
#define FF_MOV_FLAG_DEFAULT_BASE_MOOF
Definition movenc.h:288
#define FF_MOV_FLAG_WRITE_GAMA
Definition movenc.h:294
#define FF_MOV_FLAG_WRITE_COLR
Definition movenc.h:293
#define MOV_TRACK_CTTS
Definition movenc.h:114
#define FF_MOV_FLAG_DISABLE_CHPL
Definition movenc.h:287
#define MODE_3GP
Definition movenc.h:40
#define MODE_3G2
Definition movenc.h:43
#define FF_MOV_FLAG_FRAG_DISCONT
Definition movenc.h:290
#define MOV_TIMESCALE_Q
Definition movenc.h:34
#define MOV_FRAG_INFO_ALLOC_INCREMENT
Definition movenc.h:31
int ff_mov_init_hinting(AVFormatContext *s, int index, int src_index)
Definition movenchint.c:30
#define MOV_DISPOSABLE_SAMPLE
Definition movenc.h:61
#define FF_MOV_FLAG_FASTSTART
Definition movenc.h:285
#define MOV_TRACK_STPS
Definition movenc.h:115
#define FF_MOV_FLAG_EMPTY_MOOV
Definition movenc.h:280
#define MODE_ISM
Definition movenc.h:45
#define FF_MOV_FLAG_SKIP_TRAILER
Definition movenc.h:296
#define MODE_MP4
Definition movenc.h:38
#define FF_MOV_FLAG_RTP_HINT
Definition movenc.h:278
#define FF_MOV_FLAG_PREFER_ICC
Definition movenc.h:301
@ MOV_ENC_CENC_AES_CTR
Definition movenc.h:201
@ MOV_ENC_NONE
Definition movenc.h:200
#define MODE_MOV
Definition movenc.h:39
void ff_mov_close_hinting(MOVTrack *track)
Definition movenchint.c:464
#define FF_MOV_FLAG_FRAG_KEYFRAME
Definition movenc.h:281
#define FF_MOV_FLAG_ISML
Definition movenc.h:284
#define MOV_TIMESCALE
Definition movenc.h:33
#define FF_MOV_FLAG_FRAG_CUSTOM
Definition movenc.h:283
#define FF_MOV_FLAG_USE_MDTA
Definition movenc.h:295
#define FF_MOV_FLAG_SKIP_SIDX
Definition movenc.h:299
#define FF_MOV_FLAG_DELAY_MOOV
Definition movenc.h:291
#define MODE_IPOD
Definition movenc.h:44
#define FF_MOV_FLAG_OMIT_TFHD_OFFSET
Definition movenc.h:286
#define FF_MOV_FLAG_FRAGMENT
Definition movenc.h:279
#define MODE_F4V
Definition movenc.h:46
#define FF_MOV_FLAG_HYBRID_FRAGMENTED
Definition movenc.h:302
@ MOV_PRFT_SRC_WALLCLOCK
Definition movenc.h:206
@ MOV_PRFT_NONE
Definition movenc.h:205
@ MOV_PRFT_SRC_PTS
Definition movenc.h:207
@ MOV_PRFT_NB
Definition movenc.h:208
#define FF_MOV_FLAG_SEPARATE_MOOF
Definition movenc.h:282
#define MOV_PARTIAL_SYNC_SAMPLE
Definition movenc.h:60
#define MOV_INDEX_CLUSTER_SIZE
Definition movenc.h:32
#define FF_MOV_FLAG_CMAF
Definition movenc.h:300
#define MODE_PSP
Definition movenc.h:41
#define MOV_TIMECODE_FLAG_DROPFRAME
Definition movenc.h:118
#define MOV_SYNC_SAMPLE
Definition movenc.h:59
#define MOV_TRACK_ENABLED
Definition movenc.h:116
#define MODE_AVIF
Definition movenc.h:47
int ff_mov_generate_squashed_ttml_packet(AVFormatContext *s, MOVTrack *track, AVPacket *pkt)
void ff_mov_cenc_flush(MOVMuxCencContext *ctx)
Clear subsample data.
Definition movenccenc.c:633
int ff_mov_cenc_av1_write_obus(AVFormatContext *s, MOVMuxCencContext *ctx, AVIOContext *pb, const AVPacket *pkt)
Definition movenccenc.c:387
int ff_mov_cenc_avc_parse_nal_units(MOVMuxCencContext *ctx, AVIOContext *pb, const uint8_t *buf_in, int size)
Parse AVC NAL units from annex B format, the nal size and type are written in the clear while the bod...
Definition movenccenc.c:198
int ff_mov_cenc_init(MOVMuxCencContext *ctx, uint8_t *encryption_key, int use_subsamples, enum AVCodecID codec_id, int bitexact)
Initialize a CENC context.
Definition movenccenc.c:600
void ff_mov_cenc_write_stbl_atoms(MOVMuxCencContext *ctx, AVIOContext *pb, int64_t moof_offset)
Write the cenc atoms that should reside inside stbl.
Definition movenccenc.c:542
int ff_mov_cenc_write_sinf_tag(MOVTrack *track, AVIOContext *pb, uint8_t *kid)
Write the sinf atom, contained inside stsd.
Definition movenccenc.c:568
void ff_mov_cenc_free(MOVMuxCencContext *ctx)
Free a CENC context.
Definition movenccenc.c:639
int ff_mov_cenc_avc_write_nal_units(AVFormatContext *s, MOVMuxCencContext *ctx, int nal_length_size, AVIOContext *pb, const uint8_t *buf_in, int size)
Write AVC NAL units that are in MP4 format, the nal size and type are written in the clear while the ...
Definition movenccenc.c:238
int ff_mov_cenc_write_packet(MOVMuxCencContext *ctx, AVIOContext *pb, const uint8_t *buf_in, int size)
Write a fully encrypted packet.
Definition movenccenc.c:173
#define CENC_KID_SIZE
Definition movenccenc.h:30
mpeg audio layer common tables.
const uint64_t ff_mpa_cicp_channel_layout_masks[20]
#define FF_OFMT_FLAG_ALLOW_FLUSH
This flag indicates that the muxer stores data internally and supports flushing it.
Definition mux.h:38
int ff_format_shift_data(AVFormatContext *s, int64_t read_start, int shift_size)
Make shift_size amount of space at read_start by shifting data in the output at read_start until the ...
Definition mux_utils.c:71
int ff_parse_creation_time_metadata(AVFormatContext *s, int64_t *timestamp, int return_seconds)
Parse creation_time in AVFormatContext metadata if exists and warn if the parsing fails.
Definition mux_utils.c:137
const char data[16]
Definition mxf.c:149
uint8_t interlaced
Definition mxfenc.c:2336
int profile
Definition mxfenc.c:2299
uint16_t cid
Definition mxfenc.c:2335
int ff_nal_parse_units(AVIOContext *pb, const uint8_t *buf_in, int size)
Definition nal.c:113
int ff_nal_parse_units_buf(const uint8_t *buf_in, uint8_t **buf, int *size)
Definition nal.c:133
IDirect3DDxgiInterfaceAccess _COM_Outptr_ void ** p
static float distance(float x, float y, int band)
#define OPUS_SEEK_PREROLL_MS
#define av_realloc(p, s)
Definition ops_static.c:54
#define av_malloc(s)
Definition ops_static.c:52
AVOptions.
const char * av_get_pix_fmt_name(enum AVPixelFormat pix_fmt)
Return the short name for a pixel format, NULL in case pix_fmt is unknown.
Definition pixdesc.c:3404
const AVPixFmtDescriptor * av_pix_fmt_desc_get(enum AVPixelFormat pix_fmt)
Definition pixdesc.c:3484
#define AV_PIX_FMT_YUV420P10
Definition pixfmt.h:548
@ AVCOL_RANGE_MPEG
Narrow or limited range content.
Definition pixfmt.h:771
@ AVCOL_RANGE_UNSPECIFIED
Definition pixfmt.h:754
@ AVCOL_RANGE_JPEG
Full range content.
Definition pixfmt.h:788
@ AVALPHA_MODE_STRAIGHT
Alpha channel is independent of color values.
Definition pixfmt.h:824
@ AVALPHA_MODE_PREMULTIPLIED
Alpha channel is multiplied into color values.
Definition pixfmt.h:823
#define AV_PIX_FMT_YUV422P10
Definition pixfmt.h:549
AVPixelFormat
Pixel format.
Definition pixfmt.h:71
@ AV_PIX_FMT_UYVA
packed UYVA 4:4:4:4, 32bpp (1 Cr & Cb sample per 1x1 Y & A samples), UYVAUYVA...
Definition pixfmt.h:444
@ AV_PIX_FMT_GRAY16BE
Y , 16bpp, big-endian.
Definition pixfmt.h:104
@ AV_PIX_FMT_V30XLE
packed VYUX 4:4:4 like XV30, 32bpp, (msb)10V 10Y 10U 2X(lsb), little-endian
Definition pixfmt.h:449
@ AV_PIX_FMT_NONE
Definition pixfmt.h:72
@ AV_PIX_FMT_RGB24
packed RGB 8:8:8, 24bpp, RGBRGB...
Definition pixfmt.h:75
@ AV_PIX_FMT_YUV420P
planar YUV 4:2:0, 12bpp, (1 Cr & Cb sample per 2x2 Y samples)
Definition pixfmt.h:73
@ AV_PIX_FMT_MONOBLACK
Y , 1bpp, 0 is black, 1 is white, in each byte pixels are ordered from the msb to the lsb.
Definition pixfmt.h:83
@ AV_PIX_FMT_YUV422P
planar YUV 4:2:2, 16bpp, (1 Cr & Cb sample per 2x1 Y samples)
Definition pixfmt.h:77
@ AV_PIX_FMT_ARGB
packed ARGB 8:8:8:8, 32bpp, ARGBARGB...
Definition pixfmt.h:99
@ AV_PIX_FMT_RGB555BE
packed RGB 5:5:5, 16bpp, (msb)1X 5R 5G 5B(lsb), big-endian , X=unused/undefined
Definition pixfmt.h:114
@ AV_PIX_FMT_BGRA
packed BGRA 8:8:8:8, 32bpp, BGRABGRA...
Definition pixfmt.h:102
@ AV_PIX_FMT_GRAY8
Y , 8bpp.
Definition pixfmt.h:81
@ AV_PIX_FMT_UYVY422
packed YUV 4:2:2, 16bpp, Cb Y0 Cr Y1
Definition pixfmt.h:88
@ AV_PIX_FMT_RGB48BE
packed RGB 16:16:16, 48bpp, 16R, 16G, 16B, the 2-byte value for each R/G/B component is stored as big...
Definition pixfmt.h:109
@ AV_PIX_FMT_ABGR
packed ABGR 8:8:8:8, 32bpp, ABGRABGR...
Definition pixfmt.h:101
@ AV_PIX_FMT_RGBA
packed RGBA 8:8:8:8, 32bpp, RGBARGBA...
Definition pixfmt.h:100
@ AV_PIX_FMT_RGB565LE
packed RGB 5:6:5, 16bpp, (msb) 5R 6G 5B(lsb), little-endian
Definition pixfmt.h:113
@ AV_PIX_FMT_RGB555LE
packed RGB 5:5:5, 16bpp, (msb)1X 5R 5G 5B(lsb), little-endian, X=unused/undefined
Definition pixfmt.h:115
@ AV_PIX_FMT_RGB565BE
packed RGB 5:6:5, 16bpp, (msb) 5R 6G 5B(lsb), big-endian
Definition pixfmt.h:112
@ AV_PIX_FMT_YUYV422
packed YUV 4:2:2, 16bpp, Y0 Cb Y1 Cr
Definition pixfmt.h:74
@ AV_PIX_FMT_PAL8
8 bits with AV_PIX_FMT_RGB32 palette
Definition pixfmt.h:84
@ AV_PIX_FMT_BGR24
packed RGB 8:8:8, 24bpp, BGRBGR...
Definition pixfmt.h:76
@ AV_PIX_FMT_VYU444
packed VYU 4:4:4, 24bpp (1 Cr & Cb sample per 1x1 Y), VYUVYU...
Definition pixfmt.h:446
@ AV_PIX_FMT_MONOWHITE
Y , 1bpp, 0 is white, 1 is black, in each byte pixels are ordered from the msb to the lsb.
Definition pixfmt.h:82
@ AVCOL_PRI_UNSPECIFIED
Definition pixfmt.h:650
@ AVCOL_TRC_UNSPECIFIED
Definition pixfmt.h:680
@ AVCOL_SPC_UNSPECIFIED
Definition pixfmt.h:714
bitstream writer API
static void init_put_bits(PutBitContext *s, uint8_t *buffer, int buffer_size)
Initialize the PutBitContext s.
Definition put_bits.h:62
static void flush_put_bits(PutBitContext *s)
Pad the end of the output stream with zeros.
Definition put_bits.h:153
static int put_bytes_output(const PutBitContext *s)
Definition put_bits.h:99
static av_unused void put_bits32(PutBitContext *s, uint32_t value)
Write exactly 32 bits into a bitstream.
Definition put_bits.h:301
const char * name
Definition qsvenc.c:142
enum AVPixelFormat avpriv_pix_fmt_find(enum PixelFormatTagLists list, unsigned fourcc)
Definition raw.c:78
Raw Video Codec.
@ PIX_FMT_LIST_MOV
Definition raw.h:40
int ff_get_packet_palette(AVFormatContext *s, AVPacket *pkt, int ret, uint32_t *palette)
Retrieves the palette from a packet, either from side data, or appended to the video data in the pack...
Definition rawutils.c:77
int ff_reshuffle_raw_rgb(AVFormatContext *s, AVPacket **ppkt, AVCodecParameters *par, int expected_stride)
Reshuffles the lines to use the user specified stride.
Definition rawutils.c:27
const AVCodecTag ff_codec_bmp_tags[]
Definition riff.c:36
const AVCodecTag ff_codec_wav_tags[]
Definition riff.c:525
internal header for RIFF based (de)muxers do NOT include this in end user applications
#define FF_PUT_WAV_HEADER_FORCE_WAVEFORMATEX
Tell ff_put_wav_header() to use WAVEFORMATEX even for PCM codecs.
Definition riff.h:53
int ff_put_wav_header(AVFormatContext *s, AVIOContext *pb, AVCodecParameters *par, int flags)
Write WAVEFORMAT header structure.
Definition riffenc.c:54
#define av_bswap16
Definition bswap.h:28
#define FF_RTP_FLAG_OPTS(ctx, fieldname)
Definition rtpenc.h:75
#define FF_ARRAY_ELEMS(a)
unsigned int pos
Definition spdifenc.c:431
double strtod(const char *, char **)
Coded AC-3 header values up to the lfeon element, plus derived values.
uint8_t complexity_index_type_a
int substreamid
substream identification
int num_blocks
number of audio blocks
Ambient viewing environment metadata as defined by H.274.
AVRational ambient_illuminance
Environmental illuminance of the ambient viewing environment in lux.
AVRational ambient_light_x
Normalized x chromaticity coordinate of the environmental ambient light in the nominal viewing enviro...
AVRational ambient_light_y
Normalized y chromaticity coordinate of the environmental ambient light in the nominal viewing enviro...
This structure describes the bitrate properties of an encoded bitstream.
Definition defs.h:296
int64_t avg_bitrate
Average bitrate of the stream, in bits per second.
Definition defs.h:311
int64_t max_bitrate
Maximum bitrate of the stream, in bits per second.
Definition defs.h:301
int64_t buffer_size
The size of the buffer to which the ratecontrol is applied, in bits.
Definition defs.h:317
An AVChannelLayout holds information about the channel layout of audio data.
int nb_channels
Number of channels in this layout.
Describe the class of an AVClass context structure.
Definition log.h:76
This struct describes the properties of an encoded stream.
Definition codec_par.h:49
enum AVColorSpace color_space
Definition codec_par.h:192
int extradata_size
Size of the extradata content in bytes.
Definition codec_par.h:75
int frame_size
Audio frame size, if known.
Definition codec_par.h:227
enum AVFieldOrder field_order
The order of the fields in interlaced video.
Definition codec_par.h:182
int height
The height of the video frame in pixels.
Definition codec_par.h:150
int nb_coded_side_data
Amount of entries in coded_side_data.
Definition codec_par.h:88
int bits_per_coded_sample
The number of bits per sample in the codedwords.
Definition codec_par.h:113
AVChannelLayout ch_layout
The channel layout and number of channels.
Definition codec_par.h:207
int width
The width of the video frame in pixels.
Definition codec_par.h:143
int64_t bit_rate
The average bitrate of the encoded data (in bits per second).
Definition codec_par.h:99
enum AVMediaType codec_type
General type of the encoded data.
Definition codec_par.h:53
int profile
Codec-specific bitstream restrictions that the stream conforms to.
Definition codec_par.h:135
int block_align
The number of bytes per coded audio frame, required by some formats.
Definition codec_par.h:221
int bits_per_raw_sample
The number of valid bits in each output sample.
Definition codec_par.h:130
AVRational sample_aspect_ratio
The aspect ratio (width/height) which a single pixel should have when displayed.
Definition codec_par.h:161
uint32_t codec_tag
Additional information about the codec (corresponds to the AVI FOURCC).
Definition codec_par.h:61
uint8_t * extradata
Extra binary data needed for initializing the decoder, codec-dependent.
Definition codec_par.h:71
enum AVCodecID codec_id
Specific type of the encoded data (the codec used).
Definition codec_par.h:57
enum AVColorPrimaries color_primaries
Definition codec_par.h:190
int sample_rate
The number of audio samples per second.
Definition codec_par.h:213
enum AVColorTransferCharacteristic color_trc
Definition codec_par.h:191
enum AVAlphaMode alpha_mode
Video with alpha channel only.
Definition codec_par.h:261
AVPacketSideData * coded_side_data
Additional data associated with the entire stream.
Definition codec_par.h:83
enum AVColorRange color_range
Additional colorspace characteristics.
Definition codec_par.h:189
enum AVCodecID id
Definition internal.h:43
unsigned int tag
Definition internal.h:44
int depth
Number of bits in the component.
Definition pixdesc.h:57
Content light level needed by to transmit HDR over HDMI (CTA-861.3).
unsigned MaxFALL
Max average light level per frame (cd/m^2).
unsigned MaxCLL
Max content light level (cd/m^2).
char * key
Definition dict.h:91
char * value
Definition dict.h:92
This describes info used to initialize an encryption key system.
Format I/O context.
Definition avformat.h:1400
int flags
Flags modifying the (de)muxer behaviour.
Definition avformat.h:1552
int strict_std_compliance
Allow non-standard and experimental extension.
Definition avformat.h:1775
Bytestream IO Context.
Definition avio.h:160
Mastering display metadata capable of representing the color volume of the display used to master the...
AVOption.
Definition opt.h:428
This structure stores auxiliary information for decoding, presenting, or otherwise processing the cod...
Definition packet.h:431
uint8_t * data
Definition packet.h:432
This structure stores compressed data.
Definition packet.h:587
int stream_index
Definition packet.h:612
int size
Definition packet.h:611
int64_t duration
Duration of this packet in AVStream->time_base units, 0 if unknown.
Definition packet.h:628
int64_t pts
Presentation timestamp in AVStream->time_base units; the time at which the decompressed packet will b...
Definition packet.h:603
int64_t dts
Decompression timestamp in AVStream->time_base units; the time at which the packet is decompressed.
Definition packet.h:609
uint8_t * data
Definition packet.h:610
Descriptor that unambiguously describes how the bits of a pixel are stored in the up to 4 data planes...
Definition pixdesc.h:69
AVComponentDescriptor comp[4]
Parameters that describe how pixels are packed.
Definition pixdesc.h:105
uint8_t log2_chroma_w
Amount to shift the luma width right to find the chroma width.
Definition pixdesc.h:80
uint8_t log2_chroma_h
Amount to shift the luma height right to find the chroma height.
Definition pixdesc.h:89
uint8_t nb_components
The number of components each pixel has, (1-4)
Definition pixdesc.h:71
This structure supplies correlation between a packet timestamp and a wall clock production time.
Definition defs.h:345
int64_t wallclock
A UTC timestamp, in microseconds, since Unix epoch (e.g, av_gettime()).
Definition defs.h:349
Rational number (pair of numerator and denominator).
Definition rational.h:58
int num
Numerator.
Definition rational.h:59
int den
Denominator.
Definition rational.h:60
This structure describes how to handle spherical videos, outlining information about projection,...
Definition spherical.h:100
uint32_t bound_left
Distance from the left edge.
Definition spherical.h:185
enum AVSphericalProjection projection
Projection type.
Definition spherical.h:104
uint32_t bound_top
Distance from the top edge.
Definition spherical.h:186
uint32_t bound_bottom
Distance from the bottom edge.
Definition spherical.h:188
uint32_t bound_right
Distance from the right edge.
Definition spherical.h:187
int32_t pitch
Rotation around the right vector [-90, 90].
Definition spherical.h:145
int32_t roll
Rotation around the forward vector [-180, 180].
Definition spherical.h:146
int32_t yaw
Rotation around the up vector [-180, 180].
Definition spherical.h:144
uint32_t padding
Number of pixels to pad from the edge of each cube face.
Definition spherical.h:200
Stereo 3D type: this structure describes how two videos are packed within a single video surface,...
Definition stereo3d.h:203
enum AVStereo3DType type
How views are packed within the video.
Definition stereo3d.h:207
uint32_t baseline
The distance between the centres of the lenses of the camera system, in micrometers.
Definition stereo3d.h:228
AVRational horizontal_disparity_adjustment
Relative shift of the left and right images, which changes the zero parallax plane.
Definition stereo3d.h:234
enum AVStereo3DPrimaryEye primary_eye
Which eye is the primary eye when rendering in 2D.
Definition stereo3d.h:222
int flags
Additional information about the frame packing.
Definition stereo3d.h:212
AVRational horizontal_field_of_view
Horizontal field of view, in degrees.
Definition stereo3d.h:239
enum AVStereo3DView view
Determines which views are packed.
Definition stereo3d.h:217
enum AVStreamGroupEntryType type
Definition avformat.h:1177
AVStream * stream
Definition avformat.h:1179
AVStreamGroupLayeredVideo is meant to define the relation between a base layer video stream and a sep...
Definition avformat.h:1104
int height
Height of the final image for presentation.
Definition avformat.h:1129
unsigned int el_index
Index of the enhancement layer stream in AVStreamGroup.
Definition avformat.h:1113
int width
Width of the final stream for presentation.
Definition avformat.h:1125
AVStreamGroupTREF is meant to define the relation between video, audio, or subtitle streams,...
Definition avformat.h:1148
unsigned int metadata_index
Index of the metadata stream in the AVStreamGroup.
Definition avformat.h:1154
unsigned int nb_entries
Number of elements in AVStreamGroup.entries.
Definition avformat.h:1285
enum AVStreamGroupParamsType type
Group type.
Definition avformat.h:1211
AVStreamGroupEntry ** entries
A list of streams or child groups in the group.
Definition avformat.h:1298
struct AVStreamGroupTREF * tref
Definition avformat.h:1228
union AVStreamGroup::@313244315204024013007202273061153315146016101155 params
Group type-specific parameters.
int64_t id
Group type-specific group ID.
Definition avformat.h:1203
struct AVStreamGroupLayeredVideo * layered_video
Definition avformat.h:1220
Stream structure.
Definition avformat.h:768
AVCodecParameters * codecpar
Codec parameters associated with this stream.
Definition avformat.h:791
AVRational sample_aspect_ratio
sample aspect ratio (0 if unknown)
Definition avformat.h:846
int64_t nb_frames
number of frames in this stream if known or 0
Definition avformat.h:829
AVDictionary * metadata
Definition avformat.h:848
void * priv_data
Definition avformat.h:793
int id
Format-specific stream ID.
Definition avformat.h:780
int index
stream index in AVFormatContext
Definition avformat.h:774
AVRational avg_frame_rate
Average framerate.
Definition avformat.h:857
AVRational time_base
This is the fundamental unit of time (in seconds) in terms of which frame timestamps are represented.
Definition avformat.h:807
int disposition
Stream disposition - a combination of AV_DISPOSITION_* flags.
Definition avformat.h:837
unsigned fps
frame per second; must be consistent with the rate field
Definition timecode.h:45
uint32_t flags
flags such as drop frame, +24 hours support, ...
Definition timecode.h:43
AVRational rate
frame rate in rational form
Definition timecode.h:44
int start
timecode frame start (first base frame number)
Definition timecode.h:42
AVPacket * pkt
Used to hold temporary packets for the generic demuxing code.
Definition internal.h:111
Definition isom.h:69
unsigned int count
Definition isom.h:70
int offset
Definition isom.h:71
int64_t offset
Definition movenc.h:81
int64_t tfrf_offset
Definition movenc.h:84
int64_t time
Definition movenc.h:82
int64_t duration
Definition movenc.h:83
uint32_t flags
Definition movenc.h:62
unsigned int chunkNum
Chunk number if the current entry is a chunk start otherwise 0.
Definition movenc.h:56
int64_t pts
Definition movenc.h:52
int cts
Definition movenc.h:58
unsigned int samples_in_chunk
Definition movenc.h:55
unsigned int stsd_index
Definition movenc.h:54
unsigned int entries
Definition movenc.h:57
AVProducerReferenceTime prft
Definition movenc.h:63
int64_t dts
Definition movenc.h:51
uint64_t pos
Definition movenc.h:50
unsigned int size
Definition movenc.h:53
struct AVAESCTR * aes_ctr
Definition movenccenc.h:41
int reserved_moov_size
0 for disabled, -1 for automatic, size otherwise
Definition movenc.h:241
char * major_brand
Definition movenc.h:244
int64_t mdat_pos
Definition movenc.h:219
AVFormatContext * fc
Definition movenc.h:247
AVPacket * pkt
Definition movenc.h:249
int nb_tracks
Definition movenc.h:216
int iods_skip
Definition movenc.h:226
int chapter_track
qt chapter track number
Definition movenc.h:218
uint64_t mdat_size
Definition movenc.h:220
char * encryption_scheme_str
Definition movenc.h:257
int movie_timescale
Definition movenc.h:270
float gamma
Definition movenc.h:252
int avif_loop_count
Definition movenc.h:275
uint8_t * encryption_key
Definition movenc.h:259
int nb_streams
Definition movenc.h:215
int fragments
Definition movenc.h:231
int encryption_key_len
Definition movenc.h:260
int write_btrt
Definition movenc.h:266
int avif_extent_length[2]
Definition movenc.h:273
int empty_hdlr_name
Definition movenc.h:269
int missing_duration_warned
Definition movenc.h:255
AVIOContext * mdat_buf
Definition movenc.h:236
uint8_t * encryption_kid
Definition movenc.h:261
int min_fragment_duration
Definition movenc.h:233
MOVPrftBox write_prft
Definition movenc.h:268
int64_t reserved_header_pos
Definition movenc.h:242
int per_stream_grouping
Definition movenc.h:246
int iods_video_profile
Definition movenc.h:227
MOVTrack * tracks
Definition movenc.h:221
int frag_interleave
Definition movenc.h:254
int max_fragment_duration
Definition movenc.h:232
int track_ids_ok
Definition movenc.h:265
int video_track_timescale
Definition movenc.h:239
int max_fragment_size
Definition movenc.h:234
int use_editlist
Definition movenc.h:251
int nb_meta_tmcd
number of new created tmcd track based on metadata (aka not data copy)
Definition movenc.h:217
int moov_written
Definition movenc.h:230
int use_stream_ids_as_track_ids
Definition movenc.h:264
MOVEncryptionScheme encryption_scheme
Definition movenc.h:258
int first_trun
Definition movenc.h:237
int64_t avif_extent_pos[2]
Definition movenc.h:272
int iods_audio_profile
Definition movenc.h:228
int is_animated_avif
Definition movenc.h:274
int write_tmcd
Definition movenc.h:267
int64_t time
Definition movenc.h:214
int encryption_kid_len
Definition movenc.h:262
int ism_lookahead
Definition movenc.h:235
Definition isom.h:64
unsigned int count
Definition isom.h:65
unsigned int duration
Definition isom.h:66
int track_id
Definition movenc.h:123
int mono_as_fc
Definition movenc.h:127
int entry
Definition movenc.h:97
int64_t start_cts
Definition movenc.h:138
AVPacket * cover_image
Definition movenc.h:157
int * src_track
the tracks that this hint (or tmcd) track describes
Definition movenc.h:146
uint32_t default_size
Definition movenc.h:154
struct MOVTrack::@041066134315003153207320140045232207171303033040 vc1_info
int nb_src_track
Definition movenc.h:145
int first_iamf_idx
Definition movenc.h:192
int first_packet_seen
Definition movenc.h:171
int64_t dts_shift
Definition movenc.h:142
int last_iamf_idx
Definition movenc.h:193
int audio_vbr
Definition movenc.h:133
int tag
stsd fourcc
Definition movenc.h:124
uint32_t flags
Definition movenc.h:117
uint32_t timecode_flags
Definition movenc.h:121
int * extradata_size
Definition movenc.h:107
int64_t data_offset
Definition movenc.h:160
int nb_tref_tags
Definition movenc.h:135
int language
Definition movenc.h:122
PacketList squashed_packet_queue
Definition movenc.h:189
AVCodecParameters * par
Definition movenc.h:126
unsigned frag_info_capacity
Definition movenc.h:166
int nb_frag_info
Definition movenc.h:164
int multichannel_as_mono
Definition movenc.h:128
AVIOContext * mdat_buf
Definition movenc.h:159
uint64_t time
Definition movenc.h:99
AVIOContext * iamf_buf
Definition movenc.h:194
int entry_version
Definition movenc.h:96
int packet_entry
Definition movenc.h:174
int is_unaligned_qt_rgb
Definition movenc.h:185
long sample_count
Definition movenc.h:109
uint32_t palette[AVPALETTE_COUNT]
Definition movenc.h:182
int has_disposable
Definition movenc.h:113
struct IAMFContext * iamf
Definition movenc.h:191
void * eac3_priv
Definition movenc.h:178
int64_t elst_end_pts
Definition movenc.h:140
MOVIentry * cluster_written
Definition movenc.h:131
int64_t end_pts
Definition movenc.h:139
uint8_t ** extradata
Definition movenc.h:106
unsigned int squash_fragment_samples_to_one
Definition movenc.h:187
int last_sample_is_subtitle_end
Definition movenc.h:101
MOVFragmentInfo * frag_info
Definition movenc.h:165
int entries_flushed
Definition movenc.h:162
int frag_discont
Definition movenc.h:161
uint32_t default_sample_flags
Definition movenc.h:153
int pal_done
Definition movenc.h:183
MovTag * tref_tags
Definition movenc.h:136
MOVIentry * cluster
Definition movenc.h:130
uint32_t max_packet_size
Definition movenc.h:150
int hint_track
the track that hints this track, -1 if no hint track is set
Definition movenc.h:144
struct APVDecoderConfigurationRecord * apv
Definition movenc.h:196
int64_t default_duration
Definition movenc.h:152
AVStream * st
Definition movenc.h:125
MOVMuxCencContext cenc
Definition movenc.h:180
int has_keyframes
Definition movenc.h:112
long sample_size
Definition movenc.h:110
int first_packet_entry
Definition movenc.h:170
int slices
Definition movenc.h:175
int entry_written
Definition movenc.h:97
int stsd_count
Definition movenc.h:104
int64_t start_dts
Definition movenc.h:137
int first_frag_written
Definition movenc.h:172
int mode
Definition movenc.h:95
unsigned timescale
Definition movenc.h:98
int packet_seq
Definition movenc.h:173
int first_packet_seq
Definition movenc.h:169
int64_t track_duration
Definition movenc.h:100
long chunkCount
Definition movenc.h:111
AVFormatContext * rtp_ctx
the format context for the hinting rtp muxer
Definition movenc.h:147
unsigned cluster_capacity
Definition movenc.h:132
int last_stsd_index
Definition movenc.h:105
int height
active picture (w/o VBI) height for D-10/IMX
Definition movenc.h:134
int end_reliable
Definition movenc.h:141
const char * value
Definition isom.h:509
uint32_t * id
trackID of the referenced track
Definition movenc.h:91
PacketListEntry * head
uint8_t num_ind_sub
Definition movenc.c:395
uint8_t fscod
Definition movenc.c:398
uint16_t data_rate
Definition movenc.c:392
int8_t ac3_bit_rate_code
Definition movenc.c:393
uint8_t complexity_index_type_a
Definition movenc.c:417
uint8_t num_blocks
Definition movenc.c:388
struct eac3_info::@032224065145233261074362213314253377146303165010 substream[1]
uint8_t acmod
Definition movenc.c:406
uint8_t bsid
Definition movenc.c:400
AVPacket * pkt
Definition movenc.c:385
uint8_t eof
Definition movenc.c:386
uint16_t chan_loc
Definition movenc.c:413
uint8_t ec3_done
Definition movenc.c:387
uint8_t num_dep_sub
Definition movenc.c:411
uint8_t lfeon
Definition movenc.c:408
uint8_t bsmod
Definition movenc.c:404
uint32_t avg_bit_rate
Average rate in bits/second over the entire presentation.
Definition movenc.c:750
uint32_t max_bit_rate
Maximum rate in bits/second over any window of one second.
Definition movenc.c:749
uint32_t buffer_size
Size of the decoding buffer for the elementary stream in bytes.
Definition movenc.c:748
Definition rpzaenc.c:60
uint8_t level
Definition svq3.c:208
#define lrint
Definition tablegen.h:53
#define av_free(p)
#define av_malloc_array(a, b)
#define av_mallocz(s)
#define avpriv_request_sample(...)
#define av_freep(p)
#define av_log(a,...)
static uint8_t tmp[40]
Definition aes_ctr.c:52
int num
Definition error.c:23
static int ref[MAX_W *MAX_W]
#define height
Definition dsp.h:99
#define width
Definition dsp.h:99
int av_timecode_init_from_string(AVTimecode *tc, AVRational rate, const char *str, void *log_ctx)
Parse timecode representation (hh:mm:ss[:;.
Definition timecode.c:241
Timecode helpers header.
@ AV_TIMECODE_FLAG_DROPFRAME
timecode is drop frame
Definition timecode.h:36
static int64_t pts
int size
UUID parsing and serialization utilities.
#define AV_UUID_LEN
Definition uuid.h:57
uint8_t AVUUID[AV_UUID_LEN]
Definition uuid.h:60
static int write_trailer(AVFormatContext *s1)
Definition v4l2enc.c:101
enum AVCodecID codec_id
static av_always_inline int vc1_unescape_buffer(const uint8_t *src, int size, uint8_t *dst)
Definition vc1_common.h:70
static av_always_inline const uint8_t * find_next_marker(const uint8_t *src, const uint8_t *end)
Find VC-1 marker in buffer.
Definition vc1_common.h:59
@ PROFILE_ADVANCED
Definition vc1_common.h:52
@ VC1_CODE_SEQHDR
Definition vc1_common.h:40
@ VC1_CODE_SLICE
Definition vc1_common.h:36
@ VC1_CODE_ENTRYPOINT
Definition vc1_common.h:39
const char * g
Definition vf_curves.c:128
static double cr(void *priv, double x, double y)
Definition vf_geq.c:248
static double cb(void *priv, double x, double y)
Definition vf_geq.c:247
static float mean(const float *input, int size)
Definition vf_nnedi.c:861
static const Range full_range
static void copy(const float *p1, float *p2, const int length)
int len
int ff_isom_write_vpcc(void *logctx, AVIOContext *pb, const uint8_t *data, int len, const AVCodecParameters *par)
Writes VP codec configuration to the provided AVIOContext.
Definition vpcc.c:204
internal header for VPx codec configuration utilities.
static double c[64]
int ff_vvc_annexb2mp4_buf(const uint8_t *buf_in, uint8_t **buf_out, int *size, int filter_ps, int *ps_count)
Writes Annex B formatted H.266/VVC NAL units to a data buffer.
Definition vvc.c:864
int ff_isom_write_vvcc(AVIOContext *pb, const uint8_t *data, int size, int ps_array_completeness)
Writes H.266/VVC extradata (parameter sets, declarative SEI NAL units) to the provided AVIOContext.
Definition vvc.c:885
int ff_vvc_annexb2mp4(AVIOContext *pb, const uint8_t *buf_in, int size, int filter_ps, int *ps_count)
Writes Annex B formatted H.266/VVC NAL units to the provided AVIOContext.
Definition vvc.c:816