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 <stdint.h>
27#include <inttypes.h>
28
29#include "movenc.h"
30#include "avformat.h"
31#include "avio_internal.h"
32#include "dovi_isom.h"
33#include "riff.h"
34#include "avio.h"
35#include "iamf_writer.h"
36#include "isom.h"
37#include "av1.h"
38#include "avc.h"
39#include "evc.h"
40#include "apv.h"
41#include "lcevc.h"
44#include "libavcodec/flac.h"
45#include "libavcodec/get_bits.h"
46
47#include "libavcodec/internal.h"
48#include "libavcodec/put_bits.h"
50#include "libavcodec/raw.h"
51#include "internal.h"
52#include "libavutil/avstring.h"
54#include "libavutil/csp.h"
55#include "libavutil/intfloat.h"
57#include "libavutil/libm.h"
58#include "libavutil/mem.h"
59#include "libavutil/opt.h"
60#include "libavutil/dict.h"
61#include "libavutil/pixdesc.h"
62#include "libavutil/stereo3d.h"
63#include "libavutil/timecode.h"
64#include "libavutil/dovi_meta.h"
65#include "libavutil/uuid.h"
66#include "hevc.h"
67#include "rtpenc.h"
68#include "nal.h"
69#include "mov_chan.h"
70#include "movenc_ttml.h"
71#include "mux.h"
72#include "rawutils.h"
73#include "ttmlenc.h"
74#include "version.h"
75#include "vpcc.h"
76#include "vvc.h"
77
78static const AVOption options[] = {
79 { "brand", "Override major brand", offsetof(MOVMuxContext, major_brand), AV_OPT_TYPE_STRING, {.str = NULL}, .flags = AV_OPT_FLAG_ENCODING_PARAM },
80 { "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},
81 { "encryption_key", "The media encryption key (hex)", offsetof(MOVMuxContext, encryption_key), AV_OPT_TYPE_BINARY, .flags = AV_OPT_FLAG_ENCODING_PARAM },
82 { "encryption_kid", "The media encryption key identifier (hex)", offsetof(MOVMuxContext, encryption_kid), AV_OPT_TYPE_BINARY, .flags = AV_OPT_FLAG_ENCODING_PARAM },
83 { "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 },
84 { "frag_duration", "Maximum fragment duration", offsetof(MOVMuxContext, max_fragment_duration), AV_OPT_TYPE_INT, {.i64 = 0}, 0, INT_MAX, AV_OPT_FLAG_ENCODING_PARAM},
85 { "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 },
86 { "frag_size", "Maximum fragment size", offsetof(MOVMuxContext, max_fragment_size), AV_OPT_TYPE_INT, {.i64 = 0}, 0, INT_MAX, AV_OPT_FLAG_ENCODING_PARAM},
87 { "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},
88 { "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},
89 { "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},
90 { "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},
91 { "movflags", "MOV muxer flags", offsetof(MOVMuxContext, flags), AV_OPT_TYPE_FLAGS, {.i64 = 0}, INT_MIN, INT_MAX, AV_OPT_FLAG_ENCODING_PARAM, .unit = "movflags" },
92 { "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" },
93 { "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" },
94 { "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" },
95 { "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" },
96 { "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" },
97 { "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" },
98 { "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" },
99 { "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" },
100 { "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" },
101 { "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" },
102 { "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" },
103 { "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" },
104 { "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" },
105 { "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 },
106 { "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" },
107 { "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" },
108 { "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" },
109 { "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" },
110 { "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" },
111 { "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" },
112 { "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" },
113 { "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" },
114 { "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" },
115 { "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" },
116 { "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" },
117 { "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},
118 { "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},
119 { "movie_timescale", "set movie timescale", offsetof(MOVMuxContext, movie_timescale), AV_OPT_TYPE_INT, {.i64 = 0}, 0, INT_MAX, AV_OPT_FLAG_ENCODING_PARAM},
121 { "skip_iods", "Skip writing iods atom.", offsetof(MOVMuxContext, iods_skip), AV_OPT_TYPE_BOOL, {.i64 = 1}, 0, 1, AV_OPT_FLAG_ENCODING_PARAM},
122 { "use_editlist", "use edit list", offsetof(MOVMuxContext, use_editlist), AV_OPT_TYPE_BOOL, {.i64 = -1}, -1, 1, AV_OPT_FLAG_ENCODING_PARAM},
123 { "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},
124 { "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},
125 { "write_btrt", "force or disable writing btrt", offsetof(MOVMuxContext, write_btrt), AV_OPT_TYPE_BOOL, {.i64 = -1}, -1, 1, AV_OPT_FLAG_ENCODING_PARAM},
126 { "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"},
127 { "pts", NULL, 0, AV_OPT_TYPE_CONST, {.i64 = MOV_PRFT_SRC_PTS}, 0, 0, AV_OPT_FLAG_ENCODING_PARAM, .unit = "prft"},
128 { "wallclock", NULL, 0, AV_OPT_TYPE_CONST, {.i64 = MOV_PRFT_SRC_WALLCLOCK}, 0, 0, AV_OPT_FLAG_ENCODING_PARAM, .unit = "prft"},
129 { "write_tmcd", "force or disable writing tmcd", offsetof(MOVMuxContext, write_tmcd), AV_OPT_TYPE_BOOL, {.i64 = -1}, -1, 1, AV_OPT_FLAG_ENCODING_PARAM},
130 { NULL },
131};
132
134 .class_name = "mov/mp4/tgp/psp/tg2/ipod/ismv/f4v muxer",
135 .item_name = av_default_item_name,
136 .option = options,
137 .version = LIBAVUTIL_VERSION_INT,
138};
139
140static int get_moov_size(AVFormatContext *s);
142
143static int utf8len(const uint8_t *b)
144{
145 int len = 0;
146 int val;
147 while (*b) {
148 GET_UTF8(val, *b++, return -1;)
149 len++;
150 }
151 return len;
152}
153
154//FIXME support 64 bit variant with wide placeholders
156{
157 int64_t curpos = avio_tell(pb);
158 avio_seek(pb, pos, SEEK_SET);
159 avio_wb32(pb, curpos - pos); /* rewrite size */
160 avio_seek(pb, curpos, SEEK_SET);
161
162 return curpos - pos;
163}
164
166{
167 int64_t curpos = avio_tell(pb);
168 avio_seek(pb, pos, SEEK_SET);
169 avio_wb32(pb, curpos - pos); /* rewrite size */
170 avio_skip(pb, 4);
171 avio_w8(pb, version); /* rewrite version */
172 avio_seek(pb, curpos, SEEK_SET);
173
174 return curpos - pos;
175}
176
177static int co64_required(const MOVTrack *track)
178{
179 if (track->entry > 0 && track->cluster[track->entry - 1].pos + track->data_offset > UINT32_MAX)
180 return 1;
181 return 0;
182}
183
184static int is_cover_image(const AVStream *st)
185{
186 /* Eg. AV_DISPOSITION_ATTACHED_PIC | AV_DISPOSITION_TIMED_THUMBNAILS
187 * is encoded as sparse video track */
188 return st && st->disposition == AV_DISPOSITION_ATTACHED_PIC;
189}
190
191static int rtp_hinting_needed(const AVStream *st)
192{
193 /* Add hint tracks for each real audio and video stream */
194 if (is_cover_image(st))
195 return 0;
196 return st->codecpar->codec_type == AVMEDIA_TYPE_VIDEO ||
198}
199
200/* Chunk offset atom */
202{
203 int i;
204 int mode64 = co64_required(track); // use 32 bit size variant if possible
205 int64_t pos = avio_tell(pb);
206 avio_wb32(pb, 0); /* size */
207 if (mode64)
208 ffio_wfourcc(pb, "co64");
209 else
210 ffio_wfourcc(pb, "stco");
211 avio_wb32(pb, 0); /* version & flags */
212 avio_wb32(pb, track->chunkCount); /* entry count */
213 for (i = 0; i < track->entry; i++) {
214 if (!track->cluster[i].chunkNum)
215 continue;
216 if (mode64 == 1)
217 avio_wb64(pb, track->cluster[i].pos + track->data_offset);
218 else
219 avio_wb32(pb, track->cluster[i].pos + track->data_offset);
220 }
221 return update_size(pb, pos);
222}
223
224/* Sample size atom */
226{
227 int equalChunks = 1;
228 int i, j, entries = 0, tst = -1, oldtst = -1;
229
230 int64_t pos = avio_tell(pb);
231 avio_wb32(pb, 0); /* size */
232 ffio_wfourcc(pb, "stsz");
233 avio_wb32(pb, 0); /* version & flags */
234
235 for (i = 0; i < track->entry; i++) {
236 tst = track->cluster[i].size / track->cluster[i].entries;
237 if (oldtst != -1 && tst != oldtst)
238 equalChunks = 0;
239 oldtst = tst;
240 entries += track->cluster[i].entries;
241 }
242 if (equalChunks && track->entry) {
243 int sSize = track->entry ? track->cluster[0].size / track->cluster[0].entries : 0;
244 sSize = FFMAX(1, sSize); // adpcm mono case could make sSize == 0
245 avio_wb32(pb, sSize); // sample size
246 avio_wb32(pb, entries); // sample count
247 } else {
248 avio_wb32(pb, 0); // sample size
249 avio_wb32(pb, entries); // sample count
250 for (i = 0; i < track->entry; i++) {
251 for (j = 0; j < track->cluster[i].entries; j++) {
252 avio_wb32(pb, track->cluster[i].size /
253 track->cluster[i].entries);
254 }
255 }
256 }
257 return update_size(pb, pos);
258}
259
260/* Sample to chunk atom */
262{
263 int index = 0, oldidx = -1, oldval = -1, i;
264 int64_t entryPos, curpos;
265
266 int64_t pos = avio_tell(pb);
267 avio_wb32(pb, 0); /* size */
268 ffio_wfourcc(pb, "stsc");
269 avio_wb32(pb, 0); // version & flags
270 entryPos = avio_tell(pb);
271 avio_wb32(pb, track->chunkCount); // entry count
272 for (i = 0; i < track->entry; i++) {
273 if ((oldval != track->cluster[i].samples_in_chunk ||
274 oldidx != track->cluster[i].stsd_index) && track->cluster[i].chunkNum) {
275 avio_wb32(pb, track->cluster[i].chunkNum); // first chunk
276 avio_wb32(pb, track->cluster[i].samples_in_chunk); // samples per chunk
277 avio_wb32(pb, track->cluster[i].stsd_index + 1); // sample description index
278 oldval = track->cluster[i].samples_in_chunk;
279 oldidx = track->cluster[i].stsd_index;
280 index++;
281 }
282 }
283 curpos = avio_tell(pb);
284 avio_seek(pb, entryPos, SEEK_SET);
285 avio_wb32(pb, index); // rewrite size
286 avio_seek(pb, curpos, SEEK_SET);
287
288 return update_size(pb, pos);
289}
290
291/* Sync sample atom */
292static int mov_write_stss_tag(AVIOContext *pb, MOVTrack *track, uint32_t flag)
293{
294 int64_t curpos, entryPos;
295 int i, index = 0;
296 int64_t pos = avio_tell(pb);
297 avio_wb32(pb, 0); // size
298 ffio_wfourcc(pb, flag == MOV_SYNC_SAMPLE ? "stss" : "stps");
299 avio_wb32(pb, 0); // version & flags
300 entryPos = avio_tell(pb);
301 avio_wb32(pb, track->entry); // entry count
302 for (i = 0; i < track->entry; i++) {
303 if (track->cluster[i].flags & flag) {
304 avio_wb32(pb, i + 1);
305 index++;
306 }
307 }
308 curpos = avio_tell(pb);
309 avio_seek(pb, entryPos, SEEK_SET);
310 avio_wb32(pb, index); // rewrite size
311 avio_seek(pb, curpos, SEEK_SET);
312 return update_size(pb, pos);
313}
314
315/* Sample dependency atom */
317{
318 int i;
319 uint8_t leading, dependent, reference, redundancy;
320 int64_t pos = avio_tell(pb);
321 avio_wb32(pb, 0); // size
322 ffio_wfourcc(pb, "sdtp");
323 avio_wb32(pb, 0); // version & flags
324 for (i = 0; i < track->entry; i++) {
325 dependent = MOV_SAMPLE_DEPENDENCY_YES;
326 leading = reference = redundancy = MOV_SAMPLE_DEPENDENCY_UNKNOWN;
327 if (track->cluster[i].flags & MOV_DISPOSABLE_SAMPLE) {
328 reference = MOV_SAMPLE_DEPENDENCY_NO;
329 }
330 if (track->cluster[i].flags & MOV_SYNC_SAMPLE) {
331 dependent = MOV_SAMPLE_DEPENDENCY_NO;
332 }
333 avio_w8(pb, (leading << 6) | (dependent << 4) |
334 (reference << 2) | redundancy);
335 }
336 return update_size(pb, pos);
337}
338
339#if CONFIG_IAMFENC
340static int mov_write_iacb_tag(AVFormatContext *s, AVIOContext *pb, MOVTrack *track)
341{
342 AVIOContext *dyn_bc;
343 int64_t pos = avio_tell(pb);
344 uint8_t *dyn_buf = NULL;
345 int dyn_size;
346 int ret = avio_open_dyn_buf(&dyn_bc);
347 if (ret < 0)
348 return ret;
349
350 avio_wb32(pb, 0);
351 ffio_wfourcc(pb, "iacb");
352 avio_w8(pb, 1); // configurationVersion
353
354 ret = ff_iamf_write_descriptors(track->iamf, dyn_bc, s);
355 if (ret < 0) {
356 ffio_free_dyn_buf(&dyn_bc);
357 return ret;
358 }
359
360 dyn_size = avio_close_dyn_buf(dyn_bc, &dyn_buf);
361 ffio_write_leb(pb, dyn_size);
362 avio_write(pb, dyn_buf, dyn_size);
363 av_free(dyn_buf);
364
365 return update_size(pb, pos);
366}
367#endif
368
370{
371 avio_wb32(pb, 0x11); /* size */
372 if (track->mode == MODE_MOV) ffio_wfourcc(pb, "samr");
373 else ffio_wfourcc(pb, "damr");
374 ffio_wfourcc(pb, "FFMP");
375 avio_w8(pb, 0); /* decoder version */
376
377 avio_wb16(pb, 0x81FF); /* Mode set (all modes for AMR_NB) */
378 avio_w8(pb, 0x00); /* Mode change period (no restriction) */
379 avio_w8(pb, 0x01); /* Frames per sample */
380 return 0x11;
381}
382
383struct eac3_info {
385 uint8_t eof;
386 uint8_t ec3_done;
387 uint8_t num_blocks;
388
389 /* Layout of the EC3SpecificBox */
390 /* maximum bitrate */
391 uint16_t data_rate;
393 /* number of independent substreams */
394 uint8_t num_ind_sub;
395 struct {
396 /* sample rate code (see ff_ac3_sample_rate_tab) 2 bits */
397 uint8_t fscod;
398 /* bit stream identification 5 bits */
399 uint8_t bsid;
400 /* one bit reserved */
401 /* audio service mixing (not supported yet) 1 bit */
402 /* bit stream mode 3 bits */
403 uint8_t bsmod;
404 /* audio coding mode 3 bits */
405 uint8_t acmod;
406 /* sub woofer on 1 bit */
407 uint8_t lfeon;
408 /* 3 bits reserved */
409 /* number of dependent substreams associated with this substream 4 bits */
410 uint8_t num_dep_sub;
411 /* channel locations of the dependent substream(s), if any, 9 bits */
412 uint16_t chan_loc;
413 /* if there is no dependent substream, then one bit reserved instead */
414 } substream[1]; /* TODO: support 8 independent substreams */
415 /* indicates the decoding complexity, 8 bits */
417};
418
420{
421 struct eac3_info *info = track->eac3_priv;
422 PutBitContext pbc;
423 uint8_t buf[3];
424
425 if (!info || !info->ec3_done) {
427 "Cannot write moov atom before AC3 packets."
428 " Set the delay_moov flag to fix this.\n");
429 return AVERROR(EINVAL);
430 }
431
432 if (info->substream[0].bsid > 8) {
434 "RealAudio AC-3/DolbyNet with bsid %d is not defined by the "
435 "ISOBMFF specification in ETSI TS 102 366!\n",
436 info->substream[0].bsid);
437 return AVERROR(EINVAL);
438 }
439
440 if (info->ac3_bit_rate_code < 0) {
442 "No valid AC3 bit rate code for data rate of %d!\n",
443 info->data_rate);
444 return AVERROR(EINVAL);
445 }
446
447 avio_wb32(pb, 11);
448 ffio_wfourcc(pb, "dac3");
449
450 init_put_bits(&pbc, buf, sizeof(buf));
451 put_bits(&pbc, 2, info->substream[0].fscod);
452 put_bits(&pbc, 5, info->substream[0].bsid);
453 put_bits(&pbc, 3, info->substream[0].bsmod);
454 put_bits(&pbc, 3, info->substream[0].acmod);
455 put_bits(&pbc, 1, info->substream[0].lfeon);
456 put_bits(&pbc, 5, info->ac3_bit_rate_code); // bit_rate_code
457 put_bits(&pbc, 5, 0); // reserved
458
459 flush_put_bits(&pbc);
460 avio_write(pb, buf, sizeof(buf));
461
462 return 11;
463}
464
466{
467 AC3HeaderInfo *hdr = NULL;
468 struct eac3_info *info;
469 int num_blocks, ret;
470
471 if (!track->eac3_priv) {
472 if (!(track->eac3_priv = av_mallocz(sizeof(*info))))
473 return AVERROR(ENOMEM);
474
475 ((struct eac3_info *)track->eac3_priv)->ac3_bit_rate_code = -1;
476 }
477 info = track->eac3_priv;
478
479 if (!info->pkt && !(info->pkt = av_packet_alloc()))
480 return AVERROR(ENOMEM);
481
482 if (info->eof) {
483 av_assert1(!info->pkt->size);
484 ret = pkt->size;
485 goto end;
486 }
487
488 if ((ret = avpriv_ac3_parse_header(&hdr, pkt->data, pkt->size)) < 0) {
489 if (ret == AVERROR(ENOMEM))
490 goto end;
491
492 /* drop the packets until we see a good one */
493 if (!track->entry) {
494 av_log(mov->fc, AV_LOG_WARNING, "Dropping invalid packet from start of the stream\n");
495 ret = 0;
496 } else
498 goto end;
499 }
500
501 info->data_rate = FFMAX(info->data_rate, hdr->bit_rate / 1000);
503 hdr->ac3_bit_rate_code);
505
506 num_blocks = hdr->num_blocks;
507
508 if (!info->ec3_done) {
509 /* AC-3 substream must be the first one */
510 if (hdr->bitstream_id <= 10 && hdr->substreamid != 0) {
511 ret = AVERROR(EINVAL);
512 goto end;
513 }
514
515 /* this should always be the case, given that our AC-3 parser
516 * concatenates dependent frames to their independent parent */
519 /* substream ids must be incremental */
520 if (hdr->substreamid > info->num_ind_sub + 1) {
521 ret = AVERROR(EINVAL);
522 goto end;
523 }
524
525 if (hdr->substreamid == info->num_ind_sub + 1) {
526 //info->num_ind_sub++;
527 avpriv_request_sample(mov->fc, "Multiple independent substreams");
529 goto end;
530 } else if (hdr->substreamid < info->num_ind_sub ||
531 hdr->substreamid == 0 && info->substream[0].bsid) {
532 info->ec3_done = 1;
533 goto concatenate;
534 }
535 } else {
536 if (hdr->substreamid != 0) {
537 avpriv_request_sample(mov->fc, "Multiple non EAC3 independent substreams");
539 goto end;
540 }
541 }
542
543 /* fill the info needed for the "dec3" atom */
544 info->substream[hdr->substreamid].fscod = hdr->sr_code;
545 info->substream[hdr->substreamid].bsid = hdr->bitstream_id;
546 info->substream[hdr->substreamid].bsmod = hdr->bitstream_mode;
547 info->substream[hdr->substreamid].acmod = hdr->channel_mode;
548 info->substream[hdr->substreamid].lfeon = hdr->lfe_on;
549
550 if (track->par->codec_id == AV_CODEC_ID_AC3) {
551 // with AC-3 we only require the information of a single packet,
552 // so we can finish as soon as the basic values of the bit stream
553 // have been set to the track's informational structure.
554 info->ec3_done = 1;
555 goto concatenate;
556 }
557
558 /* Parse dependent substream(s), if any */
559 if (pkt->size != hdr->frame_size) {
560 int cumul_size = hdr->frame_size;
561 int parent = hdr->substreamid;
562
563 while (cumul_size != pkt->size) {
564 ret = avpriv_ac3_parse_header(&hdr, pkt->data + cumul_size, pkt->size - cumul_size);
565 if (ret < 0)
566 goto end;
568 ret = AVERROR(EINVAL);
569 goto end;
570 }
571 info->substream[parent].num_dep_sub++;
572 ret /= 8;
573
574 /* get the dependent stream channel map, if exists */
575 if (hdr->channel_map_present) {
576 /* chanmap is a 16-bit field read MSB-first, so flag index
577 * i sits at bit (15 - i), matching the indexing of
578 * ff_eac3_custom_channel_map_locations. chan_loc bits 0-7
579 * carry flag indices 5-12, i.e. chanmap bit (10 - j).
580 * The mapping is not contiguous at the top: index 13
581 * (Lts/Rts) has no chan_loc bit and is skipped, and
582 * chan_loc bit 8 carries LFE2, which is index 14 and so
583 * chanmap bit 1. */
584 for (int j = 0; j < 8; j++) {
585 if ((hdr->channel_map >> (10 - j)) & 1)
586 info->substream[parent].chan_loc |= 1 << j;
587 }
588 if ((hdr->channel_map >> 1) & 1)
589 info->substream[parent].chan_loc |= 1 << 8;
590 } else {
591 info->substream[parent].chan_loc |= hdr->channel_mode;
592 }
593 cumul_size += hdr->frame_size;
594 }
595 }
596 }
597
598concatenate:
599 if (!info->num_blocks && num_blocks == 6) {
600 ret = pkt->size;
601 goto end;
602 }
603 else if (info->num_blocks + num_blocks > 6) {
605 goto end;
606 }
607
608 if (!info->num_blocks) {
609 ret = av_packet_ref(info->pkt, pkt);
610 if (!ret)
611 info->num_blocks = num_blocks;
612 goto end;
613 } else {
614 const AVPacketSideData *sd;
615 int64_t duration = pkt->duration;
616 if ((ret = av_grow_packet(info->pkt, pkt->size)) < 0)
617 goto end;
618 sd = av_packet_side_data_get(pkt->side_data, pkt->side_data_elems, AV_PKT_DATA_SKIP_SAMPLES);
619 if (sd && sd->size >= 10) {
620 uint8_t *buf = av_packet_new_side_data(info->pkt, AV_PKT_DATA_SKIP_SAMPLES, sd->size);
621 if (buf)
622 memcpy(buf, sd->data, sd->size);
623 if (track->par->frame_size)
624 duration = FFMAX(av_rescale_q(track->par->frame_size, (AVRational){ 1, track->par->sample_rate },
625 track->st->time_base), duration);
626 }
627 memcpy(info->pkt->data + info->pkt->size - pkt->size, pkt->data, pkt->size);
628 info->num_blocks += num_blocks;
629 info->pkt->duration += duration;
630 if (info->num_blocks != 6)
631 goto end;
633 av_packet_move_ref(pkt, info->pkt);
634 info->num_blocks = 0;
635 }
636 ret = pkt->size;
637
638end:
639 av_free(hdr);
640
641 return ret;
642}
643
645{
646 PutBitContext pbc;
647 uint8_t *buf;
648 struct eac3_info *info;
649 int size, i;
650
651 if (!track->eac3_priv) {
653 "Cannot write moov atom before EAC3 packets parsed.\n");
654 return AVERROR(EINVAL);
655 }
656
657 info = track->eac3_priv;
658 size = 2 + (4 * (info->num_ind_sub + 1)) + (2 * !!info->complexity_index_type_a);
659 buf = av_malloc(size);
660 if (!buf) {
661 return AVERROR(ENOMEM);
662 }
663
664 init_put_bits(&pbc, buf, size);
665 put_bits(&pbc, 13, info->data_rate);
666 put_bits(&pbc, 3, info->num_ind_sub);
667 for (i = 0; i <= info->num_ind_sub; i++) {
668 put_bits(&pbc, 2, info->substream[i].fscod);
669 put_bits(&pbc, 5, info->substream[i].bsid);
670 put_bits(&pbc, 1, 0); /* reserved */
671 put_bits(&pbc, 1, 0); /* asvc */
672 put_bits(&pbc, 3, info->substream[i].bsmod);
673 put_bits(&pbc, 3, info->substream[i].acmod);
674 put_bits(&pbc, 1, info->substream[i].lfeon);
675 put_bits(&pbc, 3, 0); /* reserved */
676 put_bits(&pbc, 4, info->substream[i].num_dep_sub);
677 if (!info->substream[i].num_dep_sub) {
678 put_bits(&pbc, 1, 0); /* reserved */
679 } else {
680 put_bits(&pbc, 9, info->substream[i].chan_loc);
681 }
682 }
683 if (info->complexity_index_type_a) {
684 put_bits(&pbc, 7, 0); /* reserved */
685 put_bits(&pbc, 1, 1); // flag_eac3_extension_type_a
686 put_bits(&pbc, 8, info->complexity_index_type_a);
687 }
688 flush_put_bits(&pbc);
689 size = put_bytes_output(&pbc);
690
691 avio_wb32(pb, size + 8);
692 ffio_wfourcc(pb, "dec3");
693 avio_write(pb, buf, size);
694
695 av_free(buf);
696
697 return size;
698}
699
700/**
701 * This function writes extradata "as is".
702 * Extradata must be formatted like a valid atom (with size and tag).
703 */
705{
706 avio_write(pb, track->extradata[track->last_stsd_index], track->extradata_size[track->last_stsd_index]);
707 return track->extradata_size[track->last_stsd_index];
708}
709
711{
712 avio_wb32(pb, 10);
713 ffio_wfourcc(pb, "enda");
714 avio_wb16(pb, 1); /* little endian */
715 return 10;
716}
717
719{
720 avio_wb32(pb, 10);
721 ffio_wfourcc(pb, "enda");
722 avio_wb16(pb, 0); /* big endian */
723 return 10;
724}
725
726static void put_descr(AVIOContext *pb, int tag, unsigned int size)
727{
728 int i = 3;
729 avio_w8(pb, tag);
730 for (; i > 0; i--)
731 avio_w8(pb, (size >> (7 * i)) | 0x80);
732 avio_w8(pb, size & 0x7F);
733}
734
735static unsigned compute_avg_bitrate(MOVTrack *track)
736{
737 uint64_t size = 0;
738 int i;
739 if (!track->track_duration)
740 return 0;
741 for (i = 0; i < track->entry; i++)
742 size += track->cluster[i].size;
743 return size * 8 * track->timescale / track->track_duration;
744}
745
747 uint32_t buffer_size; ///< Size of the decoding buffer for the elementary stream in bytes.
748 uint32_t max_bit_rate; ///< Maximum rate in bits/second over any window of one second.
749 uint32_t avg_bit_rate; ///< Average rate in bits/second over the entire presentation.
750};
751
753{
754 const AVPacketSideData *sd = track->st ?
758 AVCPBProperties *props = sd ? (AVCPBProperties *)sd->data : NULL;
759 struct mpeg4_bit_rate_values bit_rates = { 0 };
760
761 bit_rates.avg_bit_rate = compute_avg_bitrate(track);
762 if (!bit_rates.avg_bit_rate) {
763 // if the average bit rate cannot be calculated at this point, such as
764 // in the case of fragmented MP4, utilize the following values as
765 // fall-back in priority order:
766 //
767 // 1. average bit rate property
768 // 2. bit rate (usually average over the whole clip)
769 // 3. maximum bit rate property
770
771 if (props && props->avg_bitrate) {
772 bit_rates.avg_bit_rate = props->avg_bitrate;
773 } else if (track->par->bit_rate) {
774 bit_rates.avg_bit_rate = track->par->bit_rate;
775 } else if (props && props->max_bitrate) {
776 bit_rates.avg_bit_rate = props->max_bitrate;
777 }
778 }
779
780 // (FIXME should be max rate in any 1 sec window)
781 bit_rates.max_bit_rate = FFMAX(track->par->bit_rate,
782 bit_rates.avg_bit_rate);
783
784 // utilize values from properties if we have them available
785 if (props) {
786 // no avg_bitrate signals that the track is VBR
787 if (!props->avg_bitrate)
788 bit_rates.avg_bit_rate = props->avg_bitrate;
789 bit_rates.max_bit_rate = FFMAX(bit_rates.max_bit_rate,
790 props->max_bitrate);
791 bit_rates.buffer_size = props->buffer_size / 8;
792 }
793
794 return bit_rates;
795}
796
797static int mov_write_esds_tag(AVIOContext *pb, MOVTrack *track) // Basic
798{
799 struct mpeg4_bit_rate_values bit_rates = calculate_mpeg4_bit_rates(track);
800 int64_t pos = avio_tell(pb);
801 int decoder_specific_info_len = track->extradata_size[track->last_stsd_index] ?
802 5 + track->extradata_size[track->last_stsd_index] : 0;
803
804 avio_wb32(pb, 0); // size
805 ffio_wfourcc(pb, "esds");
806 avio_wb32(pb, 0); // Version
807
808 // ES descriptor
809 put_descr(pb, 0x03, 3 + 5+13 + decoder_specific_info_len + 5+1);
810 avio_wb16(pb, track->track_id);
811 avio_w8(pb, 0x00); // flags (= no flags)
812
813 // DecoderConfig descriptor
814 put_descr(pb, 0x04, 13 + decoder_specific_info_len);
815
816 // Object type indication
817 if ((track->par->codec_id == AV_CODEC_ID_MP2 ||
818 track->par->codec_id == AV_CODEC_ID_MP3) &&
819 track->par->sample_rate > 24000)
820 avio_w8(pb, 0x6B); // 11172-3
821 else
823
824 // the following fields is made of 6 bits to identify the streamtype (4 for video, 5 for audio)
825 // plus 1 bit to indicate upstream and 1 bit set to 1 (reserved)
827 avio_w8(pb, (0x38 << 2) | 1); // flags (= NeroSubpicStream)
828 else if (track->par->codec_type == AVMEDIA_TYPE_AUDIO)
829 avio_w8(pb, 0x15); // flags (= Audiostream)
830 else
831 avio_w8(pb, 0x11); // flags (= Visualstream)
832
833 avio_wb24(pb, bit_rates.buffer_size); // Buffersize DB
834 avio_wb32(pb, bit_rates.max_bit_rate); // maxbitrate
835 avio_wb32(pb, bit_rates.avg_bit_rate);
836
837 if (track->extradata_size[track->last_stsd_index]) {
838 // DecoderSpecific info descriptor
839 put_descr(pb, 0x05, track->extradata_size[track->last_stsd_index]);
840 avio_write(pb, track->extradata[track->last_stsd_index],
841 track->extradata_size[track->last_stsd_index]);
842 }
843
844 // SL descriptor
845 put_descr(pb, 0x06, 1);
846 avio_w8(pb, 0x02);
847 return update_size(pb, pos);
848}
849
857
865
867{
868 int ret;
869 int64_t pos = avio_tell(pb);
870 avio_wb32(pb, 0);
871 avio_wl32(pb, track->tag); // store it byteswapped
872 track->par->codec_tag = av_bswap16(track->tag >> 16);
873 if ((ret = ff_put_wav_header(s, pb, track->par, 0)) < 0)
874 return ret;
875 return update_size(pb, pos);
876}
877
879{
880 int ret;
881 int64_t pos = avio_tell(pb);
882 avio_wb32(pb, 0);
883 ffio_wfourcc(pb, "wfex");
885 return ret;
886 return update_size(pb, pos);
887}
888
890{
891 int64_t pos = avio_tell(pb);
892 avio_wb32(pb, 0);
893 ffio_wfourcc(pb, "dfLa");
894 avio_w8(pb, 0); /* version */
895 avio_wb24(pb, 0); /* flags */
896
897 /* Expect the encoder to pass a METADATA_BLOCK_TYPE_STREAMINFO. */
899 return AVERROR_INVALIDDATA;
900
901 /* TODO: Write other METADATA_BLOCK_TYPEs if the encoder makes them available. */
902 avio_w8(pb, 1 << 7 | FLAC_METADATA_TYPE_STREAMINFO); /* LastMetadataBlockFlag << 7 | BlockType */
903 avio_wb24(pb, track->extradata_size[track->last_stsd_index]); /* Length */
904 avio_write(pb, track->extradata[track->last_stsd_index], track->extradata_size[track->last_stsd_index]); /* BlockData[Length] */
905
906 return update_size(pb, pos);
907}
908
910{
911 int64_t pos = avio_tell(pb);
913 avio_wb32(pb, 0);
914 ffio_wfourcc(pb, "dOps");
915 avio_w8(pb, 0); /* Version */
916 if (track->extradata_size[track->last_stsd_index] < 19) {
917 av_log(s, AV_LOG_ERROR, "invalid extradata size\n");
918 return AVERROR_INVALIDDATA;
919 }
920 /* extradata contains an Ogg OpusHead, other than byte-ordering and
921 OpusHead's preceding magic/version, OpusSpecificBox is currently
922 identical. */
923 channels = AV_RB8(track->extradata[track->last_stsd_index] + 9);
924 channel_map = AV_RB8(track->extradata[track->last_stsd_index] + 18);
925
926 avio_w8(pb, channels); /* OuputChannelCount */
927 avio_wb16(pb, AV_RL16(track->extradata[track->last_stsd_index] + 10)); /* PreSkip */
928 avio_wb32(pb, AV_RL32(track->extradata[track->last_stsd_index] + 12)); /* InputSampleRate */
929 avio_wb16(pb, AV_RL16(track->extradata[track->last_stsd_index] + 16)); /* OutputGain */
930 avio_w8(pb, channel_map); /* ChannelMappingFamily */
931 /* Write the rest of the header out without byte-swapping. */
932 if (channel_map) {
933 if (track->extradata_size[track->last_stsd_index] < 21 + channels) {
934 av_log(s, AV_LOG_ERROR, "invalid extradata size\n");
935 return AVERROR_INVALIDDATA;
936 }
937 avio_write(pb, track->extradata[track->last_stsd_index] + 19, 2 + channels); /* ChannelMappingTable */
938 }
939
940 return update_size(pb, pos);
941}
942
944{
945 int64_t pos = avio_tell(pb);
946 int length;
947 avio_wb32(pb, 0);
948 ffio_wfourcc(pb, "dmlp");
949
950 if (track->extradata_size[track->last_stsd_index] < 20) {
952 "Cannot write moov atom before TrueHD packets."
953 " Set the delay_moov flag to fix this.\n");
954 return AVERROR(EINVAL);
955 }
956
957 length = (AV_RB16(track->extradata[track->last_stsd_index]) & 0xFFF) * 2;
958 if (length < 20 || length > track->extradata_size[track->last_stsd_index])
959 return AVERROR_INVALIDDATA;
960
961 // Only TrueHD is supported
962 if (AV_RB32(track->extradata[track->last_stsd_index] + 4) != 0xF8726FBA)
963 return AVERROR_INVALIDDATA;
964
965 avio_wb32(pb, AV_RB32(track->extradata[track->last_stsd_index] + 8)); /* format_info */
966 avio_wb16(pb, AV_RB16(track->extradata[track->last_stsd_index] + 18) << 1); /* peak_data_rate */
967 avio_wb32(pb, 0); /* reserved */
968
969 return update_size(pb, pos);
970}
971
973{
974 const AVDictionaryEntry *str = av_dict_get(track->st->metadata, "SA3D", NULL, 0);
975 AVChannelLayout ch_layout = { 0 };
976 int64_t pos;
977 int ambisonic_order, ambi_channels, non_diegetic_channels;
978 int i, ret;
979
980 if (!str)
981 return 0;
982
983 ret = av_channel_layout_from_string(&ch_layout, str->value);
984 if (ret < 0) {
985 if (ret == AVERROR(EINVAL)) {
986invalid:
987 av_log(s, AV_LOG_ERROR, "Invalid SA3D layout: \"%s\"\n", str->value);
988 ret = 0;
989 }
990 av_channel_layout_uninit(&ch_layout);
991 return ret;
992 }
993
994 if (track->st->codecpar->ch_layout.nb_channels != ch_layout.nb_channels)
995 goto invalid;
996
997 ambisonic_order = av_channel_layout_ambisonic_order(&ch_layout);
998 if (ambisonic_order < 0)
999 goto invalid;
1000
1001 ambi_channels = (ambisonic_order + 1LL) * (ambisonic_order + 1LL);
1002 non_diegetic_channels = ch_layout.nb_channels - ambi_channels;
1003 if (non_diegetic_channels &&
1004 (non_diegetic_channels != 2 ||
1006 goto invalid;
1007
1008 av_log(s, AV_LOG_VERBOSE, "Inserting SA3D box with layout: \"%s\"\n", str->value);
1009
1010 pos = avio_tell(pb);
1011
1012 avio_wb32(pb, 0); // Size
1013 ffio_wfourcc(pb, "SA3D");
1014 avio_w8(pb, 0); // version
1015 avio_w8(pb, (!!non_diegetic_channels) << 7); // head_locked_stereo and ambisonic_type
1016 avio_wb32(pb, ambisonic_order); // ambisonic_order
1017 avio_w8(pb, 0); // ambisonic_channel_ordering
1018 avio_w8(pb, 0); // ambisonic_normalization
1019 avio_wb32(pb, ch_layout.nb_channels); // num_channels
1020 for (i = 0; i < ambi_channels; i++)
1022 for (; i < ch_layout.nb_channels; i++)
1023 avio_wb32(pb, av_channel_layout_channel_from_index(&ch_layout, i) + ambi_channels);
1024
1025 av_channel_layout_uninit(&ch_layout);
1026
1027 return update_size(pb, pos);
1028}
1029
1031{
1032 uint32_t layout_tag, bitmap, *channel_desc;
1033 int64_t pos = avio_tell(pb);
1034 int num_desc, ret;
1035
1036 if (track->multichannel_as_mono)
1037 return 0;
1038
1039 ret = ff_mov_get_channel_layout_tag(track->par, &layout_tag,
1040 &bitmap, &channel_desc);
1041
1042 if (ret < 0) {
1043 if (ret == AVERROR(ENOSYS)) {
1044 av_log(s, AV_LOG_WARNING, "not writing 'chan' tag due to "
1045 "lack of channel information\n");
1046 ret = 0;
1047 }
1048
1049 return ret;
1050 }
1051
1052 /* no predefined tag found + ch_layout in AV_CHANNEL_ORDER_NATIVE
1053 * but bitstream channels not actually in native order */
1054 if (layout_tag == MOV_CH_LAYOUT_UNKNOWN)
1055 return 0;
1056
1057 if (layout_tag == MOV_CH_LAYOUT_MONO && track->mono_as_fc > 0) {
1058 av_assert0(!channel_desc);
1059 channel_desc = av_malloc(sizeof(*channel_desc));
1060 if (!channel_desc)
1061 return AVERROR(ENOMEM);
1062
1063 layout_tag = 0;
1064 bitmap = 0;
1065 *channel_desc = 3; // channel label "Center"
1066 }
1067
1068 num_desc = layout_tag ? 0 : track->par->ch_layout.nb_channels;
1069
1070 avio_wb32(pb, 0); // Size
1071 ffio_wfourcc(pb, "chan"); // Type
1072 avio_w8(pb, 0); // Version
1073 avio_wb24(pb, 0); // Flags
1074 avio_wb32(pb, layout_tag); // mChannelLayoutTag
1075 avio_wb32(pb, bitmap); // mChannelBitmap
1076 avio_wb32(pb, num_desc); // mNumberChannelDescriptions
1077
1078 for (int i = 0; i < num_desc; i++) {
1079 avio_wb32(pb, channel_desc[i]); // mChannelLabel
1080 avio_wb32(pb, 0); // mChannelFlags
1081 avio_wl32(pb, 0); // mCoordinates[0]
1082 avio_wl32(pb, 0); // mCoordinates[1]
1083 avio_wl32(pb, 0); // mCoordinates[2]
1084 }
1085
1086 av_free(channel_desc);
1087
1088 return update_size(pb, pos);
1089}
1090
1092{
1093 int64_t pos = avio_tell(pb);
1094
1095 avio_wb32(pb, 0); /* size */
1096 ffio_wfourcc(pb, "wave");
1097
1098 if (track->par->codec_id != AV_CODEC_ID_QDM2) {
1099 avio_wb32(pb, 12); /* size */
1100 ffio_wfourcc(pb, "frma");
1101 avio_wl32(pb, track->tag);
1102 }
1103
1104 if (track->par->codec_id == AV_CODEC_ID_AAC) {
1105 /* useless atom needed by mplayer, ipod, not needed by quicktime */
1106 avio_wb32(pb, 12); /* size */
1107 ffio_wfourcc(pb, "mp4a");
1108 avio_wb32(pb, 0);
1109 mov_write_esds_tag(pb, track);
1110 } else if (mov_pcm_le_gt16(track->par->codec_id)) {
1112 } else if (mov_pcm_be_gt16(track->par->codec_id)) {
1114 } else if (track->par->codec_id == AV_CODEC_ID_AMR_NB) {
1115 mov_write_amr_tag(pb, track);
1116 } else if (track->par->codec_id == AV_CODEC_ID_AC3) {
1117 mov_write_ac3_tag(s, pb, track);
1118 } else if (track->par->codec_id == AV_CODEC_ID_EAC3) {
1119 mov_write_eac3_tag(s, pb, track);
1120 } else if (track->par->codec_id == AV_CODEC_ID_ALAC ||
1121 track->par->codec_id == AV_CODEC_ID_QDM2) {
1122 mov_write_extradata_tag(pb, track);
1123 } else if (track->par->codec_id == AV_CODEC_ID_ADPCM_MS ||
1125 mov_write_ms_tag(s, pb, track);
1126 }
1127
1128 avio_wb32(pb, 8); /* size */
1129 avio_wb32(pb, 0); /* null tag */
1130
1131 return update_size(pb, pos);
1132}
1133
1134static int mov_write_dvc1_structs(MOVTrack *track, uint8_t *buf)
1135{
1136 uint8_t *unescaped;
1137 const uint8_t *start, *next, *end = track->extradata[track->last_stsd_index] +
1138 track->extradata_size[track->last_stsd_index];
1139 int unescaped_size, seq_found = 0;
1140 int level = 0, interlace = 0;
1141 int packet_seq = track->vc1_info.packet_seq;
1142 int packet_entry = track->vc1_info.packet_entry;
1143 int slices = track->vc1_info.slices;
1144 PutBitContext pbc;
1145
1146 if (track->start_dts == AV_NOPTS_VALUE) {
1147 /* No packets written yet, vc1_info isn't authoritative yet. */
1148 /* Assume inline sequence and entry headers. */
1149 packet_seq = packet_entry = 1;
1151 "moov atom written before any packets, unable to write correct "
1152 "dvc1 atom. Set the delay_moov flag to fix this.\n");
1153 }
1154
1156 if (!unescaped)
1157 return AVERROR(ENOMEM);
1158 start = find_next_marker(track->extradata[track->last_stsd_index], end);
1159 for (next = start; next < end; start = next) {
1160 GetBitContext gb;
1161 int size;
1162 next = find_next_marker(start + 4, end);
1163 size = next - start - 4;
1164 if (size <= 0)
1165 continue;
1166 unescaped_size = vc1_unescape_buffer(start + 4, size, unescaped);
1167 init_get_bits(&gb, unescaped, 8 * unescaped_size);
1168 if (AV_RB32(start) == VC1_CODE_SEQHDR) {
1169 int profile = get_bits(&gb, 2);
1170 if (profile != PROFILE_ADVANCED) {
1171 av_free(unescaped);
1172 return AVERROR(ENOSYS);
1173 }
1174 seq_found = 1;
1175 level = get_bits(&gb, 3);
1176 /* chromaformat, frmrtq_postproc, bitrtq_postproc, postprocflag,
1177 * width, height */
1178 skip_bits_long(&gb, 2 + 3 + 5 + 1 + 2*12);
1179 skip_bits(&gb, 1); /* broadcast */
1180 interlace = get_bits1(&gb);
1181 skip_bits(&gb, 4); /* tfcntrflag, finterpflag, reserved, psf */
1182 }
1183 }
1184 if (!seq_found) {
1185 av_free(unescaped);
1186 return AVERROR(ENOSYS);
1187 }
1188
1189 init_put_bits(&pbc, buf, 7);
1190 /* VC1DecSpecStruc */
1191 put_bits(&pbc, 4, 12); /* profile - advanced */
1192 put_bits(&pbc, 3, level);
1193 put_bits(&pbc, 1, 0); /* reserved */
1194 /* VC1AdvDecSpecStruc */
1195 put_bits(&pbc, 3, level);
1196 put_bits(&pbc, 1, 0); /* cbr */
1197 put_bits(&pbc, 6, 0); /* reserved */
1198 put_bits(&pbc, 1, !interlace); /* no interlace */
1199 put_bits(&pbc, 1, !packet_seq); /* no multiple seq */
1200 put_bits(&pbc, 1, !packet_entry); /* no multiple entry */
1201 put_bits(&pbc, 1, !slices); /* no slice code */
1202 put_bits(&pbc, 1, 0); /* no bframe */
1203 put_bits(&pbc, 1, 0); /* reserved */
1204
1205 /* framerate */
1206 if (track->st->avg_frame_rate.num > 0 && track->st->avg_frame_rate.den > 0)
1207 put_bits32(&pbc, track->st->avg_frame_rate.num / track->st->avg_frame_rate.den);
1208 else
1209 put_bits32(&pbc, 0xffffffff);
1210
1211 flush_put_bits(&pbc);
1212
1213 av_free(unescaped);
1214
1215 return 0;
1216}
1217
1219{
1220 uint8_t buf[7] = { 0 };
1221 int ret;
1222
1223 if ((ret = mov_write_dvc1_structs(track, buf)) < 0)
1224 return ret;
1225
1226 avio_wb32(pb, track->extradata_size[track->last_stsd_index] + 8 + sizeof(buf));
1227 ffio_wfourcc(pb, "dvc1");
1228 avio_write(pb, buf, sizeof(buf));
1229 avio_write(pb, track->extradata[track->last_stsd_index],
1230 track->extradata_size[track->last_stsd_index]);
1231
1232 return 0;
1233}
1234
1236{
1237 avio_wb32(pb, track->extradata_size[track->last_stsd_index] + 8);
1238 ffio_wfourcc(pb, "glbl");
1239 avio_write(pb, track->extradata[track->last_stsd_index],
1240 track->extradata_size[track->last_stsd_index]);
1241 return 8 + track->extradata_size[track->last_stsd_index];
1242}
1243
1244/**
1245 * Compute flags for 'lpcm' tag.
1246 * See CoreAudioTypes and AudioStreamBasicDescription at Apple.
1247 */
1249{
1250 switch (codec_id) {
1253 return 11;
1256 return 9;
1257 case AV_CODEC_ID_PCM_U8:
1258 return 10;
1262 return 14;
1263 case AV_CODEC_ID_PCM_S8:
1267 return 12;
1268 default:
1269 return 0;
1270 }
1271}
1272
1273static int get_cluster_duration(MOVTrack *track, int cluster_idx)
1274{
1275 int64_t next_dts;
1276
1277 if (cluster_idx >= track->entry)
1278 return 0;
1279
1280 if (cluster_idx + 1 == track->entry)
1281 next_dts = track->track_duration + track->start_dts;
1282 else
1283 next_dts = track->cluster[cluster_idx + 1].dts;
1284
1285 next_dts -= track->cluster[cluster_idx].dts;
1286
1287 av_assert0(next_dts >= 0);
1288 av_assert0(next_dts <= INT_MAX);
1289
1290 return next_dts;
1291}
1292
1294{
1295 int i, first_duration;
1296
1297 /* use 1 for raw PCM */
1298 if (!track->audio_vbr)
1299 return 1;
1300
1301 /* check to see if duration is constant for all clusters */
1302 if (!track->entry)
1303 return 0;
1304 first_duration = get_cluster_duration(track, 0);
1305 for (i = 1; i < track->entry; i++) {
1306 if (get_cluster_duration(track, i) != first_duration)
1307 return 0;
1308 }
1309 return first_duration;
1310}
1311
1313{
1314 int64_t pos = avio_tell(pb);
1315 struct mpeg4_bit_rate_values bit_rates = calculate_mpeg4_bit_rates(track);
1316 if (!bit_rates.max_bit_rate && !bit_rates.avg_bit_rate &&
1317 !bit_rates.buffer_size)
1318 // no useful data to be written, skip
1319 return 0;
1320
1321 avio_wb32(pb, 0); /* size */
1322 ffio_wfourcc(pb, "btrt");
1323
1324 avio_wb32(pb, bit_rates.buffer_size);
1325 avio_wb32(pb, bit_rates.max_bit_rate);
1326 avio_wb32(pb, bit_rates.avg_bit_rate);
1327
1328 return update_size(pb, pos);
1329}
1330
1332{
1333 int64_t pos = avio_tell(pb);
1334 int config = 0;
1335 int ret;
1336 uint8_t *speaker_pos = NULL;
1337 const AVChannelLayout *layout = &track->par->ch_layout;
1338
1340 if (ret || !config) {
1341 config = 0;
1342 speaker_pos = av_malloc(layout->nb_channels);
1343 if (!speaker_pos)
1344 return AVERROR(ENOMEM);
1346 speaker_pos, layout->nb_channels);
1347 if (ret) {
1348 char buf[128] = {0};
1349
1350 av_freep(&speaker_pos);
1351 av_channel_layout_describe(layout, buf, sizeof(buf));
1352 av_log(s, AV_LOG_ERROR, "unsupported channel layout %s\n", buf);
1353 return ret;
1354 }
1355 }
1356
1357 avio_wb32(pb, 0); /* size */
1358 ffio_wfourcc(pb, "chnl");
1359 avio_wb32(pb, 0); /* version & flags */
1360
1361 avio_w8(pb, 1); /* stream_structure */
1362 avio_w8(pb, config);
1363 if (config) {
1364 avio_wb64(pb, 0);
1365 } else {
1366 avio_write(pb, speaker_pos, layout->nb_channels);
1367 av_freep(&speaker_pos);
1368 }
1369
1370 return update_size(pb, pos);
1371}
1372
1374{
1375 int64_t pos = avio_tell(pb);
1376 int format_flags;
1377 int sample_size;
1378
1379 avio_wb32(pb, 0); /* size */
1380 ffio_wfourcc(pb, "pcmC");
1381 avio_wb32(pb, 0); /* version & flags */
1382
1383 /* 0x01: indicates little-endian format */
1384 format_flags = (track->par->codec_id == AV_CODEC_ID_PCM_F32LE ||
1385 track->par->codec_id == AV_CODEC_ID_PCM_F64LE ||
1386 track->par->codec_id == AV_CODEC_ID_PCM_S16LE ||
1387 track->par->codec_id == AV_CODEC_ID_PCM_S24LE ||
1389 avio_w8(pb, format_flags);
1390 sample_size = track->par->bits_per_raw_sample;
1391 if (!sample_size)
1392 sample_size = av_get_exact_bits_per_sample(track->par->codec_id);
1393 av_assert0(sample_size);
1394 avio_w8(pb, sample_size);
1395
1396 return update_size(pb, pos);
1397}
1398
1400{
1401 int64_t pos = avio_tell(pb);
1402 avio_wb32(pb, 0); /* size */
1403 ffio_wfourcc(pb, "srat");
1404 avio_wb32(pb, 0); /* version & flags */
1405
1406 avio_wb32(pb, track->par->sample_rate);
1407
1408 return update_size(pb, pos);
1409}
1410
1412{
1413 int64_t pos = avio_tell(pb);
1414 int version = 0;
1415 uint32_t tag = track->tag;
1416 int ret = 0;
1417
1418 if (track->mode == MODE_MOV) {
1419 if (track->par->sample_rate > UINT16_MAX || !track->par->ch_layout.nb_channels ||
1420 track->par->codec_id == AV_CODEC_ID_EAC3 ||
1421 track->par->ch_layout.nb_channels > 2) {
1422 if (mov_get_lpcm_flags(track->par->codec_id))
1423 tag = AV_RL32("lpcm");
1424 version = 2;
1425 } else if (track->audio_vbr || mov_pcm_le_gt16(track->par->codec_id) ||
1426 mov_pcm_be_gt16(track->par->codec_id) ||
1427 track->par->codec_id == AV_CODEC_ID_ADPCM_MS ||
1429 track->par->codec_id == AV_CODEC_ID_QDM2) {
1430 version = 1;
1431 }
1432 } else if (track->mode == MODE_MP4) {
1433 if (track->par->sample_rate > UINT16_MAX &&
1435 version = 1;
1436 }
1437
1438 avio_wb32(pb, 0); /* size */
1439 if (mov->encryption_scheme != MOV_ENC_NONE) {
1440 ffio_wfourcc(pb, "enca");
1441 } else {
1442 avio_wl32(pb, tag); // store it byteswapped
1443 }
1444 avio_wb32(pb, 0); /* Reserved */
1445 avio_wb16(pb, 0); /* Reserved */
1446 avio_wb16(pb, 1); /* Data-reference index, XXX == 1 */
1447
1448 /* SoundDescription */
1449 avio_wb16(pb, version); /* Version */
1450 avio_wb16(pb, 0); /* Revision level */
1451 avio_wb32(pb, 0); /* Reserved */
1452
1453 if (version == 2) {
1454 avio_wb16(pb, 3);
1455 avio_wb16(pb, 16);
1456 avio_wb16(pb, 0xfffe);
1457 avio_wb16(pb, 0);
1458 avio_wb32(pb, 0x00010000);
1459 avio_wb32(pb, 72);
1460 avio_wb64(pb, av_double2int(track->par->sample_rate));
1461 avio_wb32(pb, track->par->ch_layout.nb_channels);
1462 avio_wb32(pb, 0x7F000000);
1465 avio_wb32(pb, track->sample_size);
1467 } else {
1468 unsigned sample_rate = track->par->sample_rate;
1469
1470 if (track->mode == MODE_MOV) {
1471 avio_wb16(pb, track->par->ch_layout.nb_channels);
1472 if (track->par->codec_id == AV_CODEC_ID_PCM_U8 ||
1473 track->par->codec_id == AV_CODEC_ID_PCM_S8)
1474 avio_wb16(pb, 8); /* bits per sample */
1475 else if (track->par->codec_id == AV_CODEC_ID_ADPCM_G726)
1476 avio_wb16(pb, track->par->bits_per_coded_sample);
1477 else
1478 avio_wb16(pb, 16);
1479 avio_wb16(pb, track->audio_vbr ? -2 : 0); /* compression ID */
1480 } else { /* reserved for mp4/3gp */
1481 avio_wb16(pb, track->tag == MKTAG('i', 'a', 'm', 'f') ?
1482 0 : track->par->ch_layout.nb_channels);
1483 if (track->par->codec_id == AV_CODEC_ID_FLAC ||
1484 track->par->codec_id == AV_CODEC_ID_ALAC) {
1485 avio_wb16(pb, track->par->bits_per_raw_sample);
1486 } else {
1487 avio_wb16(pb, 16);
1488 }
1489 avio_wb16(pb, 0);
1490
1491 while (sample_rate > UINT16_MAX)
1492 sample_rate >>= 1;
1493 }
1494
1495 avio_wb16(pb, 0); /* packet size (= 0) */
1496 if (track->tag == MKTAG('i','a','m','f'))
1497 avio_wb16(pb, 0); /* samplerate must be 0 for IAMF */
1498 else if (track->par->codec_id == AV_CODEC_ID_OPUS)
1499 avio_wb16(pb, 48000);
1500 else if (track->par->codec_id == AV_CODEC_ID_TRUEHD)
1501 avio_wb32(pb, track->par->sample_rate);
1502 else
1503 avio_wb16(pb, sample_rate);
1504
1505 if (track->par->codec_id != AV_CODEC_ID_TRUEHD)
1506 avio_wb16(pb, 0); /* Reserved */
1507 }
1508
1509 if (track->mode == MODE_MOV && version == 1) { /* SoundDescription V1 extended info */
1510 if (mov_pcm_le_gt16(track->par->codec_id) ||
1511 mov_pcm_be_gt16(track->par->codec_id))
1512 avio_wb32(pb, 1); /* must be 1 for uncompressed formats */
1513 else
1514 avio_wb32(pb, track->par->frame_size); /* Samples per packet */
1515 avio_wb32(pb, track->sample_size / track->par->ch_layout.nb_channels); /* Bytes per packet */
1516 avio_wb32(pb, track->sample_size); /* Bytes per frame */
1517 avio_wb32(pb, 2); /* Bytes per sample */
1518 }
1519
1520 if (track->mode == MODE_MOV &&
1521 (track->par->codec_id == AV_CODEC_ID_AAC ||
1522 track->par->codec_id == AV_CODEC_ID_AC3 ||
1523 track->par->codec_id == AV_CODEC_ID_EAC3 ||
1524 track->par->codec_id == AV_CODEC_ID_AMR_NB ||
1525 track->par->codec_id == AV_CODEC_ID_ALAC ||
1526 track->par->codec_id == AV_CODEC_ID_ADPCM_MS ||
1528 track->par->codec_id == AV_CODEC_ID_QDM2 ||
1529 (mov_pcm_le_gt16(track->par->codec_id) && version==1) ||
1530 (mov_pcm_be_gt16(track->par->codec_id) && version==1)))
1531 ret = mov_write_wave_tag(s, pb, track);
1532 else if (track->tag == MKTAG('m','p','4','a'))
1533 ret = mov_write_esds_tag(pb, track);
1534#if CONFIG_IAMFENC
1535 else if (track->tag == MKTAG('i','a','m','f'))
1536 ret = mov_write_iacb_tag(mov->fc, pb, track);
1537#endif
1538 else if (track->par->codec_id == AV_CODEC_ID_AMR_NB)
1539 ret = mov_write_amr_tag(pb, track);
1540 else if (track->par->codec_id == AV_CODEC_ID_AC3)
1541 ret = mov_write_ac3_tag(s, pb, track);
1542 else if (track->par->codec_id == AV_CODEC_ID_EAC3)
1543 ret = mov_write_eac3_tag(s, pb, track);
1544 else if (track->par->codec_id == AV_CODEC_ID_ALAC)
1545 ret = mov_write_extradata_tag(pb, track);
1546 else if (track->par->codec_id == AV_CODEC_ID_WMAPRO)
1547 ret = mov_write_wfex_tag(s, pb, track);
1548 else if (track->par->codec_id == AV_CODEC_ID_FLAC)
1549 ret = mov_write_dfla_tag(pb, track);
1550 else if (track->par->codec_id == AV_CODEC_ID_OPUS)
1551 ret = mov_write_dops_tag(s, pb, track);
1552 else if (track->par->codec_id == AV_CODEC_ID_TRUEHD)
1553 ret = mov_write_dmlp_tag(s, pb, track);
1554 else if (tag == MOV_MP4_IPCM_TAG || tag == MOV_MP4_FPCM_TAG) {
1555 if (track->par->sample_rate > UINT16_MAX)
1556 mov_write_srat_tag(pb, track);
1557 if (track->par->ch_layout.nb_channels > 1)
1558 ret = mov_write_chnl_tag(s, pb, track);
1559 if (ret < 0)
1560 return ret;
1561 ret = mov_write_pcmc_tag(s, pb, track);
1562 } else if (track->extradata_size[track->last_stsd_index] > 0)
1563 ret = mov_write_glbl_tag(pb, track);
1564
1565 if (ret < 0)
1566 return ret;
1567
1568 if (track->mode == MODE_MP4 && track->par->codec_type == AVMEDIA_TYPE_AUDIO
1569 && ((ret = mov_write_SA3D_tag(s, pb, track)) < 0)) {
1570 return ret;
1571 }
1572
1573 if (track->mode == MODE_MOV && track->par->codec_type == AVMEDIA_TYPE_AUDIO
1574 && ((ret = mov_write_chan_tag(s, pb, track)) < 0)) {
1575 return ret;
1576 }
1577
1579 && ((ret = ff_mov_cenc_write_sinf_tag(track, pb, mov->encryption_kid)) < 0)) {
1580 return ret;
1581 }
1582
1583 if (mov->write_btrt &&
1584 ((ret = mov_write_btrt_tag(pb, track)) < 0))
1585 return ret;
1586
1587 if (track->mode == MODE_MP4)
1588 track->entry_version = version;
1589
1590 ret = update_size(pb, pos);
1591 return ret;
1592}
1593
1595{
1596 avio_wb32(pb, 0xf); /* size */
1597 ffio_wfourcc(pb, "d263");
1598 ffio_wfourcc(pb, "FFMP");
1599 avio_w8(pb, 0); /* decoder version */
1600 /* FIXME use AVCodecContext level/profile, when encoder will set values */
1601 avio_w8(pb, 0xa); /* level */
1602 avio_w8(pb, 0); /* profile */
1603 return 0xf;
1604}
1605
1607{
1608 int64_t pos = avio_tell(pb);
1609
1610 avio_wb32(pb, 0);
1611 ffio_wfourcc(pb, "av1C");
1612 ff_isom_write_av1c(pb, track->extradata[track->last_stsd_index],
1613 track->extradata_size[track->last_stsd_index], track->mode != MODE_AVIF);
1614 return update_size(pb, pos);
1615}
1616
1618{
1619 int64_t pos = avio_tell(pb);
1620
1621 avio_wb32(pb, 0);
1622 ffio_wfourcc(pb, "avcC");
1623 ff_isom_write_avcc(pb, track->extradata[track->last_stsd_index],
1624 track->extradata_size[track->last_stsd_index]);
1625 return update_size(pb, pos);
1626}
1627
1628/* AVS3 Intelligent Media Coding
1629 * Information Technology - Intelligent Media Coding
1630 * Part 6: Intelligent Media Format
1631 */
1632static int mov_write_av3c(AVIOContext *pb, const uint8_t *data, int len)
1633{
1634 if (len < 4)
1635 return AVERROR_INVALIDDATA;
1636
1637 if (data[0] == 1) {
1638 // In Avs3DecoderConfigurationRecord format
1639 avio_write(pb, data, len);
1640 return 0;
1641 }
1642
1643 avio_w8(pb, 1); // version
1644 avio_wb16(pb, len); // sequence_header_length
1645 avio_write(pb, data, len); // sequence_header
1646 avio_w8(pb, 0xFC); // Only support library_dependency_idc = 0
1647
1648 return 0;
1649}
1650
1652{
1653 int64_t pos = avio_tell(pb);
1654 avio_wb32(pb, 0);
1655 ffio_wfourcc(pb, "av3c");
1656 mov_write_av3c(pb, track->extradata[track->last_stsd_index],
1657 track->extradata_size[track->last_stsd_index]);
1658 return update_size(pb, pos);
1659}
1660
1662{
1663 int64_t pos = avio_tell(pb);
1664
1665 avio_wb32(pb, 0);
1666 ffio_wfourcc(pb, "vpcC");
1667 ff_isom_write_vpcc(s, pb, track->extradata[track->last_stsd_index],
1668 track->extradata_size[track->last_stsd_index], track->par);
1669 return update_size(pb, pos);
1670}
1671
1673{
1674 int64_t pos = avio_tell(pb);
1675
1676 avio_wb32(pb, 0);
1677 ffio_wfourcc(pb, "hvcC");
1678 if (track->tag == MKTAG('h','v','c','1'))
1679 ff_isom_write_hvcc(pb, track->extradata[track->last_stsd_index],
1680 track->extradata_size[track->last_stsd_index], 1, s);
1681 else
1682 ff_isom_write_hvcc(pb, track->extradata[track->last_stsd_index],
1683 track->extradata_size[track->last_stsd_index], 0, s);
1684 return update_size(pb, pos);
1685}
1686
1688{
1689 int64_t pos = avio_tell(pb);
1690 int ret;
1691
1692 avio_wb32(pb, 0);
1693 ffio_wfourcc(pb, "lhvC");
1694 if (track->tag == MKTAG('h','v','c','1'))
1695 ret = ff_isom_write_lhvc(pb, track->extradata[track->last_stsd_index],
1696 track->extradata_size[track->last_stsd_index], 1, s);
1697 else
1698 ret = ff_isom_write_lhvc(pb, track->extradata[track->last_stsd_index],
1699 track->extradata_size[track->last_stsd_index], 0, s);
1700
1701 if (ret < 0) {
1702 avio_seek(pb, pos, SEEK_SET);
1703 return ret;
1704 }
1705
1706 return update_size(pb, pos);
1707}
1708
1710{
1711 int64_t pos = avio_tell(pb);
1712
1713 avio_wb32(pb, 0);
1714 ffio_wfourcc(pb, "evcC");
1715
1716 if (track->tag == MKTAG('e','v','c','1'))
1717 ff_isom_write_evcc(pb, track->extradata[track->last_stsd_index],
1718 track->extradata_size[track->last_stsd_index], 1);
1719 else
1720 ff_isom_write_evcc(pb, track->extradata[track->last_stsd_index],
1721 track->extradata_size[track->last_stsd_index], 0);
1722
1723 return update_size(pb, pos);
1724}
1725
1727{
1728 int64_t pos = avio_tell(pb);
1729
1730 avio_wb32(pb, 0);
1731 ffio_wfourcc(pb, "lvcC");
1732
1733 ff_isom_write_lvcc(pb, track->extradata[track->last_stsd_index],
1734 track->extradata_size[track->last_stsd_index], s);
1735
1736 return update_size(pb, pos);
1737}
1738
1740{
1741 int64_t pos = avio_tell(pb);
1742
1743 avio_wb32(pb, 0);
1744 ffio_wfourcc(pb, "vvcC");
1745
1746 avio_w8 (pb, 0); /* version */
1747 avio_wb24(pb, 0); /* flags */
1748
1749 if (track->tag == MKTAG('v','v','c','1'))
1750 ff_isom_write_vvcc(pb, track->extradata[track->last_stsd_index],
1751 track->extradata_size[track->last_stsd_index], 1);
1752 else
1753 ff_isom_write_vvcc(pb, track->extradata[track->last_stsd_index],
1754 track->extradata_size[track->last_stsd_index], 0);
1755 return update_size(pb, pos);
1756}
1757
1759{
1760 int64_t pos = avio_tell(pb);
1761
1762 avio_wb32(pb, 0);
1763 ffio_wfourcc(pb, "apvC");
1764
1765 avio_w8 (pb, 0); /* version */
1766 avio_wb24(pb, 0); /* flags */
1767
1768 ff_isom_write_apvc(pb, track->apv, s);
1769
1770 return update_size(pb, pos);
1771}
1772
1773/* also used by all avid codecs (dv, imx, meridien) and their variants */
1774/* https://community.avid.com/forums/t/136517.aspx */
1776{
1777 int interlaced;
1778 int cid;
1779 int display_width = track->par->width;
1780 const uint8_t *extradata;
1781
1782 if (track->extradata[track->last_stsd_index] && track->extradata_size[track->last_stsd_index] > 0x29) {
1783 if (ff_dnxhd_parse_header_prefix(track->extradata[track->last_stsd_index]) != 0) {
1784 /* looks like a DNxHD bit stream */
1785 extradata = track->extradata[track->last_stsd_index];
1786 } else {
1787 av_log(NULL, AV_LOG_WARNING, "Could not locate DNxHD bit stream in vos_data\n");
1788 return 0;
1789 }
1790 } else {
1791 av_log(NULL, AV_LOG_WARNING, "Could not locate DNxHD bit stream, vos_data too small\n");
1792 return 0;
1793 }
1794
1795 cid = AV_RB32(extradata + 0x28);
1796
1797 avio_wb32(pb, 24); /* size */
1798 ffio_wfourcc(pb, "ACLR");
1799 ffio_wfourcc(pb, "ACLR");
1800 ffio_wfourcc(pb, "0001");
1801 // 1: CCIR (supercolors will be dropped, 16 will be displayed as black)
1802 // 2: FullRange (0 will be displayed as black, 16 will be displayed as dark grey)
1803 if (track->par->color_range == AVCOL_RANGE_MPEG || /* Legal range (16-235) */
1805 avio_wb32(pb, 1);
1806 } else {
1807 avio_wb32(pb, 2);
1808 }
1809 avio_wb32(pb, 0); /* reserved */
1810
1811 if (track->tag == MKTAG('A','V','d','h')) {
1812 int alp = extradata[0x07] & 1;
1813 int pma = (extradata[0x07] >> 2) & 1;
1814 int sbd = (extradata[0x21] >> 5) & 3;
1815 int ssc = (extradata[0x2C] >> 5) & 3;
1816 int clv = (extradata[0x2C] >> 1) & 3;
1817 int clf = extradata[0x2C] & 1;
1818
1819 avio_wb32(pb, 32);
1820 ffio_wfourcc(pb, "ADHR");
1821 ffio_wfourcc(pb, "0001");
1822 avio_wb32(pb, cid); // Compression ID
1823 // 0: 4:2:2 Sub Sampling
1824 // 1: 4:2:0 Sub Sampling
1825 // 2: 4:4:4 Sub Sampling
1826 avio_wb32(pb, ssc); // Sub Sampling Control
1827 // 1: 8-bits per sample
1828 // 2: 10-bits per sample
1829 // 3: 12-bits per sample
1830 avio_wb32(pb, sbd); // Sample Bit Depth
1831 // 0: Bitstream is encoded using the YCBCR format rules and tables
1832 // 1: Bitstream is encoded using the RGB format rules and tables – only Compression IDs 1256, 1270
1833 avio_wb16(pb, clf); // Color Format
1834 // 0: ITU-R BT.709
1835 // 1: ITU-R BT.2020
1836 // 2: ITU-R BT.2020 C
1837 // 3: Out-of-band
1838 avio_wb16(pb, clv); // Color Volume
1839 // 0: Alpha channel not present
1840 // 1: Alpha channel present
1841 avio_wb16(pb, alp); // Alpha Present
1842 // 0: Alpha has not been applied to video channels
1843 // 1: Alpha has been applied to the video channels prior to encoding
1844 avio_wb16(pb, pma); // Pre-Multiplied Alpha
1845 return 0;
1846 }
1847
1848 interlaced = extradata[5] & 2;
1849
1850 avio_wb32(pb, 24); /* size */
1851 ffio_wfourcc(pb, "APRG");
1852 ffio_wfourcc(pb, "APRG");
1853 ffio_wfourcc(pb, "0001");
1854 // 1 for progressive or 2 for interlaced
1855 if (interlaced)
1856 avio_wb32(pb, 2);
1857 else
1858 avio_wb32(pb, 1);
1859 avio_wb32(pb, 0); /* reserved */
1860
1861 avio_wb32(pb, 120); /* size */
1862 ffio_wfourcc(pb, "ARES");
1863 ffio_wfourcc(pb, "ARES");
1864 ffio_wfourcc(pb, "0001");
1865 avio_wb32(pb, cid); /* cid */
1866 if ( track->par->sample_aspect_ratio.num > 0
1867 && track->par->sample_aspect_ratio.den > 0)
1868 display_width = display_width * track->par->sample_aspect_ratio.num / track->par->sample_aspect_ratio.den;
1869 avio_wb32(pb, display_width); // field width
1870 if (interlaced) {
1871 avio_wb32(pb, track->par->height / 2); // field height
1872 avio_wb32(pb, 2); // num fields
1873 avio_wb32(pb, 0); // num black lines (must be 0)
1874 // 4: HD1080i
1875 // 5: HD1080P
1876 // 6: HD720P
1877 avio_wb32(pb, 4); // video format
1878 } else {
1879 avio_wb32(pb, track->par->height);
1880 avio_wb32(pb, 1); // num fields
1881 avio_wb32(pb, 0);
1882 if (track->par->height == 1080)
1883 avio_wb32(pb, 5);
1884 else
1885 avio_wb32(pb, 6);
1886 }
1887 /* padding */
1888 ffio_fill(pb, 0, 10 * 8);
1889
1890 return 0;
1891}
1892
1894{
1895 avio_wb32(pb, 12);
1896 ffio_wfourcc(pb, "DpxE");
1897 if (track->extradata_size[track->last_stsd_index] >= 12 &&
1898 !memcmp(&track->extradata[track->last_stsd_index][4], "DpxE", 4)) {
1899 avio_wb32(pb, track->extradata[track->last_stsd_index][11]);
1900 } else {
1901 avio_wb32(pb, 1);
1902 }
1903 return 0;
1904}
1905
1907{
1908 int tag;
1909
1910 if (track->par->width == 720) { /* SD */
1911 if (track->par->height == 480) { /* NTSC */
1912 if (track->par->format == AV_PIX_FMT_YUV422P) tag = MKTAG('d','v','5','n');
1913 else tag = MKTAG('d','v','c',' ');
1914 }else if (track->par->format == AV_PIX_FMT_YUV422P) tag = MKTAG('d','v','5','p');
1915 else if (track->par->format == AV_PIX_FMT_YUV420P) tag = MKTAG('d','v','c','p');
1916 else tag = MKTAG('d','v','p','p');
1917 } else if (track->par->height == 720) { /* HD 720 line */
1918 if (track->st->time_base.den == 50) tag = MKTAG('d','v','h','q');
1919 else tag = MKTAG('d','v','h','p');
1920 } else if (track->par->height == 1080) { /* HD 1080 line */
1921 if (track->st->time_base.den == 25) tag = MKTAG('d','v','h','5');
1922 else tag = MKTAG('d','v','h','6');
1923 } else {
1924 av_log(s, AV_LOG_ERROR, "unsupported height for dv codec\n");
1925 return 0;
1926 }
1927
1928 return tag;
1929}
1930
1932{
1933 AVRational rational_framerate = st->avg_frame_rate;
1934 int rate = 0;
1935 if (rational_framerate.den != 0)
1936 rate = av_q2d(rational_framerate);
1937 return rate;
1938}
1939
1941{
1942 int tag = track->par->codec_tag;
1944 AVStream *st = track->st;
1945 int rate = defined_frame_rate(s, st);
1946
1947 if (!tag)
1948 tag = MKTAG('m', '2', 'v', '1'); //fallback tag
1949
1950 if (track->par->format == AV_PIX_FMT_YUV420P) {
1951 if (track->par->width == 1280 && track->par->height == 720) {
1952 if (!interlaced) {
1953 if (rate == 24) tag = MKTAG('x','d','v','4');
1954 else if (rate == 25) tag = MKTAG('x','d','v','5');
1955 else if (rate == 30) tag = MKTAG('x','d','v','1');
1956 else if (rate == 50) tag = MKTAG('x','d','v','a');
1957 else if (rate == 60) tag = MKTAG('x','d','v','9');
1958 }
1959 } else if (track->par->width == 1440 && track->par->height == 1080) {
1960 if (!interlaced) {
1961 if (rate == 24) tag = MKTAG('x','d','v','6');
1962 else if (rate == 25) tag = MKTAG('x','d','v','7');
1963 else if (rate == 30) tag = MKTAG('x','d','v','8');
1964 } else {
1965 if (rate == 25) tag = MKTAG('x','d','v','3');
1966 else if (rate == 30) tag = MKTAG('x','d','v','2');
1967 }
1968 } else if (track->par->width == 1920 && track->par->height == 1080) {
1969 if (!interlaced) {
1970 if (rate == 24) tag = MKTAG('x','d','v','d');
1971 else if (rate == 25) tag = MKTAG('x','d','v','e');
1972 else if (rate == 30) tag = MKTAG('x','d','v','f');
1973 } else {
1974 if (rate == 25) tag = MKTAG('x','d','v','c');
1975 else if (rate == 30) tag = MKTAG('x','d','v','b');
1976 }
1977 }
1978 } else if (track->par->format == AV_PIX_FMT_YUV422P) {
1979 if (track->par->width == 1280 && track->par->height == 720) {
1980 if (!interlaced) {
1981 if (rate == 24) tag = MKTAG('x','d','5','4');
1982 else if (rate == 25) tag = MKTAG('x','d','5','5');
1983 else if (rate == 30) tag = MKTAG('x','d','5','1');
1984 else if (rate == 50) tag = MKTAG('x','d','5','a');
1985 else if (rate == 60) tag = MKTAG('x','d','5','9');
1986 }
1987 } else if (track->par->width == 1920 && track->par->height == 1080) {
1988 if (!interlaced) {
1989 if (rate == 24) tag = MKTAG('x','d','5','d');
1990 else if (rate == 25) tag = MKTAG('x','d','5','e');
1991 else if (rate == 30) tag = MKTAG('x','d','5','f');
1992 } else {
1993 if (rate == 25) tag = MKTAG('x','d','5','c');
1994 else if (rate == 30) tag = MKTAG('x','d','5','b');
1995 }
1996 }
1997 }
1998
1999 return tag;
2000}
2001
2003{
2004 int tag = track->par->codec_tag;
2006 AVStream *st = track->st;
2007 int rate = defined_frame_rate(s, st);
2008
2009 if (!tag)
2010 tag = MKTAG('a', 'v', 'c', 'i'); //fallback tag
2011
2012 if (track->par->profile == AV_PROFILE_UNKNOWN ||
2013 !(track->par->profile & AV_PROFILE_H264_INTRA))
2014 return tag;
2015
2016 if (track->par->format == AV_PIX_FMT_YUV420P10) {
2017 if (track->par->width == 960 && track->par->height == 720) {
2018 if (!interlaced) {
2019 if (rate == 24) tag = MKTAG('a','i','5','p');
2020 else if (rate == 25) tag = MKTAG('a','i','5','q');
2021 else if (rate == 30) tag = MKTAG('a','i','5','p');
2022 else if (rate == 50) tag = MKTAG('a','i','5','q');
2023 else if (rate == 60) tag = MKTAG('a','i','5','p');
2024 }
2025 } else if (track->par->width == 1440 && track->par->height == 1080) {
2026 if (!interlaced) {
2027 if (rate == 24) tag = MKTAG('a','i','5','3');
2028 else if (rate == 25) tag = MKTAG('a','i','5','2');
2029 else if (rate == 30) tag = MKTAG('a','i','5','3');
2030 } else {
2031 if (rate == 50) tag = MKTAG('a','i','5','5');
2032 else if (rate == 60) tag = MKTAG('a','i','5','6');
2033 }
2034 }
2035 } else if (track->par->format == AV_PIX_FMT_YUV422P10) {
2036 if (track->par->width == 1280 && track->par->height == 720) {
2037 if (!interlaced) {
2038 if (rate == 24) tag = MKTAG('a','i','1','p');
2039 else if (rate == 25) tag = MKTAG('a','i','1','q');
2040 else if (rate == 30) tag = MKTAG('a','i','1','p');
2041 else if (rate == 50) tag = MKTAG('a','i','1','q');
2042 else if (rate == 60) tag = MKTAG('a','i','1','p');
2043 }
2044 } else if (track->par->width == 1920 && track->par->height == 1080) {
2045 if (!interlaced) {
2046 if (rate == 24) tag = MKTAG('a','i','1','3');
2047 else if (rate == 25) tag = MKTAG('a','i','1','2');
2048 else if (rate == 30) tag = MKTAG('a','i','1','3');
2049 } else {
2050 if (rate == 25) tag = MKTAG('a','i','1','5');
2051 else if (rate == 50) tag = MKTAG('a','i','1','5');
2052 else if (rate == 60) tag = MKTAG('a','i','1','6');
2053 }
2054 } else if ( track->par->width == 4096 && track->par->height == 2160
2055 || track->par->width == 3840 && track->par->height == 2160
2056 || track->par->width == 2048 && track->par->height == 1080) {
2057 tag = MKTAG('a','i','v','x');
2058 }
2059 }
2060
2061 return tag;
2062}
2063
2065{
2066 int tag = track->par->codec_tag;
2067
2068 if (!tag)
2069 tag = MKTAG('e', 'v', 'c', '1');
2070
2071 return tag;
2072}
2073
2075{
2076 int tag = track->par->codec_tag;
2077
2078 if (!tag)
2079 tag = MKTAG('a', 'p', 'v', '1');
2080
2081 return tag;
2082}
2083
2084
2085static const struct {
2087 uint32_t tag;
2088 unsigned bps;
2089} mov_pix_fmt_tags[] = {
2090 { AV_PIX_FMT_YUYV422, MKTAG('y','u','v','2'), 0 },
2091 { AV_PIX_FMT_YUYV422, MKTAG('y','u','v','s'), 0 },
2092 { AV_PIX_FMT_UYVY422, MKTAG('2','v','u','y'), 0 },
2093 { AV_PIX_FMT_VYU444, MKTAG('v','3','0','8'), 0 },
2094 { AV_PIX_FMT_UYVA, MKTAG('v','4','0','8'), 0 },
2095 { AV_PIX_FMT_V30XLE, MKTAG('v','4','1','0'), 0 },
2096 { AV_PIX_FMT_RGB555BE,MKTAG('r','a','w',' '), 16 },
2097 { AV_PIX_FMT_RGB555LE,MKTAG('L','5','5','5'), 16 },
2098 { AV_PIX_FMT_RGB565LE,MKTAG('L','5','6','5'), 16 },
2099 { AV_PIX_FMT_RGB565BE,MKTAG('B','5','6','5'), 16 },
2100 { AV_PIX_FMT_GRAY16BE,MKTAG('b','1','6','g'), 16 },
2101 { AV_PIX_FMT_RGB24, MKTAG('r','a','w',' '), 24 },
2102 { AV_PIX_FMT_BGR24, MKTAG('2','4','B','G'), 24 },
2103 { AV_PIX_FMT_ARGB, MKTAG('r','a','w',' '), 32 },
2104 { AV_PIX_FMT_BGRA, MKTAG('B','G','R','A'), 32 },
2105 { AV_PIX_FMT_RGBA, MKTAG('R','G','B','A'), 32 },
2106 { AV_PIX_FMT_ABGR, MKTAG('A','B','G','R'), 32 },
2107 { AV_PIX_FMT_RGB48BE, MKTAG('b','4','8','r'), 48 },
2109
2111{
2112 int tag = MKTAG('A','V','d','n');
2113 if (track->par->profile != AV_PROFILE_UNKNOWN &&
2114 track->par->profile != AV_PROFILE_DNXHD)
2115 tag = MKTAG('A','V','d','h');
2116 return tag;
2117}
2118
2120{
2121 int tag = track->par->codec_tag;
2122 int i;
2124
2125 for (i = 0; i < FF_ARRAY_ELEMS(mov_pix_fmt_tags); i++) {
2126 if (track->par->format == mov_pix_fmt_tags[i].pix_fmt) {
2127 tag = mov_pix_fmt_tags[i].tag;
2129 if (track->par->codec_tag == mov_pix_fmt_tags[i].tag)
2130 break;
2131 }
2132 }
2133
2135 track->par->bits_per_coded_sample);
2136 if (tag == MKTAG('r','a','w',' ') &&
2137 track->par->format != pix_fmt &&
2138 track->par->format != AV_PIX_FMT_GRAY8 &&
2139 track->par->format != AV_PIX_FMT_NONE)
2140 av_log(s, AV_LOG_ERROR, "%s rawvideo cannot be written to mov, output file will be unreadable\n",
2141 av_get_pix_fmt_name(track->par->format));
2142 return tag;
2143}
2144
2145static unsigned int mov_get_codec_tag(AVFormatContext *s, MOVTrack *track)
2146{
2147 unsigned int tag = track->par->codec_tag;
2148
2149 // "rtp " is used to distinguish internally created RTP-hint tracks
2150 // (with rtp_ctx) from other tracks.
2151 if (tag == MKTAG('r','t','p',' '))
2152 tag = 0;
2153 if (!tag || (s->strict_std_compliance >= FF_COMPLIANCE_NORMAL &&
2154 (track->par->codec_id == AV_CODEC_ID_DVVIDEO ||
2155 track->par->codec_id == AV_CODEC_ID_RAWVIDEO ||
2156 track->par->codec_id == AV_CODEC_ID_H263 ||
2157 track->par->codec_id == AV_CODEC_ID_H264 ||
2158 track->par->codec_id == AV_CODEC_ID_DNXHD ||
2159 track->par->codec_id == AV_CODEC_ID_MPEG2VIDEO ||
2160 av_get_bits_per_sample(track->par->codec_id)))) { // pcm audio
2161 if (track->par->codec_id == AV_CODEC_ID_DVVIDEO)
2162 tag = mov_get_dv_codec_tag(s, track);
2163 else if (track->par->codec_id == AV_CODEC_ID_RAWVIDEO)
2165 else if (track->par->codec_id == AV_CODEC_ID_MPEG2VIDEO)
2167 else if (track->par->codec_id == AV_CODEC_ID_H264)
2168 tag = mov_get_h264_codec_tag(s, track);
2169 else if (track->par->codec_id == AV_CODEC_ID_EVC)
2170 tag = mov_get_evc_codec_tag(s, track);
2171 else if (track->par->codec_id == AV_CODEC_ID_APV)
2172 tag = mov_get_apv_codec_tag(s, track);
2173 else if (track->par->codec_id == AV_CODEC_ID_DNXHD)
2174 tag = mov_get_dnxhd_codec_tag(s, track);
2175 else if (track->par->codec_type == AVMEDIA_TYPE_VIDEO) {
2177 if (!tag) { // if no mac fcc found, try with Microsoft tags
2179 if (tag)
2180 av_log(s, AV_LOG_WARNING, "Using MS style video codec tag, "
2181 "the file may be unplayable!\n");
2182 }
2183 } else if (track->par->codec_type == AVMEDIA_TYPE_AUDIO) {
2185 if (!tag) { // if no mac fcc found, try with Microsoft tags
2186 int ms_tag = ff_codec_get_tag(ff_codec_wav_tags, track->par->codec_id);
2187 if (ms_tag) {
2188 tag = MKTAG('m', 's', ((ms_tag >> 8) & 0xff), (ms_tag & 0xff));
2189 av_log(s, AV_LOG_WARNING, "Using MS style audio codec tag, "
2190 "the file may be unplayable!\n");
2191 }
2192 }
2193 } else if (track->par->codec_type == AVMEDIA_TYPE_SUBTITLE)
2195 }
2196
2197 return tag;
2198}
2199
2201 { AV_CODEC_ID_MJPEG, 0xD },
2202 { AV_CODEC_ID_PNG, 0xE },
2203 { AV_CODEC_ID_BMP, 0x1B },
2204 { AV_CODEC_ID_NONE, 0 },
2205};
2206
2207static unsigned int validate_codec_tag(const AVCodecTag *const *tags,
2208 unsigned int tag, int codec_id)
2209{
2210 int i;
2211
2212 /**
2213 * Check that tag + id is in the table
2214 */
2215 for (i = 0; tags && tags[i]; i++) {
2216 const AVCodecTag *codec_tags = tags[i];
2217 while (codec_tags->id != AV_CODEC_ID_NONE) {
2218 if (ff_toupper4(codec_tags->tag) == ff_toupper4(tag) &&
2219 codec_tags->id == codec_id)
2220 return codec_tags->tag;
2221 codec_tags++;
2222 }
2223 }
2224 return 0;
2225}
2226
2227static unsigned int mov_find_codec_tag(AVFormatContext *s, MOVTrack *track)
2228{
2229 if (is_cover_image(track->st))
2231
2232 if (track->mode == MODE_IPOD)
2233 if (!av_match_ext(s->url, "m4a") &&
2234 !av_match_ext(s->url, "m4v") &&
2235 !av_match_ext(s->url, "m4b"))
2236 av_log(s, AV_LOG_WARNING, "Warning, extension is not .m4a nor .m4v "
2237 "Quicktime/Ipod might not play the file\n");
2238
2239 if (track->mode == MODE_MOV) {
2240 return mov_get_codec_tag(s, track);
2241 } else
2242 return validate_codec_tag(s->oformat->codec_tag, track->par->codec_tag,
2243 track->par->codec_id);
2244}
2245
2246/** Write uuid atom.
2247 * Needed to make file play in iPods running newest firmware
2248 * goes after avcC atom in moov.trak.mdia.minf.stbl.stsd.avc1
2249 */
2251{
2252 avio_wb32(pb, 28);
2253 ffio_wfourcc(pb, "uuid");
2254 avio_wb32(pb, 0x6b6840f2);
2255 avio_wb32(pb, 0x5f244fc5);
2256 avio_wb32(pb, 0xba39a51b);
2257 avio_wb32(pb, 0xcf0323f3);
2258 avio_wb32(pb, 0x0);
2259 return 28;
2260}
2261
2262static const uint16_t fiel_data[] = {
2263 0x0000, 0x0100, 0x0201, 0x0206, 0x0209, 0x020e
2264};
2265
2266static int mov_write_fiel_tag(AVIOContext *pb, MOVTrack *track, int field_order)
2267{
2268 unsigned mov_field_order = 0;
2269 if (field_order < FF_ARRAY_ELEMS(fiel_data))
2270 mov_field_order = fiel_data[field_order];
2271 else
2272 return 0;
2273 avio_wb32(pb, 10);
2274 ffio_wfourcc(pb, "fiel");
2275 avio_wb16(pb, mov_field_order);
2276 return 10;
2277}
2278
2280{
2281 MOVMuxContext *mov = s->priv_data;
2282 int ret = AVERROR_BUG;
2283 int64_t pos = avio_tell(pb);
2284 avio_wb32(pb, 0); /* size */
2285 avio_wl32(pb, track->tag); // store it byteswapped
2286 avio_wb32(pb, 0); /* Reserved */
2287 avio_wb16(pb, 0); /* Reserved */
2288 avio_wb16(pb, 1); /* Data-reference index */
2289
2290 if (track->par->codec_id == AV_CODEC_ID_DVD_SUBTITLE)
2291 mov_write_esds_tag(pb, track);
2292 else if (track->par->codec_id == AV_CODEC_ID_TTML) {
2293 switch (track->par->codec_tag) {
2294 case MOV_ISMV_TTML_TAG:
2295 // ISMV dfxp requires no extradata.
2296 break;
2297 case MOV_MP4_TTML_TAG:
2298 // As specified in 14496-30, XMLSubtitleSampleEntry
2299 // Namespace
2300 avio_put_str(pb, "http://www.w3.org/ns/ttml");
2301 // Empty schema_location
2302 avio_w8(pb, 0);
2303 // Empty auxiliary_mime_types
2304 avio_w8(pb, 0);
2305 break;
2306 default:
2308 "Unknown codec tag '%s' utilized for TTML stream with "
2309 "index %d (track id %d)!\n",
2310 av_fourcc2str(track->par->codec_tag), track->st->index,
2311 track->track_id);
2312 return AVERROR(EINVAL);
2313 }
2314 } else if (track->extradata_size[track->last_stsd_index])
2315 avio_write(pb, track->extradata[track->last_stsd_index], track->extradata_size[track->last_stsd_index]);
2316
2317 if (mov->write_btrt &&
2318 ((ret = mov_write_btrt_tag(pb, track)) < 0))
2319 return ret;
2320
2321 return update_size(pb, pos);
2322}
2323
2325{
2326 int8_t stereo_mode;
2327
2328 if (stereo_3d->flags != 0) {
2329 av_log(s, AV_LOG_WARNING, "Unsupported stereo_3d flags %x. st3d not written.\n", stereo_3d->flags);
2330 return 0;
2331 }
2332
2333 switch (stereo_3d->type) {
2334 case AV_STEREO3D_2D:
2335 stereo_mode = 0;
2336 break;
2338 stereo_mode = 1;
2339 break;
2341 stereo_mode = 2;
2342 break;
2343 default:
2344 av_log(s, AV_LOG_WARNING, "Unsupported stereo_3d type %s. st3d not written.\n", av_stereo3d_type_name(stereo_3d->type));
2345 return 0;
2346 }
2347 avio_wb32(pb, 13); /* size */
2348 ffio_wfourcc(pb, "st3d");
2349 avio_wb32(pb, 0); /* version = 0 & flags = 0 */
2350 avio_w8(pb, stereo_mode);
2351 return 13;
2352}
2353
2355{
2356 int64_t sv3d_pos, svhd_pos, proj_pos;
2357 const char* metadata_source = s->flags & AVFMT_FLAG_BITEXACT ? "Lavf" : LIBAVFORMAT_IDENT;
2358
2359 if (spherical_mapping->projection != AV_SPHERICAL_EQUIRECTANGULAR &&
2360 spherical_mapping->projection != AV_SPHERICAL_EQUIRECTANGULAR_TILE &&
2361 spherical_mapping->projection != AV_SPHERICAL_CUBEMAP) {
2362 av_log(s, AV_LOG_WARNING, "Unsupported projection %d. sv3d not written.\n", spherical_mapping->projection);
2363 return 0;
2364 }
2365
2366 sv3d_pos = avio_tell(pb);
2367 avio_wb32(pb, 0); /* size */
2368 ffio_wfourcc(pb, "sv3d");
2369
2370 svhd_pos = avio_tell(pb);
2371 avio_wb32(pb, 0); /* size */
2372 ffio_wfourcc(pb, "svhd");
2373 avio_wb32(pb, 0); /* version = 0 & flags = 0 */
2374 avio_put_str(pb, metadata_source);
2375 update_size(pb, svhd_pos);
2376
2377 proj_pos = avio_tell(pb);
2378 avio_wb32(pb, 0); /* size */
2379 ffio_wfourcc(pb, "proj");
2380
2381 avio_wb32(pb, 24); /* size */
2382 ffio_wfourcc(pb, "prhd");
2383 avio_wb32(pb, 0); /* version = 0 & flags = 0 */
2384 avio_wb32(pb, spherical_mapping->yaw);
2385 avio_wb32(pb, spherical_mapping->pitch);
2386 avio_wb32(pb, spherical_mapping->roll);
2387
2388 switch (spherical_mapping->projection) {
2391 avio_wb32(pb, 28); /* size */
2392 ffio_wfourcc(pb, "equi");
2393 avio_wb32(pb, 0); /* version = 0 & flags = 0 */
2394 avio_wb32(pb, spherical_mapping->bound_top);
2395 avio_wb32(pb, spherical_mapping->bound_bottom);
2396 avio_wb32(pb, spherical_mapping->bound_left);
2397 avio_wb32(pb, spherical_mapping->bound_right);
2398 break;
2400 avio_wb32(pb, 20); /* size */
2401 ffio_wfourcc(pb, "cbmp");
2402 avio_wb32(pb, 0); /* version = 0 & flags = 0 */
2403 avio_wb32(pb, 0); /* layout */
2404 avio_wb32(pb, spherical_mapping->padding); /* padding */
2405 break;
2406 }
2407 update_size(pb, proj_pos);
2408
2409 return update_size(pb, sv3d_pos);
2410}
2411
2413{
2414 return av_rescale(q.num, b, q.den);
2415}
2416
2418 const AVStereo3D *stereo3d)
2419{
2420 if (!stereo3d->horizontal_field_of_view.num)
2421 return;
2422
2423 avio_wb32(pb, 12); /* size */
2424 ffio_wfourcc(pb, "hfov");
2426}
2427
2429 const AVSphericalMapping *spherical_mapping)
2430{
2431 avio_wb32(pb, 24); /* size */
2432 ffio_wfourcc(pb, "proj");
2433 avio_wb32(pb, 16); /* size */
2434 ffio_wfourcc(pb, "prji");
2435 avio_wb32(pb, 0); /* version + flags */
2436
2437 switch (spherical_mapping->projection) {
2439 ffio_wfourcc(pb, "rect");
2440 break;
2442 ffio_wfourcc(pb, "equi");
2443 break;
2445 ffio_wfourcc(pb, "hequ");
2446 break;
2448 ffio_wfourcc(pb, "fish");
2449 break;
2450 default:
2451 av_assert0(0);
2452 }
2453}
2454
2456 const AVStereo3D *stereo3d)
2457{
2458 int64_t pos = avio_tell(pb);
2459 int view = 0;
2460
2461 avio_wb32(pb, 0); /* size */
2462 ffio_wfourcc(pb, "eyes");
2463
2464 // stri is mandatory
2465 avio_wb32(pb, 13); /* size */
2466 ffio_wfourcc(pb, "stri");
2467 avio_wb32(pb, 0); /* version + flags */
2468 switch (stereo3d->view) {
2470 view |= 1 << 0;
2471 break;
2473 view |= 1 << 1;
2474 break;
2476 view |= (1 << 0) | (1 << 1);
2477 break;
2478 }
2479 view |= !!(stereo3d->flags & AV_STEREO3D_FLAG_INVERT) << 3;
2480 avio_w8(pb, view);
2481
2482 // hero is optional
2483 if (stereo3d->primary_eye != AV_PRIMARY_EYE_NONE) {
2484 avio_wb32(pb, 13); /* size */
2485 ffio_wfourcc(pb, "hero");
2486 avio_wb32(pb, 0); /* version + flags */
2487 avio_w8(pb, stereo3d->primary_eye);
2488 }
2489
2490 // it's not clear if cams is mandatory or optional
2491 if (stereo3d->baseline) {
2492 avio_wb32(pb, 24); /* size */
2493 ffio_wfourcc(pb, "cams");
2494 avio_wb32(pb, 16); /* size */
2495 ffio_wfourcc(pb, "blin");
2496 avio_wb32(pb, 0); /* version + flags */
2497 avio_wb32(pb, stereo3d->baseline);
2498 }
2499
2500 // it's not clear if cmfy is mandatory or optional
2501 if (stereo3d->horizontal_disparity_adjustment.num) {
2502 avio_wb32(pb, 24); /* size */
2503 ffio_wfourcc(pb, "cmfy");
2504 avio_wb32(pb, 16); /* size */
2505 ffio_wfourcc(pb, "dadj");
2506 avio_wb32(pb, 0); /* version + flags */
2508 }
2509
2510 return update_size(pb, pos);
2511}
2512
2514 const AVStereo3D *stereo3d,
2515 const AVSphericalMapping *spherical_mapping)
2516{
2517 int64_t pos;
2518
2519 if (spherical_mapping &&
2520 spherical_mapping->projection != AV_SPHERICAL_RECTILINEAR &&
2521 spherical_mapping->projection != AV_SPHERICAL_EQUIRECTANGULAR &&
2522 spherical_mapping->projection != AV_SPHERICAL_HALF_EQUIRECTANGULAR &&
2523 spherical_mapping->projection != AV_SPHERICAL_FISHEYE) {
2524 av_log(s, AV_LOG_WARNING, "Unsupported projection %d. proj not written.\n",
2525 spherical_mapping->projection);
2526 spherical_mapping = NULL;
2527 }
2528
2529 if (stereo3d && (stereo3d->type == AV_STEREO3D_2D ||
2530 (!(stereo3d->flags & AV_STEREO3D_FLAG_INVERT) &&
2531 stereo3d->view == AV_STEREO3D_VIEW_UNSPEC &&
2532 stereo3d->primary_eye == AV_PRIMARY_EYE_NONE &&
2533 !stereo3d->baseline &&
2534 !stereo3d->horizontal_disparity_adjustment.num))) {
2535 av_log(s, AV_LOG_WARNING, "Unsupported stereo 3d metadata. eyes not written.\n");
2536 stereo3d = NULL;
2537 }
2538
2539 if (!spherical_mapping && !stereo3d)
2540 return 0;
2541
2542 pos = avio_tell(pb);
2543 avio_wb32(pb, 0); /* size */
2544 ffio_wfourcc(pb, "vexu");
2545
2546 if (spherical_mapping)
2547 mov_write_vexu_proj_tag(s, pb, spherical_mapping);
2548
2549 if (stereo3d)
2550 mov_write_eyes_tag(s, pb, stereo3d);
2551
2552 return update_size(pb, pos);
2553}
2554
2556{
2557 uint8_t buf[ISOM_DVCC_DVVC_SIZE];
2558
2559 avio_wb32(pb, 32); /* size = 8 + 24 */
2560 if (dovi->dv_profile > 10)
2561 ffio_wfourcc(pb, "dvwC");
2562 else if (dovi->dv_profile > 7)
2563 ffio_wfourcc(pb, "dvvC");
2564 else
2565 ffio_wfourcc(pb, "dvcC");
2566
2567 ff_isom_put_dvcc_dvvc(s, buf, dovi);
2568 avio_write(pb, buf, sizeof(buf));
2569
2570 return 32; /* 8 + 24 */
2571}
2572
2574{
2575 avio_wb32(pb, 8 + sd->size);
2576 ffio_wfourcc(pb, "hvcE");
2577 avio_write(pb, sd->data, sd->size);
2578 return 8 + sd->size;
2579}
2580
2582 uint32_t top, uint32_t bottom,
2583 uint32_t left, uint32_t right)
2584{
2585 uint32_t cropped_width = track->par->width - left - right;
2586 uint32_t cropped_height = track->height - top - bottom;
2587 AVRational horizOff =
2588 av_sub_q((AVRational) { track->par->width - cropped_width, 2 },
2589 (AVRational) { left, 1 });
2590 AVRational vertOff =
2591 av_sub_q((AVRational) { track->height - cropped_height, 2 },
2592 (AVRational) { top, 1 });
2593
2594 avio_wb32(pb, 40);
2595 ffio_wfourcc(pb, "clap");
2596 avio_wb32(pb, cropped_width); /* apertureWidthN */
2597 avio_wb32(pb, 1); /* apertureWidthD */
2598 avio_wb32(pb, cropped_height); /* apertureHeightN */
2599 avio_wb32(pb, 1); /* apertureHeightD */
2600
2601 avio_wb32(pb, -horizOff.num);
2602 avio_wb32(pb, horizOff.den);
2603 avio_wb32(pb, -vertOff.num);
2604 avio_wb32(pb, vertOff.den);
2605
2606 return 40;
2607}
2608
2610{
2611 AVRational sar;
2612 av_reduce(&sar.num, &sar.den, track->par->sample_aspect_ratio.num,
2613 track->par->sample_aspect_ratio.den, INT_MAX);
2614
2615 avio_wb32(pb, 16);
2616 ffio_wfourcc(pb, "pasp");
2617 avio_wb32(pb, sar.num);
2618 avio_wb32(pb, sar.den);
2619 return 16;
2620}
2621
2622static int mov_write_gama_tag(AVFormatContext *s, AVIOContext *pb, MOVTrack *track, double gamma)
2623{
2624 uint32_t gama = 0;
2625 if (gamma <= 0.0)
2627 av_log(s, AV_LOG_DEBUG, "gamma value %g\n", gamma);
2628
2629 if (gamma > 1e-6) {
2630 gama = (uint32_t)lrint((double)(1<<16) * gamma);
2631 av_log(s, AV_LOG_DEBUG, "writing gama value %"PRId32"\n", gama);
2632
2633 av_assert0(track->mode == MODE_MOV);
2634 avio_wb32(pb, 12);
2635 ffio_wfourcc(pb, "gama");
2636 avio_wb32(pb, gama);
2637 return 12;
2638 } else {
2639 av_log(s, AV_LOG_WARNING, "gamma value unknown, unable to write gama atom\n");
2640 }
2641 return 0;
2642}
2643
2644static int mov_write_colr_tag(AVIOContext *pb, MOVTrack *track, int prefer_icc)
2645{
2646 int64_t pos = avio_tell(pb);
2647
2648 // Ref (MOV): https://developer.apple.com/library/mac/technotes/tn2162/_index.html#//apple_ref/doc/uid/DTS40013070-CH1-TNTAG9
2649 // Ref (MP4): ISO/IEC 14496-12:2012
2650
2651 if (prefer_icc) {
2655
2656 if (sd) {
2657 avio_wb32(pb, 12 + sd->size);
2658 ffio_wfourcc(pb, "colr");
2659 ffio_wfourcc(pb, "prof");
2660 avio_write(pb, sd->data, sd->size);
2661 return 12 + sd->size;
2662 }
2663 else {
2664 av_log(NULL, AV_LOG_INFO, "no ICC profile found, will write nclx/nclc colour info instead\n");
2665 }
2666 }
2667
2668 /* We should only ever be called for MOV, MP4 and AVIF. */
2669 av_assert0(track->mode == MODE_MOV || track->mode == MODE_MP4 ||
2670 track->mode == MODE_AVIF);
2671
2672 avio_wb32(pb, 0); /* size */
2673 ffio_wfourcc(pb, "colr");
2674 if (track->mode == MODE_MP4 || track->mode == MODE_AVIF)
2675 ffio_wfourcc(pb, "nclx");
2676 else
2677 ffio_wfourcc(pb, "nclc");
2678 // Do not try to guess the color info if it is AVCOL_PRI_UNSPECIFIED.
2679 // e.g., Dolby Vision for Apple devices should be set to AVCOL_PRI_UNSPECIFIED. See
2680 // https://developer.apple.com/av-foundation/High-Dynamic-Range-Metadata-for-Apple-Devices.pdf
2681 avio_wb16(pb, track->par->color_primaries);
2682 avio_wb16(pb, track->par->color_trc);
2683 avio_wb16(pb, track->par->color_space);
2684 if (track->mode == MODE_MP4 || track->mode == MODE_AVIF) {
2685 int full_range = track->par->color_range == AVCOL_RANGE_JPEG;
2686 avio_w8(pb, full_range << 7);
2687 }
2688
2689 return update_size(pb, pos);
2690}
2691
2693{
2694 const AVPacketSideData *side_data;
2695 const AVContentLightMetadata *content_light_metadata;
2696
2700 if (!side_data) {
2701 return 0;
2702 }
2703 content_light_metadata = (const AVContentLightMetadata*)side_data->data;
2704
2705 avio_wb32(pb, 12); // size
2706 ffio_wfourcc(pb, "clli");
2707 avio_wb16(pb, content_light_metadata->MaxCLL);
2708 avio_wb16(pb, content_light_metadata->MaxFALL);
2709 return 12;
2710}
2711
2713{
2714 const int chroma_den = 50000;
2715 const int luma_den = 10000;
2716 const AVPacketSideData *side_data;
2718
2722 if (side_data)
2723 metadata = (const AVMasteringDisplayMetadata*)side_data->data;
2724 if (!metadata || !metadata->has_primaries || !metadata->has_luminance) {
2725 return 0;
2726 }
2727
2728 avio_wb32(pb, 32); // size
2729 ffio_wfourcc(pb, "mdcv");
2730 avio_wb16(pb, rescale_rational(metadata->display_primaries[1][0], chroma_den));
2731 avio_wb16(pb, rescale_rational(metadata->display_primaries[1][1], chroma_den));
2732 avio_wb16(pb, rescale_rational(metadata->display_primaries[2][0], chroma_den));
2733 avio_wb16(pb, rescale_rational(metadata->display_primaries[2][1], chroma_den));
2734 avio_wb16(pb, rescale_rational(metadata->display_primaries[0][0], chroma_den));
2735 avio_wb16(pb, rescale_rational(metadata->display_primaries[0][1], chroma_den));
2736 avio_wb16(pb, rescale_rational(metadata->white_point[0], chroma_den));
2737 avio_wb16(pb, rescale_rational(metadata->white_point[1], chroma_den));
2738 avio_wb32(pb, rescale_rational(metadata->max_luminance, luma_den));
2739 avio_wb32(pb, rescale_rational(metadata->min_luminance, luma_den));
2740 return 32;
2741}
2742
2744{
2745 const int illuminance_den = 10000;
2746 const int ambient_den = 50000;
2747 const AVPacketSideData *side_data;
2748 const AVAmbientViewingEnvironment *ambient;
2749
2750
2754
2755 if (!side_data)
2756 return 0;
2757
2758 ambient = (const AVAmbientViewingEnvironment*)side_data->data;
2759 if (!ambient || !ambient->ambient_illuminance.num)
2760 return 0;
2761
2762 avio_wb32(pb, 16); // size
2763 ffio_wfourcc(pb, "amve");
2764 avio_wb32(pb, rescale_rational(ambient->ambient_illuminance, illuminance_den));
2765 avio_wb16(pb, rescale_rational(ambient->ambient_light_x, ambient_den));
2766 avio_wb16(pb, rescale_rational(ambient->ambient_light_y, ambient_den));
2767 return 16;
2768}
2769
2770static void find_compressor(char * compressor_name, int len, MOVTrack *track)
2771{
2772 AVDictionaryEntry *encoder;
2773 int xdcam_res = (track->par->width == 1280 && track->par->height == 720)
2774 || (track->par->width == 1440 && track->par->height == 1080)
2775 || (track->par->width == 1920 && track->par->height == 1080);
2776
2777 if ((track->mode == MODE_AVIF ||
2778 track->mode == MODE_MOV ||
2779 track->mode == MODE_MP4) &&
2780 (encoder = av_dict_get(track->st->metadata, "encoder", NULL, 0))) {
2781 av_strlcpy(compressor_name, encoder->value, 32);
2782 } else if (track->par->codec_id == AV_CODEC_ID_MPEG2VIDEO && xdcam_res) {
2784 AVStream *st = track->st;
2785 int rate = defined_frame_rate(NULL, st);
2786 av_strlcatf(compressor_name, len, "XDCAM");
2787 if (track->par->format == AV_PIX_FMT_YUV422P) {
2788 av_strlcatf(compressor_name, len, " HD422");
2789 } else if(track->par->width == 1440) {
2790 av_strlcatf(compressor_name, len, " HD");
2791 } else
2792 av_strlcatf(compressor_name, len, " EX");
2793
2794 av_strlcatf(compressor_name, len, " %d%c", track->par->height, interlaced ? 'i' : 'p');
2795
2796 av_strlcatf(compressor_name, len, "%d", rate * (interlaced + 1));
2797 }
2798}
2799
2801{
2802 int64_t pos = avio_tell(pb);
2803 // Write sane defaults:
2804 // all_ref_pics_intra = 0 : all samples can use any type of reference.
2805 // intra_pred_used = 1 : intra prediction may or may not be used.
2806 // max_ref_per_pic = 15 : reserved value to indicate that any number of
2807 // reference images can be used.
2808 uint8_t ccstValue = (0 << 7) | /* all_ref_pics_intra */
2809 (1 << 6) | /* intra_pred_used */
2810 (15 << 2); /* max_ref_per_pic */
2811 avio_wb32(pb, 0); /* size */
2812 ffio_wfourcc(pb, "ccst");
2813 avio_wb32(pb, 0); /* Version & flags */
2814 avio_w8(pb, ccstValue);
2815 avio_wb24(pb, 0); /* reserved */
2816 return update_size(pb, pos);
2817}
2818
2819static int mov_write_aux_tag(AVIOContext *pb, const char *aux_type)
2820{
2821 int64_t pos = avio_tell(pb);
2822 avio_wb32(pb, 0); /* size */
2823 ffio_wfourcc(pb, aux_type);
2824 avio_wb32(pb, 0); /* Version & flags */
2825 avio_write(pb, "urn:mpeg:mpegB:cicp:systems:auxiliary:alpha\0", 44);
2826 return update_size(pb, pos);
2827}
2828
2830{
2831 int ret = AVERROR_BUG;
2832 int64_t pos = avio_tell(pb);
2833 const AVPacketSideData *sd;
2834 char compressor_name[32] = { 0 };
2835 int avid = 0;
2836
2837 int uncompressed_ycbcr = ((track->par->codec_id == AV_CODEC_ID_RAWVIDEO && track->par->format == AV_PIX_FMT_UYVY422)
2838 || (track->par->codec_id == AV_CODEC_ID_RAWVIDEO && track->par->format == AV_PIX_FMT_YUYV422)
2839 || (track->par->codec_id == AV_CODEC_ID_RAWVIDEO && track->par->format == AV_PIX_FMT_VYU444)
2840 || (track->par->codec_id == AV_CODEC_ID_RAWVIDEO && track->par->format == AV_PIX_FMT_UYVA)
2841 || (track->par->codec_id == AV_CODEC_ID_RAWVIDEO && track->par->format == AV_PIX_FMT_V30XLE)
2842 || track->par->codec_id == AV_CODEC_ID_V210);
2843
2844 avio_wb32(pb, 0); /* size */
2845 if (mov->encryption_scheme != MOV_ENC_NONE) {
2846 ffio_wfourcc(pb, "encv");
2847 } else {
2848 avio_wl32(pb, track->tag); // store it byteswapped
2849 }
2850 avio_wb32(pb, 0); /* Reserved */
2851 avio_wb16(pb, 0); /* Reserved */
2852 avio_wb16(pb, 1); /* Data-reference index */
2853
2854 if (uncompressed_ycbcr) {
2855 avio_wb16(pb, 2); /* Codec stream version */
2856 } else {
2857 avio_wb16(pb, 0); /* Codec stream version */
2858 }
2859 avio_wb16(pb, 0); /* Codec stream revision (=0) */
2860 if (track->mode == MODE_MOV) {
2861 ffio_wfourcc(pb, "FFMP"); /* Vendor */
2862 if (track->par->codec_id == AV_CODEC_ID_RAWVIDEO || uncompressed_ycbcr) {
2863 avio_wb32(pb, 0); /* Temporal Quality */
2864 avio_wb32(pb, 0x400); /* Spatial Quality = lossless*/
2865 } else {
2866 avio_wb32(pb, 0x200); /* Temporal Quality = normal */
2867 avio_wb32(pb, 0x200); /* Spatial Quality = normal */
2868 }
2869 } else {
2870 ffio_fill(pb, 0, 3 * 4); /* Reserved */
2871 }
2872 avio_wb16(pb, track->par->width); /* Video width */
2873 avio_wb16(pb, track->height); /* Video height */
2874 avio_wb32(pb, 0x00480000); /* Horizontal resolution 72dpi */
2875 avio_wb32(pb, 0x00480000); /* Vertical resolution 72dpi */
2876 avio_wb32(pb, 0); /* Data size (= 0) */
2877 avio_wb16(pb, 1); /* Frame count (= 1) */
2878
2879 find_compressor(compressor_name, 32, track);
2880 avio_w8(pb, strlen(compressor_name));
2881 avio_write(pb, compressor_name, 31);
2882
2883 if (track->mode == MODE_MOV && track->par->codec_id == AV_CODEC_ID_V210)
2884 avio_wb16(pb, 0x18);
2885 else if (track->mode == MODE_MOV && track->par->bits_per_coded_sample)
2886 avio_wb16(pb, track->par->bits_per_coded_sample |
2887 (track->par->format == AV_PIX_FMT_GRAY8 ? 0x20 : 0));
2888 else
2889 avio_wb16(pb, 0x18); /* Reserved */
2890
2891 if (track->mode == MODE_MOV && track->par->format == AV_PIX_FMT_PAL8) {
2892 int pal_size, i;
2893 avio_wb16(pb, 0); /* Color table ID */
2894 avio_wb32(pb, 0); /* Color table seed */
2895 avio_wb16(pb, 0x8000); /* Color table flags */
2896 if (track->par->bits_per_coded_sample < 0 || track->par->bits_per_coded_sample > 8)
2897 return AVERROR(EINVAL);
2898 pal_size = 1 << track->par->bits_per_coded_sample;
2899 avio_wb16(pb, pal_size - 1); /* Color table size (zero-relative) */
2900 for (i = 0; i < pal_size; i++) {
2901 uint32_t rgb = track->palette[i];
2902 uint16_t r = (rgb >> 16) & 0xff;
2903 uint16_t g = (rgb >> 8) & 0xff;
2904 uint16_t b = rgb & 0xff;
2905 avio_wb16(pb, 0);
2906 avio_wb16(pb, (r << 8) | r);
2907 avio_wb16(pb, (g << 8) | g);
2908 avio_wb16(pb, (b << 8) | b);
2909 }
2910 } else
2911 avio_wb16(pb, 0xffff); /* Reserved */
2912
2913 if (track->tag == MKTAG('m','p','4','v'))
2914 mov_write_esds_tag(pb, track);
2915 else if (track->par->codec_id == AV_CODEC_ID_H263)
2917 else if (track->par->codec_id == AV_CODEC_ID_AVUI ||
2918 track->par->codec_id == AV_CODEC_ID_SVQ3) {
2919 mov_write_extradata_tag(pb, track);
2920 avio_wb32(pb, 0);
2921 } else if (track->par->codec_id == AV_CODEC_ID_DNXHD) {
2922 mov_write_avid_tag(pb, track);
2923 avid = 1;
2924 } else if (track->par->codec_id == AV_CODEC_ID_HEVC) {
2925 mov_write_hvcc_tag(mov->fc, pb, track);
2927 ret = mov_write_lhvc_tag(mov->fc, pb, track);
2928 if (ret < 0)
2929 av_log(mov->fc, AV_LOG_WARNING, "Not writing 'lhvC' atom for multilayer stream.\n");
2930 }
2931 } else if (track->par->codec_id == AV_CODEC_ID_VVC)
2932 mov_write_vvcc_tag(pb, track);
2933 else if (track->par->codec_id == AV_CODEC_ID_H264 && !TAG_IS_AVCI(track->tag)) {
2934 mov_write_avcc_tag(pb, track);
2935 if (track->mode == MODE_IPOD)
2937 }
2938 else if (track->par->codec_id ==AV_CODEC_ID_EVC) {
2939 mov_write_evcc_tag(pb, track);
2940 } else if (track->par->codec_id == AV_CODEC_ID_LCEVC) {
2941 mov_write_lvcc_tag(mov->fc, pb, track);
2942 } else if (track->par->codec_id ==AV_CODEC_ID_APV) {
2943 mov_write_apvc_tag(mov->fc, pb, track);
2944 } else if (track->par->codec_id == AV_CODEC_ID_VP9) {
2945 mov_write_vpcc_tag(mov->fc, pb, track);
2946 } else if (track->par->codec_id == AV_CODEC_ID_AV1) {
2947 mov_write_av1c_tag(pb, track);
2948 } else if (track->par->codec_id == AV_CODEC_ID_VC1 && track->extradata_size[track->last_stsd_index] > 0)
2949 mov_write_dvc1_tag(pb, track);
2950 else if (track->par->codec_id == AV_CODEC_ID_VP6F ||
2951 track->par->codec_id == AV_CODEC_ID_VP6A) {
2952 /* Don't write any potential extradata here - the cropping
2953 * is signalled via the normal width/height fields. */
2954 } else if (track->par->codec_id == AV_CODEC_ID_R10K) {
2955 if (track->par->codec_tag == MKTAG('R','1','0','k'))
2956 mov_write_dpxe_tag(pb, track);
2957 } else if (track->par->codec_id == AV_CODEC_ID_AVS3) {
2958 mov_write_av3c_tag(pb, track);
2959 } else if (track->extradata_size[track->last_stsd_index] > 0)
2960 mov_write_glbl_tag(pb, track);
2961
2962 if (track->par->codec_id != AV_CODEC_ID_H264 &&
2963 track->par->codec_id != AV_CODEC_ID_MPEG4 &&
2964 track->par->codec_id != AV_CODEC_ID_DNXHD) {
2965 int field_order = track->par->field_order;
2966
2967 if (field_order != AV_FIELD_UNKNOWN)
2968 mov_write_fiel_tag(pb, track, field_order);
2969 }
2970
2971 if (mov->flags & FF_MOV_FLAG_WRITE_GAMA) {
2972 if (track->mode == MODE_MOV)
2973 mov_write_gama_tag(s, pb, track, mov->gamma);
2974 else
2975 av_log(mov->fc, AV_LOG_WARNING, "Not writing 'gama' atom. Format is not MOV.\n");
2976 }
2977 if (track->mode == MODE_MOV || track->mode == MODE_MP4 || track->mode == MODE_AVIF) {
2978 int has_color_info = track->par->color_primaries != AVCOL_PRI_UNSPECIFIED &&
2979 track->par->color_trc != AVCOL_TRC_UNSPECIFIED &&
2981 if (has_color_info || mov->flags & FF_MOV_FLAG_WRITE_COLR ||
2984 int prefer_icc = mov->flags & FF_MOV_FLAG_PREFER_ICC || !has_color_info;
2985 mov_write_colr_tag(pb, track, prefer_icc);
2986 }
2987 } else if (mov->flags & FF_MOV_FLAG_WRITE_COLR) {
2988 av_log(mov->fc, AV_LOG_WARNING, "Not writing 'colr' atom. Format is not MOV or MP4 or AVIF.\n");
2989 }
2990
2991 if (track->mode == MODE_MOV || track->mode == MODE_MP4) {
2992 mov_write_clli_tag(pb, track);
2993 mov_write_mdcv_tag(pb, track);
2994 mov_write_amve_tag(pb, track);
2995 }
2996
3001 const AVPacketSideData *spherical_mapping = av_packet_side_data_get(track->st->codecpar->coded_side_data,
3004 if (stereo_3d)
3005 mov_write_st3d_tag(s, pb, (AVStereo3D*)stereo_3d->data);
3006 if (spherical_mapping)
3007 mov_write_sv3d_tag(mov->fc, pb, (AVSphericalMapping*)spherical_mapping->data);
3008 }
3009
3010 if (track->mode == MODE_MOV || (track->mode == MODE_MP4 &&
3012 const AVStereo3D *stereo3d = NULL;
3013 const AVSphericalMapping *spherical_mapping = NULL;
3014
3018 if (sd)
3019 stereo3d = (AVStereo3D *)sd->data;
3020
3024 if (sd)
3025 spherical_mapping = (AVSphericalMapping *)sd->data;
3026
3027 if (stereo3d || spherical_mapping)
3028 mov_write_vexu_tag(s, pb, stereo3d, spherical_mapping);
3029 if (stereo3d)
3030 mov_write_hfov_tag(s, pb, stereo3d);
3031 }
3032
3033 if (track->mode == MODE_MP4) {
3037 if (dovi && mov->fc->strict_std_compliance <= FF_COMPLIANCE_UNOFFICIAL) {
3039 } else if (dovi) {
3040 av_log(mov->fc, AV_LOG_WARNING, "Not writing 'dvcC'/'dvvC' box. Requires -strict unofficial.\n");
3041 }
3042
3046 if (hvce && mov->fc->strict_std_compliance <= FF_COMPLIANCE_UNOFFICIAL) {
3047 mov_write_hvce_tag(pb, hvce);
3048 } else if (hvce) {
3049 av_log(mov->fc, AV_LOG_WARNING, "Not writing 'hvcE' box. Requires -strict unofficial.\n");
3050 }
3051 }
3052
3053 if (track->par->sample_aspect_ratio.den && track->par->sample_aspect_ratio.num) {
3054 mov_write_pasp_tag(pb, track);
3055 }
3056
3060 if (sd && sd->size >= sizeof(uint32_t) * 4) {
3061 uint64_t top = AV_RL32(sd->data + 0);
3062 uint64_t bottom = AV_RL32(sd->data + 4);
3063 uint64_t left = AV_RL32(sd->data + 8);
3064 uint64_t right = AV_RL32(sd->data + 12);
3065
3066 if ((left + right) >= track->par->width ||
3067 (top + bottom) >= track->height) {
3068 av_log(s, AV_LOG_ERROR, "Invalid cropping dimensions in stream side data\n");
3069 return AVERROR(EINVAL);
3070 }
3071 if (top || bottom || left || right)
3072 mov_write_clap_tag(pb, track, top, bottom, left, right);
3073 } else if (uncompressed_ycbcr)
3074 mov_write_clap_tag(pb, track, 0, 0, 0, 0);
3075
3076 if (mov->encryption_scheme != MOV_ENC_NONE) {
3078 }
3079
3080 if (mov->write_btrt &&
3081 ((ret = mov_write_btrt_tag(pb, track)) < 0))
3082 return ret;
3083
3084 /* extra padding for avid stsd */
3085 /* https://developer.apple.com/library/mac/documentation/QuickTime/QTFF/QTFFChap2/qtff2.html#//apple_ref/doc/uid/TP40000939-CH204-61112 */
3086 if (avid)
3087 avio_wb32(pb, 0);
3088
3089 if (track->mode == MODE_AVIF) {
3091 if (mov->nb_streams > 0 && track == &mov->tracks[1])
3092 mov_write_aux_tag(pb, "auxi");
3093 }
3094
3095 return update_size(pb, pos);
3096}
3097
3099{
3100 int64_t pos = avio_tell(pb);
3101 avio_wb32(pb, 0); /* size */
3102 ffio_wfourcc(pb, "rtp ");
3103 avio_wb32(pb, 0); /* Reserved */
3104 avio_wb16(pb, 0); /* Reserved */
3105 avio_wb16(pb, 1); /* Data-reference index */
3106
3107 avio_wb16(pb, 1); /* Hint track version */
3108 avio_wb16(pb, 1); /* Highest compatible version */
3109 avio_wb32(pb, track->max_packet_size); /* Max packet size */
3110
3111 avio_wb32(pb, 12); /* size */
3112 ffio_wfourcc(pb, "tims");
3113 avio_wb32(pb, track->timescale);
3114
3115 return update_size(pb, pos);
3116}
3117
3118static int mov_write_source_reference_tag(AVIOContext *pb, MOVTrack *track, const char *reel_name)
3119{
3120 uint64_t str_size =strlen(reel_name);
3121 int64_t pos = avio_tell(pb);
3122
3123 if (str_size >= UINT16_MAX){
3124 av_log(NULL, AV_LOG_ERROR, "reel_name length %"PRIu64" is too large\n", str_size);
3125 avio_wb16(pb, 0);
3126 return AVERROR(EINVAL);
3127 }
3128
3129 avio_wb32(pb, 0); /* size */
3130 ffio_wfourcc(pb, "name"); /* Data format */
3131 avio_wb16(pb, str_size); /* string size */
3132 avio_wb16(pb, track->language); /* langcode */
3133 avio_write(pb, reel_name, str_size); /* reel name */
3134 return update_size(pb,pos);
3135}
3136
3138{
3139 int64_t pos = avio_tell(pb);
3140#if 1
3141 int frame_duration;
3142 int nb_frames;
3144
3145 if (!track->st->avg_frame_rate.num || !track->st->avg_frame_rate.den) {
3146 av_log(NULL, AV_LOG_ERROR, "avg_frame_rate not set for tmcd track.\n");
3147 return AVERROR(EINVAL);
3148 } else {
3149 frame_duration = av_rescale(track->timescale, track->st->avg_frame_rate.den, track->st->avg_frame_rate.num);
3150 nb_frames = ROUNDED_DIV(track->st->avg_frame_rate.num, track->st->avg_frame_rate.den);
3151 }
3152
3153 if (nb_frames > 255) {
3154 av_log(NULL, AV_LOG_ERROR, "fps %d is too large\n", nb_frames);
3155 return AVERROR(EINVAL);
3156 }
3157
3158 avio_wb32(pb, 0); /* size */
3159 ffio_wfourcc(pb, "tmcd"); /* Data format */
3160 avio_wb32(pb, 0); /* Reserved */
3161 avio_wb32(pb, 1); /* Data reference index */
3162 avio_wb32(pb, 0); /* Flags */
3163 avio_wb32(pb, track->timecode_flags); /* Flags (timecode) */
3164 avio_wb32(pb, track->timescale); /* Timescale */
3165 avio_wb32(pb, frame_duration); /* Frame duration */
3166 avio_w8(pb, nb_frames); /* Number of frames */
3167 avio_w8(pb, 0); /* Reserved */
3168
3169 t = av_dict_get(track->st->metadata, "reel_name", NULL, 0);
3170 if (t && utf8len(t->value) && track->mode != MODE_MP4)
3172 else
3173 avio_wb16(pb, 0); /* zero size */
3174#else
3175
3176 avio_wb32(pb, 0); /* size */
3177 ffio_wfourcc(pb, "tmcd"); /* Data format */
3178 avio_wb32(pb, 0); /* Reserved */
3179 avio_wb32(pb, 1); /* Data reference index */
3180 if (track->par->extradata_size)
3181 avio_write(pb, track->par->extradata, track->par->extradata_size);
3182#endif
3183 return update_size(pb, pos);
3184}
3185
3186static int mov_write_gpmd_tag(AVIOContext *pb, const MOVTrack *track)
3187{
3188 int64_t pos = avio_tell(pb);
3189 avio_wb32(pb, 0); /* size */
3190 ffio_wfourcc(pb, "gpmd");
3191 avio_wb32(pb, 0); /* Reserved */
3192 avio_wb16(pb, 0); /* Reserved */
3193 avio_wb16(pb, 1); /* Data-reference index */
3194 avio_wb32(pb, 0); /* Reserved */
3195 return update_size(pb, pos);
3196}
3197
3199{
3200 int64_t pos = avio_tell(pb);
3201 int ret = 0;
3202 avio_wb32(pb, 0); /* size */
3203 ffio_wfourcc(pb, "stsd");
3204 avio_wb32(pb, 0); /* version & flags */
3205 avio_wb32(pb, track->stsd_count);
3206
3207 int stsd_index_back = track->last_stsd_index;
3208 for (track->last_stsd_index = 0;
3209 track->last_stsd_index < track->stsd_count;
3210 track->last_stsd_index++) {
3211 if (track->par->codec_type == AVMEDIA_TYPE_VIDEO)
3212 ret = mov_write_video_tag(s, pb, mov, track);
3213 else if (track->par->codec_type == AVMEDIA_TYPE_AUDIO)
3214 ret = mov_write_audio_tag(s, pb, mov, track);
3215 else if (track->par->codec_type == AVMEDIA_TYPE_SUBTITLE)
3216 ret = mov_write_subtitle_tag(s, pb, track);
3217 else if (track->par->codec_tag == MKTAG('r','t','p',' '))
3218 ret = mov_write_rtp_tag(pb, track);
3219 else if (track->par->codec_tag == MKTAG('t','m','c','d'))
3220 ret = mov_write_tmcd_tag(pb, track);
3221 else if (track->par->codec_tag == MKTAG('g','p','m','d'))
3222 ret = mov_write_gpmd_tag(pb, track);
3223
3224 if (ret < 0)
3225 return ret;
3226 }
3227
3228 track->last_stsd_index = stsd_index_back;
3229
3230 return update_size_and_version(pb, pos, track->entry_version);
3231}
3232
3234{
3235 MOVMuxContext *mov = s->priv_data;
3236 MOVCtts *ctts_entries;
3237 uint32_t entries = 0;
3238 uint32_t atom_size;
3239 int i;
3240
3241 ctts_entries = av_malloc_array((track->entry + 1), sizeof(*ctts_entries)); /* worst case */
3242 if (!ctts_entries)
3243 return AVERROR(ENOMEM);
3244 ctts_entries[0].count = 1;
3245 ctts_entries[0].offset = track->cluster[0].cts;
3246 for (i = 1; i < track->entry; i++) {
3247 if (track->cluster[i].cts == ctts_entries[entries].offset) {
3248 ctts_entries[entries].count++; /* compress */
3249 } else {
3250 entries++;
3251 ctts_entries[entries].offset = track->cluster[i].cts;
3252 ctts_entries[entries].count = 1;
3253 }
3254 }
3255 entries++; /* last one */
3256 atom_size = 16 + (entries * 8);
3257 avio_wb32(pb, atom_size); /* size */
3258 ffio_wfourcc(pb, "ctts");
3260 avio_w8(pb, 1); /* version */
3261 else
3262 avio_w8(pb, 0); /* version */
3263 avio_wb24(pb, 0); /* flags */
3264 avio_wb32(pb, entries); /* entry count */
3265 for (i = 0; i < entries; i++) {
3266 avio_wb32(pb, ctts_entries[i].count);
3267 avio_wb32(pb, ctts_entries[i].offset);
3268 }
3269 av_free(ctts_entries);
3270 return atom_size;
3271}
3272
3273/* Time to sample atom */
3275{
3276 MOVStts *stts_entries = NULL;
3277 uint32_t entries = -1;
3278 uint32_t atom_size;
3279 int i;
3280
3281 if (track->par->codec_type == AVMEDIA_TYPE_AUDIO && !track->audio_vbr) {
3282 stts_entries = av_malloc(sizeof(*stts_entries)); /* one entry */
3283 if (!stts_entries)
3284 return AVERROR(ENOMEM);
3285 stts_entries[0].count = track->sample_count;
3286 stts_entries[0].duration = 1;
3287 entries = 1;
3288 } else {
3289 if (track->entry) {
3290 stts_entries = av_malloc_array(track->entry, sizeof(*stts_entries)); /* worst case */
3291 if (!stts_entries)
3292 return AVERROR(ENOMEM);
3293 }
3294 for (i = 0; i < track->entry; i++) {
3295 int duration = get_cluster_duration(track, i);
3296#if CONFIG_IAMFENC
3297 if (track->iamf && track->par->codec_id == AV_CODEC_ID_OPUS)
3298 duration = av_rescale(duration, 48000, track->par->sample_rate);
3299#endif
3300 if (i && duration == stts_entries[entries].duration) {
3301 stts_entries[entries].count++; /* compress */
3302 } else {
3303 entries++;
3304 stts_entries[entries].duration = duration;
3305 stts_entries[entries].count = 1;
3306 }
3307 }
3308 entries++; /* last one */
3309 }
3310 atom_size = 16 + (entries * 8);
3311 avio_wb32(pb, atom_size); /* size */
3312 ffio_wfourcc(pb, "stts");
3313 avio_wb32(pb, 0); /* version & flags */
3314 avio_wb32(pb, entries); /* entry count */
3315 for (i = 0; i < entries; i++) {
3316 avio_wb32(pb, stts_entries[i].count);
3317 avio_wb32(pb, stts_entries[i].duration);
3318 }
3319 av_free(stts_entries);
3320 return atom_size;
3321}
3322
3324{
3325 avio_wb32(pb, 28); /* size */
3326 ffio_wfourcc(pb, "dref");
3327 avio_wb32(pb, 0); /* version & flags */
3328 avio_wb32(pb, 1); /* entry count */
3329
3330 avio_wb32(pb, 0xc); /* size */
3331 //FIXME add the alis and rsrc atom
3332 ffio_wfourcc(pb, "url ");
3333 avio_wb32(pb, 1); /* version & flags */
3334
3335 return 28;
3336}
3337
3339{
3340 struct sgpd_entry {
3341 int count;
3342 int16_t roll_distance;
3343 int group_description_index;
3344 };
3345
3346 struct sgpd_entry *sgpd_entries = NULL;
3347 int entries = -1;
3348 int group = 0;
3349 int i, j;
3350
3351 const int OPUS_SEEK_PREROLL_MS = 80;
3352 int roll_samples = av_rescale_q(OPUS_SEEK_PREROLL_MS,
3353 (AVRational){1, 1000},
3354 (AVRational){1, 48000});
3355
3356 if (!track->entry)
3357 return 0;
3358
3359 sgpd_entries = av_malloc_array(track->entry, sizeof(*sgpd_entries));
3360 if (!sgpd_entries)
3361 return AVERROR(ENOMEM);
3362
3364
3365 if (track->par->codec_id == AV_CODEC_ID_OPUS) {
3366 for (i = 0; i < track->entry; i++) {
3367 int roll_samples_remaining = roll_samples;
3368 int distance = 0;
3369 for (j = i - 1; j >= 0; j--) {
3370 roll_samples_remaining -= get_cluster_duration(track, j);
3371 distance++;
3372 if (roll_samples_remaining <= 0)
3373 break;
3374 }
3375 /* We don't have enough preceding samples to compute a valid
3376 roll_distance here, so this sample can't be independently
3377 decoded. */
3378 if (roll_samples_remaining > 0)
3379 distance = 0;
3380 /* Verify distance is a maximum of 32 (2.5ms) packets. */
3381 if (distance > 32) {
3382 av_freep(&sgpd_entries);
3383 return AVERROR_INVALIDDATA;
3384 }
3385 if (i && distance == sgpd_entries[entries].roll_distance) {
3386 sgpd_entries[entries].count++;
3387 } else {
3388 entries++;
3389 sgpd_entries[entries].count = 1;
3390 sgpd_entries[entries].roll_distance = distance;
3391 sgpd_entries[entries].group_description_index = distance ? ++group : 0;
3392 }
3393 }
3394 } else {
3395 entries++;
3396 sgpd_entries[entries].count = track->sample_count;
3397 sgpd_entries[entries].roll_distance = 1;
3398 sgpd_entries[entries].group_description_index = ++group;
3399 }
3400 entries++;
3401
3402 if (!group) {
3403 av_free(sgpd_entries);
3404 return 0;
3405 }
3406
3407 /* Write sgpd tag */
3408 avio_wb32(pb, 24 + (group * 2)); /* size */
3409 ffio_wfourcc(pb, "sgpd");
3410 avio_wb32(pb, 1 << 24); /* fullbox */
3411 ffio_wfourcc(pb, "roll");
3412 avio_wb32(pb, 2); /* default_length */
3413 avio_wb32(pb, group); /* entry_count */
3414 for (i = 0; i < entries; i++) {
3415 if (sgpd_entries[i].group_description_index) {
3416 avio_wb16(pb, -sgpd_entries[i].roll_distance); /* roll_distance */
3417 }
3418 }
3419
3420 /* Write sbgp tag */
3421 avio_wb32(pb, 20 + (entries * 8)); /* size */
3422 ffio_wfourcc(pb, "sbgp");
3423 avio_wb32(pb, 0); /* fullbox */
3424 ffio_wfourcc(pb, "roll");
3425 avio_wb32(pb, entries); /* entry_count */
3426 for (i = 0; i < entries; i++) {
3427 avio_wb32(pb, sgpd_entries[i].count); /* sample_count */
3428 avio_wb32(pb, sgpd_entries[i].group_description_index); /* group_description_index */
3429 }
3430
3431 av_free(sgpd_entries);
3432 return 0;
3433}
3434
3436{
3437 int64_t pos = avio_tell(pb);
3438 int ret = 0;
3439
3440 avio_wb32(pb, 0); /* size */
3441 ffio_wfourcc(pb, "stbl");
3442 if ((ret = mov_write_stsd_tag(s, pb, mov, track)) < 0)
3443 return ret;
3444 mov_write_stts_tag(pb, track);
3445 if ((track->par->codec_type == AVMEDIA_TYPE_VIDEO ||
3446 track->par->codec_id == AV_CODEC_ID_TRUEHD ||
3448 (track->par->codec_id == AV_CODEC_ID_AAC && track->par->profile == AV_PROFILE_AAC_USAC) ||
3449 track->par->codec_tag == MKTAG('r','t','p',' ')) &&
3450 track->has_keyframes && track->has_keyframes < track->entry)
3452 if (track->par->codec_type == AVMEDIA_TYPE_VIDEO && track->has_disposable && track->entry)
3453 mov_write_sdtp_tag(pb, track);
3454 if (track->mode == MODE_MOV && track->flags & MOV_TRACK_STPS)
3456 if (track->par->codec_type == AVMEDIA_TYPE_VIDEO &&
3457 track->flags & MOV_TRACK_CTTS && track->entry) {
3458
3459 if ((ret = mov_write_ctts_tag(s, pb, track)) < 0)
3460 return ret;
3461 }
3462 mov_write_stsc_tag(pb, track);
3463 mov_write_stsz_tag(pb, track);
3464 mov_write_stco_tag(pb, track);
3465 if (track->cenc.aes_ctr && !(mov->flags & FF_MOV_FLAG_FRAGMENT)) {
3466 ff_mov_cenc_write_stbl_atoms(&track->cenc, pb, 0);
3467 }
3468 if (track->par->codec_id == AV_CODEC_ID_OPUS || track->par->codec_id == AV_CODEC_ID_AAC) {
3470 }
3471 return update_size(pb, pos);
3472}
3473
3475{
3476 int64_t pos = avio_tell(pb);
3477 avio_wb32(pb, 0); /* size */
3478 ffio_wfourcc(pb, "dinf");
3480 return update_size(pb, pos);
3481}
3482
3484{
3485 avio_wb32(pb, 12);
3486 ffio_wfourcc(pb, "nmhd");
3487 avio_wb32(pb, 0);
3488 return 12;
3489}
3490
3492{
3493 avio_wb32(pb, 12);
3494 ffio_wfourcc(pb, "sthd");
3495 avio_wb32(pb, 0);
3496 return 12;
3497}
3498
3500{
3501 int64_t pos = avio_tell(pb);
3502 const char *font = "Lucida Grande";
3503 avio_wb32(pb, 0); /* size */
3504 ffio_wfourcc(pb, "tcmi"); /* timecode media information atom */
3505 avio_wb32(pb, 0); /* version & flags */
3506 avio_wb16(pb, 0); /* text font */
3507 avio_wb16(pb, 0); /* text face */
3508 avio_wb16(pb, 12); /* text size */
3509 avio_wb16(pb, 0); /* (unknown, not in the QT specs...) */
3510 avio_wb16(pb, 0x0000); /* text color (red) */
3511 avio_wb16(pb, 0x0000); /* text color (green) */
3512 avio_wb16(pb, 0x0000); /* text color (blue) */
3513 avio_wb16(pb, 0xffff); /* background color (red) */
3514 avio_wb16(pb, 0xffff); /* background color (green) */
3515 avio_wb16(pb, 0xffff); /* background color (blue) */
3516 avio_w8(pb, strlen(font)); /* font len (part of the pascal string) */
3517 avio_write(pb, font, strlen(font)); /* font name */
3518 return update_size(pb, pos);
3519}
3520
3522{
3523 int64_t pos = avio_tell(pb);
3524 avio_wb32(pb, 0); /* size */
3525 ffio_wfourcc(pb, "gmhd");
3526 avio_wb32(pb, 0x18); /* gmin size */
3527 ffio_wfourcc(pb, "gmin");/* generic media info */
3528 avio_wb32(pb, 0); /* version & flags */
3529 avio_wb16(pb, 0x40); /* graphics mode = */
3530 avio_wb16(pb, 0x8000); /* opColor (r?) */
3531 avio_wb16(pb, 0x8000); /* opColor (g?) */
3532 avio_wb16(pb, 0x8000); /* opColor (b?) */
3533 avio_wb16(pb, 0); /* balance */
3534 avio_wb16(pb, 0); /* reserved */
3535
3536 /*
3537 * This special text atom is required for
3538 * Apple Quicktime chapters. The contents
3539 * don't appear to be documented, so the
3540 * bytes are copied verbatim.
3541 */
3542 if (track->tag != MKTAG('c','6','0','8')) {
3543 avio_wb32(pb, 0x2C); /* size */
3544 ffio_wfourcc(pb, "text");
3545 avio_wb16(pb, 0x01);
3546 avio_wb32(pb, 0x00);
3547 avio_wb32(pb, 0x00);
3548 avio_wb32(pb, 0x00);
3549 avio_wb32(pb, 0x01);
3550 avio_wb32(pb, 0x00);
3551 avio_wb32(pb, 0x00);
3552 avio_wb32(pb, 0x00);
3553 avio_wb32(pb, 0x00004000);
3554 avio_wb16(pb, 0x0000);
3555 }
3556
3557 if (track->par->codec_tag == MKTAG('t','m','c','d')) {
3558 int64_t tmcd_pos = avio_tell(pb);
3559 avio_wb32(pb, 0); /* size */
3560 ffio_wfourcc(pb, "tmcd");
3561 mov_write_tcmi_tag(pb, track);
3562 update_size(pb, tmcd_pos);
3563 } else if (track->par->codec_tag == MKTAG('g','p','m','d')) {
3564 int64_t gpmd_pos = avio_tell(pb);
3565 avio_wb32(pb, 0); /* size */
3566 ffio_wfourcc(pb, "gpmd");
3567 avio_wb32(pb, 0); /* version */
3568 update_size(pb, gpmd_pos);
3569 }
3570 return update_size(pb, pos);
3571}
3572
3574{
3575 avio_wb32(pb, 16); /* size */
3576 ffio_wfourcc(pb, "smhd");
3577 avio_wb32(pb, 0); /* version & flags */
3578 avio_wb16(pb, 0); /* reserved (balance, normally = 0) */
3579 avio_wb16(pb, 0); /* reserved */
3580 return 16;
3581}
3582
3584{
3585 avio_wb32(pb, 0x14); /* size (always 0x14) */
3586 ffio_wfourcc(pb, "vmhd");
3587 avio_wb32(pb, 0x01); /* version & flags */
3588 avio_wb64(pb, 0); /* reserved (graphics mode = copy) */
3589 return 0x14;
3590}
3591
3592static int is_clcp_track(MOVTrack *track)
3593{
3594 return track->tag == MKTAG('c','7','0','8') ||
3595 track->tag == MKTAG('c','6','0','8');
3596}
3597
3599{
3600 MOVMuxContext *mov = s->priv_data;
3601 const char *hdlr, *descr = NULL, *hdlr_type = NULL;
3602 int64_t pos = avio_tell(pb);
3603 size_t descr_len;
3604
3605 hdlr = "dhlr";
3606 hdlr_type = "url ";
3607 descr = "DataHandler";
3608
3609 if (track) {
3610 hdlr = (track->mode == MODE_MOV) ? "mhlr" : "\0\0\0\0";
3611 if (track->par->codec_type == AVMEDIA_TYPE_VIDEO) {
3612 if (track->mode == MODE_AVIF) {
3613 hdlr_type = (track == &mov->tracks[0]) ? "pict" : "auxv";
3614 descr = "PictureHandler";
3615 } else {
3616 hdlr_type = "vide";
3617 descr = "VideoHandler";
3618 }
3619 } else if (track->par->codec_type == AVMEDIA_TYPE_AUDIO) {
3620 hdlr_type = "soun";
3621 descr = "SoundHandler";
3622 } else if (track->par->codec_type == AVMEDIA_TYPE_SUBTITLE) {
3623 if (is_clcp_track(track)) {
3624 hdlr_type = "clcp";
3625 descr = "ClosedCaptionHandler";
3626 } else {
3627 if (track->tag == MKTAG('t','x','3','g')) {
3628 hdlr_type = "sbtl";
3629 } else if (track->tag == MKTAG('m','p','4','s')) {
3630 hdlr_type = "subp";
3631 } else if (track->tag == MOV_MP4_TTML_TAG) {
3632 hdlr_type = "subt";
3633 } else {
3634 hdlr_type = "text";
3635 }
3636 descr = "SubtitleHandler";
3637 }
3638 } else if (track->par->codec_tag == MKTAG('r','t','p',' ')) {
3639 hdlr_type = "hint";
3640 descr = "HintHandler";
3641 } else if (track->par->codec_tag == MKTAG('t','m','c','d')) {
3642 hdlr_type = "tmcd";
3643 descr = "TimeCodeHandler";
3644 } else if (track->par->codec_tag == MKTAG('g','p','m','d')) {
3645 hdlr_type = "meta";
3646 descr = "GoPro MET"; // GoPro Metadata
3647 } else {
3649 "Unknown hdlr_type for %s, writing dummy values\n",
3650 av_fourcc2str(track->par->codec_tag));
3651 }
3652 if (track->st) {
3653 // hdlr.name is used by some players to identify the content title
3654 // of the track. So if an alternate handler description is
3655 // specified, use it.
3657 t = av_dict_get(track->st->metadata, "handler_name", NULL, 0);
3658 if (t && utf8len(t->value))
3659 descr = t->value;
3660 }
3661 }
3662
3663 if (mov->empty_hdlr_name) /* expressly allowed by QTFF and not prohibited in ISO 14496-12 8.4.3.3 */
3664 descr = "";
3665
3666 avio_wb32(pb, 0); /* size */
3667 ffio_wfourcc(pb, "hdlr");
3668 avio_wb32(pb, 0); /* Version & flags */
3669 avio_write(pb, hdlr, 4); /* handler */
3670 ffio_wfourcc(pb, hdlr_type); /* handler type */
3671 avio_wb32(pb, 0); /* reserved */
3672 avio_wb32(pb, 0); /* reserved */
3673 avio_wb32(pb, 0); /* reserved */
3674 descr_len = strlen(descr);
3675 if (!track || track->mode == MODE_MOV)
3676 avio_w8(pb, descr_len); /* pascal string */
3677 avio_write(pb, descr, descr_len); /* handler description */
3678 if (track && track->mode != MODE_MOV)
3679 avio_w8(pb, 0); /* c string */
3680 return update_size(pb, pos);
3681}
3682
3683static int mov_write_pitm_tag(AVIOContext *pb, int item_id)
3684{
3685 int64_t pos = avio_tell(pb);
3686 avio_wb32(pb, 0); /* size */
3687 ffio_wfourcc(pb, "pitm");
3688 avio_wb32(pb, 0); /* Version & flags */
3689 avio_wb16(pb, item_id); /* item_id */
3690 return update_size(pb, pos);
3691}
3692
3694{
3695 int64_t pos = avio_tell(pb);
3696 avio_wb32(pb, 0); /* size */
3697 ffio_wfourcc(pb, "iloc");
3698 avio_wb32(pb, 0); /* Version & flags */
3699 avio_w8(pb, (4 << 4) + 4); /* offset_size(4) and length_size(4) */
3700 avio_w8(pb, 0); /* base_offset_size(4) and reserved(4) */
3701 avio_wb16(pb, mov->nb_streams); /* item_count */
3702
3703 for (int i = 0; i < mov->nb_streams; i++) {
3704 avio_wb16(pb, i + 1); /* item_id */
3705 avio_wb16(pb, 0); /* data_reference_index */
3706 avio_wb16(pb, 1); /* extent_count */
3707 mov->avif_extent_pos[i] = avio_tell(pb);
3708 avio_wb32(pb, 0); /* extent_offset (written later) */
3709 // For animated AVIF, we simply write the first packet's size.
3710 avio_wb32(pb, mov->avif_extent_length[i]); /* extent_length */
3711 }
3712
3713 return update_size(pb, pos);
3714}
3715
3717{
3718 int64_t iinf_pos = avio_tell(pb);
3719 avio_wb32(pb, 0); /* size */
3720 ffio_wfourcc(pb, "iinf");
3721 avio_wb32(pb, 0); /* Version & flags */
3722 avio_wb16(pb, mov->nb_streams); /* entry_count */
3723
3724 for (int i = 0; i < mov->nb_streams; i++) {
3725 int64_t infe_pos = avio_tell(pb);
3726 avio_wb32(pb, 0); /* size */
3727 ffio_wfourcc(pb, "infe");
3728 avio_w8(pb, 0x2); /* Version */
3729 avio_wb24(pb, 0); /* flags */
3730 avio_wb16(pb, i + 1); /* item_id */
3731 avio_wb16(pb, 0); /* item_protection_index */
3732 avio_write(pb, "av01", 4); /* item_type */
3733 avio_write(pb, !i ? "Color\0" : "Alpha\0", 6); /* item_name */
3734 update_size(pb, infe_pos);
3735 }
3736
3737 return update_size(pb, iinf_pos);
3738}
3739
3740
3742{
3743 int64_t auxl_pos;
3744 int64_t iref_pos = avio_tell(pb);
3745 avio_wb32(pb, 0); /* size */
3746 ffio_wfourcc(pb, "iref");
3747 avio_wb32(pb, 0); /* Version & flags */
3748
3749 auxl_pos = avio_tell(pb);
3750 avio_wb32(pb, 0); /* size */
3751 ffio_wfourcc(pb, "auxl");
3752 avio_wb16(pb, 2); /* from_item_ID */
3753 avio_wb16(pb, 1); /* reference_count */
3754 avio_wb16(pb, 1); /* to_item_ID */
3755 update_size(pb, auxl_pos);
3756
3757 return update_size(pb, iref_pos);
3758}
3759
3761 int stream_index)
3762{
3763 int64_t pos = avio_tell(pb);
3764 avio_wb32(pb, 0); /* size */
3765 ffio_wfourcc(pb, "ispe");
3766 avio_wb32(pb, 0); /* Version & flags */
3767 avio_wb32(pb, s->streams[stream_index]->codecpar->width); /* image_width */
3768 avio_wb32(pb, s->streams[stream_index]->codecpar->height); /* image_height */
3769 return update_size(pb, pos);
3770}
3771
3773 int stream_index)
3774{
3775 int64_t pos = avio_tell(pb);
3776 const AVPixFmtDescriptor *pixdesc =
3777 av_pix_fmt_desc_get(s->streams[stream_index]->codecpar->format);
3778 avio_wb32(pb, 0); /* size */
3779 ffio_wfourcc(pb, "pixi");
3780 avio_wb32(pb, 0); /* Version & flags */
3781 avio_w8(pb, pixdesc->nb_components); /* num_channels */
3782 for (int i = 0; i < pixdesc->nb_components; ++i) {
3783 avio_w8(pb, pixdesc->comp[i].depth); /* bits_per_channel */
3784 }
3785 return update_size(pb, pos);
3786}
3787
3789{
3790 int64_t pos = avio_tell(pb);
3791 avio_wb32(pb, 0); /* size */
3792 ffio_wfourcc(pb, "ipco");
3793 for (int i = 0; i < mov->nb_streams; i++) {
3794 mov_write_ispe_tag(pb, mov, s, i);
3795 mov_write_pixi_tag(pb, mov, s, i);
3796 mov_write_av1c_tag(pb, &mov->tracks[i]);
3797 if (!i)
3798 mov_write_colr_tag(pb, &mov->tracks[0], 0);
3799 else
3800 mov_write_aux_tag(pb, "auxC");
3801 }
3802 return update_size(pb, pos);
3803}
3804
3806{
3807 int64_t pos = avio_tell(pb);
3808 avio_wb32(pb, 0); /* size */
3809 ffio_wfourcc(pb, "ipma");
3810 avio_wb32(pb, 0); /* Version & flags */
3811 avio_wb32(pb, mov->nb_streams); /* entry_count */
3812
3813 for (int i = 0, index = 1; i < mov->nb_streams; i++) {
3814 avio_wb16(pb, i + 1); /* item_ID */
3815 avio_w8(pb, 4); /* association_count */
3816
3817 // ispe association.
3818 avio_w8(pb, index++); /* essential and property_index */
3819 // pixi association.
3820 avio_w8(pb, index++); /* essential and property_index */
3821 // av1C association.
3822 avio_w8(pb, 0x80 | index++); /* essential and property_index */
3823 // colr/auxC association.
3824 avio_w8(pb, index++); /* essential and property_index */
3825 }
3826 return update_size(pb, pos);
3827}
3828
3830{
3831 int64_t pos = avio_tell(pb);
3832 avio_wb32(pb, 0); /* size */
3833 ffio_wfourcc(pb, "iprp");
3834 mov_write_ipco_tag(pb, mov, s);
3835 mov_write_ipma_tag(pb, mov, s);
3836 return update_size(pb, pos);
3837}
3838
3840{
3841 /* This atom must be present, but leaving the values at zero
3842 * seems harmless. */
3843 avio_wb32(pb, 28); /* size */
3844 ffio_wfourcc(pb, "hmhd");
3845 avio_wb32(pb, 0); /* version, flags */
3846 avio_wb16(pb, 0); /* maxPDUsize */
3847 avio_wb16(pb, 0); /* avgPDUsize */
3848 avio_wb32(pb, 0); /* maxbitrate */
3849 avio_wb32(pb, 0); /* avgbitrate */
3850 avio_wb32(pb, 0); /* reserved */
3851 return 28;
3852}
3853
3855{
3856 int64_t pos = avio_tell(pb);
3857 int ret;
3858
3859 avio_wb32(pb, 0); /* size */
3860 ffio_wfourcc(pb, "minf");
3861 if (track->par->codec_type == AVMEDIA_TYPE_VIDEO)
3863 else if (track->par->codec_type == AVMEDIA_TYPE_AUDIO)
3865 else if (track->par->codec_type == AVMEDIA_TYPE_SUBTITLE) {
3866 if (track->tag == MKTAG('t','e','x','t') || is_clcp_track(track)) {
3867 mov_write_gmhd_tag(pb, track);
3868 } else if (track->tag == MOV_MP4_TTML_TAG) {
3870 } else {
3872 }
3873 } else if (track->tag == MKTAG('r','t','p',' ')) {
3875 } else if (track->tag == MKTAG('t','m','c','d')) {
3876 if (track->mode != MODE_MOV)
3878 else
3879 mov_write_gmhd_tag(pb, track);
3880 } else if (track->tag == MKTAG('g','p','m','d')) {
3881 mov_write_gmhd_tag(pb, track);
3882 }
3883 if (track->mode == MODE_MOV) /* ISO 14496-12 8.4.3.1 specifies hdlr only within mdia or meta boxes */
3886 if ((ret = mov_write_stbl_tag(s, pb, mov, track)) < 0)
3887 return ret;
3888 return update_size(pb, pos);
3889}
3890
3891static void get_pts_range(MOVMuxContext *mov, MOVTrack *track,
3892 int64_t *start, int64_t *end, int elst, int mdhd)
3893{
3894 if (track->tag == MKTAG('t','m','c','d') && mov->nb_meta_tmcd && track->nb_src_track) {
3895 // tmcd tracks gets track_duration set in mov_write_moov_tag from
3896 // another track's duration, while the end_pts may be left at zero.
3897 // Calculate the pts duration for that track instead.
3898 get_pts_range(mov, &mov->tracks[*track->src_track], start, end, elst, mdhd);
3899 *start = av_rescale(*start, track->timescale,
3900 mov->tracks[*track->src_track].timescale);
3901 *end = av_rescale(*end, track->timescale,
3902 mov->tracks[*track->src_track].timescale);
3903 return;
3904 }
3905 if (!mdhd && track->end_pts != AV_NOPTS_VALUE &&
3906 track->start_dts != AV_NOPTS_VALUE &&
3907 track->start_cts != AV_NOPTS_VALUE) {
3908 *start = track->start_dts + track->start_cts;
3909 *end = elst ? track->elst_end_pts : track->end_pts;
3910 return;
3911 }
3912 *start = 0;
3913 *end = track->track_duration;
3914}
3915
3917{
3918 int64_t start, end;
3919 get_pts_range(mov, track, &start, &end, 0, 1);
3920 return end - start;
3921}
3922
3923// Calculate the actual duration of the track, after edits.
3924// If it starts with a pts < 0, that is removed by the edit list.
3925// If it starts with a pts > 0, the edit list adds a delay before that.
3926// Thus, with edit lists enabled, the post-edit output of the file is
3927// starting with pts=0.
3929{
3930 int64_t start, end;
3931 get_pts_range(mov, track, &start, &end, 0, 0);
3932 if (mov->use_editlist != 0)
3933 start = 0;
3934 return end - start;
3935}
3936
3938{
3939 int64_t start, end;
3940 get_pts_range(mov, track, &start, &end, 1, 0);
3941 return end - start;
3942}
3943
3945{
3946 if (track && track->mode == MODE_ISM)
3947 return 1;
3948 if (duration < INT32_MAX)
3949 return 0;
3950 return 1;
3951}
3952
3954 MOVTrack *track)
3955{
3957 int version = mov_mdhd_mvhd_tkhd_version(mov, track, duration);
3958
3959 (version == 1) ? avio_wb32(pb, 44) : avio_wb32(pb, 32); /* size */
3960 ffio_wfourcc(pb, "mdhd");
3961 avio_w8(pb, version);
3962 avio_wb24(pb, 0); /* flags */
3963 if (version == 1) {
3964 avio_wb64(pb, track->time);
3965 avio_wb64(pb, track->time);
3966 } else {
3967 avio_wb32(pb, track->time); /* creation time */
3968 avio_wb32(pb, track->time); /* modification time */
3969 }
3970 avio_wb32(pb, track->timescale); /* time scale (sample rate for audio) */
3971 if (!track->entry && mov->mode == MODE_ISM)
3972 (version == 1) ? avio_wb64(pb, UINT64_C(0xffffffffffffffff)) : avio_wb32(pb, 0xffffffff);
3973 else if (!track->entry)
3974 (version == 1) ? avio_wb64(pb, 0) : avio_wb32(pb, 0);
3975 else
3976 (version == 1) ? avio_wb64(pb, duration) : avio_wb32(pb, duration); /* duration */
3977 avio_wb16(pb, track->language); /* language */
3978 avio_wb16(pb, 0); /* reserved (quality) */
3979
3980 if (version != 0 && track->mode == MODE_MOV) {
3982 "FATAL error, file duration too long for timebase, this file will not be\n"
3983 "playable with QuickTime. Choose a different timebase with "
3984 "-video_track_timescale or a different container format\n");
3985 }
3986
3987 return 32;
3988}
3989
3991 MOVMuxContext *mov, MOVTrack *track)
3992{
3993 int64_t pos = avio_tell(pb);
3994 int ret;
3995
3996 avio_wb32(pb, 0); /* size */
3997 ffio_wfourcc(pb, "mdia");
3998 mov_write_mdhd_tag(pb, mov, track);
3999 mov_write_hdlr_tag(s, pb, track);
4000 if ((ret = mov_write_minf_tag(s, pb, mov, track)) < 0)
4001 return ret;
4002 return update_size(pb, pos);
4003}
4004
4005/* transformation matrix
4006 |a b u|
4007 |c d v|
4008 |tx ty w| */
4009static void write_matrix(AVIOContext *pb, int16_t a, int16_t b, int16_t c,
4010 int16_t d, int16_t tx, int16_t ty)
4011{
4012 avio_wb32(pb, a << 16); /* 16.16 format */
4013 avio_wb32(pb, b << 16); /* 16.16 format */
4014 avio_wb32(pb, 0); /* u in 2.30 format */
4015 avio_wb32(pb, c << 16); /* 16.16 format */
4016 avio_wb32(pb, d << 16); /* 16.16 format */
4017 avio_wb32(pb, 0); /* v in 2.30 format */
4018 avio_wb32(pb, tx << 16); /* 16.16 format */
4019 avio_wb32(pb, ty << 16); /* 16.16 format */
4020 avio_wb32(pb, 1 << 30); /* w in 2.30 format */
4021}
4022
4024 MOVTrack *track, AVStream *st)
4025{
4027 mov->movie_timescale, track->timescale,
4028 AV_ROUND_UP);
4029 int version;
4031 int group = 0;
4032
4033 uint32_t *display_matrix = NULL;
4034 int i;
4035
4036 if (mov->mode == MODE_AVIF)
4037 if (!mov->avif_loop_count)
4038 duration = INT64_MAX;
4039 else
4040 duration *= mov->avif_loop_count;
4041
4042 if (st) {
4043 const AVPacketSideData *sd;
4044 if (mov->per_stream_grouping)
4045 group = st->index;
4046 else
4047 group = st->codecpar->codec_type;
4048
4052 if (sd && sd->size == 9 * sizeof(*display_matrix))
4053 display_matrix = (uint32_t *)sd->data;
4054 }
4055
4056 if (track->flags & MOV_TRACK_ENABLED)
4058
4060
4061 (version == 1) ? avio_wb32(pb, 104) : avio_wb32(pb, 92); /* size */
4062 ffio_wfourcc(pb, "tkhd");
4063 avio_w8(pb, version);
4064 avio_wb24(pb, flags);
4065 if (version == 1) {
4066 avio_wb64(pb, track->time);
4067 avio_wb64(pb, track->time);
4068 } else {
4069 avio_wb32(pb, track->time); /* creation time */
4070 avio_wb32(pb, track->time); /* modification time */
4071 }
4072 avio_wb32(pb, track->track_id); /* track-id */
4073 avio_wb32(pb, 0); /* reserved */
4074 if (!track->entry && mov->mode == MODE_ISM)
4075 (version == 1) ? avio_wb64(pb, UINT64_C(0xffffffffffffffff)) : avio_wb32(pb, 0xffffffff);
4076 else if (!track->entry)
4077 (version == 1) ? avio_wb64(pb, 0) : avio_wb32(pb, 0);
4078 else
4079 (version == 1) ? avio_wb64(pb, duration) : avio_wb32(pb, duration);
4080
4081 avio_wb32(pb, 0); /* reserved */
4082 avio_wb32(pb, 0); /* reserved */
4083 avio_wb16(pb, 0); /* layer */
4084 avio_wb16(pb, group); /* alternate group) */
4085 /* Volume, only for audio */
4086 if (track->par->codec_type == AVMEDIA_TYPE_AUDIO)
4087 avio_wb16(pb, 0x0100);
4088 else
4089 avio_wb16(pb, 0);
4090 avio_wb16(pb, 0); /* reserved */
4091
4092 /* Matrix structure */
4093 if (display_matrix) {
4094 for (i = 0; i < 9; i++)
4095 avio_wb32(pb, display_matrix[i]);
4096 } else {
4097 write_matrix(pb, 1, 0, 0, 1, 0, 0);
4098 }
4099 /* Track width and height, for visual only */
4100 if (st && (track->par->codec_type == AVMEDIA_TYPE_VIDEO ||
4101 track->par->codec_type == AVMEDIA_TYPE_SUBTITLE)) {
4102 int64_t track_width_1616;
4103 if (track->mode == MODE_MOV || track->mode == MODE_AVIF) {
4104 track_width_1616 = track->par->width * 0x10000ULL;
4105 } else {
4106 track_width_1616 = av_rescale(st->sample_aspect_ratio.num,
4107 track->par->width * 0x10000LL,
4109 if (!track_width_1616 ||
4110 track->height != track->par->height ||
4111 track_width_1616 > UINT32_MAX)
4112 track_width_1616 = track->par->width * 0x10000ULL;
4113 }
4114 if (track_width_1616 > UINT32_MAX) {
4115 av_log(mov->fc, AV_LOG_WARNING, "track width is too large\n");
4116 track_width_1616 = 0;
4117 }
4118 avio_wb32(pb, track_width_1616);
4119 if (track->height > 0xFFFF) {
4120 av_log(mov->fc, AV_LOG_WARNING, "track height is too large\n");
4121 avio_wb32(pb, 0);
4122 } else
4123 avio_wb32(pb, track->height * 0x10000U);
4124 } else {
4125 avio_wb32(pb, 0);
4126 avio_wb32(pb, 0);
4127 }
4128 return 0x5c;
4129}
4130
4132{
4134 track->par->sample_aspect_ratio.den);
4135
4136 int64_t pos = avio_tell(pb);
4137
4138 avio_wb32(pb, 0); /* size */
4139 ffio_wfourcc(pb, "tapt");
4140
4141 avio_wb32(pb, 20);
4142 ffio_wfourcc(pb, "clef");
4143 avio_wb32(pb, 0);
4144 avio_wb32(pb, width << 16);
4145 avio_wb32(pb, track->par->height << 16);
4146
4147 avio_wb32(pb, 20);
4148 ffio_wfourcc(pb, "prof");
4149 avio_wb32(pb, 0);
4150 avio_wb32(pb, width << 16);
4151 avio_wb32(pb, track->par->height << 16);
4152
4153 avio_wb32(pb, 20);
4154 ffio_wfourcc(pb, "enof");
4155 avio_wb32(pb, 0);
4156 avio_wb32(pb, track->par->width << 16);
4157 avio_wb32(pb, track->par->height << 16);
4158
4159 return update_size(pb, pos);
4160}
4161
4162// This box is written in the following cases:
4163// * Seems important for the psp playback. Without it the movie seems to hang.
4164// * Used for specifying the looping behavior of animated AVIF (as specified
4165// in Section 9.6 of the HEIF specification ISO/IEC 23008-12).
4167 MOVTrack *track)
4168{
4170 mov->movie_timescale, track->timescale,
4171 AV_ROUND_UP);
4172 int version = duration < INT32_MAX ? 0 : 1;
4173 int entry_size, entry_count, size;
4174 int64_t delay, start_ct = track->start_cts;
4175 int64_t start_dts = track->start_dts;
4176 int flags = 0;
4177
4178 if (track->entry) {
4179 if (start_dts != track->cluster[0].dts || (start_ct != track->cluster[0].cts && track->cluster[0].dts >= 0)) {
4180
4181 av_log(mov->fc, AV_LOG_DEBUG,
4182 "EDTS using dts:%"PRId64" cts:%d instead of dts:%"PRId64" cts:%"PRId64" tid:%d\n",
4183 track->cluster[0].dts, track->cluster[0].cts,
4184 start_dts, start_ct, track->track_id);
4185 start_dts = track->cluster[0].dts;
4186 start_ct = track->cluster[0].cts;
4187 }
4188 }
4189
4190 delay = av_rescale_rnd(start_dts + start_ct, mov->movie_timescale,
4191 track->timescale, AV_ROUND_DOWN);
4192
4193 if (mov->mode == MODE_AVIF) {
4194 delay = 0;
4195 // Section 9.6.3 of ISO/IEC 23008-12: flags specifies repetition of the
4196 // edit list as follows: (flags & 1) equal to 0 specifies that the edit
4197 // list is not repeated, while (flags & 1) equal to 1 specifies that the
4198 // edit list is repeated.
4199 flags = mov->avif_loop_count != 1;
4200 start_ct = 0;
4201 }
4202
4203 version |= delay < INT32_MAX ? 0 : 1;
4204
4205 entry_size = (version == 1) ? 20 : 12;
4206 entry_count = 1 + (delay > 0);
4207 size = 24 + entry_count * entry_size;
4208
4209 /* write the atom data */
4210 avio_wb32(pb, size);
4211 ffio_wfourcc(pb, "edts");
4212 avio_wb32(pb, size - 8);
4213 ffio_wfourcc(pb, "elst");
4214 avio_w8(pb, version);
4215 avio_wb24(pb, flags); /* flags */
4216
4217 avio_wb32(pb, entry_count);
4218 if (delay > 0) { /* add an empty edit to delay presentation */
4219 /* In the positive delay case, the delay includes the cts
4220 * offset, and the second edit list entry below trims out
4221 * the same amount from the actual content. This makes sure
4222 * that the offset last sample is included in the edit
4223 * list duration as well. */
4224 if (version == 1) {
4225 avio_wb64(pb, delay);
4226 avio_wb64(pb, -1);
4227 } else {
4228 avio_wb32(pb, delay);
4229 avio_wb32(pb, -1);
4230 }
4231 avio_wb32(pb, 0x00010000);
4232 } else if (mov->mode != MODE_AVIF) {
4233 /* Avoid accidentally ending up with start_ct = -1 which has got a
4234 * special meaning. Normally start_ct should end up positive or zero
4235 * here, but use FFMIN in case dts is a small positive integer
4236 * rounded to 0 when represented in movie timescale units. */
4237 av_assert0(av_rescale_rnd(start_dts, mov->movie_timescale, track->timescale, AV_ROUND_DOWN) <= 0);
4238 start_ct = -FFMIN(start_dts, 0);
4239
4240#if CONFIG_IAMFENC
4241 if (track->iamf && track->par->codec_id == AV_CODEC_ID_OPUS)
4242 start_ct = av_rescale(start_ct, 48000, track->par->sample_rate);
4243#endif
4244 /* Note, this delay is calculated from the pts of the first sample,
4245 * ensuring that we don't reduce the duration for cases with
4246 * dts<0 pts=0. */
4247 duration += delay;
4248 }
4249
4250 /* For fragmented files, we don't know the full length yet. Setting
4251 * duration to 0 allows us to only specify the offset, including
4252 * the rest of the content (from all future fragments) without specifying
4253 * an explicit duration.
4254 *
4255 * For hybrid_fragmented during mov_write_trailer (mov->moov_written != 0),
4256 * don't reset duration to zero.
4257 */
4258 if (mov->flags & FF_MOV_FLAG_FRAGMENT &&
4260 duration = 0;
4261
4262 /* duration */
4263 if (version == 1) {
4264 avio_wb64(pb, duration);
4265 avio_wb64(pb, start_ct);
4266 } else {
4267 avio_wb32(pb, duration);
4268 avio_wb32(pb, start_ct);
4269 }
4270 avio_wb32(pb, 0x00010000);
4271 return size;
4272}
4273
4275{
4276 int64_t pos = avio_tell(pb);
4277 avio_wb32(pb, 0); // size placeholder
4278 ffio_wfourcc(pb, "tref");
4279
4280 for (int i = 0; i < track->nb_tref_tags; i++) {
4281 MovTag *tag = &track->tref_tags[i];
4282 avio_wb32(pb, 8 + tag->nb_id * sizeof(*tag->id)); // size (subatom)
4283 avio_wl32(pb, tag->name);
4284 for (int j = 0; j < tag->nb_id; j++)
4285 avio_wb32(pb, tag->id[j]);
4286 }
4287 return update_size(pb, pos);
4288}
4289
4290// goes at the end of each track! ... Critical for PSP playback ("Incompatible data" without it)
4292{
4293 avio_wb32(pb, 0x34); /* size ... reports as 28 in mp4box! */
4294 ffio_wfourcc(pb, "uuid");
4295 ffio_wfourcc(pb, "USMT");
4296 avio_wb32(pb, 0x21d24fce);
4297 avio_wb32(pb, 0xbb88695c);
4298 avio_wb32(pb, 0xfac9c740);
4299 avio_wb32(pb, 0x1c); // another size here!
4300 ffio_wfourcc(pb, "MTDT");
4301 avio_wb32(pb, 0x00010012);
4302 avio_wb32(pb, 0x0a);
4303 avio_wb32(pb, 0x55c40000);
4304 avio_wb32(pb, 0x1);
4305 avio_wb32(pb, 0x0);
4306 return 0x34;
4307}
4308
4310{
4311 AVFormatContext *ctx = track->rtp_ctx;
4312 char buf[1000] = "";
4313 int len;
4314
4315 av_assert0(track->nb_src_track);
4316 ff_sdp_write_media(buf, sizeof(buf), ctx->streams[0], *track->src_track,
4317 NULL, NULL, 0, 0, ctx);
4318 av_strlcatf(buf, sizeof(buf), "a=control:streamid=%d\r\n", track->track_id);
4319 len = strlen(buf);
4320
4321 avio_wb32(pb, len + 24);
4322 ffio_wfourcc(pb, "udta");
4323 avio_wb32(pb, len + 16);
4324 ffio_wfourcc(pb, "hnti");
4325 avio_wb32(pb, len + 8);
4326 ffio_wfourcc(pb, "sdp ");
4327 avio_write(pb, buf, len);
4328 return len + 24;
4329}
4330
4332 const char *tag, const char *str)
4333{
4334 int64_t pos = avio_tell(pb);
4335 AVDictionaryEntry *t = av_dict_get(st->metadata, str, NULL, 0);
4336 if (!t || !utf8len(t->value))
4337 return 0;
4338
4339 avio_wb32(pb, 0); /* size */
4340 ffio_wfourcc(pb, tag); /* type */
4341 avio_write(pb, t->value, strlen(t->value)); /* UTF8 string value */
4342 return update_size(pb, pos);
4343}
4344
4345static int mov_write_track_kind(AVIOContext *pb, const char *scheme_uri,
4346 const char *value)
4347{
4348 int64_t pos = avio_tell(pb);
4349
4350 /* Box|FullBox basics */
4351 avio_wb32(pb, 0); /* size placeholder */
4352 ffio_wfourcc(pb, (const unsigned char *)"kind");
4353 avio_w8(pb, 0); /* version = 0 */
4354 avio_wb24(pb, 0); /* flags = 0 */
4355
4356 /* Required null-terminated scheme URI */
4357 avio_write(pb, (const unsigned char *)scheme_uri,
4358 strlen(scheme_uri));
4359 avio_w8(pb, 0);
4360
4361 /* Optional value string */
4362 if (value && value[0])
4363 avio_write(pb, (const unsigned char *)value,
4364 strlen(value));
4365
4366 avio_w8(pb, 0);
4367
4368 return update_size(pb, pos);
4369}
4370
4372{
4373 int ret = AVERROR_BUG;
4374
4375 for (int i = 0; ff_mov_track_kind_table[i].scheme_uri; i++) {
4377
4378 for (int j = 0; map.value_maps[j].disposition; j++) {
4379 const struct MP4TrackKindValueMapping value_map = map.value_maps[j];
4380 if (!(st->disposition & value_map.disposition))
4381 continue;
4382
4383 if ((ret = mov_write_track_kind(pb, map.scheme_uri, value_map.value)) < 0)
4384 return ret;
4385 }
4386 }
4387
4388 return 0;
4389}
4390
4392 AVStream *st)
4393{
4394 AVIOContext *pb_buf;
4395 int ret, size;
4396 uint8_t *buf;
4397
4398 if (!st)
4399 return 0;
4400
4401 ret = avio_open_dyn_buf(&pb_buf);
4402 if (ret < 0)
4403 return ret;
4404
4405 if (mov->mode & (MODE_MP4|MODE_MOV))
4406 mov_write_track_metadata(pb_buf, st, "name", "title");
4407
4408 if (mov->mode & MODE_MP4) {
4409 if ((ret = mov_write_track_kinds(pb_buf, st)) < 0)
4410 goto end;
4411 }
4412
4413 if ((size = avio_get_dyn_buf(pb_buf, &buf)) > 0) {
4414 avio_wb32(pb, size + 8);
4415 ffio_wfourcc(pb, "udta");
4416 avio_write(pb, buf, size);
4417 }
4418end:
4419 ffio_free_dyn_buf(&pb_buf);
4420
4421 return ret;
4422}
4423
4425 MOVTrack *track, AVStream *st)
4426{
4427 int64_t pos = avio_tell(pb);
4428 int entry_backup = track->entry;
4429 int chunk_backup = track->chunkCount;
4430 int ret;
4431
4432 /* If we want to have an empty moov, but some samples already have been
4433 * buffered (delay_moov), pretend that no samples have been written yet. */
4434 if (mov->flags & FF_MOV_FLAG_EMPTY_MOOV)
4435 track->chunkCount = track->entry = 0;
4436
4437 avio_wb32(pb, 0); /* size */
4438 ffio_wfourcc(pb, "trak");
4439 mov_write_tkhd_tag(pb, mov, track, st);
4440
4441 av_assert2(mov->use_editlist >= 0);
4442
4443 if (track->start_dts != AV_NOPTS_VALUE) {
4444 if (mov->use_editlist)
4445 mov_write_edts_tag(pb, mov, track); // PSP Movies and several other cases require edts box
4446 else if ((track->entry && track->cluster[0].dts) || track->mode == MODE_PSP || is_clcp_track(track))
4447 av_log(mov->fc, AV_LOG_WARNING,
4448 "Not writing any edit list even though one would have been required\n");
4449 }
4450
4451 if (mov->is_animated_avif)
4452 mov_write_edts_tag(pb, mov, track);
4453
4454 if (track->nb_tref_tags)
4455 mov_write_tref_tag(pb, track);
4456
4457 if ((ret = mov_write_mdia_tag(s, pb, mov, track)) < 0)
4458 return ret;
4459 if (track->mode == MODE_PSP)
4460 mov_write_uuid_tag_psp(pb, track); // PSP Movies require this uuid box
4461 if (track->tag == MKTAG('r','t','p',' '))
4462 mov_write_udta_sdp(pb, track);
4463 if (track->mode == MODE_MOV) {
4464 if (track->par->codec_type == AVMEDIA_TYPE_VIDEO) {
4465 double sample_aspect_ratio = av_q2d(st->sample_aspect_ratio);
4466 if (st->sample_aspect_ratio.num && 1.0 != sample_aspect_ratio) {
4467 mov_write_tapt_tag(pb, track);
4468 }
4469 }
4470 if (is_clcp_track(track) && st->sample_aspect_ratio.num) {
4471 mov_write_tapt_tag(pb, track);
4472 }
4473 }
4474 mov_write_track_udta_tag(pb, mov, st);
4475 track->entry = entry_backup;
4476 track->chunkCount = chunk_backup;
4477 return update_size(pb, pos);
4478}
4479
4481{
4482 int i, has_audio = 0, has_video = 0;
4483 int64_t pos = avio_tell(pb);
4484 int audio_profile = mov->iods_audio_profile;
4485 int video_profile = mov->iods_video_profile;
4486 for (i = 0; i < mov->nb_tracks; i++) {
4487 if (mov->tracks[i].entry > 0 || mov->flags & FF_MOV_FLAG_EMPTY_MOOV) {
4488 has_audio |= mov->tracks[i].par->codec_type == AVMEDIA_TYPE_AUDIO;
4489 has_video |= mov->tracks[i].par->codec_type == AVMEDIA_TYPE_VIDEO;
4490 }
4491 }
4492 if (audio_profile < 0)
4493 audio_profile = 0xFF - has_audio;
4494 if (video_profile < 0)
4495 video_profile = 0xFF - has_video;
4496 avio_wb32(pb, 0x0); /* size */
4497 ffio_wfourcc(pb, "iods");
4498 avio_wb32(pb, 0); /* version & flags */
4499 put_descr(pb, 0x10, 7);
4500 avio_wb16(pb, 0x004f);
4501 avio_w8(pb, 0xff);
4502 avio_w8(pb, 0xff);
4503 avio_w8(pb, audio_profile);
4504 avio_w8(pb, video_profile);
4505 avio_w8(pb, 0xff);
4506 return update_size(pb, pos);
4507}
4508
4510{
4511 avio_wb32(pb, 0x20); /* size */
4512 ffio_wfourcc(pb, "trex");
4513 avio_wb32(pb, 0); /* version & flags */
4514 avio_wb32(pb, track->track_id); /* track ID */
4515 avio_wb32(pb, 1); /* default sample description index */
4516 avio_wb32(pb, 0); /* default sample duration */
4517 avio_wb32(pb, 0); /* default sample size */
4518 avio_wb32(pb, 0); /* default sample flags */
4519 return 0;
4520}
4521
4523{
4524 int64_t pos = avio_tell(pb);
4525 int i;
4526 avio_wb32(pb, 0x0); /* size */
4527 ffio_wfourcc(pb, "mvex");
4528 for (i = 0; i < mov->nb_tracks; i++)
4529 mov_write_trex_tag(pb, &mov->tracks[i]);
4530 return update_size(pb, pos);
4531}
4532
4534{
4535 int max_track_id = 1, i;
4536 int64_t max_track_len = 0;
4537 int version;
4538 int timescale;
4539
4540 for (i = 0; i < mov->nb_tracks; i++) {
4541 if (mov->tracks[i].entry > 0 && mov->tracks[i].timescale) {
4542 int64_t max_track_len_temp = av_rescale_rnd(
4543 calc_pts_duration(mov, &mov->tracks[i]),
4544 mov->movie_timescale,
4545 mov->tracks[i].timescale,
4546 AV_ROUND_UP);
4547 if (max_track_len < max_track_len_temp)
4548 max_track_len = max_track_len_temp;
4549 if (max_track_id < mov->tracks[i].track_id)
4550 max_track_id = mov->tracks[i].track_id;
4551 }
4552 }
4553 /* If using delay_moov, make sure the output is the same as if no
4554 * samples had been written yet. */
4555 if (mov->flags & FF_MOV_FLAG_EMPTY_MOOV) {
4556 max_track_len = 0;
4557 max_track_id = 1;
4558 }
4559
4560 version = mov_mdhd_mvhd_tkhd_version(mov, NULL, max_track_len);
4561 avio_wb32(pb, version == 1 ? 120 : 108); /* size */
4562
4563 ffio_wfourcc(pb, "mvhd");
4564 avio_w8(pb, version);
4565 avio_wb24(pb, 0); /* flags */
4566 if (version == 1) {
4567 avio_wb64(pb, mov->time);
4568 avio_wb64(pb, mov->time);
4569 } else {
4570 avio_wb32(pb, mov->time); /* creation time */
4571 avio_wb32(pb, mov->time); /* modification time */
4572 }
4573
4574 timescale = mov->movie_timescale;
4575 if (mov->mode == MODE_AVIF && !timescale)
4576 timescale = mov->tracks[0].timescale;
4577
4578 avio_wb32(pb, timescale);
4579 (version == 1) ? avio_wb64(pb, max_track_len) : avio_wb32(pb, max_track_len); /* duration of longest track */
4580
4581 avio_wb32(pb, 0x00010000); /* reserved (preferred rate) 1.0 = normal */
4582 avio_wb16(pb, 0x0100); /* reserved (preferred volume) 1.0 = normal */
4583 ffio_fill(pb, 0, 2 + 2 * 4); /* reserved */
4584
4585 /* Matrix structure */
4586 write_matrix(pb, 1, 0, 0, 1, 0, 0);
4587
4588 avio_wb32(pb, 0); /* reserved (preview time) */
4589 avio_wb32(pb, 0); /* reserved (preview duration) */
4590 avio_wb32(pb, 0); /* reserved (poster time) */
4591 avio_wb32(pb, 0); /* reserved (selection time) */
4592 avio_wb32(pb, 0); /* reserved (selection duration) */
4593 avio_wb32(pb, 0); /* reserved (current time) */
4594 avio_wb32(pb, max_track_id + 1); /* Next track id */
4595 return 0x6c;
4596}
4597
4600{
4601 avio_wb32(pb, 33); /* size */
4602 ffio_wfourcc(pb, "hdlr");
4603 avio_wb32(pb, 0);
4604 avio_wb32(pb, 0);
4605 ffio_wfourcc(pb, "mdir");
4606 ffio_wfourcc(pb, "appl");
4607 avio_wb32(pb, 0);
4608 avio_wb32(pb, 0);
4609 avio_w8(pb, 0);
4610 return 33;
4611}
4612
4613/* helper function to write a data tag with the specified string as data */
4614static int mov_write_string_data_tag(AVIOContext *pb, const char *data, int lang, int long_style)
4615{
4616 size_t data_len = strlen(data);
4617 if (long_style) {
4618 int size = 16 + data_len;
4619 avio_wb32(pb, size); /* size */
4620 ffio_wfourcc(pb, "data");
4621 avio_wb32(pb, 1);
4622 avio_wb32(pb, 0);
4623 avio_write(pb, data, data_len);
4624 return size;
4625 } else {
4626 avio_wb16(pb, data_len); /* string length */
4627 if (!lang)
4628 lang = ff_mov_iso639_to_lang("und", 1);
4629 avio_wb16(pb, lang);
4630 avio_write(pb, data, data_len);
4631 return data_len + 4;
4632 }
4633}
4634
4635static int mov_write_string_tag(AVIOContext *pb, const char *name,
4636 const char *value, int lang, int long_style)
4637{
4638 int size = 0;
4639 if (value && value[0]) {
4640 int64_t pos = avio_tell(pb);
4641 avio_wb32(pb, 0); /* size */
4642 ffio_wfourcc(pb, name);
4643 mov_write_string_data_tag(pb, value, lang, long_style);
4644 size = update_size(pb, pos);
4645 }
4646 return size;
4647}
4648
4649static int mov_write_freeform_tag(AVIOContext *pb, const char *mean,
4650 const char *name, const char *data)
4651{
4652 if (!data || !data[0])
4653 return 0;
4654
4655 static const char stub_flags[4] = {0, 0, 0, 0};
4656
4657 int64_t entry_pos = avio_tell(pb);
4658 avio_wb32(pb, 0); /* size */
4659 ffio_wfourcc(pb, "----"); /* freeform */
4660
4661 size_t mean_len = strlen(mean);
4662 avio_wb32(pb, 12 + mean_len);
4663 ffio_wfourcc(pb, "mean");
4664 avio_write(pb, &stub_flags[0], sizeof(stub_flags));
4665 avio_write(pb, mean, mean_len);
4666
4667 size_t name_len = strlen(name);
4668 avio_wb32(pb, 12 + name_len);
4669 ffio_wfourcc(pb, "name");
4670 avio_write(pb, &stub_flags[0], sizeof(stub_flags));
4671 avio_write(pb, name, name_len);
4672
4674
4675 return update_size(pb, entry_pos);
4676}
4677
4679 const char *tag, int *lang)
4680{
4681 int l, len, len2;
4682 AVDictionaryEntry *t, *t2 = NULL;
4683 char tag2[16];
4684
4685 *lang = 0;
4686
4687 if (!(t = av_dict_get(s->metadata, tag, NULL, 0)))
4688 return NULL;
4689
4690 len = strlen(t->key);
4691 snprintf(tag2, sizeof(tag2), "%s-", tag);
4692 while ((t2 = av_dict_get(s->metadata, tag2, t2, AV_DICT_IGNORE_SUFFIX))) {
4693 len2 = strlen(t2->key);
4694 if (len2 == len + 4 && !strcmp(t->value, t2->value)
4695 && (l = ff_mov_iso639_to_lang(&t2->key[len2 - 3], 1)) >= 0) {
4696 *lang = l;
4697 return t;
4698 }
4699 }
4700 return t;
4701}
4702
4704 const char *name, const char *tag,
4705 int long_style)
4706{
4707 int lang;
4709 if (!t)
4710 return 0;
4711 return mov_write_string_tag(pb, name, t->value, lang, long_style);
4712}
4713
4715 const char *mean, const char *name,
4716 const char *tag)
4717{
4718 AVDictionaryEntry *t = av_dict_get(s->metadata, tag, NULL, 0);
4719 if (!t)
4720 return 0;
4721 return mov_write_freeform_tag(pb, mean, name, t->value);
4722}
4723
4724/* iTunes bpm number */
4726{
4727 AVDictionaryEntry *t = av_dict_get(s->metadata, "tmpo", NULL, 0);
4728 int size = 0, tmpo = t ? atoi(t->value) : 0;
4729 if (tmpo) {
4730 size = 26;
4731 avio_wb32(pb, size);
4732 ffio_wfourcc(pb, "tmpo");
4733 avio_wb32(pb, size-8); /* size */
4734 ffio_wfourcc(pb, "data");
4735 avio_wb32(pb, 0x15); //type specifier
4736 avio_wb32(pb, 0);
4737 avio_wb16(pb, tmpo); // data
4738 }
4739 return size;
4740}
4741
4742/* 3GPP TS 26.244 */
4744{
4745 int lang;
4746 int64_t pos = avio_tell(pb);
4747 double latitude, longitude, altitude;
4748 int32_t latitude_fix, longitude_fix, altitude_fix;
4749 AVDictionaryEntry *t = get_metadata_lang(s, "location", &lang);
4750 const char *ptr, *place = "";
4751 char *end;
4752 static const char *astronomical_body = "earth";
4753 if (!t)
4754 return 0;
4755
4756 ptr = t->value;
4757 latitude = strtod(ptr, &end);
4758 if (end == ptr) {
4759 av_log(s, AV_LOG_WARNING, "malformed location metadata\n");
4760 return 0;
4761 }
4762 ptr = end;
4763 longitude = strtod(ptr, &end);
4764 if (end == ptr) {
4765 av_log(s, AV_LOG_WARNING, "malformed location metadata\n");
4766 return 0;
4767 }
4768 ptr = end;
4769 altitude = strtod(ptr, &end);
4770 /* If no altitude was present, the default 0 should be fine */
4771 if (*end == '/')
4772 place = end + 1;
4773
4774 latitude_fix = (int32_t) ((1 << 16) * latitude);
4775 longitude_fix = (int32_t) ((1 << 16) * longitude);
4776 altitude_fix = (int32_t) ((1 << 16) * altitude);
4777
4778 avio_wb32(pb, 0); /* size */
4779 ffio_wfourcc(pb, "loci"); /* type */
4780 avio_wb32(pb, 0); /* version + flags */
4781 avio_wb16(pb, lang);
4782 avio_write(pb, place, strlen(place) + 1);
4783 avio_w8(pb, 0); /* role of place (0 == shooting location, 1 == real location, 2 == fictional location) */
4784 avio_wb32(pb, longitude_fix);
4785 avio_wb32(pb, latitude_fix);
4786 avio_wb32(pb, altitude_fix);
4787 avio_write(pb, astronomical_body, strlen(astronomical_body) + 1);
4788 avio_w8(pb, 0); /* additional notes, null terminated string */
4789
4790 return update_size(pb, pos);
4791}
4792
4793/* iTunes track or disc number */
4795 AVFormatContext *s, int disc)
4796{
4797 AVDictionaryEntry *t = av_dict_get(s->metadata,
4798 disc ? "disc" : "track",
4799 NULL, 0);
4800 int size = 0, track = t ? atoi(t->value) : 0;
4801 if (track) {
4802 int tracks = 0;
4803 char *slash = strchr(t->value, '/');
4804 if (slash)
4805 tracks = atoi(slash + 1);
4806 avio_wb32(pb, 32); /* size */
4807 ffio_wfourcc(pb, disc ? "disk" : "trkn");
4808 avio_wb32(pb, 24); /* size */
4809 ffio_wfourcc(pb, "data");
4810 avio_wb32(pb, 0); // 8 bytes empty
4811 avio_wb32(pb, 0);
4812 avio_wb16(pb, 0); // empty
4813 avio_wb16(pb, track); // track / disc number
4814 avio_wb16(pb, tracks); // total track / disc number
4815 avio_wb16(pb, 0); // empty
4816 size = 32;
4817 }
4818 return size;
4819}
4820
4822 const char *name, const char *tag,
4823 int len)
4824{
4826 uint8_t num;
4827 int size = 24 + len;
4828
4829 if (len != 1 && len != 4)
4830 return -1;
4831
4832 if (!(t = av_dict_get(s->metadata, tag, NULL, 0)))
4833 return 0;
4834 num = atoi(t->value);
4835
4836 avio_wb32(pb, size);
4837 ffio_wfourcc(pb, name);
4838 avio_wb32(pb, size - 8);
4839 ffio_wfourcc(pb, "data");
4840 avio_wb32(pb, 0x15);
4841 avio_wb32(pb, 0);
4842 if (len==4) avio_wb32(pb, num);
4843 else avio_w8 (pb, num);
4844
4845 return size;
4846}
4847
4849{
4850 MOVMuxContext *mov = s->priv_data;
4851 int64_t pos = 0;
4852
4853 for (int i = 0; i < mov->nb_streams; i++) {
4854 MOVTrack *trk = &mov->tracks[i];
4855
4856 if (!is_cover_image(trk->st) || trk->cover_image->size <= 0)
4857 continue;
4858
4859 if (!pos) {
4860 pos = avio_tell(pb);
4861 avio_wb32(pb, 0);
4862 ffio_wfourcc(pb, "covr");
4863 }
4864 avio_wb32(pb, 16 + trk->cover_image->size);
4865 ffio_wfourcc(pb, "data");
4866 avio_wb32(pb, trk->tag);
4867 avio_wb32(pb , 0);
4868 avio_write(pb, trk->cover_image->data, trk->cover_image->size);
4869 }
4870
4871 return pos ? update_size(pb, pos) : 0;
4872}
4873
4874/* iTunes meta data list */
4877{
4878 int64_t pos = avio_tell(pb);
4879 avio_wb32(pb, 0); /* size */
4880 ffio_wfourcc(pb, "ilst");
4881 mov_write_string_metadata(s, pb, "\251nam", "title" , 1);
4882 mov_write_string_metadata(s, pb, "\251ART", "artist" , 1);
4883 mov_write_string_metadata(s, pb, "aART", "album_artist", 1);
4884 mov_write_string_metadata(s, pb, "\251wrt", "composer" , 1);
4885 mov_write_string_metadata(s, pb, "\251alb", "album" , 1);
4886 mov_write_string_metadata(s, pb, "\251day", "date" , 1);
4887 if (!mov_write_string_metadata(s, pb, "\251too", "encoding_tool", 1)) {
4888 if (!(s->flags & AVFMT_FLAG_BITEXACT))
4889 mov_write_string_tag(pb, "\251too", LIBAVFORMAT_IDENT, 0, 1);
4890 }
4891 mov_write_string_metadata(s, pb, "\251cmt", "comment" , 1);
4892 mov_write_string_metadata(s, pb, "\251gen", "genre" , 1);
4893 mov_write_string_metadata(s, pb, "cprt", "copyright", 1);
4894 mov_write_string_metadata(s, pb, "\251grp", "grouping" , 1);
4895 mov_write_string_metadata(s, pb, "\251lyr", "lyrics" , 1);
4896 mov_write_string_metadata(s, pb, "desc", "description",1);
4897 mov_write_string_metadata(s, pb, "ldes", "synopsis" , 1);
4898 mov_write_string_metadata(s, pb, "tvsh", "show" , 1);
4899 mov_write_string_metadata(s, pb, "tven", "episode_id",1);
4900 mov_write_string_metadata(s, pb, "tvnn", "network" , 1);
4901 mov_write_string_metadata(s, pb, "keyw", "keywords" , 1);
4902 mov_write_int8_metadata (s, pb, "tves", "episode_sort",4);
4903 mov_write_int8_metadata (s, pb, "tvsn", "season_number",4);
4904 mov_write_int8_metadata (s, pb, "stik", "media_type",1);
4905 mov_write_int8_metadata (s, pb, "hdvd", "hd_video", 1);
4906 mov_write_int8_metadata (s, pb, "pgap", "gapless_playback",1);
4907 mov_write_int8_metadata (s, pb, "cpil", "compilation", 1);
4908 mov_write_covr(pb, s);
4909 mov_write_trkn_tag(pb, mov, s, 0); // track number
4910 mov_write_trkn_tag(pb, mov, s, 1); // disc number
4911 mov_write_tmpo_tag(pb, s);
4912 mov_write_custom_metadata(s, pb, "com.apple.iTunes", "DISCSUBTITLE", "disc_subtitle");
4913 return update_size(pb, pos);
4914}
4915
4918{
4919 avio_wb32(pb, 33); /* size */
4920 ffio_wfourcc(pb, "hdlr");
4921 avio_wb32(pb, 0);
4922 avio_wb32(pb, 0);
4923 ffio_wfourcc(pb, "mdta");
4924 avio_wb32(pb, 0);
4925 avio_wb32(pb, 0);
4926 avio_wb32(pb, 0);
4927 avio_w8(pb, 0);
4928 return 33;
4929}
4930
4933{
4934 const AVDictionaryEntry *t = NULL;
4935 int64_t pos = avio_tell(pb);
4936 int64_t curpos, entry_pos;
4937 int count = 0;
4938
4939 avio_wb32(pb, 0); /* size */
4940 ffio_wfourcc(pb, "keys");
4941 avio_wb32(pb, 0);
4942 entry_pos = avio_tell(pb);
4943 avio_wb32(pb, 0); /* entry count */
4944
4945 while (t = av_dict_iterate(s->metadata, t)) {
4946 size_t key_len = strlen(t->key);
4947 avio_wb32(pb, key_len + 8);
4948 ffio_wfourcc(pb, "mdta");
4949 avio_write(pb, t->key, key_len);
4950 count += 1;
4951 }
4952 curpos = avio_tell(pb);
4953 avio_seek(pb, entry_pos, SEEK_SET);
4954 avio_wb32(pb, count); // rewrite entry count
4955 avio_seek(pb, curpos, SEEK_SET);
4956
4957 return update_size(pb, pos);
4958}
4959
4962{
4963 const AVDictionaryEntry *t = NULL;
4964 int64_t pos = avio_tell(pb);
4965 int count = 1; /* keys are 1-index based */
4966
4967 avio_wb32(pb, 0); /* size */
4968 ffio_wfourcc(pb, "ilst");
4969
4970 while (t = av_dict_iterate(s->metadata, t)) {
4971 int64_t entry_pos = avio_tell(pb);
4972 avio_wb32(pb, 0); /* size */
4973 avio_wb32(pb, count); /* key */
4974 mov_write_string_data_tag(pb, t->value, 0, 1);
4975 update_size(pb, entry_pos);
4976 count += 1;
4977 }
4978 return update_size(pb, pos);
4979}
4980
4981/* meta data tags */
4984{
4985 int size = 0;
4986 int64_t pos = avio_tell(pb);
4987 avio_wb32(pb, 0); /* size */
4988 ffio_wfourcc(pb, "meta");
4989 avio_wb32(pb, 0);
4990 if (mov->flags & FF_MOV_FLAG_USE_MDTA) {
4991 mov_write_mdta_hdlr_tag(pb, mov, s);
4992 mov_write_mdta_keys_tag(pb, mov, s);
4993 mov_write_mdta_ilst_tag(pb, mov, s);
4994 } else if (mov->mode == MODE_AVIF) {
4995 mov_write_hdlr_tag(s, pb, &mov->tracks[0]);
4996 // We always write the primary item id as 1 since only one track is
4997 // supported for AVIF.
4998 mov_write_pitm_tag(pb, 1);
4999 mov_write_iloc_tag(pb, mov, s);
5000 mov_write_iinf_tag(pb, mov, s);
5001 if (mov->nb_streams > 1)
5002 mov_write_iref_tag(pb, mov, s);
5003 mov_write_iprp_tag(pb, mov, s);
5004 } else {
5005 /* iTunes metadata tag */
5006 mov_write_itunes_hdlr_tag(pb, mov, s);
5007 mov_write_ilst_tag(pb, mov, s);
5008 }
5009 size = update_size(pb, pos);
5010 return size;
5011}
5012
5014 const char *name, const char *key)
5015{
5016 int len;
5018
5019 if (!(t = av_dict_get(s->metadata, key, NULL, 0)))
5020 return 0;
5021
5022 len = strlen(t->value);
5023 if (len > 0) {
5024 int size = len + 8;
5025 avio_wb32(pb, size);
5026 ffio_wfourcc(pb, name);
5027 avio_write(pb, t->value, len);
5028 return size;
5029 }
5030 return 0;
5031}
5032
5033static int ascii_to_wc(AVIOContext *pb, const uint8_t *b)
5034{
5035 int val;
5036 while (*b) {
5037 GET_UTF8(val, *b++, return -1;)
5038 avio_wb16(pb, val);
5039 }
5040 avio_wb16(pb, 0x00);
5041 return 0;
5042}
5043
5044static uint16_t language_code(const char *str)
5045{
5046 return (((str[0] - 0x60) & 0x1F) << 10) +
5047 (((str[1] - 0x60) & 0x1F) << 5) +
5048 (( str[2] - 0x60) & 0x1F);
5049}
5050
5052 const char *tag, const char *str)
5053{
5054 int64_t pos = avio_tell(pb);
5055 AVDictionaryEntry *t = av_dict_get(s->metadata, str, NULL, 0);
5056 if (!t || !utf8len(t->value))
5057 return 0;
5058 avio_wb32(pb, 0); /* size */
5059 ffio_wfourcc(pb, tag); /* type */
5060 avio_wb32(pb, 0); /* version + flags */
5061 if (!strcmp(tag, "yrrc"))
5062 avio_wb16(pb, atoi(t->value));
5063 else {
5064 avio_wb16(pb, language_code("eng")); /* language */
5065 avio_write(pb, t->value, strlen(t->value) + 1); /* UTF8 string value */
5066 if (!strcmp(tag, "albm") &&
5067 (t = av_dict_get(s->metadata, "track", NULL, 0)))
5068 avio_w8(pb, atoi(t->value));
5069 }
5070 return update_size(pb, pos);
5071}
5072
5074{
5075 int64_t pos = avio_tell(pb);
5076 int i, nb_chapters = FFMIN(s->nb_chapters, 255);
5077
5078 avio_wb32(pb, 0); // size
5079 ffio_wfourcc(pb, "chpl");
5080 avio_wb32(pb, 0x01000000); // version + flags
5081 avio_wb32(pb, 0); // unknown
5082 avio_w8(pb, nb_chapters);
5083
5084 for (i = 0; i < nb_chapters; i++) {
5085 AVChapter *c = s->chapters[i];
5087 avio_wb64(pb, av_rescale_q(c->start, c->time_base, (AVRational){1,10000000}));
5088
5089 if ((t = av_dict_get(c->metadata, "title", NULL, 0))) {
5090 int len = FFMIN(strlen(t->value), 255);
5091 avio_w8(pb, len);
5092 avio_write(pb, t->value, len);
5093 } else
5094 avio_w8(pb, 0);
5095 }
5096 return update_size(pb, pos);
5097}
5098
5101{
5102 AVIOContext *pb_buf;
5103 int ret, size;
5104 uint8_t *buf;
5105
5106 ret = avio_open_dyn_buf(&pb_buf);
5107 if (ret < 0)
5108 return ret;
5109
5110 if (mov->mode & MODE_3GP) {
5111 mov_write_3gp_udta_tag(pb_buf, s, "perf", "artist");
5112 mov_write_3gp_udta_tag(pb_buf, s, "titl", "title");
5113 mov_write_3gp_udta_tag(pb_buf, s, "auth", "author");
5114 mov_write_3gp_udta_tag(pb_buf, s, "gnre", "genre");
5115 mov_write_3gp_udta_tag(pb_buf, s, "dscp", "comment");
5116 mov_write_3gp_udta_tag(pb_buf, s, "albm", "album");
5117 mov_write_3gp_udta_tag(pb_buf, s, "cprt", "copyright");
5118 mov_write_3gp_udta_tag(pb_buf, s, "yrrc", "date");
5119 mov_write_loci_tag(s, pb_buf);
5120 } 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
5121 mov_write_string_metadata(s, pb_buf, "\251ART", "artist", 0);
5122 mov_write_string_metadata(s, pb_buf, "\251nam", "title", 0);
5123 mov_write_string_metadata(s, pb_buf, "\251aut", "author", 0);
5124 mov_write_string_metadata(s, pb_buf, "\251alb", "album", 0);
5125 mov_write_string_metadata(s, pb_buf, "\251day", "date", 0);
5126 mov_write_string_metadata(s, pb_buf, "\251swr", "encoder", 0);
5127 // currently ignored by mov.c
5128 mov_write_string_metadata(s, pb_buf, "\251des", "comment", 0);
5129 // add support for libquicktime, this atom is also actually read by mov.c
5130 mov_write_string_metadata(s, pb_buf, "\251cmt", "comment", 0);
5131 mov_write_string_metadata(s, pb_buf, "\251gen", "genre", 0);
5132 mov_write_string_metadata(s, pb_buf, "\251cpy", "copyright", 0);
5133 mov_write_string_metadata(s, pb_buf, "\251mak", "make", 0);
5134 mov_write_string_metadata(s, pb_buf, "\251mod", "model", 0);
5135 mov_write_string_metadata(s, pb_buf, "\251xyz", "location", 0);
5136 mov_write_string_metadata(s, pb_buf, "\251key", "keywords", 0);
5137 mov_write_raw_metadata_tag(s, pb_buf, "XMP_", "xmp");
5138 } else {
5139 /* iTunes meta data */
5140 mov_write_meta_tag(pb_buf, mov, s);
5141 mov_write_loci_tag(s, pb_buf);
5142 }
5143
5144 if (s->nb_chapters && !(mov->flags & FF_MOV_FLAG_DISABLE_CHPL))
5145 mov_write_chpl_tag(pb_buf, s);
5146
5147 if ((size = avio_get_dyn_buf(pb_buf, &buf)) > 0) {
5148 avio_wb32(pb, size + 8);
5149 ffio_wfourcc(pb, "udta");
5150 avio_write(pb, buf, size);
5151 }
5152 ffio_free_dyn_buf(&pb_buf);
5153
5154 return 0;
5155}
5156
5158 const char *str, const char *lang, int type)
5159{
5160 int len = utf8len(str) + 1;
5161 if (len <= 0)
5162 return;
5163 avio_wb16(pb, len * 2 + 10); /* size */
5164 avio_wb32(pb, type); /* type */
5165 avio_wb16(pb, language_code(lang)); /* language */
5166 avio_wb16(pb, 0x01); /* ? */
5167 ascii_to_wc(pb, str);
5168}
5169
5171{
5172 AVDictionaryEntry *title = av_dict_get(s->metadata, "title", NULL, 0);
5173 int64_t pos, pos2;
5174
5175 if (title) {
5176 pos = avio_tell(pb);
5177 avio_wb32(pb, 0); /* size placeholder*/
5178 ffio_wfourcc(pb, "uuid");
5179 ffio_wfourcc(pb, "USMT");
5180 avio_wb32(pb, 0x21d24fce); /* 96 bit UUID */
5181 avio_wb32(pb, 0xbb88695c);
5182 avio_wb32(pb, 0xfac9c740);
5183
5184 pos2 = avio_tell(pb);
5185 avio_wb32(pb, 0); /* size placeholder*/
5186 ffio_wfourcc(pb, "MTDT");
5187 avio_wb16(pb, 4);
5188
5189 // ?
5190 avio_wb16(pb, 0x0C); /* size */
5191 avio_wb32(pb, 0x0B); /* type */
5192 avio_wb16(pb, language_code("und")); /* language */
5193 avio_wb16(pb, 0x0); /* ? */
5194 avio_wb16(pb, 0x021C); /* data */
5195
5196 if (!(s->flags & AVFMT_FLAG_BITEXACT))
5197 mov_write_psp_udta_tag(pb, LIBAVFORMAT_IDENT, "eng", 0x04);
5198 mov_write_psp_udta_tag(pb, title->value, "eng", 0x01);
5199 mov_write_psp_udta_tag(pb, "2006/04/01 11:11:11", "und", 0x03);
5200
5201 update_size(pb, pos2);
5202 return update_size(pb, pos);
5203 }
5204
5205 return 0;
5206}
5207
5209{
5214 if (!sd)
5215 return 0;
5216
5218 for (AVEncryptionInitInfo *copy = info; copy; copy = copy->next) {
5219 int64_t pos;
5220
5221 if (!copy->data_size && !copy->num_key_ids)
5222 continue;
5223
5224 pos = avio_tell(pb);
5225 avio_wb32(pb, 0); /* size placeholder */
5226 ffio_wfourcc(pb, "pssh");
5227 avio_w8(pb, 1); /* version */
5228 avio_wb24(pb, 0);
5229 for (int i = 0; i < copy->system_id_size; i++)
5230 avio_w8(pb, copy->system_id[i]);
5231 avio_wb32(pb, copy->num_key_ids);
5232 for (int i = 0; i < copy->num_key_ids; i++)
5233 for (int j = 0; j < copy->key_id_size; j++)
5234 avio_w8(pb, copy->key_ids[i][j]);
5235 avio_wb32(pb, copy->data_size);
5236 avio_write(pb, copy->data, copy->data_size);
5237 update_size(pb, pos);
5238 }
5239
5241
5242 return 0;
5243}
5244
5245static void build_chunks(MOVTrack *trk)
5246{
5247 int i;
5248 MOVIentry *chunk = &trk->cluster[0];
5249 uint64_t chunkSize = chunk->size;
5250 chunk->chunkNum = 1;
5251 if (trk->chunkCount)
5252 return;
5253 trk->chunkCount = 1;
5254 for (i = 1; i<trk->entry; i++){
5255 if (chunk->pos + chunkSize == trk->cluster[i].pos &&
5256 chunk->stsd_index == trk->cluster[i].stsd_index &&
5257 chunkSize + trk->cluster[i].size < (1<<20)){
5258 chunkSize += trk->cluster[i].size;
5259 chunk->samples_in_chunk += trk->cluster[i].entries;
5260 } else {
5261 trk->cluster[i].chunkNum = chunk->chunkNum+1;
5262 chunk=&trk->cluster[i];
5263 chunkSize = chunk->size;
5264 trk->chunkCount++;
5265 }
5266 }
5267}
5268
5269/**
5270 * Assign track ids. If option "use_stream_ids_as_track_ids" is set,
5271 * the stream ids are used as track ids.
5272 *
5273 * This assumes mov->tracks and s->streams are in the same order and
5274 * there are no gaps in either of them (so mov->tracks[n] refers to
5275 * s->streams[n]).
5276 *
5277 * As an exception, there can be more entries in
5278 * s->streams than in mov->tracks, in which case new track ids are
5279 * generated (starting after the largest found stream id).
5280 */
5282{
5283 int i;
5284
5285 if (mov->track_ids_ok)
5286 return 0;
5287
5288 if (mov->use_stream_ids_as_track_ids) {
5289 int next_generated_track_id = 0;
5290 for (i = 0; i < mov->nb_streams; i++) {
5291 AVStream *st = mov->tracks[i].st;
5292 if (st->id > next_generated_track_id)
5293 next_generated_track_id = st->id;
5294 }
5295
5296 for (i = 0; i < mov->nb_tracks; i++) {
5297 if (mov->tracks[i].entry <= 0 && !(mov->flags & FF_MOV_FLAG_FRAGMENT))
5298 continue;
5299
5300 mov->tracks[i].track_id = i >= mov->nb_streams ? ++next_generated_track_id : mov->tracks[i].st->id;
5301 }
5302 } else {
5303 int last_track_id = 0;
5304 for (i = 0; i < mov->nb_tracks; i++) {
5305 if (mov->tracks[i].entry <= 0 && !(mov->flags & FF_MOV_FLAG_FRAGMENT))
5306 continue;
5307
5308 last_track_id =
5309 mov->tracks[i].track_id = (mov->tracks[i].st
5310 ? FFMAX(mov->tracks[i].st->index, last_track_id)
5311 : FFMAX(i, last_track_id)) + 1;
5312 }
5313 }
5314
5315 mov->track_ids_ok = 1;
5316
5317 return 0;
5318}
5319
5320static int mov_find_tref_id(MOVMuxContext *mov, const MovTag *tag, uint32_t id)
5321{
5322 for (int i = 0; i < tag->nb_id; i++) {
5323 if (tag->id[i] == id)
5324 return 1;
5325 }
5326 return 0;
5327}
5328
5329static int mov_add_tref_id(MOVMuxContext *mov, MovTag *tag, uint32_t id)
5330{
5331 int ret = mov_find_tref_id(mov, tag, id);
5332
5333 if (!ret) {
5334 uint32_t *tmp = av_realloc_array(tag->id, tag->nb_id + 1, sizeof(*tag->id));
5335 if (!tmp)
5336 return AVERROR(ENOMEM);
5337 tag->id = tmp;
5338 tag->id[tag->nb_id++] = id;
5339 }
5340
5341 return 0;
5342}
5343
5344static MovTag *mov_find_tref_tag(MOVMuxContext *mov, const MOVTrack *trk, uint32_t name)
5345{
5346 for (int i = 0; i < trk->nb_tref_tags; i++) {
5347 MovTag *entry = &trk->tref_tags[i];
5348
5349 if (entry->name == name)
5350 return entry;
5351 }
5352 return NULL;
5353}
5354
5356{
5357 MovTag *tag = mov_find_tref_tag(mov, trk, name);
5358
5359 if (!tag) {
5361 sizeof(*trk->tref_tags));
5362 if (!tmp)
5363 return NULL;
5364 trk->tref_tags = tmp;
5365 tag = &trk->tref_tags[trk->nb_tref_tags++];
5366 *tag = (MovTag){ .name = name };
5367 }
5368
5369 return tag;
5370}
5371
5374{
5375 int i;
5376 int64_t pos = avio_tell(pb);
5377 avio_wb32(pb, 0); /* size placeholder*/
5378 ffio_wfourcc(pb, "moov");
5379
5380 mov_setup_track_ids(mov, s);
5381
5382 for (i = 0; i < mov->nb_tracks; i++) {
5383 if (mov->tracks[i].entry <= 0 && !(mov->flags & FF_MOV_FLAG_FRAGMENT))
5384 continue;
5385
5386 mov->tracks[i].time = mov->time;
5387
5388 if (mov->tracks[i].entry)
5389 build_chunks(&mov->tracks[i]);
5390 }
5391
5392 if (mov->chapter_track)
5393 for (i = 0; i < mov->nb_streams; i++) {
5394 MovTag *tag = mov_add_tref_tag(mov, &mov->tracks[i], MKTAG('c','h','a','p'));
5395 if (!tag)
5396 return AVERROR(ENOMEM);
5397
5398 int ret = mov_add_tref_id(mov, tag, mov->tracks[mov->chapter_track].track_id);
5399 if (ret < 0)
5400 return ret;
5401 }
5402 for (i = 0; i < mov->nb_tracks; i++) {
5403 MOVTrack *track = &mov->tracks[i];
5404 if (track->tag == MKTAG('r','t','p',' ')) {
5405 MovTag *tag = mov_add_tref_tag(mov, track, MKTAG('h','i','n','t'));
5406 if (!tag)
5407 return AVERROR(ENOMEM);
5408
5409 av_assert0(track->nb_src_track);
5410 int ret = mov_add_tref_id(mov, tag, mov->tracks[*track->src_track].track_id);
5411 if (ret < 0)
5412 return ret;
5413 } else if (track->tag == MKTAG('l','v','c','1') && track->nb_src_track) {
5414 MovTag *tag = mov_add_tref_tag(mov, track, MKTAG('s','b','a','s'));
5415 if (!tag)
5416 return AVERROR(ENOMEM);
5417
5418 int ret = mov_add_tref_id(mov, tag, mov->tracks[*track->src_track].track_id);
5419 if (ret < 0)
5420 return ret;
5421 } else {
5422 if (track->par->codec_type == AVMEDIA_TYPE_AUDIO) {
5426 if (sd && sd->size == sizeof(int)) {
5427 int *fallback = (int *)sd->data;
5428 if (*fallback >= 0 && *fallback < mov->nb_tracks) {
5429 MovTag *tag = mov_add_tref_tag(mov, track, MKTAG('f','a','l','l'));
5430 if (!tag)
5431 return AVERROR(ENOMEM);
5432
5433 int ret = mov_add_tref_id(mov, tag, mov->tracks[*fallback].track_id);
5434 if (ret < 0)
5435 return ret;
5436 }
5437 }
5438 }
5439 for (int j = 0; j < track->nb_src_track; j++) {
5440 int src_trk = track->src_track[j];
5441 MovTag *tag = mov_add_tref_tag(mov, &mov->tracks[src_trk], track->tag);
5442 if (!tag)
5443 return AVERROR(ENOMEM);
5444 int ret = mov_add_tref_id(mov, tag, track->track_id);
5445 if (ret < 0)
5446 return ret;
5447 }
5448 if (mov->nb_meta_tmcd && track->nb_src_track) {
5449 /* Derive the duration from the first source track, matching
5450 * the convention used by get_pts_range() and the rtp/lvc1
5451 * branches above. The source may use a different timescale. */
5452 int src_trk = track->src_track[0];
5453 track->track_duration = av_rescale(mov->tracks[src_trk].track_duration,
5454 track->timescale,
5455 mov->tracks[src_trk].timescale);
5456 }
5457 }
5458 }
5459
5460 mov_write_mvhd_tag(pb, mov);
5461 if (mov->mode != MODE_MOV && mov->mode != MODE_AVIF && !mov->iods_skip)
5462 mov_write_iods_tag(pb, mov);
5463 for (i = 0; i < mov->nb_tracks; i++) {
5464 if (mov->tracks[i].entry > 0 || mov->flags & FF_MOV_FLAG_FRAGMENT ||
5465 mov->mode == MODE_AVIF) {
5466 int ret = mov_write_trak_tag(s, pb, mov, &(mov->tracks[i]), i < mov->nb_streams ? mov->tracks[i].st : NULL);
5467 if (ret < 0)
5468 return ret;
5469 }
5470 }
5471 /* Don't write mvex for hybrid_fragmented during mov_write_trailer
5472 * (mov->moov_written != 0)
5473 */
5474 if (mov->flags & FF_MOV_FLAG_FRAGMENT &&
5476 mov_write_mvex_tag(pb, mov); /* QuickTime requires trak to precede this */
5477
5478 if (mov->mode == MODE_PSP)
5480 else if (mov->mode != MODE_AVIF)
5481 mov_write_udta_tag(pb, mov, s);
5482 for (i = 0; i < mov->nb_streams; i++)
5483 mov_write_pssh_tag(pb, mov->tracks[i].st);
5484
5485 return update_size(pb, pos);
5486}
5487
5488static void param_write_int(AVIOContext *pb, const char *name, int value)
5489{
5490 avio_printf(pb, "<param name=\"%s\" value=\"%d\" valuetype=\"data\"/>\n", name, value);
5491}
5492
5493static void param_write_string(AVIOContext *pb, const char *name, const char *value)
5494{
5495 avio_printf(pb, "<param name=\"%s\" value=\"%s\" valuetype=\"data\"/>\n", name, value);
5496}
5497
5498static void param_write_hex(AVIOContext *pb, const char *name, const uint8_t *value, int len)
5499{
5500 char buf[150];
5501 len = FFMIN(sizeof(buf) / 2 - 1, len);
5502 ff_data_to_hex(buf, value, len, 0);
5503 avio_printf(pb, "<param name=\"%s\" value=\"%s\" valuetype=\"data\"/>\n", name, buf);
5504}
5505
5507{
5508 int64_t pos = avio_tell(pb);
5509 int i;
5510
5511 static const AVUUID uuid = {
5512 0xa5, 0xd4, 0x0b, 0x30, 0xe8, 0x14, 0x11, 0xdd,
5513 0xba, 0x2f, 0x08, 0x00, 0x20, 0x0c, 0x9a, 0x66
5514 };
5515
5516 avio_wb32(pb, 0);
5517 ffio_wfourcc(pb, "uuid");
5518 avio_write(pb, uuid, AV_UUID_LEN);
5519 avio_wb32(pb, 0);
5520
5521 avio_printf(pb, "<?xml version=\"1.0\" encoding=\"utf-8\"?>\n");
5522 avio_printf(pb, "<smil xmlns=\"http://www.w3.org/2001/SMIL20/Language\">\n");
5523 avio_printf(pb, "<head>\n");
5524 if (!(mov->fc->flags & AVFMT_FLAG_BITEXACT))
5525 avio_printf(pb, "<meta name=\"creator\" content=\"%s\" />\n",
5527 avio_printf(pb, "</head>\n");
5528 avio_printf(pb, "<body>\n");
5529 avio_printf(pb, "<switch>\n");
5530
5531 mov_setup_track_ids(mov, s);
5532
5533 for (i = 0; i < mov->nb_tracks; i++) {
5534 MOVTrack *track = &mov->tracks[i];
5535 struct mpeg4_bit_rate_values bit_rates =
5537 const char *type;
5538 int track_id = track->track_id;
5539 char track_name_buf[32] = { 0 };
5540
5541 AVStream *st = track->st;
5542 AVDictionaryEntry *lang = av_dict_get(st->metadata, "language", NULL,0);
5543
5544 if (track->par->codec_type == AVMEDIA_TYPE_VIDEO && !is_cover_image(st)) {
5545 type = "video";
5546 } else if (track->par->codec_type == AVMEDIA_TYPE_AUDIO) {
5547 type = "audio";
5548 } else {
5549 continue;
5550 }
5551
5552 avio_printf(pb, "<%s systemBitrate=\"%"PRIu32"\">\n", type,
5553 bit_rates.avg_bit_rate);
5554 param_write_int(pb, "systemBitrate", bit_rates.avg_bit_rate);
5555 param_write_int(pb, "trackID", track_id);
5556 param_write_string(pb, "systemLanguage", lang ? lang->value : "und");
5557
5558 /* Build track name piece by piece: */
5559 /* 1. track type */
5560 av_strlcat(track_name_buf, type, sizeof(track_name_buf));
5561 /* 2. track language, if available */
5562 if (lang)
5563 av_strlcatf(track_name_buf, sizeof(track_name_buf),
5564 "_%s", lang->value);
5565 /* 3. special type suffix */
5566 /* "_cc" = closed captions, "_ad" = audio_description */
5568 av_strlcat(track_name_buf, "_cc", sizeof(track_name_buf));
5570 av_strlcat(track_name_buf, "_ad", sizeof(track_name_buf));
5571
5572 param_write_string(pb, "trackName", track_name_buf);
5573
5574 if (track->par->codec_type == AVMEDIA_TYPE_VIDEO) {
5575 if (track->par->codec_id == AV_CODEC_ID_H264) {
5576 uint8_t *ptr;
5577 int size = track->extradata_size[track->last_stsd_index];
5579 &size)) {
5580 param_write_hex(pb, "CodecPrivateData",
5581 ptr ? ptr : track->extradata[track->last_stsd_index],
5582 size);
5583 av_free(ptr);
5584 }
5585 param_write_string(pb, "FourCC", "H264");
5586 } else if (track->par->codec_id == AV_CODEC_ID_VC1) {
5587 param_write_string(pb, "FourCC", "WVC1");
5588 param_write_hex(pb, "CodecPrivateData", track->extradata[track->last_stsd_index],
5589 track->extradata_size[track->last_stsd_index]);
5590 }
5591 param_write_int(pb, "MaxWidth", track->par->width);
5592 param_write_int(pb, "MaxHeight", track->par->height);
5593 param_write_int(pb, "DisplayWidth", track->par->width);
5594 param_write_int(pb, "DisplayHeight", track->par->height);
5595 } else {
5596 if (track->par->codec_id == AV_CODEC_ID_AAC) {
5597 switch (track->par->profile) {
5599 param_write_string(pb, "FourCC", "AACP");
5600 break;
5601 case AV_PROFILE_AAC_HE:
5602 param_write_string(pb, "FourCC", "AACH");
5603 break;
5604 default:
5605 param_write_string(pb, "FourCC", "AACL");
5606 }
5607 } else if (track->par->codec_id == AV_CODEC_ID_WMAPRO) {
5608 param_write_string(pb, "FourCC", "WMAP");
5609 }
5610 param_write_hex(pb, "CodecPrivateData", track->extradata[track->last_stsd_index],
5611 track->extradata_size[track->last_stsd_index]);
5613 track->par->codec_id));
5614 param_write_int(pb, "Channels", track->par->ch_layout.nb_channels);
5615 param_write_int(pb, "SamplingRate", track->tag == MKTAG('i','a','m','f') ?
5616 0 : track->par->sample_rate);
5617 param_write_int(pb, "BitsPerSample", 16);
5618 param_write_int(pb, "PacketSize", track->par->block_align ?
5619 track->par->block_align : 4);
5620 }
5621 avio_printf(pb, "</%s>\n", type);
5622 }
5623 avio_printf(pb, "</switch>\n");
5624 avio_printf(pb, "</body>\n");
5625 avio_printf(pb, "</smil>\n");
5626
5627 return update_size(pb, pos);
5628}
5629
5631{
5632 avio_wb32(pb, 16);
5633 ffio_wfourcc(pb, "mfhd");
5634 avio_wb32(pb, 0);
5635 avio_wb32(pb, mov->fragments);
5636 return 0;
5637}
5638
5644
5646 MOVTrack *track, int64_t moof_offset)
5647{
5648 int64_t pos = avio_tell(pb);
5651 if (!track->entry) {
5653 } else {
5655 }
5661 }
5662 /* CMAF requires all values to be explicit in tfhd atoms */
5663 if (mov->flags & FF_MOV_FLAG_CMAF)
5665
5666 /* Don't set a default sample size, the silverlight player refuses
5667 * to play files with that set. Don't set a default sample duration,
5668 * WMP freaks out if it is set. Don't set a base data offset, PIFF
5669 * file format says it MUST NOT be set. */
5670 if (track->mode == MODE_ISM)
5673
5674 avio_wb32(pb, 0); /* size placeholder */
5675 ffio_wfourcc(pb, "tfhd");
5676 avio_w8(pb, 0); /* version */
5677 avio_wb24(pb, flags);
5678
5679 avio_wb32(pb, track->track_id); /* track-id */
5681 avio_wb64(pb, moof_offset);
5682 if (flags & MOV_TFHD_STSD_ID) {
5683 avio_wb32(pb, 1);
5684 }
5686 track->default_duration = get_cluster_duration(track, 0);
5687 avio_wb32(pb, track->default_duration);
5688 }
5690 track->default_size = track->entry ? track->cluster[0].size : 1;
5691 avio_wb32(pb, track->default_size);
5692 } else
5693 track->default_size = -1;
5694
5696 /* Set the default flags based on the second sample, if available.
5697 * If the first sample is different, that can be signaled via a separate field. */
5698 if (track->entry > 1)
5699 track->default_sample_flags = get_sample_flags(track, &track->cluster[1]);
5700 else
5701 track->default_sample_flags =
5702 track->par->codec_type == AVMEDIA_TYPE_VIDEO ?
5705 avio_wb32(pb, track->default_sample_flags);
5706 }
5707
5708 return update_size(pb, pos);
5709}
5710
5712 MOVTrack *track, int moof_size,
5713 int first, int end)
5714{
5715 int64_t pos = avio_tell(pb);
5716 uint32_t flags = MOV_TRUN_DATA_OFFSET;
5717 int i;
5718
5719 for (i = first; i < end; i++) {
5720 if (get_cluster_duration(track, i) != track->default_duration)
5722 if (track->cluster[i].size != track->default_size)
5724 if (i > first && get_sample_flags(track, &track->cluster[i]) != track->default_sample_flags)
5726 }
5727 if (!(flags & MOV_TRUN_SAMPLE_FLAGS) && track->entry > first &&
5728 get_sample_flags(track, &track->cluster[first]) != track->default_sample_flags)
5730 if (track->flags & MOV_TRACK_CTTS)
5732
5733 avio_wb32(pb, 0); /* size placeholder */
5734 ffio_wfourcc(pb, "trun");
5736 avio_w8(pb, 1); /* version */
5737 else
5738 avio_w8(pb, 0); /* version */
5739 avio_wb24(pb, flags);
5740
5741 avio_wb32(pb, end - first); /* sample count */
5744 !mov->first_trun)
5745 avio_wb32(pb, 0); /* Later tracks follow immediately after the previous one */
5746 else
5747 avio_wb32(pb, moof_size + 8 + track->data_offset +
5748 track->cluster[first].pos); /* data offset */
5750 avio_wb32(pb, get_sample_flags(track, &track->cluster[first]));
5751
5752 for (i = first; i < end; i++) {
5754 avio_wb32(pb, get_cluster_duration(track, i));
5756 avio_wb32(pb, track->cluster[i].size);
5758 avio_wb32(pb, get_sample_flags(track, &track->cluster[i]));
5760 avio_wb32(pb, track->cluster[i].cts);
5761 }
5762
5763 mov->first_trun = 0;
5764 return update_size(pb, pos);
5765}
5766
5768{
5769 int64_t pos = avio_tell(pb);
5770 static const uint8_t uuid[] = {
5771 0x6d, 0x1d, 0x9b, 0x05, 0x42, 0xd5, 0x44, 0xe6,
5772 0x80, 0xe2, 0x14, 0x1d, 0xaf, 0xf7, 0x57, 0xb2
5773 };
5774
5775 avio_wb32(pb, 0); /* size placeholder */
5776 ffio_wfourcc(pb, "uuid");
5777 avio_write(pb, uuid, AV_UUID_LEN);
5778 avio_w8(pb, 1);
5779 avio_wb24(pb, 0);
5780 avio_wb64(pb, track->cluster[0].dts + track->cluster[0].cts);
5781 avio_wb64(pb, track->end_pts -
5782 (track->cluster[0].dts + track->cluster[0].cts));
5783
5784 return update_size(pb, pos);
5785}
5786
5788 MOVTrack *track, int entry)
5789{
5790 int n = track->nb_frag_info - 1 - entry, i;
5791 int size = 8 + 16 + 4 + 1 + 16*n;
5792 static const uint8_t uuid[] = {
5793 0xd4, 0x80, 0x7e, 0xf2, 0xca, 0x39, 0x46, 0x95,
5794 0x8e, 0x54, 0x26, 0xcb, 0x9e, 0x46, 0xa7, 0x9f
5795 };
5796
5797 if (entry < 0)
5798 return 0;
5799
5800 avio_seek(pb, track->frag_info[entry].tfrf_offset, SEEK_SET);
5801 avio_wb32(pb, size);
5802 ffio_wfourcc(pb, "uuid");
5803 avio_write(pb, uuid, AV_UUID_LEN);
5804 avio_w8(pb, 1);
5805 avio_wb24(pb, 0);
5806 avio_w8(pb, n);
5807 for (i = 0; i < n; i++) {
5808 int index = entry + 1 + i;
5809 avio_wb64(pb, track->frag_info[index].time);
5810 avio_wb64(pb, track->frag_info[index].duration);
5811 }
5812 if (n < mov->ism_lookahead) {
5813 int free_size = 16 * (mov->ism_lookahead - n);
5814 avio_wb32(pb, free_size);
5815 ffio_wfourcc(pb, "free");
5816 ffio_fill(pb, 0, free_size - 8);
5817 }
5818
5819 return 0;
5820}
5821
5823 MOVTrack *track)
5824{
5825 int64_t pos = avio_tell(pb);
5826 int i;
5827 for (i = 0; i < mov->ism_lookahead; i++) {
5828 /* Update the tfrf tag for the last ism_lookahead fragments,
5829 * nb_frag_info - 1 is the next fragment to be written. */
5830 mov_write_tfrf_tag(pb, mov, track, track->nb_frag_info - 2 - i);
5831 }
5832 avio_seek(pb, pos, SEEK_SET);
5833 return 0;
5834}
5835
5836static int mov_add_tfra_entries(AVIOContext *pb, MOVMuxContext *mov, int tracks,
5837 int size)
5838{
5839 int i;
5840 for (i = 0; i < mov->nb_tracks; i++) {
5841 MOVTrack *track = &mov->tracks[i];
5842 MOVFragmentInfo *info;
5843 if ((tracks >= 0 && i != tracks) || !track->entry)
5844 continue;
5845 track->nb_frag_info++;
5846 if (track->nb_frag_info >= track->frag_info_capacity) {
5847 unsigned new_capacity = track->nb_frag_info + MOV_FRAG_INFO_ALLOC_INCREMENT;
5848 if (av_reallocp_array(&track->frag_info,
5849 new_capacity,
5850 sizeof(*track->frag_info)))
5851 return AVERROR(ENOMEM);
5852 track->frag_info_capacity = new_capacity;
5853 }
5854 info = &track->frag_info[track->nb_frag_info - 1];
5855 info->offset = avio_tell(pb);
5856 info->size = size;
5857 // Try to recreate the original pts for the first packet
5858 // from the fields we have stored
5859 info->time = track->cluster[0].dts + track->cluster[0].cts;
5860 info->duration = track->end_pts -
5861 (track->cluster[0].dts + track->cluster[0].cts);
5862 // If the pts is less than zero, we will have trimmed
5863 // away parts of the media track using an edit list,
5864 // and the corresponding start presentation time is zero.
5865 if (info->time < 0) {
5866 info->duration += info->time;
5867 info->time = 0;
5868 }
5869 info->tfrf_offset = 0;
5870 mov_write_tfrf_tags(pb, mov, track);
5871 }
5872 return 0;
5873}
5874
5875static void mov_prune_frag_info(MOVMuxContext *mov, int tracks, int max)
5876{
5877 int i;
5878 for (i = 0; i < mov->nb_tracks; i++) {
5879 MOVTrack *track = &mov->tracks[i];
5880 if ((tracks >= 0 && i != tracks) || !track->entry)
5881 continue;
5882 if (track->nb_frag_info > max) {
5883 memmove(track->frag_info, track->frag_info + (track->nb_frag_info - max), max * sizeof(*track->frag_info));
5884 track->nb_frag_info = max;
5885 }
5886 }
5887}
5888
5890{
5891 int64_t pos = avio_tell(pb);
5892
5893 avio_wb32(pb, 0); /* size */
5894 ffio_wfourcc(pb, "tfdt");
5895 avio_w8(pb, 1); /* version */
5896 avio_wb24(pb, 0);
5897 avio_wb64(pb, track->cluster[0].dts - track->start_dts);
5898 return update_size(pb, pos);
5899}
5900
5902 MOVTrack *track, int64_t moof_offset,
5903 int moof_size)
5904{
5905 int64_t pos = avio_tell(pb);
5906 int i, start = 0;
5907 avio_wb32(pb, 0); /* size placeholder */
5908 ffio_wfourcc(pb, "traf");
5909
5910 mov_write_tfhd_tag(pb, mov, track, moof_offset);
5911 if (mov->mode != MODE_ISM)
5912 mov_write_tfdt_tag(pb, track);
5913 for (i = 1; i < track->entry; i++) {
5914 if (track->cluster[i].pos != track->cluster[i - 1].pos + track->cluster[i - 1].size) {
5915 mov_write_trun_tag(pb, mov, track, moof_size, start, i);
5916 start = i;
5917 }
5918 }
5919 mov_write_trun_tag(pb, mov, track, moof_size, start, track->entry);
5920 if (mov->mode == MODE_ISM) {
5921 mov_write_tfxd_tag(pb, track);
5922
5923 if (mov->ism_lookahead) {
5924 int size = 16 + 4 + 1 + 16 * mov->ism_lookahead;
5925
5926 if (track->nb_frag_info > 0) {
5927 MOVFragmentInfo *info = &track->frag_info[track->nb_frag_info - 1];
5928 if (!info->tfrf_offset)
5929 info->tfrf_offset = avio_tell(pb);
5930 }
5931 avio_wb32(pb, 8 + size);
5932 ffio_wfourcc(pb, "free");
5933 ffio_fill(pb, 0, size);
5934 }
5935 }
5936
5937 if (track->cenc.aes_ctr && (mov->flags & FF_MOV_FLAG_FRAGMENT))
5938 ff_mov_cenc_write_stbl_atoms(&track->cenc, pb, moof_offset);
5939
5940 return update_size(pb, pos);
5941}
5942
5944 int tracks, int moof_size)
5945{
5946 int64_t pos = avio_tell(pb);
5947 int i;
5948
5949 avio_wb32(pb, 0); /* size placeholder */
5950 ffio_wfourcc(pb, "moof");
5951 mov->first_trun = 1;
5952
5953 mov_write_mfhd_tag(pb, mov);
5954 for (i = 0; i < mov->nb_tracks; i++) {
5955 MOVTrack *track = &mov->tracks[i];
5956 if (tracks >= 0 && i != tracks)
5957 continue;
5958 if (!track->entry)
5959 continue;
5960 if (track->cenc.aes_ctr && (mov->flags & FF_MOV_FLAG_FRAGMENT))
5961 mov_write_pssh_tag(pb, track->st);
5962 mov_write_traf_tag(pb, mov, track, pos, moof_size);
5963 }
5964
5965 return update_size(pb, pos);
5966}
5967
5969 MOVTrack *track, int ref_size, int total_sidx_size)
5970{
5971 int64_t pos = avio_tell(pb), offset_pos, end_pos;
5972 int64_t presentation_time, duration, offset;
5973 unsigned starts_with_SAP;
5974 int i, entries;
5975
5976 if (track->entry) {
5977 entries = 1;
5978 presentation_time = track->cluster[0].dts + track->cluster[0].cts;
5979 duration = track->end_pts -
5980 (track->cluster[0].dts + track->cluster[0].cts);
5981 starts_with_SAP = track->cluster[0].flags & MOV_SYNC_SAMPLE;
5982
5983 // pts<0 should be cut away using edts
5984 if (presentation_time < 0) {
5985 duration += presentation_time;
5986 presentation_time = 0;
5987 }
5988 } else {
5989 entries = track->nb_frag_info;
5990 if (entries <= 0)
5991 return 0;
5992 presentation_time = track->frag_info[0].time;
5993 }
5994
5995 avio_wb32(pb, 0); /* size */
5996 ffio_wfourcc(pb, "sidx");
5997 avio_w8(pb, 1); /* version */
5998 avio_wb24(pb, 0);
5999 avio_wb32(pb, track->track_id); /* reference_ID */
6000 avio_wb32(pb, track->timescale); /* timescale */
6001 avio_wb64(pb, presentation_time); /* earliest_presentation_time */
6002 offset_pos = avio_tell(pb);
6003 avio_wb64(pb, 0); /* first_offset (offset to referenced moof) */
6004 avio_wb16(pb, 0); /* reserved */
6005
6006 avio_wb16(pb, entries); /* reference_count */
6007 for (i = 0; i < entries; i++) {
6008 if (!track->entry) {
6009 if (i > 1 && track->frag_info[i].offset != track->frag_info[i - 1].offset + track->frag_info[i - 1].size) {
6010 av_log(NULL, AV_LOG_ERROR, "Non-consecutive fragments, writing incorrect sidx\n");
6011 }
6012 duration = track->frag_info[i].duration;
6013 ref_size = track->frag_info[i].size;
6014 starts_with_SAP = 1;
6015 }
6016 avio_wb32(pb, (0 << 31) | (ref_size & 0x7fffffff)); /* reference_type (0 = media) | referenced_size */
6017 avio_wb32(pb, duration); /* subsegment_duration */
6018 avio_wb32(pb, (starts_with_SAP << 31) | (0 << 28) | 0); /* starts_with_SAP | SAP_type | SAP_delta_time */
6019 }
6020
6021 end_pos = avio_tell(pb);
6022 offset = pos + total_sidx_size - end_pos;
6023 avio_seek(pb, offset_pos, SEEK_SET);
6024 avio_wb64(pb, offset);
6025 avio_seek(pb, end_pos, SEEK_SET);
6026 return update_size(pb, pos);
6027}
6028
6030 int tracks, int ref_size)
6031{
6032 int i, round, ret;
6033 AVIOContext *avio_buf;
6034 int total_size = 0;
6035 for (round = 0; round < 2; round++) {
6036 // First run one round to calculate the total size of all
6037 // sidx atoms.
6038 // This would be much simpler if we'd only write one sidx
6039 // atom, for the first track in the moof.
6040 if (round == 0) {
6041 if ((ret = ffio_open_null_buf(&avio_buf)) < 0)
6042 return ret;
6043 } else {
6044 avio_buf = pb;
6045 }
6046 for (i = 0; i < mov->nb_tracks; i++) {
6047 MOVTrack *track = &mov->tracks[i];
6048 if (tracks >= 0 && i != tracks)
6049 continue;
6050 // When writing a sidx for the full file, entry is 0, but
6051 // we want to include all tracks. ref_size is 0 in this case,
6052 // since we read it from frag_info instead.
6053 if (!track->entry && ref_size > 0)
6054 continue;
6055 total_size -= mov_write_sidx_tag(avio_buf, track, ref_size,
6056 total_size);
6057 }
6058 if (round == 0) {
6059 total_size = ffio_close_null_buf(avio_buf);
6060 if (total_size < 0)
6061 return total_size;
6062 }
6063 }
6064 return 0;
6065}
6066
6067static int mov_write_prft_tag(AVIOContext *pb, MOVMuxContext *mov, int tracks)
6068{
6069 int64_t pos = avio_tell(pb), pts_us, ntp_ts;
6070 MOVTrack *first_track;
6071 int flags = 24;
6072
6073 /* PRFT should be associated with at most one track. So, choosing only the
6074 * first track. */
6075 if (tracks > 0)
6076 return 0;
6077 first_track = &(mov->tracks[0]);
6078
6079 if (!first_track->entry) {
6080 av_log(mov->fc, AV_LOG_WARNING, "Unable to write PRFT, no entries in the track\n");
6081 return 0;
6082 }
6083
6084 if (first_track->cluster[0].pts == AV_NOPTS_VALUE) {
6085 av_log(mov->fc, AV_LOG_WARNING, "Unable to write PRFT, first PTS is invalid\n");
6086 return 0;
6087 }
6088
6089 if (mov->write_prft == MOV_PRFT_SRC_WALLCLOCK) {
6090 if (first_track->cluster[0].prft.wallclock) {
6091 /* Round the NTP time to whole milliseconds. */
6092 ntp_ts = ff_get_formatted_ntp_time((first_track->cluster[0].prft.wallclock / 1000) * 1000 +
6094 flags = first_track->cluster[0].prft.flags;
6095 } else
6097 } else if (mov->write_prft == MOV_PRFT_SRC_PTS) {
6098 pts_us = av_rescale_q(first_track->cluster[0].pts,
6099 first_track->st->time_base, AV_TIME_BASE_Q);
6100 ntp_ts = ff_get_formatted_ntp_time(pts_us + NTP_OFFSET_US);
6101 } else {
6102 av_log(mov->fc, AV_LOG_WARNING, "Unsupported PRFT box configuration: %d\n",
6103 mov->write_prft);
6104 return 0;
6105 }
6106
6107 avio_wb32(pb, 0); // Size place holder
6108 ffio_wfourcc(pb, "prft"); // Type
6109 avio_w8(pb, 1); // Version
6110 avio_wb24(pb, flags); // Flags
6111 avio_wb32(pb, first_track->track_id); // reference track ID
6112 avio_wb64(pb, ntp_ts); // NTP time stamp
6113 avio_wb64(pb, first_track->cluster[0].pts); //media time
6114 return update_size(pb, pos);
6115}
6116
6117static int mov_write_moof_tag(AVIOContext *pb, MOVMuxContext *mov, int tracks,
6118 int64_t mdat_size)
6119{
6120 AVIOContext *avio_buf;
6121 int ret, moof_size;
6122
6123 if ((ret = ffio_open_null_buf(&avio_buf)) < 0)
6124 return ret;
6125 mov_write_moof_tag_internal(avio_buf, mov, tracks, 0);
6126 moof_size = ffio_close_null_buf(avio_buf);
6127 if (moof_size < 0)
6128 return moof_size;
6129
6130 if (mov->flags & FF_MOV_FLAG_DASH &&
6132 mov_write_sidx_tags(pb, mov, tracks, moof_size + 8 + mdat_size);
6133
6134 if (mov->write_prft > MOV_PRFT_NONE && mov->write_prft < MOV_PRFT_NB)
6135 mov_write_prft_tag(pb, mov, tracks);
6136
6137 if (mov->flags & FF_MOV_FLAG_GLOBAL_SIDX ||
6138 !(mov->flags & FF_MOV_FLAG_SKIP_TRAILER) ||
6139 mov->ism_lookahead) {
6140 if ((ret = mov_add_tfra_entries(pb, mov, tracks, moof_size + 8 + mdat_size)) < 0)
6141 return ret;
6142 if (!(mov->flags & FF_MOV_FLAG_GLOBAL_SIDX) &&
6144 mov_prune_frag_info(mov, tracks, mov->ism_lookahead + 1);
6145 }
6146 }
6147
6148 return mov_write_moof_tag_internal(pb, mov, tracks, moof_size);
6149}
6150
6152{
6153 int64_t pos = avio_tell(pb);
6154 int i;
6155
6156 avio_wb32(pb, 0); /* size placeholder */
6157 ffio_wfourcc(pb, "tfra");
6158 avio_w8(pb, 1); /* version */
6159 avio_wb24(pb, 0);
6160
6161 avio_wb32(pb, track->track_id);
6162 avio_wb32(pb, 0); /* length of traf/trun/sample num */
6163 avio_wb32(pb, track->nb_frag_info);
6164 for (i = 0; i < track->nb_frag_info; i++) {
6165 avio_wb64(pb, track->frag_info[i].time);
6166 avio_wb64(pb, track->frag_info[i].offset + track->data_offset);
6167 avio_w8(pb, 1); /* traf number */
6168 avio_w8(pb, 1); /* trun number */
6169 avio_w8(pb, 1); /* sample number */
6170 }
6171
6172 return update_size(pb, pos);
6173}
6174
6176{
6177 AVIOContext *mfra_pb;
6178 int i, ret, sz;
6179 uint8_t *buf;
6180
6181 ret = avio_open_dyn_buf(&mfra_pb);
6182 if (ret < 0)
6183 return ret;
6184
6185 avio_wb32(mfra_pb, 0); /* size placeholder */
6186 ffio_wfourcc(mfra_pb, "mfra");
6187 /* An empty mfra atom is enough to indicate to the publishing point that
6188 * the stream has ended. */
6189 if (mov->flags & FF_MOV_FLAG_ISML)
6190 goto done_mfra;
6191
6192 for (i = 0; i < mov->nb_tracks; i++) {
6193 MOVTrack *track = &mov->tracks[i];
6194 if (track->nb_frag_info)
6195 mov_write_tfra_tag(mfra_pb, track);
6196 }
6197
6198 avio_wb32(mfra_pb, 16);
6199 ffio_wfourcc(mfra_pb, "mfro");
6200 avio_wb32(mfra_pb, 0); /* version + flags */
6201 avio_wb32(mfra_pb, avio_tell(mfra_pb) + 4);
6202
6203done_mfra:
6204
6205 sz = update_size(mfra_pb, 0);
6206 ret = avio_get_dyn_buf(mfra_pb, &buf);
6207 avio_write(pb, buf, ret);
6208 ffio_free_dyn_buf(&mfra_pb);
6209
6210 return sz;
6211}
6212
6214{
6215 avio_wb32(pb, 8); // placeholder for extended size field (64 bit)
6216 ffio_wfourcc(pb, mov->mode == MODE_MOV ? "wide" : "free");
6217
6218 mov->mdat_pos = avio_tell(pb);
6219 avio_wb32(pb, 0); /* size placeholder*/
6220 ffio_wfourcc(pb, "mdat");
6221 return 0;
6222}
6223
6225 int has_h264, int has_video, int write_minor)
6226{
6227 MOVMuxContext *mov = s->priv_data;
6228 int minor = 0x200;
6229
6230 if (mov->major_brand && strlen(mov->major_brand) >= 4)
6231 ffio_wfourcc(pb, mov->major_brand);
6232 else if (mov->mode == MODE_3GP) {
6233 ffio_wfourcc(pb, has_h264 ? "3gp6" : "3gp4");
6234 minor = has_h264 ? 0x100 : 0x200;
6235 } else if (mov->mode == MODE_AVIF) {
6236 ffio_wfourcc(pb, mov->is_animated_avif ? "avis" : "avif");
6237 minor = 0;
6238 } else if (mov->mode & MODE_3G2) {
6239 ffio_wfourcc(pb, has_h264 ? "3g2b" : "3g2a");
6240 minor = has_h264 ? 0x20000 : 0x10000;
6241 } else if (mov->mode == MODE_PSP)
6242 ffio_wfourcc(pb, "MSNV");
6243 else if (mov->mode == MODE_MP4 && mov->flags & FF_MOV_FLAG_FRAGMENT &&
6245 ffio_wfourcc(pb, "iso6"); // Required when using signed CTS offsets in trun boxes
6246 else if (mov->mode == MODE_MP4 && mov->flags & FF_MOV_FLAG_DEFAULT_BASE_MOOF)
6247 ffio_wfourcc(pb, "iso5"); // Required when using default-base-is-moof
6248 else if (mov->mode == MODE_MP4 && mov->flags & FF_MOV_FLAG_NEGATIVE_CTS_OFFSETS)
6249 ffio_wfourcc(pb, "iso4");
6250 else if (mov->mode == MODE_MP4)
6251 ffio_wfourcc(pb, "isom");
6252 else if (mov->mode == MODE_IPOD)
6253 ffio_wfourcc(pb, has_video ? "M4V ":"M4A ");
6254 else if (mov->mode == MODE_ISM)
6255 ffio_wfourcc(pb, "isml");
6256 else if (mov->mode == MODE_F4V)
6257 ffio_wfourcc(pb, "f4v ");
6258 else
6259 ffio_wfourcc(pb, "qt ");
6260
6261 if (write_minor)
6262 avio_wb32(pb, minor);
6263}
6264
6266{
6267 MOVMuxContext *mov = s->priv_data;
6268 int64_t pos = avio_tell(pb);
6269 int has_h264 = 0, has_av1 = 0, has_video = 0, has_dolby = 0, has_id3 = 0;
6270 int has_iamf = 0;
6271
6272#if CONFIG_IAMFENC
6273 for (int i = 0; i < s->nb_stream_groups; i++) {
6274 const AVStreamGroup *stg = s->stream_groups[i];
6275
6278 has_iamf = 1;
6279 break;
6280 }
6281 }
6282#endif
6283 for (int i = 0; i < mov->nb_streams; i++) {
6284 AVStream *st = mov->tracks[i].st;
6285 if (is_cover_image(st))
6286 continue;
6288 has_video = 1;
6290 has_h264 = 1;
6291 if (st->codecpar->codec_id == AV_CODEC_ID_AV1)
6292 has_av1 = 1;
6293 if (st->codecpar->codec_id == AV_CODEC_ID_AC3 ||
6299 has_dolby = 1;
6301 has_id3 = 1;
6302 }
6303
6304 avio_wb32(pb, 0); /* size */
6305 ffio_wfourcc(pb, "ftyp");
6306
6307 // Write major brand
6308 mov_write_ftyp_tag_internal(pb, s, has_h264, has_video, 1);
6309 // Write the major brand as the first compatible brand as well
6310 mov_write_ftyp_tag_internal(pb, s, has_h264, has_video, 0);
6311
6312 // Write compatible brands, ensuring that we don't write the major brand as a
6313 // compatible brand a second time.
6314 if (mov->mode == MODE_ISM) {
6315 ffio_wfourcc(pb, "piff");
6316 } else if (mov->mode == MODE_AVIF) {
6317 const AVPixFmtDescriptor *pix_fmt_desc =
6318 av_pix_fmt_desc_get(s->streams[0]->codecpar->format);
6319 const int depth = pix_fmt_desc->comp[0].depth;
6320 if (mov->is_animated_avif) {
6321 // For animated AVIF, major brand is "avis". Add "avif" as a
6322 // compatible brand.
6323 ffio_wfourcc(pb, "avif");
6324 ffio_wfourcc(pb, "msf1");
6325 ffio_wfourcc(pb, "iso8");
6326 }
6327 ffio_wfourcc(pb, "mif1");
6328 ffio_wfourcc(pb, "miaf");
6329 if (depth == 8 || depth == 10) {
6330 // MA1B and MA1A brands are based on AV1 profile. Short hand for
6331 // computing that is based on chroma subsampling type. 420 chroma
6332 // subsampling is MA1B. 444 chroma subsampling is MA1A.
6333 if (!pix_fmt_desc->log2_chroma_w && !pix_fmt_desc->log2_chroma_h) {
6334 // 444 chroma subsampling.
6335 ffio_wfourcc(pb, "MA1A");
6336 } else {
6337 // 420 chroma subsampling.
6338 ffio_wfourcc(pb, "MA1B");
6339 }
6340 }
6341 } else if (mov->mode != MODE_MOV) {
6342 // We add tfdt atoms when fragmenting, signal this with the iso6 compatible
6343 // brand, if not already the major brand. This is compatible with users that
6344 // don't understand tfdt.
6345 if (mov->mode == MODE_MP4) {
6346 if (mov->flags & FF_MOV_FLAG_CMAF)
6347 ffio_wfourcc(pb, "cmfc");
6349 ffio_wfourcc(pb, "iso6");
6350 if (has_av1)
6351 ffio_wfourcc(pb, "av01");
6352 if (has_dolby)
6353 ffio_wfourcc(pb, "dby1");
6354 if (has_iamf)
6355 ffio_wfourcc(pb, "iamf");
6356 } else {
6357 if (mov->flags & FF_MOV_FLAG_FRAGMENT)
6358 ffio_wfourcc(pb, "iso6");
6360 ffio_wfourcc(pb, "iso5");
6362 ffio_wfourcc(pb, "iso4");
6363 }
6364 // Brands prior to iso5 can't be signaled when using default-base-is-moof
6365 if (!(mov->flags & FF_MOV_FLAG_DEFAULT_BASE_MOOF)) {
6366 // write isom for mp4 only if it it's not the major brand already.
6368 ffio_wfourcc(pb, "isom");
6369 ffio_wfourcc(pb, "iso2");
6370 if (has_h264)
6371 ffio_wfourcc(pb, "avc1");
6372 }
6373 }
6374
6375 if (mov->mode == MODE_MP4)
6376 ffio_wfourcc(pb, "mp41");
6377
6379 ffio_wfourcc(pb, "dash");
6380
6381 if (has_id3)
6382 ffio_wfourcc(pb, "aid3");
6383
6384 return update_size(pb, pos);
6385}
6386
6388{
6389 AVStream *video_st = s->streams[0];
6390 AVCodecParameters *video_par = s->streams[0]->codecpar;
6391 AVCodecParameters *audio_par = s->streams[1]->codecpar;
6392 int audio_rate = audio_par->sample_rate;
6393 int64_t frame_rate = video_st->avg_frame_rate.den ?
6394 (video_st->avg_frame_rate.num * 0x10000LL) / video_st->avg_frame_rate.den :
6395 0;
6396 int audio_kbitrate = audio_par->bit_rate / 1000;
6397 int video_kbitrate = FFMIN(video_par->bit_rate / 1000, 800 - audio_kbitrate);
6398
6399 if (frame_rate < 0 || frame_rate > INT32_MAX) {
6400 av_log(s, AV_LOG_ERROR, "Frame rate %f outside supported range\n", frame_rate / (double)0x10000);
6401 return AVERROR(EINVAL);
6402 }
6403
6404 avio_wb32(pb, 0x94); /* size */
6405 ffio_wfourcc(pb, "uuid");
6406 ffio_wfourcc(pb, "PROF");
6407
6408 avio_wb32(pb, 0x21d24fce); /* 96 bit UUID */
6409 avio_wb32(pb, 0xbb88695c);
6410 avio_wb32(pb, 0xfac9c740);
6411
6412 avio_wb32(pb, 0x0); /* ? */
6413 avio_wb32(pb, 0x3); /* 3 sections ? */
6414
6415 avio_wb32(pb, 0x14); /* size */
6416 ffio_wfourcc(pb, "FPRF");
6417 avio_wb32(pb, 0x0); /* ? */
6418 avio_wb32(pb, 0x0); /* ? */
6419 avio_wb32(pb, 0x0); /* ? */
6420
6421 avio_wb32(pb, 0x2c); /* size */
6422 ffio_wfourcc(pb, "APRF"); /* audio */
6423 avio_wb32(pb, 0x0);
6424 avio_wb32(pb, 0x2); /* TrackID */
6425 ffio_wfourcc(pb, "mp4a");
6426 avio_wb32(pb, 0x20f);
6427 avio_wb32(pb, 0x0);
6428 avio_wb32(pb, audio_kbitrate);
6429 avio_wb32(pb, audio_kbitrate);
6430 avio_wb32(pb, audio_rate);
6431 avio_wb32(pb, audio_par->ch_layout.nb_channels);
6432
6433 avio_wb32(pb, 0x34); /* size */
6434 ffio_wfourcc(pb, "VPRF"); /* video */
6435 avio_wb32(pb, 0x0);
6436 avio_wb32(pb, 0x1); /* TrackID */
6437 if (video_par->codec_id == AV_CODEC_ID_H264) {
6438 ffio_wfourcc(pb, "avc1");
6439 avio_wb16(pb, 0x014D);
6440 avio_wb16(pb, 0x0015);
6441 } else {
6442 ffio_wfourcc(pb, "mp4v");
6443 avio_wb16(pb, 0x0000);
6444 avio_wb16(pb, 0x0103);
6445 }
6446 avio_wb32(pb, 0x0);
6447 avio_wb32(pb, video_kbitrate);
6448 avio_wb32(pb, video_kbitrate);
6449 avio_wb32(pb, frame_rate);
6450 avio_wb32(pb, frame_rate);
6451 avio_wb16(pb, video_par->width);
6452 avio_wb16(pb, video_par->height);
6453 avio_wb32(pb, 0x010001); /* ? */
6454
6455 return 0;
6456}
6457
6459{
6460 MOVMuxContext *mov = s->priv_data;
6461 int i;
6462
6464 if (mov->mode == MODE_PSP) {
6465 int video_streams_nb = 0, audio_streams_nb = 0, other_streams_nb = 0;
6466 for (i = 0; i < mov->nb_streams; i++) {
6467 AVStream *st = mov->tracks[i].st;
6468 if (is_cover_image(st))
6469 continue;
6471 video_streams_nb++;
6472 else if (st->codecpar->codec_type == AVMEDIA_TYPE_AUDIO)
6473 audio_streams_nb++;
6474 else
6475 other_streams_nb++;
6476 }
6477
6478 if (video_streams_nb != 1 || audio_streams_nb != 1 || other_streams_nb) {
6479 av_log(s, AV_LOG_ERROR, "PSP mode need one video and one audio stream\n");
6480 return AVERROR(EINVAL);
6481 }
6482 return mov_write_uuidprof_tag(pb, s);
6483 }
6484 return 0;
6485}
6486
6488{
6489 uint32_t c = -1;
6490 int i, closed_gop = 0;
6491
6492 for (i = 0; i < pkt->size - 4; i++) {
6493 c = (c << 8) + pkt->data[i];
6494 if (c == 0x1b8) { // gop
6495 closed_gop = pkt->data[i + 4] >> 6 & 0x01;
6496 } else if (c == 0x100) { // pic
6497 int temp_ref = (pkt->data[i + 1] << 2) | (pkt->data[i + 2] >> 6);
6498 if (!temp_ref || closed_gop) // I picture is not reordered
6500 else
6502 break;
6503 }
6504 }
6505 return 0;
6506}
6507
6509{
6510 const uint8_t *start, *next, *end = pkt->data + pkt->size;
6511 int seq = 0, entry = 0;
6512 int key = pkt->flags & AV_PKT_FLAG_KEY;
6513 start = find_next_marker(pkt->data, end);
6514 for (next = start; next < end; start = next) {
6515 next = find_next_marker(start + 4, end);
6516 switch (AV_RB32(start)) {
6517 case VC1_CODE_SEQHDR:
6518 seq = 1;
6519 break;
6521 entry = 1;
6522 break;
6523 case VC1_CODE_SLICE:
6524 trk->vc1_info.slices = 1;
6525 break;
6526 }
6527 }
6528 if (!trk->entry && trk->vc1_info.first_packet_seen)
6530 if (!trk->entry && !trk->vc1_info.first_frag_written) {
6531 /* First packet in first fragment */
6532 trk->vc1_info.first_packet_seq = seq;
6534 trk->vc1_info.first_packet_seen = 1;
6535 } else if ((seq && !trk->vc1_info.packet_seq) ||
6536 (entry && !trk->vc1_info.packet_entry)) {
6537 int i;
6538 for (i = 0; i < trk->entry; i++)
6539 trk->cluster[i].flags &= ~MOV_SYNC_SAMPLE;
6540 trk->has_keyframes = 0;
6541 if (seq)
6542 trk->vc1_info.packet_seq = 1;
6543 if (entry)
6544 trk->vc1_info.packet_entry = 1;
6545 if (!trk->vc1_info.first_frag_written) {
6546 /* First fragment */
6547 if ((!seq || trk->vc1_info.first_packet_seq) &&
6548 (!entry || trk->vc1_info.first_packet_entry)) {
6549 /* First packet had the same headers as this one, readd the
6550 * sync sample flag. */
6551 trk->cluster[0].flags |= MOV_SYNC_SAMPLE;
6552 trk->has_keyframes = 1;
6553 }
6554 }
6555 }
6556 if (trk->vc1_info.packet_seq && trk->vc1_info.packet_entry)
6557 key = seq && entry;
6558 else if (trk->vc1_info.packet_seq)
6559 key = seq;
6560 else if (trk->vc1_info.packet_entry)
6561 key = entry;
6562 if (key) {
6563 trk->cluster[trk->entry].flags |= MOV_SYNC_SAMPLE;
6564 trk->has_keyframes++;
6565 }
6566}
6567
6569{
6570 int length;
6571
6572 if (pkt->size < 8)
6573 return;
6574
6575 length = (AV_RB16(pkt->data) & 0xFFF) * 2;
6576 if (length < 8 || length > pkt->size)
6577 return;
6578
6579 if (AV_RB32(pkt->data + 4) == 0xF8726FBA) {
6580 trk->cluster[trk->entry].flags |= MOV_SYNC_SAMPLE;
6581 trk->has_keyframes++;
6582 }
6583
6584 return;
6585}
6586
6588{
6589 MOVMuxContext *mov = s->priv_data;
6590 int ret, buf_size;
6591 uint8_t *buf;
6592 int i, offset;
6593
6594 if (!track->mdat_buf)
6595 return 0;
6596 if (!mov->mdat_buf) {
6597 if ((ret = avio_open_dyn_buf(&mov->mdat_buf)) < 0)
6598 return ret;
6599 }
6600 buf_size = avio_get_dyn_buf(track->mdat_buf, &buf);
6601
6602 offset = avio_tell(mov->mdat_buf);
6603 avio_write(mov->mdat_buf, buf, buf_size);
6605
6606 for (i = track->entries_flushed; i < track->entry; i++)
6607 track->cluster[i].pos += offset;
6608 track->entries_flushed = track->entry;
6609 return 0;
6610}
6611
6613{
6614 MOVMuxContext *mov = s->priv_data;
6615 AVPacket *squashed_packet = mov->pkt;
6616 int ret = AVERROR_BUG;
6617
6618 switch (track->st->codecpar->codec_id) {
6619 case AV_CODEC_ID_TTML: {
6620 int had_packets = !!track->squashed_packet_queue.head;
6621
6622 if ((ret = ff_mov_generate_squashed_ttml_packet(s, track, squashed_packet)) < 0) {
6623 goto finish_squash;
6624 }
6625
6626 // We have generated a padding packet (no actual input packets in
6627 // queue) and its duration is zero. Skipping writing it.
6628 if (!had_packets && squashed_packet->duration == 0) {
6629 goto finish_squash;
6630 }
6631
6632 track->end_reliable = 1;
6633 break;
6634 }
6635 default:
6636 ret = AVERROR(EINVAL);
6637 goto finish_squash;
6638 }
6639
6640 squashed_packet->stream_index = track->st->index;
6641
6642 ret = mov_write_single_packet(s, squashed_packet);
6643
6644finish_squash:
6645 av_packet_unref(squashed_packet);
6646
6647 return ret;
6648}
6649
6651{
6652 MOVMuxContext *mov = s->priv_data;
6653
6654 for (int i = 0; i < mov->nb_streams; i++) {
6655 MOVTrack *track = &mov->tracks[i];
6656 int ret = AVERROR_BUG;
6657
6658 if (track->squash_fragment_samples_to_one && !track->entry) {
6659 if ((ret = mov_write_squashed_packet(s, track)) < 0) {
6661 "Failed to write squashed packet for %s stream with "
6662 "index %d and track id %d. Error: %s\n",
6664 track->st->index, track->track_id,
6665 av_err2str(ret));
6666 return ret;
6667 }
6668 }
6669 }
6670
6671 return 0;
6672}
6673
6675 int64_t ref_pos)
6676{
6677 int i;
6678 if (!track->entry)
6679 return 0;
6681 for (i = 0; i < track->entry; i++)
6682 track->cluster[i].pos += ref_pos + track->data_offset;
6683 if (track->cluster_written == 0) {
6684 // First flush. Chunking for this fragment may already have been
6685 // done, either if we didn't use empty_moov, or if we did use
6686 // delay_moov. In either case, reset chunking here.
6687 for (i = 0; i < track->entry; i++) {
6688 track->cluster[i].chunkNum = 0;
6689 track->cluster[i].samples_in_chunk = track->cluster[i].entries;
6690 }
6691 }
6693 track->entry_written + track->entry,
6694 sizeof(*track->cluster)))
6695 return AVERROR(ENOMEM);
6696 memcpy(&track->cluster_written[track->entry_written],
6697 track->cluster, track->entry * sizeof(*track->cluster));
6698 track->entry_written += track->entry;
6699 }
6700 track->entry = 0;
6701 track->entries_flushed = 0;
6702 track->end_reliable = 0;
6703 return 0;
6704}
6705
6706static int mov_flush_fragment(AVFormatContext *s, int force)
6707{
6708 MOVMuxContext *mov = s->priv_data;
6709 int i, first_track = -1;
6710 int64_t mdat_size = 0, mdat_start = 0;
6711 int ret;
6712 int has_video = 0, starts_with_key = 0, first_video_track = 1;
6713
6714 if (!(mov->flags & FF_MOV_FLAG_FRAGMENT))
6715 return 0;
6716
6717 // Check if we have any tracks that require squashing.
6718 // In that case, we'll have to write the packet here.
6719 if ((ret = mov_write_squashed_packets(s)) < 0)
6720 return ret;
6721
6722 // Try to fill in the duration of the last packet in each stream
6723 // from queued packets in the interleave queues. If the flushing
6724 // of fragments was triggered automatically by an AVPacket, we
6725 // already have reliable info for the end of that track, but other
6726 // tracks may need to be filled in.
6727 for (i = 0; i < mov->nb_streams; i++) {
6728 MOVTrack *track = &mov->tracks[i];
6729 if (!track->end_reliable) {
6730 const AVPacket *pkt = ff_interleaved_peek(s, i);
6731 if (pkt) {
6732 int64_t offset, dts, pts;
6734 pts = pkt->pts + offset;
6735 dts = pkt->dts + offset;
6736 if (track->dts_shift != AV_NOPTS_VALUE)
6737 dts += track->dts_shift;
6738 track->track_duration = dts - track->start_dts;
6739 if (pts != AV_NOPTS_VALUE)
6740 track->end_pts = pts;
6741 else
6742 track->end_pts = dts;
6743 if (!(pkt->flags & AV_PKT_FLAG_DISCARD))
6744 track->elst_end_pts = track->end_pts;
6745 }
6746 }
6747 }
6748
6749 for (i = 0; i < mov->nb_tracks; i++) {
6750 MOVTrack *track = &mov->tracks[i];
6751 if (track->entry <= 1)
6752 continue;
6753 // Sample durations are calculated as the diff of dts values,
6754 // but for the last sample in a fragment, we don't know the dts
6755 // of the first sample in the next fragment, so we have to rely
6756 // on what was set as duration in the AVPacket. Not all callers
6757 // set this though, so we might want to replace it with an
6758 // estimate if it currently is zero.
6759 if (get_cluster_duration(track, track->entry - 1) != 0)
6760 continue;
6761 // Use the duration (i.e. dts diff) of the second last sample for
6762 // the last one. This is a wild guess (and fatal if it turns out
6763 // to be too long), but probably the best we can do - having a zero
6764 // duration is bad as well.
6765 track->track_duration += get_cluster_duration(track, track->entry - 2);
6766 track->end_pts += get_cluster_duration(track, track->entry - 2);
6767 if (!mov->missing_duration_warned) {
6769 "Estimating the duration of the last packet in a "
6770 "fragment, consider setting the duration field in "
6771 "AVPacket instead.\n");
6772 mov->missing_duration_warned = 1;
6773 }
6774 }
6775
6776 if (!mov->moov_written) {
6777 int64_t pos = avio_tell(s->pb);
6778 uint8_t *buf;
6779 int buf_size, moov_size;
6780
6781 for (i = 0; i < mov->nb_tracks; i++)
6782 if (!mov->tracks[i].entry && !is_cover_image(mov->tracks[i].st))
6783 break;
6784 /* Don't write the initial moov unless all tracks have data */
6785 if (i < mov->nb_tracks && !force)
6786 return 0;
6787
6788 moov_size = get_moov_size(s);
6789 for (i = 0; i < mov->nb_tracks; i++)
6790 mov->tracks[i].data_offset = pos + moov_size + 8;
6791
6793 if (mov->flags & FF_MOV_FLAG_DELAY_MOOV &&
6796 if ((ret = mov_write_moov_tag(s->pb, mov, s)) < 0)
6797 return ret;
6798
6799 if (mov->flags & FF_MOV_FLAG_DELAY_MOOV) {
6800 if (mov->flags & FF_MOV_FLAG_GLOBAL_SIDX)
6801 mov->reserved_header_pos = avio_tell(s->pb);
6803 mov->moov_written = 1;
6804 return 0;
6805 }
6806
6807 if (mov->mdat_buf) {
6808 buf_size = avio_get_dyn_buf(mov->mdat_buf, &buf);
6809 avio_wb32(s->pb, buf_size + 8);
6810 ffio_wfourcc(s->pb, "mdat");
6811 avio_write(s->pb, buf, buf_size);
6813 }
6814
6815 if (mov->flags & FF_MOV_FLAG_GLOBAL_SIDX)
6816 mov->reserved_header_pos = avio_tell(s->pb);
6817
6818 mov->moov_written = 1;
6819 mov->mdat_size = 0;
6820 for (i = 0; i < mov->nb_tracks; i++)
6821 mov_finish_fragment(mov, &mov->tracks[i], 0);
6823 return 0;
6824 }
6825
6826 if (mov->frag_interleave) {
6827 for (i = 0; i < mov->nb_tracks; i++) {
6828 MOVTrack *track = &mov->tracks[i];
6829 int ret;
6830 if ((ret = mov_flush_fragment_interleaving(s, track)) < 0)
6831 return ret;
6832 }
6833
6834 if (!mov->mdat_buf)
6835 return 0;
6836 mdat_size = avio_tell(mov->mdat_buf);
6837 }
6838
6839 for (i = 0; i < mov->nb_tracks; i++) {
6840 MOVTrack *track = &mov->tracks[i];
6842 track->data_offset = 0;
6843 else
6844 track->data_offset = mdat_size;
6845 if (track->par->codec_type == AVMEDIA_TYPE_VIDEO) {
6846 has_video = 1;
6847 if (first_video_track) {
6848 if (track->entry)
6849 starts_with_key = track->cluster[0].flags & MOV_SYNC_SAMPLE;
6850 first_video_track = 0;
6851 }
6852 }
6853 if (!track->entry)
6854 continue;
6855 if (track->mdat_buf)
6856 mdat_size += avio_tell(track->mdat_buf);
6857 if (first_track < 0)
6858 first_track = i;
6859 }
6860
6861 if (!mdat_size)
6862 return 0;
6863
6864 avio_write_marker(s->pb,
6865 av_rescale(mov->tracks[first_track].cluster[0].dts, AV_TIME_BASE, mov->tracks[first_track].timescale),
6866 (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);
6867
6868 for (i = first_track; i < mov->nb_tracks; i++) {
6869 MOVTrack *track = &mov->tracks[i];
6870 int buf_size, write_moof = 1, moof_tracks = -1;
6871 uint8_t *buf;
6872
6873 if (!track->entry)
6874 continue;
6875 if (mov->flags & FF_MOV_FLAG_SEPARATE_MOOF) {
6876 mdat_size = avio_tell(track->mdat_buf);
6877 moof_tracks = i;
6878 } else {
6879 write_moof = i == first_track;
6880 }
6881
6882 if (write_moof) {
6884
6885 mov_write_moof_tag(s->pb, mov, moof_tracks, mdat_size);
6886 mov->fragments++;
6887
6888 if (track->cenc.aes_ctr)
6889 ff_mov_cenc_flush(&track->cenc);
6890
6891 avio_wb32(s->pb, mdat_size + 8);
6892 ffio_wfourcc(s->pb, "mdat");
6893 mdat_start = avio_tell(s->pb);
6894 }
6895
6896 mov_finish_fragment(mov, &mov->tracks[i], mdat_start);
6897 if (!mov->frag_interleave) {
6898 if (!track->mdat_buf)
6899 continue;
6900 buf_size = avio_get_dyn_buf(track->mdat_buf, &buf);
6901 avio_write(s->pb, buf, buf_size);
6903 } else {
6904 if (!mov->mdat_buf)
6905 continue;
6906 buf_size = avio_get_dyn_buf(mov->mdat_buf, &buf);
6907 avio_write(s->pb, buf, buf_size);
6909 }
6910 }
6911
6912 mov->mdat_size = 0;
6913
6915 return 0;
6916}
6917
6919{
6920 MOVMuxContext *mov = s->priv_data;
6921 int had_moov = mov->moov_written;
6922 int ret = mov_flush_fragment(s, force);
6923 if (ret < 0)
6924 return ret;
6925 // If using delay_moov, the first flush only wrote the moov,
6926 // not the actual moof+mdat pair, thus flush once again.
6927 if (!had_moov && mov->flags & FF_MOV_FLAG_DELAY_MOOV)
6928 ret = mov_flush_fragment(s, force);
6929 return ret;
6930}
6931
6933{
6934 int64_t ref;
6935 uint64_t duration;
6936
6937 if (trk->entry) {
6938 ref = trk->cluster[trk->entry - 1].dts;
6939 } else if ( trk->start_dts != AV_NOPTS_VALUE
6940 && !trk->frag_discont) {
6941 ref = trk->start_dts + trk->track_duration;
6942 } else
6943 ref = pkt->dts; // Skip tests for the first packet
6944
6945 if (trk->dts_shift != AV_NOPTS_VALUE) {
6946 /* With negative CTS offsets we have set an offset to the DTS,
6947 * reverse this for the check. */
6948 ref -= trk->dts_shift;
6949 }
6950
6951 duration = pkt->dts - ref;
6952 if (pkt->dts < ref || duration >= INT_MAX) {
6953 av_log(s, AV_LOG_WARNING, "Packet duration: %"PRId64" / dts: %"PRId64" in stream %d is out of range\n",
6954 duration, pkt->dts, pkt->stream_index);
6955
6956 pkt->dts = ref + 1;
6957 pkt->pts = AV_NOPTS_VALUE;
6958 }
6959
6960 if (pkt->duration < 0 || pkt->duration > INT_MAX) {
6961 av_log(s, AV_LOG_ERROR, "Application provided duration: %"PRId64" in stream %d is invalid\n", pkt->duration, pkt->stream_index);
6962 return AVERROR(EINVAL);
6963 }
6964 return 0;
6965}
6966
6968 const AVPacket *pkt, AVRational src_time_base)
6969{
6970 MOVMuxContext *mov = s->priv_data;
6971 AVStream *st;
6972 MOVTrack *track;
6973 int64_t offset, dts, pts, candidate_duration;
6974
6975 if (!(mov->flags & FF_MOV_FLAG_FRAGMENT) ||
6976 stream_index < 0 || stream_index >= s->nb_streams ||
6977 pkt->dts == AV_NOPTS_VALUE)
6978 return 0;
6979
6980 st = s->streams[stream_index];
6981 track = st->priv_data;
6982 if (!track->entry || track->start_dts == AV_NOPTS_VALUE)
6983 return 0;
6984
6985 if (ff_get_muxer_ts_offset(s, stream_index, &offset) < 0)
6986 return 0;
6987
6988 dts = av_rescale_q(pkt->dts, src_time_base, st->time_base) + offset;
6989 pts = pkt->pts == AV_NOPTS_VALUE
6991 : av_rescale_q(pkt->pts, src_time_base, st->time_base) + offset;
6992 if (track->dts_shift != AV_NOPTS_VALUE)
6993 dts += track->dts_shift;
6994
6995 candidate_duration = dts - track->start_dts;
6996 if (dts <= track->cluster[track->entry - 1].dts ||
6997 candidate_duration < 0 || candidate_duration >= track->track_duration)
6998 return 0;
6999
7000 track->track_duration = candidate_duration;
7001 track->end_pts = pts != AV_NOPTS_VALUE ? pts : dts;
7002 if (!(pkt->flags & AV_PKT_FLAG_DISCARD))
7003 track->elst_end_pts = track->end_pts;
7004 track->end_reliable = 1;
7005
7006 return 1;
7007}
7008
7010{
7011 MOVMuxContext *mov = s->priv_data;
7012 AVIOContext *pb = s->pb;
7013 MOVTrack *trk;
7014 AVCodecParameters *par;
7016 unsigned int samples_in_chunk = 0;
7018 int size = pkt->size, ret = 0, offset = 0;
7019 size_t prft_size;
7020 uint8_t *reformatted_data = NULL;
7021
7022 if (pkt->stream_index < s->nb_streams)
7023 trk = s->streams[pkt->stream_index]->priv_data;
7024 else // Timecode or chapter
7025 trk = &mov->tracks[pkt->stream_index];
7026 par = trk->par;
7027
7028 ret = check_pkt(s, trk, pkt);
7029 if (ret < 0)
7030 return ret;
7031
7032 if (pkt->pts != AV_NOPTS_VALUE &&
7033 (uint64_t)pkt->dts - pkt->pts != (int32_t)((uint64_t)pkt->dts - pkt->pts)) {
7034 av_log(s, AV_LOG_WARNING, "pts/dts pair unsupported\n");
7035 return AVERROR_PATCHWELCOME;
7036 }
7037
7038 if (mov->flags & FF_MOV_FLAG_FRAGMENT || mov->mode == MODE_AVIF) {
7039 int ret;
7040 if (mov->moov_written || mov->flags & FF_MOV_FLAG_EMPTY_MOOV) {
7041 if (mov->frag_interleave && mov->fragments > 0) {
7042 if (trk->entry - trk->entries_flushed >= mov->frag_interleave) {
7043 if ((ret = mov_flush_fragment_interleaving(s, trk)) < 0)
7044 return ret;
7045 }
7046 }
7047
7048 if (!trk->mdat_buf) {
7049 if ((ret = avio_open_dyn_buf(&trk->mdat_buf)) < 0)
7050 return ret;
7051 }
7052 pb = trk->mdat_buf;
7053 } else {
7054 if (!mov->mdat_buf) {
7055 if ((ret = avio_open_dyn_buf(&mov->mdat_buf)) < 0)
7056 return ret;
7057 }
7058 pb = mov->mdat_buf;
7059 }
7060 }
7061
7062 if (par->codec_id == AV_CODEC_ID_AMR_NB) {
7063 /* We must find out how many AMR blocks there are in one packet */
7064 static const uint16_t packed_size[16] =
7065 {13, 14, 16, 18, 20, 21, 27, 32, 6, 0, 0, 0, 0, 0, 0, 1};
7066 int len = 0;
7067
7068 while (len < size && samples_in_chunk < 100) {
7069 len += packed_size[(pkt->data[len] >> 3) & 0x0F];
7070 samples_in_chunk++;
7071 }
7072 if (samples_in_chunk > 1) {
7073 av_log(s, AV_LOG_ERROR, "fatal error, input is not a single packet, implement a AVParser for it\n");
7074 return -1;
7075 }
7076 } else if (par->codec_id == AV_CODEC_ID_ADPCM_MS ||
7078 samples_in_chunk = trk->par->frame_size;
7079 } else if (trk->sample_size)
7080 samples_in_chunk = size / trk->sample_size;
7081 else
7082 samples_in_chunk = 1;
7083
7084 if (samples_in_chunk < 1) {
7085 av_log(s, AV_LOG_ERROR, "fatal error, input packet contains no samples\n");
7086 return AVERROR_PATCHWELCOME;
7087 }
7088
7089 /* copy extradata if it exists */
7090 if (trk->extradata_size[0] == 0 && par->extradata_size > 0 &&
7091 !TAG_IS_AVCI(trk->tag) &&
7092 (par->codec_id != AV_CODEC_ID_DNXHD)) {
7093 trk->extradata[0] = av_memdup(par->extradata, par->extradata_size);
7094 if (!trk->extradata[0]) {
7095 ret = AVERROR(ENOMEM);
7096 goto err;
7097 }
7098 trk->extradata_size[0] = par->extradata_size;
7099 }
7100
7101 if ((par->codec_id == AV_CODEC_ID_DNXHD ||
7102 par->codec_id == AV_CODEC_ID_H264 ||
7103 par->codec_id == AV_CODEC_ID_HEVC ||
7104 par->codec_id == AV_CODEC_ID_VVC ||
7105 par->codec_id == AV_CODEC_ID_VP9 ||
7106 par->codec_id == AV_CODEC_ID_EVC ||
7107 par->codec_id == AV_CODEC_ID_LCEVC ||
7108 par->codec_id == AV_CODEC_ID_TRUEHD) && !trk->extradata_size[0] &&
7109 !TAG_IS_AVCI(trk->tag)) {
7110 /* copy frame to create needed atoms */
7111 trk->extradata_size[0] = size;
7113 if (!trk->extradata[0]) {
7114 ret = AVERROR(ENOMEM);
7115 goto err;
7116 }
7117 memcpy(trk->extradata[0], pkt->data, size);
7118 memset(trk->extradata[0] + size, 0, AV_INPUT_BUFFER_PADDING_SIZE);
7119 }
7120
7121 const AVPacketSideData *sd = av_packet_side_data_get(pkt->side_data, pkt->side_data_elems, AV_PKT_DATA_NEW_EXTRADATA);
7122 if (pkt->size && sd && sd->size > 0) {
7123 int i;
7124 for (i = 0; i < trk->stsd_count; i++) {
7125 if (trk->extradata_size[i] == sd->size && !memcmp(trk->extradata[i], sd->data, sd->size))
7126 break;
7127 }
7128
7129 if (i < trk->stsd_count)
7130 trk->last_stsd_index = i;
7131 else if (trk->stsd_count <= INT_MAX - 1) {
7132 int new_count = trk->stsd_count + 1;
7133 uint8_t **extradata = av_realloc_array(trk->extradata, new_count, sizeof(*trk->extradata));
7134 if (!extradata)
7135 return AVERROR(ENOMEM);
7136 trk->extradata = extradata;
7137
7138 int *extradata_size = av_realloc_array(trk->extradata_size, new_count, sizeof(*trk->extradata_size));
7139 if (!extradata_size)
7140 return AVERROR(ENOMEM);
7141 trk->extradata_size = extradata_size;
7142
7143 trk->extradata[trk->stsd_count] = av_memdup(sd->data, sd->size);
7144 if (!trk->extradata[trk->stsd_count])
7145 return AVERROR(ENOMEM);
7146
7147 trk->extradata_size[trk->stsd_count] = sd->size;
7148 trk->last_stsd_index = trk->stsd_count;
7149 trk->stsd_count = new_count;
7150 } else
7151 return AVERROR(ENOMEM);
7152 }
7153
7154 if (par->codec_id == AV_CODEC_ID_AAC && pkt->size > 2 &&
7155 (AV_RB16(pkt->data) & 0xfff0) == 0xfff0) {
7156 if (!trk->st->nb_frames) {
7157 av_log(s, AV_LOG_ERROR, "Malformed AAC bitstream detected: "
7158 "use the audio bitstream filter 'aac_adtstoasc' to fix it "
7159 "('-bsf:a aac_adtstoasc' option with ffmpeg)\n");
7160 return -1;
7161 }
7162 av_log(s, AV_LOG_WARNING, "aac bitstream error\n");
7163 }
7164 if (par->codec_id == AV_CODEC_ID_H264 && trk->extradata_size[trk->last_stsd_index] > 0 &&
7165 *(uint8_t *)trk->extradata[trk->last_stsd_index] != 1 && !TAG_IS_AVCI(trk->tag)) {
7166 /* from x264 or from bytestream H.264 */
7167 /* NAL reformatting needed */
7168 if (trk->hint_track >= 0 && trk->hint_track < mov->nb_tracks) {
7169 ret = ff_nal_parse_units_buf(pkt->data, &reformatted_data,
7170 &size);
7171 if (ret < 0)
7172 return ret;
7173 avio_write(pb, reformatted_data, size);
7174 } else {
7175 if (trk->cenc.aes_ctr) {
7176 size = ff_mov_cenc_avc_parse_nal_units(&trk->cenc, pb, pkt->data, size);
7177 if (size < 0) {
7178 ret = size;
7179 goto err;
7180 }
7181 } else {
7182 size = ff_nal_parse_units(pb, pkt->data, pkt->size);
7183 }
7184 }
7185 } else if (par->codec_id == AV_CODEC_ID_HEVC && trk->extradata_size[trk->last_stsd_index] > 6 &&
7186 (AV_RB24(trk->extradata[trk->last_stsd_index]) == 1 || AV_RB32(trk->extradata[trk->last_stsd_index]) == 1)) {
7187 /* extradata is Annex B, assume the bitstream is too and convert it */
7188 int filter_ps = (trk->tag == MKTAG('h','v','c','1'));
7189 if (trk->hint_track >= 0 && trk->hint_track < mov->nb_tracks) {
7190 ret = ff_hevc_annexb2mp4_buf(pkt->data, &reformatted_data,
7191 &size, filter_ps, NULL);
7192 if (ret < 0)
7193 return ret;
7194 avio_write(pb, reformatted_data, size);
7195 } else {
7196 if (trk->cenc.aes_ctr) {
7197 size = ff_mov_cenc_avc_parse_nal_units(&trk->cenc, pb, pkt->data, size);
7198 if (size < 0) {
7199 ret = size;
7200 goto err;
7201 }
7202 } else {
7203 size = ff_hevc_annexb2mp4(pb, pkt->data, pkt->size, filter_ps, NULL);
7204 }
7205 }
7206 } else if (par->codec_id == AV_CODEC_ID_VVC && trk->extradata_size[trk->last_stsd_index] > 6 &&
7207 (AV_RB24(trk->extradata[trk->last_stsd_index]) == 1 || AV_RB32(trk->extradata[trk->last_stsd_index]) == 1)) {
7208 /* extradata is Annex B, assume the bitstream is too and convert it */
7209 if (trk->hint_track >= 0 && trk->hint_track < mov->nb_tracks) {
7210 ret = ff_vvc_annexb2mp4_buf(pkt->data, &reformatted_data,
7211 &size, 0, NULL);
7212 if (ret < 0)
7213 return ret;
7214 avio_write(pb, reformatted_data, size);
7215 } else {
7216 size = ff_vvc_annexb2mp4(pb, pkt->data, pkt->size, 0, NULL);
7217 }
7218 } else if (par->codec_id == AV_CODEC_ID_LCEVC && trk->extradata_size[trk->last_stsd_index] > 0 &&
7219 *(uint8_t *)trk->extradata[trk->last_stsd_index] != 1) {
7220 /* extradata is Annex B, assume the bitstream is too and convert it */
7221 if (trk->hint_track >= 0 && trk->hint_track < mov->nb_tracks) {
7222 ret = ff_nal_parse_units_buf(pkt->data, &reformatted_data, &size);
7223 if (ret < 0)
7224 return ret;
7225 avio_write(pb, reformatted_data, size);
7226 } else {
7227 if (trk->cenc.aes_ctr) {
7228 size = ff_mov_cenc_avc_parse_nal_units(&trk->cenc, pb, pkt->data, size);
7229 if (size < 0) {
7230 ret = size;
7231 goto err;
7232 }
7233 } else {
7234 size = ff_nal_parse_units(pb, pkt->data, pkt->size);
7235 }
7236 }
7237 } else if (par->codec_id == AV_CODEC_ID_AV1 && !trk->cenc.aes_ctr) {
7238 if (trk->hint_track >= 0 && trk->hint_track < mov->nb_tracks) {
7239 ret = ff_av1_filter_obus_buf(pkt->data, &reformatted_data,
7240 &size, &offset);
7241 if (ret < 0)
7242 return ret;
7243 avio_write(pb, reformatted_data, size);
7244 } else {
7245 size = ff_av1_filter_obus(pb, pkt->data, pkt->size);
7246 if (trk->mode == MODE_AVIF && !mov->avif_extent_length[pkt->stream_index]) {
7247 mov->avif_extent_length[pkt->stream_index] = size;
7248 }
7249 }
7250
7251 } else if (par->codec_id == AV_CODEC_ID_AC3 ||
7252 par->codec_id == AV_CODEC_ID_EAC3) {
7253 size = handle_eac3(mov, pkt, trk);
7254 if (size < 0)
7255 return size;
7256 else if (!size)
7257 goto end;
7258 avio_write(pb, pkt->data, size);
7259 } else if (par->codec_id == AV_CODEC_ID_EIA_608) {
7260 size = 8;
7261
7262 for (int i = 0; i < pkt->size; i += 3) {
7263 if (pkt->data[i] == 0xFC) {
7264 size += 2;
7265 }
7266 }
7267 avio_wb32(pb, size);
7268 ffio_wfourcc(pb, "cdat");
7269 for (int i = 0; i < pkt->size; i += 3) {
7270 if (pkt->data[i] == 0xFC) {
7271 avio_w8(pb, pkt->data[i + 1]);
7272 avio_w8(pb, pkt->data[i + 2]);
7273 }
7274 }
7275 } else if (par->codec_id == AV_CODEC_ID_APV) {
7276 ff_isom_parse_apvc(trk->apv, pkt, s);
7277 avio_wb32(s->pb, pkt->size);
7278 size += 4;
7279
7280 avio_write(s->pb, pkt->data, pkt->size);
7281 } else {
7282 if (trk->cenc.aes_ctr) {
7283 uint8_t *extradata = trk->extradata[trk->last_stsd_index];
7284 int extradata_size = trk->extradata_size[trk->last_stsd_index];
7285 if (par->codec_id == AV_CODEC_ID_H264 && extradata_size > 4) {
7286 int nal_size_length = (extradata[4] & 0x3) + 1;
7287 ret = ff_mov_cenc_avc_write_nal_units(s, &trk->cenc, nal_size_length, pb, pkt->data, size);
7288 } else if(par->codec_id == AV_CODEC_ID_HEVC && extradata_size > 21) {
7289 int nal_size_length = (extradata[21] & 0x3) + 1;
7290 ret = ff_mov_cenc_avc_write_nal_units(s, &trk->cenc, nal_size_length, pb, pkt->data, size);
7291 } else if(par->codec_id == AV_CODEC_ID_VVC) {
7293 } else if(par->codec_id == AV_CODEC_ID_AV1) {
7294 av_assert0(size == pkt->size);
7295 ret = ff_mov_cenc_av1_write_obus(s, &trk->cenc, pb, pkt);
7296 if (ret > 0) {
7297 size = ret;
7298 ret = 0;
7299 }
7300 } else {
7301 ret = ff_mov_cenc_write_packet(&trk->cenc, pb, pkt->data, size);
7302 }
7303
7304 if (ret) {
7305 goto err;
7306 }
7307 } else {
7308 avio_write(pb, pkt->data, size);
7309 }
7310 }
7311
7312 if (trk->entry >= trk->cluster_capacity) {
7313 unsigned new_capacity = trk->entry + MOV_INDEX_CLUSTER_SIZE;
7314 void *cluster = av_realloc_array(trk->cluster, new_capacity, sizeof(*trk->cluster));
7315 if (!cluster) {
7316 ret = AVERROR(ENOMEM);
7317 goto err;
7318 }
7319 trk->cluster = cluster;
7320 trk->cluster_capacity = new_capacity;
7321 }
7322
7323 trk->cluster[trk->entry].pos = avio_tell(pb) - size;
7324 trk->cluster[trk->entry].stsd_index = trk->last_stsd_index;
7325 trk->cluster[trk->entry].samples_in_chunk = samples_in_chunk;
7326 trk->cluster[trk->entry].chunkNum = 0;
7327 trk->cluster[trk->entry].size = size;
7328 trk->cluster[trk->entry].entries = samples_in_chunk;
7329 trk->cluster[trk->entry].dts = pkt->dts;
7330 trk->cluster[trk->entry].pts = pkt->pts;
7332 !trk->entry && trk->start_dts != AV_NOPTS_VALUE) {
7333 if (!trk->frag_discont) {
7334 /* First packet of a new fragment. We already wrote the duration
7335 * of the last packet of the previous fragment based on track_duration,
7336 * which might not exactly match our dts. Therefore adjust the dts
7337 * of this packet to be what the previous packets duration implies. */
7338 trk->cluster[trk->entry].dts = trk->start_dts + trk->track_duration;
7339 /* We also may have written the pts and the corresponding duration
7340 * in sidx/tfrf/tfxd tags; make sure the sidx pts and duration match up with
7341 * the next fragment. This means the cts of the first sample must
7342 * be the same in all fragments, unless end_pts was updated by
7343 * the packet causing the fragment to be written. */
7344 if ((mov->flags & FF_MOV_FLAG_DASH &&
7346 mov->mode == MODE_ISM)
7347 pkt->pts = pkt->dts + trk->end_pts - trk->cluster[trk->entry].dts;
7348 } else {
7349 /* New fragment, but discontinuous from previous fragments.
7350 * Pretend the duration sum of the earlier fragments is
7351 * pkt->dts - trk->start_dts. */
7352 trk->end_pts = trk->elst_end_pts = AV_NOPTS_VALUE;
7353 trk->frag_discont = 0;
7354 }
7355 }
7356
7357 if (!trk->entry && trk->start_dts == AV_NOPTS_VALUE && !mov->use_editlist &&
7358 s->avoid_negative_ts == AVFMT_AVOID_NEG_TS_MAKE_ZERO) {
7359 /* Not using edit lists and shifting the first track to start from zero.
7360 * If the other streams start from a later timestamp, we won't be able
7361 * to signal the difference in starting time without an edit list.
7362 * Thus move the timestamp for this first sample to 0, increasing
7363 * its duration instead. */
7364 trk->cluster[trk->entry].dts = trk->start_dts = 0;
7365 }
7366 if (trk->start_dts == AV_NOPTS_VALUE) {
7367 trk->start_dts = pkt->dts;
7368 if (trk->frag_discont) {
7369 if (mov->use_editlist) {
7370 /* Pretend the whole stream started at pts=0, with earlier fragments
7371 * already written. If the stream started at pts=0, the duration sum
7372 * of earlier fragments would have been pkt->pts. */
7373 trk->start_dts = pkt->dts - pkt->pts;
7374 } else {
7375 /* Pretend the whole stream started at dts=0, with earlier fragments
7376 * already written, with a duration summing up to pkt->dts. */
7377 trk->start_dts = 0;
7378 }
7379 trk->frag_discont = 0;
7380 } else if (pkt->dts && mov->moov_written)
7382 "Track %d starts with a nonzero dts %"PRId64", while the moov "
7383 "already has been written. Set the delay_moov flag to handle "
7384 "this case.\n",
7385 pkt->stream_index, pkt->dts);
7386 }
7387
7388 sd = av_packet_side_data_get(pkt->side_data, pkt->side_data_elems, AV_PKT_DATA_SKIP_SAMPLES);
7389 if (sd && sd->size >= 10 && trk->par->frame_size) {
7390 duration = FFMAX(av_rescale_q(trk->par->frame_size, (AVRational){ 1, trk->par->sample_rate },
7391 trk->st->time_base), pkt->duration);
7392 if (mov->use_editlist)
7393 pkt->duration = duration;
7394 duration -= av_rescale_q(AV_RL32(sd->data + 4), (AVRational){ 1, trk->par->sample_rate },
7395 trk->st->time_base);
7396 if (duration < 0)
7397 return AVERROR_INVALIDDATA;
7398 } else
7399 duration = pkt->duration;
7400
7401 trk->track_duration = pkt->dts - trk->start_dts + pkt->duration;
7403
7404 if (pkt->pts == AV_NOPTS_VALUE) {
7405 av_log(s, AV_LOG_WARNING, "pts has no value\n");
7406 pkt->pts = pkt->dts;
7407 }
7408 if (pkt->dts != pkt->pts)
7409 trk->flags |= MOV_TRACK_CTTS;
7410 trk->cluster[trk->entry].cts = pkt->pts - pkt->dts;
7411 trk->cluster[trk->entry].flags = 0;
7412 if (trk->start_cts == AV_NOPTS_VALUE || (pkt->dts <= 0 && trk->start_cts > pkt->pts - pkt->dts))
7413 trk->start_cts = pkt->pts - pkt->dts;
7414 if (trk->end_pts == AV_NOPTS_VALUE)
7415 trk->end_pts = trk->cluster[trk->entry].dts +
7416 trk->cluster[trk->entry].cts + duration;
7417 else
7418 trk->end_pts = FFMAX(trk->end_pts, trk->cluster[trk->entry].dts +
7419 trk->cluster[trk->entry].cts +
7420 duration);
7421 if (!(pkt->flags & AV_PKT_FLAG_DISCARD))
7422 trk->elst_end_pts = trk->end_pts;
7423
7424 if (par->codec_id == AV_CODEC_ID_VC1) {
7426 } else if (par->codec_id == AV_CODEC_ID_TRUEHD) {
7428 } else if (pkt->flags & AV_PKT_FLAG_KEY) {
7429 if (mov->mode == MODE_MOV && par->codec_id == AV_CODEC_ID_MPEG2VIDEO &&
7430 trk->entry > 0) { // force sync sample for the first key frame
7432 if (trk->cluster[trk->entry].flags & MOV_PARTIAL_SYNC_SAMPLE)
7433 trk->flags |= MOV_TRACK_STPS;
7434 } else {
7435 trk->cluster[trk->entry].flags = MOV_SYNC_SAMPLE;
7436 }
7437 if (trk->cluster[trk->entry].flags & MOV_SYNC_SAMPLE)
7438 trk->has_keyframes++;
7439 }
7440 if (pkt->flags & AV_PKT_FLAG_DISPOSABLE) {
7442 trk->has_disposable++;
7443 }
7444
7446 if (prft && prft_size == sizeof(AVProducerReferenceTime))
7447 memcpy(&trk->cluster[trk->entry].prft, prft, prft_size);
7448 else
7449 memset(&trk->cluster[trk->entry].prft, 0, sizeof(AVProducerReferenceTime));
7450
7451 trk->entry++;
7452 trk->sample_count += samples_in_chunk;
7453 mov->mdat_size += size;
7454
7455 if (trk->hint_track >= 0 && trk->hint_track < mov->nb_tracks)
7457 reformatted_data ? reformatted_data + offset
7458 : NULL, size);
7459
7460end:
7461err:
7462
7463 if (pkt->data != reformatted_data)
7464 av_free(reformatted_data);
7465 return ret;
7466}
7467
7469{
7470 MOVMuxContext *mov = s->priv_data;
7471 MOVTrack *trk = s->streams[pkt->stream_index]->priv_data;
7472 AVCodecParameters *par = trk->par;
7473 int64_t frag_duration = 0;
7474 int size = pkt->size;
7475
7476 int ret = check_pkt(s, trk, pkt);
7477 if (ret < 0)
7478 return ret;
7479
7480 if (mov->flags & FF_MOV_FLAG_FRAG_DISCONT) {
7481 for (int i = 0; i < mov->nb_streams; i++)
7482 mov->tracks[i].frag_discont = 1;
7484 }
7485
7487 if (trk->dts_shift == AV_NOPTS_VALUE)
7488 trk->dts_shift = pkt->pts - pkt->dts;
7489 pkt->dts += trk->dts_shift;
7490 }
7491
7492 if (trk->par->codec_id == AV_CODEC_ID_MP4ALS ||
7493 trk->par->codec_id == AV_CODEC_ID_AAC ||
7494 trk->par->codec_id == AV_CODEC_ID_AV1 ||
7495 trk->par->codec_id == AV_CODEC_ID_FLAC) {
7496 size_t side_size;
7497 uint8_t *side = av_packet_get_side_data(pkt, AV_PKT_DATA_NEW_EXTRADATA, &side_size);
7498 /* Overwrite extradata only on flush packets or when no extradata was available during init */
7499 if (side_size > 0 && (!pkt->size || !trk->extradata_size[trk->last_stsd_index])) {
7500 void *newextra = av_malloc(side_size + AV_INPUT_BUFFER_PADDING_SIZE);
7501 if (!newextra)
7502 return AVERROR(ENOMEM);
7503 memset((uint8_t*)newextra + side_size, 0, AV_INPUT_BUFFER_PADDING_SIZE);
7504 memcpy(newextra, side, side_size);
7505 av_free(trk->extradata[trk->last_stsd_index]);
7506 trk->extradata[trk->last_stsd_index] = newextra;
7507 trk->extradata_size[trk->last_stsd_index] = side_size;
7508 }
7509 }
7510
7511 if (!pkt->size) {
7512 if (trk->start_dts == AV_NOPTS_VALUE && trk->frag_discont) {
7513 trk->start_dts = pkt->dts;
7514 if (pkt->pts != AV_NOPTS_VALUE)
7515 trk->start_cts = pkt->pts - pkt->dts;
7516 else
7517 trk->start_cts = 0;
7518 }
7519
7520 return 0; /* Discard 0 sized packets */
7521 }
7522
7523 if (trk->entry && pkt->stream_index < mov->nb_streams)
7524 frag_duration = av_rescale_q(pkt->dts - trk->cluster[0].dts,
7525 s->streams[pkt->stream_index]->time_base,
7527 if ((mov->max_fragment_duration &&
7528 frag_duration >= mov->max_fragment_duration) ||
7529 (mov->max_fragment_size && mov->mdat_size + size >= mov->max_fragment_size) ||
7532 trk->entry && pkt->flags & AV_PKT_FLAG_KEY) ||
7534 if (frag_duration >= mov->min_fragment_duration) {
7535 if (trk->entry) {
7536 // Set the duration of this track to line up with the next
7537 // sample in this track. This avoids relying on AVPacket
7538 // duration, but only helps for this particular track, not
7539 // for the other ones that are flushed at the same time.
7540 //
7541 // If we have trk->entry == 0, no fragment will be written
7542 // for this track, and we can't adjust the track end here.
7543 trk->track_duration = pkt->dts - trk->start_dts;
7544 if (pkt->pts != AV_NOPTS_VALUE)
7545 trk->end_pts = pkt->pts;
7546 else
7547 trk->end_pts = pkt->dts;
7548 if (!(pkt->flags & AV_PKT_FLAG_DISCARD))
7549 trk->elst_end_pts = trk->end_pts;
7550 trk->end_reliable = 1;
7551 }
7553 }
7554 }
7555
7556 return ff_mov_write_packet(s, pkt);
7557}
7558
7560 int stream_index,
7561 int64_t dts) {
7562 MOVMuxContext *mov = s->priv_data;
7563 AVPacket *end = mov->pkt;
7564 uint8_t data[2] = {0};
7565 int ret;
7566
7567 end->size = sizeof(data);
7568 end->data = data;
7569 end->pts = dts;
7570 end->dts = dts;
7571 end->duration = 0;
7572 end->stream_index = stream_index;
7573
7574 ret = mov_write_single_packet(s, end);
7575 av_packet_unref(end);
7576
7577 return ret;
7578}
7579
7580#if CONFIG_IAMFENC
7581static int mov_build_iamf_packet(AVFormatContext *s, MOVTrack *trk, AVPacket *pkt)
7582{
7583 uint8_t *data;
7584 int ret;
7585
7586 if (pkt->stream_index == trk->first_iamf_idx) {
7587 ret = ff_iamf_write_parameter_blocks(trk->iamf, trk->iamf_buf, pkt, s);
7588 if (ret < 0)
7589 return ret;
7590 }
7591
7592 ret = ff_iamf_write_audio_frame(trk->iamf, trk->iamf_buf,
7593 s->streams[pkt->stream_index]->id, pkt);
7594 if (ret < 0)
7595 return ret;
7596
7597 if (pkt->stream_index != trk->last_iamf_idx)
7598 return AVERROR(EAGAIN);
7599
7600 ret = avio_close_dyn_buf(trk->iamf_buf, &data);
7601 trk->iamf_buf = NULL;
7602 if (!ret) {
7603 if (pkt->size) {
7604 // Either all or none of the packets for a single
7605 // IA Sample may be empty.
7606 av_log(s, AV_LOG_ERROR, "Unexpected packet from "
7607 "stream #%d\n", pkt->stream_index);
7608 ret = AVERROR_INVALIDDATA;
7609 }
7610 av_free(data);
7611 return ret;
7612 }
7613
7614 av_buffer_unref(&pkt->buf);
7615 pkt->buf = av_buffer_create(data, ret, NULL, NULL, 0);
7616 if (!pkt->buf) {
7617 av_free(data);
7618 return AVERROR(ENOMEM);
7619 }
7620 pkt->data = data;
7621 pkt->size = ret;
7622 pkt->stream_index = trk->first_iamf_idx;
7623
7624 return avio_open_dyn_buf(&trk->iamf_buf);
7625}
7626#endif
7627
7629{
7630 int64_t pos = avio_tell(pb);
7631 const char *scheme_id_uri = "https://aomedia.org/emsg/ID3";
7632 const char *value = "";
7633
7634 av_assert0(st->time_base.num == 1);
7635
7639
7640 avio_wb32(pb, 0); /* size */
7641 ffio_wfourcc(pb, "emsg");
7642 avio_w8(pb, 1); /* version */
7643 avio_wb24(pb, 0);
7644 avio_wb32(pb, st->time_base.den); /* timescale */
7645 avio_wb64(pb, pkt->pts); /* presentation_time */
7646 avio_wb32(pb, 0xFFFFFFFFU); /* event_duration */
7647 avio_wb32(pb, 0); /* id */
7648 /* null terminated UTF8 strings */
7649 avio_write(pb, scheme_id_uri, strlen(scheme_id_uri) + 1);
7650 avio_write(pb, value, strlen(value) + 1);
7651 avio_write(pb, pkt->data, pkt->size);
7652
7653 return update_size(pb, pos);
7654}
7655
7657{
7658 MOVMuxContext *mov = s->priv_data;
7659 MOVTrack *trk;
7660
7661 if (!pkt) {
7663 return 1;
7664 }
7665
7666 if (s->streams[pkt->stream_index]->codecpar->codec_id == AV_CODEC_ID_TIMED_ID3) {
7667 mov_write_emsg_tag(s->pb, s->streams[pkt->stream_index], pkt);
7668 return 0;
7669 }
7670
7671 trk = s->streams[pkt->stream_index]->priv_data;
7672
7673#if CONFIG_IAMFENC
7674 if (trk->iamf) {
7675 int ret = mov_build_iamf_packet(s, trk, pkt);
7676 if (ret < 0) {
7677 if (ret == AVERROR(EAGAIN))
7678 return 0;
7679 av_log(s, AV_LOG_ERROR, "Error assembling an IAMF packet "
7680 "for stream #%d\n", trk->st->index);
7681 return ret;
7682 }
7683 }
7684#endif
7685
7686 if (is_cover_image(trk->st)) {
7687 int ret;
7688
7689 if (trk->st->nb_frames >= 1) {
7690 if (trk->st->nb_frames == 1)
7691 av_log(s, AV_LOG_WARNING, "Got more than one picture in stream %d,"
7692 " ignoring.\n", pkt->stream_index);
7693 return 0;
7694 }
7695
7696 if ((ret = av_packet_ref(trk->cover_image, pkt)) < 0)
7697 return ret;
7698
7699 return 0;
7700 } else {
7701 int i;
7702
7703 if (!pkt->size)
7704 return mov_write_single_packet(s, pkt); /* Passthrough. */
7705
7706 /*
7707 * Subtitles require special handling.
7708 *
7709 * 1) For full compliance, every track must have a sample at
7710 * dts == 0, which is rarely true for subtitles. So, as soon
7711 * as we see any packet with dts > 0, write an empty subtitle
7712 * at dts == 0 for any subtitle track with no samples in it.
7713 *
7714 * 2) For each subtitle track, check if the current packet's
7715 * dts is past the duration of the last subtitle sample. If
7716 * so, we now need to write an end sample for that subtitle.
7717 *
7718 * This must be done conditionally to allow for subtitles that
7719 * immediately replace each other, in which case an end sample
7720 * is not needed, and is, in fact, actively harmful.
7721 *
7722 * 3) See mov_write_trailer for how the final end sample is
7723 * handled.
7724 */
7725 for (i = 0; i < mov->nb_tracks; i++) {
7726 MOVTrack *trk = &mov->tracks[i];
7727 int ret;
7728
7729 if (trk->par->codec_id == AV_CODEC_ID_MOV_TEXT &&
7730 trk->track_duration < pkt->dts &&
7731 (trk->entry == 0 || !trk->last_sample_is_subtitle_end)) {
7733 if (ret < 0) return ret;
7735 }
7736 }
7737
7739 /*
7740 * If the track has to have its samples squashed into one sample,
7741 * we just take it into the track's queue.
7742 * This will then be utilized as the samples get written in either
7743 * mov_flush_fragment or when the mux is finalized in
7744 * mov_write_trailer.
7745 */
7746 int ret = AVERROR_BUG;
7747
7748 if (pkt->pts == AV_NOPTS_VALUE) {
7750 "Packets without a valid presentation timestamp are "
7751 "not supported with packet squashing!\n");
7752 return AVERROR(EINVAL);
7753 }
7754
7755 /* The following will reset pkt and is only allowed to be used
7756 * because we return immediately. afterwards. */
7758 pkt, NULL, 0)) < 0) {
7759 return ret;
7760 }
7761
7762 return 0;
7763 }
7764
7765
7766 if (trk->mode == MODE_MOV && trk->par->codec_type == AVMEDIA_TYPE_VIDEO) {
7767 AVPacket *opkt = pkt;
7768 int reshuffle_ret, ret;
7769 if (trk->is_unaligned_qt_rgb) {
7770 int64_t bpc = trk->par->bits_per_coded_sample != 15 ? trk->par->bits_per_coded_sample : 16;
7771 int expected_stride = ((trk->par->width * bpc + 15) >> 4)*2;
7772 reshuffle_ret = ff_reshuffle_raw_rgb(s, &pkt, trk->par, expected_stride);
7773 if (reshuffle_ret < 0)
7774 return reshuffle_ret;
7775 } else
7776 reshuffle_ret = 0;
7777 if (trk->par->format == AV_PIX_FMT_PAL8 && !trk->pal_done) {
7778 ret = ff_get_packet_palette(s, opkt, reshuffle_ret, trk->palette);
7779 if (ret < 0)
7780 goto fail;
7781 if (ret)
7782 trk->pal_done++;
7783 } else if (trk->par->codec_id == AV_CODEC_ID_RAWVIDEO &&
7784 (trk->par->format == AV_PIX_FMT_GRAY8 ||
7785 trk->par->format == AV_PIX_FMT_MONOBLACK)) {
7787 if (ret < 0)
7788 goto fail;
7789 for (i = 0; i < pkt->size; i++)
7790 pkt->data[i] = ~pkt->data[i];
7791 }
7792 if (reshuffle_ret) {
7794fail:
7795 if (reshuffle_ret)
7797 return ret;
7798 }
7799 }
7800
7801 return mov_write_single_packet(s, pkt);
7802 }
7803}
7804
7805// QuickTime chapters involve an additional text track with the chapter names
7806// as samples, and a tref pointing from the other tracks to the chapter one.
7808{
7809 static const uint8_t stub_header[] = {
7810 // TextSampleEntry
7811 0x00, 0x00, 0x00, 0x01, // displayFlags
7812 0x00, 0x00, // horizontal + vertical justification
7813 0x00, 0x00, 0x00, 0x00, // bgColourRed/Green/Blue/Alpha
7814 // BoxRecord
7815 0x00, 0x00, 0x00, 0x00, // defTextBoxTop/Left
7816 0x00, 0x00, 0x00, 0x00, // defTextBoxBottom/Right
7817 // StyleRecord
7818 0x00, 0x00, 0x00, 0x00, // startChar + endChar
7819 0x00, 0x01, // fontID
7820 0x00, 0x00, // fontStyleFlags + fontSize
7821 0x00, 0x00, 0x00, 0x00, // fgColourRed/Green/Blue/Alpha
7822 // FontTableBox
7823 0x00, 0x00, 0x00, 0x0D, // box size
7824 'f', 't', 'a', 'b', // box atom name
7825 0x00, 0x01, // entry count
7826 // FontRecord
7827 0x00, 0x01, // font ID
7828 0x00, // font name length
7829 };
7830 MOVMuxContext *mov = s->priv_data;
7831 MOVTrack *track = &mov->tracks[tracknum];
7832 AVPacket *pkt = mov->pkt;
7833 int i, len;
7834 int ret;
7835
7836 track->mode = mov->mode;
7837 track->tag = MKTAG('t','e','x','t');
7838 track->timescale = mov->movie_timescale;
7839 track->par = avcodec_parameters_alloc();
7840 if (!track->par)
7841 return AVERROR(ENOMEM);
7843 ret = ff_alloc_extradata(track->par, sizeof(stub_header));
7844 if (ret < 0)
7845 return ret;
7846 memcpy(track->par->extradata, stub_header, sizeof(stub_header));
7847
7848 if (track->extradata == NULL) {
7849 track->stsd_count = 1;
7850 track->extradata = av_calloc(1, sizeof(*track->extradata));
7851 track->extradata_size = av_calloc(1, sizeof(*track->extradata_size));
7852 if (!track->extradata || !track->extradata_size)
7853 return AVERROR(ENOMEM);
7854 }
7855
7856 track->extradata[0] = av_memdup(stub_header, sizeof(stub_header));
7857 if (!track->extradata[0])
7858 return AVERROR(ENOMEM);
7859 track->extradata_size[0] = sizeof(stub_header);
7860
7861 pkt->stream_index = tracknum;
7862 pkt->flags = AV_PKT_FLAG_KEY;
7863
7864 for (i = 0; i < s->nb_chapters; i++) {
7865 AVChapter *c = s->chapters[i];
7867
7868 int64_t end = av_rescale_q(c->end, c->time_base, (AVRational){1,mov->movie_timescale});
7869 pkt->pts = pkt->dts = av_rescale_q(c->start, c->time_base, (AVRational){1,mov->movie_timescale});
7870 pkt->duration = end - pkt->dts;
7871
7872 if ((t = av_dict_get(c->metadata, "title", NULL, 0))) {
7873 static const char encd[12] = {
7874 0x00, 0x00, 0x00, 0x0C,
7875 'e', 'n', 'c', 'd',
7876 0x00, 0x00, 0x01, 0x00 };
7877 len = strlen(t->value);
7878 pkt->size = len + 2 + 12;
7879 pkt->data = av_malloc(pkt->size);
7880 if (!pkt->data) {
7882 return AVERROR(ENOMEM);
7883 }
7884 AV_WB16(pkt->data, len);
7885 memcpy(pkt->data + 2, t->value, len);
7886 memcpy(pkt->data + len + 2, encd, sizeof(encd));
7888 av_freep(&pkt->data);
7889 }
7890 }
7891
7892 av_packet_unref(mov->pkt);
7893
7894 return 0;
7895}
7896
7897
7898static int mov_check_timecode_track(AVFormatContext *s, AVTimecode *tc, AVStream *src_st, const char *tcstr)
7899{
7900 int ret;
7901
7902 /* compute the frame number */
7903 ret = av_timecode_init_from_string(tc, src_st->avg_frame_rate, tcstr, s);
7904 return ret;
7905}
7906
7907static int mov_create_timecode_track(AVFormatContext *s, int index, int src_index, AVTimecode tc)
7908{
7909 MOVMuxContext *mov = s->priv_data;
7910 MOVTrack *track = &mov->tracks[index];
7911 AVStream *src_st = mov->tracks[src_index].st;
7912 uint8_t data[4];
7913 AVPacket *pkt = mov->pkt;
7914 AVRational rate = src_st->avg_frame_rate;
7915 int ret;
7916
7917 /* tmcd track based on video stream */
7918 track->mode = mov->mode;
7919 track->tag = MKTAG('t','m','c','d');
7920 track->src_track = av_malloc(sizeof(*track->src_track));
7921 if (!track->src_track)
7922 return AVERROR(ENOMEM);
7923 *track->src_track = src_index;
7924 track->nb_src_track = 1;
7925 track->timescale = mov->tracks[src_index].timescale;
7928
7929 /* set st to src_st for metadata access*/
7930 track->st = src_st;
7931
7932 /* encode context: tmcd data stream */
7933 track->par = avcodec_parameters_alloc();
7934 if (!track->par)
7935 return AVERROR(ENOMEM);
7937 track->par->codec_tag = track->tag;
7938 track->st->avg_frame_rate = rate;
7939
7940 /* the tmcd track just contains one packet with the frame number */
7941 pkt->data = data;
7942 pkt->stream_index = index;
7943 pkt->flags = AV_PKT_FLAG_KEY;
7944 pkt->pts = pkt->dts = av_rescale_q(tc.start, av_inv_q(rate), (AVRational){ 1, track->timescale });
7945 pkt->size = 4;
7946 AV_WB32(pkt->data, tc.start);
7947 ret = ff_mov_write_packet(s, pkt);
7949 return ret;
7950}
7951
7952/*
7953 * st->disposition controls the "enabled" flag in the tkhd tag.
7954 * QuickTime will not play a track if it is not enabled. So make sure
7955 * that one track of each type (audio, video, subtitle) is enabled.
7956 *
7957 * Subtitles are special. For audio and video, setting "enabled" also
7958 * makes the track "default" (i.e. it is rendered when played). For
7959 * subtitles, an "enabled" subtitle is not rendered by default, but
7960 * if no subtitle is enabled, the subtitle menu in QuickTime will be
7961 * empty!
7962 */
7964{
7965 MOVMuxContext *mov = s->priv_data;
7966 int i;
7967 int enabled[AVMEDIA_TYPE_NB];
7968 int first[AVMEDIA_TYPE_NB];
7969
7970 for (i = 0; i < AVMEDIA_TYPE_NB; i++) {
7971 enabled[i] = 0;
7972 first[i] = -1;
7973 }
7974
7975 for (i = 0; i < mov->nb_streams; i++) {
7976 AVStream *st = mov->tracks[i].st;
7977
7980 is_cover_image(st))
7981 continue;
7982
7983 if (first[st->codecpar->codec_type] < 0)
7984 first[st->codecpar->codec_type] = i;
7987 enabled[st->codecpar->codec_type]++;
7988 }
7989 }
7990
7991 for (i = 0; i < AVMEDIA_TYPE_NB; i++) {
7992 switch (i) {
7993 case AVMEDIA_TYPE_VIDEO:
7994 case AVMEDIA_TYPE_AUDIO:
7996 if (enabled[i] > 1)
7997 mov->per_stream_grouping = 1;
7998 if (!enabled[i] && first[i] >= 0)
7999 mov->tracks[first[i]].flags |= MOV_TRACK_ENABLED;
8000 break;
8001 }
8002 }
8003}
8004
8006{
8007 MOVMuxContext *mov = s->priv_data;
8008
8009 for (int i = 0; i < s->nb_streams; i++)
8010 s->streams[i]->priv_data = NULL;
8011
8012 if (!mov->tracks)
8013 return;
8014
8015 if (mov->chapter_track) {
8017 }
8018
8019 for (int i = 0; i < mov->nb_tracks; i++) {
8020 MOVTrack *const track = &mov->tracks[i];
8021
8022 if (track->tag == MKTAG('r','t','p',' '))
8023 ff_mov_close_hinting(track);
8024 else if (track->tag == MKTAG('t','m','c','d') && mov->nb_meta_tmcd)
8025 av_freep(&track->par);
8026 av_freep(&track->cluster);
8027 av_freep(&track->cluster_written);
8028 av_freep(&track->frag_info);
8029 av_packet_free(&track->cover_image);
8030
8031 if (track->eac3_priv) {
8032 struct eac3_info *info = track->eac3_priv;
8033 av_packet_free(&info->pkt);
8034 av_freep(&track->eac3_priv);
8035 }
8036 for (int j = 0; j < track->stsd_count; j++)
8037 av_freep(&track->extradata[j]);
8038 av_freep(&track->extradata);
8039 av_freep(&track->extradata_size);
8040
8041 for (int i = 0; i < track->nb_tref_tags; i++)
8042 av_freep(&track->tref_tags[i].id);
8043 av_freep(&track->tref_tags);
8044 av_freep(&track->src_track);
8045
8046 ff_mov_cenc_free(&track->cenc);
8047 ffio_free_dyn_buf(&track->mdat_buf);
8048
8049#if CONFIG_IAMFENC
8050 ffio_free_dyn_buf(&track->iamf_buf);
8051 if (track->iamf)
8053 av_freep(&track->iamf);
8054#endif
8055 ff_isom_close_apvc(&track->apv);
8056
8058 }
8059
8060 av_freep(&mov->tracks);
8062}
8063
8064static uint32_t rgb_to_yuv(uint32_t rgb)
8065{
8066 uint8_t r, g, b;
8067 int y, cb, cr;
8068
8069 r = (rgb >> 16) & 0xFF;
8070 g = (rgb >> 8) & 0xFF;
8071 b = (rgb ) & 0xFF;
8072
8073 y = av_clip_uint8(( 16000 + 257 * r + 504 * g + 98 * b)/1000);
8074 cb = av_clip_uint8((128000 - 148 * r - 291 * g + 439 * b)/1000);
8075 cr = av_clip_uint8((128000 + 439 * r - 368 * g - 71 * b)/1000);
8076
8077 return (y << 16) | (cr << 8) | cb;
8078}
8079
8081 AVStream *st)
8082{
8083 int i, width = 720, height = 480;
8084 int have_palette = 0, have_size = 0;
8085 uint32_t palette[16];
8086 char *cur = st->codecpar->extradata;
8087
8088 while (cur && *cur) {
8089 if (strncmp("palette:", cur, 8) == 0) {
8090 int i, count;
8091 count = sscanf(cur + 8,
8092 "%06"PRIx32", %06"PRIx32", %06"PRIx32", %06"PRIx32", "
8093 "%06"PRIx32", %06"PRIx32", %06"PRIx32", %06"PRIx32", "
8094 "%06"PRIx32", %06"PRIx32", %06"PRIx32", %06"PRIx32", "
8095 "%06"PRIx32", %06"PRIx32", %06"PRIx32", %06"PRIx32"",
8096 &palette[ 0], &palette[ 1], &palette[ 2], &palette[ 3],
8097 &palette[ 4], &palette[ 5], &palette[ 6], &palette[ 7],
8098 &palette[ 8], &palette[ 9], &palette[10], &palette[11],
8099 &palette[12], &palette[13], &palette[14], &palette[15]);
8100
8101 for (i = 0; i < count; i++) {
8102 palette[i] = rgb_to_yuv(palette[i]);
8103 }
8104 have_palette = 1;
8105 } else if (!strncmp("size:", cur, 5)) {
8106 sscanf(cur + 5, "%dx%d", &width, &height);
8107 have_size = 1;
8108 }
8109 if (have_palette && have_size)
8110 break;
8111 cur += strcspn(cur, "\n\r");
8112 cur += strspn(cur, "\n\r");
8113 }
8114 if (have_palette) {
8116 if (!track->extradata[track->last_stsd_index])
8117 return AVERROR(ENOMEM);
8118 for (i = 0; i < 16; i++) {
8119 AV_WB32(track->extradata[track->last_stsd_index] + i * 4, palette[i]);
8120 }
8121 memset(track->extradata[track->last_stsd_index] + 16*4, 0, AV_INPUT_BUFFER_PADDING_SIZE);
8122 track->extradata_size[track->last_stsd_index] = 16 * 4;
8123 }
8124 st->codecpar->width = width;
8125 st->codecpar->height = track->height = height;
8126
8127 return 0;
8128}
8129
8130#if CONFIG_IAMFENC
8131static int mov_init_iamf_track(AVFormatContext *s)
8132{
8133 MOVMuxContext *mov = s->priv_data;
8134 MOVTrack *track;
8135 IAMFContext *iamf;
8136 int first_iamf_idx = INT_MAX, last_iamf_idx = 0;
8137 int nb_audio_elements = 0, nb_mix_presentations = 0;
8138 int ret;
8139
8140 for (int i = 0; i < s->nb_stream_groups; i++) {
8141 const AVStreamGroup *stg = s->stream_groups[i];
8142
8144 nb_audio_elements++;
8146 nb_mix_presentations++;
8147 }
8148
8149 if (!nb_audio_elements && !nb_mix_presentations)
8150 return 0;
8151
8152 if (nb_audio_elements < 1 || nb_audio_elements > 2 || nb_mix_presentations < 1) {
8153 av_log(s, AV_LOG_ERROR, "There must be >= 1 and <= 2 IAMF_AUDIO_ELEMENT and at least "
8154 "one IAMF_MIX_PRESENTATION stream groups to write a IMAF track\n");
8155 return AVERROR(EINVAL);
8156 }
8157
8158 iamf = av_mallocz(sizeof(*iamf));
8159 if (!iamf)
8160 return AVERROR(ENOMEM);
8161
8162
8163 for (int i = 0; i < s->nb_stream_groups; i++) {
8164 const AVStreamGroup *stg = s->stream_groups[i];
8165 switch(stg->type) {
8167 for (int j = 0; j < stg->nb_streams; j++) {
8168 first_iamf_idx = FFMIN(stg->streams[j]->index, first_iamf_idx);
8169 last_iamf_idx = FFMAX(stg->streams[j]->index, last_iamf_idx);
8170 }
8171
8172 ret = ff_iamf_add_audio_element(iamf, stg, s);
8173 break;
8175 ret = ff_iamf_add_mix_presentation(iamf, stg, s);
8176 break;
8177 default:
8178 av_assert0(0);
8179 }
8180 if (ret < 0) {
8182 av_free(iamf);
8183 return ret;
8184 }
8185 }
8186
8187 track = &mov->tracks[first_iamf_idx];
8188 track->iamf = iamf;
8189 track->first_iamf_idx = first_iamf_idx;
8190 track->last_iamf_idx = last_iamf_idx;
8191 track->tag = MKTAG('i','a','m','f');
8192
8193 for (int i = 0; i < s->nb_stream_groups; i++) {
8194 AVStreamGroup *stg = s->stream_groups[i];
8196 continue;
8197 for (int j = 0; j < stg->nb_streams; j++)
8198 stg->streams[j]->priv_data = track;
8199 }
8200
8201 ret = avio_open_dyn_buf(&track->iamf_buf);
8202 if (ret < 0)
8203 return ret;
8204
8205 return 0;
8206}
8207#endif
8208
8210{
8211 MOVMuxContext *mov = s->priv_data;
8212 int has_iamf = 0;
8213 int i, ret;
8214
8215 mov->fc = s;
8216 mov->pkt = ffformatcontext(s)->pkt;
8217
8218 /* Default mode == MP4 */
8219 mov->mode = MODE_MP4;
8220
8221#define IS_MODE(muxer, config) (CONFIG_ ## config ## _MUXER && !strcmp(#muxer, s->oformat->name))
8222 if (IS_MODE(3gp, TGP)) mov->mode = MODE_3GP;
8223 else if (IS_MODE(3g2, TG2)) mov->mode = MODE_3GP|MODE_3G2;
8224 else if (IS_MODE(mov, MOV)) mov->mode = MODE_MOV;
8225 else if (IS_MODE(psp, PSP)) mov->mode = MODE_PSP;
8226 else if (IS_MODE(ipod, IPOD)) mov->mode = MODE_IPOD;
8227 else if (IS_MODE(ismv, ISMV)) mov->mode = MODE_ISM;
8228 else if (IS_MODE(f4v, F4V)) mov->mode = MODE_F4V;
8229 else if (IS_MODE(avif, AVIF)) mov->mode = MODE_AVIF;
8230#undef IS_MODE
8231
8232 if (mov->flags & FF_MOV_FLAG_DELAY_MOOV)
8234
8235 if (mov->mode == MODE_AVIF)
8237
8238 /* Set the FRAGMENT flag if any of the fragmentation methods are
8239 * enabled. */
8240 if (mov->max_fragment_duration || mov->max_fragment_size ||
8246
8249 av_log(s, AV_LOG_ERROR, "Setting both hybrid_fragmented and faststart is not supported.\n");
8250 return AVERROR(EINVAL);
8251 }
8252
8253 /* Set other implicit flags immediately */
8256
8257 if (mov->mode == MODE_ISM)
8260 if (mov->flags & FF_MOV_FLAG_DASH)
8263 if (mov->flags & FF_MOV_FLAG_CMAF)
8266
8267 if (mov->flags & FF_MOV_FLAG_EMPTY_MOOV && s->flags & AVFMT_FLAG_AUTO_BSF) {
8268 av_log(s, AV_LOG_VERBOSE, "Empty MOOV enabled; disabling automatic bitstream filtering\n");
8269 s->flags &= ~AVFMT_FLAG_AUTO_BSF;
8270 }
8271
8273 av_log(s, AV_LOG_WARNING, "Global SIDX enabled; Ignoring skip_sidx option\n");
8275 }
8276
8277 if (mov->flags & FF_MOV_FLAG_FASTSTART) {
8278 mov->reserved_moov_size = -1;
8279 }
8280
8281 if (mov->use_editlist < 0) {
8282 mov->use_editlist = 1;
8283 if (mov->flags & FF_MOV_FLAG_FRAGMENT &&
8284 !(mov->flags & FF_MOV_FLAG_DELAY_MOOV)) {
8285 // If we can avoid needing an edit list by shifting the
8286 // tracks, prefer that over (trying to) write edit lists
8287 // in fragmented output.
8288 if (s->avoid_negative_ts == AVFMT_AVOID_NEG_TS_AUTO ||
8289 s->avoid_negative_ts == AVFMT_AVOID_NEG_TS_MAKE_ZERO)
8290 mov->use_editlist = 0;
8291 }
8292 }
8293 if (mov->flags & FF_MOV_FLAG_EMPTY_MOOV &&
8294 !(mov->flags & FF_MOV_FLAG_DELAY_MOOV) && mov->use_editlist)
8295 av_log(s, AV_LOG_WARNING, "No meaningful edit list will be written when using empty_moov without delay_moov\n");
8296
8297 if (mov->flags & FF_MOV_FLAG_CMAF && mov->use_editlist)
8299
8300 if (!mov->use_editlist && s->avoid_negative_ts == AVFMT_AVOID_NEG_TS_AUTO &&
8302 s->avoid_negative_ts = AVFMT_AVOID_NEG_TS_MAKE_ZERO;
8303
8304 /* Clear the omit_tfhd_offset flag if default_base_moof is set;
8305 * if the latter is set that's enough and omit_tfhd_offset doesn't
8306 * add anything extra on top of that. */
8310
8311 if (mov->frag_interleave &&
8314 "Sample interleaving in fragments is mutually exclusive with "
8315 "omit_tfhd_offset and separate_moof\n");
8316 return AVERROR(EINVAL);
8317 }
8318
8319 /* Non-seekable output is ok if using fragmentation. If ism_lookahead
8320 * is enabled, we don't support non-seekable output at all. */
8321 if (!(s->pb->seekable & AVIO_SEEKABLE_NORMAL) &&
8322 (!(mov->flags & FF_MOV_FLAG_FRAGMENT) || mov->ism_lookahead ||
8323 mov->mode == MODE_AVIF)) {
8324 av_log(s, AV_LOG_ERROR, "muxer does not support non seekable output\n");
8325 return AVERROR(EINVAL);
8326 }
8327
8328 /* AVIF output must have at most two video streams (one for YUV and one for
8329 * alpha). */
8330 if (mov->mode == MODE_AVIF) {
8331 if (s->nb_streams > 2) {
8332 av_log(s, AV_LOG_ERROR, "AVIF output requires exactly one or two streams\n");
8333 return AVERROR(EINVAL);
8334 }
8335 if (s->streams[0]->codecpar->codec_type != AVMEDIA_TYPE_VIDEO &&
8336 (s->nb_streams > 1 && s->streams[1]->codecpar->codec_type != AVMEDIA_TYPE_VIDEO)) {
8337 av_log(s, AV_LOG_ERROR, "AVIF output supports only video streams\n");
8338 return AVERROR(EINVAL);
8339 }
8340 if (s->nb_streams > 1) {
8341 const AVPixFmtDescriptor *pixdesc =
8342 av_pix_fmt_desc_get(s->streams[1]->codecpar->format);
8343 if (pixdesc->nb_components != 1) {
8344 av_log(s, AV_LOG_ERROR, "Second stream for AVIF (alpha) output must have exactly one plane\n");
8345 return AVERROR(EINVAL);
8346 }
8347 }
8348 s->streams[0]->disposition |= AV_DISPOSITION_DEFAULT;
8349 }
8350
8351 for (i = 0; i < s->nb_stream_groups; i++) {
8352 AVStreamGroup *stg = s->stream_groups[i];
8353
8354 if (stg->type == AV_STREAM_GROUP_PARAMS_LCEVC) {
8355 if (stg->nb_streams != 2) {
8356 av_log(s, AV_LOG_ERROR, "Exactly two Streams are supported for Stream Groups of type LCEVC\n");
8357 return AVERROR(EINVAL);
8358 }
8360 if (lcevc->el_index > 1)
8361 return AVERROR(EINVAL);
8362 AVStream *st = stg->streams[lcevc->el_index];
8363 if (st->codecpar->codec_id != AV_CODEC_ID_LCEVC) {
8364 av_log(s, AV_LOG_ERROR, "Stream #%u is not an LCEVC stream\n", lcevc->el_index);
8365 return AVERROR(EINVAL);
8366 }
8367 }
8368
8369#if CONFIG_IAMFENC
8371 continue;
8372
8373 for (int j = 0; j < stg->nb_streams; j++) {
8374 AVStream *st = stg->streams[j];
8375
8376 if (st->priv_data) {
8377 av_log(s, AV_LOG_ERROR, "Stream %d is present in more than one Stream Group of type "
8378 "IAMF Audio Element\n", j);
8379 return AVERROR(EINVAL);
8380 }
8381 st->priv_data = st;
8382 }
8383 has_iamf = 1;
8384
8385 if (!mov->nb_tracks) // We support one track for the entire IAMF structure
8386 mov->nb_tracks++;
8387#endif
8388 }
8389
8390 for (i = 0; i < s->nb_streams; i++) {
8391 AVStream *st = s->streams[i];
8392 if (st->priv_data)
8393 continue;
8394 // Don't produce a track in the output file for timed ID3 streams.
8396 // Leave priv_data set to NULL for these AVStreams that don't
8397 // have a corresponding track.
8398 continue;
8399 }
8400 st->priv_data = st;
8401 mov->nb_tracks++;
8402 }
8403
8404 mov->nb_streams = mov->nb_tracks;
8405
8406 if (mov->mode & (MODE_MP4|MODE_MOV|MODE_IPOD) && s->nb_chapters)
8407 mov->chapter_track = mov->nb_tracks++;
8408
8409 if (mov->flags & FF_MOV_FLAG_RTP_HINT) {
8410 for (i = 0; i < s->nb_streams; i++)
8411 if (rtp_hinting_needed(s->streams[i]))
8412 mov->nb_tracks++;
8413 }
8414
8415 if (mov->write_btrt < 0) {
8416 mov->write_btrt = mov->mode == MODE_MP4;
8417 }
8418
8419 if ( mov->write_tmcd == -1 && (mov->mode == MODE_MOV || mov->mode == MODE_MP4)
8420 || mov->write_tmcd == 1) {
8421 AVDictionaryEntry *global_tcr = av_dict_get(s->metadata, "timecode",
8422 NULL, 0);
8423
8424 /* +1 tmcd track for each video stream with a timecode */
8425 for (i = 0; i < s->nb_streams; i++) {
8426 AVStream *st = s->streams[i];
8427 AVDictionaryEntry *t = global_tcr;
8429 (t || (t=av_dict_get(st->metadata, "timecode", NULL, 0)))) {
8430 AVTimecode tc;
8431 ret = mov_check_timecode_track(s, &tc, st, t->value);
8432 if (ret >= 0)
8433 mov->nb_meta_tmcd++;
8434 }
8435 }
8436
8437 /* check if there is already a tmcd track to remux */
8438 if (mov->nb_meta_tmcd) {
8439 for (i = 0; i < s->nb_streams; i++) {
8440 AVStream *st = s->streams[i];
8441 if (st->codecpar->codec_tag == MKTAG('t','m','c','d')) {
8442 av_log(s, AV_LOG_WARNING, "You requested a copy of the original timecode track "
8443 "so timecode metadata are now ignored\n");
8444 mov->nb_meta_tmcd = 0;
8445 }
8446 }
8447 }
8448
8449 mov->nb_tracks += mov->nb_meta_tmcd;
8450 }
8451
8452 // Reserve an extra stream for chapters for the case where chapters
8453 // are written in the trailer
8454 mov->tracks = av_calloc(mov->nb_tracks + 1, sizeof(*mov->tracks));
8455 if (!mov->tracks)
8456 return AVERROR(ENOMEM);
8457
8458 for (i = 0; i < mov->nb_tracks; i++) {
8459 MOVTrack *track = &mov->tracks[i];
8460
8461 track->stsd_count = 1;
8462 track->extradata = av_calloc(track->stsd_count, sizeof(*track->extradata));
8463 track->extradata_size = av_calloc(track->stsd_count, sizeof(*track->extradata_size));
8464 if (!track->extradata || !track->extradata_size)
8465 return AVERROR(ENOMEM);
8466 }
8467
8468 if (mov->encryption_scheme_str != NULL && strcmp(mov->encryption_scheme_str, "none") != 0) {
8469 if (strcmp(mov->encryption_scheme_str, "cenc-aes-ctr") == 0) {
8471
8473 av_log(s, AV_LOG_ERROR, "Invalid encryption key len %d expected %d\n",
8475 return AVERROR(EINVAL);
8476 }
8477
8478 if (mov->encryption_kid_len != CENC_KID_SIZE) {
8479 av_log(s, AV_LOG_ERROR, "Invalid encryption kid len %d expected %d\n",
8481 return AVERROR(EINVAL);
8482 }
8483 } else {
8484 av_log(s, AV_LOG_ERROR, "unsupported encryption scheme %s\n",
8486 return AVERROR(EINVAL);
8487 }
8488 }
8489
8490#if CONFIG_IAMFENC
8491 ret = mov_init_iamf_track(s);
8492 if (ret < 0)
8493 return ret;
8494#endif
8495
8496 for (int j = 0, i = 0; j < s->nb_streams; j++) {
8497 AVStream *st = s->streams[j];
8498
8499 if (st != st->priv_data) {
8500 if (has_iamf)
8501 i += has_iamf--;
8502 continue;
8503 }
8504 st->priv_data = &mov->tracks[i++];
8505 }
8506
8507 AVRational movie_timescale = (AVRational) { 0, 1 };
8508 for (i = 0; i < s->nb_streams; i++) {
8509 AVStream *st= s->streams[i];
8510 MOVTrack *track = st->priv_data;
8511
8512 if (!track)
8513 continue;
8514
8515 if (!track->st) {
8516 track->st = st;
8517 track->par = st->codecpar;
8518 }
8519
8520 movie_timescale = av_gcd_q(movie_timescale, st->time_base, INT_MAX, (AVRational){1,0});
8521 }
8522 if (!movie_timescale.den)
8523 movie_timescale = MOV_TIMESCALE_Q;
8524
8525 if (!mov->movie_timescale)
8526 mov->movie_timescale = FFMAX(movie_timescale.den, MOV_TIMESCALE);
8527
8528 for (i = 0; i < s->nb_streams; i++) {
8529 AVStream *st= s->streams[i];
8530 MOVTrack *track = st->priv_data;
8531 AVDictionaryEntry *lang = av_dict_get(st->metadata, "language", NULL,0);
8532
8533 if (!track)
8534 continue;
8535
8536 track->language = ff_mov_iso639_to_lang(lang?lang->value:"und", mov->mode!=MODE_MOV);
8537 if (track->language < 0)
8538 track->language = 32767; // Unspecified Macintosh language code
8539 track->mode = mov->mode;
8540 if (!track->tag)
8541 track->tag = mov_find_codec_tag(s, track);
8542 if (!track->tag) {
8543 av_log(s, AV_LOG_ERROR, "Could not find tag for codec %s in stream #%d, "
8544 "codec not currently supported in container\n",
8546 return AVERROR(EINVAL);
8547 }
8548 /* If hinting of this track is enabled by a later hint track,
8549 * this is updated. */
8550 track->hint_track = -1;
8551 track->start_dts = AV_NOPTS_VALUE;
8552 track->start_cts = AV_NOPTS_VALUE;
8553 track->end_pts = AV_NOPTS_VALUE;
8554 track->dts_shift = AV_NOPTS_VALUE;
8556 if (track->tag == MKTAG('m','x','3','p') || track->tag == MKTAG('m','x','3','n') ||
8557 track->tag == MKTAG('m','x','4','p') || track->tag == MKTAG('m','x','4','n') ||
8558 track->tag == MKTAG('m','x','5','p') || track->tag == MKTAG('m','x','5','n')) {
8559 if (st->codecpar->width != 720 || (st->codecpar->height != 608 && st->codecpar->height != 512)) {
8560 av_log(s, AV_LOG_ERROR, "D-10/IMX must use 720x608 or 720x512 video resolution\n");
8561 return AVERROR(EINVAL);
8562 }
8563 track->height = track->tag >> 24 == 'n' ? 486 : 576;
8564 }
8565 if (mov->video_track_timescale) {
8566 track->timescale = mov->video_track_timescale;
8567 if (mov->mode == MODE_ISM && mov->video_track_timescale != 10000000)
8568 av_log(s, AV_LOG_WARNING, "Warning: some tools, like mp4split, assume a timescale of 10000000 for ISMV.\n");
8569 } else {
8570 track->timescale = st->time_base.den;
8571 while(track->timescale < 10000)
8572 track->timescale *= 2;
8573 }
8574 if (st->codecpar->width > 65535 || st->codecpar->height > 65535) {
8575 av_log(s, AV_LOG_ERROR, "Resolution %dx%d too large for mov/mp4\n", st->codecpar->width, st->codecpar->height);
8576 return AVERROR(EINVAL);
8577 }
8578 if (track->mode == MODE_MOV && track->timescale > 100000)
8580 "WARNING codec timebase is very high. If duration is too long,\n"
8581 "file may not be playable by quicktime. Specify a shorter timebase\n"
8582 "or choose different container.\n");
8583 if (track->mode == MODE_MOV &&
8584 track->par->codec_id == AV_CODEC_ID_RAWVIDEO &&
8585 track->tag == MKTAG('r','a','w',' ')) {
8586 enum AVPixelFormat pix_fmt = track->par->format;
8587 if (pix_fmt == AV_PIX_FMT_NONE && track->par->bits_per_coded_sample == 1)
8589 track->is_unaligned_qt_rgb =
8596 }
8597 if (track->par->codec_id == AV_CODEC_ID_VP9 && track->mode != MODE_MP4) {
8598 av_log(s, AV_LOG_ERROR, "%s only supported in MP4.\n", avcodec_get_name(track->par->codec_id));
8599 return AVERROR(EINVAL);
8600 } else if (track->par->codec_id == AV_CODEC_ID_AV1 &&
8601 track->mode != MODE_MP4 && track->mode != MODE_AVIF) {
8602 av_log(s, AV_LOG_ERROR, "%s only supported in MP4 and AVIF.\n", avcodec_get_name(track->par->codec_id));
8603 return AVERROR(EINVAL);
8604 } else if (track->par->codec_id == AV_CODEC_ID_VP8) {
8605 /* altref frames handling is not defined in the spec as of version v1.0,
8606 * so just forbid muxing VP8 streams altogether until a new version does */
8607 av_log(s, AV_LOG_ERROR, "VP8 muxing is currently not supported.\n");
8608 return AVERROR_PATCHWELCOME;
8609 } else if (track->par->codec_id == AV_CODEC_ID_APV) {
8610 ret = ff_isom_init_apvc(&track->apv, s);
8611 if (ret < 0)
8612 return ret;
8613 }
8614 if (is_cover_image(st)) {
8615 track->cover_image = av_packet_alloc();
8616 if (!track->cover_image)
8617 return AVERROR(ENOMEM);
8618 }
8619 } else if (st->codecpar->codec_type == AVMEDIA_TYPE_AUDIO) {
8620 track->timescale = st->codecpar->sample_rate;
8622 av_log(s, AV_LOG_WARNING, "track %d: codec frame size is not set\n", i);
8623 track->audio_vbr = 1;
8624 }else if (st->codecpar->codec_id == AV_CODEC_ID_ADPCM_MS ||
8627 if (!st->codecpar->block_align) {
8628 av_log(s, AV_LOG_ERROR, "track %d: codec block align is not set for adpcm\n", i);
8629 return AVERROR(EINVAL);
8630 }
8631 track->sample_size = st->codecpar->block_align;
8632 }else if (st->codecpar->frame_size > 1){ /* assume compressed audio */
8633 track->audio_vbr = 1;
8634 }else{
8635 track->sample_size = (av_get_bits_per_sample(st->codecpar->codec_id) >> 3) *
8637 }
8638 if (st->codecpar->codec_id == AV_CODEC_ID_ILBC ||
8640 track->audio_vbr = 1;
8641 }
8642 if (track->mode != MODE_MOV &&
8643 track->par->codec_id == AV_CODEC_ID_MP3 && track->timescale < 16000) {
8644 if (s->strict_std_compliance >= FF_COMPLIANCE_NORMAL) {
8645 av_log(s, AV_LOG_ERROR, "track %d: muxing mp3 at %dhz is not standard, to mux anyway set strict to -1\n",
8646 i, track->par->sample_rate);
8647 return AVERROR(EINVAL);
8648 } else {
8649 av_log(s, AV_LOG_WARNING, "track %d: muxing mp3 at %dhz is not standard in MP4\n",
8650 i, track->par->sample_rate);
8651 }
8652 }
8653 if (track->par->codec_id == AV_CODEC_ID_FLAC ||
8654 track->par->codec_id == AV_CODEC_ID_TRUEHD ||
8655 track->par->codec_id == AV_CODEC_ID_OPUS) {
8656 if (track->mode != MODE_MP4) {
8657 av_log(s, AV_LOG_ERROR, "%s only supported in MP4.\n", avcodec_get_name(track->par->codec_id));
8658 return AVERROR(EINVAL);
8659 }
8660 if (track->par->codec_id == AV_CODEC_ID_TRUEHD &&
8661 s->strict_std_compliance > FF_COMPLIANCE_EXPERIMENTAL) {
8663 "%s in MP4 support is experimental, add "
8664 "'-strict %d' if you want to use it.\n",
8666 return AVERROR_EXPERIMENTAL;
8667 }
8668 }
8669 } else if (st->codecpar->codec_type == AVMEDIA_TYPE_SUBTITLE) {
8670 track->timescale = st->time_base.den;
8671
8672 if (track->par->codec_id == AV_CODEC_ID_TTML) {
8673 /* 14496-30 requires us to use a single sample per fragment
8674 for TTML, for which we define a per-track flag.
8675
8676 We set the flag in case we are receiving TTML paragraphs
8677 from the input, in other words in case we are not doing
8678 stream copy. */
8681
8682 if (track->mode != MODE_ISM &&
8683 track->par->codec_tag == MOV_ISMV_TTML_TAG &&
8684 s->strict_std_compliance > FF_COMPLIANCE_UNOFFICIAL) {
8686 "ISMV style TTML support with the 'dfxp' tag in "
8687 "non-ISMV formats is not officially supported. Add "
8688 "'-strict unofficial' if you want to use it.\n");
8689 return AVERROR_EXPERIMENTAL;
8690 }
8691 }
8692 } else if (st->codecpar->codec_type == AVMEDIA_TYPE_DATA) {
8693 track->timescale = st->time_base.den;
8694 if (track->tag == MKTAG('t','m','c','d') &&
8695 st->codecpar->extradata_size >= 8)
8696 track->timecode_flags = AV_RB32(st->codecpar->extradata + 4);
8697 } else {
8698 track->timescale = mov->movie_timescale;
8699 }
8700 if (!track->height)
8701 track->height = st->codecpar->height;
8702 /* The Protected Interoperable File Format (PIFF) standard, used by ISMV recommends but
8703 doesn't mandate a track timescale of 10,000,000. The muxer allows a custom timescale
8704 for video tracks, so if user-set, it isn't overwritten */
8705 if (mov->mode == MODE_ISM &&
8708 track->timescale = 10000000;
8709 }
8710
8711 avpriv_set_pts_info(st, 64, 1, track->timescale);
8712
8714 ret = ff_mov_cenc_init(&track->cenc, mov->encryption_key,
8715 (track->par->codec_id == AV_CODEC_ID_H264 || track->par->codec_id == AV_CODEC_ID_HEVC ||
8716 track->par->codec_id == AV_CODEC_ID_VVC || track->par->codec_id == AV_CODEC_ID_AV1),
8717 track->par->codec_id, s->flags & AVFMT_FLAG_BITEXACT);
8718 if (ret)
8719 return ret;
8720 }
8721 }
8722
8723 for (i = 0; i < s->nb_stream_groups; i++) {
8724 AVStreamGroup *stg = s->stream_groups[i];
8725
8726 switch (stg->type) {
8729 AVStream *st = stg->streams[lcevc->el_index];
8730 MOVTrack *track = st->priv_data;
8731
8732 for (int j = 0; j < mov->nb_tracks; j++) {
8733 MOVTrack *trk = &mov->tracks[j];
8734
8735 if (trk->st == stg->streams[!lcevc->el_index]) {
8736 track->src_track = av_malloc(sizeof(*track->src_track));
8737 if (!track->src_track)
8738 return AVERROR(ENOMEM);
8739 *track->src_track = j;
8740 track->nb_src_track = 1;
8741 break;
8742 }
8743 }
8744
8745 track->par->width = lcevc->width;
8746 track->par->height = track->height = lcevc->height;
8747 break;
8748 }
8750 const AVStreamGroupTREF *tref = stg->params.tref;
8751 MOVTrack *track;
8752
8753 if (tref->metadata_index >= stg->nb_streams)
8754 return AVERROR(EINVAL);
8755
8756 track = stg->streams[tref->metadata_index]->priv_data;
8757 for (int j = 0; j < stg->nb_streams; j++) {
8758 const AVStream *st2 = stg->streams[j];
8759 int index = -1;
8760
8761 if (j == tref->metadata_index)
8762 continue;
8763
8764 for (int k = 0; k < mov->nb_tracks; k++) {
8765 if (mov->tracks[k].st != st2)
8766 continue;
8767 index = k;
8768 break;
8769 }
8770 if (index < 0)
8771 return AVERROR(EINVAL);
8772
8773 int *tmp = av_realloc(track->src_track,
8774 (track->nb_src_track + 1) * sizeof(*track->src_track));
8775 if (!tmp)
8776 return AVERROR(ENOMEM);
8777 track->src_track = tmp;
8778 track->src_track[track->nb_src_track++] = index;
8779 }
8780 break;
8781 }
8782 default:
8783 break;
8784 }
8785 }
8786
8787 /* fill src_track for tmcd tracks not covered by stream groups or
8788 * created by this muxer, retaining the old behavior of src_track
8789 * being arbitrarily 0. */
8790 for (i = 0; i < s->nb_streams; i++) {
8791 AVStream *st = s->streams[i];
8792 MOVTrack *track = st->priv_data;
8793 if (st->codecpar->codec_tag != MKTAG('t','m','c','d') ||
8794 track->nb_src_track)
8795 continue;
8796
8797 track->src_track = av_malloc(sizeof(*track->src_track));
8798 if (!track->src_track)
8799 return AVERROR(ENOMEM);
8800 *track->src_track = 0;
8801 track->nb_src_track = 1;
8802 }
8803
8805 return 0;
8806}
8807
8809{
8810 AVIOContext *pb = s->pb;
8811 MOVMuxContext *mov = s->priv_data;
8812 int ret, hint_track = 0, tmcd_track = 0, nb_tracks = mov->nb_streams;
8813
8814 if (mov->mode & (MODE_MP4|MODE_MOV|MODE_IPOD) && s->nb_chapters)
8815 nb_tracks++;
8816
8817 if (mov->flags & FF_MOV_FLAG_RTP_HINT) {
8818 hint_track = nb_tracks;
8819 for (int i = 0; i < mov->nb_streams; i++) {
8820 if (rtp_hinting_needed(mov->tracks[i].st))
8821 nb_tracks++;
8822 }
8823 }
8824
8825 if (mov->nb_meta_tmcd)
8826 tmcd_track = nb_tracks;
8827
8828 for (int i = 0; i < mov->nb_streams; i++) {
8829 MOVTrack *track = &mov->tracks[i];
8830 AVStream *st = track->st;
8831
8832 /* copy extradata if it exists */
8833 if (st->codecpar->extradata_size) {
8836 else if (!TAG_IS_AVCI(track->tag) && st->codecpar->codec_id != AV_CODEC_ID_DNXHD) {
8838 track->extradata[track->last_stsd_index] =
8840 if (!track->extradata[track->last_stsd_index]) {
8841 return AVERROR(ENOMEM);
8842 }
8843 memcpy(track->extradata[track->last_stsd_index],
8844 st->codecpar->extradata, track->extradata_size[track->last_stsd_index]);
8845 memset(track->extradata[track->last_stsd_index] + track->extradata_size[track->last_stsd_index],
8847 }
8848 }
8849
8853 continue;
8854
8855 for (int j = 0; j < mov->nb_streams; j++) {
8856 AVStream *stj= mov->tracks[j].st;
8857 MOVTrack *trackj= &mov->tracks[j];
8858 if (j == i)
8859 continue;
8860
8861 if (stj->codecpar->codec_type == AVMEDIA_TYPE_AUDIO &&
8862 (trackj->par->ch_layout.nb_channels != 1 ||
8865 )
8866 track->mono_as_fc = -1;
8867
8868 if (stj->codecpar->codec_type == AVMEDIA_TYPE_AUDIO &&
8871 trackj->par->ch_layout.nb_channels == 1 && track->mono_as_fc >= 0
8872 )
8873 track->mono_as_fc++;
8874
8875 if (stj->codecpar->codec_type != AVMEDIA_TYPE_AUDIO ||
8878 trackj->language != track->language ||
8879 trackj->tag != track->tag
8880 )
8881 continue;
8882 track->multichannel_as_mono++;
8883 }
8884 }
8885
8886 if (!(mov->flags & FF_MOV_FLAG_DELAY_MOOV) ||
8888 if ((ret = mov_write_identification(pb, s)) < 0)
8889 return ret;
8890 }
8891
8892 if (mov->reserved_moov_size){
8893 mov->reserved_header_pos = avio_tell(pb);
8894 if (mov->reserved_moov_size > 0)
8895 avio_skip(pb, mov->reserved_moov_size);
8896 }
8897
8898 if (mov->flags & FF_MOV_FLAG_FRAGMENT) {
8899 /* If no fragmentation options have been set, set a default. */
8900 if (!(mov->flags & (FF_MOV_FLAG_FRAG_KEYFRAME |
8906 avio_wb32(pb, 8); // placeholder for extended size field (64 bit)
8907 ffio_wfourcc(pb, mov->mode == MODE_MOV ? "wide" : "free");
8908 mov->mdat_pos = avio_tell(pb);
8909 // The free/wide header that later will be converted into an
8910 // mdat, covering the initial moov and all the fragments.
8911 avio_wb32(pb, 0);
8912 ffio_wfourcc(pb, mov->mode == MODE_MOV ? "wide" : "free");
8913 // Write an ftyp atom, hidden in a free/wide. This is neither
8914 // exposed while the file is written, as fragmented, nor when the
8915 // file is finalized into non-fragmented form. However, this allows
8916 // accessing a pristine, sequential ftyp+moov init segment, even
8917 // after the file is finalized. It also allows dumping the whole
8918 // contents of the mdat box, to get the fragmented form of the
8919 // file.
8920 if ((ret = mov_write_identification(pb, s)) < 0)
8921 return ret;
8922 update_size(pb, mov->mdat_pos);
8923 }
8924 } else if (mov->mode != MODE_AVIF) {
8925 if (mov->flags & FF_MOV_FLAG_FASTSTART)
8926 mov->reserved_header_pos = avio_tell(pb);
8927 mov_write_mdat_tag(pb, mov);
8928 }
8929
8931 if (mov->time)
8932 mov->time += 0x7C25B080; // 1970 based -> 1904 based
8933
8934 if (mov->chapter_track)
8935 if ((ret = mov_create_chapter_track(s, mov->chapter_track)) < 0)
8936 return ret;
8937
8938 if (mov->flags & FF_MOV_FLAG_RTP_HINT) {
8939 for (int i = 0; i < mov->nb_streams; i++) {
8940 if (rtp_hinting_needed(mov->tracks[i].st)) {
8941 if ((ret = ff_mov_init_hinting(s, hint_track, i)) < 0)
8942 return ret;
8943 hint_track++;
8944 }
8945 }
8946 }
8947
8948 if (mov->nb_meta_tmcd) {
8949 const AVDictionaryEntry *t, *global_tcr = av_dict_get(s->metadata,
8950 "timecode", NULL, 0);
8951 /* Initialize the tmcd tracks */
8952 for (int i = 0; i < mov->nb_streams; i++) {
8953 AVStream *st = mov->tracks[i].st;
8954 t = global_tcr;
8955
8957 AVTimecode tc;
8958 if (!t)
8959 t = av_dict_get(st->metadata, "timecode", NULL, 0);
8960 if (!t)
8961 continue;
8962 if (mov_check_timecode_track(s, &tc, st, t->value) < 0)
8963 continue;
8964 if ((ret = mov_create_timecode_track(s, tmcd_track, i, tc)) < 0)
8965 return ret;
8966 tmcd_track++;
8967 }
8968 }
8969 }
8970
8971 avio_flush(pb);
8972
8973 if (mov->flags & FF_MOV_FLAG_ISML)
8974 mov_write_isml_manifest(pb, mov, s);
8975
8976 if (mov->flags & FF_MOV_FLAG_EMPTY_MOOV &&
8977 !(mov->flags & FF_MOV_FLAG_DELAY_MOOV)) {
8978 if ((ret = mov_write_moov_tag(pb, mov, s)) < 0)
8979 return ret;
8980 mov->moov_written = 1;
8981 if (mov->flags & FF_MOV_FLAG_GLOBAL_SIDX)
8982 mov->reserved_header_pos = avio_tell(pb);
8983 }
8984
8985 return 0;
8986}
8987
8989{
8990 int ret;
8991 AVIOContext *moov_buf;
8992 MOVMuxContext *mov = s->priv_data;
8993
8994 if ((ret = ffio_open_null_buf(&moov_buf)) < 0)
8995 return ret;
8996 if ((ret = mov_write_moov_tag(moov_buf, mov, s)) < 0)
8997 return ret;
8998 return ffio_close_null_buf(moov_buf);
8999}
9000
9002{
9003 int ret;
9004 AVIOContext *buf;
9005 MOVMuxContext *mov = s->priv_data;
9006
9007 if ((ret = ffio_open_null_buf(&buf)) < 0)
9008 return ret;
9009 mov_write_sidx_tags(buf, mov, -1, 0);
9010 return ffio_close_null_buf(buf);
9011}
9012
9013/*
9014 * This function gets the moov size if moved to the top of the file: the chunk
9015 * offset table can switch between stco (32-bit entries) to co64 (64-bit
9016 * entries) when the moov is moved to the beginning, so the size of the moov
9017 * would change. It also updates the chunk offset tables.
9018 */
9020{
9021 int i, moov_size, moov_size2;
9022 MOVMuxContext *mov = s->priv_data;
9023
9024 moov_size = get_moov_size(s);
9025 if (moov_size < 0)
9026 return moov_size;
9027
9028 for (i = 0; i < mov->nb_tracks; i++)
9029 mov->tracks[i].data_offset += moov_size;
9030
9031 moov_size2 = get_moov_size(s);
9032 if (moov_size2 < 0)
9033 return moov_size2;
9034
9035 /* if the size changed, we just switched from stco to co64 and need to
9036 * update the offsets */
9037 if (moov_size2 != moov_size)
9038 for (i = 0; i < mov->nb_tracks; i++)
9039 mov->tracks[i].data_offset += moov_size2 - moov_size;
9040
9041 return moov_size2;
9042}
9043
9045{
9046 int i, sidx_size;
9047 MOVMuxContext *mov = s->priv_data;
9048
9049 sidx_size = get_sidx_size(s);
9050 if (sidx_size < 0)
9051 return sidx_size;
9052
9053 for (i = 0; i < mov->nb_tracks; i++)
9054 mov->tracks[i].data_offset += sidx_size;
9055
9056 return sidx_size;
9057}
9058
9060{
9061 int moov_size;
9062 MOVMuxContext *mov = s->priv_data;
9063
9064 if (mov->flags & FF_MOV_FLAG_FRAGMENT)
9065 moov_size = compute_sidx_size(s);
9066 else
9067 moov_size = compute_moov_size(s);
9068 if (moov_size < 0)
9069 return moov_size;
9070
9071 return ff_format_shift_data(s, mov->reserved_header_pos, moov_size);
9072}
9073
9075{
9076 MOVMuxContext *mov = s->priv_data;
9077 AVIOContext *pb = s->pb;
9078
9079 /* Write size of mdat tag */
9080 if (mov->mdat_size + 8 <= UINT32_MAX) {
9081 avio_seek(pb, mov->mdat_pos, SEEK_SET);
9082 avio_wb32(pb, mov->mdat_size + 8);
9084 ffio_wfourcc(pb, "mdat"); // overwrite the original free/wide into a mdat
9085 } else {
9086 /* overwrite 'wide' placeholder atom */
9087 avio_seek(pb, mov->mdat_pos - 8, SEEK_SET);
9088 /* special value: real atom size will be 64 bit value after
9089 * tag field */
9090 avio_wb32(pb, 1);
9091 ffio_wfourcc(pb, "mdat");
9092 avio_wb64(pb, mov->mdat_size + 16);
9093 }
9094}
9095
9097{
9098 MOVMuxContext *mov = s->priv_data;
9099 AVIOContext *pb = s->pb;
9100 int res = 0;
9101 int i;
9102 int64_t moov_pos;
9103
9104 /*
9105 * Before actually writing the trailer, make sure that there are no
9106 * dangling subtitles, that need a terminating sample.
9107 */
9108 for (i = 0; i < mov->nb_tracks; i++) {
9109 MOVTrack *trk = &mov->tracks[i];
9110 if (trk->par->codec_id == AV_CODEC_ID_MOV_TEXT &&
9114 }
9115 }
9116
9117 //Also check for a buffered EAC3 packet
9118 for (i = 0; i < mov->nb_tracks; i++) {
9119 MOVTrack *trk = &mov->tracks[i];
9120 if (trk->par->codec_id != AV_CODEC_ID_EAC3)
9121 continue;
9122 struct eac3_info *info = trk->eac3_priv;
9123 if (!info || !info->pkt || !info->pkt->size)
9124 continue;
9125
9126 av_packet_move_ref(mov->pkt, info->pkt);
9127 info->eof = 1;
9128 res = mov_write_single_packet(s, mov->pkt);
9129 if (res < 0)
9130 return res;
9131
9132 av_packet_unref(mov->pkt);
9133 }
9134
9135 // Check if we have any tracks that require squashing.
9136 // In that case, we'll have to write the packet here.
9137 if ((res = mov_write_squashed_packets(s)) < 0)
9138 return res;
9139
9140 // If there were no chapters when the header was written, but there
9141 // are chapters now, write them in the trailer. This only works
9142 // when we are not doing fragments.
9143 if (!mov->chapter_track && !(mov->flags & FF_MOV_FLAG_FRAGMENT)) {
9144 if (mov->mode & (MODE_MP4|MODE_MOV|MODE_IPOD) && s->nb_chapters) {
9145 mov->chapter_track = mov->nb_tracks++;
9146 if ((res = mov_create_chapter_track(s, mov->chapter_track)) < 0)
9147 return res;
9148 }
9149 }
9150
9151 if (!(mov->flags & FF_MOV_FLAG_FRAGMENT) ||
9155 mov->mdat_size = avio_tell(pb) - mov->mdat_pos - 8;
9156 for (i = 0; i < mov->nb_tracks; i++) {
9157 MOVTrack *track = &mov->tracks[i];
9158 track->data_offset = 0;
9159 av_free(track->cluster);
9160 track->cluster = track->cluster_written;
9161 track->entry = track->entry_written;
9162 track->cluster_written = NULL;
9163 track->entry_written = 0;
9164 track->chunkCount = 0; // Force build_chunks to rebuild the list of chunks
9165 }
9166 // Clear the empty_moov flag, as we do want the moov to include
9167 // all the samples at this point.
9169 }
9170
9171 moov_pos = avio_tell(pb);
9172
9175
9176 avio_seek(pb, mov->reserved_moov_size > 0 ? mov->reserved_header_pos : moov_pos, SEEK_SET);
9177
9178 if (mov->flags & FF_MOV_FLAG_FASTSTART) {
9179 av_log(s, AV_LOG_INFO, "Starting second pass: moving the moov atom to the beginning of the file\n");
9180 res = shift_data(s);
9181 if (res < 0)
9182 return res;
9183 avio_seek(pb, mov->reserved_header_pos, SEEK_SET);
9184 if ((res = mov_write_moov_tag(pb, mov, s)) < 0)
9185 return res;
9186 } else if (mov->reserved_moov_size > 0) {
9187 int64_t size;
9188 if ((res = mov_write_moov_tag(pb, mov, s)) < 0)
9189 return res;
9191 if (size < 8){
9192 av_log(s, AV_LOG_ERROR, "reserved_moov_size is too small, needed %"PRId64" additional\n", 8-size);
9193 return AVERROR(EINVAL);
9194 }
9195 avio_wb32(pb, size);
9196 ffio_wfourcc(pb, "free");
9197 ffio_fill(pb, 0, size - 8);
9198 avio_seek(pb, moov_pos, SEEK_SET);
9199 } else {
9200 if ((res = mov_write_moov_tag(pb, mov, s)) < 0)
9201 return res;
9202 }
9203
9205 // With hybrid fragmentation, only write the mdat size (hiding
9206 // the original moov and all the fragments within the mdat)
9207 // after we've successfully written the complete moov, to avoid
9208 // risk for an unreadable file if writing the final moov fails.
9210 }
9211
9212 res = 0;
9213 } else {
9215 for (i = 0; i < mov->nb_tracks; i++)
9216 mov->tracks[i].data_offset = 0;
9217 if (mov->flags & FF_MOV_FLAG_GLOBAL_SIDX) {
9218 int64_t end;
9219 av_log(s, AV_LOG_INFO, "Starting second pass: inserting sidx atoms\n");
9220 res = shift_data(s);
9221 if (res < 0)
9222 return res;
9223 end = avio_tell(pb);
9224 avio_seek(pb, mov->reserved_header_pos, SEEK_SET);
9225 mov_write_sidx_tags(pb, mov, -1, 0);
9226 avio_seek(pb, end, SEEK_SET);
9227 }
9228 if (!(mov->flags & FF_MOV_FLAG_SKIP_TRAILER)) {
9230 res = mov_write_mfra_tag(pb, mov);
9231 if (res < 0)
9232 return res;
9233 }
9234 }
9235
9236 return res;
9237}
9238
9240 const AVPacket *pkt)
9241{
9242 int ret = 1;
9243
9244 if (st->codecpar->codec_id == AV_CODEC_ID_AAC) {
9245 if (pkt->size > 2 && (AV_RB16(pkt->data) & 0xfff0) == 0xfff0)
9246 ret = ff_stream_add_bitstream_filter(st, "aac_adtstoasc", NULL);
9247 } else if (st->codecpar->codec_id == AV_CODEC_ID_VP9) {
9248 ret = ff_stream_add_bitstream_filter(st, "vp9_superframe", NULL);
9249 }
9250
9251 return ret;
9252}
9253
9254#if CONFIG_AVIF_MUXER
9255static int avif_write_trailer(AVFormatContext *s)
9256{
9257 AVIOContext *pb = s->pb;
9258 MOVMuxContext *mov = s->priv_data;
9259 int64_t pos_backup, extent_offsets[2];
9260 uint8_t *buf;
9261 int buf_size, moov_size;
9262
9263 if (mov->moov_written) return 0;
9264
9265 mov->is_animated_avif = s->streams[0]->nb_frames > 1;
9266 if (mov->is_animated_avif && mov->nb_streams > 1) {
9267 // For animated avif with alpha channel, we need to write a tref tag
9268 // with type "auxl".
9269 MovTag *tag = mov_add_tref_tag(mov, &mov->tracks[1], MKTAG('a', 'u', 'x', 'l'));
9270 if (!tag)
9271 return AVERROR(ENOMEM);
9272
9273 int ret = mov_add_tref_id(mov, tag, 1);
9274 if (ret < 0)
9275 return ret;
9276 }
9278 mov_write_meta_tag(pb, mov, s);
9279
9280 moov_size = get_moov_size(s);
9281 for (int i = 0; i < mov->nb_tracks; i++)
9282 mov->tracks[i].data_offset = avio_tell(pb) + moov_size + 8;
9283
9284 if (mov->is_animated_avif) {
9285 int ret;
9286 if ((ret = mov_write_moov_tag(pb, mov, s)) < 0)
9287 return ret;
9288 }
9289
9290 buf_size = avio_get_dyn_buf(mov->mdat_buf, &buf);
9291 avio_wb32(pb, buf_size + 8);
9292 ffio_wfourcc(pb, "mdat");
9293
9294 // The offset for the YUV planes is the starting position of mdat.
9295 extent_offsets[0] = avio_tell(pb);
9296 // The offset for alpha plane is YUV offset + YUV size.
9297 extent_offsets[1] = extent_offsets[0] + mov->avif_extent_length[0];
9298
9299 avio_write(pb, buf, buf_size);
9300
9301 // write extent offsets.
9302 pos_backup = avio_tell(pb);
9303 for (int i = 0; i < mov->nb_streams; i++) {
9304 if (extent_offsets[i] != (uint32_t)extent_offsets[i]) {
9305 av_log(s, AV_LOG_ERROR, "extent offset does not fit in 32 bits\n");
9306 return AVERROR_INVALIDDATA;
9307 }
9308 avio_seek(pb, mov->avif_extent_pos[i], SEEK_SET);
9309 avio_wb32(pb, extent_offsets[i]); /* rewrite offset */
9310 }
9311 avio_seek(pb, pos_backup, SEEK_SET);
9312
9313 return 0;
9314}
9315#endif
9316
9317#if CONFIG_TGP_MUXER || CONFIG_TG2_MUXER
9318static const AVCodecTag codec_3gp_tags[] = {
9319 { AV_CODEC_ID_H263, MKTAG('s','2','6','3') },
9320 { AV_CODEC_ID_H264, MKTAG('a','v','c','1') },
9321 { AV_CODEC_ID_MPEG4, MKTAG('m','p','4','v') },
9322 { AV_CODEC_ID_AAC, MKTAG('m','p','4','a') },
9323 { AV_CODEC_ID_AMR_NB, MKTAG('s','a','m','r') },
9324 { AV_CODEC_ID_AMR_WB, MKTAG('s','a','w','b') },
9325 { AV_CODEC_ID_MOV_TEXT, MKTAG('t','x','3','g') },
9326 { AV_CODEC_ID_NONE, 0 },
9327};
9328static const AVCodecTag *const codec_3gp_tags_list[] = { codec_3gp_tags, NULL };
9329#endif
9330
9331static const AVCodecTag codec_mp4_tags[] = {
9332 { AV_CODEC_ID_MPEG4, MKTAG('m', 'p', '4', 'v') },
9333 { AV_CODEC_ID_H264, MKTAG('a', 'v', 'c', '1') },
9334 { AV_CODEC_ID_H264, MKTAG('a', 'v', 'c', '3') },
9335 { AV_CODEC_ID_HEVC, MKTAG('h', 'e', 'v', '1') },
9336 { AV_CODEC_ID_HEVC, MKTAG('h', 'v', 'c', '1') },
9337 { AV_CODEC_ID_HEVC, MKTAG('d', 'v', 'h', '1') },
9338 { AV_CODEC_ID_VVC, MKTAG('v', 'v', 'c', '1') },
9339 { AV_CODEC_ID_VVC, MKTAG('v', 'v', 'i', '1') },
9340 { AV_CODEC_ID_EVC, MKTAG('e', 'v', 'c', '1') },
9341 { AV_CODEC_ID_LCEVC, MKTAG('l', 'v', 'c', '1') },
9342 { AV_CODEC_ID_APV, MKTAG('a', 'p', 'v', '1') },
9343 { AV_CODEC_ID_MPEG2VIDEO, MKTAG('m', 'p', '4', 'v') },
9344 { AV_CODEC_ID_MPEG1VIDEO, MKTAG('m', 'p', '4', 'v') },
9345 { AV_CODEC_ID_MJPEG, MKTAG('m', 'p', '4', 'v') },
9346 { AV_CODEC_ID_PNG, MKTAG('m', 'p', '4', 'v') },
9347 { AV_CODEC_ID_JPEG2000, MKTAG('m', 'p', '4', 'v') },
9348 { AV_CODEC_ID_VC1, MKTAG('v', 'c', '-', '1') },
9349 { AV_CODEC_ID_DIRAC, MKTAG('d', 'r', 'a', 'c') },
9350 { AV_CODEC_ID_TSCC2, MKTAG('m', 'p', '4', 'v') },
9351 { AV_CODEC_ID_VP9, MKTAG('v', 'p', '0', '9') },
9352 { AV_CODEC_ID_AV1, MKTAG('a', 'v', '0', '1') },
9353 { AV_CODEC_ID_AAC, MKTAG('m', 'p', '4', 'a') },
9354 { AV_CODEC_ID_APPLE_APAC, MKTAG('a', 'p', 'a', 'c') },
9355 { AV_CODEC_ID_ALAC, MKTAG('a', 'l', 'a', 'c') },
9356 { AV_CODEC_ID_MP4ALS, MKTAG('m', 'p', '4', 'a') },
9357 { AV_CODEC_ID_MP3, MKTAG('m', 'p', '4', 'a') },
9358 { AV_CODEC_ID_MP2, MKTAG('m', 'p', '4', 'a') },
9359 { AV_CODEC_ID_AC3, MKTAG('a', 'c', '-', '3') },
9360 { AV_CODEC_ID_EAC3, MKTAG('e', 'c', '-', '3') },
9361 { AV_CODEC_ID_DTS, MKTAG('m', 'p', '4', 'a') },
9362 { AV_CODEC_ID_TRUEHD, MKTAG('m', 'l', 'p', 'a') },
9363 { AV_CODEC_ID_FLAC, MKTAG('f', 'L', 'a', 'C') },
9364 { AV_CODEC_ID_OPUS, MKTAG('O', 'p', 'u', 's') },
9365 { AV_CODEC_ID_VORBIS, MKTAG('m', 'p', '4', 'a') },
9366 { AV_CODEC_ID_QCELP, MKTAG('m', 'p', '4', 'a') },
9367 { AV_CODEC_ID_EVRC, MKTAG('m', 'p', '4', 'a') },
9368 { AV_CODEC_ID_DVD_SUBTITLE, MKTAG('m', 'p', '4', 's') },
9369 { AV_CODEC_ID_MOV_TEXT, MKTAG('t', 'x', '3', 'g') },
9370 { AV_CODEC_ID_BIN_DATA, MKTAG('g', 'p', 'm', 'd') },
9371 { AV_CODEC_ID_MPEGH_3D_AUDIO, MKTAG('m', 'h', 'm', '1') },
9374 { AV_CODEC_ID_FFV1, MKTAG('F', 'F', 'V', '1') },
9375
9376 /* ISO/IEC 23003-5 integer formats */
9383 /* ISO/IEC 23003-5 floating-point formats */
9388
9389 { AV_CODEC_ID_AVS3, MKTAG('a', 'v', 's', '3') },
9390
9391 { AV_CODEC_ID_NONE, 0 },
9392};
9393#if CONFIG_MP4_MUXER || CONFIG_PSP_MUXER
9394static const AVCodecTag *const mp4_codec_tags_list[] = { codec_mp4_tags, NULL };
9395#endif
9396
9397static const AVCodecTag codec_ism_tags[] = {
9398 { AV_CODEC_ID_WMAPRO , MKTAG('w', 'm', 'a', ' ') },
9400 { AV_CODEC_ID_NONE , 0 },
9401};
9402
9403static const AVCodecTag codec_ipod_tags[] = {
9404 { AV_CODEC_ID_H264, MKTAG('a','v','c','1') },
9405 { AV_CODEC_ID_MPEG4, MKTAG('m','p','4','v') },
9406 { AV_CODEC_ID_AAC, MKTAG('m','p','4','a') },
9407 { AV_CODEC_ID_ALAC, MKTAG('a','l','a','c') },
9408 { AV_CODEC_ID_AC3, MKTAG('a','c','-','3') },
9409 { AV_CODEC_ID_MOV_TEXT, MKTAG('t','x','3','g') },
9410 { AV_CODEC_ID_MOV_TEXT, MKTAG('t','e','x','t') },
9411 { AV_CODEC_ID_NONE, 0 },
9412};
9413
9414static const AVCodecTag codec_f4v_tags[] = {
9415 { AV_CODEC_ID_MP3, MKTAG('.','m','p','3') },
9416 { AV_CODEC_ID_AAC, MKTAG('m','p','4','a') },
9417 { AV_CODEC_ID_H264, MKTAG('a','v','c','1') },
9418 { AV_CODEC_ID_VP6A, MKTAG('V','P','6','A') },
9419 { AV_CODEC_ID_VP6F, MKTAG('V','P','6','F') },
9420 { AV_CODEC_ID_NONE, 0 },
9421};
9422
9423#if CONFIG_AVIF_MUXER
9424
9425static const AVOption avif_options[] = {
9426 { "movie_timescale", "set movie timescale", offsetof(MOVMuxContext, movie_timescale), AV_OPT_TYPE_INT, {.i64 = MOV_TIMESCALE}, 1, INT_MAX, AV_OPT_FLAG_ENCODING_PARAM},
9427 { "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 },
9428 { NULL },
9429};
9430static const AVCodecTag codec_avif_tags[] = {
9431 { AV_CODEC_ID_AV1, MKTAG('a','v','0','1') },
9432 { AV_CODEC_ID_NONE, 0 },
9433};
9434static const AVCodecTag *const codec_avif_tags_list[] = { codec_avif_tags, NULL };
9435
9436static const AVClass mov_avif_muxer_class = {
9437 .class_name = "avif muxer",
9438 .item_name = av_default_item_name,
9439 .option = avif_options,
9440 .version = LIBAVUTIL_VERSION_INT,
9441};
9442#endif
9443
9444#if CONFIG_MOV_MUXER
9446 .p.name = "mov",
9447 .p.long_name = NULL_IF_CONFIG_SMALL("QuickTime / MOV"),
9448 .p.extensions = "mov",
9449 .priv_data_size = sizeof(MOVMuxContext),
9450 .p.audio_codec = AV_CODEC_ID_AAC,
9451 .p.video_codec = CONFIG_LIBX264_ENCODER ?
9453 .init = mov_init,
9457 .deinit = mov_free,
9459 .p.codec_tag = (const AVCodecTag* const []){
9461 },
9462 .check_bitstream = mov_check_bitstream,
9463 .p.priv_class = &mov_isobmff_muxer_class,
9464 .flags_internal = FF_OFMT_FLAG_ALLOW_FLUSH,
9465};
9466#endif
9467#if CONFIG_TGP_MUXER
9469 .p.name = "3gp",
9470 .p.long_name = NULL_IF_CONFIG_SMALL("3GP (3GPP file format)"),
9471 .p.extensions = "3gp",
9472 .priv_data_size = sizeof(MOVMuxContext),
9473 .p.audio_codec = AV_CODEC_ID_AMR_NB,
9474 .p.video_codec = AV_CODEC_ID_H263,
9475 .init = mov_init,
9476 .write_header = mov_write_header,
9477 .write_packet = mov_write_packet,
9478 .write_trailer = mov_write_trailer,
9479 .deinit = mov_free,
9481 .p.codec_tag = codec_3gp_tags_list,
9482 .check_bitstream = mov_check_bitstream,
9483 .p.priv_class = &mov_isobmff_muxer_class,
9484 .flags_internal = FF_OFMT_FLAG_ALLOW_FLUSH,
9485};
9486#endif
9487#if CONFIG_MP4_MUXER
9489 .p.name = "mp4",
9490 .p.long_name = NULL_IF_CONFIG_SMALL("MP4 (MPEG-4 Part 14)"),
9491 .p.mime_type = "video/mp4",
9492 .p.extensions = "mp4",
9493 .priv_data_size = sizeof(MOVMuxContext),
9494 .p.audio_codec = AV_CODEC_ID_AAC,
9495 .p.video_codec = CONFIG_LIBX264_ENCODER ?
9497 .init = mov_init,
9501 .deinit = mov_free,
9503 .p.codec_tag = mp4_codec_tags_list,
9505 .p.priv_class = &mov_isobmff_muxer_class,
9506 .flags_internal = FF_OFMT_FLAG_ALLOW_FLUSH,
9507};
9508#endif
9509#if CONFIG_PSP_MUXER
9511 .p.name = "psp",
9512 .p.long_name = NULL_IF_CONFIG_SMALL("PSP MP4 (MPEG-4 Part 14)"),
9513 .p.extensions = "mp4,psp",
9514 .priv_data_size = sizeof(MOVMuxContext),
9515 .p.audio_codec = AV_CODEC_ID_AAC,
9516 .p.video_codec = CONFIG_LIBX264_ENCODER ?
9518 .init = mov_init,
9522 .deinit = mov_free,
9524 .p.codec_tag = mp4_codec_tags_list,
9526 .p.priv_class = &mov_isobmff_muxer_class,
9527 .flags_internal = FF_OFMT_FLAG_ALLOW_FLUSH,
9528};
9529#endif
9530#if CONFIG_TG2_MUXER
9532 .p.name = "3g2",
9533 .p.long_name = NULL_IF_CONFIG_SMALL("3GP2 (3GPP2 file format)"),
9534 .p.extensions = "3g2",
9535 .priv_data_size = sizeof(MOVMuxContext),
9536 .p.audio_codec = AV_CODEC_ID_AMR_NB,
9537 .p.video_codec = AV_CODEC_ID_H263,
9538 .init = mov_init,
9539 .write_header = mov_write_header,
9540 .write_packet = mov_write_packet,
9541 .write_trailer = mov_write_trailer,
9542 .deinit = mov_free,
9544 .p.codec_tag = codec_3gp_tags_list,
9545 .check_bitstream = mov_check_bitstream,
9546 .p.priv_class = &mov_isobmff_muxer_class,
9547 .flags_internal = FF_OFMT_FLAG_ALLOW_FLUSH,
9548};
9549#endif
9550#if CONFIG_IPOD_MUXER
9552 .p.name = "ipod",
9553 .p.long_name = NULL_IF_CONFIG_SMALL("iPod H.264 MP4 (MPEG-4 Part 14)"),
9554 .p.mime_type = "video/mp4",
9555 .p.extensions = "m4v,m4a,m4b",
9556 .priv_data_size = sizeof(MOVMuxContext),
9557 .p.audio_codec = AV_CODEC_ID_AAC,
9558 .p.video_codec = AV_CODEC_ID_H264,
9559 .init = mov_init,
9560 .write_header = mov_write_header,
9561 .write_packet = mov_write_packet,
9562 .write_trailer = mov_write_trailer,
9563 .deinit = mov_free,
9565 .p.codec_tag = (const AVCodecTag* const []){ codec_ipod_tags, 0 },
9566 .check_bitstream = mov_check_bitstream,
9567 .p.priv_class = &mov_isobmff_muxer_class,
9568 .flags_internal = FF_OFMT_FLAG_ALLOW_FLUSH,
9569};
9570#endif
9571#if CONFIG_ISMV_MUXER
9573 .p.name = "ismv",
9574 .p.long_name = NULL_IF_CONFIG_SMALL("ISMV/ISMA (Smooth Streaming)"),
9575 .p.mime_type = "video/mp4",
9576 .p.extensions = "ismv,isma",
9577 .priv_data_size = sizeof(MOVMuxContext),
9578 .p.audio_codec = AV_CODEC_ID_AAC,
9579 .p.video_codec = AV_CODEC_ID_H264,
9580 .init = mov_init,
9581 .write_header = mov_write_header,
9582 .write_packet = mov_write_packet,
9583 .write_trailer = mov_write_trailer,
9584 .deinit = mov_free,
9586 .p.codec_tag = (const AVCodecTag* const []){
9588 .check_bitstream = mov_check_bitstream,
9589 .p.priv_class = &mov_isobmff_muxer_class,
9590 .flags_internal = FF_OFMT_FLAG_ALLOW_FLUSH,
9591};
9592#endif
9593#if CONFIG_F4V_MUXER
9595 .p.name = "f4v",
9596 .p.long_name = NULL_IF_CONFIG_SMALL("F4V Adobe Flash Video"),
9597 .p.mime_type = "application/f4v",
9598 .p.extensions = "f4v",
9599 .priv_data_size = sizeof(MOVMuxContext),
9600 .p.audio_codec = AV_CODEC_ID_AAC,
9601 .p.video_codec = AV_CODEC_ID_H264,
9602 .init = mov_init,
9603 .write_header = mov_write_header,
9604 .write_packet = mov_write_packet,
9605 .write_trailer = mov_write_trailer,
9606 .deinit = mov_free,
9607 .p.flags = AVFMT_GLOBALHEADER,
9608 .p.codec_tag = (const AVCodecTag* const []){ codec_f4v_tags, 0 },
9609 .check_bitstream = mov_check_bitstream,
9610 .p.priv_class = &mov_isobmff_muxer_class,
9611 .flags_internal = FF_OFMT_FLAG_ALLOW_FLUSH,
9612};
9613#endif
9614#if CONFIG_AVIF_MUXER
9616 .p.name = "avif",
9617 .p.long_name = NULL_IF_CONFIG_SMALL("AVIF"),
9618 .p.mime_type = "image/avif",
9619 .p.extensions = "avif",
9620 .priv_data_size = sizeof(MOVMuxContext),
9621 .p.video_codec = AV_CODEC_ID_AV1,
9622 .init = mov_init,
9623 .write_header = mov_write_header,
9624 .write_packet = mov_write_packet,
9625 .write_trailer = avif_write_trailer,
9626 .deinit = mov_free,
9627 .p.flags = AVFMT_GLOBALHEADER,
9628 .p.codec_tag = codec_avif_tags_list,
9629 .p.priv_class = &mov_avif_muxer_class,
9630 .flags_internal = FF_OFMT_FLAG_ALLOW_FLUSH,
9631};
9632#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:834
Main libavformat public API header.
#define AVFMT_FLAG_BITEXACT
When muxing, try to avoid writing any random/volatile data to the output.
Definition avformat.h:1501
#define AV_DISPOSITION_HEARING_IMPAIRED
The stream is intended for hearing impaired audiences.
Definition avformat.h:676
@ AV_STREAM_GROUP_PARAMS_TREF
Definition avformat.h:1152
@ AV_STREAM_GROUP_PARAMS_IAMF_MIX_PRESENTATION
Definition avformat.h:1149
@ AV_STREAM_GROUP_PARAMS_IAMF_AUDIO_ELEMENT
Definition avformat.h:1148
@ AV_STREAM_GROUP_PARAMS_LCEVC
Definition avformat.h:1151
#define AVFMT_VARIABLE_FPS
Format allows variable fps.
Definition avformat.h:501
#define AV_DISPOSITION_MULTILAYER
The video stream contains multiple layers, e.g.
Definition avformat.h:736
#define AVFMT_TS_NEGATIVE
Format allows muxing negative timestamps.
Definition avformat.h:510
#define AVFMT_AVOID_NEG_TS_AUTO
Enabled when required by target format.
Definition avformat.h:1738
#define AVFMT_FLAG_AUTO_BSF
Add bitstream filters as requested by the muxer.
Definition avformat.h:1504
#define AV_DISPOSITION_VISUAL_IMPAIRED
The stream is intended for visually impaired audiences.
Definition avformat.h:680
#define AVFMT_GLOBALHEADER
Format wants global header.
Definition avformat.h:497
#define AV_DISPOSITION_ATTACHED_PIC
The stream is stored in the file as an attached picture/"cover art" (e.g.
Definition avformat.h:692
#define AVFMT_AVOID_NEG_TS_MAKE_ZERO
Shift timestamps so that they start at 0.
Definition avformat.h:1741
#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:639
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:494
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:1410
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:1365
int avio_get_dyn_buf(AVIOContext *s, uint8_t **pbuffer)
Return the written size and a pointer to the buffer.
Definition aviobuf.c:1377
void ffio_free_dyn_buf(AVIOContext **s)
Free a dynamic buffer.
Definition aviobuf.c:1438
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:1399
void ffio_write_leb(AVIOContext *s, unsigned val)
Definition aviobuf.c:947
int ffio_open_null_buf(AVIOContext **s)
Open a write-only fake memory stream.
Definition aviobuf.c:1462
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:1472
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:108
@ AV_FIELD_UNKNOWN
Definition defs.h:212
@ AV_FIELD_PROGRESSIVE
Definition defs.h:213
#define AV_PROFILE_AAC_USAC
Definition defs.h:76
#define AV_PROFILE_DNXHD
Definition defs.h:80
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:204
const char * key
static int64_t duration
Definition ffplay.c:330
static unsigned int nb_streams
Definition ffprobe.c:352
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:556
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:351
@ AV_CODEC_ID_PCM_S24BE
Definition codec_id.h:343
@ AV_CODEC_ID_AVS3
Definition codec_id.h:245
@ AV_CODEC_ID_VORBIS
Definition codec_id.h:458
@ AV_CODEC_ID_V210
Definition codec_id.h:177
@ AV_CODEC_ID_TIMED_ID3
Definition codec_id.h:606
@ 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:493
@ AV_CODEC_ID_RAWVIDEO
Definition codec_id.h:63
@ AV_CODEC_ID_PCM_U8
Definition codec_id.h:335
@ AV_CODEC_ID_APV
Definition codec_id.h:323
@ AV_CODEC_ID_LCEVC
Definition codec_id.h:609
@ AV_CODEC_ID_PCM_S16LE
Definition codec_id.h:330
@ AV_CODEC_ID_DVD_SUBTITLE
Definition codec_id.h:566
@ AV_CODEC_ID_TTML
Definition codec_id.h:590
@ AV_CODEC_ID_PCM_F32BE
Definition codec_id.h:350
@ AV_CODEC_ID_MP4ALS
Definition codec_id.h:498
@ 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:524
@ AV_CODEC_ID_JPEG2000
Definition codec_id.h:138
@ AV_CODEC_ID_PCM_S16BE
Definition codec_id.h:331
@ AV_CODEC_ID_PCM_S24LE
Definition codec_id.h:342
@ 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:338
@ AV_CODEC_ID_PCM_S8
Definition codec_id.h:334
@ AV_CODEC_ID_AV1
Definition codec_id.h:275
@ AV_CODEC_ID_ADPCM_MS
Definition codec_id.h:376
@ 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:544
@ AV_CODEC_ID_PCM_F64LE
Definition codec_id.h:353
@ AV_CODEC_ID_ALAC
Definition codec_id.h:469
@ AV_CODEC_ID_EIA_608
Definition codec_id.h:576
@ AV_CODEC_ID_AMR_NB
Definition codec_id.h:434
@ AV_CODEC_ID_VP6A
Definition codec_id.h:156
@ AV_CODEC_ID_MP2
Definition codec_id.h:453
@ AV_CODEC_ID_DVVIDEO
Definition codec_id.h:74
@ AV_CODEC_ID_ADPCM_IMA_QT
Definition codec_id.h:370
@ AV_CODEC_ID_DTS
Definition codec_id.h:457
@ AV_CODEC_ID_HEVC
Definition codec_id.h:223
@ AV_CODEC_ID_BIN_DATA
Definition codec_id.h:607
@ AV_CODEC_ID_ADPCM_G726
Definition codec_id.h:381
@ AV_CODEC_ID_AAC
Definition codec_id.h:455
@ AV_CODEC_ID_TRUEHD
Definition codec_id.h:497
@ AV_CODEC_ID_FLAC
Definition codec_id.h:465
@ AV_CODEC_ID_BMP
Definition codec_id.h:128
@ AV_CODEC_ID_PCM_F64BE
Definition codec_id.h:352
@ AV_CODEC_ID_H263
Definition codec_id.h:54
@ AV_CODEC_ID_QCELP
Definition codec_id.h:477
@ AV_CODEC_ID_AMR_WB
Definition codec_id.h:435
@ AV_CODEC_ID_AC3
Definition codec_id.h:456
@ AV_CODEC_ID_TSCC2
Definition codec_id.h:213
@ AV_CODEC_ID_QDM2
Definition codec_id.h:472
@ AV_CODEC_ID_PCM_S32BE
Definition codec_id.h:339
@ 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:371
@ 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:562
@ AV_CODEC_ID_AVUI
Definition codec_id.h:252
@ AV_CODEC_ID_ILBC
Definition codec_id.h:512
@ AV_CODEC_ID_MP3
preferred ID for decoding MPEG audio layer 1, 2 or 3
Definition codec_id.h:454
@ 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:513
@ 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:490
@ AV_CODEC_ID_MOV_TEXT
Definition codec_id.h:571
#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:570
@ 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:657
void av_packet_unref(AVPacket *pkt)
Wipe the packet.
Definition packet.c:434
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:650
#define AV_PKT_FLAG_DISPOSABLE
Flag is used to indicate packets that contain frames that can be discarded by the decoder.
Definition packet.h:669
void av_packet_move_ref(AVPacket *dst, AVPacket *src)
Move every field in src to dst and reset src.
Definition packet.c:491
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:516
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:442
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_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:139
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:55
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:60
#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:42
#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:217
void * av_memdup(const void *p, size_t size)
Duplicate a buffer with av_malloc().
Definition mem.c:302
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:225
#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
cl_device_type type
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:418
#define MOV_TRUN_SAMPLE_CTS
Definition isom.h:421
#define MOV_TKHD_FLAG_ENABLED
Definition isom.h:433
#define MOV_TFHD_DEFAULT_BASE_IS_MOOF
Definition isom.h:414
const AVCodecTag ff_codec_movaudio_tags[]
Definition isom_tags.c:306
#define MOV_FRAG_SAMPLE_FLAG_DEPENDS_YES
Definition isom.h:431
const AVCodecTag ff_codec_movvideo_tags[]
Definition isom_tags.c:29
#define MOV_TFHD_DEFAULT_SIZE
Definition isom.h:411
#define MOV_ISMV_TTML_TAG
Definition isom.h:482
#define MOV_FRAG_SAMPLE_FLAG_DEPENDS_NO
Definition isom.h:430
#define TAG_IS_AVCI(tag)
Definition isom.h:442
#define MOV_TRUN_FIRST_SAMPLE_FLAGS
Definition isom.h:417
#define MOV_MP4_FPCM_TAG
Definition isom.h:484
#define MOV_FRAG_SAMPLE_FLAG_IS_NON_SYNC
Definition isom.h:424
#define MOV_SAMPLE_DEPENDENCY_UNKNOWN
Definition isom.h:438
#define MOV_TFHD_STSD_ID
Definition isom.h:409
#define MOV_TRUN_SAMPLE_FLAGS
Definition isom.h:420
#define MOV_MP4_TTML_TAG
Definition isom.h:483
#define MOV_TFHD_DEFAULT_FLAGS
Definition isom.h:412
#define MOV_SAMPLE_DEPENDENCY_YES
Definition isom.h:439
#define MOV_TRUN_DATA_OFFSET
Definition isom.h:416
#define MOV_TFHD_BASE_DATA_OFFSET
Definition isom.h:408
#define MOV_MP4_IPCM_TAG
Definition isom.h:485
#define MOV_TFHD_DURATION_IS_EMPTY
Definition isom.h:413
#define MOV_TKHD_FLAG_IN_MOVIE
Definition isom.h:434
#define MOV_TRUN_SAMPLE_SIZE
Definition isom.h:419
#define MOV_SAMPLE_DEPENDENCY_NO
Definition isom.h:440
#define MOV_TFHD_DEFAULT_DURATION
Definition isom.h:410
static void put_bits(Jpeg2000EncoderContext *s, int val, int n)
put n times val bit
Definition j2kenc.c:154
int ff_isom_write_lvcc(AVIOContext *pb, const uint8_t *data, int len, void *logctx)
Definition lcevc.c:251
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:955
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:464
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:130
#define NTP_OFFSET_US
Definition internal.h:422
const AVPacket * ff_interleaved_peek(AVFormatContext *s, int stream)
Find the next packet in the interleaving queue for the given stream.
Definition mux.c:1043
static int check_bitstream(AVFormatContext *s, FFStream *sti, AVPacket *pkt)
Definition mux.c:1056
int ff_stream_add_bitstream_filter(AVStream *st, const char *name, const char *args)
Add a bitstream filter to a stream.
Definition mux.c:1294
int ff_get_muxer_ts_offset(AVFormatContext *s, int stream_index, int64_t *offset)
Definition mux.c:1027
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:88
Stereoscopic video.
version
Definition libkvazaar.c:313
Replacements for frequently missing libm functions.
static av_always_inline av_const double round(double x)
Definition libm.h:446
#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:264
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:3198
static int mov_write_stco_tag(AVIOContext *pb, MOVTrack *track)
Definition movenc.c:201
static int mov_write_vmhd_tag(AVIOContext *pb)
Definition movenc.c:3583
static int mov_write_av3c(AVIOContext *pb, const uint8_t *data, int len)
Definition movenc.c:1632
static int mov_write_trex_tag(AVIOContext *pb, MOVTrack *track)
Definition movenc.c:4509
static int get_moov_size(AVFormatContext *s)
Definition movenc.c:8988
static unsigned compute_avg_bitrate(MOVTrack *track)
Definition movenc.c:735
static int mov_write_sidx_tag(AVIOContext *pb, MOVTrack *track, int ref_size, int total_sidx_size)
Definition movenc.c:5968
static const AVCodecTag codec_cover_image_tags[]
Definition movenc.c:2200
static int mov_write_header(AVFormatContext *s)
Definition movenc.c:8808
static int mov_write_sdtp_tag(AVIOContext *pb, MOVTrack *track)
Definition movenc.c:316
static const AVCodecTag codec_ism_tags[]
Definition movenc.c:9397
static MovTag * mov_add_tref_tag(MOVMuxContext *mov, MOVTrack *trk, uint32_t name)
Definition movenc.c:5355
static int utf8len(const uint8_t *b)
Definition movenc.c:143
static AVDictionaryEntry * get_metadata_lang(AVFormatContext *s, const char *tag, int *lang)
Definition movenc.c:4678
static int mov_write_stbl_tag(AVFormatContext *s, AVIOContext *pb, MOVMuxContext *mov, MOVTrack *track)
Definition movenc.c:3435
static int mov_write_ac3_tag(AVFormatContext *s, AVIOContext *pb, MOVTrack *track)
Definition movenc.c:419
static int mov_write_hvcc_tag(AVFormatContext *s, AVIOContext *pb, MOVTrack *track)
Definition movenc.c:1672
static int mov_write_stsz_tag(AVIOContext *pb, MOVTrack *track)
Definition movenc.c:225
int ff_mov_set_fragment_end_hint(AVFormatContext *s, int stream_index, const AVPacket *pkt, AVRational src_time_base)
Definition movenc.c:6967
static int mov_write_iref_tag(AVIOContext *pb, MOVMuxContext *mov, AVFormatContext *s)
Definition movenc.c:3741
static int mov_write_uuid_tag_psp(AVIOContext *pb, MOVTrack *mov)
Definition movenc.c:4291
static int mov_write_evcc_tag(AVIOContext *pb, MOVTrack *track)
Definition movenc.c:1709
static int mov_write_raw_metadata_tag(AVFormatContext *s, AVIOContext *pb, const char *name, const char *key)
Definition movenc.c:5013
static int mov_write_dfla_tag(AVIOContext *pb, MOVTrack *track)
Definition movenc.c:889
static int mov_write_dinf_tag(AVIOContext *pb)
Definition movenc.c:3474
static int mov_write_dpxe_tag(AVIOContext *pb, MOVTrack *track)
Definition movenc.c:1893
#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:4009
static int mov_write_traf_tag(AVIOContext *pb, MOVMuxContext *mov, MOVTrack *track, int64_t moof_offset, int moof_size)
Definition movenc.c:5901
uint32_t tag
Definition movenc.c:2087
static int mov_write_emsg_tag(AVIOContext *pb, AVStream *st, AVPacket *pkt)
Definition movenc.c:7628
static int mov_flush_fragment_interleaving(AVFormatContext *s, MOVTrack *track)
Definition movenc.c:6587
static int mov_get_mpeg2_xdcam_codec_tag(AVFormatContext *s, MOVTrack *track)
Definition movenc.c:1940
static int mov_write_iinf_tag(AVIOContext *pb, MOVMuxContext *mov, AVFormatContext *s)
Definition movenc.c:3716
static int mov_write_mdhd_tag(AVIOContext *pb, MOVMuxContext *mov, MOVTrack *track)
Definition movenc.c:3953
static int mov_create_chapter_track(AVFormatContext *s, int tracknum)
Definition movenc.c:7807
static int mov_mdhd_mvhd_tkhd_version(MOVMuxContext *mov, MOVTrack *track, int64_t duration)
Definition movenc.c:3944
static int mov_add_tfra_entries(AVIOContext *pb, MOVMuxContext *mov, int tracks, int size)
Definition movenc.c:5836
static int shift_data(AVFormatContext *s)
Definition movenc.c:9059
static int mov_write_av3c_tag(AVIOContext *pb, MOVTrack *track)
Definition movenc.c:1651
static int64_t update_size_and_version(AVIOContext *pb, int64_t pos, int version)
Definition movenc.c:165
static int mov_write_wfex_tag(AVFormatContext *s, AVIOContext *pb, MOVTrack *track)
Definition movenc.c:878
static int mov_write_chan_tag(AVFormatContext *s, AVIOContext *pb, MOVTrack *track)
Definition movenc.c:1030
unsigned bps
Definition movenc.c:2088
static int mov_write_gama_tag(AVFormatContext *s, AVIOContext *pb, MOVTrack *track, double gamma)
Definition movenc.c:2622
static int mov_write_amve_tag(AVIOContext *pb, MOVTrack *track)
Definition movenc.c:2743
static const AVCodecTag codec_ipod_tags[]
Definition movenc.c:9403
static int mov_write_eac3_tag(AVFormatContext *s, AVIOContext *pb, MOVTrack *track)
Definition movenc.c:644
static int co64_required(const MOVTrack *track)
Definition movenc.c:177
static int mov_write_sthd_tag(AVIOContext *pb)
Definition movenc.c:3491
static int mov_write_aux_tag(AVIOContext *pb, const char *aux_type)
Definition movenc.c:2819
static int mov_write_pasp_tag(AVIOContext *pb, MOVTrack *track)
Definition movenc.c:2609
static int compute_moov_size(AVFormatContext *s)
Definition movenc.c:9019
static int mov_write_loci_tag(AVFormatContext *s, AVIOContext *pb)
Definition movenc.c:4743
static int mov_write_tfra_tag(AVIOContext *pb, MOVTrack *track)
Definition movenc.c:6151
static int ascii_to_wc(AVIOContext *pb, const uint8_t *b)
Definition movenc.c:5033
static int mov_write_sidx_tags(AVIOContext *pb, MOVMuxContext *mov, int tracks, int ref_size)
Definition movenc.c:6029
static int mov_write_vexu_tag(AVFormatContext *s, AVIOContext *pb, const AVStereo3D *stereo3d, const AVSphericalMapping *spherical_mapping)
Definition movenc.c:2513
static MovTag * mov_find_tref_tag(MOVMuxContext *mov, const MOVTrack *trk, uint32_t name)
Definition movenc.c:5344
static const AVClass mov_isobmff_muxer_class
Definition movenc.c:133
static int mov_preroll_write_stbl_atoms(AVIOContext *pb, MOVTrack *track)
Definition movenc.c:3338
static void mov_write_ftyp_tag_internal(AVIOContext *pb, AVFormatContext *s, int has_h264, int has_video, int write_minor)
Definition movenc.c:6224
static int mov_write_dmlp_tag(AVFormatContext *s, AVIOContext *pb, MOVTrack *track)
Definition movenc.c:943
static int mov_write_vvcc_tag(AVIOContext *pb, MOVTrack *track)
Definition movenc.c:1739
static int mov_write_iprp_tag(AVIOContext *pb, MOVMuxContext *mov, AVFormatContext *s)
Definition movenc.c:3829
static int mov_write_tmcd_tag(AVIOContext *pb, MOVTrack *track)
Definition movenc.c:3137
static int mov_create_timecode_track(AVFormatContext *s, int index, int src_index, AVTimecode tc)
Definition movenc.c:7907
static int mov_create_dvd_sub_decoder_specific_info(MOVTrack *track, AVStream *st)
Definition movenc.c:8080
static int mov_write_prft_tag(AVIOContext *pb, MOVMuxContext *mov, int tracks)
Definition movenc.c:6067
static int mov_write_glbl_tag(AVIOContext *pb, MOVTrack *track)
Definition movenc.c:1235
static int mov_write_ipco_tag(AVIOContext *pb, MOVMuxContext *mov, AVFormatContext *s)
Definition movenc.c:3788
static void mov_write_mdat_size(AVFormatContext *s)
Definition movenc.c:9074
static uint32_t get_sample_flags(MOVTrack *track, MOVIentry *entry)
Definition movenc.c:5639
static void enable_tracks(AVFormatContext *s)
Definition movenc.c:7963
static int mov_write_minf_tag(AVFormatContext *s, AVIOContext *pb, MOVMuxContext *mov, MOVTrack *track)
Definition movenc.c:3854
static int mov_pcm_le_gt16(enum AVCodecID codec_id)
Definition movenc.c:850
static int mov_write_tfrf_tag(AVIOContext *pb, MOVMuxContext *mov, MOVTrack *track, int entry)
Definition movenc.c:5787
static int mov_write_avcc_tag(AVIOContext *pb, MOVTrack *track)
Definition movenc.c:1617
static int mov_write_extradata_tag(AVIOContext *pb, MOVTrack *track)
This function writes extradata "as is".
Definition movenc.c:704
static int mov_write_covr(AVIOContext *pb, AVFormatContext *s)
Definition movenc.c:4848
static int mov_write_srat_tag(AVIOContext *pb, MOVTrack *track)
Definition movenc.c:1399
static int mov_write_smhd_tag(AVIOContext *pb)
Definition movenc.c:3573
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:2581
static int mov_finish_fragment(MOVMuxContext *mov, MOVTrack *track, int64_t ref_pos)
Definition movenc.c:6674
static int mov_write_mdta_keys_tag(AVIOContext *pb, MOVMuxContext *mov, AVFormatContext *s)
Definition movenc.c:4931
static void find_compressor(char *compressor_name, int len, MOVTrack *track)
Definition movenc.c:2770
static void mov_parse_truehd_frame(AVPacket *pkt, MOVTrack *trk)
Definition movenc.c:6568
static int mov_write_tkhd_tag(AVIOContext *pb, MOVMuxContext *mov, MOVTrack *track, AVStream *st)
Definition movenc.c:4023
static int mov_write_amr_tag(AVIOContext *pb, MOVTrack *track)
Definition movenc.c:369
static int mov_write_sv3d_tag(AVFormatContext *s, AVIOContext *pb, AVSphericalMapping *spherical_mapping)
Definition movenc.c:2354
static int mov_get_h264_codec_tag(AVFormatContext *s, MOVTrack *track)
Definition movenc.c:2002
static int mov_get_dnxhd_codec_tag(AVFormatContext *s, MOVTrack *track)
Definition movenc.c:2110
static uint32_t rgb_to_yuv(uint32_t rgb)
Definition movenc.c:8064
static int mov_write_lhvc_tag(AVFormatContext *s, AVIOContext *pb, MOVTrack *track)
Definition movenc.c:1687
static struct mpeg4_bit_rate_values calculate_mpeg4_bit_rates(MOVTrack *track)
Definition movenc.c:752
static int mov_auto_flush_fragment(AVFormatContext *s, int force)
Definition movenc.c:6918
static int mov_write_moof_tag(AVIOContext *pb, MOVMuxContext *mov, int tracks, int64_t mdat_size)
Definition movenc.c:6117
static int mov_write_moof_tag_internal(AVIOContext *pb, MOVMuxContext *mov, int tracks, int moof_size)
Definition movenc.c:5943
static int mov_write_edts_tag(AVIOContext *pb, MOVMuxContext *mov, MOVTrack *track)
Definition movenc.c:4166
static int mov_write_enda_tag_be(AVIOContext *pb)
Definition movenc.c:718
static int mov_write_track_metadata(AVIOContext *pb, AVStream *st, const char *tag, const char *str)
Definition movenc.c:4331
static void param_write_hex(AVIOContext *pb, const char *name, const uint8_t *value, int len)
Definition movenc.c:5498
static int mov_write_ilst_tag(AVIOContext *pb, MOVMuxContext *mov, AVFormatContext *s)
Definition movenc.c:4875
static void mov_prune_frag_info(MOVMuxContext *mov, int tracks, int max)
Definition movenc.c:5875
static int mov_write_d263_tag(AVIOContext *pb)
Definition movenc.c:1594
static int mov_write_tmpo_tag(AVIOContext *pb, AVFormatContext *s)
Definition movenc.c:4725
static int mov_write_iloc_tag(AVIOContext *pb, MOVMuxContext *mov, AVFormatContext *s)
Definition movenc.c:3693
static int mov_write_int8_metadata(AVFormatContext *s, AVIOContext *pb, const char *name, const char *tag, int len)
Definition movenc.c:4821
static int mov_check_timecode_track(AVFormatContext *s, AVTimecode *tc, AVStream *src_st, const char *tcstr)
Definition movenc.c:7898
static int mov_write_ms_tag(AVFormatContext *s, AVIOContext *pb, MOVTrack *track)
Definition movenc.c:866
static uint16_t language_code(const char *str)
Definition movenc.c:5044
static int mov_write_custom_metadata(AVFormatContext *s, AVIOContext *pb, const char *mean, const char *name, const char *tag)
Definition movenc.c:4714
static int mov_write_tref_tag(AVIOContext *pb, MOVTrack *track)
Definition movenc.c:4274
static void param_write_string(AVIOContext *pb, const char *name, const char *value)
Definition movenc.c:5493
static int mov_write_esds_tag(AVIOContext *pb, MOVTrack *track)
Definition movenc.c:797
static int mov_write_avid_tag(AVIOContext *pb, MOVTrack *track)
Definition movenc.c:1775
static int mov_write_ispe_tag(AVIOContext *pb, MOVMuxContext *mov, AVFormatContext *s, int stream_index)
Definition movenc.c:3760
static int64_t update_size(AVIOContext *pb, int64_t pos)
Definition movenc.c:155
static int mov_write_ipma_tag(AVIOContext *pb, MOVMuxContext *mov, AVFormatContext *s)
Definition movenc.c:3805
static int64_t calc_elst_duration(MOVMuxContext *mov, MOVTrack *track)
Definition movenc.c:3937
static int mov_add_tref_id(MOVMuxContext *mov, MovTag *tag, uint32_t id)
Definition movenc.c:5329
static int mov_write_moov_tag(AVIOContext *pb, MOVMuxContext *mov, AVFormatContext *s)
Definition movenc.c:5372
static int64_t calc_pts_duration(MOVMuxContext *mov, MOVTrack *track)
Definition movenc.c:3928
static int mov_write_dvc1_tag(AVIOContext *pb, MOVTrack *track)
Definition movenc.c:1218
static int mov_write_tfrf_tags(AVIOContext *pb, MOVMuxContext *mov, MOVTrack *track)
Definition movenc.c:5822
static int mov_write_chpl_tag(AVIOContext *pb, AVFormatContext *s)
Definition movenc.c:5073
static int mov_write_audio_tag(AVFormatContext *s, AVIOContext *pb, MOVMuxContext *mov, MOVTrack *track)
Definition movenc.c:1411
static int mov_write_string_tag(AVIOContext *pb, const char *name, const char *value, int lang, int long_style)
Definition movenc.c:4635
static int mov_write_rtp_tag(AVIOContext *pb, MOVTrack *track)
Definition movenc.c:3098
static int mov_write_dref_tag(AVIOContext *pb)
Definition movenc.c:3323
static int mov_write_hdlr_tag(AVFormatContext *s, AVIOContext *pb, MOVTrack *track)
Definition movenc.c:3598
static int mov_write_iods_tag(AVIOContext *pb, MOVMuxContext *mov)
Definition movenc.c:4480
static int mov_write_3gp_udta_tag(AVIOContext *pb, AVFormatContext *s, const char *tag, const char *str)
Definition movenc.c:5051
static int mov_find_tref_id(MOVMuxContext *mov, const MovTag *tag, uint32_t id)
Definition movenc.c:5320
static int mov_write_subtitle_end_packet(AVFormatContext *s, int stream_index, int64_t dts)
Definition movenc.c:7559
static int mov_write_gmhd_tag(AVIOContext *pb, MOVTrack *track)
Definition movenc.c:3521
static int mov_write_dvcc_dvvc_tag(AVFormatContext *s, AVIOContext *pb, AVDOVIDecoderConfigurationRecord *dovi)
Definition movenc.c:2555
static int mov_write_pssh_tag(AVIOContext *pb, AVStream *st)
Definition movenc.c:5208
static int mov_init(AVFormatContext *s)
Definition movenc.c:8209
static void param_write_int(AVIOContext *pb, const char *name, int value)
Definition movenc.c:5488
static int mov_write_string_metadata(AVFormatContext *s, AVIOContext *pb, const char *name, const char *tag, int long_style)
Definition movenc.c:4703
static int mov_get_evc_codec_tag(AVFormatContext *s, MOVTrack *track)
Definition movenc.c:2064
static int mov_write_mdta_hdlr_tag(AVIOContext *pb, MOVMuxContext *mov, AVFormatContext *s)
Definition movenc.c:4916
static int mov_write_mvhd_tag(AVIOContext *pb, MOVMuxContext *mov)
Definition movenc.c:4533
static int mov_write_track_kind(AVIOContext *pb, const char *scheme_uri, const char *value)
Definition movenc.c:4345
static void mov_write_psp_udta_tag(AVIOContext *pb, const char *str, const char *lang, int type)
Definition movenc.c:5157
static unsigned int mov_find_codec_tag(AVFormatContext *s, MOVTrack *track)
Definition movenc.c:2227
static const uint16_t fiel_data[]
Definition movenc.c:2262
static int mov_write_apvc_tag(AVFormatContext *s, AVIOContext *pb, MOVTrack *track)
Definition movenc.c:1758
static int mov_write_lvcc_tag(AVFormatContext *s, AVIOContext *pb, MOVTrack *track)
Definition movenc.c:1726
static int mov_write_dops_tag(AVFormatContext *s, AVIOContext *pb, MOVTrack *track)
Definition movenc.c:909
static int mov_write_tcmi_tag(AVIOContext *pb, MOVTrack *track)
Definition movenc.c:3499
static int64_t rescale_rational(AVRational q, int b)
Definition movenc.c:2412
static int mov_write_mfhd_tag(AVIOContext *pb, MOVMuxContext *mov)
Definition movenc.c:5630
static int mov_write_tfhd_tag(AVIOContext *pb, MOVMuxContext *mov, MOVTrack *track, int64_t moof_offset)
Definition movenc.c:5645
static int mov_write_stts_tag(AVIOContext *pb, MOVTrack *track)
Definition movenc.c:3274
static int mov_write_mfra_tag(AVIOContext *pb, MOVMuxContext *mov)
Definition movenc.c:6175
static int mov_write_clli_tag(AVIOContext *pb, MOVTrack *track)
Definition movenc.c:2692
static int mov_write_mdat_tag(AVIOContext *pb, MOVMuxContext *mov)
Definition movenc.c:6213
static int mov_write_chnl_tag(AVFormatContext *s, AVIOContext *pb, MOVTrack *track)
Definition movenc.c:1331
static int mov_write_pcmc_tag(AVFormatContext *s, AVIOContext *pb, MOVTrack *track)
Definition movenc.c:1373
static int mov_write_vpcc_tag(AVFormatContext *s, AVIOContext *pb, MOVTrack *track)
Definition movenc.c:1661
static int mov_write_video_tag(AVFormatContext *s, AVIOContext *pb, MOVMuxContext *mov, MOVTrack *track)
Definition movenc.c:2829
static int mov_write_gpmd_tag(AVIOContext *pb, const MOVTrack *track)
Definition movenc.c:3186
static int check_pkt(AVFormatContext *s, MOVTrack *trk, AVPacket *pkt)
Definition movenc.c:6932
static int mov_write_uuidprof_tag(AVIOContext *pb, AVFormatContext *s)
Definition movenc.c:6387
static int mov_write_pitm_tag(AVIOContext *pb, int item_id)
Definition movenc.c:3683
static int mov_write_identification(AVIOContext *pb, AVFormatContext *s)
Definition movenc.c:6458
static int mov_write_ctts_tag(AVFormatContext *s, AVIOContext *pb, MOVTrack *track)
Definition movenc.c:3233
static int mov_write_trkn_tag(AVIOContext *pb, MOVMuxContext *mov, AVFormatContext *s, int disc)
Definition movenc.c:4794
static int mov_write_wave_tag(AVFormatContext *s, AVIOContext *pb, MOVTrack *track)
Definition movenc.c:1091
static int mov_write_udta_sdp(AVIOContext *pb, MOVTrack *track)
Definition movenc.c:4309
static int mov_write_mdia_tag(AVFormatContext *s, AVIOContext *pb, MOVMuxContext *mov, MOVTrack *track)
Definition movenc.c:3990
static const AVCodecTag codec_f4v_tags[]
Definition movenc.c:9414
static int is_clcp_track(MOVTrack *track)
Definition movenc.c:3592
static int mov_write_trak_tag(AVFormatContext *s, AVIOContext *pb, MOVMuxContext *mov, MOVTrack *track, AVStream *st)
Definition movenc.c:4424
static int compute_sidx_size(AVFormatContext *s)
Definition movenc.c:9044
static int mov_write_itunes_hdlr_tag(AVIOContext *pb, MOVMuxContext *mov, AVFormatContext *s)
Definition movenc.c:4598
static int mov_write_dvc1_structs(MOVTrack *track, uint8_t *buf)
Definition movenc.c:1134
static int mov_write_track_kinds(AVIOContext *pb, AVStream *st)
Definition movenc.c:4371
static int handle_eac3(MOVMuxContext *mov, AVPacket *pkt, MOVTrack *track)
Definition movenc.c:465
static int mov_write_ftyp_tag(AVIOContext *pb, AVFormatContext *s)
Definition movenc.c:6265
static int get_sidx_size(AVFormatContext *s)
Definition movenc.c:9001
static int mov_write_stsc_tag(AVIOContext *pb, MOVTrack *track)
Definition movenc.c:261
static int get_samples_per_packet(MOVTrack *track)
Definition movenc.c:1293
static int mov_write_udta_tag(AVIOContext *pb, MOVMuxContext *mov, AVFormatContext *s)
Definition movenc.c:5099
static int mov_pcm_be_gt16(enum AVCodecID codec_id)
Definition movenc.c:858
static int mov_write_trailer(AVFormatContext *s)
Definition movenc.c:9096
static int mov_write_btrt_tag(AVIOContext *pb, MOVTrack *track)
Definition movenc.c:1312
static int rtp_hinting_needed(const AVStream *st)
Definition movenc.c:191
static int mov_write_nmhd_tag(AVIOContext *pb)
Definition movenc.c:3483
static int mov_get_lpcm_flags(enum AVCodecID codec_id)
Compute flags for 'lpcm' tag.
Definition movenc.c:1248
static int mov_write_pixi_tag(AVIOContext *pb, MOVMuxContext *mov, AVFormatContext *s, int stream_index)
Definition movenc.c:3772
static int mov_get_rawvideo_codec_tag(AVFormatContext *s, MOVTrack *track)
Definition movenc.c:2119
static int mov_write_squashed_packet(AVFormatContext *s, MOVTrack *track)
Definition movenc.c:6612
static int mov_write_ccst_tag(AVIOContext *pb)
Definition movenc.c:2800
static int mov_write_tapt_tag(AVIOContext *pb, MOVTrack *track)
Definition movenc.c:4131
static int defined_frame_rate(AVFormatContext *s, AVStream *st)
Definition movenc.c:1931
static void mov_free(AVFormatContext *s)
Definition movenc.c:8005
static int mov_write_uuid_tag_ipod(AVIOContext *pb)
Write uuid atom.
Definition movenc.c:2250
static void put_descr(AVIOContext *pb, int tag, unsigned int size)
Definition movenc.c:726
int ff_mov_write_packet(AVFormatContext *s, AVPacket *pkt)
Definition movenc.c:7009
static int mov_write_tfdt_tag(AVIOContext *pb, MOVTrack *track)
Definition movenc.c:5889
static int mov_setup_track_ids(MOVMuxContext *mov, AVFormatContext *s)
Assign track ids.
Definition movenc.c:5281
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:4614
static void mov_parse_vc1_frame(AVPacket *pkt, MOVTrack *trk)
Definition movenc.c:6508
static int mov_write_tfxd_tag(AVIOContext *pb, MOVTrack *track)
Definition movenc.c:5767
static int mov_flush_fragment(AVFormatContext *s, int force)
Definition movenc.c:6706
static int mov_write_single_packet(AVFormatContext *s, AVPacket *pkt)
Definition movenc.c:7468
static int mov_write_squashed_packets(AVFormatContext *s)
Definition movenc.c:6650
static int mov_write_eyes_tag(AVFormatContext *s, AVIOContext *pb, const AVStereo3D *stereo3d)
Definition movenc.c:2455
static unsigned int validate_codec_tag(const AVCodecTag *const *tags, unsigned int tag, int codec_id)
Definition movenc.c:2207
static void build_chunks(MOVTrack *trk)
Definition movenc.c:5245
static void get_pts_range(MOVMuxContext *mov, MOVTrack *track, int64_t *start, int64_t *end, int elst, int mdhd)
Definition movenc.c:3891
static int mov_write_mvex_tag(AVIOContext *pb, MOVMuxContext *mov)
Definition movenc.c:4522
static void mov_write_vexu_proj_tag(AVFormatContext *s, AVIOContext *pb, const AVSphericalMapping *spherical_mapping)
Definition movenc.c:2428
static int mov_write_st3d_tag(AVFormatContext *s, AVIOContext *pb, AVStereo3D *stereo_3d)
Definition movenc.c:2324
static unsigned int mov_get_codec_tag(AVFormatContext *s, MOVTrack *track)
Definition movenc.c:2145
static int mov_write_av1c_tag(AVIOContext *pb, MOVTrack *track)
Definition movenc.c:1606
static int mov_check_bitstream(AVFormatContext *s, AVStream *st, const AVPacket *pkt)
Definition movenc.c:9239
static int mov_write_source_reference_tag(AVIOContext *pb, MOVTrack *track, const char *reel_name)
Definition movenc.c:3118
static int get_cluster_duration(MOVTrack *track, int cluster_idx)
Definition movenc.c:1273
static int mov_write_enda_tag(AVIOContext *pb)
Definition movenc.c:710
static int64_t calc_samples_pts_duration(MOVMuxContext *mov, MOVTrack *track)
Definition movenc.c:3916
static int mov_write_fiel_tag(AVIOContext *pb, MOVTrack *track, int field_order)
Definition movenc.c:2266
static int mov_write_colr_tag(AVIOContext *pb, MOVTrack *track, int prefer_icc)
Definition movenc.c:2644
static int mov_write_mdta_ilst_tag(AVIOContext *pb, MOVMuxContext *mov, AVFormatContext *s)
Definition movenc.c:4960
static void mov_write_hfov_tag(AVFormatContext *s, AVIOContext *pb, const AVStereo3D *stereo3d)
Definition movenc.c:2417
static int mov_write_track_udta_tag(AVIOContext *pb, MOVMuxContext *mov, AVStream *st)
Definition movenc.c:4391
static int mov_parse_mpeg2_frame(AVPacket *pkt, uint32_t *flags)
Definition movenc.c:6487
static int mov_write_freeform_tag(AVIOContext *pb, const char *mean, const char *name, const char *data)
Definition movenc.c:4649
static int mov_write_SA3D_tag(AVFormatContext *s, AVIOContext *pb, MOVTrack *track)
Definition movenc.c:972
static int mov_write_packet(AVFormatContext *s, AVPacket *pkt)
Definition movenc.c:7656
static int mov_write_meta_tag(AVIOContext *pb, MOVMuxContext *mov, AVFormatContext *s)
Definition movenc.c:4982
static int mov_write_mdcv_tag(AVIOContext *pb, MOVTrack *track)
Definition movenc.c:2712
static const AVCodecTag codec_mp4_tags[]
Definition movenc.c:9331
static int mov_get_apv_codec_tag(AVFormatContext *s, MOVTrack *track)
Definition movenc.c:2074
static int mov_write_subtitle_tag(AVFormatContext *s, AVIOContext *pb, MOVTrack *track)
Definition movenc.c:2279
static int mov_write_uuidusmt_tag(AVIOContext *pb, AVFormatContext *s)
Definition movenc.c:5170
static int mov_write_isml_manifest(AVIOContext *pb, MOVMuxContext *mov, AVFormatContext *s)
Definition movenc.c:5506
static int mov_get_dv_codec_tag(AVFormatContext *s, MOVTrack *track)
Definition movenc.c:1906
static int is_cover_image(const AVStream *st)
Definition movenc.c:184
static int mov_write_trun_tag(AVIOContext *pb, MOVMuxContext *mov, MOVTrack *track, int moof_size, int first, int end)
Definition movenc.c:5711
static int mov_write_hvce_tag(AVIOContext *pb, const AVPacketSideData *sd)
Definition movenc.c:2573
static int mov_write_stss_tag(AVIOContext *pb, MOVTrack *track, uint32_t flag)
Definition movenc.c:292
static int mov_write_hmhd_tag(AVIOContext *pb)
Definition movenc.c:3839
#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
#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:3380
const AVPixFmtDescriptor * av_pix_fmt_desc_get(enum AVPixelFormat pix_fmt)
Definition pixdesc.c:3460
#define AV_PIX_FMT_YUV420P10
Definition pixfmt.h:545
@ AVCOL_RANGE_MPEG
Narrow or limited range content.
Definition pixfmt.h:766
@ AVCOL_RANGE_UNSPECIFIED
Definition pixfmt.h:749
@ AVCOL_RANGE_JPEG
Full range content.
Definition pixfmt.h:783
#define AV_PIX_FMT_YUV422P10
Definition pixfmt.h:546
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:645
@ AVCOL_TRC_UNSPECIFIED
Definition pixfmt.h:675
@ AVCOL_SPC_UNSPECIFIED
Definition pixfmt.h:709
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:74
#define FF_ARRAY_ELEMS(a)
#define snprintf
Definition snprintf.h:34
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:282
int64_t avg_bitrate
Average bitrate of the stream, in bits per second.
Definition defs.h:297
int64_t max_bitrate
Maximum bitrate of the stream, in bits per second.
Definition defs.h:287
int64_t buffer_size
The size of the buffer to which the ratecontrol is applied, in bits.
Definition defs.h:303
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
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:1333
int flags
Flags modifying the (de)muxer behaviour.
Definition avformat.h:1484
int strict_std_compliance
Allow non-standard and experimental extension.
Definition avformat.h:1707
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:424
uint8_t * data
Definition packet.h:425
This structure stores compressed data.
Definition packet.h:580
int stream_index
Definition packet.h:605
int size
Definition packet.h:604
int64_t duration
Duration of this packet in AVStream->time_base units, 0 if unknown.
Definition packet.h:621
int64_t pts
Presentation timestamp in AVStream->time_base units; the time at which the decompressed packet will b...
Definition packet.h:596
int64_t dts
Decompression timestamp in AVStream->time_base units; the time at which the packet is decompressed.
Definition packet.h:602
uint8_t * data
Definition packet.h:603
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:331
int64_t wallclock
A UTC timestamp, in microseconds, since Unix epoch (e.g, av_gettime()).
Definition defs.h:335
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
AVStreamGroupLayeredVideo is meant to define the relation between a base layer video stream and a sep...
Definition avformat.h:1093
int height
Height of the final image for presentation.
Definition avformat.h:1118
unsigned int el_index
Index of the enhancement layer stream in AVStreamGroup.
Definition avformat.h:1102
int width
Width of the final stream for presentation.
Definition avformat.h:1114
AVStreamGroupTREF is meant to define the relation between video, audio, or subtitle streams,...
Definition avformat.h:1137
unsigned int metadata_index
Index of the metadata stream in the AVStreamGroup.
Definition avformat.h:1143
union AVStreamGroup::@166361102046003066253145020066347265153020354020 params
Group type-specific parameters.
enum AVStreamGroupParamsType type
Group type.
Definition avformat.h:1186
unsigned int nb_streams
Number of elements in AVStreamGroup.streams.
Definition avformat.h:1221
struct AVStreamGroupTREF * tref
Definition avformat.h:1203
AVStream ** streams
A list of streams in the group.
Definition avformat.h:1234
struct AVStreamGroupLayeredVideo * layered_video
Definition avformat.h:1195
Stream structure.
Definition avformat.h:766
AVCodecParameters * codecpar
Codec parameters associated with this stream.
Definition avformat.h:789
AVRational sample_aspect_ratio
sample aspect ratio (0 if unknown)
Definition avformat.h:844
int64_t nb_frames
number of frames in this stream if known or 0
Definition avformat.h:827
AVDictionary * metadata
Definition avformat.h:846
void * priv_data
Definition avformat.h:791
int id
Format-specific stream ID.
Definition avformat.h:778
int index
stream index in AVFormatContext
Definition avformat.h:772
AVRational avg_frame_rate
Average framerate.
Definition avformat.h:855
AVRational time_base
This is the fundamental unit of time (in seconds) in terms of which frame timestamps are represented.
Definition avformat.h:805
int disposition
Stream disposition - a combination of AV_DISPOSITION_* flags.
Definition avformat.h:835
uint32_t flags
flags such as drop frame, +24 hours support, ...
Definition timecode.h:43
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:68
unsigned int count
Definition isom.h:69
int offset
Definition isom.h:70
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:63
unsigned int count
Definition isom.h:64
unsigned int duration
Definition isom.h:65
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:489
uint32_t * id
trackID of the referenced track
Definition movenc.h:91
PacketListEntry * head
uint8_t num_ind_sub
Definition movenc.c:394
uint8_t fscod
Definition movenc.c:397
uint16_t data_rate
Definition movenc.c:391
int8_t ac3_bit_rate_code
Definition movenc.c:392
uint8_t complexity_index_type_a
Definition movenc.c:416
uint8_t num_blocks
Definition movenc.c:387
struct eac3_info::@032224065145233261074362213314253377146303165010 substream[1]
uint8_t acmod
Definition movenc.c:405
uint8_t bsid
Definition movenc.c:399
AVPacket * pkt
Definition movenc.c:384
uint8_t eof
Definition movenc.c:385
uint16_t chan_loc
Definition movenc.c:412
uint8_t ec3_done
Definition movenc.c:386
uint8_t num_dep_sub
Definition movenc.c:410
uint8_t lfeon
Definition movenc.c:407
uint8_t bsmod
Definition movenc.c:403
uint32_t avg_bit_rate
Average rate in bits/second over the entire presentation.
Definition movenc.c:749
uint32_t max_bit_rate
Maximum rate in bits/second over any window of one second.
Definition movenc.c:748
uint32_t buffer_size
Size of the decoding buffer for the elementary stream in bytes.
Definition movenc.c:747
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
static int ref[MAX_W *MAX_W]
#define height
Definition dsp.h:89
#define width
Definition dsp.h:89
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:858
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:879
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:810