FFmpeg
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"
43 #include "libavcodec/dnxhddata.h"
44 #include "libavcodec/flac.h"
45 #include "libavcodec/get_bits.h"
46 
47 #include "libavcodec/internal.h"
48 #include "libavcodec/put_bits.h"
49 #include "libavcodec/vc1_common.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"
56 #include "libavutil/mathematics.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 
78 static 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 = MOV_TIMESCALE}, 1, INT_MAX, AV_OPT_FLAG_ENCODING_PARAM},
120  FF_RTP_FLAG_OPTS(MOVMuxContext, rtp_flags),
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 
140 static int get_moov_size(AVFormatContext *s);
142 
143 static 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 
177 static 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 
184 static 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 
191 static 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 */
201 static int mov_write_stco_tag(AVIOContext *pb, MOVTrack *track)
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 */
225 static int mov_write_stsz_tag(AVIOContext *pb, MOVTrack *track)
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 */
261 static int mov_write_stsc_tag(AVIOContext *pb, MOVTrack *track)
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 */
292 static 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 */
316 static int mov_write_sdtp_tag(AVIOContext *pb, MOVTrack *track)
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
340 static 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 
369 static int mov_write_amr_tag(AVIOContext *pb, MOVTrack *track)
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 
383 struct eac3_info {
385  uint8_t ec3_done;
386  uint8_t num_blocks;
387 
388  /* Layout of the EC3SpecificBox */
389  /* maximum bitrate */
390  uint16_t data_rate;
392  /* number of independent substreams */
393  uint8_t num_ind_sub;
394  struct {
395  /* sample rate code (see ff_ac3_sample_rate_tab) 2 bits */
396  uint8_t fscod;
397  /* bit stream identification 5 bits */
398  uint8_t bsid;
399  /* one bit reserved */
400  /* audio service mixing (not supported yet) 1 bit */
401  /* bit stream mode 3 bits */
402  uint8_t bsmod;
403  /* audio coding mode 3 bits */
404  uint8_t acmod;
405  /* sub woofer on 1 bit */
406  uint8_t lfeon;
407  /* 3 bits reserved */
408  /* number of dependent substreams associated with this substream 4 bits */
409  uint8_t num_dep_sub;
410  /* channel locations of the dependent substream(s), if any, 9 bits */
411  uint16_t chan_loc;
412  /* if there is no dependent substream, then one bit reserved instead */
413  } substream[1]; /* TODO: support 8 independent substreams */
414  /* indicates the decoding complexity, 8 bits */
416 };
417 
419 {
420  struct eac3_info *info = track->eac3_priv;
421  PutBitContext pbc;
422  uint8_t buf[3];
423 
424  if (!info || !info->ec3_done) {
426  "Cannot write moov atom before AC3 packets."
427  " Set the delay_moov flag to fix this.\n");
428  return AVERROR(EINVAL);
429  }
430 
431  if (info->substream[0].bsid > 8) {
433  "RealAudio AC-3/DolbyNet with bsid %d is not defined by the "
434  "ISOBMFF specification in ETSI TS 102 366!\n",
435  info->substream[0].bsid);
436  return AVERROR(EINVAL);
437  }
438 
439  if (info->ac3_bit_rate_code < 0) {
441  "No valid AC3 bit rate code for data rate of %d!\n",
442  info->data_rate);
443  return AVERROR(EINVAL);
444  }
445 
446  avio_wb32(pb, 11);
447  ffio_wfourcc(pb, "dac3");
448 
449  init_put_bits(&pbc, buf, sizeof(buf));
450  put_bits(&pbc, 2, info->substream[0].fscod);
451  put_bits(&pbc, 5, info->substream[0].bsid);
452  put_bits(&pbc, 3, info->substream[0].bsmod);
453  put_bits(&pbc, 3, info->substream[0].acmod);
454  put_bits(&pbc, 1, info->substream[0].lfeon);
455  put_bits(&pbc, 5, info->ac3_bit_rate_code); // bit_rate_code
456  put_bits(&pbc, 5, 0); // reserved
457 
458  flush_put_bits(&pbc);
459  avio_write(pb, buf, sizeof(buf));
460 
461  return 11;
462 }
463 
464 static int handle_eac3(MOVMuxContext *mov, AVPacket *pkt, MOVTrack *track)
465 {
466  AC3HeaderInfo *hdr = NULL;
467  struct eac3_info *info;
468  int num_blocks, ret;
469 
470  if (!track->eac3_priv) {
471  if (!(track->eac3_priv = av_mallocz(sizeof(*info))))
472  return AVERROR(ENOMEM);
473 
474  ((struct eac3_info *)track->eac3_priv)->ac3_bit_rate_code = -1;
475  }
476  info = track->eac3_priv;
477 
478  if (!info->pkt && !(info->pkt = av_packet_alloc()))
479  return AVERROR(ENOMEM);
480 
481  if ((ret = avpriv_ac3_parse_header(&hdr, pkt->data, pkt->size)) < 0) {
482  if (ret == AVERROR(ENOMEM))
483  goto end;
484 
485  /* drop the packets until we see a good one */
486  if (!track->entry) {
487  av_log(mov->fc, AV_LOG_WARNING, "Dropping invalid packet from start of the stream\n");
488  ret = 0;
489  } else
491  goto end;
492  }
493 
494  info->data_rate = FFMAX(info->data_rate, hdr->bit_rate / 1000);
495  info->ac3_bit_rate_code = FFMAX(info->ac3_bit_rate_code,
496  hdr->ac3_bit_rate_code);
497  info->complexity_index_type_a = hdr->complexity_index_type_a;
498 
499  num_blocks = hdr->num_blocks;
500 
501  if (!info->ec3_done) {
502  /* AC-3 substream must be the first one */
503  if (hdr->bitstream_id <= 10 && hdr->substreamid != 0) {
504  ret = AVERROR(EINVAL);
505  goto end;
506  }
507 
508  /* this should always be the case, given that our AC-3 parser
509  * concatenates dependent frames to their independent parent */
512  /* substream ids must be incremental */
513  if (hdr->substreamid > info->num_ind_sub + 1) {
514  ret = AVERROR(EINVAL);
515  goto end;
516  }
517 
518  if (hdr->substreamid == info->num_ind_sub + 1) {
519  //info->num_ind_sub++;
520  avpriv_request_sample(mov->fc, "Multiple independent substreams");
522  goto end;
523  } else if (hdr->substreamid < info->num_ind_sub ||
524  hdr->substreamid == 0 && info->substream[0].bsid) {
525  info->ec3_done = 1;
526  goto concatenate;
527  }
528  } else {
529  if (hdr->substreamid != 0) {
530  avpriv_request_sample(mov->fc, "Multiple non EAC3 independent substreams");
532  goto end;
533  }
534  }
535 
536  /* fill the info needed for the "dec3" atom */
537  info->substream[hdr->substreamid].fscod = hdr->sr_code;
538  info->substream[hdr->substreamid].bsid = hdr->bitstream_id;
539  info->substream[hdr->substreamid].bsmod = hdr->bitstream_mode;
540  info->substream[hdr->substreamid].acmod = hdr->channel_mode;
541  info->substream[hdr->substreamid].lfeon = hdr->lfe_on;
542 
543  if (track->par->codec_id == AV_CODEC_ID_AC3) {
544  // with AC-3 we only require the information of a single packet,
545  // so we can finish as soon as the basic values of the bit stream
546  // have been set to the track's informational structure.
547  info->ec3_done = 1;
548  goto concatenate;
549  }
550 
551  /* Parse dependent substream(s), if any */
552  if (pkt->size != hdr->frame_size) {
553  int cumul_size = hdr->frame_size;
554  int parent = hdr->substreamid;
555 
556  while (cumul_size != pkt->size) {
557  ret = avpriv_ac3_parse_header(&hdr, pkt->data + cumul_size, pkt->size - cumul_size);
558  if (ret < 0)
559  goto end;
561  ret = AVERROR(EINVAL);
562  goto end;
563  }
564  info->substream[parent].num_dep_sub++;
565  ret /= 8;
566 
567  /* get the dependent stream channel map, if exists */
568  if (hdr->channel_map_present)
569  info->substream[parent].chan_loc |= (hdr->channel_map >> 5) & 0x1f;
570  else
571  info->substream[parent].chan_loc |= hdr->channel_mode;
572  cumul_size += hdr->frame_size;
573  }
574  }
575  }
576 
577 concatenate:
578  if (!info->num_blocks && num_blocks == 6) {
579  ret = pkt->size;
580  goto end;
581  }
582  else if (info->num_blocks + num_blocks > 6) {
584  goto end;
585  }
586 
587  if (!info->num_blocks) {
588  ret = av_packet_ref(info->pkt, pkt);
589  if (!ret)
590  info->num_blocks = num_blocks;
591  goto end;
592  } else {
593  if ((ret = av_grow_packet(info->pkt, pkt->size)) < 0)
594  goto end;
595  memcpy(info->pkt->data + info->pkt->size - pkt->size, pkt->data, pkt->size);
596  info->num_blocks += num_blocks;
597  info->pkt->duration += pkt->duration;
598  if (info->num_blocks != 6)
599  goto end;
601  av_packet_move_ref(pkt, info->pkt);
602  info->num_blocks = 0;
603  }
604  ret = pkt->size;
605 
606 end:
607  av_free(hdr);
608 
609  return ret;
610 }
611 
613 {
614  PutBitContext pbc;
615  uint8_t *buf;
616  struct eac3_info *info;
617  int size, i;
618 
619  if (!track->eac3_priv) {
621  "Cannot write moov atom before EAC3 packets parsed.\n");
622  return AVERROR(EINVAL);
623  }
624 
625  info = track->eac3_priv;
626  size = 2 + (4 * (info->num_ind_sub + 1)) + (2 * !!info->complexity_index_type_a);
627  buf = av_malloc(size);
628  if (!buf) {
629  return AVERROR(ENOMEM);
630  }
631 
632  init_put_bits(&pbc, buf, size);
633  put_bits(&pbc, 13, info->data_rate);
634  put_bits(&pbc, 3, info->num_ind_sub);
635  for (i = 0; i <= info->num_ind_sub; i++) {
636  put_bits(&pbc, 2, info->substream[i].fscod);
637  put_bits(&pbc, 5, info->substream[i].bsid);
638  put_bits(&pbc, 1, 0); /* reserved */
639  put_bits(&pbc, 1, 0); /* asvc */
640  put_bits(&pbc, 3, info->substream[i].bsmod);
641  put_bits(&pbc, 3, info->substream[i].acmod);
642  put_bits(&pbc, 1, info->substream[i].lfeon);
643  put_bits(&pbc, 3, 0); /* reserved */
644  put_bits(&pbc, 4, info->substream[i].num_dep_sub);
645  if (!info->substream[i].num_dep_sub) {
646  put_bits(&pbc, 1, 0); /* reserved */
647  } else {
648  put_bits(&pbc, 9, info->substream[i].chan_loc);
649  }
650  }
651  if (info->complexity_index_type_a) {
652  put_bits(&pbc, 7, 0); /* reserved */
653  put_bits(&pbc, 1, 1); // flag_eac3_extension_type_a
654  put_bits(&pbc, 8, info->complexity_index_type_a);
655  }
656  flush_put_bits(&pbc);
657  size = put_bytes_output(&pbc);
658 
659  avio_wb32(pb, size + 8);
660  ffio_wfourcc(pb, "dec3");
661  avio_write(pb, buf, size);
662 
663  av_free(buf);
664 
665  return size;
666 }
667 
668 /**
669  * This function writes extradata "as is".
670  * Extradata must be formatted like a valid atom (with size and tag).
671  */
673 {
674  avio_write(pb, track->extradata[track->last_stsd_index], track->extradata_size[track->last_stsd_index]);
675  return track->extradata_size[track->last_stsd_index];
676 }
677 
679 {
680  avio_wb32(pb, 10);
681  ffio_wfourcc(pb, "enda");
682  avio_wb16(pb, 1); /* little endian */
683  return 10;
684 }
685 
687 {
688  avio_wb32(pb, 10);
689  ffio_wfourcc(pb, "enda");
690  avio_wb16(pb, 0); /* big endian */
691  return 10;
692 }
693 
694 static void put_descr(AVIOContext *pb, int tag, unsigned int size)
695 {
696  int i = 3;
697  avio_w8(pb, tag);
698  for (; i > 0; i--)
699  avio_w8(pb, (size >> (7 * i)) | 0x80);
700  avio_w8(pb, size & 0x7F);
701 }
702 
703 static unsigned compute_avg_bitrate(MOVTrack *track)
704 {
705  uint64_t size = 0;
706  int i;
707  if (!track->track_duration)
708  return 0;
709  for (i = 0; i < track->entry; i++)
710  size += track->cluster[i].size;
711  return size * 8 * track->timescale / track->track_duration;
712 }
713 
715  uint32_t buffer_size; ///< Size of the decoding buffer for the elementary stream in bytes.
716  uint32_t max_bit_rate; ///< Maximum rate in bits/second over any window of one second.
717  uint32_t avg_bit_rate; ///< Average rate in bits/second over the entire presentation.
718 };
719 
721 {
722  const AVPacketSideData *sd = track->st ?
724  track->st->codecpar->nb_coded_side_data,
726  AVCPBProperties *props = sd ? (AVCPBProperties *)sd->data : NULL;
727  struct mpeg4_bit_rate_values bit_rates = { 0 };
728 
729  bit_rates.avg_bit_rate = compute_avg_bitrate(track);
730  if (!bit_rates.avg_bit_rate) {
731  // if the average bit rate cannot be calculated at this point, such as
732  // in the case of fragmented MP4, utilize the following values as
733  // fall-back in priority order:
734  //
735  // 1. average bit rate property
736  // 2. bit rate (usually average over the whole clip)
737  // 3. maximum bit rate property
738 
739  if (props && props->avg_bitrate) {
740  bit_rates.avg_bit_rate = props->avg_bitrate;
741  } else if (track->par->bit_rate) {
742  bit_rates.avg_bit_rate = track->par->bit_rate;
743  } else if (props && props->max_bitrate) {
744  bit_rates.avg_bit_rate = props->max_bitrate;
745  }
746  }
747 
748  // (FIXME should be max rate in any 1 sec window)
749  bit_rates.max_bit_rate = FFMAX(track->par->bit_rate,
750  bit_rates.avg_bit_rate);
751 
752  // utilize values from properties if we have them available
753  if (props) {
754  // no avg_bitrate signals that the track is VBR
755  if (!props->avg_bitrate)
756  bit_rates.avg_bit_rate = props->avg_bitrate;
757  bit_rates.max_bit_rate = FFMAX(bit_rates.max_bit_rate,
758  props->max_bitrate);
759  bit_rates.buffer_size = props->buffer_size / 8;
760  }
761 
762  return bit_rates;
763 }
764 
765 static int mov_write_esds_tag(AVIOContext *pb, MOVTrack *track) // Basic
766 {
767  struct mpeg4_bit_rate_values bit_rates = calculate_mpeg4_bit_rates(track);
768  int64_t pos = avio_tell(pb);
769  int decoder_specific_info_len = track->extradata_size[track->last_stsd_index] ?
770  5 + track->extradata_size[track->last_stsd_index] : 0;
771 
772  avio_wb32(pb, 0); // size
773  ffio_wfourcc(pb, "esds");
774  avio_wb32(pb, 0); // Version
775 
776  // ES descriptor
777  put_descr(pb, 0x03, 3 + 5+13 + decoder_specific_info_len + 5+1);
778  avio_wb16(pb, track->track_id);
779  avio_w8(pb, 0x00); // flags (= no flags)
780 
781  // DecoderConfig descriptor
782  put_descr(pb, 0x04, 13 + decoder_specific_info_len);
783 
784  // Object type indication
785  if ((track->par->codec_id == AV_CODEC_ID_MP2 ||
786  track->par->codec_id == AV_CODEC_ID_MP3) &&
787  track->par->sample_rate > 24000)
788  avio_w8(pb, 0x6B); // 11172-3
789  else
791 
792  // the following fields is made of 6 bits to identify the streamtype (4 for video, 5 for audio)
793  // plus 1 bit to indicate upstream and 1 bit set to 1 (reserved)
794  if (track->par->codec_id == AV_CODEC_ID_DVD_SUBTITLE)
795  avio_w8(pb, (0x38 << 2) | 1); // flags (= NeroSubpicStream)
796  else if (track->par->codec_type == AVMEDIA_TYPE_AUDIO)
797  avio_w8(pb, 0x15); // flags (= Audiostream)
798  else
799  avio_w8(pb, 0x11); // flags (= Visualstream)
800 
801  avio_wb24(pb, bit_rates.buffer_size); // Buffersize DB
802  avio_wb32(pb, bit_rates.max_bit_rate); // maxbitrate
803  avio_wb32(pb, bit_rates.avg_bit_rate);
804 
805  if (track->extradata_size[track->last_stsd_index]) {
806  // DecoderSpecific info descriptor
807  put_descr(pb, 0x05, track->extradata_size[track->last_stsd_index]);
808  avio_write(pb, track->extradata[track->last_stsd_index],
809  track->extradata_size[track->last_stsd_index]);
810  }
811 
812  // SL descriptor
813  put_descr(pb, 0x06, 1);
814  avio_w8(pb, 0x02);
815  return update_size(pb, pos);
816 }
817 
819 {
820  return codec_id == AV_CODEC_ID_PCM_S24LE ||
824 }
825 
827 {
828  return codec_id == AV_CODEC_ID_PCM_S24BE ||
832 }
833 
835 {
836  int ret;
837  int64_t pos = avio_tell(pb);
838  avio_wb32(pb, 0);
839  avio_wl32(pb, track->tag); // store it byteswapped
840  track->par->codec_tag = av_bswap16(track->tag >> 16);
841  if ((ret = ff_put_wav_header(s, pb, track->par, 0)) < 0)
842  return ret;
843  return update_size(pb, pos);
844 }
845 
847 {
848  int ret;
849  int64_t pos = avio_tell(pb);
850  avio_wb32(pb, 0);
851  ffio_wfourcc(pb, "wfex");
853  return ret;
854  return update_size(pb, pos);
855 }
856 
857 static int mov_write_dfla_tag(AVIOContext *pb, MOVTrack *track)
858 {
859  int64_t pos = avio_tell(pb);
860  avio_wb32(pb, 0);
861  ffio_wfourcc(pb, "dfLa");
862  avio_w8(pb, 0); /* version */
863  avio_wb24(pb, 0); /* flags */
864 
865  /* Expect the encoder to pass a METADATA_BLOCK_TYPE_STREAMINFO. */
867  return AVERROR_INVALIDDATA;
868 
869  /* TODO: Write other METADATA_BLOCK_TYPEs if the encoder makes them available. */
870  avio_w8(pb, 1 << 7 | FLAC_METADATA_TYPE_STREAMINFO); /* LastMetadataBlockFlag << 7 | BlockType */
871  avio_wb24(pb, track->extradata_size[track->last_stsd_index]); /* Length */
872  avio_write(pb, track->extradata[track->last_stsd_index], track->extradata_size[track->last_stsd_index]); /* BlockData[Length] */
873 
874  return update_size(pb, pos);
875 }
876 
878 {
879  int64_t pos = avio_tell(pb);
880  int channels, channel_map;
881  avio_wb32(pb, 0);
882  ffio_wfourcc(pb, "dOps");
883  avio_w8(pb, 0); /* Version */
884  if (track->extradata_size[track->last_stsd_index] < 19) {
885  av_log(s, AV_LOG_ERROR, "invalid extradata size\n");
886  return AVERROR_INVALIDDATA;
887  }
888  /* extradata contains an Ogg OpusHead, other than byte-ordering and
889  OpusHead's preceding magic/version, OpusSpecificBox is currently
890  identical. */
891  channels = AV_RB8(track->extradata[track->last_stsd_index] + 9);
892  channel_map = AV_RB8(track->extradata[track->last_stsd_index] + 18);
893 
894  avio_w8(pb, channels); /* OuputChannelCount */
895  avio_wb16(pb, AV_RL16(track->extradata[track->last_stsd_index] + 10)); /* PreSkip */
896  avio_wb32(pb, AV_RL32(track->extradata[track->last_stsd_index] + 12)); /* InputSampleRate */
897  avio_wb16(pb, AV_RL16(track->extradata[track->last_stsd_index] + 16)); /* OutputGain */
898  avio_w8(pb, channel_map); /* ChannelMappingFamily */
899  /* Write the rest of the header out without byte-swapping. */
900  if (channel_map) {
901  if (track->extradata_size[track->last_stsd_index] < 21 + channels) {
902  av_log(s, AV_LOG_ERROR, "invalid extradata size\n");
903  return AVERROR_INVALIDDATA;
904  }
905  avio_write(pb, track->extradata[track->last_stsd_index] + 19, 2 + channels); /* ChannelMappingTable */
906  }
907 
908  return update_size(pb, pos);
909 }
910 
912 {
913  int64_t pos = avio_tell(pb);
914  int length;
915  avio_wb32(pb, 0);
916  ffio_wfourcc(pb, "dmlp");
917 
918  if (track->extradata_size[track->last_stsd_index] < 20) {
920  "Cannot write moov atom before TrueHD packets."
921  " Set the delay_moov flag to fix this.\n");
922  return AVERROR(EINVAL);
923  }
924 
925  length = (AV_RB16(track->extradata[track->last_stsd_index]) & 0xFFF) * 2;
926  if (length < 20 || length > track->extradata_size[track->last_stsd_index])
927  return AVERROR_INVALIDDATA;
928 
929  // Only TrueHD is supported
930  if (AV_RB32(track->extradata[track->last_stsd_index] + 4) != 0xF8726FBA)
931  return AVERROR_INVALIDDATA;
932 
933  avio_wb32(pb, AV_RB32(track->extradata[track->last_stsd_index] + 8)); /* format_info */
934  avio_wb16(pb, AV_RB16(track->extradata[track->last_stsd_index] + 18) << 1); /* peak_data_rate */
935  avio_wb32(pb, 0); /* reserved */
936 
937  return update_size(pb, pos);
938 }
939 
941 {
942  const AVDictionaryEntry *str = av_dict_get(track->st->metadata, "SA3D", NULL, 0);
943  AVChannelLayout ch_layout = { 0 };
944  int64_t pos;
945  int ambisonic_order, ambi_channels, non_diegetic_channels;
946  int i, ret;
947 
948  if (!str)
949  return 0;
950 
951  ret = av_channel_layout_from_string(&ch_layout, str->value);
952  if (ret < 0) {
953  if (ret == AVERROR(EINVAL)) {
954 invalid:
955  av_log(s, AV_LOG_ERROR, "Invalid SA3D layout: \"%s\"\n", str->value);
956  ret = 0;
957  }
958  av_channel_layout_uninit(&ch_layout);
959  return ret;
960  }
961 
962  if (track->st->codecpar->ch_layout.nb_channels != ch_layout.nb_channels)
963  goto invalid;
964 
965  ambisonic_order = av_channel_layout_ambisonic_order(&ch_layout);
966  if (ambisonic_order < 0)
967  goto invalid;
968 
969  ambi_channels = (ambisonic_order + 1LL) * (ambisonic_order + 1LL);
970  non_diegetic_channels = ch_layout.nb_channels - ambi_channels;
971  if (non_diegetic_channels &&
972  (non_diegetic_channels != 2 ||
974  goto invalid;
975 
976  av_log(s, AV_LOG_VERBOSE, "Inserting SA3D box with layout: \"%s\"\n", str->value);
977 
978  pos = avio_tell(pb);
979 
980  avio_wb32(pb, 0); // Size
981  ffio_wfourcc(pb, "SA3D");
982  avio_w8(pb, 0); // version
983  avio_w8(pb, (!!non_diegetic_channels) << 7); // head_locked_stereo and ambisonic_type
984  avio_wb32(pb, ambisonic_order); // ambisonic_order
985  avio_w8(pb, 0); // ambisonic_channel_ordering
986  avio_w8(pb, 0); // ambisonic_normalization
987  avio_wb32(pb, ch_layout.nb_channels); // num_channels
988  for (i = 0; i < ambi_channels; i++)
990  for (; i < ch_layout.nb_channels; i++)
991  avio_wb32(pb, av_channel_layout_channel_from_index(&ch_layout, i) + ambi_channels);
992 
993  av_channel_layout_uninit(&ch_layout);
994 
995  return update_size(pb, pos);
996 }
997 
999 {
1000  uint32_t layout_tag, bitmap, *channel_desc;
1001  int64_t pos = avio_tell(pb);
1002  int num_desc, ret;
1003 
1004  if (track->multichannel_as_mono)
1005  return 0;
1006 
1007  ret = ff_mov_get_channel_layout_tag(track->par, &layout_tag,
1008  &bitmap, &channel_desc);
1009 
1010  if (ret < 0) {
1011  if (ret == AVERROR(ENOSYS)) {
1012  av_log(s, AV_LOG_WARNING, "not writing 'chan' tag due to "
1013  "lack of channel information\n");
1014  ret = 0;
1015  }
1016 
1017  return ret;
1018  }
1019 
1020  if (layout_tag == MOV_CH_LAYOUT_MONO && track->mono_as_fc > 0) {
1021  av_assert0(!channel_desc);
1022  channel_desc = av_malloc(sizeof(*channel_desc));
1023  if (!channel_desc)
1024  return AVERROR(ENOMEM);
1025 
1026  layout_tag = 0;
1027  bitmap = 0;
1028  *channel_desc = 3; // channel label "Center"
1029  }
1030 
1031  num_desc = layout_tag ? 0 : track->par->ch_layout.nb_channels;
1032 
1033  avio_wb32(pb, 0); // Size
1034  ffio_wfourcc(pb, "chan"); // Type
1035  avio_w8(pb, 0); // Version
1036  avio_wb24(pb, 0); // Flags
1037  avio_wb32(pb, layout_tag); // mChannelLayoutTag
1038  avio_wb32(pb, bitmap); // mChannelBitmap
1039  avio_wb32(pb, num_desc); // mNumberChannelDescriptions
1040 
1041  for (int i = 0; i < num_desc; i++) {
1042  avio_wb32(pb, channel_desc[i]); // mChannelLabel
1043  avio_wb32(pb, 0); // mChannelFlags
1044  avio_wl32(pb, 0); // mCoordinates[0]
1045  avio_wl32(pb, 0); // mCoordinates[1]
1046  avio_wl32(pb, 0); // mCoordinates[2]
1047  }
1048 
1049  av_free(channel_desc);
1050 
1051  return update_size(pb, pos);
1052 }
1053 
1055 {
1056  int64_t pos = avio_tell(pb);
1057 
1058  avio_wb32(pb, 0); /* size */
1059  ffio_wfourcc(pb, "wave");
1060 
1061  if (track->par->codec_id != AV_CODEC_ID_QDM2) {
1062  avio_wb32(pb, 12); /* size */
1063  ffio_wfourcc(pb, "frma");
1064  avio_wl32(pb, track->tag);
1065  }
1066 
1067  if (track->par->codec_id == AV_CODEC_ID_AAC) {
1068  /* useless atom needed by mplayer, ipod, not needed by quicktime */
1069  avio_wb32(pb, 12); /* size */
1070  ffio_wfourcc(pb, "mp4a");
1071  avio_wb32(pb, 0);
1072  mov_write_esds_tag(pb, track);
1073  } else if (mov_pcm_le_gt16(track->par->codec_id)) {
1074  mov_write_enda_tag(pb);
1075  } else if (mov_pcm_be_gt16(track->par->codec_id)) {
1077  } else if (track->par->codec_id == AV_CODEC_ID_AMR_NB) {
1078  mov_write_amr_tag(pb, track);
1079  } else if (track->par->codec_id == AV_CODEC_ID_AC3) {
1080  mov_write_ac3_tag(s, pb, track);
1081  } else if (track->par->codec_id == AV_CODEC_ID_EAC3) {
1082  mov_write_eac3_tag(s, pb, track);
1083  } else if (track->par->codec_id == AV_CODEC_ID_ALAC ||
1084  track->par->codec_id == AV_CODEC_ID_QDM2) {
1085  mov_write_extradata_tag(pb, track);
1086  } else if (track->par->codec_id == AV_CODEC_ID_ADPCM_MS ||
1087  track->par->codec_id == AV_CODEC_ID_ADPCM_IMA_WAV) {
1088  mov_write_ms_tag(s, pb, track);
1089  }
1090 
1091  avio_wb32(pb, 8); /* size */
1092  avio_wb32(pb, 0); /* null tag */
1093 
1094  return update_size(pb, pos);
1095 }
1096 
1097 static int mov_write_dvc1_structs(MOVTrack *track, uint8_t *buf)
1098 {
1099  uint8_t *unescaped;
1100  const uint8_t *start, *next, *end = track->extradata[track->last_stsd_index] +
1101  track->extradata_size[track->last_stsd_index];
1102  int unescaped_size, seq_found = 0;
1103  int level = 0, interlace = 0;
1104  int packet_seq = track->vc1_info.packet_seq;
1105  int packet_entry = track->vc1_info.packet_entry;
1106  int slices = track->vc1_info.slices;
1107  PutBitContext pbc;
1108 
1109  if (track->start_dts == AV_NOPTS_VALUE) {
1110  /* No packets written yet, vc1_info isn't authoritative yet. */
1111  /* Assume inline sequence and entry headers. */
1112  packet_seq = packet_entry = 1;
1114  "moov atom written before any packets, unable to write correct "
1115  "dvc1 atom. Set the delay_moov flag to fix this.\n");
1116  }
1117 
1119  if (!unescaped)
1120  return AVERROR(ENOMEM);
1121  start = find_next_marker(track->extradata[track->last_stsd_index], end);
1122  for (next = start; next < end; start = next) {
1123  GetBitContext gb;
1124  int size;
1125  next = find_next_marker(start + 4, end);
1126  size = next - start - 4;
1127  if (size <= 0)
1128  continue;
1129  unescaped_size = vc1_unescape_buffer(start + 4, size, unescaped);
1130  init_get_bits(&gb, unescaped, 8 * unescaped_size);
1131  if (AV_RB32(start) == VC1_CODE_SEQHDR) {
1132  int profile = get_bits(&gb, 2);
1133  if (profile != PROFILE_ADVANCED) {
1134  av_free(unescaped);
1135  return AVERROR(ENOSYS);
1136  }
1137  seq_found = 1;
1138  level = get_bits(&gb, 3);
1139  /* chromaformat, frmrtq_postproc, bitrtq_postproc, postprocflag,
1140  * width, height */
1141  skip_bits_long(&gb, 2 + 3 + 5 + 1 + 2*12);
1142  skip_bits(&gb, 1); /* broadcast */
1143  interlace = get_bits1(&gb);
1144  skip_bits(&gb, 4); /* tfcntrflag, finterpflag, reserved, psf */
1145  }
1146  }
1147  if (!seq_found) {
1148  av_free(unescaped);
1149  return AVERROR(ENOSYS);
1150  }
1151 
1152  init_put_bits(&pbc, buf, 7);
1153  /* VC1DecSpecStruc */
1154  put_bits(&pbc, 4, 12); /* profile - advanced */
1155  put_bits(&pbc, 3, level);
1156  put_bits(&pbc, 1, 0); /* reserved */
1157  /* VC1AdvDecSpecStruc */
1158  put_bits(&pbc, 3, level);
1159  put_bits(&pbc, 1, 0); /* cbr */
1160  put_bits(&pbc, 6, 0); /* reserved */
1161  put_bits(&pbc, 1, !interlace); /* no interlace */
1162  put_bits(&pbc, 1, !packet_seq); /* no multiple seq */
1163  put_bits(&pbc, 1, !packet_entry); /* no multiple entry */
1164  put_bits(&pbc, 1, !slices); /* no slice code */
1165  put_bits(&pbc, 1, 0); /* no bframe */
1166  put_bits(&pbc, 1, 0); /* reserved */
1167 
1168  /* framerate */
1169  if (track->st->avg_frame_rate.num > 0 && track->st->avg_frame_rate.den > 0)
1170  put_bits32(&pbc, track->st->avg_frame_rate.num / track->st->avg_frame_rate.den);
1171  else
1172  put_bits32(&pbc, 0xffffffff);
1173 
1174  flush_put_bits(&pbc);
1175 
1176  av_free(unescaped);
1177 
1178  return 0;
1179 }
1180 
1181 static int mov_write_dvc1_tag(AVIOContext *pb, MOVTrack *track)
1182 {
1183  uint8_t buf[7] = { 0 };
1184  int ret;
1185 
1186  if ((ret = mov_write_dvc1_structs(track, buf)) < 0)
1187  return ret;
1188 
1189  avio_wb32(pb, track->extradata_size[track->last_stsd_index] + 8 + sizeof(buf));
1190  ffio_wfourcc(pb, "dvc1");
1191  avio_write(pb, buf, sizeof(buf));
1192  avio_write(pb, track->extradata[track->last_stsd_index],
1193  track->extradata_size[track->last_stsd_index]);
1194 
1195  return 0;
1196 }
1197 
1198 static int mov_write_glbl_tag(AVIOContext *pb, MOVTrack *track)
1199 {
1200  avio_wb32(pb, track->extradata_size[track->last_stsd_index] + 8);
1201  ffio_wfourcc(pb, "glbl");
1202  avio_write(pb, track->extradata[track->last_stsd_index],
1203  track->extradata_size[track->last_stsd_index]);
1204  return 8 + track->extradata_size[track->last_stsd_index];
1205 }
1206 
1207 /**
1208  * Compute flags for 'lpcm' tag.
1209  * See CoreAudioTypes and AudioStreamBasicDescription at Apple.
1210  */
1212 {
1213  switch (codec_id) {
1214  case AV_CODEC_ID_PCM_F32BE:
1215  case AV_CODEC_ID_PCM_F64BE:
1216  return 11;
1217  case AV_CODEC_ID_PCM_F32LE:
1218  case AV_CODEC_ID_PCM_F64LE:
1219  return 9;
1220  case AV_CODEC_ID_PCM_U8:
1221  return 10;
1222  case AV_CODEC_ID_PCM_S16BE:
1223  case AV_CODEC_ID_PCM_S24BE:
1224  case AV_CODEC_ID_PCM_S32BE:
1225  return 14;
1226  case AV_CODEC_ID_PCM_S8:
1227  case AV_CODEC_ID_PCM_S16LE:
1228  case AV_CODEC_ID_PCM_S24LE:
1229  case AV_CODEC_ID_PCM_S32LE:
1230  return 12;
1231  default:
1232  return 0;
1233  }
1234 }
1235 
1236 static int get_cluster_duration(MOVTrack *track, int cluster_idx)
1237 {
1238  int64_t next_dts;
1239 
1240  if (cluster_idx >= track->entry)
1241  return 0;
1242 
1243  if (cluster_idx + 1 == track->entry)
1244  next_dts = track->track_duration + track->start_dts;
1245  else
1246  next_dts = track->cluster[cluster_idx + 1].dts;
1247 
1248  next_dts -= track->cluster[cluster_idx].dts;
1249 
1250  av_assert0(next_dts >= 0);
1251  av_assert0(next_dts <= INT_MAX);
1252 
1253  return next_dts;
1254 }
1255 
1257 {
1258  int i, first_duration;
1259 
1260  /* use 1 for raw PCM */
1261  if (!track->audio_vbr)
1262  return 1;
1263 
1264  /* check to see if duration is constant for all clusters */
1265  if (!track->entry)
1266  return 0;
1267  first_duration = get_cluster_duration(track, 0);
1268  for (i = 1; i < track->entry; i++) {
1269  if (get_cluster_duration(track, i) != first_duration)
1270  return 0;
1271  }
1272  return first_duration;
1273 }
1274 
1275 static int mov_write_btrt_tag(AVIOContext *pb, MOVTrack *track)
1276 {
1277  int64_t pos = avio_tell(pb);
1278  struct mpeg4_bit_rate_values bit_rates = calculate_mpeg4_bit_rates(track);
1279  if (!bit_rates.max_bit_rate && !bit_rates.avg_bit_rate &&
1280  !bit_rates.buffer_size)
1281  // no useful data to be written, skip
1282  return 0;
1283 
1284  avio_wb32(pb, 0); /* size */
1285  ffio_wfourcc(pb, "btrt");
1286 
1287  avio_wb32(pb, bit_rates.buffer_size);
1288  avio_wb32(pb, bit_rates.max_bit_rate);
1289  avio_wb32(pb, bit_rates.avg_bit_rate);
1290 
1291  return update_size(pb, pos);
1292 }
1293 
1295 {
1296  int64_t pos = avio_tell(pb);
1297  int config = 0;
1298  int ret;
1299  uint8_t *speaker_pos = NULL;
1300  const AVChannelLayout *layout = &track->par->ch_layout;
1301 
1303  if (ret || !config) {
1304  config = 0;
1305  speaker_pos = av_malloc(layout->nb_channels);
1306  if (!speaker_pos)
1307  return AVERROR(ENOMEM);
1309  speaker_pos, layout->nb_channels);
1310  if (ret) {
1311  char buf[128] = {0};
1312 
1313  av_freep(&speaker_pos);
1314  av_channel_layout_describe(layout, buf, sizeof(buf));
1315  av_log(s, AV_LOG_ERROR, "unsupported channel layout %s\n", buf);
1316  return ret;
1317  }
1318  }
1319 
1320  avio_wb32(pb, 0); /* size */
1321  ffio_wfourcc(pb, "chnl");
1322  avio_wb32(pb, 0); /* version & flags */
1323 
1324  avio_w8(pb, 1); /* stream_structure */
1325  avio_w8(pb, config);
1326  if (config) {
1327  avio_wb64(pb, 0);
1328  } else {
1329  avio_write(pb, speaker_pos, layout->nb_channels);
1330  av_freep(&speaker_pos);
1331  }
1332 
1333  return update_size(pb, pos);
1334 }
1335 
1337 {
1338  int64_t pos = avio_tell(pb);
1339  int format_flags;
1340  int sample_size;
1341 
1342  avio_wb32(pb, 0); /* size */
1343  ffio_wfourcc(pb, "pcmC");
1344  avio_wb32(pb, 0); /* version & flags */
1345 
1346  /* 0x01: indicates little-endian format */
1347  format_flags = (track->par->codec_id == AV_CODEC_ID_PCM_F32LE ||
1348  track->par->codec_id == AV_CODEC_ID_PCM_F64LE ||
1349  track->par->codec_id == AV_CODEC_ID_PCM_S16LE ||
1350  track->par->codec_id == AV_CODEC_ID_PCM_S24LE ||
1351  track->par->codec_id == AV_CODEC_ID_PCM_S32LE);
1352  avio_w8(pb, format_flags);
1353  sample_size = track->par->bits_per_raw_sample;
1354  if (!sample_size)
1355  sample_size = av_get_exact_bits_per_sample(track->par->codec_id);
1356  av_assert0(sample_size);
1357  avio_w8(pb, sample_size);
1358 
1359  return update_size(pb, pos);
1360 }
1361 
1362 static int mov_write_srat_tag(AVIOContext *pb, MOVTrack *track)
1363 {
1364  int64_t pos = avio_tell(pb);
1365  avio_wb32(pb, 0); /* size */
1366  ffio_wfourcc(pb, "srat");
1367  avio_wb32(pb, 0); /* version & flags */
1368 
1369  avio_wb32(pb, track->par->sample_rate);
1370 
1371  return update_size(pb, pos);
1372 }
1373 
1375 {
1376  int64_t pos = avio_tell(pb);
1377  int version = 0;
1378  uint32_t tag = track->tag;
1379  int ret = 0;
1380 
1381  if (track->mode == MODE_MOV) {
1382  if (track->timescale > UINT16_MAX || !track->par->ch_layout.nb_channels) {
1383  if (mov_get_lpcm_flags(track->par->codec_id))
1384  tag = AV_RL32("lpcm");
1385  version = 2;
1386  } else if (track->audio_vbr || mov_pcm_le_gt16(track->par->codec_id) ||
1387  mov_pcm_be_gt16(track->par->codec_id) ||
1388  track->par->codec_id == AV_CODEC_ID_ADPCM_MS ||
1389  track->par->codec_id == AV_CODEC_ID_ADPCM_IMA_WAV ||
1390  track->par->codec_id == AV_CODEC_ID_QDM2) {
1391  version = 1;
1392  }
1393  } else if (track->mode == MODE_MP4) {
1394  if (track->par->sample_rate > UINT16_MAX &&
1396  version = 1;
1397  }
1398 
1399  avio_wb32(pb, 0); /* size */
1400  if (mov->encryption_scheme != MOV_ENC_NONE) {
1401  ffio_wfourcc(pb, "enca");
1402  } else {
1403  avio_wl32(pb, tag); // store it byteswapped
1404  }
1405  avio_wb32(pb, 0); /* Reserved */
1406  avio_wb16(pb, 0); /* Reserved */
1407  avio_wb16(pb, 1); /* Data-reference index, XXX == 1 */
1408 
1409  /* SoundDescription */
1410  avio_wb16(pb, version); /* Version */
1411  avio_wb16(pb, 0); /* Revision level */
1412  avio_wb32(pb, 0); /* Reserved */
1413 
1414  if (version == 2) {
1415  avio_wb16(pb, 3);
1416  avio_wb16(pb, 16);
1417  avio_wb16(pb, 0xfffe);
1418  avio_wb16(pb, 0);
1419  avio_wb32(pb, 0x00010000);
1420  avio_wb32(pb, 72);
1421  avio_wb64(pb, av_double2int(track->par->sample_rate));
1422  avio_wb32(pb, track->par->ch_layout.nb_channels);
1423  avio_wb32(pb, 0x7F000000);
1425  avio_wb32(pb, mov_get_lpcm_flags(track->par->codec_id));
1426  avio_wb32(pb, track->sample_size);
1427  avio_wb32(pb, get_samples_per_packet(track));
1428  } else {
1429  unsigned sample_rate = track->par->sample_rate;
1430 
1431  if (track->mode == MODE_MOV) {
1432  avio_wb16(pb, track->par->ch_layout.nb_channels);
1433  if (track->par->codec_id == AV_CODEC_ID_PCM_U8 ||
1434  track->par->codec_id == AV_CODEC_ID_PCM_S8)
1435  avio_wb16(pb, 8); /* bits per sample */
1436  else if (track->par->codec_id == AV_CODEC_ID_ADPCM_G726)
1437  avio_wb16(pb, track->par->bits_per_coded_sample);
1438  else
1439  avio_wb16(pb, 16);
1440  avio_wb16(pb, track->audio_vbr ? -2 : 0); /* compression ID */
1441  } else { /* reserved for mp4/3gp */
1442  avio_wb16(pb, track->tag == MKTAG('i', 'a', 'm', 'f') ?
1443  0 : track->par->ch_layout.nb_channels);
1444  if (track->par->codec_id == AV_CODEC_ID_FLAC ||
1445  track->par->codec_id == AV_CODEC_ID_ALAC) {
1446  avio_wb16(pb, track->par->bits_per_raw_sample);
1447  } else {
1448  avio_wb16(pb, 16);
1449  }
1450  avio_wb16(pb, 0);
1451 
1452  while (sample_rate > UINT16_MAX)
1453  sample_rate >>= 1;
1454  }
1455 
1456  avio_wb16(pb, 0); /* packet size (= 0) */
1457  if (track->tag == MKTAG('i','a','m','f'))
1458  avio_wb16(pb, 0); /* samplerate must be 0 for IAMF */
1459  else if (track->par->codec_id == AV_CODEC_ID_OPUS)
1460  avio_wb16(pb, 48000);
1461  else if (track->par->codec_id == AV_CODEC_ID_TRUEHD)
1462  avio_wb32(pb, track->par->sample_rate);
1463  else
1464  avio_wb16(pb, sample_rate);
1465 
1466  if (track->par->codec_id != AV_CODEC_ID_TRUEHD)
1467  avio_wb16(pb, 0); /* Reserved */
1468  }
1469 
1470  if (track->mode == MODE_MOV && version == 1) { /* SoundDescription V1 extended info */
1471  if (mov_pcm_le_gt16(track->par->codec_id) ||
1472  mov_pcm_be_gt16(track->par->codec_id))
1473  avio_wb32(pb, 1); /* must be 1 for uncompressed formats */
1474  else
1475  avio_wb32(pb, track->par->frame_size); /* Samples per packet */
1476  avio_wb32(pb, track->sample_size / track->par->ch_layout.nb_channels); /* Bytes per packet */
1477  avio_wb32(pb, track->sample_size); /* Bytes per frame */
1478  avio_wb32(pb, 2); /* Bytes per sample */
1479  }
1480 
1481  if (track->mode == MODE_MOV &&
1482  (track->par->codec_id == AV_CODEC_ID_AAC ||
1483  track->par->codec_id == AV_CODEC_ID_AC3 ||
1484  track->par->codec_id == AV_CODEC_ID_EAC3 ||
1485  track->par->codec_id == AV_CODEC_ID_AMR_NB ||
1486  track->par->codec_id == AV_CODEC_ID_ALAC ||
1487  track->par->codec_id == AV_CODEC_ID_ADPCM_MS ||
1488  track->par->codec_id == AV_CODEC_ID_ADPCM_IMA_WAV ||
1489  track->par->codec_id == AV_CODEC_ID_QDM2 ||
1490  (mov_pcm_le_gt16(track->par->codec_id) && version==1) ||
1491  (mov_pcm_be_gt16(track->par->codec_id) && version==1)))
1492  ret = mov_write_wave_tag(s, pb, track);
1493  else if (track->tag == MKTAG('m','p','4','a'))
1494  ret = mov_write_esds_tag(pb, track);
1495 #if CONFIG_IAMFENC
1496  else if (track->tag == MKTAG('i','a','m','f'))
1497  ret = mov_write_iacb_tag(mov->fc, pb, track);
1498 #endif
1499  else if (track->par->codec_id == AV_CODEC_ID_AMR_NB)
1500  ret = mov_write_amr_tag(pb, track);
1501  else if (track->par->codec_id == AV_CODEC_ID_AC3)
1502  ret = mov_write_ac3_tag(s, pb, track);
1503  else if (track->par->codec_id == AV_CODEC_ID_EAC3)
1504  ret = mov_write_eac3_tag(s, pb, track);
1505  else if (track->par->codec_id == AV_CODEC_ID_ALAC)
1506  ret = mov_write_extradata_tag(pb, track);
1507  else if (track->par->codec_id == AV_CODEC_ID_WMAPRO)
1508  ret = mov_write_wfex_tag(s, pb, track);
1509  else if (track->par->codec_id == AV_CODEC_ID_FLAC)
1510  ret = mov_write_dfla_tag(pb, track);
1511  else if (track->par->codec_id == AV_CODEC_ID_OPUS)
1512  ret = mov_write_dops_tag(s, pb, track);
1513  else if (track->par->codec_id == AV_CODEC_ID_TRUEHD)
1514  ret = mov_write_dmlp_tag(s, pb, track);
1515  else if (tag == MOV_MP4_IPCM_TAG || tag == MOV_MP4_FPCM_TAG) {
1516  if (track->par->sample_rate > UINT16_MAX)
1517  mov_write_srat_tag(pb, track);
1518  if (track->par->ch_layout.nb_channels > 1)
1519  ret = mov_write_chnl_tag(s, pb, track);
1520  if (ret < 0)
1521  return ret;
1522  ret = mov_write_pcmc_tag(s, pb, track);
1523  } else if (track->extradata_size[track->last_stsd_index] > 0)
1524  ret = mov_write_glbl_tag(pb, track);
1525 
1526  if (ret < 0)
1527  return ret;
1528 
1529  if (track->mode == MODE_MP4 && track->par->codec_type == AVMEDIA_TYPE_AUDIO
1530  && ((ret = mov_write_SA3D_tag(s, pb, track)) < 0)) {
1531  return ret;
1532  }
1533 
1534  if (track->mode == MODE_MOV && track->par->codec_type == AVMEDIA_TYPE_AUDIO
1535  && ((ret = mov_write_chan_tag(s, pb, track)) < 0)) {
1536  return ret;
1537  }
1538 
1539  if (mov->encryption_scheme != MOV_ENC_NONE
1540  && ((ret = ff_mov_cenc_write_sinf_tag(track, pb, mov->encryption_kid)) < 0)) {
1541  return ret;
1542  }
1543 
1544  if (mov->write_btrt &&
1545  ((ret = mov_write_btrt_tag(pb, track)) < 0))
1546  return ret;
1547 
1548  if (track->mode == MODE_MP4)
1549  track->entry_version = version;
1550 
1551  ret = update_size(pb, pos);
1552  return ret;
1553 }
1554 
1556 {
1557  avio_wb32(pb, 0xf); /* size */
1558  ffio_wfourcc(pb, "d263");
1559  ffio_wfourcc(pb, "FFMP");
1560  avio_w8(pb, 0); /* decoder version */
1561  /* FIXME use AVCodecContext level/profile, when encoder will set values */
1562  avio_w8(pb, 0xa); /* level */
1563  avio_w8(pb, 0); /* profile */
1564  return 0xf;
1565 }
1566 
1567 static int mov_write_av1c_tag(AVIOContext *pb, MOVTrack *track)
1568 {
1569  int64_t pos = avio_tell(pb);
1570 
1571  avio_wb32(pb, 0);
1572  ffio_wfourcc(pb, "av1C");
1573  ff_isom_write_av1c(pb, track->extradata[track->last_stsd_index],
1574  track->extradata_size[track->last_stsd_index], track->mode != MODE_AVIF);
1575  return update_size(pb, pos);
1576 }
1577 
1578 static int mov_write_avcc_tag(AVIOContext *pb, MOVTrack *track)
1579 {
1580  int64_t pos = avio_tell(pb);
1581 
1582  avio_wb32(pb, 0);
1583  ffio_wfourcc(pb, "avcC");
1584  ff_isom_write_avcc(pb, track->extradata[track->last_stsd_index],
1585  track->extradata_size[track->last_stsd_index]);
1586  return update_size(pb, pos);
1587 }
1588 
1589 /* AVS3 Intelligent Media Coding
1590  * Information Technology - Intelligent Media Coding
1591  * Part 6: Intelligent Media Format
1592  */
1593 static int mov_write_av3c(AVIOContext *pb, const uint8_t *data, int len)
1594 {
1595  if (len < 4)
1596  return AVERROR_INVALIDDATA;
1597 
1598  if (data[0] == 1) {
1599  // In Avs3DecoderConfigurationRecord format
1600  avio_write(pb, data, len);
1601  return 0;
1602  }
1603 
1604  avio_w8(pb, 1); // version
1605  avio_wb16(pb, len); // sequence_header_length
1606  avio_write(pb, data, len); // sequence_header
1607  avio_w8(pb, 0xFC); // Only support library_dependency_idc = 0
1608 
1609  return 0;
1610 }
1611 
1612 static int mov_write_av3c_tag(AVIOContext *pb, MOVTrack *track)
1613 {
1614  int64_t pos = avio_tell(pb);
1615  avio_wb32(pb, 0);
1616  ffio_wfourcc(pb, "av3c");
1617  mov_write_av3c(pb, track->extradata[track->last_stsd_index],
1618  track->extradata_size[track->last_stsd_index]);
1619  return update_size(pb, pos);
1620 }
1621 
1623 {
1624  int64_t pos = avio_tell(pb);
1625 
1626  avio_wb32(pb, 0);
1627  ffio_wfourcc(pb, "vpcC");
1628  ff_isom_write_vpcc(s, pb, track->extradata[track->last_stsd_index],
1629  track->extradata_size[track->last_stsd_index], track->par);
1630  return update_size(pb, pos);
1631 }
1632 
1634 {
1635  int64_t pos = avio_tell(pb);
1636 
1637  avio_wb32(pb, 0);
1638  ffio_wfourcc(pb, "hvcC");
1639  if (track->tag == MKTAG('h','v','c','1'))
1640  ff_isom_write_hvcc(pb, track->extradata[track->last_stsd_index],
1641  track->extradata_size[track->last_stsd_index], 1, s);
1642  else
1643  ff_isom_write_hvcc(pb, track->extradata[track->last_stsd_index],
1644  track->extradata_size[track->last_stsd_index], 0, s);
1645  return update_size(pb, pos);
1646 }
1647 
1649 {
1650  int64_t pos = avio_tell(pb);
1651  int ret;
1652 
1653  avio_wb32(pb, 0);
1654  ffio_wfourcc(pb, "lhvC");
1655  if (track->tag == MKTAG('h','v','c','1'))
1656  ret = ff_isom_write_lhvc(pb, track->extradata[track->last_stsd_index],
1657  track->extradata_size[track->last_stsd_index], 1, s);
1658  else
1659  ret = ff_isom_write_lhvc(pb, track->extradata[track->last_stsd_index],
1660  track->extradata_size[track->last_stsd_index], 0, s);
1661 
1662  if (ret < 0) {
1663  avio_seek(pb, pos, SEEK_SET);
1664  return ret;
1665  }
1666 
1667  return update_size(pb, pos);
1668 }
1669 
1670 static int mov_write_evcc_tag(AVIOContext *pb, MOVTrack *track)
1671 {
1672  int64_t pos = avio_tell(pb);
1673 
1674  avio_wb32(pb, 0);
1675  ffio_wfourcc(pb, "evcC");
1676 
1677  if (track->tag == MKTAG('e','v','c','1'))
1678  ff_isom_write_evcc(pb, track->extradata[track->last_stsd_index],
1679  track->extradata_size[track->last_stsd_index], 1);
1680  else
1681  ff_isom_write_evcc(pb, track->extradata[track->last_stsd_index],
1682  track->extradata_size[track->last_stsd_index], 0);
1683 
1684  return update_size(pb, pos);
1685 }
1686 
1687 static int mov_write_lvcc_tag(AVIOContext *pb, MOVTrack *track)
1688 {
1689  int64_t pos = avio_tell(pb);
1690 
1691  avio_wb32(pb, 0);
1692  ffio_wfourcc(pb, "lvcC");
1693 
1694  ff_isom_write_lvcc(pb, track->extradata[track->last_stsd_index],
1695  track->extradata_size[track->last_stsd_index]);
1696 
1697  return update_size(pb, pos);
1698 }
1699 
1700 static int mov_write_vvcc_tag(AVIOContext *pb, MOVTrack *track)
1701 {
1702  int64_t pos = avio_tell(pb);
1703 
1704  avio_wb32(pb, 0);
1705  ffio_wfourcc(pb, "vvcC");
1706 
1707  avio_w8 (pb, 0); /* version */
1708  avio_wb24(pb, 0); /* flags */
1709 
1710  if (track->tag == MKTAG('v','v','c','1'))
1711  ff_isom_write_vvcc(pb, track->extradata[track->last_stsd_index],
1712  track->extradata_size[track->last_stsd_index], 1);
1713  else
1714  ff_isom_write_vvcc(pb, track->extradata[track->last_stsd_index],
1715  track->extradata_size[track->last_stsd_index], 0);
1716  return update_size(pb, pos);
1717 }
1718 
1720 {
1721  int64_t pos = avio_tell(pb);
1722 
1723  avio_wb32(pb, 0);
1724  ffio_wfourcc(pb, "apvC");
1725 
1726  avio_w8 (pb, 0); /* version */
1727  avio_wb24(pb, 0); /* flags */
1728 
1729  ff_isom_write_apvc(pb, track->apv, s);
1730 
1731  return update_size(pb, pos);
1732 }
1733 
1734 /* also used by all avid codecs (dv, imx, meridien) and their variants */
1735 /* https://community.avid.com/forums/t/136517.aspx */
1736 static int mov_write_avid_tag(AVIOContext *pb, MOVTrack *track)
1737 {
1738  int interlaced;
1739  int cid;
1740  int display_width = track->par->width;
1741  const uint8_t *extradata;
1742 
1743  if (track->extradata[track->last_stsd_index] && track->extradata_size[track->last_stsd_index] > 0x29) {
1744  if (ff_dnxhd_parse_header_prefix(track->extradata[track->last_stsd_index]) != 0) {
1745  /* looks like a DNxHD bit stream */
1746  extradata = track->extradata[track->last_stsd_index];
1747  } else {
1748  av_log(NULL, AV_LOG_WARNING, "Could not locate DNxHD bit stream in vos_data\n");
1749  return 0;
1750  }
1751  } else {
1752  av_log(NULL, AV_LOG_WARNING, "Could not locate DNxHD bit stream, vos_data too small\n");
1753  return 0;
1754  }
1755 
1756  cid = AV_RB32(extradata + 0x28);
1757 
1758  avio_wb32(pb, 24); /* size */
1759  ffio_wfourcc(pb, "ACLR");
1760  ffio_wfourcc(pb, "ACLR");
1761  ffio_wfourcc(pb, "0001");
1762  // 1: CCIR (supercolors will be dropped, 16 will be displayed as black)
1763  // 2: FullRange (0 will be displayed as black, 16 will be displayed as dark grey)
1764  if (track->par->color_range == AVCOL_RANGE_MPEG || /* Legal range (16-235) */
1766  avio_wb32(pb, 1);
1767  } else {
1768  avio_wb32(pb, 2);
1769  }
1770  avio_wb32(pb, 0); /* reserved */
1771 
1772  if (track->tag == MKTAG('A','V','d','h')) {
1773  int alp = extradata[0x07] & 1;
1774  int pma = (extradata[0x07] >> 2) & 1;
1775  int sbd = (extradata[0x21] >> 5) & 3;
1776  int ssc = (extradata[0x2C] >> 5) & 3;
1777  int clv = (extradata[0x2C] >> 1) & 3;
1778  int clf = extradata[0x2C] & 1;
1779 
1780  avio_wb32(pb, 32);
1781  ffio_wfourcc(pb, "ADHR");
1782  ffio_wfourcc(pb, "0001");
1783  avio_wb32(pb, cid); // Compression ID
1784  // 0: 4:2:2 Sub Sampling
1785  // 1: 4:2:0 Sub Sampling
1786  // 2: 4:4:4 Sub Sampling
1787  avio_wb32(pb, ssc); // Sub Sampling Control
1788  // 1: 8-bits per sample
1789  // 2: 10-bits per sample
1790  // 3: 12-bits per sample
1791  avio_wb32(pb, sbd); // Sample Bit Depth
1792  // 0: Bitstream is encoded using the YCBCR format rules and tables
1793  // 1: Bitstream is encoded using the RGB format rules and tables – only Compression IDs 1256, 1270
1794  avio_wb16(pb, clf); // Color Format
1795  // 0: ITU-R BT.709
1796  // 1: ITU-R BT.2020
1797  // 2: ITU-R BT.2020 C
1798  // 3: Out-of-band
1799  avio_wb16(pb, clv); // Color Volume
1800  // 0: Alpha channel not present
1801  // 1: Alpha channel present
1802  avio_wb16(pb, alp); // Alpha Present
1803  // 0: Alpha has not been applied to video channels
1804  // 1: Alpha has been applied to the video channels prior to encoding
1805  avio_wb16(pb, pma); // Pre-Multiplied Alpha
1806  return 0;
1807  }
1808 
1809  interlaced = extradata[5] & 2;
1810 
1811  avio_wb32(pb, 24); /* size */
1812  ffio_wfourcc(pb, "APRG");
1813  ffio_wfourcc(pb, "APRG");
1814  ffio_wfourcc(pb, "0001");
1815  // 1 for progressive or 2 for interlaced
1816  if (interlaced)
1817  avio_wb32(pb, 2);
1818  else
1819  avio_wb32(pb, 1);
1820  avio_wb32(pb, 0); /* reserved */
1821 
1822  avio_wb32(pb, 120); /* size */
1823  ffio_wfourcc(pb, "ARES");
1824  ffio_wfourcc(pb, "ARES");
1825  ffio_wfourcc(pb, "0001");
1826  avio_wb32(pb, cid); /* cid */
1827  if ( track->par->sample_aspect_ratio.num > 0
1828  && track->par->sample_aspect_ratio.den > 0)
1829  display_width = display_width * track->par->sample_aspect_ratio.num / track->par->sample_aspect_ratio.den;
1830  avio_wb32(pb, display_width); // field width
1831  if (interlaced) {
1832  avio_wb32(pb, track->par->height / 2); // field height
1833  avio_wb32(pb, 2); // num fields
1834  avio_wb32(pb, 0); // num black lines (must be 0)
1835  // 4: HD1080i
1836  // 5: HD1080P
1837  // 6: HD720P
1838  avio_wb32(pb, 4); // video format
1839  } else {
1840  avio_wb32(pb, track->par->height);
1841  avio_wb32(pb, 1); // num fields
1842  avio_wb32(pb, 0);
1843  if (track->par->height == 1080)
1844  avio_wb32(pb, 5);
1845  else
1846  avio_wb32(pb, 6);
1847  }
1848  /* padding */
1849  ffio_fill(pb, 0, 10 * 8);
1850 
1851  return 0;
1852 }
1853 
1854 static int mov_write_dpxe_tag(AVIOContext *pb, MOVTrack *track)
1855 {
1856  avio_wb32(pb, 12);
1857  ffio_wfourcc(pb, "DpxE");
1858  if (track->extradata_size[track->last_stsd_index] >= 12 &&
1859  !memcmp(&track->extradata[track->last_stsd_index][4], "DpxE", 4)) {
1860  avio_wb32(pb, track->extradata[track->last_stsd_index][11]);
1861  } else {
1862  avio_wb32(pb, 1);
1863  }
1864  return 0;
1865 }
1866 
1868 {
1869  int tag;
1870 
1871  if (track->par->width == 720) { /* SD */
1872  if (track->par->height == 480) { /* NTSC */
1873  if (track->par->format == AV_PIX_FMT_YUV422P) tag = MKTAG('d','v','5','n');
1874  else tag = MKTAG('d','v','c',' ');
1875  }else if (track->par->format == AV_PIX_FMT_YUV422P) tag = MKTAG('d','v','5','p');
1876  else if (track->par->format == AV_PIX_FMT_YUV420P) tag = MKTAG('d','v','c','p');
1877  else tag = MKTAG('d','v','p','p');
1878  } else if (track->par->height == 720) { /* HD 720 line */
1879  if (track->st->time_base.den == 50) tag = MKTAG('d','v','h','q');
1880  else tag = MKTAG('d','v','h','p');
1881  } else if (track->par->height == 1080) { /* HD 1080 line */
1882  if (track->st->time_base.den == 25) tag = MKTAG('d','v','h','5');
1883  else tag = MKTAG('d','v','h','6');
1884  } else {
1885  av_log(s, AV_LOG_ERROR, "unsupported height for dv codec\n");
1886  return 0;
1887  }
1888 
1889  return tag;
1890 }
1891 
1893 {
1894  AVRational rational_framerate = st->avg_frame_rate;
1895  int rate = 0;
1896  if (rational_framerate.den != 0)
1897  rate = av_q2d(rational_framerate);
1898  return rate;
1899 }
1900 
1902 {
1903  int tag = track->par->codec_tag;
1905  AVStream *st = track->st;
1906  int rate = defined_frame_rate(s, st);
1907 
1908  if (!tag)
1909  tag = MKTAG('m', '2', 'v', '1'); //fallback tag
1910 
1911  if (track->par->format == AV_PIX_FMT_YUV420P) {
1912  if (track->par->width == 1280 && track->par->height == 720) {
1913  if (!interlaced) {
1914  if (rate == 24) tag = MKTAG('x','d','v','4');
1915  else if (rate == 25) tag = MKTAG('x','d','v','5');
1916  else if (rate == 30) tag = MKTAG('x','d','v','1');
1917  else if (rate == 50) tag = MKTAG('x','d','v','a');
1918  else if (rate == 60) tag = MKTAG('x','d','v','9');
1919  }
1920  } else if (track->par->width == 1440 && track->par->height == 1080) {
1921  if (!interlaced) {
1922  if (rate == 24) tag = MKTAG('x','d','v','6');
1923  else if (rate == 25) tag = MKTAG('x','d','v','7');
1924  else if (rate == 30) tag = MKTAG('x','d','v','8');
1925  } else {
1926  if (rate == 25) tag = MKTAG('x','d','v','3');
1927  else if (rate == 30) tag = MKTAG('x','d','v','2');
1928  }
1929  } else if (track->par->width == 1920 && track->par->height == 1080) {
1930  if (!interlaced) {
1931  if (rate == 24) tag = MKTAG('x','d','v','d');
1932  else if (rate == 25) tag = MKTAG('x','d','v','e');
1933  else if (rate == 30) tag = MKTAG('x','d','v','f');
1934  } else {
1935  if (rate == 25) tag = MKTAG('x','d','v','c');
1936  else if (rate == 30) tag = MKTAG('x','d','v','b');
1937  }
1938  }
1939  } else if (track->par->format == AV_PIX_FMT_YUV422P) {
1940  if (track->par->width == 1280 && track->par->height == 720) {
1941  if (!interlaced) {
1942  if (rate == 24) tag = MKTAG('x','d','5','4');
1943  else if (rate == 25) tag = MKTAG('x','d','5','5');
1944  else if (rate == 30) tag = MKTAG('x','d','5','1');
1945  else if (rate == 50) tag = MKTAG('x','d','5','a');
1946  else if (rate == 60) tag = MKTAG('x','d','5','9');
1947  }
1948  } else if (track->par->width == 1920 && track->par->height == 1080) {
1949  if (!interlaced) {
1950  if (rate == 24) tag = MKTAG('x','d','5','d');
1951  else if (rate == 25) tag = MKTAG('x','d','5','e');
1952  else if (rate == 30) tag = MKTAG('x','d','5','f');
1953  } else {
1954  if (rate == 25) tag = MKTAG('x','d','5','c');
1955  else if (rate == 30) tag = MKTAG('x','d','5','b');
1956  }
1957  }
1958  }
1959 
1960  return tag;
1961 }
1962 
1964 {
1965  int tag = track->par->codec_tag;
1967  AVStream *st = track->st;
1968  int rate = defined_frame_rate(s, st);
1969 
1970  if (!tag)
1971  tag = MKTAG('a', 'v', 'c', 'i'); //fallback tag
1972 
1973  if (track->par->profile == AV_PROFILE_UNKNOWN ||
1974  !(track->par->profile & AV_PROFILE_H264_INTRA))
1975  return tag;
1976 
1977  if (track->par->format == AV_PIX_FMT_YUV420P10) {
1978  if (track->par->width == 960 && track->par->height == 720) {
1979  if (!interlaced) {
1980  if (rate == 24) tag = MKTAG('a','i','5','p');
1981  else if (rate == 25) tag = MKTAG('a','i','5','q');
1982  else if (rate == 30) tag = MKTAG('a','i','5','p');
1983  else if (rate == 50) tag = MKTAG('a','i','5','q');
1984  else if (rate == 60) tag = MKTAG('a','i','5','p');
1985  }
1986  } else if (track->par->width == 1440 && track->par->height == 1080) {
1987  if (!interlaced) {
1988  if (rate == 24) tag = MKTAG('a','i','5','3');
1989  else if (rate == 25) tag = MKTAG('a','i','5','2');
1990  else if (rate == 30) tag = MKTAG('a','i','5','3');
1991  } else {
1992  if (rate == 50) tag = MKTAG('a','i','5','5');
1993  else if (rate == 60) tag = MKTAG('a','i','5','6');
1994  }
1995  }
1996  } else if (track->par->format == AV_PIX_FMT_YUV422P10) {
1997  if (track->par->width == 1280 && track->par->height == 720) {
1998  if (!interlaced) {
1999  if (rate == 24) tag = MKTAG('a','i','1','p');
2000  else if (rate == 25) tag = MKTAG('a','i','1','q');
2001  else if (rate == 30) tag = MKTAG('a','i','1','p');
2002  else if (rate == 50) tag = MKTAG('a','i','1','q');
2003  else if (rate == 60) tag = MKTAG('a','i','1','p');
2004  }
2005  } else if (track->par->width == 1920 && track->par->height == 1080) {
2006  if (!interlaced) {
2007  if (rate == 24) tag = MKTAG('a','i','1','3');
2008  else if (rate == 25) tag = MKTAG('a','i','1','2');
2009  else if (rate == 30) tag = MKTAG('a','i','1','3');
2010  } else {
2011  if (rate == 25) tag = MKTAG('a','i','1','5');
2012  else if (rate == 50) tag = MKTAG('a','i','1','5');
2013  else if (rate == 60) tag = MKTAG('a','i','1','6');
2014  }
2015  } else if ( track->par->width == 4096 && track->par->height == 2160
2016  || track->par->width == 3840 && track->par->height == 2160
2017  || track->par->width == 2048 && track->par->height == 1080) {
2018  tag = MKTAG('a','i','v','x');
2019  }
2020  }
2021 
2022  return tag;
2023 }
2024 
2026 {
2027  int tag = track->par->codec_tag;
2028 
2029  if (!tag)
2030  tag = MKTAG('e', 'v', 'c', '1');
2031 
2032  return tag;
2033 }
2034 
2036 {
2037  int tag = track->par->codec_tag;
2038 
2039  if (!tag)
2040  tag = MKTAG('a', 'p', 'v', '1');
2041 
2042  return tag;
2043 }
2044 
2045 
2046 static const struct {
2048  uint32_t tag;
2049  unsigned bps;
2050 } mov_pix_fmt_tags[] = {
2051  { AV_PIX_FMT_YUYV422, MKTAG('y','u','v','2'), 0 },
2052  { AV_PIX_FMT_YUYV422, MKTAG('y','u','v','s'), 0 },
2053  { AV_PIX_FMT_UYVY422, MKTAG('2','v','u','y'), 0 },
2054  { AV_PIX_FMT_VYU444, MKTAG('v','3','0','8'), 0 },
2055  { AV_PIX_FMT_UYVA, MKTAG('v','4','0','8'), 0 },
2056  { AV_PIX_FMT_V30XLE, MKTAG('v','4','1','0'), 0 },
2057  { AV_PIX_FMT_RGB555BE,MKTAG('r','a','w',' '), 16 },
2058  { AV_PIX_FMT_RGB555LE,MKTAG('L','5','5','5'), 16 },
2059  { AV_PIX_FMT_RGB565LE,MKTAG('L','5','6','5'), 16 },
2060  { AV_PIX_FMT_RGB565BE,MKTAG('B','5','6','5'), 16 },
2061  { AV_PIX_FMT_GRAY16BE,MKTAG('b','1','6','g'), 16 },
2062  { AV_PIX_FMT_RGB24, MKTAG('r','a','w',' '), 24 },
2063  { AV_PIX_FMT_BGR24, MKTAG('2','4','B','G'), 24 },
2064  { AV_PIX_FMT_ARGB, MKTAG('r','a','w',' '), 32 },
2065  { AV_PIX_FMT_BGRA, MKTAG('B','G','R','A'), 32 },
2066  { AV_PIX_FMT_RGBA, MKTAG('R','G','B','A'), 32 },
2067  { AV_PIX_FMT_ABGR, MKTAG('A','B','G','R'), 32 },
2068  { AV_PIX_FMT_RGB48BE, MKTAG('b','4','8','r'), 48 },
2069 };
2070 
2072 {
2073  int tag = MKTAG('A','V','d','n');
2074  if (track->par->profile != AV_PROFILE_UNKNOWN &&
2075  track->par->profile != AV_PROFILE_DNXHD)
2076  tag = MKTAG('A','V','d','h');
2077  return tag;
2078 }
2079 
2081 {
2082  int tag = track->par->codec_tag;
2083  int i;
2084  enum AVPixelFormat pix_fmt;
2085 
2086  for (i = 0; i < FF_ARRAY_ELEMS(mov_pix_fmt_tags); i++) {
2087  if (track->par->format == mov_pix_fmt_tags[i].pix_fmt) {
2088  tag = mov_pix_fmt_tags[i].tag;
2090  if (track->par->codec_tag == mov_pix_fmt_tags[i].tag)
2091  break;
2092  }
2093  }
2094 
2096  track->par->bits_per_coded_sample);
2097  if (tag == MKTAG('r','a','w',' ') &&
2098  track->par->format != pix_fmt &&
2099  track->par->format != AV_PIX_FMT_GRAY8 &&
2100  track->par->format != AV_PIX_FMT_NONE)
2101  av_log(s, AV_LOG_ERROR, "%s rawvideo cannot be written to mov, output file will be unreadable\n",
2102  av_get_pix_fmt_name(track->par->format));
2103  return tag;
2104 }
2105 
2106 static unsigned int mov_get_codec_tag(AVFormatContext *s, MOVTrack *track)
2107 {
2108  unsigned int tag = track->par->codec_tag;
2109 
2110  // "rtp " is used to distinguish internally created RTP-hint tracks
2111  // (with rtp_ctx) from other tracks.
2112  if (tag == MKTAG('r','t','p',' '))
2113  tag = 0;
2114  if (!tag || (s->strict_std_compliance >= FF_COMPLIANCE_NORMAL &&
2115  (track->par->codec_id == AV_CODEC_ID_DVVIDEO ||
2116  track->par->codec_id == AV_CODEC_ID_RAWVIDEO ||
2117  track->par->codec_id == AV_CODEC_ID_H263 ||
2118  track->par->codec_id == AV_CODEC_ID_H264 ||
2119  track->par->codec_id == AV_CODEC_ID_DNXHD ||
2120  track->par->codec_id == AV_CODEC_ID_MPEG2VIDEO ||
2121  av_get_bits_per_sample(track->par->codec_id)))) { // pcm audio
2122  if (track->par->codec_id == AV_CODEC_ID_DVVIDEO)
2123  tag = mov_get_dv_codec_tag(s, track);
2124  else if (track->par->codec_id == AV_CODEC_ID_RAWVIDEO)
2125  tag = mov_get_rawvideo_codec_tag(s, track);
2126  else if (track->par->codec_id == AV_CODEC_ID_MPEG2VIDEO)
2128  else if (track->par->codec_id == AV_CODEC_ID_H264)
2129  tag = mov_get_h264_codec_tag(s, track);
2130  else if (track->par->codec_id == AV_CODEC_ID_EVC)
2131  tag = mov_get_evc_codec_tag(s, track);
2132  else if (track->par->codec_id == AV_CODEC_ID_APV)
2133  tag = mov_get_apv_codec_tag(s, track);
2134  else if (track->par->codec_id == AV_CODEC_ID_DNXHD)
2135  tag = mov_get_dnxhd_codec_tag(s, track);
2136  else if (track->par->codec_type == AVMEDIA_TYPE_VIDEO) {
2138  if (!tag) { // if no mac fcc found, try with Microsoft tags
2140  if (tag)
2141  av_log(s, AV_LOG_WARNING, "Using MS style video codec tag, "
2142  "the file may be unplayable!\n");
2143  }
2144  } else if (track->par->codec_type == AVMEDIA_TYPE_AUDIO) {
2146  if (!tag) { // if no mac fcc found, try with Microsoft tags
2147  int ms_tag = ff_codec_get_tag(ff_codec_wav_tags, track->par->codec_id);
2148  if (ms_tag) {
2149  tag = MKTAG('m', 's', ((ms_tag >> 8) & 0xff), (ms_tag & 0xff));
2150  av_log(s, AV_LOG_WARNING, "Using MS style audio codec tag, "
2151  "the file may be unplayable!\n");
2152  }
2153  }
2154  } else if (track->par->codec_type == AVMEDIA_TYPE_SUBTITLE)
2156  }
2157 
2158  return tag;
2159 }
2160 
2162  { AV_CODEC_ID_MJPEG, 0xD },
2163  { AV_CODEC_ID_PNG, 0xE },
2164  { AV_CODEC_ID_BMP, 0x1B },
2165  { AV_CODEC_ID_NONE, 0 },
2166 };
2167 
2168 static unsigned int validate_codec_tag(const AVCodecTag *const *tags,
2169  unsigned int tag, int codec_id)
2170 {
2171  int i;
2172 
2173  /**
2174  * Check that tag + id is in the table
2175  */
2176  for (i = 0; tags && tags[i]; i++) {
2177  const AVCodecTag *codec_tags = tags[i];
2178  while (codec_tags->id != AV_CODEC_ID_NONE) {
2179  if (ff_toupper4(codec_tags->tag) == ff_toupper4(tag) &&
2180  codec_tags->id == codec_id)
2181  return codec_tags->tag;
2182  codec_tags++;
2183  }
2184  }
2185  return 0;
2186 }
2187 
2188 static unsigned int mov_find_codec_tag(AVFormatContext *s, MOVTrack *track)
2189 {
2190  if (is_cover_image(track->st))
2192 
2193  if (track->mode == MODE_IPOD)
2194  if (!av_match_ext(s->url, "m4a") &&
2195  !av_match_ext(s->url, "m4v") &&
2196  !av_match_ext(s->url, "m4b"))
2197  av_log(s, AV_LOG_WARNING, "Warning, extension is not .m4a nor .m4v "
2198  "Quicktime/Ipod might not play the file\n");
2199 
2200  if (track->mode == MODE_MOV) {
2201  return mov_get_codec_tag(s, track);
2202  } else
2203  return validate_codec_tag(s->oformat->codec_tag, track->par->codec_tag,
2204  track->par->codec_id);
2205 }
2206 
2207 /** Write uuid atom.
2208  * Needed to make file play in iPods running newest firmware
2209  * goes after avcC atom in moov.trak.mdia.minf.stbl.stsd.avc1
2210  */
2212 {
2213  avio_wb32(pb, 28);
2214  ffio_wfourcc(pb, "uuid");
2215  avio_wb32(pb, 0x6b6840f2);
2216  avio_wb32(pb, 0x5f244fc5);
2217  avio_wb32(pb, 0xba39a51b);
2218  avio_wb32(pb, 0xcf0323f3);
2219  avio_wb32(pb, 0x0);
2220  return 28;
2221 }
2222 
2223 static const uint16_t fiel_data[] = {
2224  0x0000, 0x0100, 0x0201, 0x0206, 0x0209, 0x020e
2225 };
2226 
2227 static int mov_write_fiel_tag(AVIOContext *pb, MOVTrack *track, int field_order)
2228 {
2229  unsigned mov_field_order = 0;
2230  if (field_order < FF_ARRAY_ELEMS(fiel_data))
2231  mov_field_order = fiel_data[field_order];
2232  else
2233  return 0;
2234  avio_wb32(pb, 10);
2235  ffio_wfourcc(pb, "fiel");
2236  avio_wb16(pb, mov_field_order);
2237  return 10;
2238 }
2239 
2241 {
2242  MOVMuxContext *mov = s->priv_data;
2243  int ret = AVERROR_BUG;
2244  int64_t pos = avio_tell(pb);
2245  avio_wb32(pb, 0); /* size */
2246  avio_wl32(pb, track->tag); // store it byteswapped
2247  avio_wb32(pb, 0); /* Reserved */
2248  avio_wb16(pb, 0); /* Reserved */
2249  avio_wb16(pb, 1); /* Data-reference index */
2250 
2251  if (track->par->codec_id == AV_CODEC_ID_DVD_SUBTITLE)
2252  mov_write_esds_tag(pb, track);
2253  else if (track->par->codec_id == AV_CODEC_ID_TTML) {
2254  switch (track->par->codec_tag) {
2255  case MOV_ISMV_TTML_TAG:
2256  // ISMV dfxp requires no extradata.
2257  break;
2258  case MOV_MP4_TTML_TAG:
2259  // As specified in 14496-30, XMLSubtitleSampleEntry
2260  // Namespace
2261  avio_put_str(pb, "http://www.w3.org/ns/ttml");
2262  // Empty schema_location
2263  avio_w8(pb, 0);
2264  // Empty auxiliary_mime_types
2265  avio_w8(pb, 0);
2266  break;
2267  default:
2269  "Unknown codec tag '%s' utilized for TTML stream with "
2270  "index %d (track id %d)!\n",
2271  av_fourcc2str(track->par->codec_tag), track->st->index,
2272  track->track_id);
2273  return AVERROR(EINVAL);
2274  }
2275  } else if (track->extradata_size[track->last_stsd_index])
2276  avio_write(pb, track->extradata[track->last_stsd_index], track->extradata_size[track->last_stsd_index]);
2277 
2278  if (mov->write_btrt &&
2279  ((ret = mov_write_btrt_tag(pb, track)) < 0))
2280  return ret;
2281 
2282  return update_size(pb, pos);
2283 }
2284 
2286 {
2287  int8_t stereo_mode;
2288 
2289  if (stereo_3d->flags != 0) {
2290  av_log(s, AV_LOG_WARNING, "Unsupported stereo_3d flags %x. st3d not written.\n", stereo_3d->flags);
2291  return 0;
2292  }
2293 
2294  switch (stereo_3d->type) {
2295  case AV_STEREO3D_2D:
2296  stereo_mode = 0;
2297  break;
2298  case AV_STEREO3D_TOPBOTTOM:
2299  stereo_mode = 1;
2300  break;
2302  stereo_mode = 2;
2303  break;
2304  default:
2305  av_log(s, AV_LOG_WARNING, "Unsupported stereo_3d type %s. st3d not written.\n", av_stereo3d_type_name(stereo_3d->type));
2306  return 0;
2307  }
2308  avio_wb32(pb, 13); /* size */
2309  ffio_wfourcc(pb, "st3d");
2310  avio_wb32(pb, 0); /* version = 0 & flags = 0 */
2311  avio_w8(pb, stereo_mode);
2312  return 13;
2313 }
2314 
2316 {
2317  int64_t sv3d_pos, svhd_pos, proj_pos;
2318  const char* metadata_source = s->flags & AVFMT_FLAG_BITEXACT ? "Lavf" : LIBAVFORMAT_IDENT;
2319 
2320  if (spherical_mapping->projection != AV_SPHERICAL_EQUIRECTANGULAR &&
2321  spherical_mapping->projection != AV_SPHERICAL_EQUIRECTANGULAR_TILE &&
2322  spherical_mapping->projection != AV_SPHERICAL_CUBEMAP) {
2323  av_log(s, AV_LOG_WARNING, "Unsupported projection %d. sv3d not written.\n", spherical_mapping->projection);
2324  return 0;
2325  }
2326 
2327  sv3d_pos = avio_tell(pb);
2328  avio_wb32(pb, 0); /* size */
2329  ffio_wfourcc(pb, "sv3d");
2330 
2331  svhd_pos = avio_tell(pb);
2332  avio_wb32(pb, 0); /* size */
2333  ffio_wfourcc(pb, "svhd");
2334  avio_wb32(pb, 0); /* version = 0 & flags = 0 */
2335  avio_put_str(pb, metadata_source);
2336  update_size(pb, svhd_pos);
2337 
2338  proj_pos = avio_tell(pb);
2339  avio_wb32(pb, 0); /* size */
2340  ffio_wfourcc(pb, "proj");
2341 
2342  avio_wb32(pb, 24); /* size */
2343  ffio_wfourcc(pb, "prhd");
2344  avio_wb32(pb, 0); /* version = 0 & flags = 0 */
2345  avio_wb32(pb, spherical_mapping->yaw);
2346  avio_wb32(pb, spherical_mapping->pitch);
2347  avio_wb32(pb, spherical_mapping->roll);
2348 
2349  switch (spherical_mapping->projection) {
2352  avio_wb32(pb, 28); /* size */
2353  ffio_wfourcc(pb, "equi");
2354  avio_wb32(pb, 0); /* version = 0 & flags = 0 */
2355  avio_wb32(pb, spherical_mapping->bound_top);
2356  avio_wb32(pb, spherical_mapping->bound_bottom);
2357  avio_wb32(pb, spherical_mapping->bound_left);
2358  avio_wb32(pb, spherical_mapping->bound_right);
2359  break;
2360  case AV_SPHERICAL_CUBEMAP:
2361  avio_wb32(pb, 20); /* size */
2362  ffio_wfourcc(pb, "cbmp");
2363  avio_wb32(pb, 0); /* version = 0 & flags = 0 */
2364  avio_wb32(pb, 0); /* layout */
2365  avio_wb32(pb, spherical_mapping->padding); /* padding */
2366  break;
2367  }
2368  update_size(pb, proj_pos);
2369 
2370  return update_size(pb, sv3d_pos);
2371 }
2372 
2373 static inline int64_t rescale_rational(AVRational q, int b)
2374 {
2375  return av_rescale(q.num, b, q.den);
2376 }
2377 
2379  const AVStereo3D *stereo3d)
2380 {
2381  if (!stereo3d->horizontal_field_of_view.num)
2382  return;
2383 
2384  avio_wb32(pb, 12); /* size */
2385  ffio_wfourcc(pb, "hfov");
2386  avio_wb32(pb, rescale_rational(stereo3d->horizontal_field_of_view, 1000));
2387 }
2388 
2390  const AVSphericalMapping *spherical_mapping)
2391 {
2392  avio_wb32(pb, 24); /* size */
2393  ffio_wfourcc(pb, "proj");
2394  avio_wb32(pb, 16); /* size */
2395  ffio_wfourcc(pb, "prji");
2396  avio_wb32(pb, 0); /* version + flags */
2397 
2398  switch (spherical_mapping->projection) {
2400  ffio_wfourcc(pb, "rect");
2401  break;
2403  ffio_wfourcc(pb, "equi");
2404  break;
2406  ffio_wfourcc(pb, "hequ");
2407  break;
2408  case AV_SPHERICAL_FISHEYE:
2409  ffio_wfourcc(pb, "fish");
2410  break;
2411  default:
2412  av_assert0(0);
2413  }
2414 }
2415 
2417  const AVStereo3D *stereo3d)
2418 {
2419  int64_t pos = avio_tell(pb);
2420  int view = 0;
2421 
2422  avio_wb32(pb, 0); /* size */
2423  ffio_wfourcc(pb, "eyes");
2424 
2425  // stri is mandatory
2426  avio_wb32(pb, 13); /* size */
2427  ffio_wfourcc(pb, "stri");
2428  avio_wb32(pb, 0); /* version + flags */
2429  switch (stereo3d->view) {
2430  case AV_STEREO3D_VIEW_LEFT:
2431  view |= 1 << 0;
2432  break;
2434  view |= 1 << 1;
2435  break;
2437  view |= (1 << 0) | (1 << 1);
2438  break;
2439  }
2440  view |= !!(stereo3d->flags & AV_STEREO3D_FLAG_INVERT) << 3;
2441  avio_w8(pb, view);
2442 
2443  // hero is optional
2444  if (stereo3d->primary_eye != AV_PRIMARY_EYE_NONE) {
2445  avio_wb32(pb, 13); /* size */
2446  ffio_wfourcc(pb, "hero");
2447  avio_wb32(pb, 0); /* version + flags */
2448  avio_w8(pb, stereo3d->primary_eye);
2449  }
2450 
2451  // it's not clear if cams is mandatory or optional
2452  if (stereo3d->baseline) {
2453  avio_wb32(pb, 24); /* size */
2454  ffio_wfourcc(pb, "cams");
2455  avio_wb32(pb, 16); /* size */
2456  ffio_wfourcc(pb, "blin");
2457  avio_wb32(pb, 0); /* version + flags */
2458  avio_wb32(pb, stereo3d->baseline);
2459  }
2460 
2461  // it's not clear if cmfy is mandatory or optional
2462  if (stereo3d->horizontal_disparity_adjustment.num) {
2463  avio_wb32(pb, 24); /* size */
2464  ffio_wfourcc(pb, "cmfy");
2465  avio_wb32(pb, 16); /* size */
2466  ffio_wfourcc(pb, "dadj");
2467  avio_wb32(pb, 0); /* version + flags */
2469  }
2470 
2471  return update_size(pb, pos);
2472 }
2473 
2475  const AVStereo3D *stereo3d,
2476  const AVSphericalMapping *spherical_mapping)
2477 {
2478  int64_t pos;
2479 
2480  if (spherical_mapping &&
2481  spherical_mapping->projection != AV_SPHERICAL_RECTILINEAR &&
2482  spherical_mapping->projection != AV_SPHERICAL_EQUIRECTANGULAR &&
2483  spherical_mapping->projection != AV_SPHERICAL_HALF_EQUIRECTANGULAR &&
2484  spherical_mapping->projection != AV_SPHERICAL_FISHEYE) {
2485  av_log(s, AV_LOG_WARNING, "Unsupported projection %d. proj not written.\n",
2486  spherical_mapping->projection);
2487  spherical_mapping = NULL;
2488  }
2489 
2490  if (stereo3d && (stereo3d->type == AV_STEREO3D_2D ||
2491  (!(stereo3d->flags & AV_STEREO3D_FLAG_INVERT) &&
2492  stereo3d->view == AV_STEREO3D_VIEW_UNSPEC &&
2493  stereo3d->primary_eye == AV_PRIMARY_EYE_NONE &&
2494  !stereo3d->baseline &&
2495  !stereo3d->horizontal_disparity_adjustment.num))) {
2496  av_log(s, AV_LOG_WARNING, "Unsupported stereo 3d metadata. eyes not written.\n");
2497  stereo3d = NULL;
2498  }
2499 
2500  if (!spherical_mapping && !stereo3d)
2501  return 0;
2502 
2503  pos = avio_tell(pb);
2504  avio_wb32(pb, 0); /* size */
2505  ffio_wfourcc(pb, "vexu");
2506 
2507  if (spherical_mapping)
2508  mov_write_vexu_proj_tag(s, pb, spherical_mapping);
2509 
2510  if (stereo3d)
2511  mov_write_eyes_tag(s, pb, stereo3d);
2512 
2513  return update_size(pb, pos);
2514 }
2515 
2517 {
2518  uint8_t buf[ISOM_DVCC_DVVC_SIZE];
2519 
2520  avio_wb32(pb, 32); /* size = 8 + 24 */
2521  if (dovi->dv_profile > 10)
2522  ffio_wfourcc(pb, "dvwC");
2523  else if (dovi->dv_profile > 7)
2524  ffio_wfourcc(pb, "dvvC");
2525  else
2526  ffio_wfourcc(pb, "dvcC");
2527 
2528  ff_isom_put_dvcc_dvvc(s, buf, dovi);
2529  avio_write(pb, buf, sizeof(buf));
2530 
2531  return 32; /* 8 + 24 */
2532 }
2533 
2534 static int mov_write_clap_tag(AVIOContext *pb, MOVTrack *track,
2535  uint32_t top, uint32_t bottom,
2536  uint32_t left, uint32_t right)
2537 {
2538  uint32_t cropped_width = track->par->width - left - right;
2539  uint32_t cropped_height = track->height - top - bottom;
2540  AVRational horizOff =
2541  av_sub_q((AVRational) { track->par->width - cropped_width, 2 },
2542  (AVRational) { left, 1 });
2543  AVRational vertOff =
2544  av_sub_q((AVRational) { track->height - cropped_height, 2 },
2545  (AVRational) { top, 1 });
2546 
2547  avio_wb32(pb, 40);
2548  ffio_wfourcc(pb, "clap");
2549  avio_wb32(pb, cropped_width); /* apertureWidthN */
2550  avio_wb32(pb, 1); /* apertureWidthD */
2551  avio_wb32(pb, cropped_height); /* apertureHeightN */
2552  avio_wb32(pb, 1); /* apertureHeightD */
2553 
2554  avio_wb32(pb, -horizOff.num);
2555  avio_wb32(pb, horizOff.den);
2556  avio_wb32(pb, -vertOff.num);
2557  avio_wb32(pb, vertOff.den);
2558 
2559  return 40;
2560 }
2561 
2562 static int mov_write_pasp_tag(AVIOContext *pb, MOVTrack *track)
2563 {
2564  AVRational sar;
2565  av_reduce(&sar.num, &sar.den, track->par->sample_aspect_ratio.num,
2566  track->par->sample_aspect_ratio.den, INT_MAX);
2567 
2568  avio_wb32(pb, 16);
2569  ffio_wfourcc(pb, "pasp");
2570  avio_wb32(pb, sar.num);
2571  avio_wb32(pb, sar.den);
2572  return 16;
2573 }
2574 
2575 static int mov_write_gama_tag(AVFormatContext *s, AVIOContext *pb, MOVTrack *track, double gamma)
2576 {
2577  uint32_t gama = 0;
2578  if (gamma <= 0.0)
2579  gamma = av_csp_approximate_eotf_gamma(track->par->color_trc);
2580  av_log(s, AV_LOG_DEBUG, "gamma value %g\n", gamma);
2581 
2582  if (gamma > 1e-6) {
2583  gama = (uint32_t)lrint((double)(1<<16) * gamma);
2584  av_log(s, AV_LOG_DEBUG, "writing gama value %"PRId32"\n", gama);
2585 
2586  av_assert0(track->mode == MODE_MOV);
2587  avio_wb32(pb, 12);
2588  ffio_wfourcc(pb, "gama");
2589  avio_wb32(pb, gama);
2590  return 12;
2591  } else {
2592  av_log(s, AV_LOG_WARNING, "gamma value unknown, unable to write gama atom\n");
2593  }
2594  return 0;
2595 }
2596 
2597 static int mov_write_colr_tag(AVIOContext *pb, MOVTrack *track, int prefer_icc)
2598 {
2599  int64_t pos = avio_tell(pb);
2600 
2601  // Ref (MOV): https://developer.apple.com/library/mac/technotes/tn2162/_index.html#//apple_ref/doc/uid/DTS40013070-CH1-TNTAG9
2602  // Ref (MP4): ISO/IEC 14496-12:2012
2603 
2604  if (prefer_icc) {
2606  track->st->codecpar->nb_coded_side_data,
2608 
2609  if (sd) {
2610  avio_wb32(pb, 12 + sd->size);
2611  ffio_wfourcc(pb, "colr");
2612  ffio_wfourcc(pb, "prof");
2613  avio_write(pb, sd->data, sd->size);
2614  return 12 + sd->size;
2615  }
2616  else {
2617  av_log(NULL, AV_LOG_INFO, "no ICC profile found, will write nclx/nclc colour info instead\n");
2618  }
2619  }
2620 
2621  /* We should only ever be called for MOV, MP4 and AVIF. */
2622  av_assert0(track->mode == MODE_MOV || track->mode == MODE_MP4 ||
2623  track->mode == MODE_AVIF);
2624 
2625  avio_wb32(pb, 0); /* size */
2626  ffio_wfourcc(pb, "colr");
2627  if (track->mode == MODE_MP4 || track->mode == MODE_AVIF)
2628  ffio_wfourcc(pb, "nclx");
2629  else
2630  ffio_wfourcc(pb, "nclc");
2631  // Do not try to guess the color info if it is AVCOL_PRI_UNSPECIFIED.
2632  // e.g., Dolby Vision for Apple devices should be set to AVCOL_PRI_UNSPECIFIED. See
2633  // https://developer.apple.com/av-foundation/High-Dynamic-Range-Metadata-for-Apple-Devices.pdf
2634  avio_wb16(pb, track->par->color_primaries);
2635  avio_wb16(pb, track->par->color_trc);
2636  avio_wb16(pb, track->par->color_space);
2637  if (track->mode == MODE_MP4 || track->mode == MODE_AVIF) {
2638  int full_range = track->par->color_range == AVCOL_RANGE_JPEG;
2639  avio_w8(pb, full_range << 7);
2640  }
2641 
2642  return update_size(pb, pos);
2643 }
2644 
2645 static int mov_write_clli_tag(AVIOContext *pb, MOVTrack *track)
2646 {
2647  const AVPacketSideData *side_data;
2648  const AVContentLightMetadata *content_light_metadata;
2649 
2650  side_data = av_packet_side_data_get(track->st->codecpar->coded_side_data,
2651  track->st->codecpar->nb_coded_side_data,
2653  if (!side_data) {
2654  return 0;
2655  }
2656  content_light_metadata = (const AVContentLightMetadata*)side_data->data;
2657 
2658  avio_wb32(pb, 12); // size
2659  ffio_wfourcc(pb, "clli");
2660  avio_wb16(pb, content_light_metadata->MaxCLL);
2661  avio_wb16(pb, content_light_metadata->MaxFALL);
2662  return 12;
2663 }
2664 
2665 static int mov_write_mdcv_tag(AVIOContext *pb, MOVTrack *track)
2666 {
2667  const int chroma_den = 50000;
2668  const int luma_den = 10000;
2669  const AVPacketSideData *side_data;
2671 
2672  side_data = av_packet_side_data_get(track->st->codecpar->coded_side_data,
2673  track->st->codecpar->nb_coded_side_data,
2675  if (side_data)
2676  metadata = (const AVMasteringDisplayMetadata*)side_data->data;
2677  if (!metadata || !metadata->has_primaries || !metadata->has_luminance) {
2678  return 0;
2679  }
2680 
2681  avio_wb32(pb, 32); // size
2682  ffio_wfourcc(pb, "mdcv");
2683  avio_wb16(pb, rescale_rational(metadata->display_primaries[1][0], chroma_den));
2684  avio_wb16(pb, rescale_rational(metadata->display_primaries[1][1], chroma_den));
2685  avio_wb16(pb, rescale_rational(metadata->display_primaries[2][0], chroma_den));
2686  avio_wb16(pb, rescale_rational(metadata->display_primaries[2][1], chroma_den));
2687  avio_wb16(pb, rescale_rational(metadata->display_primaries[0][0], chroma_den));
2688  avio_wb16(pb, rescale_rational(metadata->display_primaries[0][1], chroma_den));
2689  avio_wb16(pb, rescale_rational(metadata->white_point[0], chroma_den));
2690  avio_wb16(pb, rescale_rational(metadata->white_point[1], chroma_den));
2691  avio_wb32(pb, rescale_rational(metadata->max_luminance, luma_den));
2692  avio_wb32(pb, rescale_rational(metadata->min_luminance, luma_den));
2693  return 32;
2694 }
2695 
2696 static int mov_write_amve_tag(AVIOContext *pb, MOVTrack *track)
2697 {
2698  const int illuminance_den = 10000;
2699  const int ambient_den = 50000;
2700  const AVPacketSideData *side_data;
2701  const AVAmbientViewingEnvironment *ambient;
2702 
2703 
2704  side_data = av_packet_side_data_get(track->st->codecpar->coded_side_data,
2705  track->st->codecpar->nb_coded_side_data,
2707 
2708  if (!side_data)
2709  return 0;
2710 
2711  ambient = (const AVAmbientViewingEnvironment*)side_data->data;
2712  if (!ambient || !ambient->ambient_illuminance.num)
2713  return 0;
2714 
2715  avio_wb32(pb, 16); // size
2716  ffio_wfourcc(pb, "amve");
2717  avio_wb32(pb, rescale_rational(ambient->ambient_illuminance, illuminance_den));
2718  avio_wb16(pb, rescale_rational(ambient->ambient_light_x, ambient_den));
2719  avio_wb16(pb, rescale_rational(ambient->ambient_light_y, ambient_den));
2720  return 16;
2721 }
2722 
2723 static void find_compressor(char * compressor_name, int len, MOVTrack *track)
2724 {
2725  AVDictionaryEntry *encoder;
2726  int xdcam_res = (track->par->width == 1280 && track->par->height == 720)
2727  || (track->par->width == 1440 && track->par->height == 1080)
2728  || (track->par->width == 1920 && track->par->height == 1080);
2729 
2730  if ((track->mode == MODE_AVIF ||
2731  track->mode == MODE_MOV ||
2732  track->mode == MODE_MP4) &&
2733  (encoder = av_dict_get(track->st->metadata, "encoder", NULL, 0))) {
2734  av_strlcpy(compressor_name, encoder->value, 32);
2735  } else if (track->par->codec_id == AV_CODEC_ID_MPEG2VIDEO && xdcam_res) {
2737  AVStream *st = track->st;
2738  int rate = defined_frame_rate(NULL, st);
2739  av_strlcatf(compressor_name, len, "XDCAM");
2740  if (track->par->format == AV_PIX_FMT_YUV422P) {
2741  av_strlcatf(compressor_name, len, " HD422");
2742  } else if(track->par->width == 1440) {
2743  av_strlcatf(compressor_name, len, " HD");
2744  } else
2745  av_strlcatf(compressor_name, len, " EX");
2746 
2747  av_strlcatf(compressor_name, len, " %d%c", track->par->height, interlaced ? 'i' : 'p');
2748 
2749  av_strlcatf(compressor_name, len, "%d", rate * (interlaced + 1));
2750  }
2751 }
2752 
2754 {
2755  int64_t pos = avio_tell(pb);
2756  // Write sane defaults:
2757  // all_ref_pics_intra = 0 : all samples can use any type of reference.
2758  // intra_pred_used = 1 : intra prediction may or may not be used.
2759  // max_ref_per_pic = 15 : reserved value to indicate that any number of
2760  // reference images can be used.
2761  uint8_t ccstValue = (0 << 7) | /* all_ref_pics_intra */
2762  (1 << 6) | /* intra_pred_used */
2763  (15 << 2); /* max_ref_per_pic */
2764  avio_wb32(pb, 0); /* size */
2765  ffio_wfourcc(pb, "ccst");
2766  avio_wb32(pb, 0); /* Version & flags */
2767  avio_w8(pb, ccstValue);
2768  avio_wb24(pb, 0); /* reserved */
2769  return update_size(pb, pos);
2770 }
2771 
2772 static int mov_write_aux_tag(AVIOContext *pb, const char *aux_type)
2773 {
2774  int64_t pos = avio_tell(pb);
2775  avio_wb32(pb, 0); /* size */
2776  ffio_wfourcc(pb, aux_type);
2777  avio_wb32(pb, 0); /* Version & flags */
2778  avio_write(pb, "urn:mpeg:mpegB:cicp:systems:auxiliary:alpha\0", 44);
2779  return update_size(pb, pos);
2780 }
2781 
2783 {
2784  int ret = AVERROR_BUG;
2785  int64_t pos = avio_tell(pb);
2786  const AVPacketSideData *sd;
2787  char compressor_name[32] = { 0 };
2788  int avid = 0;
2789 
2790  int uncompressed_ycbcr = ((track->par->codec_id == AV_CODEC_ID_RAWVIDEO && track->par->format == AV_PIX_FMT_UYVY422)
2791  || (track->par->codec_id == AV_CODEC_ID_RAWVIDEO && track->par->format == AV_PIX_FMT_YUYV422)
2792  || (track->par->codec_id == AV_CODEC_ID_RAWVIDEO && track->par->format == AV_PIX_FMT_VYU444)
2793  || (track->par->codec_id == AV_CODEC_ID_RAWVIDEO && track->par->format == AV_PIX_FMT_UYVA)
2794  || (track->par->codec_id == AV_CODEC_ID_RAWVIDEO && track->par->format == AV_PIX_FMT_V30XLE)
2796  || track->par->codec_id == AV_CODEC_ID_V308
2797  || track->par->codec_id == AV_CODEC_ID_V408
2798  || track->par->codec_id == AV_CODEC_ID_V410
2799 #endif
2800  || track->par->codec_id == AV_CODEC_ID_V210);
2801 
2802  avio_wb32(pb, 0); /* size */
2803  if (mov->encryption_scheme != MOV_ENC_NONE) {
2804  ffio_wfourcc(pb, "encv");
2805  } else {
2806  avio_wl32(pb, track->tag); // store it byteswapped
2807  }
2808  avio_wb32(pb, 0); /* Reserved */
2809  avio_wb16(pb, 0); /* Reserved */
2810  avio_wb16(pb, 1); /* Data-reference index */
2811 
2812  if (uncompressed_ycbcr) {
2813  avio_wb16(pb, 2); /* Codec stream version */
2814  } else {
2815  avio_wb16(pb, 0); /* Codec stream version */
2816  }
2817  avio_wb16(pb, 0); /* Codec stream revision (=0) */
2818  if (track->mode == MODE_MOV) {
2819  ffio_wfourcc(pb, "FFMP"); /* Vendor */
2820  if (track->par->codec_id == AV_CODEC_ID_RAWVIDEO || uncompressed_ycbcr) {
2821  avio_wb32(pb, 0); /* Temporal Quality */
2822  avio_wb32(pb, 0x400); /* Spatial Quality = lossless*/
2823  } else {
2824  avio_wb32(pb, 0x200); /* Temporal Quality = normal */
2825  avio_wb32(pb, 0x200); /* Spatial Quality = normal */
2826  }
2827  } else {
2828  ffio_fill(pb, 0, 3 * 4); /* Reserved */
2829  }
2830  avio_wb16(pb, track->par->width); /* Video width */
2831  avio_wb16(pb, track->height); /* Video height */
2832  avio_wb32(pb, 0x00480000); /* Horizontal resolution 72dpi */
2833  avio_wb32(pb, 0x00480000); /* Vertical resolution 72dpi */
2834  avio_wb32(pb, 0); /* Data size (= 0) */
2835  avio_wb16(pb, 1); /* Frame count (= 1) */
2836 
2837  find_compressor(compressor_name, 32, track);
2838  avio_w8(pb, strlen(compressor_name));
2839  avio_write(pb, compressor_name, 31);
2840 
2841  if (track->mode == MODE_MOV &&
2842  (track->par->codec_id == AV_CODEC_ID_V410 || track->par->codec_id == AV_CODEC_ID_V210))
2843  avio_wb16(pb, 0x18);
2844  else if (track->mode == MODE_MOV && track->par->bits_per_coded_sample)
2845  avio_wb16(pb, track->par->bits_per_coded_sample |
2846  (track->par->format == AV_PIX_FMT_GRAY8 ? 0x20 : 0));
2847  else
2848  avio_wb16(pb, 0x18); /* Reserved */
2849 
2850  if (track->mode == MODE_MOV && track->par->format == AV_PIX_FMT_PAL8) {
2851  int pal_size, i;
2852  avio_wb16(pb, 0); /* Color table ID */
2853  avio_wb32(pb, 0); /* Color table seed */
2854  avio_wb16(pb, 0x8000); /* Color table flags */
2855  if (track->par->bits_per_coded_sample < 0 || track->par->bits_per_coded_sample > 8)
2856  return AVERROR(EINVAL);
2857  pal_size = 1 << track->par->bits_per_coded_sample;
2858  avio_wb16(pb, pal_size - 1); /* Color table size (zero-relative) */
2859  for (i = 0; i < pal_size; i++) {
2860  uint32_t rgb = track->palette[i];
2861  uint16_t r = (rgb >> 16) & 0xff;
2862  uint16_t g = (rgb >> 8) & 0xff;
2863  uint16_t b = rgb & 0xff;
2864  avio_wb16(pb, 0);
2865  avio_wb16(pb, (r << 8) | r);
2866  avio_wb16(pb, (g << 8) | g);
2867  avio_wb16(pb, (b << 8) | b);
2868  }
2869  } else
2870  avio_wb16(pb, 0xffff); /* Reserved */
2871 
2872  if (track->tag == MKTAG('m','p','4','v'))
2873  mov_write_esds_tag(pb, track);
2874  else if (track->par->codec_id == AV_CODEC_ID_H263)
2875  mov_write_d263_tag(pb);
2876  else if (track->par->codec_id == AV_CODEC_ID_AVUI ||
2877  track->par->codec_id == AV_CODEC_ID_SVQ3) {
2878  mov_write_extradata_tag(pb, track);
2879  avio_wb32(pb, 0);
2880  } else if (track->par->codec_id == AV_CODEC_ID_DNXHD) {
2881  mov_write_avid_tag(pb, track);
2882  avid = 1;
2883  } else if (track->par->codec_id == AV_CODEC_ID_HEVC) {
2884  mov_write_hvcc_tag(mov->fc, pb, track);
2885  if (track->st->disposition & AV_DISPOSITION_MULTILAYER) {
2886  ret = mov_write_lhvc_tag(mov->fc, pb, track);
2887  if (ret < 0)
2888  av_log(mov->fc, AV_LOG_WARNING, "Not writing 'lhvC' atom for multilayer stream.\n");
2889  }
2890  } else if (track->par->codec_id == AV_CODEC_ID_VVC)
2891  mov_write_vvcc_tag(pb, track);
2892  else if (track->par->codec_id == AV_CODEC_ID_H264 && !TAG_IS_AVCI(track->tag)) {
2893  mov_write_avcc_tag(pb, track);
2894  if (track->mode == MODE_IPOD)
2896  }
2897  else if (track->par->codec_id ==AV_CODEC_ID_EVC) {
2898  mov_write_evcc_tag(pb, track);
2899  } else if (track->par->codec_id == AV_CODEC_ID_LCEVC) {
2900  mov_write_lvcc_tag(pb, track);
2901  } else if (track->par->codec_id ==AV_CODEC_ID_APV) {
2902  mov_write_apvc_tag(mov->fc, pb, track);
2903  } else if (track->par->codec_id == AV_CODEC_ID_VP9) {
2904  mov_write_vpcc_tag(mov->fc, pb, track);
2905  } else if (track->par->codec_id == AV_CODEC_ID_AV1) {
2906  mov_write_av1c_tag(pb, track);
2907  } else if (track->par->codec_id == AV_CODEC_ID_VC1 && track->extradata_size[track->last_stsd_index] > 0)
2908  mov_write_dvc1_tag(pb, track);
2909  else if (track->par->codec_id == AV_CODEC_ID_VP6F ||
2910  track->par->codec_id == AV_CODEC_ID_VP6A) {
2911  /* Don't write any potential extradata here - the cropping
2912  * is signalled via the normal width/height fields. */
2913  } else if (track->par->codec_id == AV_CODEC_ID_R10K) {
2914  if (track->par->codec_tag == MKTAG('R','1','0','k'))
2915  mov_write_dpxe_tag(pb, track);
2916  } else if (track->par->codec_id == AV_CODEC_ID_AVS3) {
2917  mov_write_av3c_tag(pb, track);
2918  } else if (track->extradata_size[track->last_stsd_index] > 0)
2919  mov_write_glbl_tag(pb, track);
2920 
2921  if (track->par->codec_id != AV_CODEC_ID_H264 &&
2922  track->par->codec_id != AV_CODEC_ID_MPEG4 &&
2923  track->par->codec_id != AV_CODEC_ID_DNXHD) {
2924  int field_order = track->par->field_order;
2925 
2926  if (field_order != AV_FIELD_UNKNOWN)
2927  mov_write_fiel_tag(pb, track, field_order);
2928  }
2929 
2930  if (mov->flags & FF_MOV_FLAG_WRITE_GAMA) {
2931  if (track->mode == MODE_MOV)
2932  mov_write_gama_tag(s, pb, track, mov->gamma);
2933  else
2934  av_log(mov->fc, AV_LOG_WARNING, "Not writing 'gama' atom. Format is not MOV.\n");
2935  }
2936  if (track->mode == MODE_MOV || track->mode == MODE_MP4 || track->mode == MODE_AVIF) {
2937  int has_color_info = track->par->color_primaries != AVCOL_PRI_UNSPECIFIED &&
2938  track->par->color_trc != AVCOL_TRC_UNSPECIFIED &&
2940  if (has_color_info || mov->flags & FF_MOV_FLAG_WRITE_COLR ||
2943  int prefer_icc = mov->flags & FF_MOV_FLAG_PREFER_ICC || !has_color_info;
2944  mov_write_colr_tag(pb, track, prefer_icc);
2945  }
2946  } else if (mov->flags & FF_MOV_FLAG_WRITE_COLR) {
2947  av_log(mov->fc, AV_LOG_WARNING, "Not writing 'colr' atom. Format is not MOV or MP4 or AVIF.\n");
2948  }
2949 
2950  if (track->mode == MODE_MOV || track->mode == MODE_MP4) {
2951  mov_write_clli_tag(pb, track);
2952  mov_write_mdcv_tag(pb, track);
2953  mov_write_amve_tag(pb, track);
2954  }
2955 
2956  if (track->mode == MODE_MP4 && mov->fc->strict_std_compliance <= FF_COMPLIANCE_UNOFFICIAL) {
2958  track->st->codecpar->nb_coded_side_data,
2960  const AVPacketSideData *spherical_mapping = av_packet_side_data_get(track->st->codecpar->coded_side_data,
2961  track->st->codecpar->nb_coded_side_data,
2963  if (stereo_3d)
2964  mov_write_st3d_tag(s, pb, (AVStereo3D*)stereo_3d->data);
2965  if (spherical_mapping)
2966  mov_write_sv3d_tag(mov->fc, pb, (AVSphericalMapping*)spherical_mapping->data);
2967  }
2968 
2969  if (track->mode == MODE_MOV || (track->mode == MODE_MP4 &&
2971  const AVStereo3D *stereo3d = NULL;
2972  const AVSphericalMapping *spherical_mapping = NULL;
2973 
2975  track->st->codecpar->nb_coded_side_data,
2977  if (sd)
2978  stereo3d = (AVStereo3D *)sd->data;
2979 
2981  track->st->codecpar->nb_coded_side_data,
2983  if (sd)
2984  spherical_mapping = (AVSphericalMapping *)sd->data;
2985 
2986  if (stereo3d || spherical_mapping)
2987  mov_write_vexu_tag(s, pb, stereo3d, spherical_mapping);
2988  if (stereo3d)
2989  mov_write_hfov_tag(s, pb, stereo3d);
2990  }
2991 
2992  if (track->mode == MODE_MP4) {
2994  track->st->codecpar->nb_coded_side_data,
2996  if (dovi && mov->fc->strict_std_compliance <= FF_COMPLIANCE_UNOFFICIAL) {
2998  } else if (dovi) {
2999  av_log(mov->fc, AV_LOG_WARNING, "Not writing 'dvcC'/'dvvC' box. Requires -strict unofficial.\n");
3000  }
3001  }
3002 
3003  if (track->par->sample_aspect_ratio.den && track->par->sample_aspect_ratio.num) {
3004  mov_write_pasp_tag(pb, track);
3005  }
3006 
3008  track->st->codecpar->nb_coded_side_data,
3010  if (sd && sd->size >= sizeof(uint32_t) * 4) {
3011  uint64_t top = AV_RL32(sd->data + 0);
3012  uint64_t bottom = AV_RL32(sd->data + 4);
3013  uint64_t left = AV_RL32(sd->data + 8);
3014  uint64_t right = AV_RL32(sd->data + 12);
3015 
3016  if ((left + right) >= track->par->width ||
3017  (top + bottom) >= track->height) {
3018  av_log(s, AV_LOG_ERROR, "Invalid cropping dimensions in stream side data\n");
3019  return AVERROR(EINVAL);
3020  }
3021  if (top || bottom || left || right)
3022  mov_write_clap_tag(pb, track, top, bottom, left, right);
3023  } else if (uncompressed_ycbcr)
3024  mov_write_clap_tag(pb, track, 0, 0, 0, 0);
3025 
3026  if (mov->encryption_scheme != MOV_ENC_NONE) {
3027  ff_mov_cenc_write_sinf_tag(track, pb, mov->encryption_kid);
3028  }
3029 
3030  if (mov->write_btrt &&
3031  ((ret = mov_write_btrt_tag(pb, track)) < 0))
3032  return ret;
3033 
3034  /* extra padding for avid stsd */
3035  /* https://developer.apple.com/library/mac/documentation/QuickTime/QTFF/QTFFChap2/qtff2.html#//apple_ref/doc/uid/TP40000939-CH204-61112 */
3036  if (avid)
3037  avio_wb32(pb, 0);
3038 
3039  if (track->mode == MODE_AVIF) {
3040  mov_write_ccst_tag(pb);
3041  if (mov->nb_streams > 0 && track == &mov->tracks[1])
3042  mov_write_aux_tag(pb, "auxi");
3043  }
3044 
3045  return update_size(pb, pos);
3046 }
3047 
3048 static int mov_write_rtp_tag(AVIOContext *pb, MOVTrack *track)
3049 {
3050  int64_t pos = avio_tell(pb);
3051  avio_wb32(pb, 0); /* size */
3052  ffio_wfourcc(pb, "rtp ");
3053  avio_wb32(pb, 0); /* Reserved */
3054  avio_wb16(pb, 0); /* Reserved */
3055  avio_wb16(pb, 1); /* Data-reference index */
3056 
3057  avio_wb16(pb, 1); /* Hint track version */
3058  avio_wb16(pb, 1); /* Highest compatible version */
3059  avio_wb32(pb, track->max_packet_size); /* Max packet size */
3060 
3061  avio_wb32(pb, 12); /* size */
3062  ffio_wfourcc(pb, "tims");
3063  avio_wb32(pb, track->timescale);
3064 
3065  return update_size(pb, pos);
3066 }
3067 
3068 static int mov_write_source_reference_tag(AVIOContext *pb, MOVTrack *track, const char *reel_name)
3069 {
3070  uint64_t str_size =strlen(reel_name);
3071  int64_t pos = avio_tell(pb);
3072 
3073  if (str_size >= UINT16_MAX){
3074  av_log(NULL, AV_LOG_ERROR, "reel_name length %"PRIu64" is too large\n", str_size);
3075  avio_wb16(pb, 0);
3076  return AVERROR(EINVAL);
3077  }
3078 
3079  avio_wb32(pb, 0); /* size */
3080  ffio_wfourcc(pb, "name"); /* Data format */
3081  avio_wb16(pb, str_size); /* string size */
3082  avio_wb16(pb, track->language); /* langcode */
3083  avio_write(pb, reel_name, str_size); /* reel name */
3084  return update_size(pb,pos);
3085 }
3086 
3087 static int mov_write_tmcd_tag(AVIOContext *pb, MOVTrack *track)
3088 {
3089  int64_t pos = avio_tell(pb);
3090 #if 1
3091  int frame_duration;
3092  int nb_frames;
3093  AVDictionaryEntry *t = NULL;
3094 
3095  if (!track->st->avg_frame_rate.num || !track->st->avg_frame_rate.den) {
3096  av_log(NULL, AV_LOG_ERROR, "avg_frame_rate not set for tmcd track.\n");
3097  return AVERROR(EINVAL);
3098  } else {
3099  frame_duration = av_rescale(track->timescale, track->st->avg_frame_rate.den, track->st->avg_frame_rate.num);
3100  nb_frames = ROUNDED_DIV(track->st->avg_frame_rate.num, track->st->avg_frame_rate.den);
3101  }
3102 
3103  if (nb_frames > 255) {
3104  av_log(NULL, AV_LOG_ERROR, "fps %d is too large\n", nb_frames);
3105  return AVERROR(EINVAL);
3106  }
3107 
3108  avio_wb32(pb, 0); /* size */
3109  ffio_wfourcc(pb, "tmcd"); /* Data format */
3110  avio_wb32(pb, 0); /* Reserved */
3111  avio_wb32(pb, 1); /* Data reference index */
3112  avio_wb32(pb, 0); /* Flags */
3113  avio_wb32(pb, track->timecode_flags); /* Flags (timecode) */
3114  avio_wb32(pb, track->timescale); /* Timescale */
3115  avio_wb32(pb, frame_duration); /* Frame duration */
3116  avio_w8(pb, nb_frames); /* Number of frames */
3117  avio_w8(pb, 0); /* Reserved */
3118 
3119  t = av_dict_get(track->st->metadata, "reel_name", NULL, 0);
3120  if (t && utf8len(t->value) && track->mode != MODE_MP4)
3121  mov_write_source_reference_tag(pb, track, t->value);
3122  else
3123  avio_wb16(pb, 0); /* zero size */
3124 #else
3125 
3126  avio_wb32(pb, 0); /* size */
3127  ffio_wfourcc(pb, "tmcd"); /* Data format */
3128  avio_wb32(pb, 0); /* Reserved */
3129  avio_wb32(pb, 1); /* Data reference index */
3130  if (track->par->extradata_size)
3131  avio_write(pb, track->par->extradata, track->par->extradata_size);
3132 #endif
3133  return update_size(pb, pos);
3134 }
3135 
3136 static int mov_write_gpmd_tag(AVIOContext *pb, const MOVTrack *track)
3137 {
3138  int64_t pos = avio_tell(pb);
3139  avio_wb32(pb, 0); /* size */
3140  ffio_wfourcc(pb, "gpmd");
3141  avio_wb32(pb, 0); /* Reserved */
3142  avio_wb16(pb, 0); /* Reserved */
3143  avio_wb16(pb, 1); /* Data-reference index */
3144  avio_wb32(pb, 0); /* Reserved */
3145  return update_size(pb, pos);
3146 }
3147 
3149 {
3150  int64_t pos = avio_tell(pb);
3151  int ret = 0;
3152  avio_wb32(pb, 0); /* size */
3153  ffio_wfourcc(pb, "stsd");
3154  avio_wb32(pb, 0); /* version & flags */
3155  avio_wb32(pb, track->stsd_count);
3156 
3157  int stsd_index_back = track->last_stsd_index;
3158  for (track->last_stsd_index = 0;
3159  track->last_stsd_index < track->stsd_count;
3160  track->last_stsd_index++) {
3161  if (track->par->codec_type == AVMEDIA_TYPE_VIDEO)
3162  ret = mov_write_video_tag(s, pb, mov, track);
3163  else if (track->par->codec_type == AVMEDIA_TYPE_AUDIO)
3164  ret = mov_write_audio_tag(s, pb, mov, track);
3165  else if (track->par->codec_type == AVMEDIA_TYPE_SUBTITLE)
3166  ret = mov_write_subtitle_tag(s, pb, track);
3167  else if (track->par->codec_tag == MKTAG('r','t','p',' '))
3168  ret = mov_write_rtp_tag(pb, track);
3169  else if (track->par->codec_tag == MKTAG('t','m','c','d'))
3170  ret = mov_write_tmcd_tag(pb, track);
3171  else if (track->par->codec_tag == MKTAG('g','p','m','d'))
3172  ret = mov_write_gpmd_tag(pb, track);
3173 
3174  if (ret < 0)
3175  return ret;
3176  }
3177 
3178  track->last_stsd_index = stsd_index_back;
3179 
3180  return update_size_and_version(pb, pos, track->entry_version);
3181 }
3182 
3184 {
3185  MOVMuxContext *mov = s->priv_data;
3186  MOVCtts *ctts_entries;
3187  uint32_t entries = 0;
3188  uint32_t atom_size;
3189  int i;
3190 
3191  ctts_entries = av_malloc_array((track->entry + 1), sizeof(*ctts_entries)); /* worst case */
3192  if (!ctts_entries)
3193  return AVERROR(ENOMEM);
3194  ctts_entries[0].count = 1;
3195  ctts_entries[0].offset = track->cluster[0].cts;
3196  for (i = 1; i < track->entry; i++) {
3197  if (track->cluster[i].cts == ctts_entries[entries].offset) {
3198  ctts_entries[entries].count++; /* compress */
3199  } else {
3200  entries++;
3201  ctts_entries[entries].offset = track->cluster[i].cts;
3202  ctts_entries[entries].count = 1;
3203  }
3204  }
3205  entries++; /* last one */
3206  atom_size = 16 + (entries * 8);
3207  avio_wb32(pb, atom_size); /* size */
3208  ffio_wfourcc(pb, "ctts");
3210  avio_w8(pb, 1); /* version */
3211  else
3212  avio_w8(pb, 0); /* version */
3213  avio_wb24(pb, 0); /* flags */
3214  avio_wb32(pb, entries); /* entry count */
3215  for (i = 0; i < entries; i++) {
3216  avio_wb32(pb, ctts_entries[i].count);
3217  avio_wb32(pb, ctts_entries[i].offset);
3218  }
3219  av_free(ctts_entries);
3220  return atom_size;
3221 }
3222 
3223 /* Time to sample atom */
3224 static int mov_write_stts_tag(AVIOContext *pb, MOVTrack *track)
3225 {
3226  MOVStts *stts_entries = NULL;
3227  uint32_t entries = -1;
3228  uint32_t atom_size;
3229  int i;
3230 
3231  if (track->par->codec_type == AVMEDIA_TYPE_AUDIO && !track->audio_vbr) {
3232  stts_entries = av_malloc(sizeof(*stts_entries)); /* one entry */
3233  if (!stts_entries)
3234  return AVERROR(ENOMEM);
3235  stts_entries[0].count = track->sample_count;
3236  stts_entries[0].duration = 1;
3237  entries = 1;
3238  } else {
3239  if (track->entry) {
3240  stts_entries = av_malloc_array(track->entry, sizeof(*stts_entries)); /* worst case */
3241  if (!stts_entries)
3242  return AVERROR(ENOMEM);
3243  }
3244  for (i = 0; i < track->entry; i++) {
3245  int duration = get_cluster_duration(track, i);
3246 #if CONFIG_IAMFENC
3247  if (track->iamf && track->par->codec_id == AV_CODEC_ID_OPUS)
3248  duration = av_rescale(duration, 48000, track->par->sample_rate);
3249 #endif
3250  if (i && duration == stts_entries[entries].duration) {
3251  stts_entries[entries].count++; /* compress */
3252  } else {
3253  entries++;
3254  stts_entries[entries].duration = duration;
3255  stts_entries[entries].count = 1;
3256  }
3257  }
3258  entries++; /* last one */
3259  }
3260  atom_size = 16 + (entries * 8);
3261  avio_wb32(pb, atom_size); /* size */
3262  ffio_wfourcc(pb, "stts");
3263  avio_wb32(pb, 0); /* version & flags */
3264  avio_wb32(pb, entries); /* entry count */
3265  for (i = 0; i < entries; i++) {
3266  avio_wb32(pb, stts_entries[i].count);
3267  avio_wb32(pb, stts_entries[i].duration);
3268  }
3269  av_free(stts_entries);
3270  return atom_size;
3271 }
3272 
3274 {
3275  avio_wb32(pb, 28); /* size */
3276  ffio_wfourcc(pb, "dref");
3277  avio_wb32(pb, 0); /* version & flags */
3278  avio_wb32(pb, 1); /* entry count */
3279 
3280  avio_wb32(pb, 0xc); /* size */
3281  //FIXME add the alis and rsrc atom
3282  ffio_wfourcc(pb, "url ");
3283  avio_wb32(pb, 1); /* version & flags */
3284 
3285  return 28;
3286 }
3287 
3289 {
3290  struct sgpd_entry {
3291  int count;
3292  int16_t roll_distance;
3293  int group_description_index;
3294  };
3295 
3296  struct sgpd_entry *sgpd_entries = NULL;
3297  int entries = -1;
3298  int group = 0;
3299  int i, j;
3300 
3301  const int OPUS_SEEK_PREROLL_MS = 80;
3302  int roll_samples = av_rescale_q(OPUS_SEEK_PREROLL_MS,
3303  (AVRational){1, 1000},
3304  (AVRational){1, 48000});
3305 
3306  if (!track->entry)
3307  return 0;
3308 
3309  sgpd_entries = av_malloc_array(track->entry, sizeof(*sgpd_entries));
3310  if (!sgpd_entries)
3311  return AVERROR(ENOMEM);
3312 
3314 
3315  if (track->par->codec_id == AV_CODEC_ID_OPUS) {
3316  for (i = 0; i < track->entry; i++) {
3317  int roll_samples_remaining = roll_samples;
3318  int distance = 0;
3319  for (j = i - 1; j >= 0; j--) {
3320  roll_samples_remaining -= get_cluster_duration(track, j);
3321  distance++;
3322  if (roll_samples_remaining <= 0)
3323  break;
3324  }
3325  /* We don't have enough preceding samples to compute a valid
3326  roll_distance here, so this sample can't be independently
3327  decoded. */
3328  if (roll_samples_remaining > 0)
3329  distance = 0;
3330  /* Verify distance is a maximum of 32 (2.5ms) packets. */
3331  if (distance > 32)
3332  return AVERROR_INVALIDDATA;
3333  if (i && distance == sgpd_entries[entries].roll_distance) {
3334  sgpd_entries[entries].count++;
3335  } else {
3336  entries++;
3337  sgpd_entries[entries].count = 1;
3338  sgpd_entries[entries].roll_distance = distance;
3339  sgpd_entries[entries].group_description_index = distance ? ++group : 0;
3340  }
3341  }
3342  } else {
3343  entries++;
3344  sgpd_entries[entries].count = track->sample_count;
3345  sgpd_entries[entries].roll_distance = 1;
3346  sgpd_entries[entries].group_description_index = ++group;
3347  }
3348  entries++;
3349 
3350  if (!group) {
3351  av_free(sgpd_entries);
3352  return 0;
3353  }
3354 
3355  /* Write sgpd tag */
3356  avio_wb32(pb, 24 + (group * 2)); /* size */
3357  ffio_wfourcc(pb, "sgpd");
3358  avio_wb32(pb, 1 << 24); /* fullbox */
3359  ffio_wfourcc(pb, "roll");
3360  avio_wb32(pb, 2); /* default_length */
3361  avio_wb32(pb, group); /* entry_count */
3362  for (i = 0; i < entries; i++) {
3363  if (sgpd_entries[i].group_description_index) {
3364  avio_wb16(pb, -sgpd_entries[i].roll_distance); /* roll_distance */
3365  }
3366  }
3367 
3368  /* Write sbgp tag */
3369  avio_wb32(pb, 20 + (entries * 8)); /* size */
3370  ffio_wfourcc(pb, "sbgp");
3371  avio_wb32(pb, 0); /* fullbox */
3372  ffio_wfourcc(pb, "roll");
3373  avio_wb32(pb, entries); /* entry_count */
3374  for (i = 0; i < entries; i++) {
3375  avio_wb32(pb, sgpd_entries[i].count); /* sample_count */
3376  avio_wb32(pb, sgpd_entries[i].group_description_index); /* group_description_index */
3377  }
3378 
3379  av_free(sgpd_entries);
3380  return 0;
3381 }
3382 
3384 {
3385  int64_t pos = avio_tell(pb);
3386  int ret = 0;
3387 
3388  avio_wb32(pb, 0); /* size */
3389  ffio_wfourcc(pb, "stbl");
3390  if ((ret = mov_write_stsd_tag(s, pb, mov, track)) < 0)
3391  return ret;
3392  mov_write_stts_tag(pb, track);
3393  if ((track->par->codec_type == AVMEDIA_TYPE_VIDEO ||
3394  track->par->codec_id == AV_CODEC_ID_TRUEHD ||
3396  (track->par->codec_id == AV_CODEC_ID_AAC && track->par->profile == AV_PROFILE_AAC_USAC) ||
3397  track->par->codec_tag == MKTAG('r','t','p',' ')) &&
3398  track->has_keyframes && track->has_keyframes < track->entry)
3399  mov_write_stss_tag(pb, track, MOV_SYNC_SAMPLE);
3400  if (track->par->codec_type == AVMEDIA_TYPE_VIDEO && track->has_disposable && track->entry)
3401  mov_write_sdtp_tag(pb, track);
3402  if (track->mode == MODE_MOV && track->flags & MOV_TRACK_STPS)
3404  if (track->par->codec_type == AVMEDIA_TYPE_VIDEO &&
3405  track->flags & MOV_TRACK_CTTS && track->entry) {
3406 
3407  if ((ret = mov_write_ctts_tag(s, pb, track)) < 0)
3408  return ret;
3409  }
3410  mov_write_stsc_tag(pb, track);
3411  mov_write_stsz_tag(pb, track);
3412  mov_write_stco_tag(pb, track);
3413  if (track->cenc.aes_ctr && !(mov->flags & FF_MOV_FLAG_FRAGMENT)) {
3414  ff_mov_cenc_write_stbl_atoms(&track->cenc, pb, 0);
3415  }
3416  if (track->par->codec_id == AV_CODEC_ID_OPUS || track->par->codec_id == AV_CODEC_ID_AAC) {
3417  mov_preroll_write_stbl_atoms(pb, track);
3418  }
3419  return update_size(pb, pos);
3420 }
3421 
3423 {
3424  int64_t pos = avio_tell(pb);
3425  avio_wb32(pb, 0); /* size */
3426  ffio_wfourcc(pb, "dinf");
3427  mov_write_dref_tag(pb);
3428  return update_size(pb, pos);
3429 }
3430 
3432 {
3433  avio_wb32(pb, 12);
3434  ffio_wfourcc(pb, "nmhd");
3435  avio_wb32(pb, 0);
3436  return 12;
3437 }
3438 
3440 {
3441  avio_wb32(pb, 12);
3442  ffio_wfourcc(pb, "sthd");
3443  avio_wb32(pb, 0);
3444  return 12;
3445 }
3446 
3447 static int mov_write_tcmi_tag(AVIOContext *pb, MOVTrack *track)
3448 {
3449  int64_t pos = avio_tell(pb);
3450  const char *font = "Lucida Grande";
3451  avio_wb32(pb, 0); /* size */
3452  ffio_wfourcc(pb, "tcmi"); /* timecode media information atom */
3453  avio_wb32(pb, 0); /* version & flags */
3454  avio_wb16(pb, 0); /* text font */
3455  avio_wb16(pb, 0); /* text face */
3456  avio_wb16(pb, 12); /* text size */
3457  avio_wb16(pb, 0); /* (unknown, not in the QT specs...) */
3458  avio_wb16(pb, 0x0000); /* text color (red) */
3459  avio_wb16(pb, 0x0000); /* text color (green) */
3460  avio_wb16(pb, 0x0000); /* text color (blue) */
3461  avio_wb16(pb, 0xffff); /* background color (red) */
3462  avio_wb16(pb, 0xffff); /* background color (green) */
3463  avio_wb16(pb, 0xffff); /* background color (blue) */
3464  avio_w8(pb, strlen(font)); /* font len (part of the pascal string) */
3465  avio_write(pb, font, strlen(font)); /* font name */
3466  return update_size(pb, pos);
3467 }
3468 
3469 static int mov_write_gmhd_tag(AVIOContext *pb, MOVTrack *track)
3470 {
3471  int64_t pos = avio_tell(pb);
3472  avio_wb32(pb, 0); /* size */
3473  ffio_wfourcc(pb, "gmhd");
3474  avio_wb32(pb, 0x18); /* gmin size */
3475  ffio_wfourcc(pb, "gmin");/* generic media info */
3476  avio_wb32(pb, 0); /* version & flags */
3477  avio_wb16(pb, 0x40); /* graphics mode = */
3478  avio_wb16(pb, 0x8000); /* opColor (r?) */
3479  avio_wb16(pb, 0x8000); /* opColor (g?) */
3480  avio_wb16(pb, 0x8000); /* opColor (b?) */
3481  avio_wb16(pb, 0); /* balance */
3482  avio_wb16(pb, 0); /* reserved */
3483 
3484  /*
3485  * This special text atom is required for
3486  * Apple Quicktime chapters. The contents
3487  * don't appear to be documented, so the
3488  * bytes are copied verbatim.
3489  */
3490  if (track->tag != MKTAG('c','6','0','8')) {
3491  avio_wb32(pb, 0x2C); /* size */
3492  ffio_wfourcc(pb, "text");
3493  avio_wb16(pb, 0x01);
3494  avio_wb32(pb, 0x00);
3495  avio_wb32(pb, 0x00);
3496  avio_wb32(pb, 0x00);
3497  avio_wb32(pb, 0x01);
3498  avio_wb32(pb, 0x00);
3499  avio_wb32(pb, 0x00);
3500  avio_wb32(pb, 0x00);
3501  avio_wb32(pb, 0x00004000);
3502  avio_wb16(pb, 0x0000);
3503  }
3504 
3505  if (track->par->codec_tag == MKTAG('t','m','c','d')) {
3506  int64_t tmcd_pos = avio_tell(pb);
3507  avio_wb32(pb, 0); /* size */
3508  ffio_wfourcc(pb, "tmcd");
3509  mov_write_tcmi_tag(pb, track);
3510  update_size(pb, tmcd_pos);
3511  } else if (track->par->codec_tag == MKTAG('g','p','m','d')) {
3512  int64_t gpmd_pos = avio_tell(pb);
3513  avio_wb32(pb, 0); /* size */
3514  ffio_wfourcc(pb, "gpmd");
3515  avio_wb32(pb, 0); /* version */
3516  update_size(pb, gpmd_pos);
3517  }
3518  return update_size(pb, pos);
3519 }
3520 
3522 {
3523  avio_wb32(pb, 16); /* size */
3524  ffio_wfourcc(pb, "smhd");
3525  avio_wb32(pb, 0); /* version & flags */
3526  avio_wb16(pb, 0); /* reserved (balance, normally = 0) */
3527  avio_wb16(pb, 0); /* reserved */
3528  return 16;
3529 }
3530 
3532 {
3533  avio_wb32(pb, 0x14); /* size (always 0x14) */
3534  ffio_wfourcc(pb, "vmhd");
3535  avio_wb32(pb, 0x01); /* version & flags */
3536  avio_wb64(pb, 0); /* reserved (graphics mode = copy) */
3537  return 0x14;
3538 }
3539 
3540 static int is_clcp_track(MOVTrack *track)
3541 {
3542  return track->tag == MKTAG('c','7','0','8') ||
3543  track->tag == MKTAG('c','6','0','8');
3544 }
3545 
3547 {
3548  MOVMuxContext *mov = s->priv_data;
3549  const char *hdlr, *descr = NULL, *hdlr_type = NULL;
3550  int64_t pos = avio_tell(pb);
3551  size_t descr_len;
3552 
3553  hdlr = "dhlr";
3554  hdlr_type = "url ";
3555  descr = "DataHandler";
3556 
3557  if (track) {
3558  hdlr = (track->mode == MODE_MOV) ? "mhlr" : "\0\0\0\0";
3559  if (track->par->codec_type == AVMEDIA_TYPE_VIDEO) {
3560  if (track->mode == MODE_AVIF) {
3561  hdlr_type = (track == &mov->tracks[0]) ? "pict" : "auxv";
3562  descr = "PictureHandler";
3563  } else {
3564  hdlr_type = "vide";
3565  descr = "VideoHandler";
3566  }
3567  } else if (track->par->codec_type == AVMEDIA_TYPE_AUDIO) {
3568  hdlr_type = "soun";
3569  descr = "SoundHandler";
3570  } else if (track->par->codec_type == AVMEDIA_TYPE_SUBTITLE) {
3571  if (is_clcp_track(track)) {
3572  hdlr_type = "clcp";
3573  descr = "ClosedCaptionHandler";
3574  } else {
3575  if (track->tag == MKTAG('t','x','3','g')) {
3576  hdlr_type = "sbtl";
3577  } else if (track->tag == MKTAG('m','p','4','s')) {
3578  hdlr_type = "subp";
3579  } else if (track->tag == MOV_MP4_TTML_TAG) {
3580  hdlr_type = "subt";
3581  } else {
3582  hdlr_type = "text";
3583  }
3584  descr = "SubtitleHandler";
3585  }
3586  } else if (track->par->codec_tag == MKTAG('r','t','p',' ')) {
3587  hdlr_type = "hint";
3588  descr = "HintHandler";
3589  } else if (track->par->codec_tag == MKTAG('t','m','c','d')) {
3590  hdlr_type = "tmcd";
3591  descr = "TimeCodeHandler";
3592  } else if (track->par->codec_tag == MKTAG('g','p','m','d')) {
3593  hdlr_type = "meta";
3594  descr = "GoPro MET"; // GoPro Metadata
3595  } else {
3597  "Unknown hdlr_type for %s, writing dummy values\n",
3598  av_fourcc2str(track->par->codec_tag));
3599  }
3600  if (track->st) {
3601  // hdlr.name is used by some players to identify the content title
3602  // of the track. So if an alternate handler description is
3603  // specified, use it.
3604  AVDictionaryEntry *t;
3605  t = av_dict_get(track->st->metadata, "handler_name", NULL, 0);
3606  if (t && utf8len(t->value))
3607  descr = t->value;
3608  }
3609  }
3610 
3611  if (mov->empty_hdlr_name) /* expressly allowed by QTFF and not prohibited in ISO 14496-12 8.4.3.3 */
3612  descr = "";
3613 
3614  avio_wb32(pb, 0); /* size */
3615  ffio_wfourcc(pb, "hdlr");
3616  avio_wb32(pb, 0); /* Version & flags */
3617  avio_write(pb, hdlr, 4); /* handler */
3618  ffio_wfourcc(pb, hdlr_type); /* handler type */
3619  avio_wb32(pb, 0); /* reserved */
3620  avio_wb32(pb, 0); /* reserved */
3621  avio_wb32(pb, 0); /* reserved */
3622  descr_len = strlen(descr);
3623  if (!track || track->mode == MODE_MOV)
3624  avio_w8(pb, descr_len); /* pascal string */
3625  avio_write(pb, descr, descr_len); /* handler description */
3626  if (track && track->mode != MODE_MOV)
3627  avio_w8(pb, 0); /* c string */
3628  return update_size(pb, pos);
3629 }
3630 
3631 static int mov_write_pitm_tag(AVIOContext *pb, int item_id)
3632 {
3633  int64_t pos = avio_tell(pb);
3634  avio_wb32(pb, 0); /* size */
3635  ffio_wfourcc(pb, "pitm");
3636  avio_wb32(pb, 0); /* Version & flags */
3637  avio_wb16(pb, item_id); /* item_id */
3638  return update_size(pb, pos);
3639 }
3640 
3642 {
3643  int64_t pos = avio_tell(pb);
3644  avio_wb32(pb, 0); /* size */
3645  ffio_wfourcc(pb, "iloc");
3646  avio_wb32(pb, 0); /* Version & flags */
3647  avio_w8(pb, (4 << 4) + 4); /* offset_size(4) and length_size(4) */
3648  avio_w8(pb, 0); /* base_offset_size(4) and reserved(4) */
3649  avio_wb16(pb, mov->nb_streams); /* item_count */
3650 
3651  for (int i = 0; i < mov->nb_streams; i++) {
3652  avio_wb16(pb, i + 1); /* item_id */
3653  avio_wb16(pb, 0); /* data_reference_index */
3654  avio_wb16(pb, 1); /* extent_count */
3655  mov->avif_extent_pos[i] = avio_tell(pb);
3656  avio_wb32(pb, 0); /* extent_offset (written later) */
3657  // For animated AVIF, we simply write the first packet's size.
3658  avio_wb32(pb, mov->avif_extent_length[i]); /* extent_length */
3659  }
3660 
3661  return update_size(pb, pos);
3662 }
3663 
3665 {
3666  int64_t iinf_pos = avio_tell(pb);
3667  avio_wb32(pb, 0); /* size */
3668  ffio_wfourcc(pb, "iinf");
3669  avio_wb32(pb, 0); /* Version & flags */
3670  avio_wb16(pb, mov->nb_streams); /* entry_count */
3671 
3672  for (int i = 0; i < mov->nb_streams; i++) {
3673  int64_t infe_pos = avio_tell(pb);
3674  avio_wb32(pb, 0); /* size */
3675  ffio_wfourcc(pb, "infe");
3676  avio_w8(pb, 0x2); /* Version */
3677  avio_wb24(pb, 0); /* flags */
3678  avio_wb16(pb, i + 1); /* item_id */
3679  avio_wb16(pb, 0); /* item_protection_index */
3680  avio_write(pb, "av01", 4); /* item_type */
3681  avio_write(pb, !i ? "Color\0" : "Alpha\0", 6); /* item_name */
3682  update_size(pb, infe_pos);
3683  }
3684 
3685  return update_size(pb, iinf_pos);
3686 }
3687 
3688 
3690 {
3691  int64_t auxl_pos;
3692  int64_t iref_pos = avio_tell(pb);
3693  avio_wb32(pb, 0); /* size */
3694  ffio_wfourcc(pb, "iref");
3695  avio_wb32(pb, 0); /* Version & flags */
3696 
3697  auxl_pos = avio_tell(pb);
3698  avio_wb32(pb, 0); /* size */
3699  ffio_wfourcc(pb, "auxl");
3700  avio_wb16(pb, 2); /* from_item_ID */
3701  avio_wb16(pb, 1); /* reference_count */
3702  avio_wb16(pb, 1); /* to_item_ID */
3703  update_size(pb, auxl_pos);
3704 
3705  return update_size(pb, iref_pos);
3706 }
3707 
3709  int stream_index)
3710 {
3711  int64_t pos = avio_tell(pb);
3712  avio_wb32(pb, 0); /* size */
3713  ffio_wfourcc(pb, "ispe");
3714  avio_wb32(pb, 0); /* Version & flags */
3715  avio_wb32(pb, s->streams[stream_index]->codecpar->width); /* image_width */
3716  avio_wb32(pb, s->streams[stream_index]->codecpar->height); /* image_height */
3717  return update_size(pb, pos);
3718 }
3719 
3721  int stream_index)
3722 {
3723  int64_t pos = avio_tell(pb);
3724  const AVPixFmtDescriptor *pixdesc =
3725  av_pix_fmt_desc_get(s->streams[stream_index]->codecpar->format);
3726  avio_wb32(pb, 0); /* size */
3727  ffio_wfourcc(pb, "pixi");
3728  avio_wb32(pb, 0); /* Version & flags */
3729  avio_w8(pb, pixdesc->nb_components); /* num_channels */
3730  for (int i = 0; i < pixdesc->nb_components; ++i) {
3731  avio_w8(pb, pixdesc->comp[i].depth); /* bits_per_channel */
3732  }
3733  return update_size(pb, pos);
3734 }
3735 
3737 {
3738  int64_t pos = avio_tell(pb);
3739  avio_wb32(pb, 0); /* size */
3740  ffio_wfourcc(pb, "ipco");
3741  for (int i = 0; i < mov->nb_streams; i++) {
3742  mov_write_ispe_tag(pb, mov, s, i);
3743  mov_write_pixi_tag(pb, mov, s, i);
3744  mov_write_av1c_tag(pb, &mov->tracks[i]);
3745  if (!i)
3746  mov_write_colr_tag(pb, &mov->tracks[0], 0);
3747  else
3748  mov_write_aux_tag(pb, "auxC");
3749  }
3750  return update_size(pb, pos);
3751 }
3752 
3754 {
3755  int64_t pos = avio_tell(pb);
3756  avio_wb32(pb, 0); /* size */
3757  ffio_wfourcc(pb, "ipma");
3758  avio_wb32(pb, 0); /* Version & flags */
3759  avio_wb32(pb, mov->nb_streams); /* entry_count */
3760 
3761  for (int i = 0, index = 1; i < mov->nb_streams; i++) {
3762  avio_wb16(pb, i + 1); /* item_ID */
3763  avio_w8(pb, 4); /* association_count */
3764 
3765  // ispe association.
3766  avio_w8(pb, index++); /* essential and property_index */
3767  // pixi association.
3768  avio_w8(pb, index++); /* essential and property_index */
3769  // av1C association.
3770  avio_w8(pb, 0x80 | index++); /* essential and property_index */
3771  // colr/auxC association.
3772  avio_w8(pb, index++); /* essential and property_index */
3773  }
3774  return update_size(pb, pos);
3775 }
3776 
3778 {
3779  int64_t pos = avio_tell(pb);
3780  avio_wb32(pb, 0); /* size */
3781  ffio_wfourcc(pb, "iprp");
3782  mov_write_ipco_tag(pb, mov, s);
3783  mov_write_ipma_tag(pb, mov, s);
3784  return update_size(pb, pos);
3785 }
3786 
3788 {
3789  /* This atom must be present, but leaving the values at zero
3790  * seems harmless. */
3791  avio_wb32(pb, 28); /* size */
3792  ffio_wfourcc(pb, "hmhd");
3793  avio_wb32(pb, 0); /* version, flags */
3794  avio_wb16(pb, 0); /* maxPDUsize */
3795  avio_wb16(pb, 0); /* avgPDUsize */
3796  avio_wb32(pb, 0); /* maxbitrate */
3797  avio_wb32(pb, 0); /* avgbitrate */
3798  avio_wb32(pb, 0); /* reserved */
3799  return 28;
3800 }
3801 
3803 {
3804  int64_t pos = avio_tell(pb);
3805  int ret;
3806 
3807  avio_wb32(pb, 0); /* size */
3808  ffio_wfourcc(pb, "minf");
3809  if (track->par->codec_type == AVMEDIA_TYPE_VIDEO)
3810  mov_write_vmhd_tag(pb);
3811  else if (track->par->codec_type == AVMEDIA_TYPE_AUDIO)
3812  mov_write_smhd_tag(pb);
3813  else if (track->par->codec_type == AVMEDIA_TYPE_SUBTITLE) {
3814  if (track->tag == MKTAG('t','e','x','t') || is_clcp_track(track)) {
3815  mov_write_gmhd_tag(pb, track);
3816  } else if (track->tag == MOV_MP4_TTML_TAG) {
3817  mov_write_sthd_tag(pb);
3818  } else {
3819  mov_write_nmhd_tag(pb);
3820  }
3821  } else if (track->tag == MKTAG('r','t','p',' ')) {
3822  mov_write_hmhd_tag(pb);
3823  } else if (track->tag == MKTAG('t','m','c','d')) {
3824  if (track->mode != MODE_MOV)
3825  mov_write_nmhd_tag(pb);
3826  else
3827  mov_write_gmhd_tag(pb, track);
3828  } else if (track->tag == MKTAG('g','p','m','d')) {
3829  mov_write_gmhd_tag(pb, track);
3830  }
3831  if (track->mode == MODE_MOV) /* ISO 14496-12 8.4.3.1 specifies hdlr only within mdia or meta boxes */
3832  mov_write_hdlr_tag(s, pb, NULL);
3833  mov_write_dinf_tag(pb);
3834  if ((ret = mov_write_stbl_tag(s, pb, mov, track)) < 0)
3835  return ret;
3836  return update_size(pb, pos);
3837 }
3838 
3839 static void get_pts_range(MOVMuxContext *mov, MOVTrack *track,
3840  int64_t *start, int64_t *end, int elst)
3841 {
3842  if (track->tag == MKTAG('t','m','c','d') && mov->nb_meta_tmcd && track->nb_src_track) {
3843  // tmcd tracks gets track_duration set in mov_write_moov_tag from
3844  // another track's duration, while the end_pts may be left at zero.
3845  // Calculate the pts duration for that track instead.
3846  get_pts_range(mov, &mov->tracks[*track->src_track], start, end, elst);
3847  *start = av_rescale(*start, track->timescale,
3848  mov->tracks[*track->src_track].timescale);
3849  *end = av_rescale(*end, track->timescale,
3850  mov->tracks[*track->src_track].timescale);
3851  return;
3852  }
3853  if (track->end_pts != AV_NOPTS_VALUE &&
3854  track->start_dts != AV_NOPTS_VALUE &&
3855  track->start_cts != AV_NOPTS_VALUE) {
3856  *start = track->start_dts + track->start_cts;
3857  *end = elst ? track->elst_end_pts : track->end_pts;
3858  return;
3859  }
3860  *start = 0;
3861  *end = track->track_duration;
3862 }
3863 
3865 {
3866  int64_t start, end;
3867  get_pts_range(mov, track, &start, &end, 0);
3868  return end - start;
3869 }
3870 
3871 // Calculate the actual duration of the track, after edits.
3872 // If it starts with a pts < 0, that is removed by the edit list.
3873 // If it starts with a pts > 0, the edit list adds a delay before that.
3874 // Thus, with edit lists enabled, the post-edit output of the file is
3875 // starting with pts=0.
3877 {
3878  int64_t start, end;
3879  get_pts_range(mov, track, &start, &end, 0);
3880  if (mov->use_editlist != 0)
3881  start = 0;
3882  return end - start;
3883 }
3884 
3886 {
3887  int64_t start, end;
3888  get_pts_range(mov, track, &start, &end, 1);
3889  return end - start;
3890 }
3891 
3893 {
3894  if (track && track->mode == MODE_ISM)
3895  return 1;
3896  if (duration < INT32_MAX)
3897  return 0;
3898  return 1;
3899 }
3900 
3902  MOVTrack *track)
3903 {
3905  int version = mov_mdhd_mvhd_tkhd_version(mov, track, duration);
3906 
3907  (version == 1) ? avio_wb32(pb, 44) : avio_wb32(pb, 32); /* size */
3908  ffio_wfourcc(pb, "mdhd");
3909  avio_w8(pb, version);
3910  avio_wb24(pb, 0); /* flags */
3911  if (version == 1) {
3912  avio_wb64(pb, track->time);
3913  avio_wb64(pb, track->time);
3914  } else {
3915  avio_wb32(pb, track->time); /* creation time */
3916  avio_wb32(pb, track->time); /* modification time */
3917  }
3918  avio_wb32(pb, track->timescale); /* time scale (sample rate for audio) */
3919  if (!track->entry && mov->mode == MODE_ISM)
3920  (version == 1) ? avio_wb64(pb, UINT64_C(0xffffffffffffffff)) : avio_wb32(pb, 0xffffffff);
3921  else if (!track->entry)
3922  (version == 1) ? avio_wb64(pb, 0) : avio_wb32(pb, 0);
3923  else
3924  (version == 1) ? avio_wb64(pb, duration) : avio_wb32(pb, duration); /* duration */
3925  avio_wb16(pb, track->language); /* language */
3926  avio_wb16(pb, 0); /* reserved (quality) */
3927 
3928  if (version != 0 && track->mode == MODE_MOV) {
3930  "FATAL error, file duration too long for timebase, this file will not be\n"
3931  "playable with QuickTime. Choose a different timebase with "
3932  "-video_track_timescale or a different container format\n");
3933  }
3934 
3935  return 32;
3936 }
3937 
3939  MOVMuxContext *mov, MOVTrack *track)
3940 {
3941  int64_t pos = avio_tell(pb);
3942  int ret;
3943 
3944  avio_wb32(pb, 0); /* size */
3945  ffio_wfourcc(pb, "mdia");
3946  mov_write_mdhd_tag(pb, mov, track);
3947  mov_write_hdlr_tag(s, pb, track);
3948  if ((ret = mov_write_minf_tag(s, pb, mov, track)) < 0)
3949  return ret;
3950  return update_size(pb, pos);
3951 }
3952 
3953 /* transformation matrix
3954  |a b u|
3955  |c d v|
3956  |tx ty w| */
3957 static void write_matrix(AVIOContext *pb, int16_t a, int16_t b, int16_t c,
3958  int16_t d, int16_t tx, int16_t ty)
3959 {
3960  avio_wb32(pb, a << 16); /* 16.16 format */
3961  avio_wb32(pb, b << 16); /* 16.16 format */
3962  avio_wb32(pb, 0); /* u in 2.30 format */
3963  avio_wb32(pb, c << 16); /* 16.16 format */
3964  avio_wb32(pb, d << 16); /* 16.16 format */
3965  avio_wb32(pb, 0); /* v in 2.30 format */
3966  avio_wb32(pb, tx << 16); /* 16.16 format */
3967  avio_wb32(pb, ty << 16); /* 16.16 format */
3968  avio_wb32(pb, 1 << 30); /* w in 2.30 format */
3969 }
3970 
3972  MOVTrack *track, AVStream *st)
3973 {
3975  mov->movie_timescale, track->timescale,
3976  AV_ROUND_UP);
3977  int version;
3979  int group = 0;
3980 
3981  uint32_t *display_matrix = NULL;
3982  int i;
3983 
3984  if (mov->mode == MODE_AVIF)
3985  if (!mov->avif_loop_count)
3986  duration = INT64_MAX;
3987  else
3988  duration *= mov->avif_loop_count;
3989 
3990  if (st) {
3991  const AVPacketSideData *sd;
3992  if (mov->per_stream_grouping)
3993  group = st->index;
3994  else
3995  group = st->codecpar->codec_type;
3996 
4000  if (sd && sd->size == 9 * sizeof(*display_matrix))
4001  display_matrix = (uint32_t *)sd->data;
4002  }
4003 
4004  if (track->flags & MOV_TRACK_ENABLED)
4006 
4008 
4009  (version == 1) ? avio_wb32(pb, 104) : avio_wb32(pb, 92); /* size */
4010  ffio_wfourcc(pb, "tkhd");
4011  avio_w8(pb, version);
4012  avio_wb24(pb, flags);
4013  if (version == 1) {
4014  avio_wb64(pb, track->time);
4015  avio_wb64(pb, track->time);
4016  } else {
4017  avio_wb32(pb, track->time); /* creation time */
4018  avio_wb32(pb, track->time); /* modification time */
4019  }
4020  avio_wb32(pb, track->track_id); /* track-id */
4021  avio_wb32(pb, 0); /* reserved */
4022  if (!track->entry && mov->mode == MODE_ISM)
4023  (version == 1) ? avio_wb64(pb, UINT64_C(0xffffffffffffffff)) : avio_wb32(pb, 0xffffffff);
4024  else if (!track->entry)
4025  (version == 1) ? avio_wb64(pb, 0) : avio_wb32(pb, 0);
4026  else
4027  (version == 1) ? avio_wb64(pb, duration) : avio_wb32(pb, duration);
4028 
4029  avio_wb32(pb, 0); /* reserved */
4030  avio_wb32(pb, 0); /* reserved */
4031  avio_wb16(pb, 0); /* layer */
4032  avio_wb16(pb, group); /* alternate group) */
4033  /* Volume, only for audio */
4034  if (track->par->codec_type == AVMEDIA_TYPE_AUDIO)
4035  avio_wb16(pb, 0x0100);
4036  else
4037  avio_wb16(pb, 0);
4038  avio_wb16(pb, 0); /* reserved */
4039 
4040  /* Matrix structure */
4041  if (display_matrix) {
4042  for (i = 0; i < 9; i++)
4043  avio_wb32(pb, display_matrix[i]);
4044  } else {
4045  write_matrix(pb, 1, 0, 0, 1, 0, 0);
4046  }
4047  /* Track width and height, for visual only */
4048  if (st && (track->par->codec_type == AVMEDIA_TYPE_VIDEO ||
4049  track->par->codec_type == AVMEDIA_TYPE_SUBTITLE)) {
4050  int64_t track_width_1616;
4051  if (track->mode == MODE_MOV || track->mode == MODE_AVIF) {
4052  track_width_1616 = track->par->width * 0x10000ULL;
4053  } else {
4054  track_width_1616 = av_rescale(st->sample_aspect_ratio.num,
4055  track->par->width * 0x10000LL,
4056  st->sample_aspect_ratio.den);
4057  if (!track_width_1616 ||
4058  track->height != track->par->height ||
4059  track_width_1616 > UINT32_MAX)
4060  track_width_1616 = track->par->width * 0x10000ULL;
4061  }
4062  if (track_width_1616 > UINT32_MAX) {
4063  av_log(mov->fc, AV_LOG_WARNING, "track width is too large\n");
4064  track_width_1616 = 0;
4065  }
4066  avio_wb32(pb, track_width_1616);
4067  if (track->height > 0xFFFF) {
4068  av_log(mov->fc, AV_LOG_WARNING, "track height is too large\n");
4069  avio_wb32(pb, 0);
4070  } else
4071  avio_wb32(pb, track->height * 0x10000U);
4072  } else {
4073  avio_wb32(pb, 0);
4074  avio_wb32(pb, 0);
4075  }
4076  return 0x5c;
4077 }
4078 
4079 static int mov_write_tapt_tag(AVIOContext *pb, MOVTrack *track)
4080 {
4082  track->par->sample_aspect_ratio.den);
4083 
4084  int64_t pos = avio_tell(pb);
4085 
4086  avio_wb32(pb, 0); /* size */
4087  ffio_wfourcc(pb, "tapt");
4088 
4089  avio_wb32(pb, 20);
4090  ffio_wfourcc(pb, "clef");
4091  avio_wb32(pb, 0);
4092  avio_wb32(pb, width << 16);
4093  avio_wb32(pb, track->par->height << 16);
4094 
4095  avio_wb32(pb, 20);
4096  ffio_wfourcc(pb, "prof");
4097  avio_wb32(pb, 0);
4098  avio_wb32(pb, width << 16);
4099  avio_wb32(pb, track->par->height << 16);
4100 
4101  avio_wb32(pb, 20);
4102  ffio_wfourcc(pb, "enof");
4103  avio_wb32(pb, 0);
4104  avio_wb32(pb, track->par->width << 16);
4105  avio_wb32(pb, track->par->height << 16);
4106 
4107  return update_size(pb, pos);
4108 }
4109 
4110 // This box is written in the following cases:
4111 // * Seems important for the psp playback. Without it the movie seems to hang.
4112 // * Used for specifying the looping behavior of animated AVIF (as specified
4113 // in Section 9.6 of the HEIF specification ISO/IEC 23008-12).
4115  MOVTrack *track)
4116 {
4118  mov->movie_timescale, track->timescale,
4119  AV_ROUND_UP);
4120  int version = duration < INT32_MAX ? 0 : 1;
4121  int entry_size, entry_count, size;
4122  int64_t delay, start_ct = track->start_cts;
4123  int64_t start_dts = track->start_dts;
4124  int flags = 0;
4125 
4126  if (track->entry) {
4127  if (start_dts != track->cluster[0].dts || (start_ct != track->cluster[0].cts && track->cluster[0].dts >= 0)) {
4128 
4129  av_log(mov->fc, AV_LOG_DEBUG,
4130  "EDTS using dts:%"PRId64" cts:%d instead of dts:%"PRId64" cts:%"PRId64" tid:%d\n",
4131  track->cluster[0].dts, track->cluster[0].cts,
4132  start_dts, start_ct, track->track_id);
4133  start_dts = track->cluster[0].dts;
4134  start_ct = track->cluster[0].cts;
4135  }
4136  }
4137 
4138  delay = av_rescale_rnd(start_dts + start_ct, mov->movie_timescale,
4139  track->timescale, AV_ROUND_DOWN);
4140 
4141  if (mov->mode == MODE_AVIF) {
4142  delay = 0;
4143  // Section 9.6.3 of ISO/IEC 23008-12: flags specifies repetition of the
4144  // edit list as follows: (flags & 1) equal to 0 specifies that the edit
4145  // list is not repeated, while (flags & 1) equal to 1 specifies that the
4146  // edit list is repeated.
4147  flags = mov->avif_loop_count != 1;
4148  start_ct = 0;
4149  }
4150 
4151  version |= delay < INT32_MAX ? 0 : 1;
4152 
4153  entry_size = (version == 1) ? 20 : 12;
4154  entry_count = 1 + (delay > 0);
4155  size = 24 + entry_count * entry_size;
4156 
4157  /* write the atom data */
4158  avio_wb32(pb, size);
4159  ffio_wfourcc(pb, "edts");
4160  avio_wb32(pb, size - 8);
4161  ffio_wfourcc(pb, "elst");
4162  avio_w8(pb, version);
4163  avio_wb24(pb, flags); /* flags */
4164 
4165  avio_wb32(pb, entry_count);
4166  if (delay > 0) { /* add an empty edit to delay presentation */
4167  /* In the positive delay case, the delay includes the cts
4168  * offset, and the second edit list entry below trims out
4169  * the same amount from the actual content. This makes sure
4170  * that the offset last sample is included in the edit
4171  * list duration as well. */
4172  if (version == 1) {
4173  avio_wb64(pb, delay);
4174  avio_wb64(pb, -1);
4175  } else {
4176  avio_wb32(pb, delay);
4177  avio_wb32(pb, -1);
4178  }
4179  avio_wb32(pb, 0x00010000);
4180  } else if (mov->mode != MODE_AVIF) {
4181  /* Avoid accidentally ending up with start_ct = -1 which has got a
4182  * special meaning. Normally start_ct should end up positive or zero
4183  * here, but use FFMIN in case dts is a small positive integer
4184  * rounded to 0 when represented in movie timescale units. */
4185  av_assert0(av_rescale_rnd(start_dts, mov->movie_timescale, track->timescale, AV_ROUND_DOWN) <= 0);
4186  start_ct = -FFMIN(start_dts, 0);
4187 
4188 #if CONFIG_IAMFENC
4189  if (track->iamf && track->par->codec_id == AV_CODEC_ID_OPUS)
4190  start_ct = av_rescale(start_ct, 48000, track->par->sample_rate);
4191 #endif
4192  /* Note, this delay is calculated from the pts of the first sample,
4193  * ensuring that we don't reduce the duration for cases with
4194  * dts<0 pts=0. */
4195  duration += delay;
4196  }
4197 
4198  /* For fragmented files, we don't know the full length yet. Setting
4199  * duration to 0 allows us to only specify the offset, including
4200  * the rest of the content (from all future fragments) without specifying
4201  * an explicit duration.
4202  *
4203  * For hybrid_fragmented during mov_write_trailer (mov->moov_written != 0),
4204  * don't reset duration to zero.
4205  */
4206  if (mov->flags & FF_MOV_FLAG_FRAGMENT &&
4208  duration = 0;
4209 
4210  /* duration */
4211  if (version == 1) {
4212  avio_wb64(pb, duration);
4213  avio_wb64(pb, start_ct);
4214  } else {
4215  avio_wb32(pb, duration);
4216  avio_wb32(pb, start_ct);
4217  }
4218  avio_wb32(pb, 0x00010000);
4219  return size;
4220 }
4221 
4222 static int mov_write_tref_tag(AVIOContext *pb, MOVTrack *track)
4223 {
4224  int64_t pos = avio_tell(pb);
4225  avio_wb32(pb, 0); // size placeholder
4226  ffio_wfourcc(pb, "tref");
4227 
4228  for (int i = 0; i < track->nb_tref_tags; i++) {
4229  MovTag *tag = &track->tref_tags[i];
4230  avio_wb32(pb, 8 + tag->nb_id * sizeof(*tag->id)); // size (subatom)
4231  avio_wl32(pb, tag->name);
4232  for (int j = 0; j < tag->nb_id; j++)
4233  avio_wb32(pb, tag->id[j]);
4234  }
4235  return update_size(pb, pos);
4236 }
4237 
4238 // goes at the end of each track! ... Critical for PSP playback ("Incompatible data" without it)
4240 {
4241  avio_wb32(pb, 0x34); /* size ... reports as 28 in mp4box! */
4242  ffio_wfourcc(pb, "uuid");
4243  ffio_wfourcc(pb, "USMT");
4244  avio_wb32(pb, 0x21d24fce);
4245  avio_wb32(pb, 0xbb88695c);
4246  avio_wb32(pb, 0xfac9c740);
4247  avio_wb32(pb, 0x1c); // another size here!
4248  ffio_wfourcc(pb, "MTDT");
4249  avio_wb32(pb, 0x00010012);
4250  avio_wb32(pb, 0x0a);
4251  avio_wb32(pb, 0x55c40000);
4252  avio_wb32(pb, 0x1);
4253  avio_wb32(pb, 0x0);
4254  return 0x34;
4255 }
4256 
4257 static int mov_write_udta_sdp(AVIOContext *pb, MOVTrack *track)
4258 {
4259  AVFormatContext *ctx = track->rtp_ctx;
4260  char buf[1000] = "";
4261  int len;
4262 
4263  av_assert0(track->nb_src_track);
4264  ff_sdp_write_media(buf, sizeof(buf), ctx->streams[0], *track->src_track,
4265  NULL, NULL, 0, 0, ctx);
4266  av_strlcatf(buf, sizeof(buf), "a=control:streamid=%d\r\n", track->track_id);
4267  len = strlen(buf);
4268 
4269  avio_wb32(pb, len + 24);
4270  ffio_wfourcc(pb, "udta");
4271  avio_wb32(pb, len + 16);
4272  ffio_wfourcc(pb, "hnti");
4273  avio_wb32(pb, len + 8);
4274  ffio_wfourcc(pb, "sdp ");
4275  avio_write(pb, buf, len);
4276  return len + 24;
4277 }
4278 
4280  const char *tag, const char *str)
4281 {
4282  int64_t pos = avio_tell(pb);
4283  AVDictionaryEntry *t = av_dict_get(st->metadata, str, NULL, 0);
4284  if (!t || !utf8len(t->value))
4285  return 0;
4286 
4287  avio_wb32(pb, 0); /* size */
4288  ffio_wfourcc(pb, tag); /* type */
4289  avio_write(pb, t->value, strlen(t->value)); /* UTF8 string value */
4290  return update_size(pb, pos);
4291 }
4292 
4293 static int mov_write_track_kind(AVIOContext *pb, const char *scheme_uri,
4294  const char *value)
4295 {
4296  int64_t pos = avio_tell(pb);
4297 
4298  /* Box|FullBox basics */
4299  avio_wb32(pb, 0); /* size placeholder */
4300  ffio_wfourcc(pb, (const unsigned char *)"kind");
4301  avio_w8(pb, 0); /* version = 0 */
4302  avio_wb24(pb, 0); /* flags = 0 */
4303 
4304  /* Required null-terminated scheme URI */
4305  avio_write(pb, (const unsigned char *)scheme_uri,
4306  strlen(scheme_uri));
4307  avio_w8(pb, 0);
4308 
4309  /* Optional value string */
4310  if (value && value[0])
4311  avio_write(pb, (const unsigned char *)value,
4312  strlen(value));
4313 
4314  avio_w8(pb, 0);
4315 
4316  return update_size(pb, pos);
4317 }
4318 
4320 {
4321  int ret = AVERROR_BUG;
4322 
4323  for (int i = 0; ff_mov_track_kind_table[i].scheme_uri; i++) {
4325 
4326  for (int j = 0; map.value_maps[j].disposition; j++) {
4327  const struct MP4TrackKindValueMapping value_map = map.value_maps[j];
4328  if (!(st->disposition & value_map.disposition))
4329  continue;
4330 
4331  if ((ret = mov_write_track_kind(pb, map.scheme_uri, value_map.value)) < 0)
4332  return ret;
4333  }
4334  }
4335 
4336  return 0;
4337 }
4338 
4340  AVStream *st)
4341 {
4342  AVIOContext *pb_buf;
4343  int ret, size;
4344  uint8_t *buf;
4345 
4346  if (!st)
4347  return 0;
4348 
4349  ret = avio_open_dyn_buf(&pb_buf);
4350  if (ret < 0)
4351  return ret;
4352 
4353  if (mov->mode & (MODE_MP4|MODE_MOV))
4354  mov_write_track_metadata(pb_buf, st, "name", "title");
4355 
4356  if (mov->mode & MODE_MP4) {
4357  if ((ret = mov_write_track_kinds(pb_buf, st)) < 0)
4358  goto end;
4359  }
4360 
4361  if ((size = avio_get_dyn_buf(pb_buf, &buf)) > 0) {
4362  avio_wb32(pb, size + 8);
4363  ffio_wfourcc(pb, "udta");
4364  avio_write(pb, buf, size);
4365  }
4366 end:
4367  ffio_free_dyn_buf(&pb_buf);
4368 
4369  return ret;
4370 }
4371 
4373  MOVTrack *track, AVStream *st)
4374 {
4375  int64_t pos = avio_tell(pb);
4376  int entry_backup = track->entry;
4377  int chunk_backup = track->chunkCount;
4378  int ret;
4379 
4380  /* If we want to have an empty moov, but some samples already have been
4381  * buffered (delay_moov), pretend that no samples have been written yet. */
4382  if (mov->flags & FF_MOV_FLAG_EMPTY_MOOV)
4383  track->chunkCount = track->entry = 0;
4384 
4385  avio_wb32(pb, 0); /* size */
4386  ffio_wfourcc(pb, "trak");
4387  mov_write_tkhd_tag(pb, mov, track, st);
4388 
4389  av_assert2(mov->use_editlist >= 0);
4390 
4391  if (track->start_dts != AV_NOPTS_VALUE) {
4392  if (mov->use_editlist)
4393  mov_write_edts_tag(pb, mov, track); // PSP Movies and several other cases require edts box
4394  else if ((track->entry && track->cluster[0].dts) || track->mode == MODE_PSP || is_clcp_track(track))
4395  av_log(mov->fc, AV_LOG_WARNING,
4396  "Not writing any edit list even though one would have been required\n");
4397  }
4398 
4399  if (mov->is_animated_avif)
4400  mov_write_edts_tag(pb, mov, track);
4401 
4402  if (track->nb_tref_tags)
4403  mov_write_tref_tag(pb, track);
4404 
4405  if ((ret = mov_write_mdia_tag(s, pb, mov, track)) < 0)
4406  return ret;
4407  if (track->mode == MODE_PSP)
4408  mov_write_uuid_tag_psp(pb, track); // PSP Movies require this uuid box
4409  if (track->tag == MKTAG('r','t','p',' '))
4410  mov_write_udta_sdp(pb, track);
4411  if (track->mode == MODE_MOV) {
4412  if (track->par->codec_type == AVMEDIA_TYPE_VIDEO) {
4413  double sample_aspect_ratio = av_q2d(st->sample_aspect_ratio);
4414  if (st->sample_aspect_ratio.num && 1.0 != sample_aspect_ratio) {
4415  mov_write_tapt_tag(pb, track);
4416  }
4417  }
4418  if (is_clcp_track(track) && st->sample_aspect_ratio.num) {
4419  mov_write_tapt_tag(pb, track);
4420  }
4421  }
4422  mov_write_track_udta_tag(pb, mov, st);
4423  track->entry = entry_backup;
4424  track->chunkCount = chunk_backup;
4425  return update_size(pb, pos);
4426 }
4427 
4429 {
4430  int i, has_audio = 0, has_video = 0;
4431  int64_t pos = avio_tell(pb);
4432  int audio_profile = mov->iods_audio_profile;
4433  int video_profile = mov->iods_video_profile;
4434  for (i = 0; i < mov->nb_tracks; i++) {
4435  if (mov->tracks[i].entry > 0 || mov->flags & FF_MOV_FLAG_EMPTY_MOOV) {
4436  has_audio |= mov->tracks[i].par->codec_type == AVMEDIA_TYPE_AUDIO;
4437  has_video |= mov->tracks[i].par->codec_type == AVMEDIA_TYPE_VIDEO;
4438  }
4439  }
4440  if (audio_profile < 0)
4441  audio_profile = 0xFF - has_audio;
4442  if (video_profile < 0)
4443  video_profile = 0xFF - has_video;
4444  avio_wb32(pb, 0x0); /* size */
4445  ffio_wfourcc(pb, "iods");
4446  avio_wb32(pb, 0); /* version & flags */
4447  put_descr(pb, 0x10, 7);
4448  avio_wb16(pb, 0x004f);
4449  avio_w8(pb, 0xff);
4450  avio_w8(pb, 0xff);
4451  avio_w8(pb, audio_profile);
4452  avio_w8(pb, video_profile);
4453  avio_w8(pb, 0xff);
4454  return update_size(pb, pos);
4455 }
4456 
4457 static int mov_write_trex_tag(AVIOContext *pb, MOVTrack *track)
4458 {
4459  avio_wb32(pb, 0x20); /* size */
4460  ffio_wfourcc(pb, "trex");
4461  avio_wb32(pb, 0); /* version & flags */
4462  avio_wb32(pb, track->track_id); /* track ID */
4463  avio_wb32(pb, 1); /* default sample description index */
4464  avio_wb32(pb, 0); /* default sample duration */
4465  avio_wb32(pb, 0); /* default sample size */
4466  avio_wb32(pb, 0); /* default sample flags */
4467  return 0;
4468 }
4469 
4471 {
4472  int64_t pos = avio_tell(pb);
4473  int i;
4474  avio_wb32(pb, 0x0); /* size */
4475  ffio_wfourcc(pb, "mvex");
4476  for (i = 0; i < mov->nb_tracks; i++)
4477  mov_write_trex_tag(pb, &mov->tracks[i]);
4478  return update_size(pb, pos);
4479 }
4480 
4482 {
4483  int max_track_id = 1, i;
4484  int64_t max_track_len = 0;
4485  int version;
4486  int timescale;
4487 
4488  for (i = 0; i < mov->nb_tracks; i++) {
4489  if (mov->tracks[i].entry > 0 && mov->tracks[i].timescale) {
4490  int64_t max_track_len_temp = av_rescale_rnd(
4491  calc_pts_duration(mov, &mov->tracks[i]),
4492  mov->movie_timescale,
4493  mov->tracks[i].timescale,
4494  AV_ROUND_UP);
4495  if (max_track_len < max_track_len_temp)
4496  max_track_len = max_track_len_temp;
4497  if (max_track_id < mov->tracks[i].track_id)
4498  max_track_id = mov->tracks[i].track_id;
4499  }
4500  }
4501  /* If using delay_moov, make sure the output is the same as if no
4502  * samples had been written yet. */
4503  if (mov->flags & FF_MOV_FLAG_EMPTY_MOOV) {
4504  max_track_len = 0;
4505  max_track_id = 1;
4506  }
4507 
4508  version = mov_mdhd_mvhd_tkhd_version(mov, NULL, max_track_len);
4509  avio_wb32(pb, version == 1 ? 120 : 108); /* size */
4510 
4511  ffio_wfourcc(pb, "mvhd");
4512  avio_w8(pb, version);
4513  avio_wb24(pb, 0); /* flags */
4514  if (version == 1) {
4515  avio_wb64(pb, mov->time);
4516  avio_wb64(pb, mov->time);
4517  } else {
4518  avio_wb32(pb, mov->time); /* creation time */
4519  avio_wb32(pb, mov->time); /* modification time */
4520  }
4521 
4522  timescale = mov->movie_timescale;
4523  if (mov->mode == MODE_AVIF && !timescale)
4524  timescale = mov->tracks[0].timescale;
4525 
4526  avio_wb32(pb, timescale);
4527  (version == 1) ? avio_wb64(pb, max_track_len) : avio_wb32(pb, max_track_len); /* duration of longest track */
4528 
4529  avio_wb32(pb, 0x00010000); /* reserved (preferred rate) 1.0 = normal */
4530  avio_wb16(pb, 0x0100); /* reserved (preferred volume) 1.0 = normal */
4531  ffio_fill(pb, 0, 2 + 2 * 4); /* reserved */
4532 
4533  /* Matrix structure */
4534  write_matrix(pb, 1, 0, 0, 1, 0, 0);
4535 
4536  avio_wb32(pb, 0); /* reserved (preview time) */
4537  avio_wb32(pb, 0); /* reserved (preview duration) */
4538  avio_wb32(pb, 0); /* reserved (poster time) */
4539  avio_wb32(pb, 0); /* reserved (selection time) */
4540  avio_wb32(pb, 0); /* reserved (selection duration) */
4541  avio_wb32(pb, 0); /* reserved (current time) */
4542  avio_wb32(pb, max_track_id + 1); /* Next track id */
4543  return 0x6c;
4544 }
4545 
4547  AVFormatContext *s)
4548 {
4549  avio_wb32(pb, 33); /* size */
4550  ffio_wfourcc(pb, "hdlr");
4551  avio_wb32(pb, 0);
4552  avio_wb32(pb, 0);
4553  ffio_wfourcc(pb, "mdir");
4554  ffio_wfourcc(pb, "appl");
4555  avio_wb32(pb, 0);
4556  avio_wb32(pb, 0);
4557  avio_w8(pb, 0);
4558  return 33;
4559 }
4560 
4561 /* helper function to write a data tag with the specified string as data */
4562 static int mov_write_string_data_tag(AVIOContext *pb, const char *data, int lang, int long_style)
4563 {
4564  size_t data_len = strlen(data);
4565  if (long_style) {
4566  int size = 16 + data_len;
4567  avio_wb32(pb, size); /* size */
4568  ffio_wfourcc(pb, "data");
4569  avio_wb32(pb, 1);
4570  avio_wb32(pb, 0);
4571  avio_write(pb, data, data_len);
4572  return size;
4573  } else {
4574  avio_wb16(pb, data_len); /* string length */
4575  if (!lang)
4576  lang = ff_mov_iso639_to_lang("und", 1);
4577  avio_wb16(pb, lang);
4578  avio_write(pb, data, data_len);
4579  return data_len + 4;
4580  }
4581 }
4582 
4583 static int mov_write_string_tag(AVIOContext *pb, const char *name,
4584  const char *value, int lang, int long_style)
4585 {
4586  int size = 0;
4587  if (value && value[0]) {
4588  int64_t pos = avio_tell(pb);
4589  avio_wb32(pb, 0); /* size */
4590  ffio_wfourcc(pb, name);
4591  mov_write_string_data_tag(pb, value, lang, long_style);
4592  size = update_size(pb, pos);
4593  }
4594  return size;
4595 }
4596 
4598  const char *tag, int *lang)
4599 {
4600  int l, len, len2;
4601  AVDictionaryEntry *t, *t2 = NULL;
4602  char tag2[16];
4603 
4604  *lang = 0;
4605 
4606  if (!(t = av_dict_get(s->metadata, tag, NULL, 0)))
4607  return NULL;
4608 
4609  len = strlen(t->key);
4610  snprintf(tag2, sizeof(tag2), "%s-", tag);
4611  while ((t2 = av_dict_get(s->metadata, tag2, t2, AV_DICT_IGNORE_SUFFIX))) {
4612  len2 = strlen(t2->key);
4613  if (len2 == len + 4 && !strcmp(t->value, t2->value)
4614  && (l = ff_mov_iso639_to_lang(&t2->key[len2 - 3], 1)) >= 0) {
4615  *lang = l;
4616  return t;
4617  }
4618  }
4619  return t;
4620 }
4621 
4623  const char *name, const char *tag,
4624  int long_style)
4625 {
4626  int lang;
4627  AVDictionaryEntry *t = get_metadata_lang(s, tag, &lang);
4628  if (!t)
4629  return 0;
4630  return mov_write_string_tag(pb, name, t->value, lang, long_style);
4631 }
4632 
4633 /* iTunes bpm number */
4635 {
4636  AVDictionaryEntry *t = av_dict_get(s->metadata, "tmpo", NULL, 0);
4637  int size = 0, tmpo = t ? atoi(t->value) : 0;
4638  if (tmpo) {
4639  size = 26;
4640  avio_wb32(pb, size);
4641  ffio_wfourcc(pb, "tmpo");
4642  avio_wb32(pb, size-8); /* size */
4643  ffio_wfourcc(pb, "data");
4644  avio_wb32(pb, 0x15); //type specifier
4645  avio_wb32(pb, 0);
4646  avio_wb16(pb, tmpo); // data
4647  }
4648  return size;
4649 }
4650 
4651 /* 3GPP TS 26.244 */
4653 {
4654  int lang;
4655  int64_t pos = avio_tell(pb);
4656  double latitude, longitude, altitude;
4657  int32_t latitude_fix, longitude_fix, altitude_fix;
4658  AVDictionaryEntry *t = get_metadata_lang(s, "location", &lang);
4659  const char *ptr, *place = "";
4660  char *end;
4661  static const char *astronomical_body = "earth";
4662  if (!t)
4663  return 0;
4664 
4665  ptr = t->value;
4666  latitude = strtod(ptr, &end);
4667  if (end == ptr) {
4668  av_log(s, AV_LOG_WARNING, "malformed location metadata\n");
4669  return 0;
4670  }
4671  ptr = end;
4672  longitude = strtod(ptr, &end);
4673  if (end == ptr) {
4674  av_log(s, AV_LOG_WARNING, "malformed location metadata\n");
4675  return 0;
4676  }
4677  ptr = end;
4678  altitude = strtod(ptr, &end);
4679  /* If no altitude was present, the default 0 should be fine */
4680  if (*end == '/')
4681  place = end + 1;
4682 
4683  latitude_fix = (int32_t) ((1 << 16) * latitude);
4684  longitude_fix = (int32_t) ((1 << 16) * longitude);
4685  altitude_fix = (int32_t) ((1 << 16) * altitude);
4686 
4687  avio_wb32(pb, 0); /* size */
4688  ffio_wfourcc(pb, "loci"); /* type */
4689  avio_wb32(pb, 0); /* version + flags */
4690  avio_wb16(pb, lang);
4691  avio_write(pb, place, strlen(place) + 1);
4692  avio_w8(pb, 0); /* role of place (0 == shooting location, 1 == real location, 2 == fictional location) */
4693  avio_wb32(pb, longitude_fix);
4694  avio_wb32(pb, latitude_fix);
4695  avio_wb32(pb, altitude_fix);
4696  avio_write(pb, astronomical_body, strlen(astronomical_body) + 1);
4697  avio_w8(pb, 0); /* additional notes, null terminated string */
4698 
4699  return update_size(pb, pos);
4700 }
4701 
4702 /* iTunes track or disc number */
4704  AVFormatContext *s, int disc)
4705 {
4706  AVDictionaryEntry *t = av_dict_get(s->metadata,
4707  disc ? "disc" : "track",
4708  NULL, 0);
4709  int size = 0, track = t ? atoi(t->value) : 0;
4710  if (track) {
4711  int tracks = 0;
4712  char *slash = strchr(t->value, '/');
4713  if (slash)
4714  tracks = atoi(slash + 1);
4715  avio_wb32(pb, 32); /* size */
4716  ffio_wfourcc(pb, disc ? "disk" : "trkn");
4717  avio_wb32(pb, 24); /* size */
4718  ffio_wfourcc(pb, "data");
4719  avio_wb32(pb, 0); // 8 bytes empty
4720  avio_wb32(pb, 0);
4721  avio_wb16(pb, 0); // empty
4722  avio_wb16(pb, track); // track / disc number
4723  avio_wb16(pb, tracks); // total track / disc number
4724  avio_wb16(pb, 0); // empty
4725  size = 32;
4726  }
4727  return size;
4728 }
4729 
4731  const char *name, const char *tag,
4732  int len)
4733 {
4734  AVDictionaryEntry *t = NULL;
4735  uint8_t num;
4736  int size = 24 + len;
4737 
4738  if (len != 1 && len != 4)
4739  return -1;
4740 
4741  if (!(t = av_dict_get(s->metadata, tag, NULL, 0)))
4742  return 0;
4743  num = atoi(t->value);
4744 
4745  avio_wb32(pb, size);
4746  ffio_wfourcc(pb, name);
4747  avio_wb32(pb, size - 8);
4748  ffio_wfourcc(pb, "data");
4749  avio_wb32(pb, 0x15);
4750  avio_wb32(pb, 0);
4751  if (len==4) avio_wb32(pb, num);
4752  else avio_w8 (pb, num);
4753 
4754  return size;
4755 }
4756 
4758 {
4759  MOVMuxContext *mov = s->priv_data;
4760  int64_t pos = 0;
4761 
4762  for (int i = 0; i < mov->nb_streams; i++) {
4763  MOVTrack *trk = &mov->tracks[i];
4764 
4765  if (!is_cover_image(trk->st) || trk->cover_image->size <= 0)
4766  continue;
4767 
4768  if (!pos) {
4769  pos = avio_tell(pb);
4770  avio_wb32(pb, 0);
4771  ffio_wfourcc(pb, "covr");
4772  }
4773  avio_wb32(pb, 16 + trk->cover_image->size);
4774  ffio_wfourcc(pb, "data");
4775  avio_wb32(pb, trk->tag);
4776  avio_wb32(pb , 0);
4777  avio_write(pb, trk->cover_image->data, trk->cover_image->size);
4778  }
4779 
4780  return pos ? update_size(pb, pos) : 0;
4781 }
4782 
4783 /* iTunes meta data list */
4785  AVFormatContext *s)
4786 {
4787  int64_t pos = avio_tell(pb);
4788  avio_wb32(pb, 0); /* size */
4789  ffio_wfourcc(pb, "ilst");
4790  mov_write_string_metadata(s, pb, "\251nam", "title" , 1);
4791  mov_write_string_metadata(s, pb, "\251ART", "artist" , 1);
4792  mov_write_string_metadata(s, pb, "aART", "album_artist", 1);
4793  mov_write_string_metadata(s, pb, "\251wrt", "composer" , 1);
4794  mov_write_string_metadata(s, pb, "\251alb", "album" , 1);
4795  mov_write_string_metadata(s, pb, "\251day", "date" , 1);
4796  if (!mov_write_string_metadata(s, pb, "\251too", "encoding_tool", 1)) {
4797  if (!(s->flags & AVFMT_FLAG_BITEXACT))
4798  mov_write_string_tag(pb, "\251too", LIBAVFORMAT_IDENT, 0, 1);
4799  }
4800  mov_write_string_metadata(s, pb, "\251cmt", "comment" , 1);
4801  mov_write_string_metadata(s, pb, "\251gen", "genre" , 1);
4802  mov_write_string_metadata(s, pb, "cprt", "copyright", 1);
4803  mov_write_string_metadata(s, pb, "\251grp", "grouping" , 1);
4804  mov_write_string_metadata(s, pb, "\251lyr", "lyrics" , 1);
4805  mov_write_string_metadata(s, pb, "desc", "description",1);
4806  mov_write_string_metadata(s, pb, "ldes", "synopsis" , 1);
4807  mov_write_string_metadata(s, pb, "tvsh", "show" , 1);
4808  mov_write_string_metadata(s, pb, "tven", "episode_id",1);
4809  mov_write_string_metadata(s, pb, "tvnn", "network" , 1);
4810  mov_write_string_metadata(s, pb, "keyw", "keywords" , 1);
4811  mov_write_int8_metadata (s, pb, "tves", "episode_sort",4);
4812  mov_write_int8_metadata (s, pb, "tvsn", "season_number",4);
4813  mov_write_int8_metadata (s, pb, "stik", "media_type",1);
4814  mov_write_int8_metadata (s, pb, "hdvd", "hd_video", 1);
4815  mov_write_int8_metadata (s, pb, "pgap", "gapless_playback",1);
4816  mov_write_int8_metadata (s, pb, "cpil", "compilation", 1);
4817  mov_write_covr(pb, s);
4818  mov_write_trkn_tag(pb, mov, s, 0); // track number
4819  mov_write_trkn_tag(pb, mov, s, 1); // disc number
4820  mov_write_tmpo_tag(pb, s);
4821  return update_size(pb, pos);
4822 }
4823 
4825  AVFormatContext *s)
4826 {
4827  avio_wb32(pb, 33); /* size */
4828  ffio_wfourcc(pb, "hdlr");
4829  avio_wb32(pb, 0);
4830  avio_wb32(pb, 0);
4831  ffio_wfourcc(pb, "mdta");
4832  avio_wb32(pb, 0);
4833  avio_wb32(pb, 0);
4834  avio_wb32(pb, 0);
4835  avio_w8(pb, 0);
4836  return 33;
4837 }
4838 
4840  AVFormatContext *s)
4841 {
4842  const AVDictionaryEntry *t = NULL;
4843  int64_t pos = avio_tell(pb);
4844  int64_t curpos, entry_pos;
4845  int count = 0;
4846 
4847  avio_wb32(pb, 0); /* size */
4848  ffio_wfourcc(pb, "keys");
4849  avio_wb32(pb, 0);
4850  entry_pos = avio_tell(pb);
4851  avio_wb32(pb, 0); /* entry count */
4852 
4853  while (t = av_dict_iterate(s->metadata, t)) {
4854  size_t key_len = strlen(t->key);
4855  avio_wb32(pb, key_len + 8);
4856  ffio_wfourcc(pb, "mdta");
4857  avio_write(pb, t->key, key_len);
4858  count += 1;
4859  }
4860  curpos = avio_tell(pb);
4861  avio_seek(pb, entry_pos, SEEK_SET);
4862  avio_wb32(pb, count); // rewrite entry count
4863  avio_seek(pb, curpos, SEEK_SET);
4864 
4865  return update_size(pb, pos);
4866 }
4867 
4869  AVFormatContext *s)
4870 {
4871  const AVDictionaryEntry *t = NULL;
4872  int64_t pos = avio_tell(pb);
4873  int count = 1; /* keys are 1-index based */
4874 
4875  avio_wb32(pb, 0); /* size */
4876  ffio_wfourcc(pb, "ilst");
4877 
4878  while (t = av_dict_iterate(s->metadata, t)) {
4879  int64_t entry_pos = avio_tell(pb);
4880  avio_wb32(pb, 0); /* size */
4881  avio_wb32(pb, count); /* key */
4882  mov_write_string_data_tag(pb, t->value, 0, 1);
4883  update_size(pb, entry_pos);
4884  count += 1;
4885  }
4886  return update_size(pb, pos);
4887 }
4888 
4889 /* meta data tags */
4891  AVFormatContext *s)
4892 {
4893  int size = 0;
4894  int64_t pos = avio_tell(pb);
4895  avio_wb32(pb, 0); /* size */
4896  ffio_wfourcc(pb, "meta");
4897  avio_wb32(pb, 0);
4898  if (mov->flags & FF_MOV_FLAG_USE_MDTA) {
4899  mov_write_mdta_hdlr_tag(pb, mov, s);
4900  mov_write_mdta_keys_tag(pb, mov, s);
4901  mov_write_mdta_ilst_tag(pb, mov, s);
4902  } else if (mov->mode == MODE_AVIF) {
4903  mov_write_hdlr_tag(s, pb, &mov->tracks[0]);
4904  // We always write the primary item id as 1 since only one track is
4905  // supported for AVIF.
4906  mov_write_pitm_tag(pb, 1);
4907  mov_write_iloc_tag(pb, mov, s);
4908  mov_write_iinf_tag(pb, mov, s);
4909  if (mov->nb_streams > 1)
4910  mov_write_iref_tag(pb, mov, s);
4911  mov_write_iprp_tag(pb, mov, s);
4912  } else {
4913  /* iTunes metadata tag */
4914  mov_write_itunes_hdlr_tag(pb, mov, s);
4915  mov_write_ilst_tag(pb, mov, s);
4916  }
4917  size = update_size(pb, pos);
4918  return size;
4919 }
4920 
4922  const char *name, const char *key)
4923 {
4924  int len;
4925  AVDictionaryEntry *t;
4926 
4927  if (!(t = av_dict_get(s->metadata, key, NULL, 0)))
4928  return 0;
4929 
4930  len = strlen(t->value);
4931  if (len > 0) {
4932  int size = len + 8;
4933  avio_wb32(pb, size);
4934  ffio_wfourcc(pb, name);
4935  avio_write(pb, t->value, len);
4936  return size;
4937  }
4938  return 0;
4939 }
4940 
4941 static int ascii_to_wc(AVIOContext *pb, const uint8_t *b)
4942 {
4943  int val;
4944  while (*b) {
4945  GET_UTF8(val, *b++, return -1;)
4946  avio_wb16(pb, val);
4947  }
4948  avio_wb16(pb, 0x00);
4949  return 0;
4950 }
4951 
4952 static uint16_t language_code(const char *str)
4953 {
4954  return (((str[0] - 0x60) & 0x1F) << 10) +
4955  (((str[1] - 0x60) & 0x1F) << 5) +
4956  (( str[2] - 0x60) & 0x1F);
4957 }
4958 
4960  const char *tag, const char *str)
4961 {
4962  int64_t pos = avio_tell(pb);
4963  AVDictionaryEntry *t = av_dict_get(s->metadata, str, NULL, 0);
4964  if (!t || !utf8len(t->value))
4965  return 0;
4966  avio_wb32(pb, 0); /* size */
4967  ffio_wfourcc(pb, tag); /* type */
4968  avio_wb32(pb, 0); /* version + flags */
4969  if (!strcmp(tag, "yrrc"))
4970  avio_wb16(pb, atoi(t->value));
4971  else {
4972  avio_wb16(pb, language_code("eng")); /* language */
4973  avio_write(pb, t->value, strlen(t->value) + 1); /* UTF8 string value */
4974  if (!strcmp(tag, "albm") &&
4975  (t = av_dict_get(s->metadata, "track", NULL, 0)))
4976  avio_w8(pb, atoi(t->value));
4977  }
4978  return update_size(pb, pos);
4979 }
4980 
4982 {
4983  int64_t pos = avio_tell(pb);
4984  int i, nb_chapters = FFMIN(s->nb_chapters, 255);
4985 
4986  avio_wb32(pb, 0); // size
4987  ffio_wfourcc(pb, "chpl");
4988  avio_wb32(pb, 0x01000000); // version + flags
4989  avio_wb32(pb, 0); // unknown
4990  avio_w8(pb, nb_chapters);
4991 
4992  for (i = 0; i < nb_chapters; i++) {
4993  AVChapter *c = s->chapters[i];
4994  AVDictionaryEntry *t;
4995  avio_wb64(pb, av_rescale_q(c->start, c->time_base, (AVRational){1,10000000}));
4996 
4997  if ((t = av_dict_get(c->metadata, "title", NULL, 0))) {
4998  int len = FFMIN(strlen(t->value), 255);
4999  avio_w8(pb, len);
5000  avio_write(pb, t->value, len);
5001  } else
5002  avio_w8(pb, 0);
5003  }
5004  return update_size(pb, pos);
5005 }
5006 
5008  AVFormatContext *s)
5009 {
5010  AVIOContext *pb_buf;
5011  int ret, size;
5012  uint8_t *buf;
5013 
5014  ret = avio_open_dyn_buf(&pb_buf);
5015  if (ret < 0)
5016  return ret;
5017 
5018  if (mov->mode & MODE_3GP) {
5019  mov_write_3gp_udta_tag(pb_buf, s, "perf", "artist");
5020  mov_write_3gp_udta_tag(pb_buf, s, "titl", "title");
5021  mov_write_3gp_udta_tag(pb_buf, s, "auth", "author");
5022  mov_write_3gp_udta_tag(pb_buf, s, "gnre", "genre");
5023  mov_write_3gp_udta_tag(pb_buf, s, "dscp", "comment");
5024  mov_write_3gp_udta_tag(pb_buf, s, "albm", "album");
5025  mov_write_3gp_udta_tag(pb_buf, s, "cprt", "copyright");
5026  mov_write_3gp_udta_tag(pb_buf, s, "yrrc", "date");
5027  mov_write_loci_tag(s, pb_buf);
5028  } 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
5029  mov_write_string_metadata(s, pb_buf, "\251ART", "artist", 0);
5030  mov_write_string_metadata(s, pb_buf, "\251nam", "title", 0);
5031  mov_write_string_metadata(s, pb_buf, "\251aut", "author", 0);
5032  mov_write_string_metadata(s, pb_buf, "\251alb", "album", 0);
5033  mov_write_string_metadata(s, pb_buf, "\251day", "date", 0);
5034  mov_write_string_metadata(s, pb_buf, "\251swr", "encoder", 0);
5035  // currently ignored by mov.c
5036  mov_write_string_metadata(s, pb_buf, "\251des", "comment", 0);
5037  // add support for libquicktime, this atom is also actually read by mov.c
5038  mov_write_string_metadata(s, pb_buf, "\251cmt", "comment", 0);
5039  mov_write_string_metadata(s, pb_buf, "\251gen", "genre", 0);
5040  mov_write_string_metadata(s, pb_buf, "\251cpy", "copyright", 0);
5041  mov_write_string_metadata(s, pb_buf, "\251mak", "make", 0);
5042  mov_write_string_metadata(s, pb_buf, "\251mod", "model", 0);
5043  mov_write_string_metadata(s, pb_buf, "\251xyz", "location", 0);
5044  mov_write_string_metadata(s, pb_buf, "\251key", "keywords", 0);
5045  mov_write_raw_metadata_tag(s, pb_buf, "XMP_", "xmp");
5046  } else {
5047  /* iTunes meta data */
5048  mov_write_meta_tag(pb_buf, mov, s);
5049  mov_write_loci_tag(s, pb_buf);
5050  }
5051 
5052  if (s->nb_chapters && !(mov->flags & FF_MOV_FLAG_DISABLE_CHPL))
5053  mov_write_chpl_tag(pb_buf, s);
5054 
5055  if ((size = avio_get_dyn_buf(pb_buf, &buf)) > 0) {
5056  avio_wb32(pb, size + 8);
5057  ffio_wfourcc(pb, "udta");
5058  avio_write(pb, buf, size);
5059  }
5060  ffio_free_dyn_buf(&pb_buf);
5061 
5062  return 0;
5063 }
5064 
5066  const char *str, const char *lang, int type)
5067 {
5068  int len = utf8len(str) + 1;
5069  if (len <= 0)
5070  return;
5071  avio_wb16(pb, len * 2 + 10); /* size */
5072  avio_wb32(pb, type); /* type */
5073  avio_wb16(pb, language_code(lang)); /* language */
5074  avio_wb16(pb, 0x01); /* ? */
5075  ascii_to_wc(pb, str);
5076 }
5077 
5079 {
5080  AVDictionaryEntry *title = av_dict_get(s->metadata, "title", NULL, 0);
5081  int64_t pos, pos2;
5082 
5083  if (title) {
5084  pos = avio_tell(pb);
5085  avio_wb32(pb, 0); /* size placeholder*/
5086  ffio_wfourcc(pb, "uuid");
5087  ffio_wfourcc(pb, "USMT");
5088  avio_wb32(pb, 0x21d24fce); /* 96 bit UUID */
5089  avio_wb32(pb, 0xbb88695c);
5090  avio_wb32(pb, 0xfac9c740);
5091 
5092  pos2 = avio_tell(pb);
5093  avio_wb32(pb, 0); /* size placeholder*/
5094  ffio_wfourcc(pb, "MTDT");
5095  avio_wb16(pb, 4);
5096 
5097  // ?
5098  avio_wb16(pb, 0x0C); /* size */
5099  avio_wb32(pb, 0x0B); /* type */
5100  avio_wb16(pb, language_code("und")); /* language */
5101  avio_wb16(pb, 0x0); /* ? */
5102  avio_wb16(pb, 0x021C); /* data */
5103 
5104  if (!(s->flags & AVFMT_FLAG_BITEXACT))
5105  mov_write_psp_udta_tag(pb, LIBAVFORMAT_IDENT, "eng", 0x04);
5106  mov_write_psp_udta_tag(pb, title->value, "eng", 0x01);
5107  mov_write_psp_udta_tag(pb, "2006/04/01 11:11:11", "und", 0x03);
5108 
5109  update_size(pb, pos2);
5110  return update_size(pb, pos);
5111  }
5112 
5113  return 0;
5114 }
5115 
5117 {
5122  if (!sd)
5123  return 0;
5124 
5126  for (AVEncryptionInitInfo *copy = info; copy; copy = copy->next) {
5127  int64_t pos;
5128 
5129  if (!copy->data_size && !copy->num_key_ids)
5130  continue;
5131 
5132  pos = avio_tell(pb);
5133  avio_wb32(pb, 0); /* size placeholder */
5134  ffio_wfourcc(pb, "pssh");
5135  avio_w8(pb, 1); /* version */
5136  avio_wb24(pb, 0);
5137  for (int i = 0; i < copy->system_id_size; i++)
5138  avio_w8(pb, copy->system_id[i]);
5139  avio_wb32(pb, copy->num_key_ids);
5140  for (int i = 0; i < copy->num_key_ids; i++)
5141  for (int j = 0; j < copy->key_id_size; j++)
5142  avio_w8(pb, copy->key_ids[i][j]);
5143  avio_wb32(pb, copy->data_size);
5144  avio_write(pb, copy->data, copy->data_size);
5145  update_size(pb, pos);
5146  }
5147 
5149 
5150  return 0;
5151 }
5152 
5153 static void build_chunks(MOVTrack *trk)
5154 {
5155  int i;
5156  MOVIentry *chunk = &trk->cluster[0];
5157  uint64_t chunkSize = chunk->size;
5158  chunk->chunkNum = 1;
5159  if (trk->chunkCount)
5160  return;
5161  trk->chunkCount = 1;
5162  for (i = 1; i<trk->entry; i++){
5163  if (chunk->pos + chunkSize == trk->cluster[i].pos &&
5164  chunk->stsd_index == trk->cluster[i].stsd_index &&
5165  chunkSize + trk->cluster[i].size < (1<<20)){
5166  chunkSize += trk->cluster[i].size;
5167  chunk->samples_in_chunk += trk->cluster[i].entries;
5168  } else {
5169  trk->cluster[i].chunkNum = chunk->chunkNum+1;
5170  chunk=&trk->cluster[i];
5171  chunkSize = chunk->size;
5172  trk->chunkCount++;
5173  }
5174  }
5175 }
5176 
5177 /**
5178  * Assign track ids. If option "use_stream_ids_as_track_ids" is set,
5179  * the stream ids are used as track ids.
5180  *
5181  * This assumes mov->tracks and s->streams are in the same order and
5182  * there are no gaps in either of them (so mov->tracks[n] refers to
5183  * s->streams[n]).
5184  *
5185  * As an exception, there can be more entries in
5186  * s->streams than in mov->tracks, in which case new track ids are
5187  * generated (starting after the largest found stream id).
5188  */
5190 {
5191  int i;
5192 
5193  if (mov->track_ids_ok)
5194  return 0;
5195 
5196  if (mov->use_stream_ids_as_track_ids) {
5197  int next_generated_track_id = 0;
5198  for (i = 0; i < mov->nb_streams; i++) {
5199  AVStream *st = mov->tracks[i].st;
5200  if (st->id > next_generated_track_id)
5201  next_generated_track_id = st->id;
5202  }
5203 
5204  for (i = 0; i < mov->nb_tracks; i++) {
5205  if (mov->tracks[i].entry <= 0 && !(mov->flags & FF_MOV_FLAG_FRAGMENT))
5206  continue;
5207 
5208  mov->tracks[i].track_id = i >= mov->nb_streams ? ++next_generated_track_id : mov->tracks[i].st->id;
5209  }
5210  } else {
5211  int last_track_id = 0;
5212  for (i = 0; i < mov->nb_tracks; i++) {
5213  if (mov->tracks[i].entry <= 0 && !(mov->flags & FF_MOV_FLAG_FRAGMENT))
5214  continue;
5215 
5216  last_track_id =
5217  mov->tracks[i].track_id = (mov->tracks[i].st
5218  ? FFMAX(mov->tracks[i].st->index, last_track_id)
5219  : FFMAX(i, last_track_id)) + 1;
5220  }
5221  }
5222 
5223  mov->track_ids_ok = 1;
5224 
5225  return 0;
5226 }
5227 
5228 static int mov_find_tref_id(MOVMuxContext *mov, const MovTag *tag, uint32_t id)
5229 {
5230  for (int i = 0; i < tag->nb_id; i++) {
5231  if (tag->id[i] == id)
5232  return 1;
5233  }
5234  return 0;
5235 }
5236 
5237 static int mov_add_tref_id(MOVMuxContext *mov, MovTag *tag, uint32_t id)
5238 {
5239  int ret = mov_find_tref_id(mov, tag, id);
5240 
5241  if (!ret) {
5242  uint32_t *tmp = av_realloc_array(tag->id, tag->nb_id + 1, sizeof(*tag->id));
5243  if (!tmp)
5244  return AVERROR(ENOMEM);
5245  tag->id = tmp;
5246  tag->id[tag->nb_id++] = id;
5247  }
5248 
5249  return 0;
5250 }
5251 
5252 static MovTag *mov_find_tref_tag(MOVMuxContext *mov, const MOVTrack *trk, uint32_t name)
5253 {
5254  for (int i = 0; i < trk->nb_tref_tags; i++) {
5255  MovTag *entry = &trk->tref_tags[i];
5256 
5257  if (entry->name == name)
5258  return entry;
5259  }
5260  return NULL;
5261 }
5262 
5263 static MovTag *mov_add_tref_tag(MOVMuxContext *mov, MOVTrack *trk, uint32_t name)
5264 {
5265  MovTag *tag = mov_find_tref_tag(mov, trk, name);
5266 
5267  if (!tag) {
5268  MovTag *tmp = av_realloc_array(trk->tref_tags, trk->nb_tref_tags + 1,
5269  sizeof(*trk->tref_tags));
5270  if (!tmp)
5271  return NULL;
5272  trk->tref_tags = tmp;
5273  tag = &trk->tref_tags[trk->nb_tref_tags++];
5274  *tag = (MovTag){ .name = name };
5275  }
5276 
5277  return tag;
5278 }
5279 
5281  AVFormatContext *s)
5282 {
5283  int i;
5284  int64_t pos = avio_tell(pb);
5285  avio_wb32(pb, 0); /* size placeholder*/
5286  ffio_wfourcc(pb, "moov");
5287 
5288  mov_setup_track_ids(mov, s);
5289 
5290  for (i = 0; i < mov->nb_tracks; i++) {
5291  if (mov->tracks[i].entry <= 0 && !(mov->flags & FF_MOV_FLAG_FRAGMENT))
5292  continue;
5293 
5294  mov->tracks[i].time = mov->time;
5295 
5296  if (mov->tracks[i].entry)
5297  build_chunks(&mov->tracks[i]);
5298  }
5299 
5300  if (mov->chapter_track)
5301  for (i = 0; i < mov->nb_streams; i++) {
5302  MovTag *tag = mov_add_tref_tag(mov, &mov->tracks[i], MKTAG('c','h','a','p'));
5303  if (!tag)
5304  return AVERROR(ENOMEM);
5305 
5306  int ret = mov_add_tref_id(mov, tag, mov->tracks[mov->chapter_track].track_id);
5307  if (ret < 0)
5308  return ret;
5309  }
5310  for (i = 0; i < mov->nb_tracks; i++) {
5311  MOVTrack *track = &mov->tracks[i];
5312  if (track->tag == MKTAG('r','t','p',' ')) {
5313  MovTag *tag = mov_add_tref_tag(mov, track, MKTAG('h','i','n','t'));
5314  if (!tag)
5315  return AVERROR(ENOMEM);
5316 
5317  av_assert0(track->nb_src_track);
5318  int ret = mov_add_tref_id(mov, tag, mov->tracks[*track->src_track].track_id);
5319  if (ret < 0)
5320  return ret;
5321  } else if (track->tag == MKTAG('l','v','c','1') && track->nb_src_track) {
5322  MovTag *tag = mov_add_tref_tag(mov, track, MKTAG('s','b','a','s'));
5323  if (!tag)
5324  return AVERROR(ENOMEM);
5325 
5326  int ret = mov_add_tref_id(mov, tag, mov->tracks[*track->src_track].track_id);
5327  if (ret < 0)
5328  return ret;
5329  } else {
5330  if (track->par->codec_type == AVMEDIA_TYPE_AUDIO) {
5332  track->st->codecpar->nb_coded_side_data,
5334  if (sd && sd->size == sizeof(int)) {
5335  int *fallback = (int *)sd->data;
5336  if (*fallback >= 0 && *fallback < mov->nb_tracks) {
5337  MovTag *tag = mov_add_tref_tag(mov, track, MKTAG('f','a','l','l'));
5338  if (!tag)
5339  return AVERROR(ENOMEM);
5340 
5341  int ret = mov_add_tref_id(mov, tag, mov->tracks[*fallback].track_id);
5342  if (ret < 0)
5343  return ret;
5344  }
5345  }
5346  }
5347  for (int j = 0; j < track->nb_src_track; j++) {
5348  int src_trk = track->src_track[j];
5349  MovTag *tag = mov_add_tref_tag(mov, &mov->tracks[src_trk], track->tag);
5350  if (!tag)
5351  return AVERROR(ENOMEM);
5352  int ret = mov_add_tref_id(mov, tag, track->track_id);
5353  if (ret < 0)
5354  return ret;
5355  //src_trk may have a different timescale than the tmcd track
5356  track->track_duration = av_rescale(mov->tracks[src_trk].track_duration,
5357  track->timescale,
5358  mov->tracks[src_trk].timescale);
5359  }
5360  }
5361  }
5362 
5363  mov_write_mvhd_tag(pb, mov);
5364  if (mov->mode != MODE_MOV && mov->mode != MODE_AVIF && !mov->iods_skip)
5365  mov_write_iods_tag(pb, mov);
5366  for (i = 0; i < mov->nb_tracks; i++) {
5367  if (mov->tracks[i].entry > 0 || mov->flags & FF_MOV_FLAG_FRAGMENT ||
5368  mov->mode == MODE_AVIF) {
5369  int ret = mov_write_trak_tag(s, pb, mov, &(mov->tracks[i]), i < mov->nb_streams ? mov->tracks[i].st : NULL);
5370  if (ret < 0)
5371  return ret;
5372  }
5373  }
5374  /* Don't write mvex for hybrid_fragmented during mov_write_trailer
5375  * (mov->moov_written != 0)
5376  */
5377  if (mov->flags & FF_MOV_FLAG_FRAGMENT &&
5379  mov_write_mvex_tag(pb, mov); /* QuickTime requires trak to precede this */
5380 
5381  if (mov->mode == MODE_PSP)
5383  else if (mov->mode != MODE_AVIF)
5384  mov_write_udta_tag(pb, mov, s);
5385  for (i = 0; i < mov->nb_streams; i++)
5386  mov_write_pssh_tag(pb, mov->tracks[i].st);
5387 
5388  return update_size(pb, pos);
5389 }
5390 
5391 static void param_write_int(AVIOContext *pb, const char *name, int value)
5392 {
5393  avio_printf(pb, "<param name=\"%s\" value=\"%d\" valuetype=\"data\"/>\n", name, value);
5394 }
5395 
5396 static void param_write_string(AVIOContext *pb, const char *name, const char *value)
5397 {
5398  avio_printf(pb, "<param name=\"%s\" value=\"%s\" valuetype=\"data\"/>\n", name, value);
5399 }
5400 
5401 static void param_write_hex(AVIOContext *pb, const char *name, const uint8_t *value, int len)
5402 {
5403  char buf[150];
5404  len = FFMIN(sizeof(buf) / 2 - 1, len);
5405  ff_data_to_hex(buf, value, len, 0);
5406  avio_printf(pb, "<param name=\"%s\" value=\"%s\" valuetype=\"data\"/>\n", name, buf);
5407 }
5408 
5410 {
5411  int64_t pos = avio_tell(pb);
5412  int i;
5413 
5414  static const AVUUID uuid = {
5415  0xa5, 0xd4, 0x0b, 0x30, 0xe8, 0x14, 0x11, 0xdd,
5416  0xba, 0x2f, 0x08, 0x00, 0x20, 0x0c, 0x9a, 0x66
5417  };
5418 
5419  avio_wb32(pb, 0);
5420  ffio_wfourcc(pb, "uuid");
5421  avio_write(pb, uuid, AV_UUID_LEN);
5422  avio_wb32(pb, 0);
5423 
5424  avio_printf(pb, "<?xml version=\"1.0\" encoding=\"utf-8\"?>\n");
5425  avio_printf(pb, "<smil xmlns=\"http://www.w3.org/2001/SMIL20/Language\">\n");
5426  avio_printf(pb, "<head>\n");
5427  if (!(mov->fc->flags & AVFMT_FLAG_BITEXACT))
5428  avio_printf(pb, "<meta name=\"creator\" content=\"%s\" />\n",
5430  avio_printf(pb, "</head>\n");
5431  avio_printf(pb, "<body>\n");
5432  avio_printf(pb, "<switch>\n");
5433 
5434  mov_setup_track_ids(mov, s);
5435 
5436  for (i = 0; i < mov->nb_tracks; i++) {
5437  MOVTrack *track = &mov->tracks[i];
5438  struct mpeg4_bit_rate_values bit_rates =
5440  const char *type;
5441  int track_id = track->track_id;
5442  char track_name_buf[32] = { 0 };
5443 
5444  AVStream *st = track->st;
5445  AVDictionaryEntry *lang = av_dict_get(st->metadata, "language", NULL,0);
5446 
5447  if (track->par->codec_type == AVMEDIA_TYPE_VIDEO && !is_cover_image(st)) {
5448  type = "video";
5449  } else if (track->par->codec_type == AVMEDIA_TYPE_AUDIO) {
5450  type = "audio";
5451  } else {
5452  continue;
5453  }
5454 
5455  avio_printf(pb, "<%s systemBitrate=\"%"PRIu32"\">\n", type,
5456  bit_rates.avg_bit_rate);
5457  param_write_int(pb, "systemBitrate", bit_rates.avg_bit_rate);
5458  param_write_int(pb, "trackID", track_id);
5459  param_write_string(pb, "systemLanguage", lang ? lang->value : "und");
5460 
5461  /* Build track name piece by piece: */
5462  /* 1. track type */
5463  av_strlcat(track_name_buf, type, sizeof(track_name_buf));
5464  /* 2. track language, if available */
5465  if (lang)
5466  av_strlcatf(track_name_buf, sizeof(track_name_buf),
5467  "_%s", lang->value);
5468  /* 3. special type suffix */
5469  /* "_cc" = closed captions, "_ad" = audio_description */
5471  av_strlcat(track_name_buf, "_cc", sizeof(track_name_buf));
5473  av_strlcat(track_name_buf, "_ad", sizeof(track_name_buf));
5474 
5475  param_write_string(pb, "trackName", track_name_buf);
5476 
5477  if (track->par->codec_type == AVMEDIA_TYPE_VIDEO) {
5478  if (track->par->codec_id == AV_CODEC_ID_H264) {
5479  uint8_t *ptr;
5480  int size = track->extradata_size[track->last_stsd_index];
5481  if (!ff_avc_write_annexb_extradata(track->extradata[track->last_stsd_index], &ptr,
5482  &size)) {
5483  param_write_hex(pb, "CodecPrivateData",
5484  ptr ? ptr : track->extradata[track->last_stsd_index],
5485  size);
5486  av_free(ptr);
5487  }
5488  param_write_string(pb, "FourCC", "H264");
5489  } else if (track->par->codec_id == AV_CODEC_ID_VC1) {
5490  param_write_string(pb, "FourCC", "WVC1");
5491  param_write_hex(pb, "CodecPrivateData", track->extradata[track->last_stsd_index],
5492  track->extradata_size[track->last_stsd_index]);
5493  }
5494  param_write_int(pb, "MaxWidth", track->par->width);
5495  param_write_int(pb, "MaxHeight", track->par->height);
5496  param_write_int(pb, "DisplayWidth", track->par->width);
5497  param_write_int(pb, "DisplayHeight", track->par->height);
5498  } else {
5499  if (track->par->codec_id == AV_CODEC_ID_AAC) {
5500  switch (track->par->profile) {
5501  case AV_PROFILE_AAC_HE_V2:
5502  param_write_string(pb, "FourCC", "AACP");
5503  break;
5504  case AV_PROFILE_AAC_HE:
5505  param_write_string(pb, "FourCC", "AACH");
5506  break;
5507  default:
5508  param_write_string(pb, "FourCC", "AACL");
5509  }
5510  } else if (track->par->codec_id == AV_CODEC_ID_WMAPRO) {
5511  param_write_string(pb, "FourCC", "WMAP");
5512  }
5513  param_write_hex(pb, "CodecPrivateData", track->extradata[track->last_stsd_index],
5514  track->extradata_size[track->last_stsd_index]);
5516  track->par->codec_id));
5517  param_write_int(pb, "Channels", track->par->ch_layout.nb_channels);
5518  param_write_int(pb, "SamplingRate", track->tag == MKTAG('i','a','m','f') ?
5519  0 : track->par->sample_rate);
5520  param_write_int(pb, "BitsPerSample", 16);
5521  param_write_int(pb, "PacketSize", track->par->block_align ?
5522  track->par->block_align : 4);
5523  }
5524  avio_printf(pb, "</%s>\n", type);
5525  }
5526  avio_printf(pb, "</switch>\n");
5527  avio_printf(pb, "</body>\n");
5528  avio_printf(pb, "</smil>\n");
5529 
5530  return update_size(pb, pos);
5531 }
5532 
5534 {
5535  avio_wb32(pb, 16);
5536  ffio_wfourcc(pb, "mfhd");
5537  avio_wb32(pb, 0);
5538  avio_wb32(pb, mov->fragments);
5539  return 0;
5540 }
5541 
5542 static uint32_t get_sample_flags(MOVTrack *track, MOVIentry *entry)
5543 {
5546 }
5547 
5549  MOVTrack *track, int64_t moof_offset)
5550 {
5551  int64_t pos = avio_tell(pb);
5554  if (!track->entry) {
5556  } else {
5558  }
5561  if (mov->flags & FF_MOV_FLAG_DEFAULT_BASE_MOOF) {
5564  }
5565  /* CMAF requires all values to be explicit in tfhd atoms */
5566  if (mov->flags & FF_MOV_FLAG_CMAF)
5568 
5569  /* Don't set a default sample size, the silverlight player refuses
5570  * to play files with that set. Don't set a default sample duration,
5571  * WMP freaks out if it is set. Don't set a base data offset, PIFF
5572  * file format says it MUST NOT be set. */
5573  if (track->mode == MODE_ISM)
5576 
5577  avio_wb32(pb, 0); /* size placeholder */
5578  ffio_wfourcc(pb, "tfhd");
5579  avio_w8(pb, 0); /* version */
5580  avio_wb24(pb, flags);
5581 
5582  avio_wb32(pb, track->track_id); /* track-id */
5584  avio_wb64(pb, moof_offset);
5585  if (flags & MOV_TFHD_STSD_ID) {
5586  avio_wb32(pb, 1);
5587  }
5589  track->default_duration = get_cluster_duration(track, 0);
5590  avio_wb32(pb, track->default_duration);
5591  }
5592  if (flags & MOV_TFHD_DEFAULT_SIZE) {
5593  track->default_size = track->entry ? track->cluster[0].size : 1;
5594  avio_wb32(pb, track->default_size);
5595  } else
5596  track->default_size = -1;
5597 
5598  if (flags & MOV_TFHD_DEFAULT_FLAGS) {
5599  /* Set the default flags based on the second sample, if available.
5600  * If the first sample is different, that can be signaled via a separate field. */
5601  if (track->entry > 1)
5602  track->default_sample_flags = get_sample_flags(track, &track->cluster[1]);
5603  else
5604  track->default_sample_flags =
5605  track->par->codec_type == AVMEDIA_TYPE_VIDEO ?
5608  avio_wb32(pb, track->default_sample_flags);
5609  }
5610 
5611  return update_size(pb, pos);
5612 }
5613 
5615  MOVTrack *track, int moof_size,
5616  int first, int end)
5617 {
5618  int64_t pos = avio_tell(pb);
5619  uint32_t flags = MOV_TRUN_DATA_OFFSET;
5620  int i;
5621 
5622  for (i = first; i < end; i++) {
5623  if (get_cluster_duration(track, i) != track->default_duration)
5625  if (track->cluster[i].size != track->default_size)
5627  if (i > first && get_sample_flags(track, &track->cluster[i]) != track->default_sample_flags)
5629  }
5630  if (!(flags & MOV_TRUN_SAMPLE_FLAGS) && track->entry > first &&
5631  get_sample_flags(track, &track->cluster[first]) != track->default_sample_flags)
5633  if (track->flags & MOV_TRACK_CTTS)
5635 
5636  avio_wb32(pb, 0); /* size placeholder */
5637  ffio_wfourcc(pb, "trun");
5639  avio_w8(pb, 1); /* version */
5640  else
5641  avio_w8(pb, 0); /* version */
5642  avio_wb24(pb, flags);
5643 
5644  avio_wb32(pb, end - first); /* sample count */
5645  if (mov->flags & FF_MOV_FLAG_OMIT_TFHD_OFFSET &&
5647  !mov->first_trun)
5648  avio_wb32(pb, 0); /* Later tracks follow immediately after the previous one */
5649  else
5650  avio_wb32(pb, moof_size + 8 + track->data_offset +
5651  track->cluster[first].pos); /* data offset */
5653  avio_wb32(pb, get_sample_flags(track, &track->cluster[first]));
5654 
5655  for (i = first; i < end; i++) {
5657  avio_wb32(pb, get_cluster_duration(track, i));
5659  avio_wb32(pb, track->cluster[i].size);
5661  avio_wb32(pb, get_sample_flags(track, &track->cluster[i]));
5662  if (flags & MOV_TRUN_SAMPLE_CTS)
5663  avio_wb32(pb, track->cluster[i].cts);
5664  }
5665 
5666  mov->first_trun = 0;
5667  return update_size(pb, pos);
5668 }
5669 
5670 static int mov_write_tfxd_tag(AVIOContext *pb, MOVTrack *track)
5671 {
5672  int64_t pos = avio_tell(pb);
5673  static const uint8_t uuid[] = {
5674  0x6d, 0x1d, 0x9b, 0x05, 0x42, 0xd5, 0x44, 0xe6,
5675  0x80, 0xe2, 0x14, 0x1d, 0xaf, 0xf7, 0x57, 0xb2
5676  };
5677 
5678  avio_wb32(pb, 0); /* size placeholder */
5679  ffio_wfourcc(pb, "uuid");
5680  avio_write(pb, uuid, AV_UUID_LEN);
5681  avio_w8(pb, 1);
5682  avio_wb24(pb, 0);
5683  avio_wb64(pb, track->cluster[0].dts + track->cluster[0].cts);
5684  avio_wb64(pb, track->end_pts -
5685  (track->cluster[0].dts + track->cluster[0].cts));
5686 
5687  return update_size(pb, pos);
5688 }
5689 
5691  MOVTrack *track, int entry)
5692 {
5693  int n = track->nb_frag_info - 1 - entry, i;
5694  int size = 8 + 16 + 4 + 1 + 16*n;
5695  static const uint8_t uuid[] = {
5696  0xd4, 0x80, 0x7e, 0xf2, 0xca, 0x39, 0x46, 0x95,
5697  0x8e, 0x54, 0x26, 0xcb, 0x9e, 0x46, 0xa7, 0x9f
5698  };
5699 
5700  if (entry < 0)
5701  return 0;
5702 
5703  avio_seek(pb, track->frag_info[entry].tfrf_offset, SEEK_SET);
5704  avio_wb32(pb, size);
5705  ffio_wfourcc(pb, "uuid");
5706  avio_write(pb, uuid, AV_UUID_LEN);
5707  avio_w8(pb, 1);
5708  avio_wb24(pb, 0);
5709  avio_w8(pb, n);
5710  for (i = 0; i < n; i++) {
5711  int index = entry + 1 + i;
5712  avio_wb64(pb, track->frag_info[index].time);
5713  avio_wb64(pb, track->frag_info[index].duration);
5714  }
5715  if (n < mov->ism_lookahead) {
5716  int free_size = 16 * (mov->ism_lookahead - n);
5717  avio_wb32(pb, free_size);
5718  ffio_wfourcc(pb, "free");
5719  ffio_fill(pb, 0, free_size - 8);
5720  }
5721 
5722  return 0;
5723 }
5724 
5726  MOVTrack *track)
5727 {
5728  int64_t pos = avio_tell(pb);
5729  int i;
5730  for (i = 0; i < mov->ism_lookahead; i++) {
5731  /* Update the tfrf tag for the last ism_lookahead fragments,
5732  * nb_frag_info - 1 is the next fragment to be written. */
5733  mov_write_tfrf_tag(pb, mov, track, track->nb_frag_info - 2 - i);
5734  }
5735  avio_seek(pb, pos, SEEK_SET);
5736  return 0;
5737 }
5738 
5739 static int mov_add_tfra_entries(AVIOContext *pb, MOVMuxContext *mov, int tracks,
5740  int size)
5741 {
5742  int i;
5743  for (i = 0; i < mov->nb_tracks; i++) {
5744  MOVTrack *track = &mov->tracks[i];
5746  if ((tracks >= 0 && i != tracks) || !track->entry)
5747  continue;
5748  track->nb_frag_info++;
5749  if (track->nb_frag_info >= track->frag_info_capacity) {
5750  unsigned new_capacity = track->nb_frag_info + MOV_FRAG_INFO_ALLOC_INCREMENT;
5751  if (av_reallocp_array(&track->frag_info,
5752  new_capacity,
5753  sizeof(*track->frag_info)))
5754  return AVERROR(ENOMEM);
5755  track->frag_info_capacity = new_capacity;
5756  }
5757  info = &track->frag_info[track->nb_frag_info - 1];
5758  info->offset = avio_tell(pb);
5759  info->size = size;
5760  // Try to recreate the original pts for the first packet
5761  // from the fields we have stored
5762  info->time = track->cluster[0].dts + track->cluster[0].cts;
5763  info->duration = track->end_pts -
5764  (track->cluster[0].dts + track->cluster[0].cts);
5765  // If the pts is less than zero, we will have trimmed
5766  // away parts of the media track using an edit list,
5767  // and the corresponding start presentation time is zero.
5768  if (info->time < 0) {
5769  info->duration += info->time;
5770  info->time = 0;
5771  }
5772  info->tfrf_offset = 0;
5773  mov_write_tfrf_tags(pb, mov, track);
5774  }
5775  return 0;
5776 }
5777 
5778 static void mov_prune_frag_info(MOVMuxContext *mov, int tracks, int max)
5779 {
5780  int i;
5781  for (i = 0; i < mov->nb_tracks; i++) {
5782  MOVTrack *track = &mov->tracks[i];
5783  if ((tracks >= 0 && i != tracks) || !track->entry)
5784  continue;
5785  if (track->nb_frag_info > max) {
5786  memmove(track->frag_info, track->frag_info + (track->nb_frag_info - max), max * sizeof(*track->frag_info));
5787  track->nb_frag_info = max;
5788  }
5789  }
5790 }
5791 
5792 static int mov_write_tfdt_tag(AVIOContext *pb, MOVTrack *track)
5793 {
5794  int64_t pos = avio_tell(pb);
5795 
5796  avio_wb32(pb, 0); /* size */
5797  ffio_wfourcc(pb, "tfdt");
5798  avio_w8(pb, 1); /* version */
5799  avio_wb24(pb, 0);
5800  avio_wb64(pb, track->cluster[0].dts - track->start_dts);
5801  return update_size(pb, pos);
5802 }
5803 
5805  MOVTrack *track, int64_t moof_offset,
5806  int moof_size)
5807 {
5808  int64_t pos = avio_tell(pb);
5809  int i, start = 0;
5810  avio_wb32(pb, 0); /* size placeholder */
5811  ffio_wfourcc(pb, "traf");
5812 
5813  mov_write_tfhd_tag(pb, mov, track, moof_offset);
5814  if (mov->mode != MODE_ISM)
5815  mov_write_tfdt_tag(pb, track);
5816  for (i = 1; i < track->entry; i++) {
5817  if (track->cluster[i].pos != track->cluster[i - 1].pos + track->cluster[i - 1].size) {
5818  mov_write_trun_tag(pb, mov, track, moof_size, start, i);
5819  start = i;
5820  }
5821  }
5822  mov_write_trun_tag(pb, mov, track, moof_size, start, track->entry);
5823  if (mov->mode == MODE_ISM) {
5824  mov_write_tfxd_tag(pb, track);
5825 
5826  if (mov->ism_lookahead) {
5827  int size = 16 + 4 + 1 + 16 * mov->ism_lookahead;
5828 
5829  if (track->nb_frag_info > 0) {
5830  MOVFragmentInfo *info = &track->frag_info[track->nb_frag_info - 1];
5831  if (!info->tfrf_offset)
5832  info->tfrf_offset = avio_tell(pb);
5833  }
5834  avio_wb32(pb, 8 + size);
5835  ffio_wfourcc(pb, "free");
5836  ffio_fill(pb, 0, size);
5837  }
5838  }
5839 
5840  if (track->cenc.aes_ctr && (mov->flags & FF_MOV_FLAG_FRAGMENT))
5841  ff_mov_cenc_write_stbl_atoms(&track->cenc, pb, moof_offset);
5842 
5843  return update_size(pb, pos);
5844 }
5845 
5847  int tracks, int moof_size)
5848 {
5849  int64_t pos = avio_tell(pb);
5850  int i;
5851 
5852  avio_wb32(pb, 0); /* size placeholder */
5853  ffio_wfourcc(pb, "moof");
5854  mov->first_trun = 1;
5855 
5856  mov_write_mfhd_tag(pb, mov);
5857  for (i = 0; i < mov->nb_tracks; i++) {
5858  MOVTrack *track = &mov->tracks[i];
5859  if (tracks >= 0 && i != tracks)
5860  continue;
5861  if (!track->entry)
5862  continue;
5863  if (track->cenc.aes_ctr && (mov->flags & FF_MOV_FLAG_FRAGMENT))
5864  mov_write_pssh_tag(pb, track->st);
5865  mov_write_traf_tag(pb, mov, track, pos, moof_size);
5866  }
5867 
5868  return update_size(pb, pos);
5869 }
5870 
5872  MOVTrack *track, int ref_size, int total_sidx_size)
5873 {
5874  int64_t pos = avio_tell(pb), offset_pos, end_pos;
5875  int64_t presentation_time, duration, offset;
5876  unsigned starts_with_SAP;
5877  int i, entries;
5878 
5879  if (track->entry) {
5880  entries = 1;
5881  presentation_time = track->cluster[0].dts + track->cluster[0].cts;
5882  duration = track->end_pts -
5883  (track->cluster[0].dts + track->cluster[0].cts);
5884  starts_with_SAP = track->cluster[0].flags & MOV_SYNC_SAMPLE;
5885 
5886  // pts<0 should be cut away using edts
5887  if (presentation_time < 0) {
5888  duration += presentation_time;
5889  presentation_time = 0;
5890  }
5891  } else {
5892  entries = track->nb_frag_info;
5893  if (entries <= 0)
5894  return 0;
5895  presentation_time = track->frag_info[0].time;
5896  }
5897 
5898  avio_wb32(pb, 0); /* size */
5899  ffio_wfourcc(pb, "sidx");
5900  avio_w8(pb, 1); /* version */
5901  avio_wb24(pb, 0);
5902  avio_wb32(pb, track->track_id); /* reference_ID */
5903  avio_wb32(pb, track->timescale); /* timescale */
5904  avio_wb64(pb, presentation_time); /* earliest_presentation_time */
5905  offset_pos = avio_tell(pb);
5906  avio_wb64(pb, 0); /* first_offset (offset to referenced moof) */
5907  avio_wb16(pb, 0); /* reserved */
5908 
5909  avio_wb16(pb, entries); /* reference_count */
5910  for (i = 0; i < entries; i++) {
5911  if (!track->entry) {
5912  if (i > 1 && track->frag_info[i].offset != track->frag_info[i - 1].offset + track->frag_info[i - 1].size) {
5913  av_log(NULL, AV_LOG_ERROR, "Non-consecutive fragments, writing incorrect sidx\n");
5914  }
5915  duration = track->frag_info[i].duration;
5916  ref_size = track->frag_info[i].size;
5917  starts_with_SAP = 1;
5918  }
5919  avio_wb32(pb, (0 << 31) | (ref_size & 0x7fffffff)); /* reference_type (0 = media) | referenced_size */
5920  avio_wb32(pb, duration); /* subsegment_duration */
5921  avio_wb32(pb, (starts_with_SAP << 31) | (0 << 28) | 0); /* starts_with_SAP | SAP_type | SAP_delta_time */
5922  }
5923 
5924  end_pos = avio_tell(pb);
5925  offset = pos + total_sidx_size - end_pos;
5926  avio_seek(pb, offset_pos, SEEK_SET);
5927  avio_wb64(pb, offset);
5928  avio_seek(pb, end_pos, SEEK_SET);
5929  return update_size(pb, pos);
5930 }
5931 
5933  int tracks, int ref_size)
5934 {
5935  int i, round, ret;
5936  AVIOContext *avio_buf;
5937  int total_size = 0;
5938  for (round = 0; round < 2; round++) {
5939  // First run one round to calculate the total size of all
5940  // sidx atoms.
5941  // This would be much simpler if we'd only write one sidx
5942  // atom, for the first track in the moof.
5943  if (round == 0) {
5944  if ((ret = ffio_open_null_buf(&avio_buf)) < 0)
5945  return ret;
5946  } else {
5947  avio_buf = pb;
5948  }
5949  for (i = 0; i < mov->nb_tracks; i++) {
5950  MOVTrack *track = &mov->tracks[i];
5951  if (tracks >= 0 && i != tracks)
5952  continue;
5953  // When writing a sidx for the full file, entry is 0, but
5954  // we want to include all tracks. ref_size is 0 in this case,
5955  // since we read it from frag_info instead.
5956  if (!track->entry && ref_size > 0)
5957  continue;
5958  total_size -= mov_write_sidx_tag(avio_buf, track, ref_size,
5959  total_size);
5960  }
5961  if (round == 0) {
5962  total_size = ffio_close_null_buf(avio_buf);
5963  if (total_size < 0)
5964  return total_size;
5965  }
5966  }
5967  return 0;
5968 }
5969 
5970 static int mov_write_prft_tag(AVIOContext *pb, MOVMuxContext *mov, int tracks)
5971 {
5972  int64_t pos = avio_tell(pb), pts_us, ntp_ts;
5973  MOVTrack *first_track;
5974  int flags = 24;
5975 
5976  /* PRFT should be associated with at most one track. So, choosing only the
5977  * first track. */
5978  if (tracks > 0)
5979  return 0;
5980  first_track = &(mov->tracks[0]);
5981 
5982  if (!first_track->entry) {
5983  av_log(mov->fc, AV_LOG_WARNING, "Unable to write PRFT, no entries in the track\n");
5984  return 0;
5985  }
5986 
5987  if (first_track->cluster[0].pts == AV_NOPTS_VALUE) {
5988  av_log(mov->fc, AV_LOG_WARNING, "Unable to write PRFT, first PTS is invalid\n");
5989  return 0;
5990  }
5991 
5992  if (mov->write_prft == MOV_PRFT_SRC_WALLCLOCK) {
5993  if (first_track->cluster[0].prft.wallclock) {
5994  /* Round the NTP time to whole milliseconds. */
5995  ntp_ts = ff_get_formatted_ntp_time((first_track->cluster[0].prft.wallclock / 1000) * 1000 +
5996  NTP_OFFSET_US);
5997  flags = first_track->cluster[0].prft.flags;
5998  } else
6000  } else if (mov->write_prft == MOV_PRFT_SRC_PTS) {
6001  pts_us = av_rescale_q(first_track->cluster[0].pts,
6002  first_track->st->time_base, AV_TIME_BASE_Q);
6003  ntp_ts = ff_get_formatted_ntp_time(pts_us + NTP_OFFSET_US);
6004  } else {
6005  av_log(mov->fc, AV_LOG_WARNING, "Unsupported PRFT box configuration: %d\n",
6006  mov->write_prft);
6007  return 0;
6008  }
6009 
6010  avio_wb32(pb, 0); // Size place holder
6011  ffio_wfourcc(pb, "prft"); // Type
6012  avio_w8(pb, 1); // Version
6013  avio_wb24(pb, flags); // Flags
6014  avio_wb32(pb, first_track->track_id); // reference track ID
6015  avio_wb64(pb, ntp_ts); // NTP time stamp
6016  avio_wb64(pb, first_track->cluster[0].pts); //media time
6017  return update_size(pb, pos);
6018 }
6019 
6020 static int mov_write_moof_tag(AVIOContext *pb, MOVMuxContext *mov, int tracks,
6021  int64_t mdat_size)
6022 {
6023  AVIOContext *avio_buf;
6024  int ret, moof_size;
6025 
6026  if ((ret = ffio_open_null_buf(&avio_buf)) < 0)
6027  return ret;
6028  mov_write_moof_tag_internal(avio_buf, mov, tracks, 0);
6029  moof_size = ffio_close_null_buf(avio_buf);
6030  if (moof_size < 0)
6031  return moof_size;
6032 
6033  if (mov->flags & FF_MOV_FLAG_DASH &&
6035  mov_write_sidx_tags(pb, mov, tracks, moof_size + 8 + mdat_size);
6036 
6037  if (mov->write_prft > MOV_PRFT_NONE && mov->write_prft < MOV_PRFT_NB)
6038  mov_write_prft_tag(pb, mov, tracks);
6039 
6040  if (mov->flags & FF_MOV_FLAG_GLOBAL_SIDX ||
6041  !(mov->flags & FF_MOV_FLAG_SKIP_TRAILER) ||
6042  mov->ism_lookahead) {
6043  if ((ret = mov_add_tfra_entries(pb, mov, tracks, moof_size + 8 + mdat_size)) < 0)
6044  return ret;
6045  if (!(mov->flags & FF_MOV_FLAG_GLOBAL_SIDX) &&
6047  mov_prune_frag_info(mov, tracks, mov->ism_lookahead + 1);
6048  }
6049  }
6050 
6051  return mov_write_moof_tag_internal(pb, mov, tracks, moof_size);
6052 }
6053 
6054 static int mov_write_tfra_tag(AVIOContext *pb, MOVTrack *track)
6055 {
6056  int64_t pos = avio_tell(pb);
6057  int i;
6058 
6059  avio_wb32(pb, 0); /* size placeholder */
6060  ffio_wfourcc(pb, "tfra");
6061  avio_w8(pb, 1); /* version */
6062  avio_wb24(pb, 0);
6063 
6064  avio_wb32(pb, track->track_id);
6065  avio_wb32(pb, 0); /* length of traf/trun/sample num */
6066  avio_wb32(pb, track->nb_frag_info);
6067  for (i = 0; i < track->nb_frag_info; i++) {
6068  avio_wb64(pb, track->frag_info[i].time);
6069  avio_wb64(pb, track->frag_info[i].offset + track->data_offset);
6070  avio_w8(pb, 1); /* traf number */
6071  avio_w8(pb, 1); /* trun number */
6072  avio_w8(pb, 1); /* sample number */
6073  }
6074 
6075  return update_size(pb, pos);
6076 }
6077 
6079 {
6080  AVIOContext *mfra_pb;
6081  int i, ret, sz;
6082  uint8_t *buf;
6083 
6084  ret = avio_open_dyn_buf(&mfra_pb);
6085  if (ret < 0)
6086  return ret;
6087 
6088  avio_wb32(mfra_pb, 0); /* size placeholder */
6089  ffio_wfourcc(mfra_pb, "mfra");
6090  /* An empty mfra atom is enough to indicate to the publishing point that
6091  * the stream has ended. */
6092  if (mov->flags & FF_MOV_FLAG_ISML)
6093  goto done_mfra;
6094 
6095  for (i = 0; i < mov->nb_tracks; i++) {
6096  MOVTrack *track = &mov->tracks[i];
6097  if (track->nb_frag_info)
6098  mov_write_tfra_tag(mfra_pb, track);
6099  }
6100 
6101  avio_wb32(mfra_pb, 16);
6102  ffio_wfourcc(mfra_pb, "mfro");
6103  avio_wb32(mfra_pb, 0); /* version + flags */
6104  avio_wb32(mfra_pb, avio_tell(mfra_pb) + 4);
6105 
6106 done_mfra:
6107 
6108  sz = update_size(mfra_pb, 0);
6109  ret = avio_get_dyn_buf(mfra_pb, &buf);
6110  avio_write(pb, buf, ret);
6111  ffio_free_dyn_buf(&mfra_pb);
6112 
6113  return sz;
6114 }
6115 
6117 {
6118  avio_wb32(pb, 8); // placeholder for extended size field (64 bit)
6119  ffio_wfourcc(pb, mov->mode == MODE_MOV ? "wide" : "free");
6120 
6121  mov->mdat_pos = avio_tell(pb);
6122  avio_wb32(pb, 0); /* size placeholder*/
6123  ffio_wfourcc(pb, "mdat");
6124  return 0;
6125 }
6126 
6128  int has_h264, int has_video, int write_minor)
6129 {
6130  MOVMuxContext *mov = s->priv_data;
6131  int minor = 0x200;
6132 
6133  if (mov->major_brand && strlen(mov->major_brand) >= 4)
6134  ffio_wfourcc(pb, mov->major_brand);
6135  else if (mov->mode == MODE_3GP) {
6136  ffio_wfourcc(pb, has_h264 ? "3gp6" : "3gp4");
6137  minor = has_h264 ? 0x100 : 0x200;
6138  } else if (mov->mode == MODE_AVIF) {
6139  ffio_wfourcc(pb, mov->is_animated_avif ? "avis" : "avif");
6140  minor = 0;
6141  } else if (mov->mode & MODE_3G2) {
6142  ffio_wfourcc(pb, has_h264 ? "3g2b" : "3g2a");
6143  minor = has_h264 ? 0x20000 : 0x10000;
6144  } else if (mov->mode == MODE_PSP)
6145  ffio_wfourcc(pb, "MSNV");
6146  else if (mov->mode == MODE_MP4 && mov->flags & FF_MOV_FLAG_FRAGMENT &&
6148  ffio_wfourcc(pb, "iso6"); // Required when using signed CTS offsets in trun boxes
6149  else if (mov->mode == MODE_MP4 && mov->flags & FF_MOV_FLAG_DEFAULT_BASE_MOOF)
6150  ffio_wfourcc(pb, "iso5"); // Required when using default-base-is-moof
6151  else if (mov->mode == MODE_MP4 && mov->flags & FF_MOV_FLAG_NEGATIVE_CTS_OFFSETS)
6152  ffio_wfourcc(pb, "iso4");
6153  else if (mov->mode == MODE_MP4)
6154  ffio_wfourcc(pb, "isom");
6155  else if (mov->mode == MODE_IPOD)
6156  ffio_wfourcc(pb, has_video ? "M4V ":"M4A ");
6157  else if (mov->mode == MODE_ISM)
6158  ffio_wfourcc(pb, "isml");
6159  else if (mov->mode == MODE_F4V)
6160  ffio_wfourcc(pb, "f4v ");
6161  else
6162  ffio_wfourcc(pb, "qt ");
6163 
6164  if (write_minor)
6165  avio_wb32(pb, minor);
6166 }
6167 
6169 {
6170  MOVMuxContext *mov = s->priv_data;
6171  int64_t pos = avio_tell(pb);
6172  int has_h264 = 0, has_av1 = 0, has_video = 0, has_dolby = 0, has_id3 = 0;
6173  int has_iamf = 0;
6174 
6175 #if CONFIG_IAMFENC
6176  for (int i = 0; i < s->nb_stream_groups; i++) {
6177  const AVStreamGroup *stg = s->stream_groups[i];
6178 
6181  has_iamf = 1;
6182  break;
6183  }
6184  }
6185 #endif
6186  for (int i = 0; i < mov->nb_streams; i++) {
6187  AVStream *st = mov->tracks[i].st;
6188  if (is_cover_image(st))
6189  continue;
6191  has_video = 1;
6192  if (st->codecpar->codec_id == AV_CODEC_ID_H264)
6193  has_h264 = 1;
6194  if (st->codecpar->codec_id == AV_CODEC_ID_AV1)
6195  has_av1 = 1;
6196  if (st->codecpar->codec_id == AV_CODEC_ID_AC3 ||
6202  has_dolby = 1;
6204  has_id3 = 1;
6205  }
6206 
6207  avio_wb32(pb, 0); /* size */
6208  ffio_wfourcc(pb, "ftyp");
6209 
6210  // Write major brand
6211  mov_write_ftyp_tag_internal(pb, s, has_h264, has_video, 1);
6212  // Write the major brand as the first compatible brand as well
6213  mov_write_ftyp_tag_internal(pb, s, has_h264, has_video, 0);
6214 
6215  // Write compatible brands, ensuring that we don't write the major brand as a
6216  // compatible brand a second time.
6217  if (mov->mode == MODE_ISM) {
6218  ffio_wfourcc(pb, "piff");
6219  } else if (mov->mode == MODE_AVIF) {
6220  const AVPixFmtDescriptor *pix_fmt_desc =
6221  av_pix_fmt_desc_get(s->streams[0]->codecpar->format);
6222  const int depth = pix_fmt_desc->comp[0].depth;
6223  if (mov->is_animated_avif) {
6224  // For animated AVIF, major brand is "avis". Add "avif" as a
6225  // compatible brand.
6226  ffio_wfourcc(pb, "avif");
6227  ffio_wfourcc(pb, "msf1");
6228  ffio_wfourcc(pb, "iso8");
6229  }
6230  ffio_wfourcc(pb, "mif1");
6231  ffio_wfourcc(pb, "miaf");
6232  if (depth == 8 || depth == 10) {
6233  // MA1B and MA1A brands are based on AV1 profile. Short hand for
6234  // computing that is based on chroma subsampling type. 420 chroma
6235  // subsampling is MA1B. 444 chroma subsampling is MA1A.
6236  if (!pix_fmt_desc->log2_chroma_w && !pix_fmt_desc->log2_chroma_h) {
6237  // 444 chroma subsampling.
6238  ffio_wfourcc(pb, "MA1A");
6239  } else {
6240  // 420 chroma subsampling.
6241  ffio_wfourcc(pb, "MA1B");
6242  }
6243  }
6244  } else if (mov->mode != MODE_MOV) {
6245  // We add tfdt atoms when fragmenting, signal this with the iso6 compatible
6246  // brand, if not already the major brand. This is compatible with users that
6247  // don't understand tfdt.
6248  if (mov->mode == MODE_MP4) {
6249  if (mov->flags & FF_MOV_FLAG_CMAF)
6250  ffio_wfourcc(pb, "cmfc");
6252  ffio_wfourcc(pb, "iso6");
6253  if (has_av1)
6254  ffio_wfourcc(pb, "av01");
6255  if (has_dolby)
6256  ffio_wfourcc(pb, "dby1");
6257  if (has_iamf)
6258  ffio_wfourcc(pb, "iamf");
6259  } else {
6260  if (mov->flags & FF_MOV_FLAG_FRAGMENT)
6261  ffio_wfourcc(pb, "iso6");
6263  ffio_wfourcc(pb, "iso5");
6264  else if (mov->flags & FF_MOV_FLAG_NEGATIVE_CTS_OFFSETS)
6265  ffio_wfourcc(pb, "iso4");
6266  }
6267  // Brands prior to iso5 can't be signaled when using default-base-is-moof
6268  if (!(mov->flags & FF_MOV_FLAG_DEFAULT_BASE_MOOF)) {
6269  // write isom for mp4 only if it it's not the major brand already.
6270  if (mov->mode != MODE_MP4 || mov->flags & FF_MOV_FLAG_NEGATIVE_CTS_OFFSETS)
6271  ffio_wfourcc(pb, "isom");
6272  ffio_wfourcc(pb, "iso2");
6273  if (has_h264)
6274  ffio_wfourcc(pb, "avc1");
6275  }
6276  }
6277 
6278  if (mov->mode == MODE_MP4)
6279  ffio_wfourcc(pb, "mp41");
6280 
6281  if (mov->flags & FF_MOV_FLAG_DASH && mov->flags & FF_MOV_FLAG_GLOBAL_SIDX)
6282  ffio_wfourcc(pb, "dash");
6283 
6284  if (has_id3)
6285  ffio_wfourcc(pb, "aid3");
6286 
6287  return update_size(pb, pos);
6288 }
6289 
6291 {
6292  AVStream *video_st = s->streams[0];
6293  AVCodecParameters *video_par = s->streams[0]->codecpar;
6294  AVCodecParameters *audio_par = s->streams[1]->codecpar;
6295  int audio_rate = audio_par->sample_rate;
6296  int64_t frame_rate = video_st->avg_frame_rate.den ?
6298  0;
6299  int audio_kbitrate = audio_par->bit_rate / 1000;
6300  int video_kbitrate = FFMIN(video_par->bit_rate / 1000, 800 - audio_kbitrate);
6301 
6302  if (frame_rate < 0 || frame_rate > INT32_MAX) {
6303  av_log(s, AV_LOG_ERROR, "Frame rate %f outside supported range\n", frame_rate / (double)0x10000);
6304  return AVERROR(EINVAL);
6305  }
6306 
6307  avio_wb32(pb, 0x94); /* size */
6308  ffio_wfourcc(pb, "uuid");
6309  ffio_wfourcc(pb, "PROF");
6310 
6311  avio_wb32(pb, 0x21d24fce); /* 96 bit UUID */
6312  avio_wb32(pb, 0xbb88695c);
6313  avio_wb32(pb, 0xfac9c740);
6314 
6315  avio_wb32(pb, 0x0); /* ? */
6316  avio_wb32(pb, 0x3); /* 3 sections ? */
6317 
6318  avio_wb32(pb, 0x14); /* size */
6319  ffio_wfourcc(pb, "FPRF");
6320  avio_wb32(pb, 0x0); /* ? */
6321  avio_wb32(pb, 0x0); /* ? */
6322  avio_wb32(pb, 0x0); /* ? */
6323 
6324  avio_wb32(pb, 0x2c); /* size */
6325  ffio_wfourcc(pb, "APRF"); /* audio */
6326  avio_wb32(pb, 0x0);
6327  avio_wb32(pb, 0x2); /* TrackID */
6328  ffio_wfourcc(pb, "mp4a");
6329  avio_wb32(pb, 0x20f);
6330  avio_wb32(pb, 0x0);
6331  avio_wb32(pb, audio_kbitrate);
6332  avio_wb32(pb, audio_kbitrate);
6333  avio_wb32(pb, audio_rate);
6334  avio_wb32(pb, audio_par->ch_layout.nb_channels);
6335 
6336  avio_wb32(pb, 0x34); /* size */
6337  ffio_wfourcc(pb, "VPRF"); /* video */
6338  avio_wb32(pb, 0x0);
6339  avio_wb32(pb, 0x1); /* TrackID */
6340  if (video_par->codec_id == AV_CODEC_ID_H264) {
6341  ffio_wfourcc(pb, "avc1");
6342  avio_wb16(pb, 0x014D);
6343  avio_wb16(pb, 0x0015);
6344  } else {
6345  ffio_wfourcc(pb, "mp4v");
6346  avio_wb16(pb, 0x0000);
6347  avio_wb16(pb, 0x0103);
6348  }
6349  avio_wb32(pb, 0x0);
6350  avio_wb32(pb, video_kbitrate);
6351  avio_wb32(pb, video_kbitrate);
6352  avio_wb32(pb, frame_rate);
6353  avio_wb32(pb, frame_rate);
6354  avio_wb16(pb, video_par->width);
6355  avio_wb16(pb, video_par->height);
6356  avio_wb32(pb, 0x010001); /* ? */
6357 
6358  return 0;
6359 }
6360 
6362 {
6363  MOVMuxContext *mov = s->priv_data;
6364  int i;
6365 
6366  mov_write_ftyp_tag(pb,s);
6367  if (mov->mode == MODE_PSP) {
6368  int video_streams_nb = 0, audio_streams_nb = 0, other_streams_nb = 0;
6369  for (i = 0; i < mov->nb_streams; i++) {
6370  AVStream *st = mov->tracks[i].st;
6371  if (is_cover_image(st))
6372  continue;
6374  video_streams_nb++;
6375  else if (st->codecpar->codec_type == AVMEDIA_TYPE_AUDIO)
6376  audio_streams_nb++;
6377  else
6378  other_streams_nb++;
6379  }
6380 
6381  if (video_streams_nb != 1 || audio_streams_nb != 1 || other_streams_nb) {
6382  av_log(s, AV_LOG_ERROR, "PSP mode need one video and one audio stream\n");
6383  return AVERROR(EINVAL);
6384  }
6385  return mov_write_uuidprof_tag(pb, s);
6386  }
6387  return 0;
6388 }
6389 
6390 static int mov_parse_mpeg2_frame(AVPacket *pkt, uint32_t *flags)
6391 {
6392  uint32_t c = -1;
6393  int i, closed_gop = 0;
6394 
6395  for (i = 0; i < pkt->size - 4; i++) {
6396  c = (c << 8) + pkt->data[i];
6397  if (c == 0x1b8) { // gop
6398  closed_gop = pkt->data[i + 4] >> 6 & 0x01;
6399  } else if (c == 0x100) { // pic
6400  int temp_ref = (pkt->data[i + 1] << 2) | (pkt->data[i + 2] >> 6);
6401  if (!temp_ref || closed_gop) // I picture is not reordered
6403  else
6405  break;
6406  }
6407  }
6408  return 0;
6409 }
6410 
6412 {
6413  const uint8_t *start, *next, *end = pkt->data + pkt->size;
6414  int seq = 0, entry = 0;
6415  int key = pkt->flags & AV_PKT_FLAG_KEY;
6416  start = find_next_marker(pkt->data, end);
6417  for (next = start; next < end; start = next) {
6418  next = find_next_marker(start + 4, end);
6419  switch (AV_RB32(start)) {
6420  case VC1_CODE_SEQHDR:
6421  seq = 1;
6422  break;
6423  case VC1_CODE_ENTRYPOINT:
6424  entry = 1;
6425  break;
6426  case VC1_CODE_SLICE:
6427  trk->vc1_info.slices = 1;
6428  break;
6429  }
6430  }
6431  if (!trk->entry && trk->vc1_info.first_packet_seen)
6432  trk->vc1_info.first_frag_written = 1;
6433  if (!trk->entry && !trk->vc1_info.first_frag_written) {
6434  /* First packet in first fragment */
6435  trk->vc1_info.first_packet_seq = seq;
6437  trk->vc1_info.first_packet_seen = 1;
6438  } else if ((seq && !trk->vc1_info.packet_seq) ||
6439  (entry && !trk->vc1_info.packet_entry)) {
6440  int i;
6441  for (i = 0; i < trk->entry; i++)
6442  trk->cluster[i].flags &= ~MOV_SYNC_SAMPLE;
6443  trk->has_keyframes = 0;
6444  if (seq)
6445  trk->vc1_info.packet_seq = 1;
6446  if (entry)
6447  trk->vc1_info.packet_entry = 1;
6448  if (!trk->vc1_info.first_frag_written) {
6449  /* First fragment */
6450  if ((!seq || trk->vc1_info.first_packet_seq) &&
6451  (!entry || trk->vc1_info.first_packet_entry)) {
6452  /* First packet had the same headers as this one, readd the
6453  * sync sample flag. */
6454  trk->cluster[0].flags |= MOV_SYNC_SAMPLE;
6455  trk->has_keyframes = 1;
6456  }
6457  }
6458  }
6459  if (trk->vc1_info.packet_seq && trk->vc1_info.packet_entry)
6460  key = seq && entry;
6461  else if (trk->vc1_info.packet_seq)
6462  key = seq;
6463  else if (trk->vc1_info.packet_entry)
6464  key = entry;
6465  if (key) {
6466  trk->cluster[trk->entry].flags |= MOV_SYNC_SAMPLE;
6467  trk->has_keyframes++;
6468  }
6469 }
6470 
6472 {
6473  int length;
6474 
6475  if (pkt->size < 8)
6476  return;
6477 
6478  length = (AV_RB16(pkt->data) & 0xFFF) * 2;
6479  if (length < 8 || length > pkt->size)
6480  return;
6481 
6482  if (AV_RB32(pkt->data + 4) == 0xF8726FBA) {
6483  trk->cluster[trk->entry].flags |= MOV_SYNC_SAMPLE;
6484  trk->has_keyframes++;
6485  }
6486 
6487  return;
6488 }
6489 
6491 {
6492  MOVMuxContext *mov = s->priv_data;
6493  int ret, buf_size;
6494  uint8_t *buf;
6495  int i, offset;
6496 
6497  if (!track->mdat_buf)
6498  return 0;
6499  if (!mov->mdat_buf) {
6500  if ((ret = avio_open_dyn_buf(&mov->mdat_buf)) < 0)
6501  return ret;
6502  }
6503  buf_size = avio_get_dyn_buf(track->mdat_buf, &buf);
6504 
6505  offset = avio_tell(mov->mdat_buf);
6506  avio_write(mov->mdat_buf, buf, buf_size);
6507  ffio_reset_dyn_buf(track->mdat_buf);
6508 
6509  for (i = track->entries_flushed; i < track->entry; i++)
6510  track->cluster[i].pos += offset;
6511  track->entries_flushed = track->entry;
6512  return 0;
6513 }
6514 
6516 {
6517  MOVMuxContext *mov = s->priv_data;
6518  AVPacket *squashed_packet = mov->pkt;
6519  int ret = AVERROR_BUG;
6520 
6521  switch (track->st->codecpar->codec_id) {
6522  case AV_CODEC_ID_TTML: {
6523  int had_packets = !!track->squashed_packet_queue.head;
6524 
6525  if ((ret = ff_mov_generate_squashed_ttml_packet(s, track, squashed_packet)) < 0) {
6526  goto finish_squash;
6527  }
6528 
6529  // We have generated a padding packet (no actual input packets in
6530  // queue) and its duration is zero. Skipping writing it.
6531  if (!had_packets && squashed_packet->duration == 0) {
6532  goto finish_squash;
6533  }
6534 
6535  track->end_reliable = 1;
6536  break;
6537  }
6538  default:
6539  ret = AVERROR(EINVAL);
6540  goto finish_squash;
6541  }
6542 
6543  squashed_packet->stream_index = track->st->index;
6544 
6545  ret = mov_write_single_packet(s, squashed_packet);
6546 
6547 finish_squash:
6548  av_packet_unref(squashed_packet);
6549 
6550  return ret;
6551 }
6552 
6554 {
6555  MOVMuxContext *mov = s->priv_data;
6556 
6557  for (int i = 0; i < mov->nb_streams; i++) {
6558  MOVTrack *track = &mov->tracks[i];
6559  int ret = AVERROR_BUG;
6560 
6561  if (track->squash_fragment_samples_to_one && !track->entry) {
6562  if ((ret = mov_write_squashed_packet(s, track)) < 0) {
6564  "Failed to write squashed packet for %s stream with "
6565  "index %d and track id %d. Error: %s\n",
6567  track->st->index, track->track_id,
6568  av_err2str(ret));
6569  return ret;
6570  }
6571  }
6572  }
6573 
6574  return 0;
6575 }
6576 
6578  int64_t ref_pos)
6579 {
6580  int i;
6581  if (!track->entry)
6582  return 0;
6583  if (mov->flags & FF_MOV_FLAG_HYBRID_FRAGMENTED) {
6584  for (i = 0; i < track->entry; i++)
6585  track->cluster[i].pos += ref_pos + track->data_offset;
6586  if (track->cluster_written == 0) {
6587  // First flush. Chunking for this fragment may already have been
6588  // done, either if we didn't use empty_moov, or if we did use
6589  // delay_moov. In either case, reset chunking here.
6590  for (i = 0; i < track->entry; i++) {
6591  track->cluster[i].chunkNum = 0;
6592  track->cluster[i].samples_in_chunk = track->cluster[i].entries;
6593  }
6594  }
6595  if (av_reallocp_array(&track->cluster_written,
6596  track->entry_written + track->entry,
6597  sizeof(*track->cluster)))
6598  return AVERROR(ENOMEM);
6599  memcpy(&track->cluster_written[track->entry_written],
6600  track->cluster, track->entry * sizeof(*track->cluster));
6601  track->entry_written += track->entry;
6602  }
6603  track->entry = 0;
6604  track->entries_flushed = 0;
6605  track->end_reliable = 0;
6606  return 0;
6607 }
6608 
6609 static int mov_flush_fragment(AVFormatContext *s, int force)
6610 {
6611  MOVMuxContext *mov = s->priv_data;
6612  int i, first_track = -1;
6613  int64_t mdat_size = 0, mdat_start = 0;
6614  int ret;
6615  int has_video = 0, starts_with_key = 0, first_video_track = 1;
6616 
6617  if (!(mov->flags & FF_MOV_FLAG_FRAGMENT))
6618  return 0;
6619 
6620  // Check if we have any tracks that require squashing.
6621  // In that case, we'll have to write the packet here.
6622  if ((ret = mov_write_squashed_packets(s)) < 0)
6623  return ret;
6624 
6625  // Try to fill in the duration of the last packet in each stream
6626  // from queued packets in the interleave queues. If the flushing
6627  // of fragments was triggered automatically by an AVPacket, we
6628  // already have reliable info for the end of that track, but other
6629  // tracks may need to be filled in.
6630  for (i = 0; i < mov->nb_streams; i++) {
6631  MOVTrack *track = &mov->tracks[i];
6632  if (!track->end_reliable) {
6633  const AVPacket *pkt = ff_interleaved_peek(s, i);
6634  if (pkt) {
6635  int64_t offset, dts, pts;
6637  pts = pkt->pts + offset;
6638  dts = pkt->dts + offset;
6639  if (track->dts_shift != AV_NOPTS_VALUE)
6640  dts += track->dts_shift;
6641  track->track_duration = dts - track->start_dts;
6642  if (pts != AV_NOPTS_VALUE)
6643  track->end_pts = pts;
6644  else
6645  track->end_pts = dts;
6646  if (!(pkt->flags & AV_PKT_FLAG_DISCARD))
6647  track->elst_end_pts = track->end_pts;
6648  }
6649  }
6650  }
6651 
6652  for (i = 0; i < mov->nb_tracks; i++) {
6653  MOVTrack *track = &mov->tracks[i];
6654  if (track->entry <= 1)
6655  continue;
6656  // Sample durations are calculated as the diff of dts values,
6657  // but for the last sample in a fragment, we don't know the dts
6658  // of the first sample in the next fragment, so we have to rely
6659  // on what was set as duration in the AVPacket. Not all callers
6660  // set this though, so we might want to replace it with an
6661  // estimate if it currently is zero.
6662  if (get_cluster_duration(track, track->entry - 1) != 0)
6663  continue;
6664  // Use the duration (i.e. dts diff) of the second last sample for
6665  // the last one. This is a wild guess (and fatal if it turns out
6666  // to be too long), but probably the best we can do - having a zero
6667  // duration is bad as well.
6668  track->track_duration += get_cluster_duration(track, track->entry - 2);
6669  track->end_pts += get_cluster_duration(track, track->entry - 2);
6670  if (!mov->missing_duration_warned) {
6672  "Estimating the duration of the last packet in a "
6673  "fragment, consider setting the duration field in "
6674  "AVPacket instead.\n");
6675  mov->missing_duration_warned = 1;
6676  }
6677  }
6678 
6679  if (!mov->moov_written) {
6680  int64_t pos = avio_tell(s->pb);
6681  uint8_t *buf;
6682  int buf_size, moov_size;
6683 
6684  for (i = 0; i < mov->nb_tracks; i++)
6685  if (!mov->tracks[i].entry && !is_cover_image(mov->tracks[i].st))
6686  break;
6687  /* Don't write the initial moov unless all tracks have data */
6688  if (i < mov->nb_tracks && !force)
6689  return 0;
6690 
6691  moov_size = get_moov_size(s);
6692  for (i = 0; i < mov->nb_tracks; i++)
6693  mov->tracks[i].data_offset = pos + moov_size + 8;
6694 
6696  if (mov->flags & FF_MOV_FLAG_DELAY_MOOV &&
6699  if ((ret = mov_write_moov_tag(s->pb, mov, s)) < 0)
6700  return ret;
6701 
6702  if (mov->flags & FF_MOV_FLAG_DELAY_MOOV) {
6703  if (mov->flags & FF_MOV_FLAG_GLOBAL_SIDX)
6704  mov->reserved_header_pos = avio_tell(s->pb);
6706  mov->moov_written = 1;
6707  return 0;
6708  }
6709 
6710  buf_size = avio_get_dyn_buf(mov->mdat_buf, &buf);
6711  avio_wb32(s->pb, buf_size + 8);
6712  ffio_wfourcc(s->pb, "mdat");
6713  avio_write(s->pb, buf, buf_size);
6715 
6716  if (mov->flags & FF_MOV_FLAG_GLOBAL_SIDX)
6717  mov->reserved_header_pos = avio_tell(s->pb);
6718 
6719  mov->moov_written = 1;
6720  mov->mdat_size = 0;
6721  for (i = 0; i < mov->nb_tracks; i++)
6722  mov_finish_fragment(mov, &mov->tracks[i], 0);
6724  return 0;
6725  }
6726 
6727  if (mov->frag_interleave) {
6728  for (i = 0; i < mov->nb_tracks; i++) {
6729  MOVTrack *track = &mov->tracks[i];
6730  int ret;
6731  if ((ret = mov_flush_fragment_interleaving(s, track)) < 0)
6732  return ret;
6733  }
6734 
6735  if (!mov->mdat_buf)
6736  return 0;
6737  mdat_size = avio_tell(mov->mdat_buf);
6738  }
6739 
6740  for (i = 0; i < mov->nb_tracks; i++) {
6741  MOVTrack *track = &mov->tracks[i];
6742  if (mov->flags & FF_MOV_FLAG_SEPARATE_MOOF || mov->frag_interleave)
6743  track->data_offset = 0;
6744  else
6745  track->data_offset = mdat_size;
6746  if (track->par->codec_type == AVMEDIA_TYPE_VIDEO) {
6747  has_video = 1;
6748  if (first_video_track) {
6749  if (track->entry)
6750  starts_with_key = track->cluster[0].flags & MOV_SYNC_SAMPLE;
6751  first_video_track = 0;
6752  }
6753  }
6754  if (!track->entry)
6755  continue;
6756  if (track->mdat_buf)
6757  mdat_size += avio_tell(track->mdat_buf);
6758  if (first_track < 0)
6759  first_track = i;
6760  }
6761 
6762  if (!mdat_size)
6763  return 0;
6764 
6765  avio_write_marker(s->pb,
6766  av_rescale(mov->tracks[first_track].cluster[0].dts, AV_TIME_BASE, mov->tracks[first_track].timescale),
6767  (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);
6768 
6769  for (i = first_track; i < mov->nb_tracks; i++) {
6770  MOVTrack *track = &mov->tracks[i];
6771  int buf_size, write_moof = 1, moof_tracks = -1;
6772  uint8_t *buf;
6773 
6774  if (!track->entry)
6775  continue;
6776  if (mov->flags & FF_MOV_FLAG_SEPARATE_MOOF) {
6777  mdat_size = avio_tell(track->mdat_buf);
6778  moof_tracks = i;
6779  } else {
6780  write_moof = i == first_track;
6781  }
6782 
6783  if (write_moof) {
6785 
6786  mov_write_moof_tag(s->pb, mov, moof_tracks, mdat_size);
6787  mov->fragments++;
6788 
6789  if (track->cenc.aes_ctr)
6790  ff_mov_cenc_flush(&track->cenc);
6791 
6792  avio_wb32(s->pb, mdat_size + 8);
6793  ffio_wfourcc(s->pb, "mdat");
6794  mdat_start = avio_tell(s->pb);
6795  }
6796 
6797  mov_finish_fragment(mov, &mov->tracks[i], mdat_start);
6798  if (!mov->frag_interleave) {
6799  if (!track->mdat_buf)
6800  continue;
6801  buf_size = avio_get_dyn_buf(track->mdat_buf, &buf);
6802  avio_write(s->pb, buf, buf_size);
6803  ffio_reset_dyn_buf(track->mdat_buf);
6804  } else {
6805  if (!mov->mdat_buf)
6806  continue;
6807  buf_size = avio_get_dyn_buf(mov->mdat_buf, &buf);
6808  avio_write(s->pb, buf, buf_size);
6810  }
6811  }
6812 
6813  mov->mdat_size = 0;
6814 
6816  return 0;
6817 }
6818 
6820 {
6821  MOVMuxContext *mov = s->priv_data;
6822  int had_moov = mov->moov_written;
6823  int ret = mov_flush_fragment(s, force);
6824  if (ret < 0)
6825  return ret;
6826  // If using delay_moov, the first flush only wrote the moov,
6827  // not the actual moof+mdat pair, thus flush once again.
6828  if (!had_moov && mov->flags & FF_MOV_FLAG_DELAY_MOOV)
6829  ret = mov_flush_fragment(s, force);
6830  return ret;
6831 }
6832 
6834 {
6835  int64_t ref;
6836  uint64_t duration;
6837 
6838  if (trk->entry) {
6839  ref = trk->cluster[trk->entry - 1].dts;
6840  } else if ( trk->start_dts != AV_NOPTS_VALUE
6841  && !trk->frag_discont) {
6842  ref = trk->start_dts + trk->track_duration;
6843  } else
6844  ref = pkt->dts; // Skip tests for the first packet
6845 
6846  if (trk->dts_shift != AV_NOPTS_VALUE) {
6847  /* With negative CTS offsets we have set an offset to the DTS,
6848  * reverse this for the check. */
6849  ref -= trk->dts_shift;
6850  }
6851 
6852  duration = pkt->dts - ref;
6853  if (pkt->dts < ref || duration >= INT_MAX) {
6854  av_log(s, AV_LOG_WARNING, "Packet duration: %"PRId64" / dts: %"PRId64" in stream %d is out of range\n",
6856 
6857  pkt->dts = ref + 1;
6858  pkt->pts = AV_NOPTS_VALUE;
6859  }
6860 
6861  if (pkt->duration < 0 || pkt->duration > INT_MAX) {
6862  av_log(s, AV_LOG_ERROR, "Application provided duration: %"PRId64" in stream %d is invalid\n", pkt->duration, pkt->stream_index);
6863  return AVERROR(EINVAL);
6864  }
6865  return 0;
6866 }
6867 
6869 {
6870  MOVMuxContext *mov = s->priv_data;
6871  AVIOContext *pb = s->pb;
6872  MOVTrack *trk;
6873  AVCodecParameters *par;
6875  unsigned int samples_in_chunk = 0;
6876  int size = pkt->size, ret = 0, offset = 0;
6877  size_t prft_size;
6878  uint8_t *reformatted_data = NULL;
6879 
6880  if (pkt->stream_index < s->nb_streams)
6881  trk = s->streams[pkt->stream_index]->priv_data;
6882  else // Timecode or chapter
6883  trk = &mov->tracks[pkt->stream_index];
6884  par = trk->par;
6885 
6886  ret = check_pkt(s, trk, pkt);
6887  if (ret < 0)
6888  return ret;
6889 
6890  if (pkt->pts != AV_NOPTS_VALUE &&
6891  (uint64_t)pkt->dts - pkt->pts != (int32_t)((uint64_t)pkt->dts - pkt->pts)) {
6892  av_log(s, AV_LOG_WARNING, "pts/dts pair unsupported\n");
6893  return AVERROR_PATCHWELCOME;
6894  }
6895 
6896  if (mov->flags & FF_MOV_FLAG_FRAGMENT || mov->mode == MODE_AVIF) {
6897  int ret;
6898  if (mov->moov_written || mov->flags & FF_MOV_FLAG_EMPTY_MOOV) {
6899  if (mov->frag_interleave && mov->fragments > 0) {
6900  if (trk->entry - trk->entries_flushed >= mov->frag_interleave) {
6901  if ((ret = mov_flush_fragment_interleaving(s, trk)) < 0)
6902  return ret;
6903  }
6904  }
6905 
6906  if (!trk->mdat_buf) {
6907  if ((ret = avio_open_dyn_buf(&trk->mdat_buf)) < 0)
6908  return ret;
6909  }
6910  pb = trk->mdat_buf;
6911  } else {
6912  if (!mov->mdat_buf) {
6913  if ((ret = avio_open_dyn_buf(&mov->mdat_buf)) < 0)
6914  return ret;
6915  }
6916  pb = mov->mdat_buf;
6917  }
6918  }
6919 
6920  if (par->codec_id == AV_CODEC_ID_AMR_NB) {
6921  /* We must find out how many AMR blocks there are in one packet */
6922  static const uint16_t packed_size[16] =
6923  {13, 14, 16, 18, 20, 21, 27, 32, 6, 0, 0, 0, 0, 0, 0, 1};
6924  int len = 0;
6925 
6926  while (len < size && samples_in_chunk < 100) {
6927  len += packed_size[(pkt->data[len] >> 3) & 0x0F];
6928  samples_in_chunk++;
6929  }
6930  if (samples_in_chunk > 1) {
6931  av_log(s, AV_LOG_ERROR, "fatal error, input is not a single packet, implement a AVParser for it\n");
6932  return -1;
6933  }
6934  } else if (par->codec_id == AV_CODEC_ID_ADPCM_MS ||
6936  samples_in_chunk = trk->par->frame_size;
6937  } else if (trk->sample_size)
6938  samples_in_chunk = size / trk->sample_size;
6939  else
6940  samples_in_chunk = 1;
6941 
6942  if (samples_in_chunk < 1) {
6943  av_log(s, AV_LOG_ERROR, "fatal error, input packet contains no samples\n");
6944  return AVERROR_PATCHWELCOME;
6945  }
6946 
6947  /* copy extradata if it exists */
6948  if (trk->extradata_size[0] == 0 && par->extradata_size > 0 &&
6949  !TAG_IS_AVCI(trk->tag) &&
6950  (par->codec_id != AV_CODEC_ID_DNXHD)) {
6951  trk->extradata[0] = av_memdup(par->extradata, par->extradata_size);
6952  if (!trk->extradata[0]) {
6953  ret = AVERROR(ENOMEM);
6954  goto err;
6955  }
6956  trk->extradata_size[0] = par->extradata_size;
6957  }
6958 
6959  if ((par->codec_id == AV_CODEC_ID_DNXHD ||
6960  par->codec_id == AV_CODEC_ID_H264 ||
6961  par->codec_id == AV_CODEC_ID_HEVC ||
6962  par->codec_id == AV_CODEC_ID_VVC ||
6963  par->codec_id == AV_CODEC_ID_VP9 ||
6964  par->codec_id == AV_CODEC_ID_EVC ||
6965  par->codec_id == AV_CODEC_ID_LCEVC ||
6966  par->codec_id == AV_CODEC_ID_TRUEHD) && !trk->extradata_size[0] &&
6967  !TAG_IS_AVCI(trk->tag)) {
6968  /* copy frame to create needed atoms */
6969  trk->extradata_size[0] = size;
6971  if (!trk->extradata[0]) {
6972  ret = AVERROR(ENOMEM);
6973  goto err;
6974  }
6975  memcpy(trk->extradata[0], pkt->data, size);
6976  memset(trk->extradata[0] + size, 0, AV_INPUT_BUFFER_PADDING_SIZE);
6977  }
6978 
6980  if (pkt->size && sd && sd->size > 0) {
6981  int i;
6982  for (i = 0; i < trk->stsd_count; i++) {
6983  if (trk->extradata_size[i] == sd->size && !memcmp(trk->extradata[i], sd->data, sd->size))
6984  break;
6985  }
6986 
6987  if (i < trk->stsd_count)
6988  trk->last_stsd_index = i;
6989  else if (trk->stsd_count <= INT_MAX - 1) {
6990  int new_count = trk->stsd_count + 1;
6991  uint8_t **extradata = av_realloc_array(trk->extradata, new_count, sizeof(*trk->extradata));
6992  if (!extradata)
6993  return AVERROR(ENOMEM);
6994  trk->extradata = extradata;
6995 
6996  int *extradata_size = av_realloc_array(trk->extradata_size, new_count, sizeof(*trk->extradata_size));
6997  if (!extradata_size)
6998  return AVERROR(ENOMEM);
6999  trk->extradata_size = extradata_size;
7000 
7001  trk->extradata[trk->stsd_count] = av_memdup(sd->data, sd->size);
7002  if (!trk->extradata[trk->stsd_count])
7003  return AVERROR(ENOMEM);
7004 
7005  trk->extradata_size[trk->stsd_count] = sd->size;
7006  trk->last_stsd_index = trk->stsd_count;
7007  trk->stsd_count = new_count;
7008  } else
7009  return AVERROR(ENOMEM);
7010  }
7011 
7012  if (par->codec_id == AV_CODEC_ID_AAC && pkt->size > 2 &&
7013  (AV_RB16(pkt->data) & 0xfff0) == 0xfff0) {
7014  if (!trk->st->nb_frames) {
7015  av_log(s, AV_LOG_ERROR, "Malformed AAC bitstream detected: "
7016  "use the audio bitstream filter 'aac_adtstoasc' to fix it "
7017  "('-bsf:a aac_adtstoasc' option with ffmpeg)\n");
7018  return -1;
7019  }
7020  av_log(s, AV_LOG_WARNING, "aac bitstream error\n");
7021  }
7022  if (par->codec_id == AV_CODEC_ID_H264 && trk->extradata_size[trk->last_stsd_index] > 0 &&
7023  *(uint8_t *)trk->extradata[trk->last_stsd_index] != 1 && !TAG_IS_AVCI(trk->tag)) {
7024  /* from x264 or from bytestream H.264 */
7025  /* NAL reformatting needed */
7026  if (trk->hint_track >= 0 && trk->hint_track < mov->nb_tracks) {
7027  ret = ff_nal_parse_units_buf(pkt->data, &reformatted_data,
7028  &size);
7029  if (ret < 0)
7030  return ret;
7031  avio_write(pb, reformatted_data, size);
7032  } else {
7033  if (trk->cenc.aes_ctr) {
7035  if (size < 0) {
7036  ret = size;
7037  goto err;
7038  }
7039  } else {
7040  size = ff_nal_parse_units(pb, pkt->data, pkt->size);
7041  }
7042  }
7043  } else if (par->codec_id == AV_CODEC_ID_HEVC && trk->extradata_size[trk->last_stsd_index] > 6 &&
7044  (AV_RB24(trk->extradata[trk->last_stsd_index]) == 1 || AV_RB32(trk->extradata[trk->last_stsd_index]) == 1)) {
7045  /* extradata is Annex B, assume the bitstream is too and convert it */
7046  int filter_ps = (trk->tag == MKTAG('h','v','c','1'));
7047  if (trk->hint_track >= 0 && trk->hint_track < mov->nb_tracks) {
7048  ret = ff_hevc_annexb2mp4_buf(pkt->data, &reformatted_data,
7049  &size, filter_ps, NULL);
7050  if (ret < 0)
7051  return ret;
7052  avio_write(pb, reformatted_data, size);
7053  } else {
7054  if (trk->cenc.aes_ctr) {
7056  if (size < 0) {
7057  ret = size;
7058  goto err;
7059  }
7060  } else {
7061  size = ff_hevc_annexb2mp4(pb, pkt->data, pkt->size, filter_ps, NULL);
7062  }
7063  }
7064  } else if (par->codec_id == AV_CODEC_ID_VVC && trk->extradata_size[trk->last_stsd_index] > 6 &&
7065  (AV_RB24(trk->extradata[trk->last_stsd_index]) == 1 || AV_RB32(trk->extradata[trk->last_stsd_index]) == 1)) {
7066  /* extradata is Annex B, assume the bitstream is too and convert it */
7067  if (trk->hint_track >= 0 && trk->hint_track < mov->nb_tracks) {
7068  ret = ff_vvc_annexb2mp4_buf(pkt->data, &reformatted_data,
7069  &size, 0, NULL);
7070  if (ret < 0)
7071  return ret;
7072  avio_write(pb, reformatted_data, size);
7073  } else {
7074  size = ff_vvc_annexb2mp4(pb, pkt->data, pkt->size, 0, NULL);
7075  }
7076  } else if (par->codec_id == AV_CODEC_ID_LCEVC && trk->extradata_size[trk->last_stsd_index] > 0 &&
7077  *(uint8_t *)trk->extradata[trk->last_stsd_index] != 1) {
7078  /* extradata is Annex B, assume the bitstream is too and convert it */
7079  if (trk->hint_track >= 0 && trk->hint_track < mov->nb_tracks) {
7080  ret = ff_nal_parse_units_buf(pkt->data, &reformatted_data, &size);
7081  if (ret < 0)
7082  return ret;
7083  avio_write(pb, reformatted_data, size);
7084  } else {
7085  if (trk->cenc.aes_ctr) {
7087  if (size < 0) {
7088  ret = size;
7089  goto err;
7090  }
7091  } else {
7092  size = ff_nal_parse_units(pb, pkt->data, pkt->size);
7093  }
7094  }
7095  } else if (par->codec_id == AV_CODEC_ID_AV1 && !trk->cenc.aes_ctr) {
7096  if (trk->hint_track >= 0 && trk->hint_track < mov->nb_tracks) {
7097  ret = ff_av1_filter_obus_buf(pkt->data, &reformatted_data,
7098  &size, &offset);
7099  if (ret < 0)
7100  return ret;
7101  avio_write(pb, reformatted_data, size);
7102  } else {
7103  size = ff_av1_filter_obus(pb, pkt->data, pkt->size);
7104  if (trk->mode == MODE_AVIF && !mov->avif_extent_length[pkt->stream_index]) {
7106  }
7107  }
7108 
7109  } else if (par->codec_id == AV_CODEC_ID_AC3 ||
7110  par->codec_id == AV_CODEC_ID_EAC3) {
7111  size = handle_eac3(mov, pkt, trk);
7112  if (size < 0)
7113  return size;
7114  else if (!size)
7115  goto end;
7116  avio_write(pb, pkt->data, size);
7117  } else if (par->codec_id == AV_CODEC_ID_EIA_608) {
7118  size = 8;
7119 
7120  for (int i = 0; i < pkt->size; i += 3) {
7121  if (pkt->data[i] == 0xFC) {
7122  size += 2;
7123  }
7124  }
7125  avio_wb32(pb, size);
7126  ffio_wfourcc(pb, "cdat");
7127  for (int i = 0; i < pkt->size; i += 3) {
7128  if (pkt->data[i] == 0xFC) {
7129  avio_w8(pb, pkt->data[i + 1]);
7130  avio_w8(pb, pkt->data[i + 2]);
7131  }
7132  }
7133  } else if (par->codec_id == AV_CODEC_ID_APV) {
7134  ff_isom_parse_apvc(trk->apv, pkt, s);
7135  avio_wb32(s->pb, pkt->size);
7136  size += 4;
7137 
7138  avio_write(s->pb, pkt->data, pkt->size);
7139  } else {
7140  if (trk->cenc.aes_ctr) {
7141  uint8_t *extradata = trk->extradata[trk->last_stsd_index];
7142  int extradata_size = trk->extradata_size[trk->last_stsd_index];
7143  if (par->codec_id == AV_CODEC_ID_H264 && extradata_size > 4) {
7144  int nal_size_length = (extradata[4] & 0x3) + 1;
7145  ret = ff_mov_cenc_avc_write_nal_units(s, &trk->cenc, nal_size_length, pb, pkt->data, size);
7146  } else if(par->codec_id == AV_CODEC_ID_HEVC && extradata_size > 21) {
7147  int nal_size_length = (extradata[21] & 0x3) + 1;
7148  ret = ff_mov_cenc_avc_write_nal_units(s, &trk->cenc, nal_size_length, pb, pkt->data, size);
7149  } else if(par->codec_id == AV_CODEC_ID_VVC) {
7151  } else if(par->codec_id == AV_CODEC_ID_AV1) {
7152  av_assert0(size == pkt->size);
7153  ret = ff_mov_cenc_av1_write_obus(s, &trk->cenc, pb, pkt);
7154  if (ret > 0) {
7155  size = ret;
7156  ret = 0;
7157  }
7158  } else {
7159  ret = ff_mov_cenc_write_packet(&trk->cenc, pb, pkt->data, size);
7160  }
7161 
7162  if (ret) {
7163  goto err;
7164  }
7165  } else {
7166  avio_write(pb, pkt->data, size);
7167  }
7168  }
7169 
7170  if (trk->entry >= trk->cluster_capacity) {
7171  unsigned new_capacity = trk->entry + MOV_INDEX_CLUSTER_SIZE;
7172  void *cluster = av_realloc_array(trk->cluster, new_capacity, sizeof(*trk->cluster));
7173  if (!cluster) {
7174  ret = AVERROR(ENOMEM);
7175  goto err;
7176  }
7177  trk->cluster = cluster;
7178  trk->cluster_capacity = new_capacity;
7179  }
7180 
7181  trk->cluster[trk->entry].pos = avio_tell(pb) - size;
7182  trk->cluster[trk->entry].stsd_index = trk->last_stsd_index;
7183  trk->cluster[trk->entry].samples_in_chunk = samples_in_chunk;
7184  trk->cluster[trk->entry].chunkNum = 0;
7185  trk->cluster[trk->entry].size = size;
7186  trk->cluster[trk->entry].entries = samples_in_chunk;
7187  trk->cluster[trk->entry].dts = pkt->dts;
7188  trk->cluster[trk->entry].pts = pkt->pts;
7189  if (!trk->squash_fragment_samples_to_one &&
7190  !trk->entry && trk->start_dts != AV_NOPTS_VALUE) {
7191  if (!trk->frag_discont) {
7192  /* First packet of a new fragment. We already wrote the duration
7193  * of the last packet of the previous fragment based on track_duration,
7194  * which might not exactly match our dts. Therefore adjust the dts
7195  * of this packet to be what the previous packets duration implies. */
7196  trk->cluster[trk->entry].dts = trk->start_dts + trk->track_duration;
7197  /* We also may have written the pts and the corresponding duration
7198  * in sidx/tfrf/tfxd tags; make sure the sidx pts and duration match up with
7199  * the next fragment. This means the cts of the first sample must
7200  * be the same in all fragments, unless end_pts was updated by
7201  * the packet causing the fragment to be written. */
7202  if ((mov->flags & FF_MOV_FLAG_DASH &&
7204  mov->mode == MODE_ISM)
7205  pkt->pts = pkt->dts + trk->end_pts - trk->cluster[trk->entry].dts;
7206  } else {
7207  /* New fragment, but discontinuous from previous fragments.
7208  * Pretend the duration sum of the earlier fragments is
7209  * pkt->dts - trk->start_dts. */
7210  trk->end_pts = trk->elst_end_pts = AV_NOPTS_VALUE;
7211  trk->frag_discont = 0;
7212  }
7213  }
7214 
7215  if (!trk->entry && trk->start_dts == AV_NOPTS_VALUE && !mov->use_editlist &&
7216  s->avoid_negative_ts == AVFMT_AVOID_NEG_TS_MAKE_ZERO) {
7217  /* Not using edit lists and shifting the first track to start from zero.
7218  * If the other streams start from a later timestamp, we won't be able
7219  * to signal the difference in starting time without an edit list.
7220  * Thus move the timestamp for this first sample to 0, increasing
7221  * its duration instead. */
7222  trk->cluster[trk->entry].dts = trk->start_dts = 0;
7223  }
7224  if (trk->start_dts == AV_NOPTS_VALUE) {
7225  trk->start_dts = pkt->dts;
7226  if (trk->frag_discont) {
7227  if (mov->use_editlist) {
7228  /* Pretend the whole stream started at pts=0, with earlier fragments
7229  * already written. If the stream started at pts=0, the duration sum
7230  * of earlier fragments would have been pkt->pts. */
7231  trk->start_dts = pkt->dts - pkt->pts;
7232  } else {
7233  /* Pretend the whole stream started at dts=0, with earlier fragments
7234  * already written, with a duration summing up to pkt->dts. */
7235  trk->start_dts = 0;
7236  }
7237  trk->frag_discont = 0;
7238  } else if (pkt->dts && mov->moov_written)
7240  "Track %d starts with a nonzero dts %"PRId64", while the moov "
7241  "already has been written. Set the delay_moov flag to handle "
7242  "this case.\n",
7243  pkt->stream_index, pkt->dts);
7244  }
7245  trk->track_duration = pkt->dts - trk->start_dts + pkt->duration;
7246  trk->last_sample_is_subtitle_end = 0;
7247 
7248  if (pkt->pts == AV_NOPTS_VALUE) {
7249  av_log(s, AV_LOG_WARNING, "pts has no value\n");
7250  pkt->pts = pkt->dts;
7251  }
7252  if (pkt->dts != pkt->pts)
7253  trk->flags |= MOV_TRACK_CTTS;
7254  trk->cluster[trk->entry].cts = pkt->pts - pkt->dts;
7255  trk->cluster[trk->entry].flags = 0;
7256  if (trk->start_cts == AV_NOPTS_VALUE || (pkt->dts <= 0 && trk->start_cts > pkt->pts - pkt->dts))
7257  trk->start_cts = pkt->pts - pkt->dts;
7258  if (trk->end_pts == AV_NOPTS_VALUE)
7259  trk->end_pts = trk->cluster[trk->entry].dts +
7260  trk->cluster[trk->entry].cts + pkt->duration;
7261  else
7262  trk->end_pts = FFMAX(trk->end_pts, trk->cluster[trk->entry].dts +
7263  trk->cluster[trk->entry].cts +
7264  pkt->duration);
7265  if (!(pkt->flags & AV_PKT_FLAG_DISCARD))
7266  trk->elst_end_pts = trk->end_pts;
7267 
7268  if (par->codec_id == AV_CODEC_ID_VC1) {
7269  mov_parse_vc1_frame(pkt, trk);
7270  } else if (par->codec_id == AV_CODEC_ID_TRUEHD) {
7272  } else if (pkt->flags & AV_PKT_FLAG_KEY) {
7273  if (mov->mode == MODE_MOV && par->codec_id == AV_CODEC_ID_MPEG2VIDEO &&
7274  trk->entry > 0) { // force sync sample for the first key frame
7276  if (trk->cluster[trk->entry].flags & MOV_PARTIAL_SYNC_SAMPLE)
7277  trk->flags |= MOV_TRACK_STPS;
7278  } else {
7279  trk->cluster[trk->entry].flags = MOV_SYNC_SAMPLE;
7280  }
7281  if (trk->cluster[trk->entry].flags & MOV_SYNC_SAMPLE)
7282  trk->has_keyframes++;
7283  }
7284  if (pkt->flags & AV_PKT_FLAG_DISPOSABLE) {
7285  trk->cluster[trk->entry].flags |= MOV_DISPOSABLE_SAMPLE;
7286  trk->has_disposable++;
7287  }
7288 
7290  if (prft && prft_size == sizeof(AVProducerReferenceTime))
7291  memcpy(&trk->cluster[trk->entry].prft, prft, prft_size);
7292  else
7293  memset(&trk->cluster[trk->entry].prft, 0, sizeof(AVProducerReferenceTime));
7294 
7295  trk->entry++;
7296  trk->sample_count += samples_in_chunk;
7297  mov->mdat_size += size;
7298 
7299  if (trk->hint_track >= 0 && trk->hint_track < mov->nb_tracks)
7301  reformatted_data ? reformatted_data + offset
7302  : NULL, size);
7303 
7304 end:
7305 err:
7306 
7307  if (pkt->data != reformatted_data)
7308  av_free(reformatted_data);
7309  return ret;
7310 }
7311 
7313 {
7314  MOVMuxContext *mov = s->priv_data;
7315  MOVTrack *trk = s->streams[pkt->stream_index]->priv_data;
7316  AVCodecParameters *par = trk->par;
7317  int64_t frag_duration = 0;
7318  int size = pkt->size;
7319 
7320  int ret = check_pkt(s, trk, pkt);
7321  if (ret < 0)
7322  return ret;
7323 
7324  if (mov->flags & FF_MOV_FLAG_FRAG_DISCONT) {
7325  for (int i = 0; i < mov->nb_streams; i++)
7326  mov->tracks[i].frag_discont = 1;
7328  }
7329 
7331  if (trk->dts_shift == AV_NOPTS_VALUE)
7332  trk->dts_shift = pkt->pts - pkt->dts;
7333  pkt->dts += trk->dts_shift;
7334  }
7335 
7336  if (trk->par->codec_id == AV_CODEC_ID_MP4ALS ||
7337  trk->par->codec_id == AV_CODEC_ID_AAC ||
7338  trk->par->codec_id == AV_CODEC_ID_AV1 ||
7339  trk->par->codec_id == AV_CODEC_ID_FLAC) {
7340  size_t side_size;
7341  uint8_t *side = av_packet_get_side_data(pkt, AV_PKT_DATA_NEW_EXTRADATA, &side_size);
7342  /* Overwrite extradata only on flush packets or when no extradata was available during init */
7343  if (side_size > 0 && (!pkt->size || !trk->extradata_size[trk->last_stsd_index])) {
7344  void *newextra = av_malloc(side_size + AV_INPUT_BUFFER_PADDING_SIZE);
7345  if (!newextra)
7346  return AVERROR(ENOMEM);
7347  memset((uint8_t*)newextra + side_size, 0, AV_INPUT_BUFFER_PADDING_SIZE);
7348  memcpy(newextra, side, side_size);
7349  av_free(trk->extradata[trk->last_stsd_index]);
7350  trk->extradata[trk->last_stsd_index] = newextra;
7351  trk->extradata_size[trk->last_stsd_index] = side_size;
7352  }
7353  }
7354 
7355  if (!pkt->size) {
7356  if (trk->start_dts == AV_NOPTS_VALUE && trk->frag_discont) {
7357  trk->start_dts = pkt->dts;
7358  if (pkt->pts != AV_NOPTS_VALUE)
7359  trk->start_cts = pkt->pts - pkt->dts;
7360  else
7361  trk->start_cts = 0;
7362  }
7363 
7364  return 0; /* Discard 0 sized packets */
7365  }
7366 
7367  if (trk->entry && pkt->stream_index < mov->nb_streams)
7368  frag_duration = av_rescale_q(pkt->dts - trk->cluster[0].dts,
7369  s->streams[pkt->stream_index]->time_base,
7370  AV_TIME_BASE_Q);
7371  if ((mov->max_fragment_duration &&
7372  frag_duration >= mov->max_fragment_duration) ||
7373  (mov->max_fragment_size && mov->mdat_size + size >= mov->max_fragment_size) ||
7374  (mov->flags & FF_MOV_FLAG_FRAG_KEYFRAME &&
7375  par->codec_type == AVMEDIA_TYPE_VIDEO &&
7376  trk->entry && pkt->flags & AV_PKT_FLAG_KEY) ||
7378  if (frag_duration >= mov->min_fragment_duration) {
7379  if (trk->entry) {
7380  // Set the duration of this track to line up with the next
7381  // sample in this track. This avoids relying on AVPacket
7382  // duration, but only helps for this particular track, not
7383  // for the other ones that are flushed at the same time.
7384  //
7385  // If we have trk->entry == 0, no fragment will be written
7386  // for this track, and we can't adjust the track end here.
7387  trk->track_duration = pkt->dts - trk->start_dts;
7388  if (pkt->pts != AV_NOPTS_VALUE)
7389  trk->end_pts = pkt->pts;
7390  else
7391  trk->end_pts = pkt->dts;
7392  if (!(pkt->flags & AV_PKT_FLAG_DISCARD))
7393  trk->elst_end_pts = trk->end_pts;
7394  trk->end_reliable = 1;
7395  }
7397  }
7398  }
7399 
7400  return ff_mov_write_packet(s, pkt);
7401 }
7402 
7404  int stream_index,
7405  int64_t dts) {
7406  MOVMuxContext *mov = s->priv_data;
7407  AVPacket *end = mov->pkt;
7408  uint8_t data[2] = {0};
7409  int ret;
7410 
7411  end->size = sizeof(data);
7412  end->data = data;
7413  end->pts = dts;
7414  end->dts = dts;
7415  end->duration = 0;
7416  end->stream_index = stream_index;
7417 
7418  ret = mov_write_single_packet(s, end);
7419  av_packet_unref(end);
7420 
7421  return ret;
7422 }
7423 
7424 #if CONFIG_IAMFENC
7425 static int mov_build_iamf_packet(AVFormatContext *s, MOVTrack *trk, AVPacket *pkt)
7426 {
7427  uint8_t *data;
7428  int ret;
7429 
7430  if (pkt->stream_index == trk->first_iamf_idx) {
7432  if (ret < 0)
7433  return ret;
7434  }
7435 
7437  s->streams[pkt->stream_index]->id, pkt);
7438  if (ret < 0)
7439  return ret;
7440 
7441  if (pkt->stream_index != trk->last_iamf_idx)
7442  return AVERROR(EAGAIN);
7443 
7444  ret = avio_close_dyn_buf(trk->iamf_buf, &data);
7445  trk->iamf_buf = NULL;
7446  if (!ret) {
7447  if (pkt->size) {
7448  // Either all or none of the packets for a single
7449  // IA Sample may be empty.
7450  av_log(s, AV_LOG_ERROR, "Unexpected packet from "
7451  "stream #%d\n", pkt->stream_index);
7453  }
7454  av_free(data);
7455  return ret;
7456  }
7457 
7458  av_buffer_unref(&pkt->buf);
7459  pkt->buf = av_buffer_create(data, ret, NULL, NULL, 0);
7460  if (!pkt->buf) {
7461  av_free(data);
7462  return AVERROR(ENOMEM);
7463  }
7464  pkt->data = data;
7465  pkt->size = ret;
7467 
7468  return avio_open_dyn_buf(&trk->iamf_buf);
7469 }
7470 #endif
7471 
7473 {
7474  int64_t pos = avio_tell(pb);
7475  const char *scheme_id_uri = "https://aomedia.org/emsg/ID3";
7476  const char *value = "";
7477 
7478  av_assert0(st->time_base.num == 1);
7479 
7480  avio_write_marker(pb,
7483 
7484  avio_wb32(pb, 0); /* size */
7485  ffio_wfourcc(pb, "emsg");
7486  avio_w8(pb, 1); /* version */
7487  avio_wb24(pb, 0);
7488  avio_wb32(pb, st->time_base.den); /* timescale */
7489  avio_wb64(pb, pkt->pts); /* presentation_time */
7490  avio_wb32(pb, 0xFFFFFFFFU); /* event_duration */
7491  avio_wb32(pb, 0); /* id */
7492  /* null terminated UTF8 strings */
7493  avio_write(pb, scheme_id_uri, strlen(scheme_id_uri) + 1);
7494  avio_write(pb, value, strlen(value) + 1);
7495  avio_write(pb, pkt->data, pkt->size);
7496 
7497  return update_size(pb, pos);
7498 }
7499 
7501 {
7502  MOVMuxContext *mov = s->priv_data;
7503  MOVTrack *trk;
7504 
7505  if (!pkt) {
7506  mov_flush_fragment(s, 1);
7507  return 1;
7508  }
7509 
7510  if (s->streams[pkt->stream_index]->codecpar->codec_id == AV_CODEC_ID_TIMED_ID3) {
7511  mov_write_emsg_tag(s->pb, s->streams[pkt->stream_index], pkt);
7512  return 0;
7513  }
7514 
7515  trk = s->streams[pkt->stream_index]->priv_data;
7516 
7517 #if CONFIG_IAMFENC
7518  if (trk->iamf) {
7519  int ret = mov_build_iamf_packet(s, trk, pkt);
7520  if (ret < 0) {
7521  if (ret == AVERROR(EAGAIN))
7522  return 0;
7523  av_log(s, AV_LOG_ERROR, "Error assembling an IAMF packet "
7524  "for stream #%d\n", trk->st->index);
7525  return ret;
7526  }
7527  }
7528 #endif
7529 
7530  if (is_cover_image(trk->st)) {
7531  int ret;
7532 
7533  if (trk->st->nb_frames >= 1) {
7534  if (trk->st->nb_frames == 1)
7535  av_log(s, AV_LOG_WARNING, "Got more than one picture in stream %d,"
7536  " ignoring.\n", pkt->stream_index);
7537  return 0;
7538  }
7539 
7540  if ((ret = av_packet_ref(trk->cover_image, pkt)) < 0)
7541  return ret;
7542 
7543  return 0;
7544  } else {
7545  int i;
7546 
7547  if (!pkt->size)
7548  return mov_write_single_packet(s, pkt); /* Passthrough. */
7549 
7550  /*
7551  * Subtitles require special handling.
7552  *
7553  * 1) For full compliance, every track must have a sample at
7554  * dts == 0, which is rarely true for subtitles. So, as soon
7555  * as we see any packet with dts > 0, write an empty subtitle
7556  * at dts == 0 for any subtitle track with no samples in it.
7557  *
7558  * 2) For each subtitle track, check if the current packet's
7559  * dts is past the duration of the last subtitle sample. If
7560  * so, we now need to write an end sample for that subtitle.
7561  *
7562  * This must be done conditionally to allow for subtitles that
7563  * immediately replace each other, in which case an end sample
7564  * is not needed, and is, in fact, actively harmful.
7565  *
7566  * 3) See mov_write_trailer for how the final end sample is
7567  * handled.
7568  */
7569  for (i = 0; i < mov->nb_tracks; i++) {
7570  MOVTrack *trk = &mov->tracks[i];
7571  int ret;
7572 
7573  if (trk->par->codec_id == AV_CODEC_ID_MOV_TEXT &&
7574  trk->track_duration < pkt->dts &&
7575  (trk->entry == 0 || !trk->last_sample_is_subtitle_end)) {
7577  if (ret < 0) return ret;
7578  trk->last_sample_is_subtitle_end = 1;
7579  }
7580  }
7581 
7582  if (trk->squash_fragment_samples_to_one) {
7583  /*
7584  * If the track has to have its samples squashed into one sample,
7585  * we just take it into the track's queue.
7586  * This will then be utilized as the samples get written in either
7587  * mov_flush_fragment or when the mux is finalized in
7588  * mov_write_trailer.
7589  */
7590  int ret = AVERROR_BUG;
7591 
7592  if (pkt->pts == AV_NOPTS_VALUE) {
7594  "Packets without a valid presentation timestamp are "
7595  "not supported with packet squashing!\n");
7596  return AVERROR(EINVAL);
7597  }
7598 
7599  /* The following will reset pkt and is only allowed to be used
7600  * because we return immediately. afterwards. */
7602  pkt, NULL, 0)) < 0) {
7603  return ret;
7604  }
7605 
7606  return 0;
7607  }
7608 
7609 
7610  if (trk->mode == MODE_MOV && trk->par->codec_type == AVMEDIA_TYPE_VIDEO) {
7611  AVPacket *opkt = pkt;
7612  int reshuffle_ret, ret;
7613  if (trk->is_unaligned_qt_rgb) {
7614  int64_t bpc = trk->par->bits_per_coded_sample != 15 ? trk->par->bits_per_coded_sample : 16;
7615  int expected_stride = ((trk->par->width * bpc + 15) >> 4)*2;
7616  reshuffle_ret = ff_reshuffle_raw_rgb(s, &pkt, trk->par, expected_stride);
7617  if (reshuffle_ret < 0)
7618  return reshuffle_ret;
7619  } else
7620  reshuffle_ret = 0;
7621  if (trk->par->format == AV_PIX_FMT_PAL8 && !trk->pal_done) {
7622  ret = ff_get_packet_palette(s, opkt, reshuffle_ret, trk->palette);
7623  if (ret < 0)
7624  goto fail;
7625  if (ret)
7626  trk->pal_done++;
7627  } else if (trk->par->codec_id == AV_CODEC_ID_RAWVIDEO &&
7628  (trk->par->format == AV_PIX_FMT_GRAY8 ||
7629  trk->par->format == AV_PIX_FMT_MONOBLACK)) {
7631  if (ret < 0)
7632  goto fail;
7633  for (i = 0; i < pkt->size; i++)
7634  pkt->data[i] = ~pkt->data[i];
7635  }
7636  if (reshuffle_ret) {
7638 fail:
7639  if (reshuffle_ret)
7640  av_packet_free(&pkt);
7641  return ret;
7642  }
7643  }
7644 
7645  return mov_write_single_packet(s, pkt);
7646  }
7647 }
7648 
7649 // QuickTime chapters involve an additional text track with the chapter names
7650 // as samples, and a tref pointing from the other tracks to the chapter one.
7651 static int mov_create_chapter_track(AVFormatContext *s, int tracknum)
7652 {
7653  static const uint8_t stub_header[] = {
7654  // TextSampleEntry
7655  0x00, 0x00, 0x00, 0x01, // displayFlags
7656  0x00, 0x00, // horizontal + vertical justification
7657  0x00, 0x00, 0x00, 0x00, // bgColourRed/Green/Blue/Alpha
7658  // BoxRecord
7659  0x00, 0x00, 0x00, 0x00, // defTextBoxTop/Left
7660  0x00, 0x00, 0x00, 0x00, // defTextBoxBottom/Right
7661  // StyleRecord
7662  0x00, 0x00, 0x00, 0x00, // startChar + endChar
7663  0x00, 0x01, // fontID
7664  0x00, 0x00, // fontStyleFlags + fontSize
7665  0x00, 0x00, 0x00, 0x00, // fgColourRed/Green/Blue/Alpha
7666  // FontTableBox
7667  0x00, 0x00, 0x00, 0x0D, // box size
7668  'f', 't', 'a', 'b', // box atom name
7669  0x00, 0x01, // entry count
7670  // FontRecord
7671  0x00, 0x01, // font ID
7672  0x00, // font name length
7673  };
7674  MOVMuxContext *mov = s->priv_data;
7675  MOVTrack *track = &mov->tracks[tracknum];
7676  AVPacket *pkt = mov->pkt;
7677  int i, len;
7678  int ret;
7679 
7680  track->mode = mov->mode;
7681  track->tag = MKTAG('t','e','x','t');
7682  track->timescale = mov->movie_timescale;
7683  track->par = avcodec_parameters_alloc();
7684  if (!track->par)
7685  return AVERROR(ENOMEM);
7687  ret = ff_alloc_extradata(track->par, sizeof(stub_header));
7688  if (ret < 0)
7689  return ret;
7690  memcpy(track->par->extradata, stub_header, sizeof(stub_header));
7691 
7692  if (track->extradata == NULL) {
7693  track->stsd_count = 1;
7694  track->extradata = av_calloc(1, sizeof(*track->extradata));
7695  track->extradata_size = av_calloc(1, sizeof(*track->extradata_size));
7696  if (!track->extradata || !track->extradata_size)
7697  return AVERROR(ENOMEM);
7698  }
7699 
7700  track->extradata[0] = av_memdup(stub_header, sizeof(stub_header));
7701  if (!track->extradata[0])
7702  return AVERROR(ENOMEM);
7703  track->extradata_size[0] = sizeof(stub_header);
7704 
7705  pkt->stream_index = tracknum;
7707 
7708  for (i = 0; i < s->nb_chapters; i++) {
7709  AVChapter *c = s->chapters[i];
7710  AVDictionaryEntry *t;
7711 
7712  int64_t end = av_rescale_q(c->end, c->time_base, (AVRational){1,mov->movie_timescale});
7713  pkt->pts = pkt->dts = av_rescale_q(c->start, c->time_base, (AVRational){1,mov->movie_timescale});
7714  pkt->duration = end - pkt->dts;
7715 
7716  if ((t = av_dict_get(c->metadata, "title", NULL, 0))) {
7717  static const char encd[12] = {
7718  0x00, 0x00, 0x00, 0x0C,
7719  'e', 'n', 'c', 'd',
7720  0x00, 0x00, 0x01, 0x00 };
7721  len = strlen(t->value);
7722  pkt->size = len + 2 + 12;
7723  pkt->data = av_malloc(pkt->size);
7724  if (!pkt->data) {
7726  return AVERROR(ENOMEM);
7727  }
7728  AV_WB16(pkt->data, len);
7729  memcpy(pkt->data + 2, t->value, len);
7730  memcpy(pkt->data + len + 2, encd, sizeof(encd));
7732  av_freep(&pkt->data);
7733  }
7734  }
7735 
7736  av_packet_unref(mov->pkt);
7737 
7738  return 0;
7739 }
7740 
7741 
7742 static int mov_check_timecode_track(AVFormatContext *s, AVTimecode *tc, AVStream *src_st, const char *tcstr)
7743 {
7744  int ret;
7745 
7746  /* compute the frame number */
7747  ret = av_timecode_init_from_string(tc, src_st->avg_frame_rate, tcstr, s);
7748  return ret;
7749 }
7750 
7751 static int mov_create_timecode_track(AVFormatContext *s, int index, int src_index, AVTimecode tc)
7752 {
7753  MOVMuxContext *mov = s->priv_data;
7754  MOVTrack *track = &mov->tracks[index];
7755  AVStream *src_st = mov->tracks[src_index].st;
7756  uint8_t data[4];
7757  AVPacket *pkt = mov->pkt;
7758  AVRational rate = src_st->avg_frame_rate;
7759  int ret;
7760 
7761  /* tmcd track based on video stream */
7762  track->mode = mov->mode;
7763  track->tag = MKTAG('t','m','c','d');
7764  track->src_track = av_malloc(sizeof(*track->src_track));
7765  if (!track->src_track)
7766  return AVERROR(ENOMEM);
7767  *track->src_track = src_index;
7768  track->nb_src_track = 1;
7769  track->timescale = mov->tracks[src_index].timescale;
7772 
7773  /* set st to src_st for metadata access*/
7774  track->st = src_st;
7775 
7776  /* encode context: tmcd data stream */
7777  track->par = avcodec_parameters_alloc();
7778  if (!track->par)
7779  return AVERROR(ENOMEM);
7780  track->par->codec_type = AVMEDIA_TYPE_DATA;
7781  track->par->codec_tag = track->tag;
7782  track->st->avg_frame_rate = rate;
7783 
7784  /* the tmcd track just contains one packet with the frame number */
7785  pkt->data = data;
7786  pkt->stream_index = index;
7788  pkt->pts = pkt->dts = av_rescale_q(tc.start, av_inv_q(rate), (AVRational){1,mov->movie_timescale});
7789  pkt->size = 4;
7790  AV_WB32(pkt->data, tc.start);
7793  return ret;
7794 }
7795 
7796 /*
7797  * st->disposition controls the "enabled" flag in the tkhd tag.
7798  * QuickTime will not play a track if it is not enabled. So make sure
7799  * that one track of each type (audio, video, subtitle) is enabled.
7800  *
7801  * Subtitles are special. For audio and video, setting "enabled" also
7802  * makes the track "default" (i.e. it is rendered when played). For
7803  * subtitles, an "enabled" subtitle is not rendered by default, but
7804  * if no subtitle is enabled, the subtitle menu in QuickTime will be
7805  * empty!
7806  */
7808 {
7809  MOVMuxContext *mov = s->priv_data;
7810  int i;
7811  int enabled[AVMEDIA_TYPE_NB];
7812  int first[AVMEDIA_TYPE_NB];
7813 
7814  for (i = 0; i < AVMEDIA_TYPE_NB; i++) {
7815  enabled[i] = 0;
7816  first[i] = -1;
7817  }
7818 
7819  for (i = 0; i < mov->nb_streams; i++) {
7820  AVStream *st = mov->tracks[i].st;
7821 
7824  is_cover_image(st))
7825  continue;
7826 
7827  if (first[st->codecpar->codec_type] < 0)
7828  first[st->codecpar->codec_type] = i;
7829  if (st->disposition & AV_DISPOSITION_DEFAULT) {
7830  mov->tracks[i].flags |= MOV_TRACK_ENABLED;
7831  enabled[st->codecpar->codec_type]++;
7832  }
7833  }
7834 
7835  for (i = 0; i < AVMEDIA_TYPE_NB; i++) {
7836  switch (i) {
7837  case AVMEDIA_TYPE_VIDEO:
7838  case AVMEDIA_TYPE_AUDIO:
7839  case AVMEDIA_TYPE_SUBTITLE:
7840  if (enabled[i] > 1)
7841  mov->per_stream_grouping = 1;
7842  if (!enabled[i] && first[i] >= 0)
7843  mov->tracks[first[i]].flags |= MOV_TRACK_ENABLED;
7844  break;
7845  }
7846  }
7847 }
7848 
7850 {
7851  MOVMuxContext *mov = s->priv_data;
7852 
7853  for (int i = 0; i < s->nb_streams; i++)
7854  s->streams[i]->priv_data = NULL;
7855 
7856  if (!mov->tracks)
7857  return;
7858 
7859  if (mov->chapter_track) {
7861  }
7862 
7863  for (int i = 0; i < mov->nb_tracks; i++) {
7864  MOVTrack *const track = &mov->tracks[i];
7865 
7866  if (track->tag == MKTAG('r','t','p',' '))
7867  ff_mov_close_hinting(track);
7868  else if (track->tag == MKTAG('t','m','c','d') && mov->nb_meta_tmcd)
7869  av_freep(&track->par);
7870  av_freep(&track->cluster);
7871  av_freep(&track->cluster_written);
7872  av_freep(&track->frag_info);
7873  av_packet_free(&track->cover_image);
7874 
7875  if (track->eac3_priv) {
7876  struct eac3_info *info = track->eac3_priv;
7877  av_packet_free(&info->pkt);
7878  av_freep(&track->eac3_priv);
7879  }
7880  for (int j = 0; j < track->stsd_count; j++)
7881  av_freep(&track->extradata[j]);
7882  av_freep(&track->extradata);
7883  av_freep(&track->extradata_size);
7884 
7885  for (int i = 0; i < track->nb_tref_tags; i++)
7886  av_freep(&track->tref_tags[i].id);
7887  av_freep(&track->tref_tags);
7888  av_freep(&track->src_track);
7889 
7890  ff_mov_cenc_free(&track->cenc);
7891  ffio_free_dyn_buf(&track->mdat_buf);
7892 
7893 #if CONFIG_IAMFENC
7894  ffio_free_dyn_buf(&track->iamf_buf);
7895  if (track->iamf)
7896  ff_iamf_uninit_context(track->iamf);
7897  av_freep(&track->iamf);
7898 #endif
7899  ff_isom_close_apvc(&track->apv);
7900 
7902  }
7903 
7904  av_freep(&mov->tracks);
7905  ffio_free_dyn_buf(&mov->mdat_buf);
7906 }
7907 
7908 static uint32_t rgb_to_yuv(uint32_t rgb)
7909 {
7910  uint8_t r, g, b;
7911  int y, cb, cr;
7912 
7913  r = (rgb >> 16) & 0xFF;
7914  g = (rgb >> 8) & 0xFF;
7915  b = (rgb ) & 0xFF;
7916 
7917  y = av_clip_uint8(( 16000 + 257 * r + 504 * g + 98 * b)/1000);
7918  cb = av_clip_uint8((128000 - 148 * r - 291 * g + 439 * b)/1000);
7919  cr = av_clip_uint8((128000 + 439 * r - 368 * g - 71 * b)/1000);
7920 
7921  return (y << 16) | (cr << 8) | cb;
7922 }
7923 
7925  AVStream *st)
7926 {
7927  int i, width = 720, height = 480;
7928  int have_palette = 0, have_size = 0;
7929  uint32_t palette[16];
7930  char *cur = track->extradata[track->last_stsd_index];
7931 
7932  while (cur && *cur) {
7933  if (strncmp("palette:", cur, 8) == 0) {
7934  int i, count;
7935  count = sscanf(cur + 8,
7936  "%06"PRIx32", %06"PRIx32", %06"PRIx32", %06"PRIx32", "
7937  "%06"PRIx32", %06"PRIx32", %06"PRIx32", %06"PRIx32", "
7938  "%06"PRIx32", %06"PRIx32", %06"PRIx32", %06"PRIx32", "
7939  "%06"PRIx32", %06"PRIx32", %06"PRIx32", %06"PRIx32"",
7940  &palette[ 0], &palette[ 1], &palette[ 2], &palette[ 3],
7941  &palette[ 4], &palette[ 5], &palette[ 6], &palette[ 7],
7942  &palette[ 8], &palette[ 9], &palette[10], &palette[11],
7943  &palette[12], &palette[13], &palette[14], &palette[15]);
7944 
7945  for (i = 0; i < count; i++) {
7946  palette[i] = rgb_to_yuv(palette[i]);
7947  }
7948  have_palette = 1;
7949  } else if (!strncmp("size:", cur, 5)) {
7950  sscanf(cur + 5, "%dx%d", &width, &height);
7951  have_size = 1;
7952  }
7953  if (have_palette && have_size)
7954  break;
7955  cur += strcspn(cur, "\n\r");
7956  cur += strspn(cur, "\n\r");
7957  }
7958  if (have_palette) {
7960  if (!track->extradata[track->last_stsd_index])
7961  return AVERROR(ENOMEM);
7962  for (i = 0; i < 16; i++) {
7963  AV_WB32(track->extradata[track->last_stsd_index] + i * 4, palette[i]);
7964  }
7965  memset(track->extradata[track->last_stsd_index] + 16*4, 0, AV_INPUT_BUFFER_PADDING_SIZE);
7966  track->extradata_size[track->last_stsd_index] = 16 * 4;
7967  }
7968  st->codecpar->width = width;
7969  st->codecpar->height = track->height = height;
7970 
7971  return 0;
7972 }
7973 
7974 #if CONFIG_IAMFENC
7975 static int mov_init_iamf_track(AVFormatContext *s)
7976 {
7977  MOVMuxContext *mov = s->priv_data;
7978  MOVTrack *track;
7979  IAMFContext *iamf;
7980  int first_iamf_idx = INT_MAX, last_iamf_idx = 0;
7981  int nb_audio_elements = 0, nb_mix_presentations = 0;
7982  int ret;
7983 
7984  for (int i = 0; i < s->nb_stream_groups; i++) {
7985  const AVStreamGroup *stg = s->stream_groups[i];
7986 
7988  nb_audio_elements++;
7990  nb_mix_presentations++;
7991  }
7992 
7993  if (!nb_audio_elements && !nb_mix_presentations)
7994  return 0;
7995 
7996  if (nb_audio_elements < 1 || nb_audio_elements > 2 || nb_mix_presentations < 1) {
7997  av_log(s, AV_LOG_ERROR, "There must be >= 1 and <= 2 IAMF_AUDIO_ELEMENT and at least "
7998  "one IAMF_MIX_PRESENTATION stream groups to write a IMAF track\n");
7999  return AVERROR(EINVAL);
8000  }
8001 
8002  iamf = av_mallocz(sizeof(*iamf));
8003  if (!iamf)
8004  return AVERROR(ENOMEM);
8005 
8006 
8007  for (int i = 0; i < s->nb_stream_groups; i++) {
8008  const AVStreamGroup *stg = s->stream_groups[i];
8009  switch(stg->type) {
8011  for (int j = 0; j < stg->nb_streams; j++) {
8012  first_iamf_idx = FFMIN(stg->streams[j]->index, first_iamf_idx);
8013  last_iamf_idx = FFMAX(stg->streams[j]->index, last_iamf_idx);
8014  }
8015 
8016  ret = ff_iamf_add_audio_element(iamf, stg, s);
8017  break;
8019  ret = ff_iamf_add_mix_presentation(iamf, stg, s);
8020  break;
8021  default:
8022  av_assert0(0);
8023  }
8024  if (ret < 0) {
8025  ff_iamf_uninit_context(iamf);
8026  av_free(iamf);
8027  return ret;
8028  }
8029  }
8030 
8031  track = &mov->tracks[first_iamf_idx];
8032  track->iamf = iamf;
8033  track->first_iamf_idx = first_iamf_idx;
8034  track->last_iamf_idx = last_iamf_idx;
8035  track->tag = MKTAG('i','a','m','f');
8036 
8037  for (int i = 0; i < s->nb_stream_groups; i++) {
8038  AVStreamGroup *stg = s->stream_groups[i];
8040  continue;
8041  for (int j = 0; j < stg->nb_streams; j++)
8042  stg->streams[j]->priv_data = track;
8043  }
8044 
8045  ret = avio_open_dyn_buf(&track->iamf_buf);
8046  if (ret < 0)
8047  return ret;
8048 
8049  return 0;
8050 }
8051 #endif
8052 
8054 {
8055  MOVMuxContext *mov = s->priv_data;
8056  int has_iamf = 0;
8057  int i, ret;
8058 
8059  mov->fc = s;
8060  mov->pkt = ffformatcontext(s)->pkt;
8061 
8062  /* Default mode == MP4 */
8063  mov->mode = MODE_MP4;
8064 
8065 #define IS_MODE(muxer, config) (CONFIG_ ## config ## _MUXER && !strcmp(#muxer, s->oformat->name))
8066  if (IS_MODE(3gp, TGP)) mov->mode = MODE_3GP;
8067  else if (IS_MODE(3g2, TG2)) mov->mode = MODE_3GP|MODE_3G2;
8068  else if (IS_MODE(mov, MOV)) mov->mode = MODE_MOV;
8069  else if (IS_MODE(psp, PSP)) mov->mode = MODE_PSP;
8070  else if (IS_MODE(ipod, IPOD)) mov->mode = MODE_IPOD;
8071  else if (IS_MODE(ismv, ISMV)) mov->mode = MODE_ISM;
8072  else if (IS_MODE(f4v, F4V)) mov->mode = MODE_F4V;
8073  else if (IS_MODE(avif, AVIF)) mov->mode = MODE_AVIF;
8074 #undef IS_MODE
8075 
8076  if (mov->flags & FF_MOV_FLAG_DELAY_MOOV)
8077  mov->flags |= FF_MOV_FLAG_EMPTY_MOOV;
8078 
8079  if (mov->mode == MODE_AVIF)
8080  mov->flags |= FF_MOV_FLAG_DELAY_MOOV;
8081 
8082  /* Set the FRAGMENT flag if any of the fragmentation methods are
8083  * enabled. */
8084  if (mov->max_fragment_duration || mov->max_fragment_size ||
8085  mov->flags & (FF_MOV_FLAG_EMPTY_MOOV |
8089  mov->flags |= FF_MOV_FLAG_FRAGMENT;
8090 
8091  if (mov->flags & FF_MOV_FLAG_HYBRID_FRAGMENTED &&
8092  mov->flags & FF_MOV_FLAG_FASTSTART) {
8093  av_log(s, AV_LOG_ERROR, "Setting both hybrid_fragmented and faststart is not supported.\n");
8094  return AVERROR(EINVAL);
8095  }
8096 
8097  /* Set other implicit flags immediately */
8099  mov->flags |= FF_MOV_FLAG_FRAGMENT;
8100 
8101  if (mov->mode == MODE_ISM)
8104  if (mov->flags & FF_MOV_FLAG_DASH)
8107  if (mov->flags & FF_MOV_FLAG_CMAF)
8110 
8111  if (mov->flags & FF_MOV_FLAG_EMPTY_MOOV && s->flags & AVFMT_FLAG_AUTO_BSF) {
8112  av_log(s, AV_LOG_VERBOSE, "Empty MOOV enabled; disabling automatic bitstream filtering\n");
8113  s->flags &= ~AVFMT_FLAG_AUTO_BSF;
8114  }
8115 
8117  av_log(s, AV_LOG_WARNING, "Global SIDX enabled; Ignoring skip_sidx option\n");
8118  mov->flags &= ~FF_MOV_FLAG_SKIP_SIDX;
8119  }
8120 
8121  if (mov->flags & FF_MOV_FLAG_FASTSTART) {
8122  mov->reserved_moov_size = -1;
8123  }
8124 
8125  if (mov->use_editlist < 0) {
8126  mov->use_editlist = 1;
8127  if (mov->flags & FF_MOV_FLAG_FRAGMENT &&
8128  !(mov->flags & FF_MOV_FLAG_DELAY_MOOV)) {
8129  // If we can avoid needing an edit list by shifting the
8130  // tracks, prefer that over (trying to) write edit lists
8131  // in fragmented output.
8132  if (s->avoid_negative_ts == AVFMT_AVOID_NEG_TS_AUTO ||
8133  s->avoid_negative_ts == AVFMT_AVOID_NEG_TS_MAKE_ZERO)
8134  mov->use_editlist = 0;
8135  }
8136  }
8137  if (mov->flags & FF_MOV_FLAG_EMPTY_MOOV &&
8138  !(mov->flags & FF_MOV_FLAG_DELAY_MOOV) && mov->use_editlist)
8139  av_log(s, AV_LOG_WARNING, "No meaningful edit list will be written when using empty_moov without delay_moov\n");
8140 
8141  if (!mov->use_editlist && s->avoid_negative_ts == AVFMT_AVOID_NEG_TS_AUTO &&
8143  s->avoid_negative_ts = AVFMT_AVOID_NEG_TS_MAKE_ZERO;
8144 
8145  /* Clear the omit_tfhd_offset flag if default_base_moof is set;
8146  * if the latter is set that's enough and omit_tfhd_offset doesn't
8147  * add anything extra on top of that. */
8148  if (mov->flags & FF_MOV_FLAG_OMIT_TFHD_OFFSET &&
8151 
8152  if (mov->frag_interleave &&
8155  "Sample interleaving in fragments is mutually exclusive with "
8156  "omit_tfhd_offset and separate_moof\n");
8157  return AVERROR(EINVAL);
8158  }
8159 
8160  /* Non-seekable output is ok if using fragmentation. If ism_lookahead
8161  * is enabled, we don't support non-seekable output at all. */
8162  if (!(s->pb->seekable & AVIO_SEEKABLE_NORMAL) &&
8163  (!(mov->flags & FF_MOV_FLAG_FRAGMENT) || mov->ism_lookahead ||
8164  mov->mode == MODE_AVIF)) {
8165  av_log(s, AV_LOG_ERROR, "muxer does not support non seekable output\n");
8166  return AVERROR(EINVAL);
8167  }
8168 
8169  /* AVIF output must have at most two video streams (one for YUV and one for
8170  * alpha). */
8171  if (mov->mode == MODE_AVIF) {
8172  if (s->nb_streams > 2) {
8173  av_log(s, AV_LOG_ERROR, "AVIF output requires exactly one or two streams\n");
8174  return AVERROR(EINVAL);
8175  }
8176  if (s->streams[0]->codecpar->codec_type != AVMEDIA_TYPE_VIDEO &&
8177  (s->nb_streams > 1 && s->streams[1]->codecpar->codec_type != AVMEDIA_TYPE_VIDEO)) {
8178  av_log(s, AV_LOG_ERROR, "AVIF output supports only video streams\n");
8179  return AVERROR(EINVAL);
8180  }
8181  if (s->nb_streams > 1) {
8182  const AVPixFmtDescriptor *pixdesc =
8183  av_pix_fmt_desc_get(s->streams[1]->codecpar->format);
8184  if (pixdesc->nb_components != 1) {
8185  av_log(s, AV_LOG_ERROR, "Second stream for AVIF (alpha) output must have exactly one plane\n");
8186  return AVERROR(EINVAL);
8187  }
8188  }
8189  s->streams[0]->disposition |= AV_DISPOSITION_DEFAULT;
8190  }
8191 
8192  for (i = 0; i < s->nb_stream_groups; i++) {
8193  AVStreamGroup *stg = s->stream_groups[i];
8194 
8195  if (stg->type == AV_STREAM_GROUP_PARAMS_LCEVC) {
8196  if (stg->nb_streams != 2) {
8197  av_log(s, AV_LOG_ERROR, "Exactly two Streams are supported for Stream Groups of type LCEVC\n");
8198  return AVERROR(EINVAL);
8199  }
8200  AVStreamGroupLCEVC *lcevc = stg->params.lcevc;
8201  if (lcevc->lcevc_index > 1)
8202  return AVERROR(EINVAL);
8203  AVStream *st = stg->streams[lcevc->lcevc_index];
8204  if (st->codecpar->codec_id != AV_CODEC_ID_LCEVC) {
8205  av_log(s, AV_LOG_ERROR, "Stream #%u is not an LCEVC stream\n", lcevc->lcevc_index);
8206  return AVERROR(EINVAL);
8207  }
8208  }
8209 
8210 #if CONFIG_IAMFENC
8212  continue;
8213 
8214  for (int j = 0; j < stg->nb_streams; j++) {
8215  AVStream *st = stg->streams[j];
8216 
8217  if (st->priv_data) {
8218  av_log(s, AV_LOG_ERROR, "Stream %d is present in more than one Stream Group of type "
8219  "IAMF Audio Element\n", j);
8220  return AVERROR(EINVAL);
8221  }
8222  st->priv_data = st;
8223  }
8224  has_iamf = 1;
8225 
8226  if (!mov->nb_tracks) // We support one track for the entire IAMF structure
8227  mov->nb_tracks++;
8228 #endif
8229  }
8230 
8231  for (i = 0; i < s->nb_streams; i++) {
8232  AVStream *st = s->streams[i];
8233  if (st->priv_data)
8234  continue;
8235  // Don't produce a track in the output file for timed ID3 streams.
8236  if (st->codecpar->codec_id == AV_CODEC_ID_TIMED_ID3) {
8237  // Leave priv_data set to NULL for these AVStreams that don't
8238  // have a corresponding track.
8239  continue;
8240  }
8241  st->priv_data = st;
8242  mov->nb_tracks++;
8243  }
8244 
8245  mov->nb_streams = mov->nb_tracks;
8246 
8247  if (mov->mode & (MODE_MP4|MODE_MOV|MODE_IPOD) && s->nb_chapters)
8248  mov->chapter_track = mov->nb_tracks++;
8249 
8250  if (mov->flags & FF_MOV_FLAG_RTP_HINT) {
8251  for (i = 0; i < s->nb_streams; i++)
8252  if (rtp_hinting_needed(s->streams[i]))
8253  mov->nb_tracks++;
8254  }
8255 
8256  if (mov->write_btrt < 0) {
8257  mov->write_btrt = mov->mode == MODE_MP4;
8258  }
8259 
8260  if ( mov->write_tmcd == -1 && (mov->mode == MODE_MOV || mov->mode == MODE_MP4)
8261  || mov->write_tmcd == 1) {
8262  AVDictionaryEntry *global_tcr = av_dict_get(s->metadata, "timecode",
8263  NULL, 0);
8264 
8265  /* +1 tmcd track for each video stream with a timecode */
8266  for (i = 0; i < s->nb_streams; i++) {
8267  AVStream *st = s->streams[i];
8268  AVDictionaryEntry *t = global_tcr;
8269  if (st->codecpar->codec_type == AVMEDIA_TYPE_VIDEO &&
8270  (t || (t=av_dict_get(st->metadata, "timecode", NULL, 0)))) {
8271  AVTimecode tc;
8272  ret = mov_check_timecode_track(s, &tc, st, t->value);
8273  if (ret >= 0)
8274  mov->nb_meta_tmcd++;
8275  }
8276  }
8277 
8278  /* check if there is already a tmcd track to remux */
8279  if (mov->nb_meta_tmcd) {
8280  for (i = 0; i < s->nb_streams; i++) {
8281  AVStream *st = s->streams[i];
8282  if (st->codecpar->codec_tag == MKTAG('t','m','c','d')) {
8283  av_log(s, AV_LOG_WARNING, "You requested a copy of the original timecode track "
8284  "so timecode metadata are now ignored\n");
8285  mov->nb_meta_tmcd = 0;
8286  }
8287  }
8288  }
8289 
8290  mov->nb_tracks += mov->nb_meta_tmcd;
8291  }
8292 
8293  // Reserve an extra stream for chapters for the case where chapters
8294  // are written in the trailer
8295  mov->tracks = av_calloc(mov->nb_tracks + 1, sizeof(*mov->tracks));
8296  if (!mov->tracks)
8297  return AVERROR(ENOMEM);
8298 
8299  for (i = 0; i < mov->nb_tracks; i++) {
8300  MOVTrack *track = &mov->tracks[i];
8301 
8302  track->stsd_count = 1;
8303  track->extradata = av_calloc(track->stsd_count, sizeof(*track->extradata));
8304  track->extradata_size = av_calloc(track->stsd_count, sizeof(*track->extradata_size));
8305  if (!track->extradata || !track->extradata_size)
8306  return AVERROR(ENOMEM);
8307  }
8308 
8309  if (mov->encryption_scheme_str != NULL && strcmp(mov->encryption_scheme_str, "none") != 0) {
8310  if (strcmp(mov->encryption_scheme_str, "cenc-aes-ctr") == 0) {
8312 
8313  if (mov->encryption_key_len != AES_CTR_KEY_SIZE) {
8314  av_log(s, AV_LOG_ERROR, "Invalid encryption key len %d expected %d\n",
8316  return AVERROR(EINVAL);
8317  }
8318 
8319  if (mov->encryption_kid_len != CENC_KID_SIZE) {
8320  av_log(s, AV_LOG_ERROR, "Invalid encryption kid len %d expected %d\n",
8322  return AVERROR(EINVAL);
8323  }
8324  } else {
8325  av_log(s, AV_LOG_ERROR, "unsupported encryption scheme %s\n",
8326  mov->encryption_scheme_str);
8327  return AVERROR(EINVAL);
8328  }
8329  }
8330 
8331 #if CONFIG_IAMFENC
8332  ret = mov_init_iamf_track(s);
8333  if (ret < 0)
8334  return ret;
8335 #endif
8336 
8337  for (int j = 0, i = 0; j < s->nb_streams; j++) {
8338  AVStream *st = s->streams[j];
8339 
8340  if (st != st->priv_data) {
8341  if (has_iamf)
8342  i += has_iamf--;
8343  continue;
8344  }
8345  st->priv_data = &mov->tracks[i++];
8346  }
8347 
8348  for (i = 0; i < s->nb_streams; i++) {
8349  AVStream *st= s->streams[i];
8350  MOVTrack *track = st->priv_data;
8351  AVDictionaryEntry *lang = av_dict_get(st->metadata, "language", NULL,0);
8352 
8353  if (!track)
8354  continue;
8355 
8356  if (!track->st) {
8357  track->st = st;
8358  track->par = st->codecpar;
8359  }
8360  track->language = ff_mov_iso639_to_lang(lang?lang->value:"und", mov->mode!=MODE_MOV);
8361  if (track->language < 0)
8362  track->language = 32767; // Unspecified Macintosh language code
8363  track->mode = mov->mode;
8364  if (!track->tag)
8365  track->tag = mov_find_codec_tag(s, track);
8366  if (!track->tag) {
8367  av_log(s, AV_LOG_ERROR, "Could not find tag for codec %s in stream #%d, "
8368  "codec not currently supported in container\n",
8370  return AVERROR(EINVAL);
8371  }
8372  /* If hinting of this track is enabled by a later hint track,
8373  * this is updated. */
8374  track->hint_track = -1;
8375  track->start_dts = AV_NOPTS_VALUE;
8376  track->start_cts = AV_NOPTS_VALUE;
8377  track->end_pts = AV_NOPTS_VALUE;
8378  track->dts_shift = AV_NOPTS_VALUE;
8379  if (st->codecpar->codec_type == AVMEDIA_TYPE_VIDEO) {
8380  if (track->tag == MKTAG('m','x','3','p') || track->tag == MKTAG('m','x','3','n') ||
8381  track->tag == MKTAG('m','x','4','p') || track->tag == MKTAG('m','x','4','n') ||
8382  track->tag == MKTAG('m','x','5','p') || track->tag == MKTAG('m','x','5','n')) {
8383  if (st->codecpar->width != 720 || (st->codecpar->height != 608 && st->codecpar->height != 512)) {
8384  av_log(s, AV_LOG_ERROR, "D-10/IMX must use 720x608 or 720x512 video resolution\n");
8385  return AVERROR(EINVAL);
8386  }
8387  track->height = track->tag >> 24 == 'n' ? 486 : 576;
8388  }
8389  if (mov->video_track_timescale) {
8390  track->timescale = mov->video_track_timescale;
8391  if (mov->mode == MODE_ISM && mov->video_track_timescale != 10000000)
8392  av_log(s, AV_LOG_WARNING, "Warning: some tools, like mp4split, assume a timescale of 10000000 for ISMV.\n");
8393  } else {
8394  track->timescale = st->time_base.den;
8395  while(track->timescale < 10000)
8396  track->timescale *= 2;
8397  }
8398  if (st->codecpar->width > 65535 || st->codecpar->height > 65535) {
8399  av_log(s, AV_LOG_ERROR, "Resolution %dx%d too large for mov/mp4\n", st->codecpar->width, st->codecpar->height);
8400  return AVERROR(EINVAL);
8401  }
8402  if (track->mode == MODE_MOV && track->timescale > 100000)
8404  "WARNING codec timebase is very high. If duration is too long,\n"
8405  "file may not be playable by quicktime. Specify a shorter timebase\n"
8406  "or choose different container.\n");
8407  if (track->mode == MODE_MOV &&
8408  track->par->codec_id == AV_CODEC_ID_RAWVIDEO &&
8409  track->tag == MKTAG('r','a','w',' ')) {
8410  enum AVPixelFormat pix_fmt = track->par->format;
8411  if (pix_fmt == AV_PIX_FMT_NONE && track->par->bits_per_coded_sample == 1)
8413  track->is_unaligned_qt_rgb =
8416  pix_fmt == AV_PIX_FMT_PAL8 ||
8420  }
8421  if (track->par->codec_id == AV_CODEC_ID_VP9 && track->mode != MODE_MP4) {
8422  av_log(s, AV_LOG_ERROR, "%s only supported in MP4.\n", avcodec_get_name(track->par->codec_id));
8423  return AVERROR(EINVAL);
8424  } else if (track->par->codec_id == AV_CODEC_ID_AV1 &&
8425  track->mode != MODE_MP4 && track->mode != MODE_AVIF) {
8426  av_log(s, AV_LOG_ERROR, "%s only supported in MP4 and AVIF.\n", avcodec_get_name(track->par->codec_id));
8427  return AVERROR(EINVAL);
8428  } else if (track->par->codec_id == AV_CODEC_ID_VP8) {
8429  /* altref frames handling is not defined in the spec as of version v1.0,
8430  * so just forbid muxing VP8 streams altogether until a new version does */
8431  av_log(s, AV_LOG_ERROR, "VP8 muxing is currently not supported.\n");
8432  return AVERROR_PATCHWELCOME;
8433  } else if (track->par->codec_id == AV_CODEC_ID_APV) {
8434  ret = ff_isom_init_apvc(&track->apv, s);
8435  if (ret < 0)
8436  return ret;
8437  }
8438  if (is_cover_image(st)) {
8439  track->cover_image = av_packet_alloc();
8440  if (!track->cover_image)
8441  return AVERROR(ENOMEM);
8442  }
8443  } else if (st->codecpar->codec_type == AVMEDIA_TYPE_AUDIO) {
8444  track->timescale = st->codecpar->sample_rate;
8446  av_log(s, AV_LOG_WARNING, "track %d: codec frame size is not set\n", i);
8447  track->audio_vbr = 1;
8448  }else if (st->codecpar->codec_id == AV_CODEC_ID_ADPCM_MS ||
8451  if (!st->codecpar->block_align) {
8452  av_log(s, AV_LOG_ERROR, "track %d: codec block align is not set for adpcm\n", i);
8453  return AVERROR(EINVAL);
8454  }
8455  track->sample_size = st->codecpar->block_align;
8456  }else if (st->codecpar->frame_size > 1){ /* assume compressed audio */
8457  track->audio_vbr = 1;
8458  }else{
8459  track->sample_size = (av_get_bits_per_sample(st->codecpar->codec_id) >> 3) *
8461  }
8462  if (st->codecpar->codec_id == AV_CODEC_ID_ILBC ||
8464  track->audio_vbr = 1;
8465  }
8466  if (track->mode != MODE_MOV &&
8467  track->par->codec_id == AV_CODEC_ID_MP3 && track->timescale < 16000) {
8468  if (s->strict_std_compliance >= FF_COMPLIANCE_NORMAL) {
8469  av_log(s, AV_LOG_ERROR, "track %d: muxing mp3 at %dhz is not standard, to mux anyway set strict to -1\n",
8470  i, track->par->sample_rate);
8471  return AVERROR(EINVAL);
8472  } else {
8473  av_log(s, AV_LOG_WARNING, "track %d: muxing mp3 at %dhz is not standard in MP4\n",
8474  i, track->par->sample_rate);
8475  }
8476  }
8477  if (track->par->codec_id == AV_CODEC_ID_FLAC ||
8478  track->par->codec_id == AV_CODEC_ID_TRUEHD ||
8479  track->par->codec_id == AV_CODEC_ID_OPUS) {
8480  if (track->mode != MODE_MP4) {
8481  av_log(s, AV_LOG_ERROR, "%s only supported in MP4.\n", avcodec_get_name(track->par->codec_id));
8482  return AVERROR(EINVAL);
8483  }
8484  if (track->par->codec_id == AV_CODEC_ID_TRUEHD &&
8485  s->strict_std_compliance > FF_COMPLIANCE_EXPERIMENTAL) {
8487  "%s in MP4 support is experimental, add "
8488  "'-strict %d' if you want to use it.\n",
8490  return AVERROR_EXPERIMENTAL;
8491  }
8492  }
8493  } else if (st->codecpar->codec_type == AVMEDIA_TYPE_SUBTITLE) {
8494  track->timescale = st->time_base.den;
8495 
8496  if (track->par->codec_id == AV_CODEC_ID_TTML) {
8497  /* 14496-30 requires us to use a single sample per fragment
8498  for TTML, for which we define a per-track flag.
8499 
8500  We set the flag in case we are receiving TTML paragraphs
8501  from the input, in other words in case we are not doing
8502  stream copy. */
8505 
8506  if (track->mode != MODE_ISM &&
8507  track->par->codec_tag == MOV_ISMV_TTML_TAG &&
8508  s->strict_std_compliance > FF_COMPLIANCE_UNOFFICIAL) {
8510  "ISMV style TTML support with the 'dfxp' tag in "
8511  "non-ISMV formats is not officially supported. Add "
8512  "'-strict unofficial' if you want to use it.\n");
8513  return AVERROR_EXPERIMENTAL;
8514  }
8515  }
8516  } else if (st->codecpar->codec_type == AVMEDIA_TYPE_DATA) {
8517  track->timescale = st->time_base.den;
8518  } else {
8519  track->timescale = mov->movie_timescale;
8520  }
8521  if (!track->height)
8522  track->height = st->codecpar->height;
8523  /* The Protected Interoperable File Format (PIFF) standard, used by ISMV recommends but
8524  doesn't mandate a track timescale of 10,000,000. The muxer allows a custom timescale
8525  for video tracks, so if user-set, it isn't overwritten */
8526  if (mov->mode == MODE_ISM &&
8529  track->timescale = 10000000;
8530  }
8531 
8532  avpriv_set_pts_info(st, 64, 1, track->timescale);
8533 
8535  ret = ff_mov_cenc_init(&track->cenc, mov->encryption_key,
8536  (track->par->codec_id == AV_CODEC_ID_H264 || track->par->codec_id == AV_CODEC_ID_HEVC ||
8537  track->par->codec_id == AV_CODEC_ID_VVC || track->par->codec_id == AV_CODEC_ID_AV1),
8538  track->par->codec_id, s->flags & AVFMT_FLAG_BITEXACT);
8539  if (ret)
8540  return ret;
8541  }
8542  }
8543 
8544  for (i = 0; i < s->nb_stream_groups; i++) {
8545  AVStreamGroup *stg = s->stream_groups[i];
8546 
8547  switch (stg->type) {
8549  AVStreamGroupLCEVC *lcevc = stg->params.lcevc;
8550  AVStream *st = stg->streams[lcevc->lcevc_index];
8551  MOVTrack *track = st->priv_data;
8552 
8553  for (int j = 0; j < mov->nb_tracks; j++) {
8554  MOVTrack *trk = &mov->tracks[j];
8555 
8556  if (trk->st == stg->streams[!lcevc->lcevc_index]) {
8557  track->src_track = av_malloc(sizeof(*track->src_track));
8558  if (!track->src_track)
8559  return AVERROR(ENOMEM);
8560  *track->src_track = j;
8561  track->nb_src_track = 1;
8562  break;
8563  }
8564  }
8565 
8566  track->par->width = lcevc->width;
8567  track->par->height = track->height = lcevc->height;
8568  break;
8569  }
8571  const AVStreamGroupTREF *tref = stg->params.tref;
8572  MOVTrack *track;
8573 
8574  if (tref->metadata_index >= stg->nb_streams)
8575  return AVERROR(EINVAL);
8576 
8577  track = stg->streams[tref->metadata_index]->priv_data;
8578  for (int j = 0; j < stg->nb_streams; j++) {
8579  const AVStream *st2 = stg->streams[j];
8580  int index = -1;
8581 
8582  for (int k = 0; k < mov->nb_tracks; k++) {
8583  if (mov->tracks[k].st != st2)
8584  continue;
8585  index = k;
8586  break;
8587  }
8588  if (index < 0)
8589  return AVERROR(EINVAL);
8590 
8591  int *tmp = av_realloc(track->src_track,
8592  (track->nb_src_track + 1) * sizeof(*track->src_track));
8593  if (!tmp)
8594  return AVERROR(ENOMEM);
8595  track->src_track = tmp;
8596  track->src_track[track->nb_src_track++] = index;
8597  }
8598  break;
8599  }
8600  default:
8601  break;
8602  }
8603  }
8604 
8605  /* fill src_track for tmcd tracks not covered by stream groups or
8606  * created by this muxer, retaining the old behavior of src_track
8607  * being arbitrarily 0. */
8608  for (i = 0; i < s->nb_streams; i++) {
8609  AVStream *st = s->streams[i];
8610  MOVTrack *track = st->priv_data;
8611  if (st->codecpar->codec_tag != MKTAG('t','m','c','d') ||
8612  track->nb_src_track)
8613  continue;
8614 
8615  track->src_track = av_malloc(sizeof(*track->src_track));
8616  if (!track->src_track)
8617  return AVERROR(ENOMEM);
8618  *track->src_track = 0;
8619  track->nb_src_track = 1;
8620  }
8621 
8622  enable_tracks(s);
8623  return 0;
8624 }
8625 
8627 {
8628  AVIOContext *pb = s->pb;
8629  MOVMuxContext *mov = s->priv_data;
8630  int ret, hint_track = 0, tmcd_track = 0, nb_tracks = mov->nb_streams;
8631 
8632  if (mov->mode & (MODE_MP4|MODE_MOV|MODE_IPOD) && s->nb_chapters)
8633  nb_tracks++;
8634 
8635  if (mov->flags & FF_MOV_FLAG_RTP_HINT) {
8636  hint_track = nb_tracks;
8637  for (int i = 0; i < mov->nb_streams; i++) {
8638  if (rtp_hinting_needed(mov->tracks[i].st))
8639  nb_tracks++;
8640  }
8641  }
8642 
8643  if (mov->nb_meta_tmcd)
8644  tmcd_track = nb_tracks;
8645 
8646  for (int i = 0; i < mov->nb_streams; i++) {
8647  MOVTrack *track = &mov->tracks[i];
8648  AVStream *st = track->st;
8649 
8650  /* copy extradata if it exists */
8651  if (st->codecpar->extradata_size) {
8654  else if (!TAG_IS_AVCI(track->tag) && st->codecpar->codec_id != AV_CODEC_ID_DNXHD) {
8655  track->extradata_size[track->last_stsd_index] = st->codecpar->extradata_size;
8656  track->extradata[track->last_stsd_index] =
8658  if (!track->extradata[track->last_stsd_index]) {
8659  return AVERROR(ENOMEM);
8660  }
8661  memcpy(track->extradata[track->last_stsd_index],
8662  st->codecpar->extradata, track->extradata_size[track->last_stsd_index]);
8663  memset(track->extradata[track->last_stsd_index] + track->extradata_size[track->last_stsd_index],
8665  }
8666  }
8667 
8668  if (st->codecpar->codec_type != AVMEDIA_TYPE_AUDIO ||
8671  continue;
8672 
8673  for (int j = 0; j < mov->nb_streams; j++) {
8674  AVStream *stj= mov->tracks[j].st;
8675  MOVTrack *trackj= &mov->tracks[j];
8676  if (j == i)
8677  continue;
8678 
8679  if (stj->codecpar->codec_type == AVMEDIA_TYPE_AUDIO &&
8680  (trackj->par->ch_layout.nb_channels != 1 ||
8683  )
8684  track->mono_as_fc = -1;
8685 
8686  if (stj->codecpar->codec_type == AVMEDIA_TYPE_AUDIO &&
8689  trackj->par->ch_layout.nb_channels == 1 && track->mono_as_fc >= 0
8690  )
8691  track->mono_as_fc++;
8692 
8693  if (stj->codecpar->codec_type != AVMEDIA_TYPE_AUDIO ||
8696  trackj->language != track->language ||
8697  trackj->tag != track->tag
8698  )
8699  continue;
8700  track->multichannel_as_mono++;
8701  }
8702  }
8703 
8704  if (!(mov->flags & FF_MOV_FLAG_DELAY_MOOV) ||
8706  if ((ret = mov_write_identification(pb, s)) < 0)
8707  return ret;
8708  }
8709 
8710  if (mov->reserved_moov_size){
8711  mov->reserved_header_pos = avio_tell(pb);
8712  if (mov->reserved_moov_size > 0)
8713  avio_skip(pb, mov->reserved_moov_size);
8714  }
8715 
8716  if (mov->flags & FF_MOV_FLAG_FRAGMENT) {
8717  /* If no fragmentation options have been set, set a default. */
8718  if (!(mov->flags & (FF_MOV_FLAG_FRAG_KEYFRAME |
8723  if (mov->flags & FF_MOV_FLAG_HYBRID_FRAGMENTED) {
8724  avio_wb32(pb, 8); // placeholder for extended size field (64 bit)
8725  ffio_wfourcc(pb, mov->mode == MODE_MOV ? "wide" : "free");
8726  mov->mdat_pos = avio_tell(pb);
8727  // The free/wide header that later will be converted into an
8728  // mdat, covering the initial moov and all the fragments.
8729  avio_wb32(pb, 0);
8730  ffio_wfourcc(pb, mov->mode == MODE_MOV ? "wide" : "free");
8731  // Write an ftyp atom, hidden in a free/wide. This is neither
8732  // exposed while the file is written, as fragmented, nor when the
8733  // file is finalized into non-fragmented form. However, this allows
8734  // accessing a pristine, sequential ftyp+moov init segment, even
8735  // after the file is finalized. It also allows dumping the whole
8736  // contents of the mdat box, to get the fragmented form of the
8737  // file.
8738  if ((ret = mov_write_identification(pb, s)) < 0)
8739  return ret;
8740  update_size(pb, mov->mdat_pos);
8741  }
8742  } else if (mov->mode != MODE_AVIF) {
8743  if (mov->flags & FF_MOV_FLAG_FASTSTART)
8744  mov->reserved_header_pos = avio_tell(pb);
8745  mov_write_mdat_tag(pb, mov);
8746  }
8747 
8749  if (mov->time)
8750  mov->time += 0x7C25B080; // 1970 based -> 1904 based
8751 
8752  if (mov->chapter_track)
8753  if ((ret = mov_create_chapter_track(s, mov->chapter_track)) < 0)
8754  return ret;
8755 
8756  if (mov->flags & FF_MOV_FLAG_RTP_HINT) {
8757  for (int i = 0; i < mov->nb_streams; i++) {
8758  if (rtp_hinting_needed(mov->tracks[i].st)) {
8759  if ((ret = ff_mov_init_hinting(s, hint_track, i)) < 0)
8760  return ret;
8761  hint_track++;
8762  }
8763  }
8764  }
8765 
8766  if (mov->nb_meta_tmcd) {
8767  const AVDictionaryEntry *t, *global_tcr = av_dict_get(s->metadata,
8768  "timecode", NULL, 0);
8769  /* Initialize the tmcd tracks */
8770  for (int i = 0; i < mov->nb_streams; i++) {
8771  AVStream *st = mov->tracks[i].st;
8772  t = global_tcr;
8773 
8774  if (st->codecpar->codec_type == AVMEDIA_TYPE_VIDEO) {
8775  AVTimecode tc;
8776  if (!t)
8777  t = av_dict_get(st->metadata, "timecode", NULL, 0);
8778  if (!t)
8779  continue;
8780  if (mov_check_timecode_track(s, &tc, st, t->value) < 0)
8781  continue;
8782  if ((ret = mov_create_timecode_track(s, tmcd_track, i, tc)) < 0)
8783  return ret;
8784  tmcd_track++;
8785  }
8786  }
8787  }
8788 
8789  avio_flush(pb);
8790 
8791  if (mov->flags & FF_MOV_FLAG_ISML)
8792  mov_write_isml_manifest(pb, mov, s);
8793 
8794  if (mov->flags & FF_MOV_FLAG_EMPTY_MOOV &&
8795  !(mov->flags & FF_MOV_FLAG_DELAY_MOOV)) {
8796  if ((ret = mov_write_moov_tag(pb, mov, s)) < 0)
8797  return ret;
8798  mov->moov_written = 1;
8799  if (mov->flags & FF_MOV_FLAG_GLOBAL_SIDX)
8800  mov->reserved_header_pos = avio_tell(pb);
8801  }
8802 
8803  return 0;
8804 }
8805 
8807 {
8808  int ret;
8809  AVIOContext *moov_buf;
8810  MOVMuxContext *mov = s->priv_data;
8811 
8812  if ((ret = ffio_open_null_buf(&moov_buf)) < 0)
8813  return ret;
8814  if ((ret = mov_write_moov_tag(moov_buf, mov, s)) < 0)
8815  return ret;
8816  return ffio_close_null_buf(moov_buf);
8817 }
8818 
8820 {
8821  int ret;
8822  AVIOContext *buf;
8823  MOVMuxContext *mov = s->priv_data;
8824 
8825  if ((ret = ffio_open_null_buf(&buf)) < 0)
8826  return ret;
8827  mov_write_sidx_tags(buf, mov, -1, 0);
8828  return ffio_close_null_buf(buf);
8829 }
8830 
8831 /*
8832  * This function gets the moov size if moved to the top of the file: the chunk
8833  * offset table can switch between stco (32-bit entries) to co64 (64-bit
8834  * entries) when the moov is moved to the beginning, so the size of the moov
8835  * would change. It also updates the chunk offset tables.
8836  */
8838 {
8839  int i, moov_size, moov_size2;
8840  MOVMuxContext *mov = s->priv_data;
8841 
8842  moov_size = get_moov_size(s);
8843  if (moov_size < 0)
8844  return moov_size;
8845 
8846  for (i = 0; i < mov->nb_tracks; i++)
8847  mov->tracks[i].data_offset += moov_size;
8848 
8849  moov_size2 = get_moov_size(s);
8850  if (moov_size2 < 0)
8851  return moov_size2;
8852 
8853  /* if the size changed, we just switched from stco to co64 and need to
8854  * update the offsets */
8855  if (moov_size2 != moov_size)
8856  for (i = 0; i < mov->nb_tracks; i++)
8857  mov->tracks[i].data_offset += moov_size2 - moov_size;
8858 
8859  return moov_size2;
8860 }
8861 
8863 {
8864  int i, sidx_size;
8865  MOVMuxContext *mov = s->priv_data;
8866 
8867  sidx_size = get_sidx_size(s);
8868  if (sidx_size < 0)
8869  return sidx_size;
8870 
8871  for (i = 0; i < mov->nb_tracks; i++)
8872  mov->tracks[i].data_offset += sidx_size;
8873 
8874  return sidx_size;
8875 }
8876 
8878 {
8879  int moov_size;
8880  MOVMuxContext *mov = s->priv_data;
8881 
8882  if (mov->flags & FF_MOV_FLAG_FRAGMENT)
8883  moov_size = compute_sidx_size(s);
8884  else
8885  moov_size = compute_moov_size(s);
8886  if (moov_size < 0)
8887  return moov_size;
8888 
8889  return ff_format_shift_data(s, mov->reserved_header_pos, moov_size);
8890 }
8891 
8893 {
8894  MOVMuxContext *mov = s->priv_data;
8895  AVIOContext *pb = s->pb;
8896 
8897  /* Write size of mdat tag */
8898  if (mov->mdat_size + 8 <= UINT32_MAX) {
8899  avio_seek(pb, mov->mdat_pos, SEEK_SET);
8900  avio_wb32(pb, mov->mdat_size + 8);
8902  ffio_wfourcc(pb, "mdat"); // overwrite the original free/wide into a mdat
8903  } else {
8904  /* overwrite 'wide' placeholder atom */
8905  avio_seek(pb, mov->mdat_pos - 8, SEEK_SET);
8906  /* special value: real atom size will be 64 bit value after
8907  * tag field */
8908  avio_wb32(pb, 1);
8909  ffio_wfourcc(pb, "mdat");
8910  avio_wb64(pb, mov->mdat_size + 16);
8911  }
8912 }
8913 
8915 {
8916  MOVMuxContext *mov = s->priv_data;
8917  AVIOContext *pb = s->pb;
8918  int res = 0;
8919  int i;
8920  int64_t moov_pos;
8921 
8922  /*
8923  * Before actually writing the trailer, make sure that there are no
8924  * dangling subtitles, that need a terminating sample.
8925  */
8926  for (i = 0; i < mov->nb_tracks; i++) {
8927  MOVTrack *trk = &mov->tracks[i];
8928  if (trk->par->codec_id == AV_CODEC_ID_MOV_TEXT &&
8931  trk->last_sample_is_subtitle_end = 1;
8932  }
8933  }
8934 
8935  // Check if we have any tracks that require squashing.
8936  // In that case, we'll have to write the packet here.
8937  if ((res = mov_write_squashed_packets(s)) < 0)
8938  return res;
8939 
8940  // If there were no chapters when the header was written, but there
8941  // are chapters now, write them in the trailer. This only works
8942  // when we are not doing fragments.
8943  if (!mov->chapter_track && !(mov->flags & FF_MOV_FLAG_FRAGMENT)) {
8944  if (mov->mode & (MODE_MP4|MODE_MOV|MODE_IPOD) && s->nb_chapters) {
8945  mov->chapter_track = mov->nb_tracks++;
8946  if ((res = mov_create_chapter_track(s, mov->chapter_track)) < 0)
8947  return res;
8948  }
8949  }
8950 
8951  if (!(mov->flags & FF_MOV_FLAG_FRAGMENT) ||
8953  if (mov->flags & FF_MOV_FLAG_HYBRID_FRAGMENTED) {
8955  mov->mdat_size = avio_tell(pb) - mov->mdat_pos - 8;
8956  for (i = 0; i < mov->nb_tracks; i++) {
8957  MOVTrack *track = &mov->tracks[i];
8958  track->data_offset = 0;
8959  av_free(track->cluster);
8960  track->cluster = track->cluster_written;
8961  track->entry = track->entry_written;
8962  track->cluster_written = NULL;
8963  track->entry_written = 0;
8964  track->chunkCount = 0; // Force build_chunks to rebuild the list of chunks
8965  }
8966  // Clear the empty_moov flag, as we do want the moov to include
8967  // all the samples at this point.
8968  mov->flags &= ~FF_MOV_FLAG_EMPTY_MOOV;
8969  }
8970 
8971  moov_pos = avio_tell(pb);
8972 
8973  if (!(mov->flags & FF_MOV_FLAG_HYBRID_FRAGMENTED))
8975 
8976  avio_seek(pb, mov->reserved_moov_size > 0 ? mov->reserved_header_pos : moov_pos, SEEK_SET);
8977 
8978  if (mov->flags & FF_MOV_FLAG_FASTSTART) {
8979  av_log(s, AV_LOG_INFO, "Starting second pass: moving the moov atom to the beginning of the file\n");
8980  res = shift_data(s);
8981  if (res < 0)
8982  return res;
8983  avio_seek(pb, mov->reserved_header_pos, SEEK_SET);
8984  if ((res = mov_write_moov_tag(pb, mov, s)) < 0)
8985  return res;
8986  } else if (mov->reserved_moov_size > 0) {
8987  int64_t size;
8988  if ((res = mov_write_moov_tag(pb, mov, s)) < 0)
8989  return res;
8990  size = mov->reserved_moov_size - (avio_tell(pb) - mov->reserved_header_pos);
8991  if (size < 8){
8992  av_log(s, AV_LOG_ERROR, "reserved_moov_size is too small, needed %"PRId64" additional\n", 8-size);
8993  return AVERROR(EINVAL);
8994  }
8995  avio_wb32(pb, size);
8996  ffio_wfourcc(pb, "free");
8997  ffio_fill(pb, 0, size - 8);
8998  avio_seek(pb, moov_pos, SEEK_SET);
8999  } else {
9000  if ((res = mov_write_moov_tag(pb, mov, s)) < 0)
9001  return res;
9002  }
9003 
9004  if (mov->flags & FF_MOV_FLAG_HYBRID_FRAGMENTED) {
9005  // With hybrid fragmentation, only write the mdat size (hiding
9006  // the original moov and all the fragments within the mdat)
9007  // after we've successfully written the complete moov, to avoid
9008  // risk for an unreadable file if writing the final moov fails.
9010  }
9011 
9012  res = 0;
9013  } else {
9015  for (i = 0; i < mov->nb_tracks; i++)
9016  mov->tracks[i].data_offset = 0;
9017  if (mov->flags & FF_MOV_FLAG_GLOBAL_SIDX) {
9018  int64_t end;
9019  av_log(s, AV_LOG_INFO, "Starting second pass: inserting sidx atoms\n");
9020  res = shift_data(s);
9021  if (res < 0)
9022  return res;
9023  end = avio_tell(pb);
9024  avio_seek(pb, mov->reserved_header_pos, SEEK_SET);
9025  mov_write_sidx_tags(pb, mov, -1, 0);
9026  avio_seek(pb, end, SEEK_SET);
9027  }
9028  if (!(mov->flags & FF_MOV_FLAG_SKIP_TRAILER)) {
9030  res = mov_write_mfra_tag(pb, mov);
9031  if (res < 0)
9032  return res;
9033  }
9034  }
9035 
9036  return res;
9037 }
9038 
9040  const AVPacket *pkt)
9041 {
9042  int ret = 1;
9043 
9044  if (st->codecpar->codec_id == AV_CODEC_ID_AAC) {
9045  if (pkt->size > 2 && (AV_RB16(pkt->data) & 0xfff0) == 0xfff0)
9046  ret = ff_stream_add_bitstream_filter(st, "aac_adtstoasc", NULL);
9047  } else if (st->codecpar->codec_id == AV_CODEC_ID_VP9) {
9048  ret = ff_stream_add_bitstream_filter(st, "vp9_superframe", NULL);
9049  }
9050 
9051  return ret;
9052 }
9053 
9054 #if CONFIG_AVIF_MUXER
9055 static int avif_write_trailer(AVFormatContext *s)
9056 {
9057  AVIOContext *pb = s->pb;
9058  MOVMuxContext *mov = s->priv_data;
9059  int64_t pos_backup, extent_offsets[2];
9060  uint8_t *buf;
9061  int buf_size, moov_size;
9062 
9063  if (mov->moov_written) return 0;
9064 
9065  mov->is_animated_avif = s->streams[0]->nb_frames > 1;
9066  if (mov->is_animated_avif && mov->nb_streams > 1) {
9067  // For animated avif with alpha channel, we need to write a tref tag
9068  // with type "auxl".
9069  MovTag *tag = mov_add_tref_tag(mov, &mov->tracks[1], MKTAG('a', 'u', 'x', 'l'));
9070  if (!tag)
9071  return AVERROR(ENOMEM);
9072 
9073  int ret = mov_add_tref_id(mov, tag, 1);
9074  if (ret < 0)
9075  return ret;
9076  }
9078  mov_write_meta_tag(pb, mov, s);
9079 
9080  moov_size = get_moov_size(s);
9081  for (int i = 0; i < mov->nb_tracks; i++)
9082  mov->tracks[i].data_offset = avio_tell(pb) + moov_size + 8;
9083 
9084  if (mov->is_animated_avif) {
9085  int ret;
9086  if ((ret = mov_write_moov_tag(pb, mov, s)) < 0)
9087  return ret;
9088  }
9089 
9090  buf_size = avio_get_dyn_buf(mov->mdat_buf, &buf);
9091  avio_wb32(pb, buf_size + 8);
9092  ffio_wfourcc(pb, "mdat");
9093 
9094  // The offset for the YUV planes is the starting position of mdat.
9095  extent_offsets[0] = avio_tell(pb);
9096  // The offset for alpha plane is YUV offset + YUV size.
9097  extent_offsets[1] = extent_offsets[0] + mov->avif_extent_length[0];
9098 
9099  avio_write(pb, buf, buf_size);
9100 
9101  // write extent offsets.
9102  pos_backup = avio_tell(pb);
9103  for (int i = 0; i < mov->nb_streams; i++) {
9104  if (extent_offsets[i] != (uint32_t)extent_offsets[i]) {
9105  av_log(s, AV_LOG_ERROR, "extent offset does not fit in 32 bits\n");
9106  return AVERROR_INVALIDDATA;
9107  }
9108  avio_seek(pb, mov->avif_extent_pos[i], SEEK_SET);
9109  avio_wb32(pb, extent_offsets[i]); /* rewrite offset */
9110  }
9111  avio_seek(pb, pos_backup, SEEK_SET);
9112 
9113  return 0;
9114 }
9115 #endif
9116 
9117 #if CONFIG_TGP_MUXER || CONFIG_TG2_MUXER
9118 static const AVCodecTag codec_3gp_tags[] = {
9119  { AV_CODEC_ID_H263, MKTAG('s','2','6','3') },
9120  { AV_CODEC_ID_H264, MKTAG('a','v','c','1') },
9121  { AV_CODEC_ID_MPEG4, MKTAG('m','p','4','v') },
9122  { AV_CODEC_ID_AAC, MKTAG('m','p','4','a') },
9123  { AV_CODEC_ID_AMR_NB, MKTAG('s','a','m','r') },
9124  { AV_CODEC_ID_AMR_WB, MKTAG('s','a','w','b') },
9125  { AV_CODEC_ID_MOV_TEXT, MKTAG('t','x','3','g') },
9126  { AV_CODEC_ID_NONE, 0 },
9127 };
9128 static const AVCodecTag *const codec_3gp_tags_list[] = { codec_3gp_tags, NULL };
9129 #endif
9130 
9131 static const AVCodecTag codec_mp4_tags[] = {
9132  { AV_CODEC_ID_MPEG4, MKTAG('m', 'p', '4', 'v') },
9133  { AV_CODEC_ID_H264, MKTAG('a', 'v', 'c', '1') },
9134  { AV_CODEC_ID_H264, MKTAG('a', 'v', 'c', '3') },
9135  { AV_CODEC_ID_HEVC, MKTAG('h', 'e', 'v', '1') },
9136  { AV_CODEC_ID_HEVC, MKTAG('h', 'v', 'c', '1') },
9137  { AV_CODEC_ID_HEVC, MKTAG('d', 'v', 'h', '1') },
9138  { AV_CODEC_ID_VVC, MKTAG('v', 'v', 'c', '1') },
9139  { AV_CODEC_ID_VVC, MKTAG('v', 'v', 'i', '1') },
9140  { AV_CODEC_ID_EVC, MKTAG('e', 'v', 'c', '1') },
9141  { AV_CODEC_ID_LCEVC, MKTAG('l', 'v', 'c', '1') },
9142  { AV_CODEC_ID_APV, MKTAG('a', 'p', 'v', '1') },
9143  { AV_CODEC_ID_MPEG2VIDEO, MKTAG('m', 'p', '4', 'v') },
9144  { AV_CODEC_ID_MPEG1VIDEO, MKTAG('m', 'p', '4', 'v') },
9145  { AV_CODEC_ID_MJPEG, MKTAG('m', 'p', '4', 'v') },
9146  { AV_CODEC_ID_PNG, MKTAG('m', 'p', '4', 'v') },
9147  { AV_CODEC_ID_JPEG2000, MKTAG('m', 'p', '4', 'v') },
9148  { AV_CODEC_ID_VC1, MKTAG('v', 'c', '-', '1') },
9149  { AV_CODEC_ID_DIRAC, MKTAG('d', 'r', 'a', 'c') },
9150  { AV_CODEC_ID_TSCC2, MKTAG('m', 'p', '4', 'v') },
9151  { AV_CODEC_ID_VP9, MKTAG('v', 'p', '0', '9') },
9152  { AV_CODEC_ID_AV1, MKTAG('a', 'v', '0', '1') },
9153  { AV_CODEC_ID_AAC, MKTAG('m', 'p', '4', 'a') },
9154  { AV_CODEC_ID_ALAC, MKTAG('a', 'l', 'a', 'c') },
9155  { AV_CODEC_ID_MP4ALS, MKTAG('m', 'p', '4', 'a') },
9156  { AV_CODEC_ID_MP3, MKTAG('m', 'p', '4', 'a') },
9157  { AV_CODEC_ID_MP2, MKTAG('m', 'p', '4', 'a') },
9158  { AV_CODEC_ID_AC3, MKTAG('a', 'c', '-', '3') },
9159  { AV_CODEC_ID_EAC3, MKTAG('e', 'c', '-', '3') },
9160  { AV_CODEC_ID_DTS, MKTAG('m', 'p', '4', 'a') },
9161  { AV_CODEC_ID_TRUEHD, MKTAG('m', 'l', 'p', 'a') },
9162  { AV_CODEC_ID_FLAC, MKTAG('f', 'L', 'a', 'C') },
9163  { AV_CODEC_ID_OPUS, MKTAG('O', 'p', 'u', 's') },
9164  { AV_CODEC_ID_VORBIS, MKTAG('m', 'p', '4', 'a') },
9165  { AV_CODEC_ID_QCELP, MKTAG('m', 'p', '4', 'a') },
9166  { AV_CODEC_ID_EVRC, MKTAG('m', 'p', '4', 'a') },
9167  { AV_CODEC_ID_DVD_SUBTITLE, MKTAG('m', 'p', '4', 's') },
9168  { AV_CODEC_ID_MOV_TEXT, MKTAG('t', 'x', '3', 'g') },
9169  { AV_CODEC_ID_BIN_DATA, MKTAG('g', 'p', 'm', 'd') },
9170  { AV_CODEC_ID_MPEGH_3D_AUDIO, MKTAG('m', 'h', 'm', '1') },
9173  { AV_CODEC_ID_FFV1, MKTAG('F', 'F', 'V', '1') },
9174 
9175  /* ISO/IEC 23003-5 integer formats */
9182  /* ISO/IEC 23003-5 floating-point formats */
9187 
9188  { AV_CODEC_ID_AVS3, MKTAG('a', 'v', 's', '3') },
9189 
9190  { AV_CODEC_ID_NONE, 0 },
9191 };
9192 #if CONFIG_MP4_MUXER || CONFIG_PSP_MUXER
9193 static const AVCodecTag *const mp4_codec_tags_list[] = { codec_mp4_tags, NULL };
9194 #endif
9195 
9196 static const AVCodecTag codec_ism_tags[] = {
9197  { AV_CODEC_ID_WMAPRO , MKTAG('w', 'm', 'a', ' ') },
9199  { AV_CODEC_ID_NONE , 0 },
9200 };
9201 
9202 static const AVCodecTag codec_ipod_tags[] = {
9203  { AV_CODEC_ID_H264, MKTAG('a','v','c','1') },
9204  { AV_CODEC_ID_MPEG4, MKTAG('m','p','4','v') },
9205  { AV_CODEC_ID_AAC, MKTAG('m','p','4','a') },
9206  { AV_CODEC_ID_ALAC, MKTAG('a','l','a','c') },
9207  { AV_CODEC_ID_AC3, MKTAG('a','c','-','3') },
9208  { AV_CODEC_ID_MOV_TEXT, MKTAG('t','x','3','g') },
9209  { AV_CODEC_ID_MOV_TEXT, MKTAG('t','e','x','t') },
9210  { AV_CODEC_ID_NONE, 0 },
9211 };
9212 
9213 static const AVCodecTag codec_f4v_tags[] = {
9214  { AV_CODEC_ID_MP3, MKTAG('.','m','p','3') },
9215  { AV_CODEC_ID_AAC, MKTAG('m','p','4','a') },
9216  { AV_CODEC_ID_H264, MKTAG('a','v','c','1') },
9217  { AV_CODEC_ID_VP6A, MKTAG('V','P','6','A') },
9218  { AV_CODEC_ID_VP6F, MKTAG('V','P','6','F') },
9219  { AV_CODEC_ID_NONE, 0 },
9220 };
9221 
9222 #if CONFIG_AVIF_MUXER
9223 
9224 static const AVOption avif_options[] = {
9225  { "movie_timescale", "set movie timescale", offsetof(MOVMuxContext, movie_timescale), AV_OPT_TYPE_INT, {.i64 = MOV_TIMESCALE}, 1, INT_MAX, AV_OPT_FLAG_ENCODING_PARAM},
9226  { "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 },
9227  { NULL },
9228 };
9229 static const AVCodecTag codec_avif_tags[] = {
9230  { AV_CODEC_ID_AV1, MKTAG('a','v','0','1') },
9231  { AV_CODEC_ID_NONE, 0 },
9232 };
9233 static const AVCodecTag *const codec_avif_tags_list[] = { codec_avif_tags, NULL };
9234 
9235 static const AVClass mov_avif_muxer_class = {
9236  .class_name = "avif muxer",
9237  .item_name = av_default_item_name,
9238  .option = avif_options,
9239  .version = LIBAVUTIL_VERSION_INT,
9240 };
9241 #endif
9242 
9243 #if CONFIG_MOV_MUXER
9244 const FFOutputFormat ff_mov_muxer = {
9245  .p.name = "mov",
9246  .p.long_name = NULL_IF_CONFIG_SMALL("QuickTime / MOV"),
9247  .p.extensions = "mov",
9248  .priv_data_size = sizeof(MOVMuxContext),
9249  .p.audio_codec = AV_CODEC_ID_AAC,
9250  .p.video_codec = CONFIG_LIBX264_ENCODER ?
9252  .init = mov_init,
9253  .write_header = mov_write_header,
9254  .write_packet = mov_write_packet,
9255  .write_trailer = mov_write_trailer,
9256  .deinit = mov_free,
9258  .p.codec_tag = (const AVCodecTag* const []){
9260  },
9261  .check_bitstream = mov_check_bitstream,
9262  .p.priv_class = &mov_isobmff_muxer_class,
9263  .flags_internal = FF_OFMT_FLAG_ALLOW_FLUSH,
9264 };
9265 #endif
9266 #if CONFIG_TGP_MUXER
9267 const FFOutputFormat ff_tgp_muxer = {
9268  .p.name = "3gp",
9269  .p.long_name = NULL_IF_CONFIG_SMALL("3GP (3GPP file format)"),
9270  .p.extensions = "3gp",
9271  .priv_data_size = sizeof(MOVMuxContext),
9272  .p.audio_codec = AV_CODEC_ID_AMR_NB,
9273  .p.video_codec = AV_CODEC_ID_H263,
9274  .init = mov_init,
9275  .write_header = mov_write_header,
9276  .write_packet = mov_write_packet,
9277  .write_trailer = mov_write_trailer,
9278  .deinit = mov_free,
9280  .p.codec_tag = codec_3gp_tags_list,
9281  .check_bitstream = mov_check_bitstream,
9282  .p.priv_class = &mov_isobmff_muxer_class,
9283  .flags_internal = FF_OFMT_FLAG_ALLOW_FLUSH,
9284 };
9285 #endif
9286 #if CONFIG_MP4_MUXER
9287 const FFOutputFormat ff_mp4_muxer = {
9288  .p.name = "mp4",
9289  .p.long_name = NULL_IF_CONFIG_SMALL("MP4 (MPEG-4 Part 14)"),
9290  .p.mime_type = "video/mp4",
9291  .p.extensions = "mp4",
9292  .priv_data_size = sizeof(MOVMuxContext),
9293  .p.audio_codec = AV_CODEC_ID_AAC,
9294  .p.video_codec = CONFIG_LIBX264_ENCODER ?
9296  .init = mov_init,
9297  .write_header = mov_write_header,
9298  .write_packet = mov_write_packet,
9299  .write_trailer = mov_write_trailer,
9300  .deinit = mov_free,
9302  .p.codec_tag = mp4_codec_tags_list,
9303  .check_bitstream = mov_check_bitstream,
9304  .p.priv_class = &mov_isobmff_muxer_class,
9305  .flags_internal = FF_OFMT_FLAG_ALLOW_FLUSH,
9306 };
9307 #endif
9308 #if CONFIG_PSP_MUXER
9309 const FFOutputFormat ff_psp_muxer = {
9310  .p.name = "psp",
9311  .p.long_name = NULL_IF_CONFIG_SMALL("PSP MP4 (MPEG-4 Part 14)"),
9312  .p.extensions = "mp4,psp",
9313  .priv_data_size = sizeof(MOVMuxContext),
9314  .p.audio_codec = AV_CODEC_ID_AAC,
9315  .p.video_codec = CONFIG_LIBX264_ENCODER ?
9317  .init = mov_init,
9318  .write_header = mov_write_header,
9319  .write_packet = mov_write_packet,
9320  .write_trailer = mov_write_trailer,
9321  .deinit = mov_free,
9323  .p.codec_tag = mp4_codec_tags_list,
9324  .check_bitstream = mov_check_bitstream,
9325  .p.priv_class = &mov_isobmff_muxer_class,
9326  .flags_internal = FF_OFMT_FLAG_ALLOW_FLUSH,
9327 };
9328 #endif
9329 #if CONFIG_TG2_MUXER
9330 const FFOutputFormat ff_tg2_muxer = {
9331  .p.name = "3g2",
9332  .p.long_name = NULL_IF_CONFIG_SMALL("3GP2 (3GPP2 file format)"),
9333  .p.extensions = "3g2",
9334  .priv_data_size = sizeof(MOVMuxContext),
9335  .p.audio_codec = AV_CODEC_ID_AMR_NB,
9336  .p.video_codec = AV_CODEC_ID_H263,
9337  .init = mov_init,
9338  .write_header = mov_write_header,
9339  .write_packet = mov_write_packet,
9340  .write_trailer = mov_write_trailer,
9341  .deinit = mov_free,
9343  .p.codec_tag = codec_3gp_tags_list,
9344  .check_bitstream = mov_check_bitstream,
9345  .p.priv_class = &mov_isobmff_muxer_class,
9346  .flags_internal = FF_OFMT_FLAG_ALLOW_FLUSH,
9347 };
9348 #endif
9349 #if CONFIG_IPOD_MUXER
9350 const FFOutputFormat ff_ipod_muxer = {
9351  .p.name = "ipod",
9352  .p.long_name = NULL_IF_CONFIG_SMALL("iPod H.264 MP4 (MPEG-4 Part 14)"),
9353  .p.mime_type = "video/mp4",
9354  .p.extensions = "m4v,m4a,m4b",
9355  .priv_data_size = sizeof(MOVMuxContext),
9356  .p.audio_codec = AV_CODEC_ID_AAC,
9357  .p.video_codec = AV_CODEC_ID_H264,
9358  .init = mov_init,
9359  .write_header = mov_write_header,
9360  .write_packet = mov_write_packet,
9361  .write_trailer = mov_write_trailer,
9362  .deinit = mov_free,
9364  .p.codec_tag = (const AVCodecTag* const []){ codec_ipod_tags, 0 },
9365  .check_bitstream = mov_check_bitstream,
9366  .p.priv_class = &mov_isobmff_muxer_class,
9367  .flags_internal = FF_OFMT_FLAG_ALLOW_FLUSH,
9368 };
9369 #endif
9370 #if CONFIG_ISMV_MUXER
9371 const FFOutputFormat ff_ismv_muxer = {
9372  .p.name = "ismv",
9373  .p.long_name = NULL_IF_CONFIG_SMALL("ISMV/ISMA (Smooth Streaming)"),
9374  .p.mime_type = "video/mp4",
9375  .p.extensions = "ismv,isma",
9376  .priv_data_size = sizeof(MOVMuxContext),
9377  .p.audio_codec = AV_CODEC_ID_AAC,
9378  .p.video_codec = AV_CODEC_ID_H264,
9379  .init = mov_init,
9380  .write_header = mov_write_header,
9381  .write_packet = mov_write_packet,
9382  .write_trailer = mov_write_trailer,
9383  .deinit = mov_free,
9385  .p.codec_tag = (const AVCodecTag* const []){
9387  .check_bitstream = mov_check_bitstream,
9388  .p.priv_class = &mov_isobmff_muxer_class,
9389  .flags_internal = FF_OFMT_FLAG_ALLOW_FLUSH,
9390 };
9391 #endif
9392 #if CONFIG_F4V_MUXER
9393 const FFOutputFormat ff_f4v_muxer = {
9394  .p.name = "f4v",
9395  .p.long_name = NULL_IF_CONFIG_SMALL("F4V Adobe Flash Video"),
9396  .p.mime_type = "application/f4v",
9397  .p.extensions = "f4v",
9398  .priv_data_size = sizeof(MOVMuxContext),
9399  .p.audio_codec = AV_CODEC_ID_AAC,
9400  .p.video_codec = AV_CODEC_ID_H264,
9401  .init = mov_init,
9402  .write_header = mov_write_header,
9403  .write_packet = mov_write_packet,
9404  .write_trailer = mov_write_trailer,
9405  .deinit = mov_free,
9406  .p.flags = AVFMT_GLOBALHEADER,
9407  .p.codec_tag = (const AVCodecTag* const []){ codec_f4v_tags, 0 },
9408  .check_bitstream = mov_check_bitstream,
9409  .p.priv_class = &mov_isobmff_muxer_class,
9410  .flags_internal = FF_OFMT_FLAG_ALLOW_FLUSH,
9411 };
9412 #endif
9413 #if CONFIG_AVIF_MUXER
9414 const FFOutputFormat ff_avif_muxer = {
9415  .p.name = "avif",
9416  .p.long_name = NULL_IF_CONFIG_SMALL("AVIF"),
9417  .p.mime_type = "image/avif",
9418  .p.extensions = "avif",
9419  .priv_data_size = sizeof(MOVMuxContext),
9420  .p.video_codec = AV_CODEC_ID_AV1,
9421  .init = mov_init,
9422  .write_header = mov_write_header,
9423  .write_packet = mov_write_packet,
9424  .write_trailer = avif_write_trailer,
9425  .deinit = mov_free,
9426  .p.flags = AVFMT_GLOBALHEADER,
9427  .p.codec_tag = codec_avif_tags_list,
9428  .p.priv_class = &mov_avif_muxer_class,
9429  .flags_internal = FF_OFMT_FLAG_ALLOW_FLUSH,
9430 };
9431 #endif
AV_CODEC_ID_PCM_S16LE
@ AV_CODEC_ID_PCM_S16LE
Definition: codec_id.h:338
flags
const SwsFlags flags[]
Definition: swscale.c:72
codec_ism_tags
static const AVCodecTag codec_ism_tags[]
Definition: movenc.c:9196
ff_isom_write_vpcc
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
MOVTrack::height
int height
active picture (w/o VBI) height for D-10/IMX
Definition: movenc.h:133
MOVMuxContext::mdat_pos
int64_t mdat_pos
Definition: movenc.h:218
MOVTrack::elst_end_pts
int64_t elst_end_pts
Definition: movenc.h:139
mov_write_traf_tag
static int mov_write_traf_tag(AVIOContext *pb, MOVMuxContext *mov, MOVTrack *track, int64_t moof_offset, int moof_size)
Definition: movenc.c:5804
AV_CODEC_ID_EIA_608
@ AV_CODEC_ID_EIA_608
Definition: codec_id.h:582
AV_PKT_DATA_DISPLAYMATRIX
@ AV_PKT_DATA_DISPLAYMATRIX
This side data contains a 3x3 transformation matrix describing an affine transformation that needs to...
Definition: packet.h:105
AV_ROUND_UP
@ AV_ROUND_UP
Round toward +infinity.
Definition: mathematics.h:134
av_packet_unref
void av_packet_unref(AVPacket *pkt)
Wipe the packet.
Definition: packet.c:433
eac3_info
Definition: movenc.c:383
MOVMuxContext::nb_tracks
int nb_tracks
Definition: movenc.h:215
MOVMuxContext::fc
AVFormatContext * fc
Definition: movenc.h:246
MOVTrack::end_pts
int64_t end_pts
Definition: movenc.h:138
MOVMuxContext::iods_audio_profile
int iods_audio_profile
Definition: movenc.h:227
MODE_PSP
#define MODE_PSP
Definition: movenc.h:40
mov_write_udta_sdp
static int mov_write_udta_sdp(AVIOContext *pb, MOVTrack *track)
Definition: movenc.c:4257
AVMEDIA_TYPE_SUBTITLE
@ AVMEDIA_TYPE_SUBTITLE
Definition: avutil.h:203
AV_CODEC_ID_VP6F
@ AV_CODEC_ID_VP6F
Definition: codec_id.h:144
FF_MOV_FLAG_GLOBAL_SIDX
#define FF_MOV_FLAG_GLOBAL_SIDX
Definition: movenc.h:291
skip_bits_long
static void skip_bits_long(GetBitContext *s, int n)
Skips the specified number of bits.
Definition: get_bits.h:280
AV_LOG_WARNING
#define AV_LOG_WARNING
Something somehow does not look correct.
Definition: log.h:216
MOV_TFHD_DEFAULT_FLAGS
#define MOV_TFHD_DEFAULT_FLAGS
Definition: isom.h:412
MODE_IPOD
#define MODE_IPOD
Definition: movenc.h:43
MODE_MP4
#define MODE_MP4
Definition: movenc.h:37
AV_CODEC_ID_PCM_F32BE
@ AV_CODEC_ID_PCM_F32BE
Definition: codec_id.h:358
AVCodecParameters::extradata
uint8_t * extradata
Extra binary data needed for initializing the decoder, codec-dependent.
Definition: codec_par.h:71
AV_CODEC_ID_ADPCM_MS
@ AV_CODEC_ID_ADPCM_MS
Definition: codec_id.h:383
AVPixelFormat
AVPixelFormat
Pixel format.
Definition: pixfmt.h:71
mov_get_dnxhd_codec_tag
static int mov_get_dnxhd_codec_tag(AVFormatContext *s, MOVTrack *track)
Definition: movenc.c:2071
calc_elst_duration
static int64_t calc_elst_duration(MOVMuxContext *mov, MOVTrack *track)
Definition: movenc.c:3885
name
it s the only field you need to keep assuming you have a context There is some magic you don t need to care about around this just let it vf default minimum maximum flags name is the option name
Definition: writing_filters.txt:88
LIBAVFORMAT_IDENT
#define LIBAVFORMAT_IDENT
Definition: version.h:45
PacketList::head
PacketListEntry * head
Definition: packet_internal.h:34
AV_CODEC_ID_ADPCM_IMA_QT
@ AV_CODEC_ID_ADPCM_IMA_QT
Definition: codec_id.h:377
AVERROR_EXPERIMENTAL
#define AVERROR_EXPERIMENTAL
Requested feature is flagged experimental. Set strict_std_compliance if you really want to use it.
Definition: error.h:74
movenc_ttml.h
entry
#define entry
Definition: aom_film_grain_template.c:66
eac3_info::num_dep_sub
uint8_t num_dep_sub
Definition: movenc.c:409
MOVTrack::chunkCount
long chunkCount
Definition: movenc.h:110
MOVTrack::cluster_written
MOVIentry * cluster_written
Definition: movenc.h:130
level
uint8_t level
Definition: svq3.c:208
AV_CODEC_ID_AC3
@ AV_CODEC_ID_AC3
Definition: codec_id.h:463
AV_STEREO3D_VIEW_LEFT
@ AV_STEREO3D_VIEW_LEFT
Frame contains only the left view.
Definition: stereo3d.h:158
AVIO_DATA_MARKER_BOUNDARY_POINT
@ 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
AC3HeaderInfo::frame_type
uint8_t frame_type
Definition: ac3_parser_internal.h:45
mov_write_moov_tag
static int mov_write_moov_tag(AVIOContext *pb, MOVMuxContext *mov, AVFormatContext *s)
Definition: movenc.c:5280
ff_ntp_time
uint64_t ff_ntp_time(void)
Get the current time since NTP epoch in microseconds.
Definition: utils.c:257
mov_write_eyes_tag
static int mov_write_eyes_tag(AVFormatContext *s, AVIOContext *pb, const AVStereo3D *stereo3d)
Definition: movenc.c:2416
MOV_TRUN_SAMPLE_FLAGS
#define MOV_TRUN_SAMPLE_FLAGS
Definition: isom.h:420
mov_write_vmhd_tag
static int mov_write_vmhd_tag(AVIOContext *pb)
Definition: movenc.c:3531
MOVFragmentInfo::tfrf_offset
int64_t tfrf_offset
Definition: movenc.h:83
AV_PKT_DATA_AMBIENT_VIEWING_ENVIRONMENT
@ AV_PKT_DATA_AMBIENT_VIEWING_ENVIRONMENT
Ambient viewing environment metadata, as defined by H.274.
Definition: packet.h:327
AVOutputFormat::name
const char * name
Definition: avformat.h:507
r
const char * r
Definition: vf_curves.c:127
AVERROR
Filter the word “frame” indicates either a video frame or a group of audio as stored in an AVFrame structure Format for each input and each output the list of supported formats For video that means pixel format For audio that means channel sample they are references to shared objects When the negotiation mechanism computes the intersection of the formats supported at each end of a all references to both lists are replaced with a reference to the intersection And when a single format is eventually chosen for a link amongst the remaining all references to the list are updated That means that if a filter requires that its input and output have the same format amongst a supported all it has to do is use a reference to the same list of formats query_formats can leave some formats unset and return AVERROR(EAGAIN) to cause the negotiation mechanism toagain later. That can be used by filters with complex requirements to use the format negotiated on one link to set the formats supported on another. Frame references ownership and permissions
opt.h
mov_write_track_kinds
static int mov_write_track_kinds(AVIOContext *pb, AVStream *st)
Definition: movenc.c:4319
MOVTrack::squash_fragment_samples_to_one
unsigned int squash_fragment_samples_to_one
Definition: movenc.h:186
MOVMuxContext::mode
int mode
Definition: movenc.h:212
AV_PROFILE_H264_INTRA
#define AV_PROFILE_H264_INTRA
Definition: defs.h:108
FF_MOV_FLAG_FRAG_KEYFRAME
#define FF_MOV_FLAG_FRAG_KEYFRAME
Definition: movenc.h:280
MOVTrack::vc1_info
struct MOVTrack::@492 vc1_info
mov_write_wfex_tag
static int mov_write_wfex_tag(AVFormatContext *s, AVIOContext *pb, MOVTrack *track)
Definition: movenc.c:846
MOV_TKHD_FLAG_ENABLED
#define MOV_TKHD_FLAG_ENABLED
Definition: isom.h:433
mov_write_mfra_tag
static int mov_write_mfra_tag(AVIOContext *pb, MOVMuxContext *mov)
Definition: movenc.c:6078
AVCodecParameters::codec_type
enum AVMediaType codec_type
General type of the encoded data.
Definition: codec_par.h:53
AVSphericalMapping::projection
enum AVSphericalProjection projection
Projection type.
Definition: spherical.h:104
mov_write_udta_tag
static int mov_write_udta_tag(AVIOContext *pb, MOVMuxContext *mov, AVFormatContext *s)
Definition: movenc.c:5007
AV_STREAM_GROUP_PARAMS_LCEVC
@ AV_STREAM_GROUP_PARAMS_LCEVC
Definition: avformat.h:1109
hevc.h
libm.h
mov_add_tfra_entries
static int mov_add_tfra_entries(AVIOContext *pb, MOVMuxContext *mov, int tracks, int size)
Definition: movenc.c:5739
AVSphericalMapping::bound_bottom
uint32_t bound_bottom
Distance from the bottom edge.
Definition: spherical.h:188
mov_write_3gp_udta_tag
static int mov_write_3gp_udta_tag(AVIOContext *pb, AVFormatContext *s, const char *tag, const char *str)
Definition: movenc.c:4959
ffio_wfourcc
static av_always_inline void ffio_wfourcc(AVIOContext *pb, const uint8_t *s)
Definition: avio_internal.h:124
AV_CODEC_ID_V308
@ AV_CODEC_ID_V308
Definition: codec_id.h:260
AVUUID
uint8_t AVUUID[AV_UUID_LEN]
Definition: uuid.h:60
put_bytes_output
static int put_bytes_output(const PutBitContext *s)
Definition: put_bits.h:99
FF_MOV_FLAG_HYBRID_FRAGMENTED
#define FF_MOV_FLAG_HYBRID_FRAGMENTED
Definition: movenc.h:301
cb
static double cb(void *priv, double x, double y)
Definition: vf_geq.c:247
mpeg4_bit_rate_values::buffer_size
uint32_t buffer_size
Size of the decoding buffer for the elementary stream in bytes.
Definition: movenc.c:715
ff_mp4_obj_type
const AVCodecTag ff_mp4_obj_type[]
Definition: isom.c:34
MOVMuxContext::encryption_scheme
MOVEncryptionScheme encryption_scheme
Definition: movenc.h:257
FF_MOV_FLAG_WRITE_COLR
#define FF_MOV_FLAG_WRITE_COLR
Definition: movenc.h:292
AV_PKT_DATA_FRAME_CROPPING
@ 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
mov_write_single_packet
static int mov_write_single_packet(AVFormatContext *s, AVPacket *pkt)
Definition: movenc.c:7312
AVCodecParameters
This struct describes the properties of an encoded stream.
Definition: codec_par.h:49
mov_write_trun_tag
static int mov_write_trun_tag(AVIOContext *pb, MOVMuxContext *mov, MOVTrack *track, int moof_size, int first, int end)
Definition: movenc.c:5614
MOVTrack::mode
int mode
Definition: movenc.h:94
mov_write_mvhd_tag
static int mov_write_mvhd_tag(AVIOContext *pb, MOVMuxContext *mov)
Definition: movenc.c:4481
AVAmbientViewingEnvironment
Ambient viewing environment metadata as defined by H.274.
Definition: ambient_viewing_environment.h:36
ffformatcontext
static av_always_inline FFFormatContext * ffformatcontext(AVFormatContext *s)
Definition: internal.h:123
get_sample_flags
static uint32_t get_sample_flags(MOVTrack *track, MOVIentry *entry)
Definition: movenc.c:5542
AVCodecParameters::color_space
enum AVColorSpace color_space
Definition: codec_par.h:192
strtod
double strtod(const char *, char **)
AV_PKT_DATA_NEW_EXTRADATA
@ 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
mov_write_track_udta_tag
static int mov_write_track_udta_tag(AVIOContext *pb, MOVMuxContext *mov, AVStream *st)
Definition: movenc.c:4339
MOVIentry
Definition: movenc.h:48
AVStream::priv_data
void * priv_data
Definition: avformat.h:771
av_pix_fmt_desc_get
const AVPixFmtDescriptor * av_pix_fmt_desc_get(enum AVPixelFormat pix_fmt)
Definition: pixdesc.c:3456
AVFMT_VARIABLE_FPS
#define AVFMT_VARIABLE_FPS
Format allows variable fps.
Definition: avformat.h:481
FF_MOV_FLAG_SKIP_TRAILER
#define FF_MOV_FLAG_SKIP_TRAILER
Definition: movenc.h:295
mov_write_gama_tag
static int mov_write_gama_tag(AVFormatContext *s, AVIOContext *pb, MOVTrack *track, double gamma)
Definition: movenc.c:2575
AV_DISPOSITION_ATTACHED_PIC
#define AV_DISPOSITION_ATTACHED_PIC
The stream is stored in the file as an attached picture/"cover art" (e.g.
Definition: avformat.h:672
AV_FIELD_PROGRESSIVE
@ AV_FIELD_PROGRESSIVE
Definition: defs.h:213
AV_PKT_DATA_MASTERING_DISPLAY_METADATA
@ AV_PKT_DATA_MASTERING_DISPLAY_METADATA
Mastering display metadata (based on SMPTE-2086:2014).
Definition: packet.h:219
MOVFragmentInfo::size
int size
Definition: movenc.h:84
AV_PKT_FLAG_DISCARD
#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
IS_MODE
#define IS_MODE(muxer, config)
MOVFragmentInfo
Definition: movenc.h:79
MOVTrack::last_iamf_idx
int last_iamf_idx
Definition: movenc.h:192
AV_TIME_BASE_Q
#define AV_TIME_BASE_Q
Internal time base represented as fractional value.
Definition: avutil.h:263
AV_CODEC_ID_DIRAC
@ AV_CODEC_ID_DIRAC
Definition: codec_id.h:168
AVCodecTag::id
enum AVCodecID id
Definition: internal.h:43
eac3_info::num_blocks
uint8_t num_blocks
Definition: movenc.c:386
int64_t
long long int64_t
Definition: coverity.c:34
av_grow_packet
int av_grow_packet(AVPacket *pkt, int grow_by)
Increase packet size, correctly zeroing padding.
Definition: packet.c:121
mov_write_ms_tag
static int mov_write_ms_tag(AVFormatContext *s, AVIOContext *pb, MOVTrack *track)
Definition: movenc.c:834
init_put_bits
static void init_put_bits(PutBitContext *s, uint8_t *buffer, int buffer_size)
Initialize the PutBitContext s.
Definition: put_bits.h:62
MOVTrack::iamf_buf
AVIOContext * iamf_buf
Definition: movenc.h:193
mov_auto_flush_fragment
static int mov_auto_flush_fragment(AVFormatContext *s, int force)
Definition: movenc.c:6819
AV_CODEC_ID_RAWVIDEO
@ AV_CODEC_ID_RAWVIDEO
Definition: codec_id.h:65
mov_pcm_le_gt16
static int mov_pcm_le_gt16(enum AVCodecID codec_id)
Definition: movenc.c:818
vvc.h
ff_vvc_annexb2mp4
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
ff_get_formatted_ntp_time
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
AV_DISPOSITION_DEFAULT
#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:619
MOVMuxContext::min_fragment_duration
int min_fragment_duration
Definition: movenc.h:232
AV_CODEC_ID_MPEG4
@ AV_CODEC_ID_MPEG4
Definition: codec_id.h:64
MOVMuxContext::avif_extent_length
int avif_extent_length[2]
Definition: movenc.h:272
AVContentLightMetadata::MaxCLL
unsigned MaxCLL
Max content light level (cd/m^2).
Definition: mastering_display_metadata.h:111
ff_isom_write_vvcc
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
MODE_MOV
#define MODE_MOV
Definition: movenc.h:38
MOVMuxContext::encryption_scheme_str
char * encryption_scheme_str
Definition: movenc.h:256
FF_MOV_FLAG_FRAG_CUSTOM
#define FF_MOV_FLAG_FRAG_CUSTOM
Definition: movenc.h:282
av_encryption_init_info_free
void av_encryption_init_info_free(AVEncryptionInitInfo *info)
Frees the given encryption init info object.
Definition: encryption_info.c:216
mov_write_enda_tag
static int mov_write_enda_tag(AVIOContext *pb)
Definition: movenc.c:678
mov_write_apvc_tag
static int mov_write_apvc_tag(AVFormatContext *s, AVIOContext *pb, MOVTrack *track)
Definition: movenc.c:1719
put_bits
static void put_bits(Jpeg2000EncoderContext *s, int val, int n)
put n times val bit
Definition: j2kenc.c:154
pixdesc.h
AVFormatContext::streams
AVStream ** streams
A list of all streams in the file.
Definition: avformat.h:1351
av_channel_layout_ambisonic_order
int av_channel_layout_ambisonic_order(const AVChannelLayout *channel_layout)
Return the order if the layout is n-th order standard-order ambisonic.
Definition: channel_layout.c:486
MOVCtts
Definition: isom.h:68
AVPacketSideData
This structure stores auxiliary information for decoding, presenting, or otherwise processing the cod...
Definition: packet.h:416
AVCOL_RANGE_JPEG
@ AVCOL_RANGE_JPEG
Full range content.
Definition: pixfmt.h:777
AVFormatContext::strict_std_compliance
int strict_std_compliance
Allow non-standard and experimental extension.
Definition: avformat.h:1638
mov_write_iods_tag
static int mov_write_iods_tag(AVIOContext *pb, MOVMuxContext *mov)
Definition: movenc.c:4428
av_channel_layout_channel_from_index
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.
Definition: channel_layout.c:674
AVProducerReferenceTime::wallclock
int64_t wallclock
A UTC timestamp, in microseconds, since Unix epoch (e.g, av_gettime()).
Definition: defs.h:335
mov_write_tkhd_tag
static int mov_write_tkhd_tag(AVIOContext *pb, MOVMuxContext *mov, MOVTrack *track, AVStream *st)
Definition: movenc.c:3971
internal.h
AVPacket::data
uint8_t * data
Definition: packet.h:595
AV_PKT_DATA_ENCRYPTION_INIT_INFO
@ AV_PKT_DATA_ENCRYPTION_INIT_INFO
This side data is encryption initialization data.
Definition: packet.h:246
AVComponentDescriptor::depth
int depth
Number of bits in the component.
Definition: pixdesc.h:57
mov_init
static int mov_init(AVFormatContext *s)
Definition: movenc.c:8053
AVAmbientViewingEnvironment::ambient_light_x
AVRational ambient_light_x
Normalized x chromaticity coordinate of the environmental ambient light in the nominal viewing enviro...
Definition: ambient_viewing_environment.h:47
MOV_FRAG_INFO_ALLOC_INCREMENT
#define MOV_FRAG_INFO_ALLOC_INCREMENT
Definition: movenc.h:31
AV_PKT_DATA_FALLBACK_TRACK
@ AV_PKT_DATA_FALLBACK_TRACK
This side data contains an integer value representing the stream index of a "fallback" track.
Definition: packet.h:137
enable_tracks
static void enable_tracks(AVFormatContext *s)
Definition: movenc.c:7807
mov_write_ccst_tag
static int mov_write_ccst_tag(AVIOContext *pb)
Definition: movenc.c:2753
AVOption
AVOption.
Definition: opt.h:429
MOVFragmentInfo::duration
int64_t duration
Definition: movenc.h:82
b
#define b
Definition: input.c:43
AVCOL_TRC_UNSPECIFIED
@ AVCOL_TRC_UNSPECIFIED
Definition: pixfmt.h:669
mov_write_mdta_hdlr_tag
static int mov_write_mdta_hdlr_tag(AVIOContext *pb, MOVMuxContext *mov, AVFormatContext *s)
Definition: movenc.c:4824
mov_write_raw_metadata_tag
static int mov_write_raw_metadata_tag(AVFormatContext *s, AVIOContext *pb, const char *name, const char *key)
Definition: movenc.c:4921
AVStream::avg_frame_rate
AVRational avg_frame_rate
Average framerate.
Definition: avformat.h:835
MOVTrack::flags
uint32_t flags
Definition: movenc.h:116
data
const char data[16]
Definition: mxf.c:149
AV_PIX_FMT_MONOWHITE
@ 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
AVTimecode::flags
uint32_t flags
flags such as drop frame, +24 hours support, ...
Definition: timecode.h:43
AV_CODEC_ID_ALAC
@ AV_CODEC_ID_ALAC
Definition: codec_id.h:476
MOVTrack::tag
int tag
stsd fourcc
Definition: movenc.h:123
MOVTrack::pal_done
int pal_done
Definition: movenc.h:182
AV_PIX_FMT_YUV420P10
#define AV_PIX_FMT_YUV420P10
Definition: pixfmt.h:539
AV_DICT_IGNORE_SUFFIX
#define AV_DICT_IGNORE_SUFFIX
Return first entry in a dictionary whose first part corresponds to the search key,...
Definition: dict.h:75
AV_CODEC_ID_AMR_NB
@ AV_CODEC_ID_AMR_NB
Definition: codec_id.h:441
AVStreamGroupTREF::metadata_index
unsigned int metadata_index
Index of the metadata stream in the AVStreamGroup.
Definition: avformat.h:1101
MOVIentry::dts
int64_t dts
Definition: movenc.h:50
ff_isom_write_lvcc
int ff_isom_write_lvcc(AVIOContext *pb, const uint8_t *data, int len)
Definition: lcevc.c:251
MOV_TIMESCALE
#define MOV_TIMESCALE
Definition: movenc.h:33
co64_required
static int co64_required(const MOVTrack *track)
Definition: movenc.c:177
mov_write_aux_tag
static int mov_write_aux_tag(AVIOContext *pb, const char *aux_type)
Definition: movenc.c:2772
MOVMuxContext::encryption_key
uint8_t * encryption_key
Definition: movenc.h:258
ff_toupper4
unsigned int ff_toupper4(unsigned int x)
Definition: to_upper4.h:29
ff_parse_creation_time_metadata
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
AV_LOG_VERBOSE
#define AV_LOG_VERBOSE
Detailed information.
Definition: log.h:226
ff_codec_wav_tags
const AVCodecTag ff_codec_wav_tags[]
Definition: riff.c:530
MOVIentry::flags
uint32_t flags
Definition: movenc.h:61
mov_write_itunes_hdlr_tag
static int mov_write_itunes_hdlr_tag(AVIOContext *pb, MOVMuxContext *mov, AVFormatContext *s)
Definition: movenc.c:4546
mov_write_header
static int mov_write_header(AVFormatContext *s)
Definition: movenc.c:8626
nb_streams
static unsigned int nb_streams
Definition: ffprobe.c:352
mov_write_sv3d_tag
static int mov_write_sv3d_tag(AVFormatContext *s, AVIOContext *pb, AVSphericalMapping *spherical_mapping)
Definition: movenc.c:2315
put_bits32
static av_unused void put_bits32(PutBitContext *s, uint32_t value)
Write exactly 32 bits into a bitstream.
Definition: put_bits.h:301
MP4TrackKindMapping::scheme_uri
const char * scheme_uri
Definition: isom.h:493
AV_PIX_FMT_BGR24
@ AV_PIX_FMT_BGR24
packed RGB 8:8:8, 24bpp, BGRBGR...
Definition: pixfmt.h:76
AV_PIX_FMT_BGRA
@ AV_PIX_FMT_BGRA
packed BGRA 8:8:8:8, 32bpp, BGRABGRA...
Definition: pixfmt.h:102
mov_write_loci_tag
static int mov_write_loci_tag(AVFormatContext *s, AVIOContext *pb)
Definition: movenc.c:4652
AVPacket::duration
int64_t duration
Duration of this packet in AVStream->time_base units, 0 if unknown.
Definition: packet.h:613
get_sidx_size
static int get_sidx_size(AVFormatContext *s)
Definition: movenc.c:8819
AVStreamGroup::tref
struct AVStreamGroupTREF * tref
Definition: avformat.h:1153
AVCodecParameters::codec_tag
uint32_t codec_tag
Additional information about the codec (corresponds to the AVI FOURCC).
Definition: codec_par.h:61
AV_SPHERICAL_EQUIRECTANGULAR_TILE
@ AV_SPHERICAL_EQUIRECTANGULAR_TILE
Video represents a portion of a sphere mapped on a flat surface using equirectangular projection.
Definition: spherical.h:68
AVStereo3D::baseline
uint32_t baseline
The distance between the centres of the lenses of the camera system, in micrometers.
Definition: stereo3d.h:228
max
#define max(a, b)
Definition: cuda_runtime.h:33
FF_MOV_FLAG_WRITE_GAMA
#define FF_MOV_FLAG_WRITE_GAMA
Definition: movenc.h:293
mathematics.h
FF_COMPLIANCE_EXPERIMENTAL
#define FF_COMPLIANCE_EXPERIMENTAL
Allow nonstandardized experimental things.
Definition: defs.h:62
mov_write_d263_tag
static int mov_write_d263_tag(AVIOContext *pb)
Definition: movenc.c:1555
MOVTrack::track_id
int track_id
Definition: movenc.h:122
AV_CODEC_ID_FLAC
@ AV_CODEC_ID_FLAC
Definition: codec_id.h:472
AV_PKT_FLAG_DISPOSABLE
#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
FFMAX
#define FFMAX(a, b)
Definition: macros.h:47
fiel_data
static const uint16_t fiel_data[]
Definition: movenc.c:2223
av_sub_q
AVRational av_sub_q(AVRational b, AVRational c)
Subtract one rational from another.
Definition: rational.c:101
ff_mov_init_hinting
int ff_mov_init_hinting(AVFormatContext *s, int index, int src_index)
Definition: movenchint.c:30
ff_isom_write_apvc
void ff_isom_write_apvc(AVIOContext *pb, const APVDecoderConfigurationRecord *apvc, void *logctx)
Definition: apv.c:80
ff_mov_get_channel_layout_tag
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:463
AVChannelLayout::nb_channels
int nb_channels
Number of channels in this layout.
Definition: channel_layout.h:329
mov_write_srat_tag
static int mov_write_srat_tag(AVIOContext *pb, MOVTrack *track)
Definition: movenc.c:1362
AV_SPHERICAL_EQUIRECTANGULAR
@ AV_SPHERICAL_EQUIRECTANGULAR
Video represents a sphere mapped on a flat surface using equirectangular projection.
Definition: spherical.h:52
intfloat.h
mov_write_rtp_tag
static int mov_write_rtp_tag(AVIOContext *pb, MOVTrack *track)
Definition: movenc.c:3048
MOVTrack::track_duration
int64_t track_duration
Definition: movenc.h:99
MOV_SAMPLE_DEPENDENCY_UNKNOWN
#define MOV_SAMPLE_DEPENDENCY_UNKNOWN
Definition: isom.h:438
is_clcp_track
static int is_clcp_track(MOVTrack *track)
Definition: movenc.c:3540
AV_CODEC_ID_R10K
@ AV_CODEC_ID_R10K
Definition: codec_id.h:197
codec_cover_image_tags
static const AVCodecTag codec_cover_image_tags[]
Definition: movenc.c:2161
av_encryption_init_info_get_side_data
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.
Definition: encryption_info.c:231
AV_STEREO3D_VIEW_RIGHT
@ AV_STEREO3D_VIEW_RIGHT
Frame contains only the right view.
Definition: stereo3d.h:163
av_strlcatf
size_t av_strlcatf(char *dst, size_t size, const char *fmt,...)
Definition: avstring.c:103
AV_CODEC_ID_TRUEHD
@ AV_CODEC_ID_TRUEHD
Definition: codec_id.h:504
AV_STEREO3D_VIEW_UNSPEC
@ AV_STEREO3D_VIEW_UNSPEC
Content is unspecified.
Definition: stereo3d.h:168
avio_get_dyn_buf
int avio_get_dyn_buf(AVIOContext *s, uint8_t **pbuffer)
Return the written size and a pointer to the buffer.
Definition: aviobuf.c:1377
tf_sess_config.config
config
Definition: tf_sess_config.py:33
AV_PKT_FLAG_KEY
#define AV_PKT_FLAG_KEY
The packet contains a keyframe.
Definition: packet.h:650
MOVTrack::dts_shift
int64_t dts_shift
Definition: movenc.h:141
init_get_bits
static int init_get_bits(GetBitContext *s, const uint8_t *buffer, int bit_size)
Initialize GetBitContext.
Definition: get_bits.h:517
ff_get_muxer_ts_offset
int ff_get_muxer_ts_offset(AVFormatContext *s, int stream_index, int64_t *offset)
Definition: mux.c:1027
av_packet_free
void av_packet_free(AVPacket **pkt)
Free the packet, if the packet is reference counted, it will be unreferenced first.
Definition: packet.c:74
MOVIentry::entries
unsigned int entries
Definition: movenc.h:56
AV_PIX_FMT_RGB555BE
@ 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
MOVMuxContext::write_prft
MOVPrftBox write_prft
Definition: movenc.h:267
MOVTrack::first_frag_written
int first_frag_written
Definition: movenc.h:171
ascii_to_wc
static int ascii_to_wc(AVIOContext *pb, const uint8_t *b)
Definition: movenc.c:4941
FFOutputFormat::p
AVOutputFormat p
The public AVOutputFormat.
Definition: mux.h:65
FF_RTP_FLAG_OPTS
#define FF_RTP_FLAG_OPTS(ctx, fieldname)
Definition: rtpenc.h:74
AV_CODEC_ID_AMR_WB
@ AV_CODEC_ID_AMR_WB
Definition: codec_id.h:442
AV_CODEC_ID_BIN_DATA
@ AV_CODEC_ID_BIN_DATA
Definition: codec_id.h:613
MOVMuxContext::mdat_size
uint64_t mdat_size
Definition: movenc.h:219
mov_write_chnl_tag
static int mov_write_chnl_tag(AVFormatContext *s, AVIOContext *pb, MOVTrack *track)
Definition: movenc.c:1294
MOVMuxContext::write_tmcd
int write_tmcd
Definition: movenc.h:266
OPUS_SEEK_PREROLL_MS
#define OPUS_SEEK_PREROLL_MS
Definition: oggparseopus.c:36
FF_MOV_FLAG_CMAF
#define FF_MOV_FLAG_CMAF
Definition: movenc.h:299
mov_write_tfdt_tag
static int mov_write_tfdt_tag(AVIOContext *pb, MOVTrack *track)
Definition: movenc.c:5792
MOVTrack::frag_info
MOVFragmentInfo * frag_info
Definition: movenc.h:164
mov_write_wave_tag
static int mov_write_wave_tag(AVFormatContext *s, AVIOContext *pb, MOVTrack *track)
Definition: movenc.c:1054
find_next_marker
static const av_always_inline uint8_t * find_next_marker(const uint8_t *src, const uint8_t *end)
Find VC-1 marker in buffer.
Definition: vc1_common.h:59
mov_find_tref_id
static int mov_find_tref_id(MOVMuxContext *mov, const MovTag *tag, uint32_t id)
Definition: movenc.c:5228
AV_CODEC_ID_MPEGH_3D_AUDIO
@ AV_CODEC_ID_MPEGH_3D_AUDIO
Definition: codec_id.h:551
MOV_PRFT_SRC_PTS
@ MOV_PRFT_SRC_PTS
Definition: movenc.h:206
MOVTrack
Definition: movenc.h:93
av_memdup
void * av_memdup(const void *p, size_t size)
Duplicate a buffer with av_malloc().
Definition: mem.c:304
AVContentLightMetadata
Content light level needed by to transmit HDR over HDMI (CTA-861.3).
Definition: mastering_display_metadata.h:107
AV_PKT_DATA_DOVI_CONF
@ AV_PKT_DATA_DOVI_CONF
DOVI configuration ref: dolby-vision-bitstreams-within-the-iso-base-media-file-format-v2....
Definition: packet.h:280
MOVFragmentInfo::offset
int64_t offset
Definition: movenc.h:80
AVStereo3D::horizontal_field_of_view
AVRational horizontal_field_of_view
Horizontal field of view, in degrees.
Definition: stereo3d.h:239
skip_bits
static void skip_bits(GetBitContext *s, int n)
Definition: get_bits.h:383
AVCodecParameters::color_primaries
enum AVColorPrimaries color_primaries
Definition: codec_par.h:190
avio_write_marker
void avio_write_marker(AVIOContext *s, int64_t time, enum AVIODataMarkerType type)
Mark the written bytestream as a specific type.
Definition: aviobuf.c:464
AV_PIX_FMT_GRAY16BE
@ AV_PIX_FMT_GRAY16BE
Y , 16bpp, big-endian.
Definition: pixfmt.h:104
AV_STEREO3D_SIDEBYSIDE
@ AV_STEREO3D_SIDEBYSIDE
Views are next to each other.
Definition: stereo3d.h:64
AVPacketSideData::size
size_t size
Definition: packet.h:418
mov_write_trex_tag
static int mov_write_trex_tag(AVIOContext *pb, MOVTrack *track)
Definition: movenc.c:4457
get_bits
static unsigned int get_bits(GetBitContext *s, int n)
Read 1-25 bits.
Definition: get_bits.h:337
FF_MOV_FLAG_FRAG_EVERY_FRAME
#define FF_MOV_FLAG_FRAG_EVERY_FRAME
Definition: movenc.h:297
mov_write_dvc1_tag
static int mov_write_dvc1_tag(AVIOContext *pb, MOVTrack *track)
Definition: movenc.c:1181
rgb
Definition: rpzaenc.c:60
MOVTrack::entry_version
int entry_version
Definition: movenc.h:95
put_descr
static void put_descr(AVIOContext *pb, int tag, unsigned int size)
Definition: movenc.c:694
eac3_info::ac3_bit_rate_code
int8_t ac3_bit_rate_code
Definition: movenc.c:391
mov_write_vexu_proj_tag
static void mov_write_vexu_proj_tag(AVFormatContext *s, AVIOContext *pb, const AVSphericalMapping *spherical_mapping)
Definition: movenc.c:2389
MOV_ENC_NONE
@ MOV_ENC_NONE
Definition: movenc.h:199
MODE_ISM
#define MODE_ISM
Definition: movenc.h:44
get_pts_range
static void get_pts_range(MOVMuxContext *mov, MOVTrack *track, int64_t *start, int64_t *end, int elst)
Definition: movenc.c:3839
mov_write_pcmc_tag
static int mov_write_pcmc_tag(AVFormatContext *s, AVIOContext *pb, MOVTrack *track)
Definition: movenc.c:1336
AV_STEREO3D_VIEW_PACKED
@ AV_STEREO3D_VIEW_PACKED
Frame contains two packed views.
Definition: stereo3d.h:153
avpriv_set_pts_info
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:900
AV_OPT_TYPE_BINARY
@ 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:286
calc_samples_pts_duration
static int64_t calc_samples_pts_duration(MOVMuxContext *mov, MOVTrack *track)
Definition: movenc.c:3864
AC3HeaderInfo::complexity_index_type_a
uint8_t complexity_index_type_a
Definition: ac3_parser_internal.h:81
FF_MOV_FLAG_DEFAULT_BASE_MOOF
#define FF_MOV_FLAG_DEFAULT_BASE_MOOF
Definition: movenc.h:287
mov_write_audio_tag
static int mov_write_audio_tag(AVFormatContext *s, AVIOContext *pb, MOVMuxContext *mov, MOVTrack *track)
Definition: movenc.c:1374
eac3_info::acmod
uint8_t acmod
Definition: movenc.c:404
MOV_TRACK_CTTS
#define MOV_TRACK_CTTS
Definition: movenc.h:113
AV_CODEC_ID_PCM_S16BE
@ AV_CODEC_ID_PCM_S16BE
Definition: codec_id.h:339
defined_frame_rate
static int defined_frame_rate(AVFormatContext *s, AVStream *st)
Definition: movenc.c:1892
MOV_FRAG_SAMPLE_FLAG_IS_NON_SYNC
#define MOV_FRAG_SAMPLE_FLAG_IS_NON_SYNC
Definition: isom.h:424
fail
#define fail()
Definition: checkasm.h:225
mov_write_gpmd_tag
static int mov_write_gpmd_tag(AVIOContext *pb, const MOVTrack *track)
Definition: movenc.c:3136
AVCodecParameters::bits_per_raw_sample
int bits_per_raw_sample
The number of valid bits in each output sample.
Definition: codec_par.h:130
mov_write_string_metadata
static int mov_write_string_metadata(AVFormatContext *s, AVIOContext *pb, const char *name, const char *tag, int long_style)
Definition: movenc.c:4622
ffio_open_null_buf
int ffio_open_null_buf(AVIOContext **s)
Open a write-only fake memory stream.
Definition: aviobuf.c:1462
AV_STEREO3D_2D
@ AV_STEREO3D_2D
Video is not stereoscopic (and metadata has to be there).
Definition: stereo3d.h:52
AVFMT_FLAG_AUTO_BSF
#define AVFMT_FLAG_AUTO_BSF
Add bitstream filters as requested by the muxer.
Definition: avformat.h:1454
MOVMuxContext::use_editlist
int use_editlist
Definition: movenc.h:250
mov_write_mvex_tag
static int mov_write_mvex_tag(AVIOContext *pb, MOVMuxContext *mov)
Definition: movenc.c:4470
timecode.h
MOV_TRACK_STPS
#define MOV_TRACK_STPS
Definition: movenc.h:114
eac3_info::chan_loc
uint16_t chan_loc
Definition: movenc.c:411
mov_write_dref_tag
static int mov_write_dref_tag(AVIOContext *pb)
Definition: movenc.c:3273
GetBitContext
Definition: get_bits.h:109
AVTimecode::start
int start
timecode frame start (first base frame number)
Definition: timecode.h:42
mov_write_mdhd_tag
static int mov_write_mdhd_tag(AVIOContext *pb, MOVMuxContext *mov, MOVTrack *track)
Definition: movenc.c:3901
mov_write_video_tag
static int mov_write_video_tag(AVFormatContext *s, AVIOContext *pb, MOVMuxContext *mov, MOVTrack *track)
Definition: movenc.c:2782
AC3HeaderInfo
Definition: ac3_parser_internal.h:34
mov_write_evcc_tag
static int mov_write_evcc_tag(AVIOContext *pb, MOVTrack *track)
Definition: movenc.c:1670
MOVTrack::frag_discont
int frag_discont
Definition: movenc.h:160
mov_get_rawvideo_codec_tag
static int mov_get_rawvideo_codec_tag(AVFormatContext *s, MOVTrack *track)
Definition: movenc.c:2080
mov_write_esds_tag
static int mov_write_esds_tag(AVIOContext *pb, MOVTrack *track)
Definition: movenc.c:765
AC3HeaderInfo::frame_size
uint16_t frame_size
Definition: ac3_parser_internal.h:62
avio_tell
static av_always_inline int64_t avio_tell(AVIOContext *s)
ftell() equivalent for AVIOContext.
Definition: avio.h:494
MOVTrack::first_packet_entry
int first_packet_entry
Definition: movenc.h:169
mov_write_ftyp_tag
static int mov_write_ftyp_tag(AVIOContext *pb, AVFormatContext *s)
Definition: movenc.c:6168
EAC3_FRAME_TYPE_DEPENDENT
@ EAC3_FRAME_TYPE_DEPENDENT
Definition: ac3defs.h:112
AVChapter
Definition: avformat.h:1242
MOV_TRUN_SAMPLE_DURATION
#define MOV_TRUN_SAMPLE_DURATION
Definition: isom.h:418
val
static double val(void *priv, double ch)
Definition: aeval.c:77
compute_avg_bitrate
static unsigned compute_avg_bitrate(MOVTrack *track)
Definition: movenc.c:703
MOVTrack::apv
struct APVDecoderConfigurationRecord * apv
Definition: movenc.h:195
MOVIentry::size
unsigned int size
Definition: movenc.h:52
validate_codec_tag
static unsigned int validate_codec_tag(const AVCodecTag *const *tags, unsigned int tag, int codec_id)
Definition: movenc.c:2168
MOVTrack::mdat_buf
AVIOContext * mdat_buf
Definition: movenc.h:158
MOVTrack::cluster
MOVIentry * cluster
Definition: movenc.h:129
AVFMT_AVOID_NEG_TS_MAKE_ZERO
#define AVFMT_AVOID_NEG_TS_MAKE_ZERO
Shift timestamps so that they start at 0.
Definition: avformat.h:1672
AC3HeaderInfo::channel_mode
uint8_t channel_mode
Definition: ac3_parser_internal.h:43
type
it s the only field you need to keep assuming you have a context There is some magic you don t need to care about around this just let it vf type
Definition: writing_filters.txt:86
mov_write_lvcc_tag
static int mov_write_lvcc_tag(AVIOContext *pb, MOVTrack *track)
Definition: movenc.c:1687
mov_setup_track_ids
static int mov_setup_track_ids(MOVMuxContext *mov, AVFormatContext *s)
Assign track ids.
Definition: movenc.c:5189
pts
static int64_t pts
Definition: transcode_aac.c:644
AVStreamGroupLCEVC
AVStreamGroupLCEVC is meant to define the relation between video streams and a data stream containing...
Definition: avformat.h:1071
MOV_SYNC_SAMPLE
#define MOV_SYNC_SAMPLE
Definition: movenc.h:58
FF_MOV_FLAG_USE_MDTA
#define FF_MOV_FLAG_USE_MDTA
Definition: movenc.h:294
AV_CODEC_ID_MP3
@ AV_CODEC_ID_MP3
preferred ID for decoding MPEG audio layer 1, 2 or 3
Definition: codec_id.h:461
mov_finish_fragment
static int mov_finish_fragment(MOVMuxContext *mov, MOVTrack *track, int64_t ref_pos)
Definition: movenc.c:6577
mov_write_iref_tag
static int mov_write_iref_tag(AVIOContext *pb, MOVMuxContext *mov, AVFormatContext *s)
Definition: movenc.c:3689
AVAmbientViewingEnvironment::ambient_illuminance
AVRational ambient_illuminance
Environmental illuminance of the ambient viewing environment in lux.
Definition: ambient_viewing_environment.h:40
mov_write_pssh_tag
static int mov_write_pssh_tag(AVIOContext *pb, AVStream *st)
Definition: movenc.c:5116
MOVMuxContext::iods_video_profile
int iods_video_profile
Definition: movenc.h:226
av_reduce
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
MOV_PRFT_NB
@ MOV_PRFT_NB
Definition: movenc.h:207
ff_data_to_hex
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:458
AVRational::num
int num
Numerator.
Definition: rational.h:59
AV_CH_LAYOUT_STEREO
#define AV_CH_LAYOUT_STEREO
Definition: channel_layout.h:218
vpcc.h
MOV_CH_LAYOUT_MONO
@ MOV_CH_LAYOUT_MONO
Definition: mov_chan.h:56
mov_get_dv_codec_tag
static int mov_get_dv_codec_tag(AVFormatContext *s, MOVTrack *track)
Definition: movenc.c:1867
MOVIentry::prft
AVProducerReferenceTime prft
Definition: movenc.h:62
MOV_FRAG_SAMPLE_FLAG_DEPENDS_YES
#define MOV_FRAG_SAMPLE_FLAG_DEPENDS_YES
Definition: isom.h:431
MovTag
Definition: movenc.h:87
MOV_TRUN_DATA_OFFSET
#define MOV_TRUN_DATA_OFFSET
Definition: isom.h:416
eac3_info::lfeon
uint8_t lfeon
Definition: movenc.c:406
handle_eac3
static int handle_eac3(MOVMuxContext *mov, AVPacket *pkt, MOVTrack *track)
Definition: movenc.c:464
CENC_KID_SIZE
#define CENC_KID_SIZE
Definition: movenccenc.h:30
raw.h
ff_psp_muxer
const FFOutputFormat ff_psp_muxer
ff_mov_cenc_free
void ff_mov_cenc_free(MOVMuxCencContext *ctx)
Free a CENC context.
Definition: movenccenc.c:639
ff_isom_write_evcc
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
dnxhddata.h
mov_prune_frag_info
static void mov_prune_frag_info(MOVMuxContext *mov, int tracks, int max)
Definition: movenc.c:5778
av_get_bits_per_sample
int av_get_bits_per_sample(enum AVCodecID codec_id)
Return codec bits per sample.
Definition: utils.c:549
GET_UTF8
#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:488
AVCodecParameters::color_trc
enum AVColorTransferCharacteristic color_trc
Definition: codec_par.h:191
MOVTrack::st
AVStream * st
Definition: movenc.h:124
avio_close_dyn_buf
int avio_close_dyn_buf(AVIOContext *s, uint8_t **pbuffer)
Return the written size and a pointer to the buffer.
Definition: aviobuf.c:1410
mov_write_tmpo_tag
static int mov_write_tmpo_tag(AVIOContext *pb, AVFormatContext *s)
Definition: movenc.c:4634
ff_mp4_muxer
const FFOutputFormat ff_mp4_muxer
MOVTrack::nb_tref_tags
int nb_tref_tags
Definition: movenc.h:134
mov_write_trak_tag
static int mov_write_trak_tag(AVFormatContext *s, AVIOContext *pb, MOVMuxContext *mov, MOVTrack *track, AVStream *st)
Definition: movenc.c:4372
AV_CODEC_ID_PCM_S8
@ AV_CODEC_ID_PCM_S8
Definition: codec_id.h:342
first
trying all byte sequences megabyte in length and selecting the best looking sequence will yield cases to try But first
Definition: rate_distortion.txt:12
MODE_AVIF
#define MODE_AVIF
Definition: movenc.h:46
pix_fmt
enum AVPixelFormat pix_fmt
Definition: movenc.c:2047
lrint
#define lrint
Definition: tablegen.h:53
eac3_info::pkt
AVPacket * pkt
Definition: movenc.c:384
eac3_info::bsmod
uint8_t bsmod
Definition: movenc.c:402
MOVTrack::palette
uint32_t palette[AVPALETTE_COUNT]
Definition: movenc.h:181
pkt
static AVPacket * pkt
Definition: movenc.c:60
AV_LOG_ERROR
#define AV_LOG_ERROR
Something went wrong and cannot losslessly be recovered.
Definition: log.h:210
FF_MOV_FLAG_FRAG_DISCONT
#define FF_MOV_FLAG_FRAG_DISCONT
Definition: movenc.h:289
mov_write_trailer
static int mov_write_trailer(AVFormatContext *s)
Definition: movenc.c:8914
ff_tg2_muxer
const FFOutputFormat ff_tg2_muxer
FF_ARRAY_ELEMS
#define FF_ARRAY_ELEMS(a)
Definition: sinewin_tablegen.c:29
AV_PROFILE_UNKNOWN
#define AV_PROFILE_UNKNOWN
Definition: defs.h:65
AVCodecTag
Definition: internal.h:42
mov_write_emsg_tag
static int mov_write_emsg_tag(AVIOContext *pb, AVStream *st, AVPacket *pkt)
Definition: movenc.c:7472
MOVTrack::squashed_packet_queue
PacketList squashed_packet_queue
Definition: movenc.h:188
MOVTrack::mono_as_fc
int mono_as_fc
Definition: movenc.h:126
MOVMuxContext::encryption_kid_len
int encryption_kid_len
Definition: movenc.h:261
MOVMuxContext::pkt
AVPacket * pkt
Definition: movenc.h:248
duration
static int64_t duration
Definition: movenc.c:65
AV_FIELD_UNKNOWN
@ AV_FIELD_UNKNOWN
Definition: defs.h:212
AVCodecParameters::frame_size
int frame_size
Audio frame size, if known.
Definition: codec_par.h:227
av_dict_get
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
avio_open_dyn_buf
int avio_open_dyn_buf(AVIOContext **s)
Open a write only memory stream.
Definition: aviobuf.c:1365
av_channel_layout_describe
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.
Definition: channel_layout.c:654
AES_CTR_KEY_SIZE
#define AES_CTR_KEY_SIZE
Definition: aes_ctr.h:35
AV_STREAM_GROUP_PARAMS_IAMF_MIX_PRESENTATION
@ AV_STREAM_GROUP_PARAMS_IAMF_MIX_PRESENTATION
Definition: avformat.h:1107
MOVMuxContext::chapter_track
int chapter_track
qt chapter track number
Definition: movenc.h:217
FF_MOV_FLAG_FRAGMENT
#define FF_MOV_FLAG_FRAGMENT
Definition: movenc.h:278
full_range
bool full_range
Definition: hwcontext_videotoolbox.c:47
AV_CODEC_ID_ADPCM_G726
@ AV_CODEC_ID_ADPCM_G726
Definition: codec_id.h:388
VC1_CODE_SLICE
@ VC1_CODE_SLICE
Definition: vc1_common.h:36
ff_iamf_add_audio_element
int ff_iamf_add_audio_element(IAMFContext *iamf, const AVStreamGroup *stg, void *log_ctx)
Definition: iamf_writer.c:223
stereo3d.h
s
#define s(width, name)
Definition: cbs_vp9.c:198
MOV_TFHD_DEFAULT_BASE_IS_MOOF
#define MOV_TFHD_DEFAULT_BASE_IS_MOOF
Definition: isom.h:414
AV_CODEC_ID_BMP
@ AV_CODEC_ID_BMP
Definition: codec_id.h:130
mov_write_chpl_tag
static int mov_write_chpl_tag(AVIOContext *pb, AVFormatContext *s)
Definition: movenc.c:4981
AV_CODEC_ID_EVC
@ AV_CODEC_ID_EVC
Definition: codec_id.h:325
AV_CODEC_ID_WMAPRO
@ AV_CODEC_ID_WMAPRO
Definition: codec_id.h:497
MOV_TFHD_DEFAULT_DURATION
#define MOV_TFHD_DEFAULT_DURATION
Definition: isom.h:410
MOVMuxContext::movie_timescale
int movie_timescale
Definition: movenc.h:269
MOVCtts::count
unsigned int count
Definition: isom.h:69
av_realloc_array
void * av_realloc_array(void *ptr, size_t nmemb, size_t size)
Definition: mem.c:217
AVFormatContext::flags
int flags
Flags modifying the (de)muxer behaviour.
Definition: avformat.h:1434
AVCodecParameters::sample_aspect_ratio
AVRational sample_aspect_ratio
The aspect ratio (width/height) which a single pixel should have when displayed.
Definition: codec_par.h:161
FF_MOV_FLAG_DELAY_MOOV
#define FF_MOV_FLAG_DELAY_MOOV
Definition: movenc.h:290
mov_write_av3c
static int mov_write_av3c(AVIOContext *pb, const uint8_t *data, int len)
Definition: movenc.c:1593
g
const char * g
Definition: vf_curves.c:128
mov_write_ac3_tag
static int mov_write_ac3_tag(AVFormatContext *s, AVIOContext *pb, MOVTrack *track)
Definition: movenc.c:418
MOVMuxContext::per_stream_grouping
int per_stream_grouping
Definition: movenc.h:245
AVDictionaryEntry::key
char * key
Definition: dict.h:91
AVSphericalMapping::bound_top
uint32_t bound_top
Distance from the top edge.
Definition: spherical.h:186
AVMEDIA_TYPE_AUDIO
@ AVMEDIA_TYPE_AUDIO
Definition: avutil.h:201
AV_CODEC_ID_VP9
@ AV_CODEC_ID_VP9
Definition: codec_id.h:222
AVCodecParameters::width
int width
The width of the video frame in pixels.
Definition: codec_par.h:143
AV_CODEC_ID_MP2
@ AV_CODEC_ID_MP2
Definition: codec_id.h:460
ff_av1_filter_obus_buf
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
MOV_TRUN_FIRST_SAMPLE_FLAGS
#define MOV_TRUN_FIRST_SAMPLE_FLAGS
Definition: isom.h:417
MOVTrack::stsd_count
int stsd_count
Definition: movenc.h:103
av_q2d
static double av_q2d(AVRational a)
Convert an AVRational to a double.
Definition: rational.h:104
MOVMuxContext::nb_meta_tmcd
int nb_meta_tmcd
number of new created tmcd track based on metadata (aka not data copy)
Definition: movenc.h:216
utf8len
static int utf8len(const uint8_t *b)
Definition: movenc.c:143
info
MIPS optimizations info
Definition: mips.txt:2
mov_write_tfra_tag
static int mov_write_tfra_tag(AVIOContext *pb, MOVTrack *track)
Definition: movenc.c:6054
MOVStts::duration
unsigned int duration
Definition: isom.h:65
av_match_ext
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
MOVTrack::timecode_flags
uint32_t timecode_flags
Definition: movenc.h:120
MOVIentry::pts
int64_t pts
Definition: movenc.h:51
MOVTrack::has_disposable
int has_disposable
Definition: movenc.h:112
FF_MOV_FLAG_NEGATIVE_CTS_OFFSETS
#define FF_MOV_FLAG_NEGATIVE_CTS_OFFSETS
Definition: movenc.h:296
av_assert0
#define av_assert0(cond)
assert() equivalent, that is always enabled.
Definition: avassert.h:42
MODE_F4V
#define MODE_F4V
Definition: movenc.h:45
AVMEDIA_TYPE_NB
@ AVMEDIA_TYPE_NB
Definition: avutil.h:205
EAC3_FRAME_TYPE_INDEPENDENT
@ EAC3_FRAME_TYPE_INDEPENDENT
Definition: ac3defs.h:111
mov_write_trkn_tag
static int mov_write_trkn_tag(AVIOContext *pb, MOVMuxContext *mov, AVFormatContext *s, int disc)
Definition: movenc.c:4703
MOVTrack::entry_written
int entry_written
Definition: movenc.h:96
ff_isom_put_dvcc_dvvc
void ff_isom_put_dvcc_dvvc(void *logctx, uint8_t out[ISOM_DVCC_DVVC_SIZE], const AVDOVIDecoderConfigurationRecord *dovi)
Definition: dovi_isom.c:89
FF_MOV_FLAG_PREFER_ICC
#define FF_MOV_FLAG_PREFER_ICC
Definition: movenc.h:300
PROFILE_ADVANCED
@ PROFILE_ADVANCED
Definition: vc1_common.h:52
ff_nal_parse_units
int ff_nal_parse_units(AVIOContext *pb, const uint8_t *buf_in, int size)
Definition: nal.c:113
MOVMuxContext::encryption_kid
uint8_t * encryption_kid
Definition: movenc.h:260
AV_LOG_DEBUG
#define AV_LOG_DEBUG
Stuff which is only useful for libav* developers.
Definition: log.h:231
AVPacketSideData::data
uint8_t * data
Definition: packet.h:417
AVDOVIDecoderConfigurationRecord::dv_profile
uint8_t dv_profile
Definition: dovi_meta.h:58
eac3_info::substream
struct eac3_info::@491 substream[1]
ctx
static AVFormatContext * ctx
Definition: movenc.c:49
channels
channels
Definition: aptx.h:31
mov_write_ipco_tag
static int mov_write_ipco_tag(AVIOContext *pb, MOVMuxContext *mov, AVFormatContext *s)
Definition: movenc.c:3736
get_bits.h
mov_write_stco_tag
static int mov_write_stco_tag(AVIOContext *pb, MOVTrack *track)
Definition: movenc.c:201
mov_write_iloc_tag
static int mov_write_iloc_tag(AVIOContext *pb, MOVMuxContext *mov, AVFormatContext *s)
Definition: movenc.c:3641
AV_RL16
uint64_t_TMPL AV_WL64 unsigned int_TMPL AV_WL32 unsigned int_TMPL AV_WL24 unsigned int_TMPL AV_RL16
Definition: bytestream.h:94
AV_PKT_DATA_STEREO3D
@ 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
MOVMuxContext::frag_interleave
int frag_interleave
Definition: movenc.h:253
ffio_write_leb
void ffio_write_leb(AVIOContext *s, unsigned val)
Definition: aviobuf.c:947
av_rescale_q
int64_t av_rescale_q(int64_t a, AVRational bq, AVRational cq)
Rescale a 64-bit integer by 2 rational numbers.
Definition: mathematics.c:142
FLAC_METADATA_TYPE_STREAMINFO
@ FLAC_METADATA_TYPE_STREAMINFO
Definition: flac.h:46
channel_map
static const uint8_t channel_map[8][8]
Definition: atrac3plusdec.c:52
AVPixFmtDescriptor::log2_chroma_w
uint8_t log2_chroma_w
Amount to shift the luma width right to find the chroma width.
Definition: pixdesc.h:80
MOVTrack::max_packet_size
uint32_t max_packet_size
Definition: movenc.h:149
MOVTrack::sample_size
long sample_size
Definition: movenc.h:109
codec_id
enum AVCodecID codec_id
Definition: vaapi_decode.c:410
AV_PIX_FMT_YUV420P
@ AV_PIX_FMT_YUV420P
planar YUV 4:2:0, 12bpp, (1 Cr & Cb sample per 2x2 Y samples)
Definition: pixfmt.h:73
AV_CODEC_ID_SVQ3
@ AV_CODEC_ID_SVQ3
Definition: codec_id.h:75
key
const char * key
Definition: hwcontext_opencl.c:189
AVCodecParameters::nb_coded_side_data
int nb_coded_side_data
Amount of entries in coded_side_data.
Definition: codec_par.h:88
AVMEDIA_TYPE_DATA
@ AVMEDIA_TYPE_DATA
Opaque data information usually continuous.
Definition: avutil.h:202
av_mallocz
#define av_mallocz(s)
Definition: tableprint_vlc.h:31
MOVIentry::pos
uint64_t pos
Definition: movenc.h:49
mov_parse_mpeg2_frame
static int mov_parse_mpeg2_frame(AVPacket *pkt, uint32_t *flags)
Definition: movenc.c:6390
mov_write_tcmi_tag
static int mov_write_tcmi_tag(AVIOContext *pb, MOVTrack *track)
Definition: movenc.c:3447
build_chunks
static void build_chunks(MOVTrack *trk)
Definition: movenc.c:5153
MOV_PRFT_NONE
@ MOV_PRFT_NONE
Definition: movenc.h:204
AVCOL_PRI_UNSPECIFIED
@ AVCOL_PRI_UNSPECIFIED
Definition: pixfmt.h:639
mov_write_edts_tag
static int mov_write_edts_tag(AVIOContext *pb, MOVMuxContext *mov, MOVTrack *track)
Definition: movenc.c:4114
AVCPBProperties
This structure describes the bitrate properties of an encoded bitstream.
Definition: defs.h:282
ff_format_shift_data
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
mov_write_colr_tag
static int mov_write_colr_tag(AVIOContext *pb, MOVTrack *track, int prefer_icc)
Definition: movenc.c:2597
AV_CODEC_ID_H264
@ AV_CODEC_ID_H264
Definition: codec_id.h:79
PutBitContext
Definition: put_bits.h:50
mov_write_hdlr_tag
static int mov_write_hdlr_tag(AVFormatContext *s, AVIOContext *pb, MOVTrack *track)
Definition: movenc.c:3546
MOVMuxContext::time
int64_t time
Definition: movenc.h:213
tmp
static uint8_t tmp[40]
Definition: aes_ctr.c:52
MOVTrack::packet_entry
int packet_entry
Definition: movenc.h:173
AV_PIX_FMT_RGBA
@ AV_PIX_FMT_RGBA
packed RGBA 8:8:8:8, 32bpp, RGBARGBA...
Definition: pixfmt.h:100
AVStereo3D::flags
int flags
Additional information about the frame packing.
Definition: stereo3d.h:212
AV_CODEC_ID_PNG
@ AV_CODEC_ID_PNG
Definition: codec_id.h:113
AV_CODEC_ID_AVUI
@ AV_CODEC_ID_AVUI
Definition: codec_id.h:257
FF_MOV_FLAG_RTP_HINT
#define FF_MOV_FLAG_RTP_HINT
Definition: movenc.h:277
if
if(ret)
Definition: filter_design.txt:179
mov_write_mfhd_tag
static int mov_write_mfhd_tag(AVIOContext *pb, MOVMuxContext *mov)
Definition: movenc.c:5533
mov_write_psp_udta_tag
static void mov_write_psp_udta_tag(AVIOContext *pb, const char *str, const char *lang, int type)
Definition: movenc.c:5065
mov_write_vpcc_tag
static int mov_write_vpcc_tag(AVFormatContext *s, AVIOContext *pb, MOVTrack *track)
Definition: movenc.c:1622
avio_flush
void avio_flush(AVIOContext *s)
Force flushing of buffered data.
Definition: aviobuf.c:228
MOVMuxContext::use_stream_ids_as_track_ids
int use_stream_ids_as_track_ids
Definition: movenc.h:263
avpriv_packet_list_free
void avpriv_packet_list_free(PacketList *pkt_buf)
Wipe the list and unref all the packets in it.
Definition: packet.c:610
MOVTrack::sample_count
long sample_count
Definition: movenc.h:108
MOVTrack::start_dts
int64_t start_dts
Definition: movenc.h:136
AV_CODEC_ID_AVS3
@ AV_CODEC_ID_AVS3
Definition: codec_id.h:250
AVFormatContext
Format I/O context.
Definition: avformat.h:1283
MOVMuxContext::iods_skip
int iods_skip
Definition: movenc.h:225
mov_isobmff_muxer_class
static const AVClass mov_isobmff_muxer_class
Definition: movenc.c:133
calculate_mpeg4_bit_rates
static struct mpeg4_bit_rate_values calculate_mpeg4_bit_rates(MOVTrack *track)
Definition: movenc.c:720
evc.h
AVStreamGroupLCEVC::height
int height
Height of the final image for presentation.
Definition: avformat.h:1085
options
static const AVOption options[]
Definition: movenc.c:78
AVPacket::buf
AVBufferRef * buf
A reference to the reference-counted buffer where the packet data is stored.
Definition: packet.h:578
AVStream::codecpar
AVCodecParameters * codecpar
Codec parameters associated with this stream.
Definition: avformat.h:769
compute_moov_size
static int compute_moov_size(AVFormatContext *s)
Definition: movenc.c:8837
AV_PIX_FMT_RGB565LE
@ AV_PIX_FMT_RGB565LE
packed RGB 5:6:5, 16bpp, (msb) 5R 6G 5B(lsb), little-endian
Definition: pixfmt.h:113
lcevc.h
LIBAVUTIL_VERSION_INT
#define LIBAVUTIL_VERSION_INT
Definition: version.h:85
AVClass
Describe the class of an AVClass context structure.
Definition: log.h:76
metadata
Stream codec metadata
Definition: ogg-flac-chained-meta.txt:2
AVStream::time_base
AVRational time_base
This is the fundamental unit of time (in seconds) in terms of which frame timestamps are represented.
Definition: avformat.h:785
NULL
#define NULL
Definition: coverity.c:32
ff_put_wav_header
int ff_put_wav_header(AVFormatContext *s, AVIOContext *pb, AVCodecParameters *par, int flags)
Write WAVEFORMAT header structure.
Definition: riffenc.c:54
AVERROR_PATCHWELCOME
#define AVERROR_PATCHWELCOME
Not yet implemented in FFmpeg, patches welcome.
Definition: error.h:64
mov_write_pitm_tag
static int mov_write_pitm_tag(AVIOContext *pb, int item_id)
Definition: movenc.c:3631
av_buffer_unref
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
mov_pcm_be_gt16
static int mov_pcm_be_gt16(enum AVCodecID codec_id)
Definition: movenc.c:826
AV_CODEC_ID_AV1
@ AV_CODEC_ID_AV1
Definition: codec_id.h:284
AVPixFmtDescriptor::nb_components
uint8_t nb_components
The number of components each pixel has, (1-4)
Definition: pixdesc.h:71
AVEncryptionInitInfo
This describes info used to initialize an encryption key system.
Definition: encryption_info.h:88
isom.h
AV_CODEC_ID_TIMED_ID3
@ AV_CODEC_ID_TIMED_ID3
Definition: codec_id.h:612
mov_check_timecode_track
static int mov_check_timecode_track(AVFormatContext *s, AVTimecode *tc, AVStream *src_st, const char *tcstr)
Definition: movenc.c:7742
codec_f4v_tags
static const AVCodecTag codec_f4v_tags[]
Definition: movenc.c:9213
mov_create_timecode_track
static int mov_create_timecode_track(AVFormatContext *s, int index, int src_index, AVTimecode tc)
Definition: movenc.c:7751
mov_write_extradata_tag
static int mov_write_extradata_tag(AVIOContext *pb, MOVTrack *track)
This function writes extradata "as is".
Definition: movenc.c:672
mov_write_packet
static int mov_write_packet(AVFormatContext *s, AVPacket *pkt)
Definition: movenc.c:7500
MP4TrackKindValueMapping::disposition
int disposition
Definition: isom.h:488
mov_write_stsc_tag
static int mov_write_stsc_tag(AVIOContext *pb, MOVTrack *track)
Definition: movenc.c:261
AV_WB16
#define AV_WB16(p, v)
Definition: intreadwrite.h:401
avpriv_packet_list_put
int avpriv_packet_list_put(PacketList *packet_buffer, AVPacket *pkt, int(*copy)(AVPacket *dst, const AVPacket *src), int flags)
Append an AVPacket to the list.
Definition: packet.c:547
AVIO_DATA_MARKER_TRAILER
@ AVIO_DATA_MARKER_TRAILER
Trailer data, which doesn't contain actual content, but only for finalizing the output file.
Definition: avio.h:139
AV_PIX_FMT_YUYV422
@ AV_PIX_FMT_YUYV422
packed YUV 4:2:2, 16bpp, Y0 Cb Y1 Cr
Definition: pixfmt.h:74
get_moov_size
static int get_moov_size(AVFormatContext *s)
Definition: movenc.c:8806
vc1_unescape_buffer
static av_always_inline int vc1_unescape_buffer(const uint8_t *src, int size, uint8_t *dst)
Definition: vc1_common.h:70
MOVMuxContext::encryption_key_len
int encryption_key_len
Definition: movenc.h:259
AV_CODEC_ID_MOV_TEXT
@ AV_CODEC_ID_MOV_TEXT
Definition: codec_id.h:577
ff_mov_cenc_avc_write_nal_units
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
AVRational
Rational number (pair of numerator and denominator).
Definition: rational.h:58
ff_hevc_annexb2mp4_buf
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:1249
rtp_hinting_needed
static int rtp_hinting_needed(const AVStream *st)
Definition: movenc.c:191
mov_get_apv_codec_tag
static int mov_get_apv_codec_tag(AVFormatContext *s, MOVTrack *track)
Definition: movenc.c:2035
check_pkt
static int check_pkt(AVFormatContext *s, MOVTrack *trk, AVPacket *pkt)
Definition: movenc.c:6833
VC1_CODE_SEQHDR
@ VC1_CODE_SEQHDR
Definition: vc1_common.h:40
ff_isom_write_hvcc
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:1398
ffio_close_null_buf
int ffio_close_null_buf(AVIOContext *s)
Close a null buffer.
Definition: aviobuf.c:1472
AV_PIX_FMT_MONOBLACK
@ 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
mov_write_squashed_packets
static int mov_write_squashed_packets(AVFormatContext *s)
Definition: movenc.c:6553
MOVMuxContext::max_fragment_size
int max_fragment_size
Definition: movenc.h:233
ROUNDED_DIV
#define ROUNDED_DIV(a, b)
Definition: common.h:58
AV_CODEC_ID_DVD_SUBTITLE
@ AV_CODEC_ID_DVD_SUBTITLE
Definition: codec_id.h:572
av_default_item_name
const char * av_default_item_name(void *ptr)
Return the context name.
Definition: log.c:242
AVStereo3D::horizontal_disparity_adjustment
AVRational horizontal_disparity_adjustment
Relative shift of the left and right images, which changes the zero parallax plane.
Definition: stereo3d.h:234
get_bits1
static unsigned int get_bits1(GetBitContext *s)
Definition: get_bits.h:391
mov_write_moof_tag_internal
static int mov_write_moof_tag_internal(AVIOContext *pb, MOVMuxContext *mov, int tracks, int moof_size)
Definition: movenc.c:5846
mov_write_clap_tag
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:2534
avc.h
MOVTrack::cenc
MOVMuxCencContext cenc
Definition: movenc.h:179
AVStreamGroupTREF
AVStreamGroupTREF is meant to define the relation between video, audio, or subtitle streams,...
Definition: avformat.h:1095
options
Definition: swscale.c:45
TAG_IS_AVCI
#define TAG_IS_AVCI(tag)
Definition: isom.h:442
AC3HeaderInfo::substreamid
int substreamid
substream identification
Definition: ac3_parser_internal.h:46
MOVTrack::last_sample_is_subtitle_end
int last_sample_is_subtitle_end
Definition: movenc.h:100
VC1_CODE_ENTRYPOINT
@ VC1_CODE_ENTRYPOINT
Definition: vc1_common.h:39
AVStream::metadata
AVDictionary * metadata
Definition: avformat.h:826
get_cluster_duration
static int get_cluster_duration(MOVTrack *track, int cluster_idx)
Definition: movenc.c:1236
FLAC_STREAMINFO_SIZE
#define FLAC_STREAMINFO_SIZE
Definition: flac.h:32
FFOutputFormat
Definition: mux.h:61
mov_write_pasp_tag
static int mov_write_pasp_tag(AVIOContext *pb, MOVTrack *track)
Definition: movenc.c:2562
MOV_SAMPLE_DEPENDENCY_NO
#define MOV_SAMPLE_DEPENDENCY_NO
Definition: isom.h:440
MOVMuxContext
Definition: movenc.h:210
mov_add_tref_tag
static MovTag * mov_add_tref_tag(MOVMuxContext *mov, MOVTrack *trk, uint32_t name)
Definition: movenc.c:5263
ff_iamf_add_mix_presentation
int ff_iamf_add_mix_presentation(IAMFContext *iamf, const AVStreamGroup *stg, void *log_ctx)
Definition: iamf_writer.c:433
MOVMuxContext::missing_duration_warned
int missing_duration_warned
Definition: movenc.h:254
MOVTrack::data_offset
int64_t data_offset
Definition: movenc.h:159
mov_write_track_metadata
static int mov_write_track_metadata(AVIOContext *pb, AVStream *st, const char *tag, const char *str)
Definition: movenc.c:4279
ff_mov_close_hinting
void ff_mov_close_hinting(MOVTrack *track)
Definition: movenchint.c:464
avio_w8
void avio_w8(AVIOContext *s, int b)
Definition: aviobuf.c:184
mov_write_amve_tag
static int mov_write_amve_tag(AVIOContext *pb, MOVTrack *track)
Definition: movenc.c:2696
ff_mov_get_channel_positions_from_layout
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:702
ff_codec_movvideo_tags
const AVCodecTag ff_codec_movvideo_tags[]
Definition: isom_tags.c:29
AV_PIX_FMT_YUV422P10
#define AV_PIX_FMT_YUV422P10
Definition: pixfmt.h:540
mov_get_lpcm_flags
static int mov_get_lpcm_flags(enum AVCodecID codec_id)
Compute flags for 'lpcm' tag.
Definition: movenc.c:1211
ffio_fill
void ffio_fill(AVIOContext *s, int b, int64_t count)
Definition: aviobuf.c:192
MOVIentry::cts
int cts
Definition: movenc.h:57
AV_DISPOSITION_MULTILAYER
#define AV_DISPOSITION_MULTILAYER
The video stream contains multiple layers, e.g.
Definition: avformat.h:716
AV_CODEC_ID_QDM2
@ AV_CODEC_ID_QDM2
Definition: codec_id.h:479
AV_PIX_FMT_GRAY8
@ AV_PIX_FMT_GRAY8
Y , 8bpp.
Definition: pixfmt.h:81
mov_write_nmhd_tag
static int mov_write_nmhd_tag(AVIOContext *pb)
Definition: movenc.c:3431
AVProducerReferenceTime
This structure supplies correlation between a packet timestamp and a wall clock production time.
Definition: defs.h:331
av_packet_ref
int av_packet_ref(AVPacket *dst, const AVPacket *src)
Setup a new reference to the data described by a given packet.
Definition: packet.c:441
MOVTrack::nb_src_track
int nb_src_track
Definition: movenc.h:144
AVCodecParameters::ch_layout
AVChannelLayout ch_layout
The channel layout and number of channels.
Definition: codec_par.h:207
mov_get_codec_tag
static unsigned int mov_get_codec_tag(AVFormatContext *s, MOVTrack *track)
Definition: movenc.c:2106
av_packet_move_ref
void av_packet_move_ref(AVPacket *dst, AVPacket *src)
Move every field in src to dst and reset src.
Definition: packet.c:490
mov_write_minf_tag
static int mov_write_minf_tag(AVFormatContext *s, AVIOContext *pb, MOVMuxContext *mov, MOVTrack *track)
Definition: movenc.c:3802
mov_write_SA3D_tag
static int mov_write_SA3D_tag(AVFormatContext *s, AVIOContext *pb, MOVTrack *track)
Definition: movenc.c:940
AV_CODEC_ID_VP6A
@ AV_CODEC_ID_VP6A
Definition: codec_id.h:158
MOVTrack::packet_seq
int packet_seq
Definition: movenc.h:172
param_write_int
static void param_write_int(AVIOContext *pb, const char *name, int value)
Definition: movenc.c:5391
FF_MOV_FLAG_DISABLE_CHPL
#define FF_MOV_FLAG_DISABLE_CHPL
Definition: movenc.h:286
mov_write_ctts_tag
static int mov_write_ctts_tag(AVFormatContext *s, AVIOContext *pb, MOVTrack *track)
Definition: movenc.c:3183
mov_write_string_data_tag
static int mov_write_string_data_tag(AVIOContext *pb, const char *data, int lang, int long_style)
Definition: movenc.c:4562
AVProducerReferenceTime::flags
int flags
Definition: defs.h:336
MOV_MP4_TTML_TAG
#define MOV_MP4_TTML_TAG
Definition: isom.h:483
AV_PKT_DATA_CONTENT_LIGHT_LEVEL
@ AV_PKT_DATA_CONTENT_LIGHT_LEVEL
Content light level (based on CTA-861.3).
Definition: packet.h:232
MOV_TFHD_BASE_DATA_OFFSET
#define MOV_TFHD_BASE_DATA_OFFSET
Definition: isom.h:408
AV_PIX_FMT_ABGR
@ AV_PIX_FMT_ABGR
packed ABGR 8:8:8:8, 32bpp, ABGRABGR...
Definition: pixfmt.h:101
AV_CODEC_ID_MP4ALS
@ AV_CODEC_ID_MP4ALS
Definition: codec_id.h:505
AVCOL_RANGE_UNSPECIFIED
@ AVCOL_RANGE_UNSPECIFIED
Definition: pixfmt.h:743
mov_write_isml_manifest
static int mov_write_isml_manifest(AVIOContext *pb, MOVMuxContext *mov, AVFormatContext *s)
Definition: movenc.c:5409
MOVMuxContext::empty_hdlr_name
int empty_hdlr_name
Definition: movenc.h:268
ff_codec_movaudio_tags
const AVCodecTag ff_codec_movaudio_tags[]
Definition: isom_tags.c:311
AV_OPT_FLAG_ENCODING_PARAM
#define AV_OPT_FLAG_ENCODING_PARAM
A generic parameter which can be set by the user for muxing or encoding.
Definition: opt.h:352
index
int index
Definition: gxfenc.c:90
c
Undefined Behavior In the C some operations are like signed integer dereferencing freed accessing outside allocated Undefined Behavior must not occur in a C it is not safe even if the output of undefined operations is unused The unsafety may seem nit picking but Optimizing compilers have in fact optimized code on the assumption that no undefined Behavior occurs Optimizing code based on wrong assumptions can and has in some cases lead to effects beyond the output of computations The signed integer overflow problem in speed critical code Code which is highly optimized and works with signed integers sometimes has the problem that often the output of the computation does not c
Definition: undefined.txt:32
mov_write_subtitle_end_packet
static int mov_write_subtitle_end_packet(AVFormatContext *s, int stream_index, int64_t dts)
Definition: movenc.c:7403
AVCodecParameters::sample_rate
int sample_rate
The number of audio samples per second.
Definition: codec_par.h:213
av_csp_approximate_eotf_gamma
double av_csp_approximate_eotf_gamma(enum AVColorTransferCharacteristic trc)
Determine a suitable EOTF 'gamma' value to match the supplied AVColorTransferCharacteristic.
Definition: csp.c:187
mov_write_stbl_tag
static int mov_write_stbl_tag(AVFormatContext *s, AVIOContext *pb, MOVMuxContext *mov, MOVTrack *track)
Definition: movenc.c:3383
cid
uint16_t cid
Definition: mxfenc.c:2335
compute_sidx_size
static int compute_sidx_size(AVFormatContext *s)
Definition: movenc.c:8862
MOVStts
Definition: isom.h:63
AC3HeaderInfo::num_blocks
int num_blocks
number of audio blocks
Definition: ac3_parser_internal.h:51
AV_CODEC_ID_MPEG1VIDEO
@ AV_CODEC_ID_MPEG1VIDEO
Definition: codec_id.h:53
av_buffer_create
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
ff_ipod_muxer
const FFOutputFormat ff_ipod_muxer
find_compressor
static void find_compressor(char *compressor_name, int len, MOVTrack *track)
Definition: movenc.c:2723
AVStream::nb_frames
int64_t nb_frames
number of frames in this stream if known or 0
Definition: avformat.h:807
movenc.h
AVCodecID
AVCodecID
Identify the syntax and semantics of the bitstream.
Definition: codec_id.h:49
av_packet_side_data_get
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:645
AV_CODEC_ID_EAC3
@ AV_CODEC_ID_EAC3
Definition: codec_id.h:500
AV_PKT_DATA_SPHERICAL
@ AV_PKT_DATA_SPHERICAL
This side data should be associated with a video stream and corresponds to the AVSphericalMapping str...
Definition: packet.h:225
AVCodecParameters::extradata_size
int extradata_size
Size of the extradata content in bytes.
Definition: codec_par.h:75
AV_WB32
#define AV_WB32(p, v)
Definition: intreadwrite.h:415
MOV_FRAG_SAMPLE_FLAG_DEPENDS_NO
#define MOV_FRAG_SAMPLE_FLAG_DEPENDS_NO
Definition: isom.h:430
EAC3_FRAME_TYPE_AC3_CONVERT
@ EAC3_FRAME_TYPE_AC3_CONVERT
Definition: ac3defs.h:113
AV_CODEC_ID_AAC
@ AV_CODEC_ID_AAC
Definition: codec_id.h:462
ff_mov_get_channel_config_from_layout
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:673
AVStereo3D::primary_eye
enum AVStereo3DPrimaryEye primary_eye
Which eye is the primary eye when rendering in 2D.
Definition: stereo3d.h:222
AV_ROUND_DOWN
@ AV_ROUND_DOWN
Round toward -infinity.
Definition: mathematics.h:133
AV_UUID_LEN
#define AV_UUID_LEN
Definition: uuid.h:57
av_rescale_rnd
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
AV_CODEC_ID_QCELP
@ AV_CODEC_ID_QCELP
Definition: codec_id.h:484
AV_SPHERICAL_HALF_EQUIRECTANGULAR
@ AV_SPHERICAL_HALF_EQUIRECTANGULAR
Video frame displays as a 180 degree equirectangular projection.
Definition: spherical.h:73
av_get_exact_bits_per_sample
int av_get_exact_bits_per_sample(enum AVCodecID codec_id)
Return codec bits per sample.
Definition: utils.c:454
ff_mov_generate_squashed_ttml_packet
int ff_mov_generate_squashed_ttml_packet(AVFormatContext *s, MOVTrack *track, AVPacket *pkt)
Definition: movenc_ttml.c:236
AV_CODEC_ID_FFV1
@ AV_CODEC_ID_FFV1
Definition: codec_id.h:85
AVIOContext
Bytestream IO Context.
Definition: avio.h:160
AV_CODEC_ID_PCM_S24LE
@ AV_CODEC_ID_PCM_S24LE
Definition: codec_id.h:350
AV_PIX_FMT_RGB24
@ AV_PIX_FMT_RGB24
packed RGB 8:8:8, 24bpp, RGBRGB...
Definition: pixfmt.h:75
AV_SPHERICAL_CUBEMAP
@ AV_SPHERICAL_CUBEMAP
Video frame is split into 6 faces of a cube, and arranged on a 3x2 layout.
Definition: spherical.h:61
ffio_reset_dyn_buf
void ffio_reset_dyn_buf(AVIOContext *s)
Reset a dynamic buffer.
Definition: aviobuf.c:1399
ff_mov_cenc_av1_write_obus
int ff_mov_cenc_av1_write_obus(AVFormatContext *s, MOVMuxCencContext *ctx, AVIOContext *pb, const AVPacket *pkt)
Definition: movenccenc.c:387
ac3_parser_internal.h
AVPacket::size
int size
Definition: packet.h:596
NULL_IF_CONFIG_SMALL
#define NULL_IF_CONFIG_SMALL(x)
Return NULL if CONFIG_SMALL is true, otherwise the argument without modification.
Definition: internal.h:94
avpriv_pix_fmt_find
enum AVPixelFormat avpriv_pix_fmt_find(enum PixelFormatTagLists list, unsigned fourcc)
Definition: raw.c:78
AV_STREAM_GROUP_PARAMS_TREF
@ AV_STREAM_GROUP_PARAMS_TREF
Definition: avformat.h:1110
codec_ipod_tags
static const AVCodecTag codec_ipod_tags[]
Definition: movenc.c:9202
copy
static void copy(const float *p1, float *p2, const int length)
Definition: vf_vaguedenoiser.c:186
FF_OFMT_FLAG_ALLOW_FLUSH
#define FF_OFMT_FLAG_ALLOW_FLUSH
This flag indicates that the muxer stores data internally and supports flushing it.
Definition: mux.h:38
ff_isom_write_avcc
int ff_isom_write_avcc(AVIOContext *pb, const uint8_t *data, int len)
Definition: avc.c:31
height
#define height
Definition: dsp.h:89
AC3HeaderInfo::channel_map_present
uint8_t channel_map_present
Definition: ac3_parser_internal.h:49
MOVTrack::cover_image
AVPacket * cover_image
Definition: movenc.h:156
AVChannelLayout
An AVChannelLayout holds information about the channel layout of audio data.
Definition: channel_layout.h:319
MOVFragmentInfo::time
int64_t time
Definition: movenc.h:81
AVSphericalMapping::bound_right
uint32_t bound_right
Distance from the right edge.
Definition: spherical.h:187
mov_write_dpxe_tag
static int mov_write_dpxe_tag(AVIOContext *pb, MOVTrack *track)
Definition: movenc.c:1854
mov_write_vvcc_tag
static int mov_write_vvcc_tag(AVIOContext *pb, MOVTrack *track)
Definition: movenc.c:1700
FF_MOV_FLAG_FASTSTART
#define FF_MOV_FLAG_FASTSTART
Definition: movenc.h:284
mpeg4_bit_rate_values::avg_bit_rate
uint32_t avg_bit_rate
Average rate in bits/second over the entire presentation.
Definition: movenc.c:717
MOVTrack::language
int language
Definition: movenc.h:121
i
#define i(width, name, range_min, range_max)
Definition: cbs_h264.c:63
av_err2str
#define av_err2str(errnum)
Convenience macro, the return value should be used only directly in function arguments but never stan...
Definition: error.h:122
MOVMuxContext::first_trun
int first_trun
Definition: movenc.h:236
MOVMuxContext::ism_lookahead
int ism_lookahead
Definition: movenc.h:234
ff_vvc_annexb2mp4_buf
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
mov_write_eac3_tag
static int mov_write_eac3_tag(AVFormatContext *s, AVIOContext *pb, MOVTrack *track)
Definition: movenc.c:612
update_size_and_version
static int64_t update_size_and_version(AVIOContext *pb, int64_t pos, int version)
Definition: movenc.c:165
uuid.h
mov_write_hfov_tag
static void mov_write_hfov_tag(AVFormatContext *s, AVIOContext *pb, const AVStereo3D *stereo3d)
Definition: movenc.c:2378
ff_mov_cenc_write_stbl_atoms
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
AV_CODEC_ID_DTS
@ AV_CODEC_ID_DTS
Definition: codec_id.h:464
bps
unsigned bps
Definition: movenc.c:2049
MOVTrack::default_sample_flags
uint32_t default_sample_flags
Definition: movenc.h:152
ff_nal_parse_units_buf
int ff_nal_parse_units_buf(const uint8_t *buf_in, uint8_t **buf, int *size)
Definition: nal.c:133
mov_write_vexu_tag
static int mov_write_vexu_tag(AVFormatContext *s, AVIOContext *pb, const AVStereo3D *stereo3d, const AVSphericalMapping *spherical_mapping)
Definition: movenc.c:2474
ff_mov_cenc_write_packet
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
AC3HeaderInfo::lfe_on
uint8_t lfe_on
Definition: ac3_parser_internal.h:44
mpeg4_bit_rate_values
Definition: movenc.c:714
AV_CODEC_ID_H263
@ AV_CODEC_ID_H263
Definition: codec_id.h:56
MOV_TFHD_STSD_ID
#define MOV_TFHD_STSD_ID
Definition: isom.h:409
ff_iamf_uninit_context
void ff_iamf_uninit_context(IAMFContext *c)
Definition: iamf.c:172
size
int size
Definition: twinvq_data.h:10344
MOVMuxContext::avif_extent_pos
int64_t avif_extent_pos[2]
Definition: movenc.h:271
mov_write_mdta_keys_tag
static int mov_write_mdta_keys_tag(AVIOContext *pb, MOVMuxContext *mov, AVFormatContext *s)
Definition: movenc.c:4839
AV_CODEC_ID_V408
@ AV_CODEC_ID_V408
Definition: codec_id.h:261
avio.h
mov_write_uuid_tag_psp
static int mov_write_uuid_tag_psp(AVIOContext *pb, MOVTrack *mov)
Definition: movenc.c:4239
video_st
static AVStream * video_st
Definition: movenc.c:61
AV_NOPTS_VALUE
#define AV_NOPTS_VALUE
Undefined timestamp value.
Definition: avutil.h:247
NTP_OFFSET_US
#define NTP_OFFSET_US
Definition: internal.h:419
codec_mp4_tags
static const AVCodecTag codec_mp4_tags[]
Definition: movenc.c:9131
ff_iamf_write_parameter_blocks
int ff_iamf_write_parameter_blocks(const IAMFContext *iamf, AVIOContext *pb, const AVPacket *pkt, void *log_ctx)
Definition: iamf_writer.c:1172
AV_RB32
uint64_t_TMPL AV_WL64 unsigned int_TMPL AV_WL32 unsigned int_TMPL AV_WL24 unsigned int_TMPL AV_WL16 uint64_t_TMPL AV_WB64 unsigned int_TMPL AV_RB32
Definition: bytestream.h:96
AV_CODEC_ID_V210
@ AV_CODEC_ID_V210
Definition: codec_id.h:179
mov_write_lhvc_tag
static int mov_write_lhvc_tag(AVFormatContext *s, AVIOContext *pb, MOVTrack *track)
Definition: movenc.c:1648
get_metadata_lang
static AVDictionaryEntry * get_metadata_lang(AVFormatContext *s, const char *tag, int *lang)
Definition: movenc.c:4597
FF_MOV_FLAG_ISML
#define FF_MOV_FLAG_ISML
Definition: movenc.h:283
FF_PUT_WAV_HEADER_FORCE_WAVEFORMATEX
#define FF_PUT_WAV_HEADER_FORCE_WAVEFORMATEX
Tell ff_put_wav_header() to use WAVEFORMATEX even for PCM codecs.
Definition: riff.h:53
AVCodecParameters::profile
int profile
Codec-specific bitstream restrictions that the stream conforms to.
Definition: codec_par.h:135
write_matrix
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:3957
mov_create_dvd_sub_decoder_specific_info
static int mov_create_dvd_sub_decoder_specific_info(MOVTrack *track, AVStream *st)
Definition: movenc.c:7924
AV_CODEC_ID_OPUS
@ AV_CODEC_ID_OPUS
Definition: codec_id.h:520
MOVMuxContext::reserved_header_pos
int64_t reserved_header_pos
Definition: movenc.h:241
MOVTrack::audio_vbr
int audio_vbr
Definition: movenc.h:132
mov_write_gmhd_tag
static int mov_write_gmhd_tag(AVIOContext *pb, MOVTrack *track)
Definition: movenc.c:3469
IAMFContext
Definition: iamf.h:128
mov_write_stsd_tag
static int mov_write_stsd_tag(AVFormatContext *s, AVIOContext *pb, MOVMuxContext *mov, MOVTrack *track)
Definition: movenc.c:3148
AVMEDIA_TYPE_UNKNOWN
@ AVMEDIA_TYPE_UNKNOWN
Usually treated as AVMEDIA_TYPE_DATA.
Definition: avutil.h:199
AVStream::sample_aspect_ratio
AVRational sample_aspect_ratio
sample aspect ratio (0 if unknown)
Definition: avformat.h:824
mov_write_tmcd_tag
static int mov_write_tmcd_tag(AVIOContext *pb, MOVTrack *track)
Definition: movenc.c:3087
mov_write_dmlp_tag
static int mov_write_dmlp_tag(AVFormatContext *s, AVIOContext *pb, MOVTrack *track)
Definition: movenc.c:911
AVIO_DATA_MARKER_SYNC_POINT
@ AVIO_DATA_MARKER_SYNC_POINT
A point in the output bytestream where a decoder can start decoding (i.e.
Definition: avio.h:121
MOVTrack::end_reliable
int end_reliable
Definition: movenc.h:140
ff_mov_iso639_to_lang
int ff_mov_iso639_to_lang(const char lang[4], int mp4)
Definition: isom.c:233
calc_pts_duration
static int64_t calc_pts_duration(MOVMuxContext *mov, MOVTrack *track)
Definition: movenc.c:3876
dovi_isom.h
AV_DISPOSITION_HEARING_IMPAIRED
#define AV_DISPOSITION_HEARING_IMPAIRED
The stream is intended for hearing impaired audiences.
Definition: avformat.h:656
ff_isom_write_av1c
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
AVPacket::dts
int64_t dts
Decompression timestamp in AVStream->time_base units; the time at which the packet is decompressed.
Definition: packet.h:594
avio_write
void avio_write(AVIOContext *s, const unsigned char *buf, int size)
Definition: aviobuf.c:206
avio_wb32
void avio_wb32(AVIOContext *s, unsigned int val)
Definition: aviobuf.c:368
FF_COMPLIANCE_NORMAL
#define FF_COMPLIANCE_NORMAL
Definition: defs.h:60
AVSphericalMapping::padding
uint32_t padding
Number of pixels to pad from the edge of each cube face.
Definition: spherical.h:200
a
The reader does not expect b to be semantically here and if the code is changed by maybe adding a a division or other the signedness will almost certainly be mistaken To avoid this confusion a new type was SUINT is the C unsigned type but it holds a signed int to use the same example SUINT a
Definition: undefined.txt:41
MOVTrack::slices
int slices
Definition: movenc.h:174
av_reallocp_array
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
mov_get_evc_codec_tag
static int mov_get_evc_codec_tag(AVFormatContext *s, MOVTrack *track)
Definition: movenc.c:2025
AV_PRIMARY_EYE_NONE
@ AV_PRIMARY_EYE_NONE
Neither eye.
Definition: stereo3d.h:178
MOV_MP4_FPCM_TAG
#define MOV_MP4_FPCM_TAG
Definition: isom.h:484
avio_wl32
void avio_wl32(AVIOContext *s, unsigned int val)
Definition: aviobuf.c:360
csp.h
AV_CODEC_ID_VVC
@ AV_CODEC_ID_VVC
Definition: codec_id.h:252
MOVTrack::first_packet_seen
int first_packet_seen
Definition: movenc.h:170
mov_write_subtitle_tag
static int mov_write_subtitle_tag(AVFormatContext *s, AVIOContext *pb, MOVTrack *track)
Definition: movenc.c:2240
AV_PKT_DATA_PRFT
@ AV_PKT_DATA_PRFT
Producer Reference Time data corresponding to the AVProducerReferenceTime struct, usually exported by...
Definition: packet.h:265
mov_write_track_kind
static int mov_write_track_kind(AVIOContext *pb, const char *scheme_uri, const char *value)
Definition: movenc.c:4293
offset
it s the only field you need to keep assuming you have a context There is some magic you don t need to care about around this just let it vf offset
Definition: writing_filters.txt:86
AVStreamGroupLCEVC::lcevc_index
unsigned int lcevc_index
Index of the LCEVC data stream in AVStreamGroup.
Definition: avformat.h:1077
AVStreamGroup::lcevc
struct AVStreamGroupLCEVC * lcevc
Definition: avformat.h:1152
AV_CODEC_ID_LCEVC
@ AV_CODEC_ID_LCEVC
Definition: codec_id.h:615
AC3HeaderInfo::bitstream_mode
uint8_t bitstream_mode
Definition: ac3_parser_internal.h:42
AVPacket::flags
int flags
A combination of AV_PKT_FLAG values.
Definition: packet.h:601
av_packet_alloc
AVPacket * av_packet_alloc(void)
Allocate an AVPacket and set its fields to default values.
Definition: packet.c:63
xf
#define xf(width, name, var, range_min, range_max, subs,...)
Definition: cbs_av1.c:622
FF_COMPLIANCE_UNOFFICIAL
#define FF_COMPLIANCE_UNOFFICIAL
Allow unofficial extensions.
Definition: defs.h:61
MOVTrack::start_cts
int64_t start_cts
Definition: movenc.h:137
AVCodecParameters::avcodec_parameters_alloc
AVCodecParameters * avcodec_parameters_alloc(void)
Allocate a new AVCodecParameters and set its fields to default values (unknown/invalid/0).
Definition: codec_par.c:57
version
version
Definition: libkvazaar.c:313
AV_STREAM_GROUP_PARAMS_IAMF_AUDIO_ELEMENT
@ AV_STREAM_GROUP_PARAMS_IAMF_AUDIO_ELEMENT
Definition: avformat.h:1106
mov_write_avid_tag
static int mov_write_avid_tag(AVIOContext *pb, MOVTrack *track)
Definition: movenc.c:1736
mov_write_mdta_ilst_tag
static int mov_write_mdta_ilst_tag(AVIOContext *pb, MOVMuxContext *mov, AVFormatContext *s)
Definition: movenc.c:4868
AV_STEREO3D_FLAG_INVERT
#define AV_STEREO3D_FLAG_INVERT
Inverted views, Right/Bottom represents the left view.
Definition: stereo3d.h:194
MOVIentry::chunkNum
unsigned int chunkNum
Chunk number if the current entry is a chunk start otherwise 0.
Definition: movenc.h:55
AVStreamGroup::streams
AVStream ** streams
A list of streams in the group.
Definition: avformat.h:1184
vc1_common.h
mov_write_meta_tag
static int mov_write_meta_tag(AVIOContext *pb, MOVMuxContext *mov, AVFormatContext *s)
Definition: movenc.c:4890
FF_MOV_FLAG_OMIT_TFHD_OFFSET
#define FF_MOV_FLAG_OMIT_TFHD_OFFSET
Definition: movenc.h:285
MOV_MP4_IPCM_TAG
#define MOV_MP4_IPCM_TAG
Definition: isom.h:485
MOV_DISPOSABLE_SAMPLE
#define MOV_DISPOSABLE_SAMPLE
Definition: movenc.h:60
shift_data
static int shift_data(AVFormatContext *s)
Definition: movenc.c:8877
mov_write_dvc1_structs
static int mov_write_dvc1_structs(MOVTrack *track, uint8_t *buf)
Definition: movenc.c:1097
av_channel_layout_compare
int av_channel_layout_compare(const AVChannelLayout *chl, const AVChannelLayout *chl1)
Check whether two channel layouts are semantically the same, i.e.
Definition: channel_layout.c:811
mov_write_iinf_tag
static int mov_write_iinf_tag(AVIOContext *pb, MOVMuxContext *mov, AVFormatContext *s)
Definition: movenc.c:3664
AC3HeaderInfo::ac3_bit_rate_code
int8_t ac3_bit_rate_code
Definition: ac3_parser_internal.h:64
AV_CODEC_ID_TSCC2
@ AV_CODEC_ID_TSCC2
Definition: codec_id.h:218
AV_LOG_INFO
#define AV_LOG_INFO
Standard information.
Definition: log.h:221
mov_free
static void mov_free(AVFormatContext *s)
Definition: movenc.c:7849
MODE_3GP
#define MODE_3GP
Definition: movenc.h:39
MOVTrack::time
uint64_t time
Definition: movenc.h:98
FF_MOV_FLAG_SKIP_SIDX
#define FF_MOV_FLAG_SKIP_SIDX
Definition: movenc.h:298
AV_PIX_FMT_ARGB
@ AV_PIX_FMT_ARGB
packed ARGB 8:8:8:8, 32bpp, ARGBARGB...
Definition: pixfmt.h:99
AV_OPT_TYPE_FLOAT
@ AV_OPT_TYPE_FLOAT
Underlying C type is float.
Definition: opt.h:271
apv.h
ff_mov_add_hinted_packet
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
AV_SPHERICAL_RECTILINEAR
@ AV_SPHERICAL_RECTILINEAR
Video frame displays on a flat, rectangular 2D surface.
Definition: spherical.h:78
layout
Filter the word “frame” indicates either a video frame or a group of audio as stored in an AVFrame structure Format for each input and each output the list of supported formats For video that means pixel format For audio that means channel layout
Definition: filter_design.txt:18
mov_write_covr
static int mov_write_covr(AVIOContext *pb, AVFormatContext *s)
Definition: movenc.c:4757
avcodec_get_name
const char * avcodec_get_name(enum AVCodecID id)
Get the name of a codec.
Definition: utils.c:406
AV_CODEC_ID_MJPEG
@ AV_CODEC_ID_MJPEG
Definition: codec_id.h:59
MOVTrack::hint_track
int hint_track
the track that hints this track, -1 if no hint track is set
Definition: movenc.h:143
MOVTrack::has_keyframes
int has_keyframes
Definition: movenc.h:111
AV_PIX_FMT_UYVA
@ 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_double2int
static av_always_inline uint64_t av_double2int(double f)
Reinterpret a double as a 64-bit integer.
Definition: intfloat.h:70
mov_write_iprp_tag
static int mov_write_iprp_tag(AVIOContext *pb, MOVMuxContext *mov, AVFormatContext *s)
Definition: movenc.c:3777
interlaced
uint8_t interlaced
Definition: mxfenc.c:2336
MOVTrack::entry
int entry
Definition: movenc.h:96
av_assert2
#define av_assert2(cond)
assert() equivalent, that does lie in speed critical code.
Definition: avassert.h:68
mov_write_uuidprof_tag
static int mov_write_uuidprof_tag(AVIOContext *pb, AVFormatContext *s)
Definition: movenc.c:6290
av_channel_layout_from_string
int av_channel_layout_from_string(AVChannelLayout *channel_layout, const char *str)
Initialize a channel layout from a given string description.
Definition: channel_layout.c:313
AV_PKT_DATA_CPB_PROPERTIES
@ AV_PKT_DATA_CPB_PROPERTIES
This side data corresponds to the AVCPBProperties struct.
Definition: packet.h:142
mov_write_dinf_tag
static int mov_write_dinf_tag(AVIOContext *pb)
Definition: movenc.c:3422
AV_PIX_FMT_RGB555LE
@ 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
AVSphericalMapping::roll
int32_t roll
Rotation around the forward vector [-180, 180].
Definition: spherical.h:146
AV_PIX_FMT_RGB48BE
@ 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
mov_write_av3c_tag
static int mov_write_av3c_tag(AVIOContext *pb, MOVTrack *track)
Definition: movenc.c:1612
ff_interleaved_peek
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
AVFMT_GLOBALHEADER
#define AVFMT_GLOBALHEADER
Format wants global header.
Definition: avformat.h:477
av_malloc
#define av_malloc(s)
Definition: ops_asmgen.c:44
FF_MOV_FLAG_EMPTY_MOOV
#define FF_MOV_FLAG_EMPTY_MOOV
Definition: movenc.h:279
AV_CODEC_ID_NONE
@ AV_CODEC_ID_NONE
Definition: codec_id.h:50
AVPacket::pts
int64_t pts
Presentation timestamp in AVStream->time_base units; the time at which the decompressed packet will b...
Definition: packet.h:588
avio_internal.h
ff_mov_write_packet
int ff_mov_write_packet(AVFormatContext *s, AVPacket *pkt)
Definition: movenc.c:6868
MOVCtts::offset
int offset
Definition: isom.h:70
round
static av_always_inline av_const double round(double x)
Definition: libm.h:446
MOVMuxContext::nb_streams
int nb_streams
Definition: movenc.h:214
av_packet_get_side_data
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
AV_SPHERICAL_FISHEYE
@ AV_SPHERICAL_FISHEYE
Fisheye projection (Apple).
Definition: spherical.h:84
AV_CODEC_ID_EVRC
@ AV_CODEC_ID_EVRC
Definition: codec_id.h:531
AVCodecParameters::height
int height
The height of the video frame in pixels.
Definition: codec_par.h:150
mov_write_avcc_tag
static int mov_write_avcc_tag(AVIOContext *pb, MOVTrack *track)
Definition: movenc.c:1578
AV_TIME_BASE
#define AV_TIME_BASE
Internal time base represented as integer.
Definition: avutil.h:253
MOVMuxContext::fragments
int fragments
Definition: movenc.h:230
AVCodecParameters::block_align
int block_align
The number of bytes per coded audio frame, required by some formats.
Definition: codec_par.h:221
AV_CODEC_ID_TTML
@ AV_CODEC_ID_TTML
Definition: codec_id.h:596
av_malloc_array
#define av_malloc_array(a, b)
Definition: tableprint_vlc.h:32
mov_get_mpeg2_xdcam_codec_tag
static int mov_get_mpeg2_xdcam_codec_tag(AVFormatContext *s, MOVTrack *track)
Definition: movenc.c:1901
MOV_PRFT_SRC_WALLCLOCK
@ MOV_PRFT_SRC_WALLCLOCK
Definition: movenc.h:205
AV_PKT_DATA_ICC_PROFILE
@ 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
mov_pix_fmt_tags
static const struct @490 mov_pix_fmt_tags[]
AV_STEREO3D_TOPBOTTOM
@ AV_STEREO3D_TOPBOTTOM
Views are on top of each other.
Definition: stereo3d.h:76
ff_mov_cenc_flush
void ff_mov_cenc_flush(MOVMuxCencContext *ctx)
Clear subsample data.
Definition: movenccenc.c:633
MOVTrack::extradata_size
int * extradata_size
Definition: movenc.h:106
mov_write_string_tag
static int mov_write_string_tag(AVIOContext *pb, const char *name, const char *value, int lang, int long_style)
Definition: movenc.c:4583
MOVTrack::first_packet_seq
int first_packet_seq
Definition: movenc.h:168
ff_get_packet_palette
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:71
eac3_info::data_rate
uint16_t data_rate
Definition: movenc.c:390
avpriv_ac3_parse_header
int avpriv_ac3_parse_header(AC3HeaderInfo **phdr, const uint8_t *buf, size_t size)
Definition: ac3_parser.c:491
AV_CODEC_ID_PCM_F64BE
@ AV_CODEC_ID_PCM_F64BE
Definition: codec_id.h:360
mov_write_mdat_size
static void mov_write_mdat_size(AVFormatContext *s)
Definition: movenc.c:8892
AV_CODEC_ID_HEVC
@ AV_CODEC_ID_HEVC
Definition: codec_id.h:228
value
it s the only field you need to keep assuming you have a context There is some magic you don t need to care about around this just let it vf default value
Definition: writing_filters.txt:86
MOVMuxContext::video_track_timescale
int video_track_timescale
Definition: movenc.h:238
mov_write_stss_tag
static int mov_write_stss_tag(AVIOContext *pb, MOVTrack *track, uint32_t flag)
Definition: movenc.c:292
MOV_TIMECODE_FLAG_DROPFRAME
#define MOV_TIMECODE_FLAG_DROPFRAME
Definition: movenc.h:117
FFMIN
#define FFMIN(a, b)
Definition: macros.h:49
mov_parse_truehd_frame
static void mov_parse_truehd_frame(AVPacket *pkt, MOVTrack *trk)
Definition: movenc.c:6471
AV_CODEC_ID_DVVIDEO
@ AV_CODEC_ID_DVVIDEO
Definition: codec_id.h:76
AV_CODEC_ID_PCM_S32BE
@ AV_CODEC_ID_PCM_S32BE
Definition: codec_id.h:347
AC3HeaderInfo::channel_map
uint16_t channel_map
Definition: ac3_parser_internal.h:50
MOVMuxContext::max_fragment_duration
int max_fragment_duration
Definition: movenc.h:231
ff_mov_cenc_init
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
AVStreamGroup::params
union AVStreamGroup::@447 params
Group type-specific parameters.
MOVTrack::rtp_ctx
AVFormatContext * rtp_ctx
the format context for the hinting rtp muxer
Definition: movenc.h:146
av_inv_q
static av_always_inline AVRational av_inv_q(AVRational q)
Invert a rational.
Definition: rational.h:159
AV_CODEC_ID_VC1
@ AV_CODEC_ID_VC1
Definition: codec_id.h:122
mov_find_tref_tag
static MovTag * mov_find_tref_tag(MOVMuxContext *mov, const MOVTrack *trk, uint32_t name)
Definition: movenc.c:5252
AVCodecParameters::color_range
enum AVColorRange color_range
Additional colorspace characteristics.
Definition: codec_par.h:189
AVMasteringDisplayMetadata
Mastering display metadata capable of representing the color volume of the display used to master the...
Definition: mastering_display_metadata.h:38
len
int len
Definition: vorbis_enc_data.h:426
AV_CODEC_ID_JPEG2000
@ AV_CODEC_ID_JPEG2000
Definition: codec_id.h:140
MOV_TFHD_DEFAULT_SIZE
#define MOV_TFHD_DEFAULT_SIZE
Definition: isom.h:411
mov_write_tapt_tag
static int mov_write_tapt_tag(AVIOContext *pb, MOVTrack *track)
Definition: movenc.c:4079
mov_write_stsz_tag
static int mov_write_stsz_tag(AVIOContext *pb, MOVTrack *track)
Definition: movenc.c:225
profile
int profile
Definition: mxfenc.c:2299
AVCOL_SPC_UNSPECIFIED
@ AVCOL_SPC_UNSPECIFIED
Definition: pixfmt.h:703
rtpenc.h
mov_check_bitstream
static int mov_check_bitstream(AVFormatContext *s, AVStream *st, const AVPacket *pkt)
Definition: movenc.c:9039
MOV_SAMPLE_DEPENDENCY_YES
#define MOV_SAMPLE_DEPENDENCY_YES
Definition: isom.h:439
av_rescale
int64_t av_rescale(int64_t a, int64_t b, int64_t c)
Rescale a 64-bit integer with rounding to nearest.
Definition: mathematics.c:129
AVCodecParameters::coded_side_data
AVPacketSideData * coded_side_data
Additional data associated with the entire stream.
Definition: codec_par.h:83
nal.h
AVCOL_RANGE_MPEG
@ AVCOL_RANGE_MPEG
Narrow or limited range content.
Definition: pixfmt.h:760
av_calloc
void * av_calloc(size_t nmemb, size_t size)
Definition: mem.c:264
MOVTrack::iamf
struct IAMFContext * iamf
Definition: movenc.h:190
AVCodecParameters::field_order
enum AVFieldOrder field_order
The order of the fields in interlaced video.
Definition: codec_par.h:182
update_size
static int64_t update_size(AVIOContext *pb, int64_t pos)
Definition: movenc.c:155
MP4TrackKindValueMapping
Definition: isom.h:487
ff_tgp_muxer
const FFOutputFormat ff_tgp_muxer
AVFMT_TS_NEGATIVE
#define AVFMT_TS_NEGATIVE
Format allows muxing negative timestamps.
Definition: avformat.h:490
ff_sdp_write_media
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
ff_iamf_write_audio_frame
int ff_iamf_write_audio_frame(const IAMFContext *iamf, AVIOContext *pb, unsigned audio_substream_id, const AVPacket *pkt)
Definition: iamf_writer.c:1222
ff_iamf_write_descriptors
int ff_iamf_write_descriptors(const IAMFContext *iamf, AVIOContext *pb, void *log_ctx)
Definition: iamf_writer.c:1014
version.h
AV_TIMECODE_FLAG_DROPFRAME
@ AV_TIMECODE_FLAG_DROPFRAME
timecode is drop frame
Definition: timecode.h:36
mov_write_tfhd_tag
static int mov_write_tfhd_tag(AVIOContext *pb, MOVMuxContext *mov, MOVTrack *track, int64_t moof_offset)
Definition: movenc.c:5548
ff_mov_muxer
const FFOutputFormat ff_mov_muxer
mov_write_stts_tag
static int mov_write_stts_tag(AVIOContext *pb, MOVTrack *track)
Definition: movenc.c:3224
AV_PIX_FMT_PAL8
@ AV_PIX_FMT_PAL8
8 bits with AV_PIX_FMT_RGB32 palette
Definition: pixfmt.h:84
mov_chan.h
AVStream::disposition
int disposition
Stream disposition - a combination of AV_DISPOSITION_* flags.
Definition: avformat.h:815
AV_DISPOSITION_VISUAL_IMPAIRED
#define AV_DISPOSITION_VISUAL_IMPAIRED
The stream is intended for visually impaired audiences.
Definition: avformat.h:660
mov_write_moof_tag
static int mov_write_moof_tag(AVIOContext *pb, MOVMuxContext *mov, int tracks, int64_t mdat_size)
Definition: movenc.c:6020
AV_PROFILE_DNXHD
#define AV_PROFILE_DNXHD
Definition: defs.h:80
tag
uint32_t tag
Definition: movenc.c:2048
ffio_free_dyn_buf
void ffio_free_dyn_buf(AVIOContext **s)
Free a dynamic buffer.
Definition: aviobuf.c:1438
AVStream::id
int id
Format-specific stream ID.
Definition: avformat.h:758
AVFMT_FLAG_BITEXACT
#define AVFMT_FLAG_BITEXACT
When muxing, try to avoid writing any random/volatile data to the output.
Definition: avformat.h:1451
ret
ret
Definition: filter_design.txt:187
AVStream
Stream structure.
Definition: avformat.h:746
AV_CODEC_ID_APV
@ AV_CODEC_ID_APV
Definition: codec_id.h:332
mov_get_h264_codec_tag
static int mov_get_h264_codec_tag(AVFormatContext *s, MOVTrack *track)
Definition: movenc.c:1963
avio_seek
int64_t avio_seek(AVIOContext *s, int64_t offset, int whence)
fseek() equivalent for AVIOContext.
Definition: aviobuf.c:236
mov_write_int8_metadata
static int mov_write_int8_metadata(AVFormatContext *s, AVIOContext *pb, const char *name, const char *tag, int len)
Definition: movenc.c:4730
AVClass::class_name
const char * class_name
The name of the class; usually it is the same name as the context structure type to which the AVClass...
Definition: log.h:81
mov_write_pixi_tag
static int mov_write_pixi_tag(AVIOContext *pb, MOVMuxContext *mov, AVFormatContext *s, int stream_index)
Definition: movenc.c:3720
ff_dnxhd_parse_header_prefix
static av_always_inline uint64_t ff_dnxhd_parse_header_prefix(const uint8_t *buf)
Definition: dnxhddata.h:85
ff_mov_cenc_write_sinf_tag
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
av_strlcat
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
MOVMuxContext::track_ids_ok
int track_ids_ok
Definition: movenc.h:264
AVSphericalMapping::pitch
int32_t pitch
Rotation around the right vector [-90, 90].
Definition: spherical.h:145
mov_write_hvcc_tag
static int mov_write_hvcc_tag(AVFormatContext *s, AVIOContext *pb, MOVTrack *track)
Definition: movenc.c:1633
ff_av1_filter_obus
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
rawutils.h
ff_isom_close_apvc
void ff_isom_close_apvc(APVDecoderConfigurationRecord **papvc)
Definition: apv.c:375
MOVTrack::entries_flushed
int entries_flushed
Definition: movenc.h:161
MOV_TKHD_FLAG_IN_MOVIE
#define MOV_TKHD_FLAG_IN_MOVIE
Definition: isom.h:434
AVStereo3D::type
enum AVStereo3DType type
How views are packed within the video.
Definition: stereo3d.h:207
FF_MOV_FLAG_DASH
#define FF_MOV_FLAG_DASH
Definition: movenc.h:288
mov_write_tref_tag
static int mov_write_tref_tag(AVIOContext *pb, MOVTrack *track)
Definition: movenc.c:4222
mov_write_uuid_tag_ipod
static int mov_write_uuid_tag_ipod(AVIOContext *pb)
Write uuid atom.
Definition: movenc.c:2211
pos
unsigned int pos
Definition: spdifenc.c:414
MOVMuxCencContext::aes_ctr
struct AVAESCTR * aes_ctr
Definition: movenccenc.h:41
avformat.h
dovi_meta.h
dict.h
AVPacket::side_data
AVPacketSideData * side_data
Additional packet data that can be provided by the container.
Definition: packet.h:606
MOVMuxContext::is_animated_avif
int is_animated_avif
Definition: movenc.h:273
flag
#define flag(name)
Definition: cbs_av1.c:496
AV_INPUT_BUFFER_PADDING_SIZE
#define AV_INPUT_BUFFER_PADDING_SIZE
Definition: defs.h:40
id
enum AVCodecID id
Definition: dts2pts.c:550
left
Tag MUST be and< 10hcoeff half pel interpolation filter coefficients, hcoeff[0] are the 2 middle coefficients[1] are the next outer ones and so on, resulting in a filter like:...eff[2], hcoeff[1], hcoeff[0], hcoeff[0], hcoeff[1], hcoeff[2] ... the sign of the coefficients is not explicitly stored but alternates after each coeff and coeff[0] is positive, so ...,+,-,+,-,+,+,-,+,-,+,... hcoeff[0] is not explicitly stored but found by subtracting the sum of all stored coefficients with signs from 32 hcoeff[0]=32 - hcoeff[1] - hcoeff[2] - ... a good choice for hcoeff and htaps is htaps=6 hcoeff={40,-10, 2} an alternative which requires more computations at both encoder and decoder side and may or may not be better is htaps=8 hcoeff={42,-14, 6,-2}ref_frames minimum of the number of available reference frames and max_ref_frames for example the first frame after a key frame always has ref_frames=1spatial_decomposition_type wavelet type 0 is a 9/7 symmetric compact integer wavelet 1 is a 5/3 symmetric compact integer wavelet others are reserved stored as delta from last, last is reset to 0 if always_reset||keyframeqlog quality(logarithmic quantizer scale) stored as delta from last, last is reset to 0 if always_reset||keyframemv_scale stored as delta from last, last is reset to 0 if always_reset||keyframe FIXME check that everything works fine if this changes between framesqbias dequantization bias stored as delta from last, last is reset to 0 if always_reset||keyframeblock_max_depth maximum depth of the block tree stored as delta from last, last is reset to 0 if always_reset||keyframequant_table quantization tableHighlevel bitstream structure:==============================--------------------------------------------|Header|--------------------------------------------|------------------------------------|||Block0||||split?||||yes no||||......... intra?||||:Block01 :yes no||||:Block02 :....... ..........||||:Block03 ::y DC ::ref index:||||:Block04 ::cb DC ::motion x :||||......... :cr DC ::motion y :||||....... ..........|||------------------------------------||------------------------------------|||Block1|||...|--------------------------------------------|------------ ------------ ------------|||Y subbands||Cb subbands||Cr subbands||||--- ---||--- ---||--- ---|||||LL0||HL0||||LL0||HL0||||LL0||HL0|||||--- ---||--- ---||--- ---||||--- ---||--- ---||--- ---|||||LH0||HH0||||LH0||HH0||||LH0||HH0|||||--- ---||--- ---||--- ---||||--- ---||--- ---||--- ---|||||HL1||LH1||||HL1||LH1||||HL1||LH1|||||--- ---||--- ---||--- ---||||--- ---||--- ---||--- ---|||||HH1||HL2||||HH1||HL2||||HH1||HL2|||||...||...||...|||------------ ------------ ------------|--------------------------------------------Decoding process:=================------------|||Subbands|------------||||------------|Intra DC||||LL0 subband prediction ------------|\ Dequantization ------------------- \||Reference frames|\ IDWT|------- -------|Motion \|||Frame 0||Frame 1||Compensation . OBMC v -------|------- -------|--------------. \------> Frame n output Frame Frame<----------------------------------/|...|------------------- Range Coder:============Binary Range Coder:------------------- The implemented range coder is an adapted version based upon "Range encoding: an algorithm for removing redundancy from a digitised message." by G. N. N. Martin. The symbols encoded by the Snow range coder are bits(0|1). The associated probabilities are not fix but change depending on the symbol mix seen so far. bit seen|new state ---------+----------------------------------------------- 0|256 - state_transition_table[256 - old_state];1|state_transition_table[old_state];state_transition_table={ 0, 0, 0, 0, 0, 0, 0, 0, 20, 21, 22, 23, 24, 25, 26, 27, 28, 29, 30, 31, 32, 33, 34, 35, 36, 37, 37, 38, 39, 40, 41, 42, 43, 44, 45, 46, 47, 48, 49, 50, 51, 52, 53, 54, 55, 56, 56, 57, 58, 59, 60, 61, 62, 63, 64, 65, 66, 67, 68, 69, 70, 71, 72, 73, 74, 75, 75, 76, 77, 78, 79, 80, 81, 82, 83, 84, 85, 86, 87, 88, 89, 90, 91, 92, 93, 94, 94, 95, 96, 97, 98, 99, 100, 101, 102, 103, 104, 105, 106, 107, 108, 109, 110, 111, 112, 113, 114, 114, 115, 116, 117, 118, 119, 120, 121, 122, 123, 124, 125, 126, 127, 128, 129, 130, 131, 132, 133, 133, 134, 135, 136, 137, 138, 139, 140, 141, 142, 143, 144, 145, 146, 147, 148, 149, 150, 151, 152, 152, 153, 154, 155, 156, 157, 158, 159, 160, 161, 162, 163, 164, 165, 166, 167, 168, 169, 170, 171, 171, 172, 173, 174, 175, 176, 177, 178, 179, 180, 181, 182, 183, 184, 185, 186, 187, 188, 189, 190, 190, 191, 192, 194, 194, 195, 196, 197, 198, 199, 200, 201, 202, 202, 204, 205, 206, 207, 208, 209, 209, 210, 211, 212, 213, 215, 215, 216, 217, 218, 219, 220, 220, 222, 223, 224, 225, 226, 227, 227, 229, 229, 230, 231, 232, 234, 234, 235, 236, 237, 238, 239, 240, 241, 242, 243, 244, 245, 246, 247, 248, 248, 0, 0, 0, 0, 0, 0, 0};FIXME Range Coding of integers:------------------------- FIXME Neighboring Blocks:===================left and top are set to the respective blocks unless they are outside of the image in which case they are set to the Null block top-left is set to the top left block unless it is outside of the image in which case it is set to the left block if this block has no larger parent block or it is at the left side of its parent block and the top right block is not outside of the image then the top right block is used for top-right else the top-left block is used Null block y, cb, cr are 128 level, ref, mx and my are 0 Motion Vector Prediction:=========================1. the motion vectors of all the neighboring blocks are scaled to compensate for the difference of reference frames scaled_mv=(mv *(256 *(current_reference+1)/(mv.reference+1))+128)> the median of the scaled left
Definition: snow.txt:386
AV_PIX_FMT_UYVY422
@ AV_PIX_FMT_UYVY422
packed YUV 4:2:2, 16bpp, Cb Y0 Cr Y1
Definition: pixfmt.h:88
AV_RL32
uint64_t_TMPL AV_WL64 unsigned int_TMPL AV_RL32
Definition: bytestream.h:92
MODE_3G2
#define MODE_3G2
Definition: movenc.h:42
AVCodecParameters::avcodec_parameters_free
void avcodec_parameters_free(AVCodecParameters **par)
Free an AVCodecParameters instance and everything associated with it and write NULL to the supplied p...
Definition: codec_par.c:67
mov_flush_fragment
static int mov_flush_fragment(AVFormatContext *s, int force)
Definition: movenc.c:6609
avio_printf
int avio_printf(AVIOContext *s, const char *fmt,...) av_printf_format(2
Writes a formatted string to the context.
mov_write_sthd_tag
static int mov_write_sthd_tag(AVIOContext *pb)
Definition: movenc.c:3439
MOVTrack::par
AVCodecParameters * par
Definition: movenc.h:125
ff_isom_parse_apvc
int ff_isom_parse_apvc(APVDecoderConfigurationRecord *apvc, const AVPacket *pkt, void *logctx)
Definition: apv.c:252
AVStreamGroup
Definition: avformat.h:1116
AVStream::index
int index
stream index in AVFormatContext
Definition: avformat.h:752
eac3_info::num_ind_sub
uint8_t num_ind_sub
Definition: movenc.c:393
MOV_INDEX_CLUSTER_SIZE
#define MOV_INDEX_CLUSTER_SIZE
Definition: movenc.h:32
ff_codec_bmp_tags
const AVCodecTag ff_codec_bmp_tags[]
Definition: riff.c:36
FF_MOV_FLAG_SEPARATE_MOOF
#define FF_MOV_FLAG_SEPARATE_MOOF
Definition: movenc.h:281
AVStreamGroup::nb_streams
unsigned int nb_streams
Number of elements in AVStreamGroup.streams.
Definition: avformat.h:1171
channel_layout.h
ff_avc_write_annexb_extradata
int ff_avc_write_annexb_extradata(const uint8_t *in, uint8_t **buf, int *size)
Definition: avc.c:144
MOVMuxContext::flags
int flags
Definition: movenc.h:222
AV_PROFILE_AAC_HE_V2
#define AV_PROFILE_AAC_HE_V2
Definition: defs.h:73
AV_CODEC_ID_V410
@ AV_CODEC_ID_V410
Definition: codec_id.h:210
MOVTrack::last_stsd_index
int last_stsd_index
Definition: movenc.h:104
av_channel_layout_subset
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...
Definition: channel_layout.c:867
MOVMuxContext::reserved_moov_size
int reserved_moov_size
0 for disabled, -1 for automatic, size otherwise
Definition: movenc.h:240
ISOM_DVCC_DVVC_SIZE
#define ISOM_DVCC_DVVC_SIZE
Definition: dovi_isom.h:29
AVIO_SEEKABLE_NORMAL
#define AVIO_SEEKABLE_NORMAL
Seeking works like for a local file.
Definition: avio.h:41
is_cover_image
static int is_cover_image(const AVStream *st)
Definition: movenc.c:184
AVRational::den
int den
Denominator.
Definition: rational.h:60
rgb_to_yuv
static uint32_t rgb_to_yuv(uint32_t rgb)
Definition: movenc.c:7908
AV_PIX_FMT_NONE
@ AV_PIX_FMT_NONE
Definition: pixfmt.h:72
mov_create_chapter_track
static int mov_create_chapter_track(AVFormatContext *s, int tracknum)
Definition: movenc.c:7651
mov_write_ftyp_tag_internal
static void mov_write_ftyp_tag_internal(AVIOContext *pb, AVFormatContext *s, int has_h264, int has_video, int write_minor)
Definition: movenc.c:6127
mov_write_prft_tag
static int mov_write_prft_tag(AVIOContext *pb, MOVMuxContext *mov, int tracks)
Definition: movenc.c:5970
mov_write_fiel_tag
static int mov_write_fiel_tag(AVIOContext *pb, MOVTrack *track, int field_order)
Definition: movenc.c:2227
AV_OPT_TYPE_INT
@ AV_OPT_TYPE_INT
Underlying C type is int.
Definition: opt.h:259
av_channel_layout_uninit
void av_channel_layout_uninit(AVChannelLayout *channel_layout)
Free any allocated data in the channel layout and reset the channel count to 0.
Definition: channel_layout.c:443
ff_codec_get_tag
unsigned int ff_codec_get_tag(const AVCodecTag *tags, enum AVCodecID id)
Definition: utils.c:133
AVIO_DATA_MARKER_HEADER
@ AVIO_DATA_MARKER_HEADER
Header data; this needs to be present for the stream to be decodeable.
Definition: avio.h:114
MOVTrack::is_unaligned_qt_rgb
int is_unaligned_qt_rgb
Definition: movenc.h:184
av_packet_make_writable
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:515
mov_write_identification
static int mov_write_identification(AVIOContext *pb, AVFormatContext *s)
Definition: movenc.c:6361
mov_write_sidx_tags
static int mov_write_sidx_tags(AVIOContext *pb, MOVMuxContext *mov, int tracks, int ref_size)
Definition: movenc.c:5932
eac3_info::bsid
uint8_t bsid
Definition: movenc.c:398
MOVMuxContext::tracks
MOVTrack * tracks
Definition: movenc.h:220
AV_RB8
uint64_t_TMPL AV_WL64 unsigned int_TMPL AV_WL32 unsigned int_TMPL AV_WL24 unsigned int_TMPL AV_WL16 uint64_t_TMPL AV_WB64 unsigned int_TMPL AV_WB32 unsigned int_TMPL AV_WB24 unsigned int_TMPL AV_WB16 unsigned int_TMPL AV_RB8
Definition: bytestream.h:99
ref
static int ref[MAX_W *MAX_W]
Definition: jpeg2000dwt.c:117
AVPixFmtDescriptor::comp
AVComponentDescriptor comp[4]
Parameters that describe how pixels are packed.
Definition: pixdesc.h:105
MOVTrack::multichannel_as_mono
int multichannel_as_mono
Definition: movenc.h:127
mov_write_ilst_tag
static int mov_write_ilst_tag(AVIOContext *pb, MOVMuxContext *mov, AVFormatContext *s)
Definition: movenc.c:4784
mov_flush_fragment_interleaving
static int mov_flush_fragment_interleaving(AVFormatContext *s, MOVTrack *track)
Definition: movenc.c:6490
eac3_info::complexity_index_type_a
uint8_t complexity_index_type_a
Definition: movenc.c:415
mov_write_btrt_tag
static int mov_write_btrt_tag(AVIOContext *pb, MOVTrack *track)
Definition: movenc.c:1275
mov_write_glbl_tag
static int mov_write_glbl_tag(AVIOContext *pb, MOVTrack *track)
Definition: movenc.c:1198
AVStreamGroupLCEVC::width
int width
Width of the final stream for presentation.
Definition: avformat.h:1081
Windows::Graphics::DirectX::Direct3D11::p
IDirect3DDxgiInterfaceAccess _COM_Outptr_ void ** p
Definition: vsrc_gfxcapture_winrt.hpp:53
eac3_info::ec3_done
uint8_t ec3_done
Definition: movenc.c:385
mov_mdhd_mvhd_tkhd_version
static int mov_mdhd_mvhd_tkhd_version(MOVMuxContext *mov, MOVTrack *track, int64_t duration)
Definition: movenc.c:3892
ff_codec_movsubtitle_tags
const AVCodecTag ff_codec_movsubtitle_tags[]
Definition: isom.c:75
AVPacket::stream_index
int stream_index
Definition: packet.h:597
mov_write_mdia_tag
static int mov_write_mdia_tag(AVFormatContext *s, AVIOContext *pb, MOVMuxContext *mov, MOVTrack *track)
Definition: movenc.c:3938
av_clip_uint8
#define av_clip_uint8
Definition: common.h:106
avio_skip
int64_t avio_skip(AVIOContext *s, int64_t offset)
Skip given number of bytes forward.
Definition: aviobuf.c:321
AV_PIX_FMT_RGB565BE
@ AV_PIX_FMT_RGB565BE
packed RGB 5:6:5, 16bpp, (msb) 5R 6G 5B(lsb), big-endian
Definition: pixfmt.h:112
avio_wb64
void avio_wb64(AVIOContext *s, uint64_t val)
Definition: aviobuf.c:434
MOV_TRACK_ENABLED
#define MOV_TRACK_ENABLED
Definition: movenc.h:115
av_realloc
#define av_realloc(p, s)
Definition: ops_asmgen.c:46
mov_write_ispe_tag
static int mov_write_ispe_tag(AVIOContext *pb, MOVMuxContext *mov, AVFormatContext *s, int stream_index)
Definition: movenc.c:3708
AC3HeaderInfo::bitstream_id
uint8_t bitstream_id
Definition: ac3_parser_internal.h:41
AVMEDIA_TYPE_VIDEO
@ AVMEDIA_TYPE_VIDEO
Definition: avutil.h:200
ff_reshuffle_raw_rgb
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
AV_CODEC_ID_PCM_S32LE
@ AV_CODEC_ID_PCM_S32LE
Definition: codec_id.h:346
AVCodecParameters::bits_per_coded_sample
int bits_per_coded_sample
The number of bits per sample in the codedwords.
Definition: codec_par.h:113
AV_PIX_FMT_V30XLE
@ 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_YUV422P
@ AV_PIX_FMT_YUV422P
planar YUV 4:2:2, 16bpp, (1 Cr & Cb sample per 2x1 Y samples)
Definition: pixfmt.h:77
mov_write_sdtp_tag
static int mov_write_sdtp_tag(AVIOContext *pb, MOVTrack *track)
Definition: movenc.c:316
mem.h
AVStreamGroup::type
enum AVStreamGroupParamsType type
Group type.
Definition: avformat.h:1143
param_write_hex
static void param_write_hex(AVIOContext *pb, const char *name, const uint8_t *value, int len)
Definition: movenc.c:5401
MOVTrack::timescale
unsigned timescale
Definition: movenc.h:97
ff_ismv_muxer
const FFOutputFormat ff_ismv_muxer
mov_write_av1c_tag
static int mov_write_av1c_tag(AVIOContext *pb, MOVTrack *track)
Definition: movenc.c:1567
AV_CODEC_ID_PCM_U8
@ AV_CODEC_ID_PCM_U8
Definition: codec_id.h:343
AVSphericalMapping::bound_left
uint32_t bound_left
Distance from the left edge.
Definition: spherical.h:185
FFFormatContext::pkt
AVPacket * pkt
Used to hold temporary packets for the generic demuxing code.
Definition: internal.h:111
avpriv_request_sample
#define avpriv_request_sample(...)
Definition: tableprint_vlc.h:37
AVCodecParameters::format
int format
Definition: codec_par.h:94
flush_put_bits
static void flush_put_bits(PutBitContext *s)
Pad the end of the output stream with zeros.
Definition: put_bits.h:153
mov_write_uuidusmt_tag
static int mov_write_uuidusmt_tag(AVIOContext *pb, AVFormatContext *s)
Definition: movenc.c:5078
AVPixFmtDescriptor
Descriptor that unambiguously describes how the bits of a pixel are stored in the up to 4 data planes...
Definition: pixdesc.h:69
avio_wb24
void avio_wb24(AVIOContext *s, unsigned int val)
Definition: aviobuf.c:458
map
const VDPAUPixFmtMap * map
Definition: hwcontext_vdpau.c:71
MOVMuxContext::avif_loop_count
int avif_loop_count
Definition: movenc.h:274
AV_CHANNEL_LAYOUT_MONO
#define AV_CHANNEL_LAYOUT_MONO
Definition: channel_layout.h:394
mpeg4_bit_rate_values::max_bit_rate
uint32_t max_bit_rate
Maximum rate in bits/second over any window of one second.
Definition: movenc.c:716
AV_CODEC_ID_PCM_F64LE
@ AV_CODEC_ID_PCM_F64LE
Definition: codec_id.h:361
mov_write_dvcc_dvvc_tag
static int mov_write_dvcc_dvvc_tag(AVFormatContext *s, AVIOContext *pb, AVDOVIDecoderConfigurationRecord *dovi)
Definition: movenc.c:2516
mov_preroll_write_stbl_atoms
static int mov_preroll_write_stbl_atoms(AVIOContext *pb, MOVTrack *track)
Definition: movenc.c:3288
AVStereo3D::view
enum AVStereo3DView view
Determines which views are packed.
Definition: stereo3d.h:217
MOVMuxContext::major_brand
char * major_brand
Definition: movenc.h:243
AV_PROFILE_AAC_HE
#define AV_PROFILE_AAC_HE
Definition: defs.h:72
av_free
#define av_free(p)
Definition: tableprint_vlc.h:34
mov_write_chan_tag
static int mov_write_chan_tag(AVFormatContext *s, AVIOContext *pb, MOVTrack *track)
Definition: movenc.c:998
AVDictionaryEntry
Definition: dict.h:90
mov_write_st3d_tag
static int mov_write_st3d_tag(AVFormatContext *s, AVIOContext *pb, AVStereo3D *stereo_3d)
Definition: movenc.c:2285
MOVTrack::cluster_capacity
unsigned cluster_capacity
Definition: movenc.h:131
MOVMuxContext::write_btrt
int write_btrt
Definition: movenc.h:265
MOVIentry::stsd_index
unsigned int stsd_index
Definition: movenc.h:53
language_code
static uint16_t language_code(const char *str)
Definition: movenc.c:4952
AVCodecParameters::codec_id
enum AVCodecID codec_id
Specific type of the encoded data (the codec used).
Definition: codec_par.h:57
mov_write_ipma_tag
static int mov_write_ipma_tag(AVIOContext *pb, MOVMuxContext *mov, AVFormatContext *s)
Definition: movenc.c:3753
get_samples_per_packet
static int get_samples_per_packet(MOVTrack *track)
Definition: movenc.c:1256
MOV_ENC_CENC_AES_CTR
@ MOV_ENC_CENC_AES_CTR
Definition: movenc.h:200
mov_write_smhd_tag
static int mov_write_smhd_tag(AVIOContext *pb)
Definition: movenc.c:3521
AVContentLightMetadata::MaxFALL
unsigned MaxFALL
Max average light level per frame (cd/m^2).
Definition: mastering_display_metadata.h:116
AVPacket
This structure stores compressed data.
Definition: packet.h:572
MOVTrack::extradata
uint8_t ** extradata
Definition: movenc.h:105
cr
static double cr(void *priv, double x, double y)
Definition: vf_geq.c:248
AV_OPT_TYPE_BOOL
@ AV_OPT_TYPE_BOOL
Underlying C type is int.
Definition: opt.h:327
PIX_FMT_LIST_MOV
@ PIX_FMT_LIST_MOV
Definition: raw.h:40
AV_CODEC_ID_ADPCM_IMA_WAV
@ AV_CODEC_ID_ADPCM_IMA_WAV
Definition: codec_id.h:378
av_freep
#define av_freep(p)
Definition: tableprint_vlc.h:35
mov_write_source_reference_tag
static int mov_write_source_reference_tag(AVIOContext *pb, MOVTrack *track, const char *reel_name)
Definition: movenc.c:3068
ff_avif_muxer
const FFOutputFormat ff_avif_muxer
mov_parse_vc1_frame
static void mov_parse_vc1_frame(AVPacket *pkt, MOVTrack *trk)
Definition: movenc.c:6411
riff.h
MOV_TFHD_DURATION_IS_EMPTY
#define MOV_TFHD_DURATION_IS_EMPTY
Definition: isom.h:413
AV_CODEC_ID_ILBC
@ AV_CODEC_ID_ILBC
Definition: codec_id.h:519
AV_CHAN_AMBISONIC_BASE
@ AV_CHAN_AMBISONIC_BASE
Range of channels between AV_CHAN_AMBISONIC_BASE and AV_CHAN_AMBISONIC_END represent Ambisonic compon...
Definition: channel_layout.h:108
MOV_TRUN_SAMPLE_SIZE
#define MOV_TRUN_SAMPLE_SIZE
Definition: isom.h:419
ff_isom_init_apvc
int ff_isom_init_apvc(APVDecoderConfigurationRecord **papvc, void *logctx)
Definition: apv.c:352
AV_OPT_TYPE_FLAGS
@ AV_OPT_TYPE_FLAGS
Underlying C type is unsigned int.
Definition: opt.h:255
int32_t
int32_t
Definition: audioconvert.c:56
distance
static float distance(float x, float y, int band)
Definition: nellymoserenc.c:231
MOVTrack::eac3_priv
void * eac3_priv
Definition: movenc.h:177
mov_write_dops_tag
static int mov_write_dops_tag(AVFormatContext *s, AVIOContext *pb, MOVTrack *track)
Definition: movenc.c:877
mov_write_squashed_packet
static int mov_write_squashed_packet(AVFormatContext *s, MOVTrack *track)
Definition: movenc.c:6515
avio_wb16
void avio_wb16(AVIOContext *s, unsigned int val)
Definition: aviobuf.c:446
AV_CODEC_ID_VP8
@ AV_CODEC_ID_VP8
Definition: codec_id.h:192
mov_write_hmhd_tag
static int mov_write_hmhd_tag(AVIOContext *pb)
Definition: movenc.c:3787
AVERROR_BUG
#define AVERROR_BUG
Internal bug, also see AVERROR_BUG2.
Definition: error.h:52
rgb
static const SheerTable rgb[2]
Definition: sheervideodata.h:32
MP4TrackKindValueMapping::value
const char * value
Definition: isom.h:489
av_strlcpy
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
AV_CODEC_ID_PCM_F32LE
@ AV_CODEC_ID_PCM_F32LE
Definition: codec_id.h:359
param_write_string
static void param_write_string(AVIOContext *pb, const char *name, const char *value)
Definition: movenc.c:5396
AVCodecParameters::bit_rate
int64_t bit_rate
The average bitrate of the encoded data (in bits per second).
Definition: codec_par.h:99
mov_write_mdcv_tag
static int mov_write_mdcv_tag(AVIOContext *pb, MOVTrack *track)
Definition: movenc.c:2665
MOVStts::count
unsigned int count
Definition: isom.h:64
ttmlenc.h
av_log
#define av_log(a,...)
Definition: tableprint_vlc.h:27
mov_write_enda_tag_be
static int mov_write_enda_tag_be(AVIOContext *pb)
Definition: movenc.c:686
rescale_rational
static int64_t rescale_rational(AVRational q, int b)
Definition: movenc.c:2373
ff_isom_write_lhvc
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:1405
AVERROR_INVALIDDATA
#define AVERROR_INVALIDDATA
Invalid data found when processing input.
Definition: error.h:61
ff_mov_track_kind_table
const struct MP4TrackKindMapping ff_mov_track_kind_table[]
Definition: isom.c:451
MovTag::id
uint32_t * id
trackID of the referenced track
Definition: movenc.h:90
av_stereo3d_type_name
const char * av_stereo3d_type_name(unsigned int type)
Provide a human-readable name of a given stereo3d type.
Definition: stereo3d.c:92
MOVMuxContext::mdat_buf
AVIOContext * mdat_buf
Definition: movenc.h:235
mov_write_amr_tag
static int mov_write_amr_tag(AVIOContext *pb, MOVTrack *track)
Definition: movenc.c:369
mov_write_mdat_tag
static int mov_write_mdat_tag(AVIOContext *pb, MOVMuxContext *mov)
Definition: movenc.c:6116
MKTAG
#define MKTAG(a, b, c, d)
Definition: macros.h:55
av1.h
mov_write_tfrf_tag
static int mov_write_tfrf_tag(AVIOContext *pb, MOVMuxContext *mov, MOVTrack *track, int entry)
Definition: movenc.c:5690
AV_CODEC_ID_VORBIS
@ AV_CODEC_ID_VORBIS
Definition: codec_id.h:465
MOVTrack::default_duration
int64_t default_duration
Definition: movenc.h:151
AVFMT_AVOID_NEG_TS_AUTO
#define AVFMT_AVOID_NEG_TS_AUTO
Enabled when required by target format.
Definition: avformat.h:1669
av_timecode_init_from_string
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
AVStereo3D
Stereo 3D type: this structure describes how two videos are packed within a single video surface,...
Definition: stereo3d.h:203
AVDictionaryEntry::value
char * value
Definition: dict.h:92
avstring.h
ff_mov_cenc_avc_parse_nal_units
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
AV_OPT_TYPE_STRING
@ 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:276
width
#define width
Definition: dsp.h:89
AVAmbientViewingEnvironment::ambient_light_y
AVRational ambient_light_y
Normalized y chromaticity coordinate of the environmental ambient light in the nominal viewing enviro...
Definition: ambient_viewing_environment.h:54
flac.h
MOVTrack::frag_info_capacity
unsigned frag_info_capacity
Definition: movenc.h:165
AVTimecode
Definition: timecode.h:41
AV_RB24
uint64_t_TMPL AV_WL64 unsigned int_TMPL AV_WL32 unsigned int_TMPL AV_WL24 unsigned int_TMPL AV_WL16 uint64_t_TMPL AV_WB64 unsigned int_TMPL AV_WB32 unsigned int_TMPL AV_RB24
Definition: bytestream.h:97
AV_PIX_FMT_VYU444
@ AV_PIX_FMT_VYU444
packed VYU 4:4:4, 24bpp (1 Cr & Cb sample per 1x1 Y), VYUVYU...
Definition: pixfmt.h:446
av_bswap16
#define av_bswap16
Definition: bswap.h:28
ff_is_ttml_stream_paragraph_based
static unsigned int ff_is_ttml_stream_paragraph_based(const AVCodecParameters *codecpar)
Definition: ttmlenc.h:28
MOVTrack::first_iamf_idx
int first_iamf_idx
Definition: movenc.h:191
AVCodecTag::tag
unsigned int tag
Definition: internal.h:44
avio_put_str
int avio_put_str(AVIOContext *s, const char *str)
Write a NULL-terminated string.
Definition: aviobuf.c:376
put_bits.h
AV_CODEC_ID_MPEG2VIDEO
@ AV_CODEC_ID_MPEG2VIDEO
preferred ID for MPEG-1/2 video decoding
Definition: codec_id.h:54
AC3HeaderInfo::sr_code
uint8_t sr_code
Definition: ac3_parser_internal.h:40
MOV_TRUN_SAMPLE_CTS
#define MOV_TRUN_SAMPLE_CTS
Definition: isom.h:421
AV_OPT_TYPE_CONST
@ AV_OPT_TYPE_CONST
Special option type for declaring named constants.
Definition: opt.h:299
MOV_ISMV_TTML_TAG
#define MOV_ISMV_TTML_TAG
Definition: isom.h:482
snprintf
#define snprintf
Definition: snprintf.h:34
mov_add_tref_id
static int mov_add_tref_id(MOVMuxContext *mov, MovTag *tag, uint32_t id)
Definition: movenc.c:5237
mov_write_tfrf_tags
static int mov_write_tfrf_tags(AVIOContext *pb, MOVMuxContext *mov, MOVTrack *track)
Definition: movenc.c:5725
ff_stream_add_bitstream_filter
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
AV_PROFILE_AAC_USAC
#define AV_PROFILE_AAC_USAC
Definition: defs.h:76
AV_CODEC_ID_PCM_S24BE
@ AV_CODEC_ID_PCM_S24BE
Definition: codec_id.h:351
AC3HeaderInfo::bit_rate
uint32_t bit_rate
Definition: ac3_parser_internal.h:60
mov_find_codec_tag
static unsigned int mov_find_codec_tag(AVFormatContext *s, MOVTrack *track)
Definition: movenc.c:2188
MOVTrack::src_track
int * src_track
the tracks that this hint (or tmcd) track describes
Definition: movenc.h:145
AVSphericalMapping
This structure describes how to handle spherical videos, outlining information about projection,...
Definition: spherical.h:100
MOVMuxContext::moov_written
int moov_written
Definition: movenc.h:229
av_dict_iterate
const AVDictionaryEntry * av_dict_iterate(const AVDictionary *m, const AVDictionaryEntry *prev)
Iterate over a dictionary.
Definition: dict.c:42
AVPixFmtDescriptor::log2_chroma_h
uint8_t log2_chroma_h
Amount to shift the luma height right to find the chroma height.
Definition: pixdesc.h:89
mov_write_tfxd_tag
static int mov_write_tfxd_tag(AVIOContext *pb, MOVTrack *track)
Definition: movenc.c:5670
MOV_PARTIAL_SYNC_SAMPLE
#define MOV_PARTIAL_SYNC_SAMPLE
Definition: movenc.h:59
AVSphericalMapping::yaw
int32_t yaw
Rotation around the up vector [-180, 180].
Definition: spherical.h:144
MOVTrack::tref_tags
MovTag * tref_tags
Definition: movenc.h:135
AV_CODEC_ID_DNXHD
@ AV_CODEC_ID_DNXHD
Definition: codec_id.h:151
MOVTrack::default_size
uint32_t default_size
Definition: movenc.h:153
ff_f4v_muxer
const FFOutputFormat ff_f4v_muxer
mov_write_clli_tag
static int mov_write_clli_tag(AVIOContext *pb, MOVTrack *track)
Definition: movenc.c:2645
FF_API_V408_CODECID
#define FF_API_V408_CODECID
Definition: version_major.h:42
MOVMuxContext::gamma
float gamma
Definition: movenc.h:251
AVPacket::side_data_elems
int side_data_elems
Definition: packet.h:607
av_get_pix_fmt_name
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:3376
ff_hevc_annexb2mp4
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:1201
AV_RB16
uint64_t_TMPL AV_WL64 unsigned int_TMPL AV_WL32 unsigned int_TMPL AV_WL24 unsigned int_TMPL AV_WL16 uint64_t_TMPL AV_WB64 unsigned int_TMPL AV_WB32 unsigned int_TMPL AV_WB24 unsigned int_TMPL AV_RB16
Definition: bytestream.h:98
MOVTrack::nb_frag_info
int nb_frag_info
Definition: movenc.h:163
iamf_writer.h
av_fourcc2str
#define av_fourcc2str(fourcc)
Definition: avutil.h:347
mov_write_dfla_tag
static int mov_write_dfla_tag(AVIOContext *pb, MOVTrack *track)
Definition: movenc.c:857
MP4TrackKindMapping
Definition: isom.h:492
ff_alloc_extradata
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
AVDOVIDecoderConfigurationRecord
Definition: dovi_meta.h:55
mov_write_sidx_tag
static int mov_write_sidx_tag(AVIOContext *pb, MOVTrack *track, int ref_size, int total_sidx_size)
Definition: movenc.c:5871
AVIO_DATA_MARKER_FLUSH_POINT
@ 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
mux.h
eac3_info::fscod
uint8_t fscod
Definition: movenc.c:396
MOVIentry::samples_in_chunk
unsigned int samples_in_chunk
Definition: movenc.h:54