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