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 
1693 static int mov_write_lvcc_tag(AVIOContext *pb, MOVTrack *track)
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]);
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(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  return AVERROR_INVALIDDATA;
3350  if (i && distance == sgpd_entries[entries].roll_distance) {
3351  sgpd_entries[entries].count++;
3352  } else {
3353  entries++;
3354  sgpd_entries[entries].count = 1;
3355  sgpd_entries[entries].roll_distance = distance;
3356  sgpd_entries[entries].group_description_index = distance ? ++group : 0;
3357  }
3358  }
3359  } else {
3360  entries++;
3361  sgpd_entries[entries].count = track->sample_count;
3362  sgpd_entries[entries].roll_distance = 1;
3363  sgpd_entries[entries].group_description_index = ++group;
3364  }
3365  entries++;
3366 
3367  if (!group) {
3368  av_free(sgpd_entries);
3369  return 0;
3370  }
3371 
3372  /* Write sgpd tag */
3373  avio_wb32(pb, 24 + (group * 2)); /* size */
3374  ffio_wfourcc(pb, "sgpd");
3375  avio_wb32(pb, 1 << 24); /* fullbox */
3376  ffio_wfourcc(pb, "roll");
3377  avio_wb32(pb, 2); /* default_length */
3378  avio_wb32(pb, group); /* entry_count */
3379  for (i = 0; i < entries; i++) {
3380  if (sgpd_entries[i].group_description_index) {
3381  avio_wb16(pb, -sgpd_entries[i].roll_distance); /* roll_distance */
3382  }
3383  }
3384 
3385  /* Write sbgp tag */
3386  avio_wb32(pb, 20 + (entries * 8)); /* size */
3387  ffio_wfourcc(pb, "sbgp");
3388  avio_wb32(pb, 0); /* fullbox */
3389  ffio_wfourcc(pb, "roll");
3390  avio_wb32(pb, entries); /* entry_count */
3391  for (i = 0; i < entries; i++) {
3392  avio_wb32(pb, sgpd_entries[i].count); /* sample_count */
3393  avio_wb32(pb, sgpd_entries[i].group_description_index); /* group_description_index */
3394  }
3395 
3396  av_free(sgpd_entries);
3397  return 0;
3398 }
3399 
3401 {
3402  int64_t pos = avio_tell(pb);
3403  int ret = 0;
3404 
3405  avio_wb32(pb, 0); /* size */
3406  ffio_wfourcc(pb, "stbl");
3407  if ((ret = mov_write_stsd_tag(s, pb, mov, track)) < 0)
3408  return ret;
3409  mov_write_stts_tag(pb, track);
3410  if ((track->par->codec_type == AVMEDIA_TYPE_VIDEO ||
3411  track->par->codec_id == AV_CODEC_ID_TRUEHD ||
3413  (track->par->codec_id == AV_CODEC_ID_AAC && track->par->profile == AV_PROFILE_AAC_USAC) ||
3414  track->par->codec_tag == MKTAG('r','t','p',' ')) &&
3415  track->has_keyframes && track->has_keyframes < track->entry)
3416  mov_write_stss_tag(pb, track, MOV_SYNC_SAMPLE);
3417  if (track->par->codec_type == AVMEDIA_TYPE_VIDEO && track->has_disposable && track->entry)
3418  mov_write_sdtp_tag(pb, track);
3419  if (track->mode == MODE_MOV && track->flags & MOV_TRACK_STPS)
3421  if (track->par->codec_type == AVMEDIA_TYPE_VIDEO &&
3422  track->flags & MOV_TRACK_CTTS && track->entry) {
3423 
3424  if ((ret = mov_write_ctts_tag(s, pb, track)) < 0)
3425  return ret;
3426  }
3427  mov_write_stsc_tag(pb, track);
3428  mov_write_stsz_tag(pb, track);
3429  mov_write_stco_tag(pb, track);
3430  if (track->cenc.aes_ctr && !(mov->flags & FF_MOV_FLAG_FRAGMENT)) {
3431  ff_mov_cenc_write_stbl_atoms(&track->cenc, pb, 0);
3432  }
3433  if (track->par->codec_id == AV_CODEC_ID_OPUS || track->par->codec_id == AV_CODEC_ID_AAC) {
3434  mov_preroll_write_stbl_atoms(pb, track);
3435  }
3436  return update_size(pb, pos);
3437 }
3438 
3440 {
3441  int64_t pos = avio_tell(pb);
3442  avio_wb32(pb, 0); /* size */
3443  ffio_wfourcc(pb, "dinf");
3444  mov_write_dref_tag(pb);
3445  return update_size(pb, pos);
3446 }
3447 
3449 {
3450  avio_wb32(pb, 12);
3451  ffio_wfourcc(pb, "nmhd");
3452  avio_wb32(pb, 0);
3453  return 12;
3454 }
3455 
3457 {
3458  avio_wb32(pb, 12);
3459  ffio_wfourcc(pb, "sthd");
3460  avio_wb32(pb, 0);
3461  return 12;
3462 }
3463 
3464 static int mov_write_tcmi_tag(AVIOContext *pb, MOVTrack *track)
3465 {
3466  int64_t pos = avio_tell(pb);
3467  const char *font = "Lucida Grande";
3468  avio_wb32(pb, 0); /* size */
3469  ffio_wfourcc(pb, "tcmi"); /* timecode media information atom */
3470  avio_wb32(pb, 0); /* version & flags */
3471  avio_wb16(pb, 0); /* text font */
3472  avio_wb16(pb, 0); /* text face */
3473  avio_wb16(pb, 12); /* text size */
3474  avio_wb16(pb, 0); /* (unknown, not in the QT specs...) */
3475  avio_wb16(pb, 0x0000); /* text color (red) */
3476  avio_wb16(pb, 0x0000); /* text color (green) */
3477  avio_wb16(pb, 0x0000); /* text color (blue) */
3478  avio_wb16(pb, 0xffff); /* background color (red) */
3479  avio_wb16(pb, 0xffff); /* background color (green) */
3480  avio_wb16(pb, 0xffff); /* background color (blue) */
3481  avio_w8(pb, strlen(font)); /* font len (part of the pascal string) */
3482  avio_write(pb, font, strlen(font)); /* font name */
3483  return update_size(pb, pos);
3484 }
3485 
3486 static int mov_write_gmhd_tag(AVIOContext *pb, MOVTrack *track)
3487 {
3488  int64_t pos = avio_tell(pb);
3489  avio_wb32(pb, 0); /* size */
3490  ffio_wfourcc(pb, "gmhd");
3491  avio_wb32(pb, 0x18); /* gmin size */
3492  ffio_wfourcc(pb, "gmin");/* generic media info */
3493  avio_wb32(pb, 0); /* version & flags */
3494  avio_wb16(pb, 0x40); /* graphics mode = */
3495  avio_wb16(pb, 0x8000); /* opColor (r?) */
3496  avio_wb16(pb, 0x8000); /* opColor (g?) */
3497  avio_wb16(pb, 0x8000); /* opColor (b?) */
3498  avio_wb16(pb, 0); /* balance */
3499  avio_wb16(pb, 0); /* reserved */
3500 
3501  /*
3502  * This special text atom is required for
3503  * Apple Quicktime chapters. The contents
3504  * don't appear to be documented, so the
3505  * bytes are copied verbatim.
3506  */
3507  if (track->tag != MKTAG('c','6','0','8')) {
3508  avio_wb32(pb, 0x2C); /* size */
3509  ffio_wfourcc(pb, "text");
3510  avio_wb16(pb, 0x01);
3511  avio_wb32(pb, 0x00);
3512  avio_wb32(pb, 0x00);
3513  avio_wb32(pb, 0x00);
3514  avio_wb32(pb, 0x01);
3515  avio_wb32(pb, 0x00);
3516  avio_wb32(pb, 0x00);
3517  avio_wb32(pb, 0x00);
3518  avio_wb32(pb, 0x00004000);
3519  avio_wb16(pb, 0x0000);
3520  }
3521 
3522  if (track->par->codec_tag == MKTAG('t','m','c','d')) {
3523  int64_t tmcd_pos = avio_tell(pb);
3524  avio_wb32(pb, 0); /* size */
3525  ffio_wfourcc(pb, "tmcd");
3526  mov_write_tcmi_tag(pb, track);
3527  update_size(pb, tmcd_pos);
3528  } else if (track->par->codec_tag == MKTAG('g','p','m','d')) {
3529  int64_t gpmd_pos = avio_tell(pb);
3530  avio_wb32(pb, 0); /* size */
3531  ffio_wfourcc(pb, "gpmd");
3532  avio_wb32(pb, 0); /* version */
3533  update_size(pb, gpmd_pos);
3534  }
3535  return update_size(pb, pos);
3536 }
3537 
3539 {
3540  avio_wb32(pb, 16); /* size */
3541  ffio_wfourcc(pb, "smhd");
3542  avio_wb32(pb, 0); /* version & flags */
3543  avio_wb16(pb, 0); /* reserved (balance, normally = 0) */
3544  avio_wb16(pb, 0); /* reserved */
3545  return 16;
3546 }
3547 
3549 {
3550  avio_wb32(pb, 0x14); /* size (always 0x14) */
3551  ffio_wfourcc(pb, "vmhd");
3552  avio_wb32(pb, 0x01); /* version & flags */
3553  avio_wb64(pb, 0); /* reserved (graphics mode = copy) */
3554  return 0x14;
3555 }
3556 
3557 static int is_clcp_track(MOVTrack *track)
3558 {
3559  return track->tag == MKTAG('c','7','0','8') ||
3560  track->tag == MKTAG('c','6','0','8');
3561 }
3562 
3564 {
3565  MOVMuxContext *mov = s->priv_data;
3566  const char *hdlr, *descr = NULL, *hdlr_type = NULL;
3567  int64_t pos = avio_tell(pb);
3568  size_t descr_len;
3569 
3570  hdlr = "dhlr";
3571  hdlr_type = "url ";
3572  descr = "DataHandler";
3573 
3574  if (track) {
3575  hdlr = (track->mode == MODE_MOV) ? "mhlr" : "\0\0\0\0";
3576  if (track->par->codec_type == AVMEDIA_TYPE_VIDEO) {
3577  if (track->mode == MODE_AVIF) {
3578  hdlr_type = (track == &mov->tracks[0]) ? "pict" : "auxv";
3579  descr = "PictureHandler";
3580  } else {
3581  hdlr_type = "vide";
3582  descr = "VideoHandler";
3583  }
3584  } else if (track->par->codec_type == AVMEDIA_TYPE_AUDIO) {
3585  hdlr_type = "soun";
3586  descr = "SoundHandler";
3587  } else if (track->par->codec_type == AVMEDIA_TYPE_SUBTITLE) {
3588  if (is_clcp_track(track)) {
3589  hdlr_type = "clcp";
3590  descr = "ClosedCaptionHandler";
3591  } else {
3592  if (track->tag == MKTAG('t','x','3','g')) {
3593  hdlr_type = "sbtl";
3594  } else if (track->tag == MKTAG('m','p','4','s')) {
3595  hdlr_type = "subp";
3596  } else if (track->tag == MOV_MP4_TTML_TAG) {
3597  hdlr_type = "subt";
3598  } else {
3599  hdlr_type = "text";
3600  }
3601  descr = "SubtitleHandler";
3602  }
3603  } else if (track->par->codec_tag == MKTAG('r','t','p',' ')) {
3604  hdlr_type = "hint";
3605  descr = "HintHandler";
3606  } else if (track->par->codec_tag == MKTAG('t','m','c','d')) {
3607  hdlr_type = "tmcd";
3608  descr = "TimeCodeHandler";
3609  } else if (track->par->codec_tag == MKTAG('g','p','m','d')) {
3610  hdlr_type = "meta";
3611  descr = "GoPro MET"; // GoPro Metadata
3612  } else {
3614  "Unknown hdlr_type for %s, writing dummy values\n",
3615  av_fourcc2str(track->par->codec_tag));
3616  }
3617  if (track->st) {
3618  // hdlr.name is used by some players to identify the content title
3619  // of the track. So if an alternate handler description is
3620  // specified, use it.
3621  AVDictionaryEntry *t;
3622  t = av_dict_get(track->st->metadata, "handler_name", NULL, 0);
3623  if (t && utf8len(t->value))
3624  descr = t->value;
3625  }
3626  }
3627 
3628  if (mov->empty_hdlr_name) /* expressly allowed by QTFF and not prohibited in ISO 14496-12 8.4.3.3 */
3629  descr = "";
3630 
3631  avio_wb32(pb, 0); /* size */
3632  ffio_wfourcc(pb, "hdlr");
3633  avio_wb32(pb, 0); /* Version & flags */
3634  avio_write(pb, hdlr, 4); /* handler */
3635  ffio_wfourcc(pb, hdlr_type); /* handler type */
3636  avio_wb32(pb, 0); /* reserved */
3637  avio_wb32(pb, 0); /* reserved */
3638  avio_wb32(pb, 0); /* reserved */
3639  descr_len = strlen(descr);
3640  if (!track || track->mode == MODE_MOV)
3641  avio_w8(pb, descr_len); /* pascal string */
3642  avio_write(pb, descr, descr_len); /* handler description */
3643  if (track && track->mode != MODE_MOV)
3644  avio_w8(pb, 0); /* c string */
3645  return update_size(pb, pos);
3646 }
3647 
3648 static int mov_write_pitm_tag(AVIOContext *pb, int item_id)
3649 {
3650  int64_t pos = avio_tell(pb);
3651  avio_wb32(pb, 0); /* size */
3652  ffio_wfourcc(pb, "pitm");
3653  avio_wb32(pb, 0); /* Version & flags */
3654  avio_wb16(pb, item_id); /* item_id */
3655  return update_size(pb, pos);
3656 }
3657 
3659 {
3660  int64_t pos = avio_tell(pb);
3661  avio_wb32(pb, 0); /* size */
3662  ffio_wfourcc(pb, "iloc");
3663  avio_wb32(pb, 0); /* Version & flags */
3664  avio_w8(pb, (4 << 4) + 4); /* offset_size(4) and length_size(4) */
3665  avio_w8(pb, 0); /* base_offset_size(4) and reserved(4) */
3666  avio_wb16(pb, mov->nb_streams); /* item_count */
3667 
3668  for (int i = 0; i < mov->nb_streams; i++) {
3669  avio_wb16(pb, i + 1); /* item_id */
3670  avio_wb16(pb, 0); /* data_reference_index */
3671  avio_wb16(pb, 1); /* extent_count */
3672  mov->avif_extent_pos[i] = avio_tell(pb);
3673  avio_wb32(pb, 0); /* extent_offset (written later) */
3674  // For animated AVIF, we simply write the first packet's size.
3675  avio_wb32(pb, mov->avif_extent_length[i]); /* extent_length */
3676  }
3677 
3678  return update_size(pb, pos);
3679 }
3680 
3682 {
3683  int64_t iinf_pos = avio_tell(pb);
3684  avio_wb32(pb, 0); /* size */
3685  ffio_wfourcc(pb, "iinf");
3686  avio_wb32(pb, 0); /* Version & flags */
3687  avio_wb16(pb, mov->nb_streams); /* entry_count */
3688 
3689  for (int i = 0; i < mov->nb_streams; i++) {
3690  int64_t infe_pos = avio_tell(pb);
3691  avio_wb32(pb, 0); /* size */
3692  ffio_wfourcc(pb, "infe");
3693  avio_w8(pb, 0x2); /* Version */
3694  avio_wb24(pb, 0); /* flags */
3695  avio_wb16(pb, i + 1); /* item_id */
3696  avio_wb16(pb, 0); /* item_protection_index */
3697  avio_write(pb, "av01", 4); /* item_type */
3698  avio_write(pb, !i ? "Color\0" : "Alpha\0", 6); /* item_name */
3699  update_size(pb, infe_pos);
3700  }
3701 
3702  return update_size(pb, iinf_pos);
3703 }
3704 
3705 
3707 {
3708  int64_t auxl_pos;
3709  int64_t iref_pos = avio_tell(pb);
3710  avio_wb32(pb, 0); /* size */
3711  ffio_wfourcc(pb, "iref");
3712  avio_wb32(pb, 0); /* Version & flags */
3713 
3714  auxl_pos = avio_tell(pb);
3715  avio_wb32(pb, 0); /* size */
3716  ffio_wfourcc(pb, "auxl");
3717  avio_wb16(pb, 2); /* from_item_ID */
3718  avio_wb16(pb, 1); /* reference_count */
3719  avio_wb16(pb, 1); /* to_item_ID */
3720  update_size(pb, auxl_pos);
3721 
3722  return update_size(pb, iref_pos);
3723 }
3724 
3726  int stream_index)
3727 {
3728  int64_t pos = avio_tell(pb);
3729  avio_wb32(pb, 0); /* size */
3730  ffio_wfourcc(pb, "ispe");
3731  avio_wb32(pb, 0); /* Version & flags */
3732  avio_wb32(pb, s->streams[stream_index]->codecpar->width); /* image_width */
3733  avio_wb32(pb, s->streams[stream_index]->codecpar->height); /* image_height */
3734  return update_size(pb, pos);
3735 }
3736 
3738  int stream_index)
3739 {
3740  int64_t pos = avio_tell(pb);
3741  const AVPixFmtDescriptor *pixdesc =
3742  av_pix_fmt_desc_get(s->streams[stream_index]->codecpar->format);
3743  avio_wb32(pb, 0); /* size */
3744  ffio_wfourcc(pb, "pixi");
3745  avio_wb32(pb, 0); /* Version & flags */
3746  avio_w8(pb, pixdesc->nb_components); /* num_channels */
3747  for (int i = 0; i < pixdesc->nb_components; ++i) {
3748  avio_w8(pb, pixdesc->comp[i].depth); /* bits_per_channel */
3749  }
3750  return update_size(pb, pos);
3751 }
3752 
3754 {
3755  int64_t pos = avio_tell(pb);
3756  avio_wb32(pb, 0); /* size */
3757  ffio_wfourcc(pb, "ipco");
3758  for (int i = 0; i < mov->nb_streams; i++) {
3759  mov_write_ispe_tag(pb, mov, s, i);
3760  mov_write_pixi_tag(pb, mov, s, i);
3761  mov_write_av1c_tag(pb, &mov->tracks[i]);
3762  if (!i)
3763  mov_write_colr_tag(pb, &mov->tracks[0], 0);
3764  else
3765  mov_write_aux_tag(pb, "auxC");
3766  }
3767  return update_size(pb, pos);
3768 }
3769 
3771 {
3772  int64_t pos = avio_tell(pb);
3773  avio_wb32(pb, 0); /* size */
3774  ffio_wfourcc(pb, "ipma");
3775  avio_wb32(pb, 0); /* Version & flags */
3776  avio_wb32(pb, mov->nb_streams); /* entry_count */
3777 
3778  for (int i = 0, index = 1; i < mov->nb_streams; i++) {
3779  avio_wb16(pb, i + 1); /* item_ID */
3780  avio_w8(pb, 4); /* association_count */
3781 
3782  // ispe association.
3783  avio_w8(pb, index++); /* essential and property_index */
3784  // pixi association.
3785  avio_w8(pb, index++); /* essential and property_index */
3786  // av1C association.
3787  avio_w8(pb, 0x80 | index++); /* essential and property_index */
3788  // colr/auxC association.
3789  avio_w8(pb, index++); /* essential and property_index */
3790  }
3791  return update_size(pb, pos);
3792 }
3793 
3795 {
3796  int64_t pos = avio_tell(pb);
3797  avio_wb32(pb, 0); /* size */
3798  ffio_wfourcc(pb, "iprp");
3799  mov_write_ipco_tag(pb, mov, s);
3800  mov_write_ipma_tag(pb, mov, s);
3801  return update_size(pb, pos);
3802 }
3803 
3805 {
3806  /* This atom must be present, but leaving the values at zero
3807  * seems harmless. */
3808  avio_wb32(pb, 28); /* size */
3809  ffio_wfourcc(pb, "hmhd");
3810  avio_wb32(pb, 0); /* version, flags */
3811  avio_wb16(pb, 0); /* maxPDUsize */
3812  avio_wb16(pb, 0); /* avgPDUsize */
3813  avio_wb32(pb, 0); /* maxbitrate */
3814  avio_wb32(pb, 0); /* avgbitrate */
3815  avio_wb32(pb, 0); /* reserved */
3816  return 28;
3817 }
3818 
3820 {
3821  int64_t pos = avio_tell(pb);
3822  int ret;
3823 
3824  avio_wb32(pb, 0); /* size */
3825  ffio_wfourcc(pb, "minf");
3826  if (track->par->codec_type == AVMEDIA_TYPE_VIDEO)
3827  mov_write_vmhd_tag(pb);
3828  else if (track->par->codec_type == AVMEDIA_TYPE_AUDIO)
3829  mov_write_smhd_tag(pb);
3830  else if (track->par->codec_type == AVMEDIA_TYPE_SUBTITLE) {
3831  if (track->tag == MKTAG('t','e','x','t') || is_clcp_track(track)) {
3832  mov_write_gmhd_tag(pb, track);
3833  } else if (track->tag == MOV_MP4_TTML_TAG) {
3834  mov_write_sthd_tag(pb);
3835  } else {
3836  mov_write_nmhd_tag(pb);
3837  }
3838  } else if (track->tag == MKTAG('r','t','p',' ')) {
3839  mov_write_hmhd_tag(pb);
3840  } else if (track->tag == MKTAG('t','m','c','d')) {
3841  if (track->mode != MODE_MOV)
3842  mov_write_nmhd_tag(pb);
3843  else
3844  mov_write_gmhd_tag(pb, track);
3845  } else if (track->tag == MKTAG('g','p','m','d')) {
3846  mov_write_gmhd_tag(pb, track);
3847  }
3848  if (track->mode == MODE_MOV) /* ISO 14496-12 8.4.3.1 specifies hdlr only within mdia or meta boxes */
3849  mov_write_hdlr_tag(s, pb, NULL);
3850  mov_write_dinf_tag(pb);
3851  if ((ret = mov_write_stbl_tag(s, pb, mov, track)) < 0)
3852  return ret;
3853  return update_size(pb, pos);
3854 }
3855 
3856 static void get_pts_range(MOVMuxContext *mov, MOVTrack *track,
3857  int64_t *start, int64_t *end, int elst, int mdhd)
3858 {
3859  if (track->tag == MKTAG('t','m','c','d') && mov->nb_meta_tmcd && track->nb_src_track) {
3860  // tmcd tracks gets track_duration set in mov_write_moov_tag from
3861  // another track's duration, while the end_pts may be left at zero.
3862  // Calculate the pts duration for that track instead.
3863  get_pts_range(mov, &mov->tracks[*track->src_track], start, end, elst, mdhd);
3864  *start = av_rescale(*start, track->timescale,
3865  mov->tracks[*track->src_track].timescale);
3866  *end = av_rescale(*end, track->timescale,
3867  mov->tracks[*track->src_track].timescale);
3868  return;
3869  }
3870  if (!mdhd && track->end_pts != AV_NOPTS_VALUE &&
3871  track->start_dts != AV_NOPTS_VALUE &&
3872  track->start_cts != AV_NOPTS_VALUE) {
3873  *start = track->start_dts + track->start_cts;
3874  *end = elst ? track->elst_end_pts : track->end_pts;
3875  return;
3876  }
3877  *start = 0;
3878  *end = track->track_duration;
3879 }
3880 
3882 {
3883  int64_t start, end;
3884  get_pts_range(mov, track, &start, &end, 0, 1);
3885  return end - start;
3886 }
3887 
3888 // Calculate the actual duration of the track, after edits.
3889 // If it starts with a pts < 0, that is removed by the edit list.
3890 // If it starts with a pts > 0, the edit list adds a delay before that.
3891 // Thus, with edit lists enabled, the post-edit output of the file is
3892 // starting with pts=0.
3894 {
3895  int64_t start, end;
3896  get_pts_range(mov, track, &start, &end, 0, 0);
3897  if (mov->use_editlist != 0)
3898  start = 0;
3899  return end - start;
3900 }
3901 
3903 {
3904  int64_t start, end;
3905  get_pts_range(mov, track, &start, &end, 1, 0);
3906  return end - start;
3907 }
3908 
3910 {
3911  if (track && track->mode == MODE_ISM)
3912  return 1;
3913  if (duration < INT32_MAX)
3914  return 0;
3915  return 1;
3916 }
3917 
3919  MOVTrack *track)
3920 {
3922  int version = mov_mdhd_mvhd_tkhd_version(mov, track, duration);
3923 
3924  (version == 1) ? avio_wb32(pb, 44) : avio_wb32(pb, 32); /* size */
3925  ffio_wfourcc(pb, "mdhd");
3926  avio_w8(pb, version);
3927  avio_wb24(pb, 0); /* flags */
3928  if (version == 1) {
3929  avio_wb64(pb, track->time);
3930  avio_wb64(pb, track->time);
3931  } else {
3932  avio_wb32(pb, track->time); /* creation time */
3933  avio_wb32(pb, track->time); /* modification time */
3934  }
3935  avio_wb32(pb, track->timescale); /* time scale (sample rate for audio) */
3936  if (!track->entry && mov->mode == MODE_ISM)
3937  (version == 1) ? avio_wb64(pb, UINT64_C(0xffffffffffffffff)) : avio_wb32(pb, 0xffffffff);
3938  else if (!track->entry)
3939  (version == 1) ? avio_wb64(pb, 0) : avio_wb32(pb, 0);
3940  else
3941  (version == 1) ? avio_wb64(pb, duration) : avio_wb32(pb, duration); /* duration */
3942  avio_wb16(pb, track->language); /* language */
3943  avio_wb16(pb, 0); /* reserved (quality) */
3944 
3945  if (version != 0 && track->mode == MODE_MOV) {
3947  "FATAL error, file duration too long for timebase, this file will not be\n"
3948  "playable with QuickTime. Choose a different timebase with "
3949  "-video_track_timescale or a different container format\n");
3950  }
3951 
3952  return 32;
3953 }
3954 
3956  MOVMuxContext *mov, MOVTrack *track)
3957 {
3958  int64_t pos = avio_tell(pb);
3959  int ret;
3960 
3961  avio_wb32(pb, 0); /* size */
3962  ffio_wfourcc(pb, "mdia");
3963  mov_write_mdhd_tag(pb, mov, track);
3964  mov_write_hdlr_tag(s, pb, track);
3965  if ((ret = mov_write_minf_tag(s, pb, mov, track)) < 0)
3966  return ret;
3967  return update_size(pb, pos);
3968 }
3969 
3970 /* transformation matrix
3971  |a b u|
3972  |c d v|
3973  |tx ty w| */
3974 static void write_matrix(AVIOContext *pb, int16_t a, int16_t b, int16_t c,
3975  int16_t d, int16_t tx, int16_t ty)
3976 {
3977  avio_wb32(pb, a << 16); /* 16.16 format */
3978  avio_wb32(pb, b << 16); /* 16.16 format */
3979  avio_wb32(pb, 0); /* u in 2.30 format */
3980  avio_wb32(pb, c << 16); /* 16.16 format */
3981  avio_wb32(pb, d << 16); /* 16.16 format */
3982  avio_wb32(pb, 0); /* v in 2.30 format */
3983  avio_wb32(pb, tx << 16); /* 16.16 format */
3984  avio_wb32(pb, ty << 16); /* 16.16 format */
3985  avio_wb32(pb, 1 << 30); /* w in 2.30 format */
3986 }
3987 
3989  MOVTrack *track, AVStream *st)
3990 {
3992  mov->movie_timescale, track->timescale,
3993  AV_ROUND_UP);
3994  int version;
3996  int group = 0;
3997 
3998  uint32_t *display_matrix = NULL;
3999  int i;
4000 
4001  if (mov->mode == MODE_AVIF)
4002  if (!mov->avif_loop_count)
4003  duration = INT64_MAX;
4004  else
4005  duration *= mov->avif_loop_count;
4006 
4007  if (st) {
4008  const AVPacketSideData *sd;
4009  if (mov->per_stream_grouping)
4010  group = st->index;
4011  else
4012  group = st->codecpar->codec_type;
4013 
4017  if (sd && sd->size == 9 * sizeof(*display_matrix))
4018  display_matrix = (uint32_t *)sd->data;
4019  }
4020 
4021  if (track->flags & MOV_TRACK_ENABLED)
4023 
4025 
4026  (version == 1) ? avio_wb32(pb, 104) : avio_wb32(pb, 92); /* size */
4027  ffio_wfourcc(pb, "tkhd");
4028  avio_w8(pb, version);
4029  avio_wb24(pb, flags);
4030  if (version == 1) {
4031  avio_wb64(pb, track->time);
4032  avio_wb64(pb, track->time);
4033  } else {
4034  avio_wb32(pb, track->time); /* creation time */
4035  avio_wb32(pb, track->time); /* modification time */
4036  }
4037  avio_wb32(pb, track->track_id); /* track-id */
4038  avio_wb32(pb, 0); /* reserved */
4039  if (!track->entry && mov->mode == MODE_ISM)
4040  (version == 1) ? avio_wb64(pb, UINT64_C(0xffffffffffffffff)) : avio_wb32(pb, 0xffffffff);
4041  else if (!track->entry)
4042  (version == 1) ? avio_wb64(pb, 0) : avio_wb32(pb, 0);
4043  else
4044  (version == 1) ? avio_wb64(pb, duration) : avio_wb32(pb, duration);
4045 
4046  avio_wb32(pb, 0); /* reserved */
4047  avio_wb32(pb, 0); /* reserved */
4048  avio_wb16(pb, 0); /* layer */
4049  avio_wb16(pb, group); /* alternate group) */
4050  /* Volume, only for audio */
4051  if (track->par->codec_type == AVMEDIA_TYPE_AUDIO)
4052  avio_wb16(pb, 0x0100);
4053  else
4054  avio_wb16(pb, 0);
4055  avio_wb16(pb, 0); /* reserved */
4056 
4057  /* Matrix structure */
4058  if (display_matrix) {
4059  for (i = 0; i < 9; i++)
4060  avio_wb32(pb, display_matrix[i]);
4061  } else {
4062  write_matrix(pb, 1, 0, 0, 1, 0, 0);
4063  }
4064  /* Track width and height, for visual only */
4065  if (st && (track->par->codec_type == AVMEDIA_TYPE_VIDEO ||
4066  track->par->codec_type == AVMEDIA_TYPE_SUBTITLE)) {
4067  int64_t track_width_1616;
4068  if (track->mode == MODE_MOV || track->mode == MODE_AVIF) {
4069  track_width_1616 = track->par->width * 0x10000ULL;
4070  } else {
4071  track_width_1616 = av_rescale(st->sample_aspect_ratio.num,
4072  track->par->width * 0x10000LL,
4073  st->sample_aspect_ratio.den);
4074  if (!track_width_1616 ||
4075  track->height != track->par->height ||
4076  track_width_1616 > UINT32_MAX)
4077  track_width_1616 = track->par->width * 0x10000ULL;
4078  }
4079  if (track_width_1616 > UINT32_MAX) {
4080  av_log(mov->fc, AV_LOG_WARNING, "track width is too large\n");
4081  track_width_1616 = 0;
4082  }
4083  avio_wb32(pb, track_width_1616);
4084  if (track->height > 0xFFFF) {
4085  av_log(mov->fc, AV_LOG_WARNING, "track height is too large\n");
4086  avio_wb32(pb, 0);
4087  } else
4088  avio_wb32(pb, track->height * 0x10000U);
4089  } else {
4090  avio_wb32(pb, 0);
4091  avio_wb32(pb, 0);
4092  }
4093  return 0x5c;
4094 }
4095 
4096 static int mov_write_tapt_tag(AVIOContext *pb, MOVTrack *track)
4097 {
4099  track->par->sample_aspect_ratio.den);
4100 
4101  int64_t pos = avio_tell(pb);
4102 
4103  avio_wb32(pb, 0); /* size */
4104  ffio_wfourcc(pb, "tapt");
4105 
4106  avio_wb32(pb, 20);
4107  ffio_wfourcc(pb, "clef");
4108  avio_wb32(pb, 0);
4109  avio_wb32(pb, width << 16);
4110  avio_wb32(pb, track->par->height << 16);
4111 
4112  avio_wb32(pb, 20);
4113  ffio_wfourcc(pb, "prof");
4114  avio_wb32(pb, 0);
4115  avio_wb32(pb, width << 16);
4116  avio_wb32(pb, track->par->height << 16);
4117 
4118  avio_wb32(pb, 20);
4119  ffio_wfourcc(pb, "enof");
4120  avio_wb32(pb, 0);
4121  avio_wb32(pb, track->par->width << 16);
4122  avio_wb32(pb, track->par->height << 16);
4123 
4124  return update_size(pb, pos);
4125 }
4126 
4127 // This box is written in the following cases:
4128 // * Seems important for the psp playback. Without it the movie seems to hang.
4129 // * Used for specifying the looping behavior of animated AVIF (as specified
4130 // in Section 9.6 of the HEIF specification ISO/IEC 23008-12).
4132  MOVTrack *track)
4133 {
4135  mov->movie_timescale, track->timescale,
4136  AV_ROUND_UP);
4137  int version = duration < INT32_MAX ? 0 : 1;
4138  int entry_size, entry_count, size;
4139  int64_t delay, start_ct = track->start_cts;
4140  int64_t start_dts = track->start_dts;
4141  int flags = 0;
4142 
4143  if (track->entry) {
4144  if (start_dts != track->cluster[0].dts || (start_ct != track->cluster[0].cts && track->cluster[0].dts >= 0)) {
4145 
4146  av_log(mov->fc, AV_LOG_DEBUG,
4147  "EDTS using dts:%"PRId64" cts:%d instead of dts:%"PRId64" cts:%"PRId64" tid:%d\n",
4148  track->cluster[0].dts, track->cluster[0].cts,
4149  start_dts, start_ct, track->track_id);
4150  start_dts = track->cluster[0].dts;
4151  start_ct = track->cluster[0].cts;
4152  }
4153  }
4154 
4155  delay = av_rescale_rnd(start_dts + start_ct, mov->movie_timescale,
4156  track->timescale, AV_ROUND_DOWN);
4157 
4158  if (mov->mode == MODE_AVIF) {
4159  delay = 0;
4160  // Section 9.6.3 of ISO/IEC 23008-12: flags specifies repetition of the
4161  // edit list as follows: (flags & 1) equal to 0 specifies that the edit
4162  // list is not repeated, while (flags & 1) equal to 1 specifies that the
4163  // edit list is repeated.
4164  flags = mov->avif_loop_count != 1;
4165  start_ct = 0;
4166  }
4167 
4168  version |= delay < INT32_MAX ? 0 : 1;
4169 
4170  entry_size = (version == 1) ? 20 : 12;
4171  entry_count = 1 + (delay > 0);
4172  size = 24 + entry_count * entry_size;
4173 
4174  /* write the atom data */
4175  avio_wb32(pb, size);
4176  ffio_wfourcc(pb, "edts");
4177  avio_wb32(pb, size - 8);
4178  ffio_wfourcc(pb, "elst");
4179  avio_w8(pb, version);
4180  avio_wb24(pb, flags); /* flags */
4181 
4182  avio_wb32(pb, entry_count);
4183  if (delay > 0) { /* add an empty edit to delay presentation */
4184  /* In the positive delay case, the delay includes the cts
4185  * offset, and the second edit list entry below trims out
4186  * the same amount from the actual content. This makes sure
4187  * that the offset last sample is included in the edit
4188  * list duration as well. */
4189  if (version == 1) {
4190  avio_wb64(pb, delay);
4191  avio_wb64(pb, -1);
4192  } else {
4193  avio_wb32(pb, delay);
4194  avio_wb32(pb, -1);
4195  }
4196  avio_wb32(pb, 0x00010000);
4197  } else if (mov->mode != MODE_AVIF) {
4198  /* Avoid accidentally ending up with start_ct = -1 which has got a
4199  * special meaning. Normally start_ct should end up positive or zero
4200  * here, but use FFMIN in case dts is a small positive integer
4201  * rounded to 0 when represented in movie timescale units. */
4202  av_assert0(av_rescale_rnd(start_dts, mov->movie_timescale, track->timescale, AV_ROUND_DOWN) <= 0);
4203  start_ct = -FFMIN(start_dts, 0);
4204 
4205 #if CONFIG_IAMFENC
4206  if (track->iamf && track->par->codec_id == AV_CODEC_ID_OPUS)
4207  start_ct = av_rescale(start_ct, 48000, track->par->sample_rate);
4208 #endif
4209  /* Note, this delay is calculated from the pts of the first sample,
4210  * ensuring that we don't reduce the duration for cases with
4211  * dts<0 pts=0. */
4212  duration += delay;
4213  }
4214 
4215  /* For fragmented files, we don't know the full length yet. Setting
4216  * duration to 0 allows us to only specify the offset, including
4217  * the rest of the content (from all future fragments) without specifying
4218  * an explicit duration.
4219  *
4220  * For hybrid_fragmented during mov_write_trailer (mov->moov_written != 0),
4221  * don't reset duration to zero.
4222  */
4223  if (mov->flags & FF_MOV_FLAG_FRAGMENT &&
4225  duration = 0;
4226 
4227  /* duration */
4228  if (version == 1) {
4229  avio_wb64(pb, duration);
4230  avio_wb64(pb, start_ct);
4231  } else {
4232  avio_wb32(pb, duration);
4233  avio_wb32(pb, start_ct);
4234  }
4235  avio_wb32(pb, 0x00010000);
4236  return size;
4237 }
4238 
4239 static int mov_write_tref_tag(AVIOContext *pb, MOVTrack *track)
4240 {
4241  int64_t pos = avio_tell(pb);
4242  avio_wb32(pb, 0); // size placeholder
4243  ffio_wfourcc(pb, "tref");
4244 
4245  for (int i = 0; i < track->nb_tref_tags; i++) {
4246  MovTag *tag = &track->tref_tags[i];
4247  avio_wb32(pb, 8 + tag->nb_id * sizeof(*tag->id)); // size (subatom)
4248  avio_wl32(pb, tag->name);
4249  for (int j = 0; j < tag->nb_id; j++)
4250  avio_wb32(pb, tag->id[j]);
4251  }
4252  return update_size(pb, pos);
4253 }
4254 
4255 // goes at the end of each track! ... Critical for PSP playback ("Incompatible data" without it)
4257 {
4258  avio_wb32(pb, 0x34); /* size ... reports as 28 in mp4box! */
4259  ffio_wfourcc(pb, "uuid");
4260  ffio_wfourcc(pb, "USMT");
4261  avio_wb32(pb, 0x21d24fce);
4262  avio_wb32(pb, 0xbb88695c);
4263  avio_wb32(pb, 0xfac9c740);
4264  avio_wb32(pb, 0x1c); // another size here!
4265  ffio_wfourcc(pb, "MTDT");
4266  avio_wb32(pb, 0x00010012);
4267  avio_wb32(pb, 0x0a);
4268  avio_wb32(pb, 0x55c40000);
4269  avio_wb32(pb, 0x1);
4270  avio_wb32(pb, 0x0);
4271  return 0x34;
4272 }
4273 
4274 static int mov_write_udta_sdp(AVIOContext *pb, MOVTrack *track)
4275 {
4276  AVFormatContext *ctx = track->rtp_ctx;
4277  char buf[1000] = "";
4278  int len;
4279 
4280  av_assert0(track->nb_src_track);
4281  ff_sdp_write_media(buf, sizeof(buf), ctx->streams[0], *track->src_track,
4282  NULL, NULL, 0, 0, ctx);
4283  av_strlcatf(buf, sizeof(buf), "a=control:streamid=%d\r\n", track->track_id);
4284  len = strlen(buf);
4285 
4286  avio_wb32(pb, len + 24);
4287  ffio_wfourcc(pb, "udta");
4288  avio_wb32(pb, len + 16);
4289  ffio_wfourcc(pb, "hnti");
4290  avio_wb32(pb, len + 8);
4291  ffio_wfourcc(pb, "sdp ");
4292  avio_write(pb, buf, len);
4293  return len + 24;
4294 }
4295 
4297  const char *tag, const char *str)
4298 {
4299  int64_t pos = avio_tell(pb);
4300  AVDictionaryEntry *t = av_dict_get(st->metadata, str, NULL, 0);
4301  if (!t || !utf8len(t->value))
4302  return 0;
4303 
4304  avio_wb32(pb, 0); /* size */
4305  ffio_wfourcc(pb, tag); /* type */
4306  avio_write(pb, t->value, strlen(t->value)); /* UTF8 string value */
4307  return update_size(pb, pos);
4308 }
4309 
4310 static int mov_write_track_kind(AVIOContext *pb, const char *scheme_uri,
4311  const char *value)
4312 {
4313  int64_t pos = avio_tell(pb);
4314 
4315  /* Box|FullBox basics */
4316  avio_wb32(pb, 0); /* size placeholder */
4317  ffio_wfourcc(pb, (const unsigned char *)"kind");
4318  avio_w8(pb, 0); /* version = 0 */
4319  avio_wb24(pb, 0); /* flags = 0 */
4320 
4321  /* Required null-terminated scheme URI */
4322  avio_write(pb, (const unsigned char *)scheme_uri,
4323  strlen(scheme_uri));
4324  avio_w8(pb, 0);
4325 
4326  /* Optional value string */
4327  if (value && value[0])
4328  avio_write(pb, (const unsigned char *)value,
4329  strlen(value));
4330 
4331  avio_w8(pb, 0);
4332 
4333  return update_size(pb, pos);
4334 }
4335 
4337 {
4338  int ret = AVERROR_BUG;
4339 
4340  for (int i = 0; ff_mov_track_kind_table[i].scheme_uri; i++) {
4342 
4343  for (int j = 0; map.value_maps[j].disposition; j++) {
4344  const struct MP4TrackKindValueMapping value_map = map.value_maps[j];
4345  if (!(st->disposition & value_map.disposition))
4346  continue;
4347 
4348  if ((ret = mov_write_track_kind(pb, map.scheme_uri, value_map.value)) < 0)
4349  return ret;
4350  }
4351  }
4352 
4353  return 0;
4354 }
4355 
4357  AVStream *st)
4358 {
4359  AVIOContext *pb_buf;
4360  int ret, size;
4361  uint8_t *buf;
4362 
4363  if (!st)
4364  return 0;
4365 
4366  ret = avio_open_dyn_buf(&pb_buf);
4367  if (ret < 0)
4368  return ret;
4369 
4370  if (mov->mode & (MODE_MP4|MODE_MOV))
4371  mov_write_track_metadata(pb_buf, st, "name", "title");
4372 
4373  if (mov->mode & MODE_MP4) {
4374  if ((ret = mov_write_track_kinds(pb_buf, st)) < 0)
4375  goto end;
4376  }
4377 
4378  if ((size = avio_get_dyn_buf(pb_buf, &buf)) > 0) {
4379  avio_wb32(pb, size + 8);
4380  ffio_wfourcc(pb, "udta");
4381  avio_write(pb, buf, size);
4382  }
4383 end:
4384  ffio_free_dyn_buf(&pb_buf);
4385 
4386  return ret;
4387 }
4388 
4390  MOVTrack *track, AVStream *st)
4391 {
4392  int64_t pos = avio_tell(pb);
4393  int entry_backup = track->entry;
4394  int chunk_backup = track->chunkCount;
4395  int ret;
4396 
4397  /* If we want to have an empty moov, but some samples already have been
4398  * buffered (delay_moov), pretend that no samples have been written yet. */
4399  if (mov->flags & FF_MOV_FLAG_EMPTY_MOOV)
4400  track->chunkCount = track->entry = 0;
4401 
4402  avio_wb32(pb, 0); /* size */
4403  ffio_wfourcc(pb, "trak");
4404  mov_write_tkhd_tag(pb, mov, track, st);
4405 
4406  av_assert2(mov->use_editlist >= 0);
4407 
4408  if (track->start_dts != AV_NOPTS_VALUE) {
4409  if (mov->use_editlist)
4410  mov_write_edts_tag(pb, mov, track); // PSP Movies and several other cases require edts box
4411  else if ((track->entry && track->cluster[0].dts) || track->mode == MODE_PSP || is_clcp_track(track))
4412  av_log(mov->fc, AV_LOG_WARNING,
4413  "Not writing any edit list even though one would have been required\n");
4414  }
4415 
4416  if (mov->is_animated_avif)
4417  mov_write_edts_tag(pb, mov, track);
4418 
4419  if (track->nb_tref_tags)
4420  mov_write_tref_tag(pb, track);
4421 
4422  if ((ret = mov_write_mdia_tag(s, pb, mov, track)) < 0)
4423  return ret;
4424  if (track->mode == MODE_PSP)
4425  mov_write_uuid_tag_psp(pb, track); // PSP Movies require this uuid box
4426  if (track->tag == MKTAG('r','t','p',' '))
4427  mov_write_udta_sdp(pb, track);
4428  if (track->mode == MODE_MOV) {
4429  if (track->par->codec_type == AVMEDIA_TYPE_VIDEO) {
4430  double sample_aspect_ratio = av_q2d(st->sample_aspect_ratio);
4431  if (st->sample_aspect_ratio.num && 1.0 != sample_aspect_ratio) {
4432  mov_write_tapt_tag(pb, track);
4433  }
4434  }
4435  if (is_clcp_track(track) && st->sample_aspect_ratio.num) {
4436  mov_write_tapt_tag(pb, track);
4437  }
4438  }
4439  mov_write_track_udta_tag(pb, mov, st);
4440  track->entry = entry_backup;
4441  track->chunkCount = chunk_backup;
4442  return update_size(pb, pos);
4443 }
4444 
4446 {
4447  int i, has_audio = 0, has_video = 0;
4448  int64_t pos = avio_tell(pb);
4449  int audio_profile = mov->iods_audio_profile;
4450  int video_profile = mov->iods_video_profile;
4451  for (i = 0; i < mov->nb_tracks; i++) {
4452  if (mov->tracks[i].entry > 0 || mov->flags & FF_MOV_FLAG_EMPTY_MOOV) {
4453  has_audio |= mov->tracks[i].par->codec_type == AVMEDIA_TYPE_AUDIO;
4454  has_video |= mov->tracks[i].par->codec_type == AVMEDIA_TYPE_VIDEO;
4455  }
4456  }
4457  if (audio_profile < 0)
4458  audio_profile = 0xFF - has_audio;
4459  if (video_profile < 0)
4460  video_profile = 0xFF - has_video;
4461  avio_wb32(pb, 0x0); /* size */
4462  ffio_wfourcc(pb, "iods");
4463  avio_wb32(pb, 0); /* version & flags */
4464  put_descr(pb, 0x10, 7);
4465  avio_wb16(pb, 0x004f);
4466  avio_w8(pb, 0xff);
4467  avio_w8(pb, 0xff);
4468  avio_w8(pb, audio_profile);
4469  avio_w8(pb, video_profile);
4470  avio_w8(pb, 0xff);
4471  return update_size(pb, pos);
4472 }
4473 
4474 static int mov_write_trex_tag(AVIOContext *pb, MOVTrack *track)
4475 {
4476  avio_wb32(pb, 0x20); /* size */
4477  ffio_wfourcc(pb, "trex");
4478  avio_wb32(pb, 0); /* version & flags */
4479  avio_wb32(pb, track->track_id); /* track ID */
4480  avio_wb32(pb, 1); /* default sample description index */
4481  avio_wb32(pb, 0); /* default sample duration */
4482  avio_wb32(pb, 0); /* default sample size */
4483  avio_wb32(pb, 0); /* default sample flags */
4484  return 0;
4485 }
4486 
4488 {
4489  int64_t pos = avio_tell(pb);
4490  int i;
4491  avio_wb32(pb, 0x0); /* size */
4492  ffio_wfourcc(pb, "mvex");
4493  for (i = 0; i < mov->nb_tracks; i++)
4494  mov_write_trex_tag(pb, &mov->tracks[i]);
4495  return update_size(pb, pos);
4496 }
4497 
4499 {
4500  int max_track_id = 1, i;
4501  int64_t max_track_len = 0;
4502  int version;
4503  int timescale;
4504 
4505  for (i = 0; i < mov->nb_tracks; i++) {
4506  if (mov->tracks[i].entry > 0 && mov->tracks[i].timescale) {
4507  int64_t max_track_len_temp = av_rescale_rnd(
4508  calc_pts_duration(mov, &mov->tracks[i]),
4509  mov->movie_timescale,
4510  mov->tracks[i].timescale,
4511  AV_ROUND_UP);
4512  if (max_track_len < max_track_len_temp)
4513  max_track_len = max_track_len_temp;
4514  if (max_track_id < mov->tracks[i].track_id)
4515  max_track_id = mov->tracks[i].track_id;
4516  }
4517  }
4518  /* If using delay_moov, make sure the output is the same as if no
4519  * samples had been written yet. */
4520  if (mov->flags & FF_MOV_FLAG_EMPTY_MOOV) {
4521  max_track_len = 0;
4522  max_track_id = 1;
4523  }
4524 
4525  version = mov_mdhd_mvhd_tkhd_version(mov, NULL, max_track_len);
4526  avio_wb32(pb, version == 1 ? 120 : 108); /* size */
4527 
4528  ffio_wfourcc(pb, "mvhd");
4529  avio_w8(pb, version);
4530  avio_wb24(pb, 0); /* flags */
4531  if (version == 1) {
4532  avio_wb64(pb, mov->time);
4533  avio_wb64(pb, mov->time);
4534  } else {
4535  avio_wb32(pb, mov->time); /* creation time */
4536  avio_wb32(pb, mov->time); /* modification time */
4537  }
4538 
4539  timescale = mov->movie_timescale;
4540  if (mov->mode == MODE_AVIF && !timescale)
4541  timescale = mov->tracks[0].timescale;
4542 
4543  avio_wb32(pb, timescale);
4544  (version == 1) ? avio_wb64(pb, max_track_len) : avio_wb32(pb, max_track_len); /* duration of longest track */
4545 
4546  avio_wb32(pb, 0x00010000); /* reserved (preferred rate) 1.0 = normal */
4547  avio_wb16(pb, 0x0100); /* reserved (preferred volume) 1.0 = normal */
4548  ffio_fill(pb, 0, 2 + 2 * 4); /* reserved */
4549 
4550  /* Matrix structure */
4551  write_matrix(pb, 1, 0, 0, 1, 0, 0);
4552 
4553  avio_wb32(pb, 0); /* reserved (preview time) */
4554  avio_wb32(pb, 0); /* reserved (preview duration) */
4555  avio_wb32(pb, 0); /* reserved (poster time) */
4556  avio_wb32(pb, 0); /* reserved (selection time) */
4557  avio_wb32(pb, 0); /* reserved (selection duration) */
4558  avio_wb32(pb, 0); /* reserved (current time) */
4559  avio_wb32(pb, max_track_id + 1); /* Next track id */
4560  return 0x6c;
4561 }
4562 
4564  AVFormatContext *s)
4565 {
4566  avio_wb32(pb, 33); /* size */
4567  ffio_wfourcc(pb, "hdlr");
4568  avio_wb32(pb, 0);
4569  avio_wb32(pb, 0);
4570  ffio_wfourcc(pb, "mdir");
4571  ffio_wfourcc(pb, "appl");
4572  avio_wb32(pb, 0);
4573  avio_wb32(pb, 0);
4574  avio_w8(pb, 0);
4575  return 33;
4576 }
4577 
4578 /* helper function to write a data tag with the specified string as data */
4579 static int mov_write_string_data_tag(AVIOContext *pb, const char *data, int lang, int long_style)
4580 {
4581  size_t data_len = strlen(data);
4582  if (long_style) {
4583  int size = 16 + data_len;
4584  avio_wb32(pb, size); /* size */
4585  ffio_wfourcc(pb, "data");
4586  avio_wb32(pb, 1);
4587  avio_wb32(pb, 0);
4588  avio_write(pb, data, data_len);
4589  return size;
4590  } else {
4591  avio_wb16(pb, data_len); /* string length */
4592  if (!lang)
4593  lang = ff_mov_iso639_to_lang("und", 1);
4594  avio_wb16(pb, lang);
4595  avio_write(pb, data, data_len);
4596  return data_len + 4;
4597  }
4598 }
4599 
4600 static int mov_write_string_tag(AVIOContext *pb, const char *name,
4601  const char *value, int lang, int long_style)
4602 {
4603  int size = 0;
4604  if (value && value[0]) {
4605  int64_t pos = avio_tell(pb);
4606  avio_wb32(pb, 0); /* size */
4607  ffio_wfourcc(pb, name);
4608  mov_write_string_data_tag(pb, value, lang, long_style);
4609  size = update_size(pb, pos);
4610  }
4611  return size;
4612 }
4613 
4614 static int mov_write_freeform_tag(AVIOContext *pb, const char *mean,
4615  const char *name, const char *data)
4616 {
4617  if (!data || !data[0])
4618  return 0;
4619 
4620  static const char stub_flags[4] = {0, 0, 0, 0};
4621 
4622  int64_t entry_pos = avio_tell(pb);
4623  avio_wb32(pb, 0); /* size */
4624  ffio_wfourcc(pb, "----"); /* freeform */
4625 
4626  size_t mean_len = strlen(mean);
4627  avio_wb32(pb, 12 + mean_len);
4628  ffio_wfourcc(pb, "mean");
4629  avio_write(pb, &stub_flags[0], sizeof(stub_flags));
4630  avio_write(pb, mean, mean_len);
4631 
4632  size_t name_len = strlen(name);
4633  avio_wb32(pb, 12 + name_len);
4634  ffio_wfourcc(pb, "name");
4635  avio_write(pb, &stub_flags[0], sizeof(stub_flags));
4636  avio_write(pb, name, name_len);
4637 
4638  mov_write_string_data_tag(pb, data, 0, 1);
4639 
4640  return update_size(pb, entry_pos);
4641 }
4642 
4644  const char *tag, int *lang)
4645 {
4646  int l, len, len2;
4647  AVDictionaryEntry *t, *t2 = NULL;
4648  char tag2[16];
4649 
4650  *lang = 0;
4651 
4652  if (!(t = av_dict_get(s->metadata, tag, NULL, 0)))
4653  return NULL;
4654 
4655  len = strlen(t->key);
4656  snprintf(tag2, sizeof(tag2), "%s-", tag);
4657  while ((t2 = av_dict_get(s->metadata, tag2, t2, AV_DICT_IGNORE_SUFFIX))) {
4658  len2 = strlen(t2->key);
4659  if (len2 == len + 4 && !strcmp(t->value, t2->value)
4660  && (l = ff_mov_iso639_to_lang(&t2->key[len2 - 3], 1)) >= 0) {
4661  *lang = l;
4662  return t;
4663  }
4664  }
4665  return t;
4666 }
4667 
4669  const char *name, const char *tag,
4670  int long_style)
4671 {
4672  int lang;
4673  AVDictionaryEntry *t = get_metadata_lang(s, tag, &lang);
4674  if (!t)
4675  return 0;
4676  return mov_write_string_tag(pb, name, t->value, lang, long_style);
4677 }
4678 
4680  const char *mean, const char *name,
4681  const char *tag)
4682 {
4683  AVDictionaryEntry *t = av_dict_get(s->metadata, tag, NULL, 0);
4684  if (!t)
4685  return 0;
4686  return mov_write_freeform_tag(pb, mean, name, t->value);
4687 }
4688 
4689 /* iTunes bpm number */
4691 {
4692  AVDictionaryEntry *t = av_dict_get(s->metadata, "tmpo", NULL, 0);
4693  int size = 0, tmpo = t ? atoi(t->value) : 0;
4694  if (tmpo) {
4695  size = 26;
4696  avio_wb32(pb, size);
4697  ffio_wfourcc(pb, "tmpo");
4698  avio_wb32(pb, size-8); /* size */
4699  ffio_wfourcc(pb, "data");
4700  avio_wb32(pb, 0x15); //type specifier
4701  avio_wb32(pb, 0);
4702  avio_wb16(pb, tmpo); // data
4703  }
4704  return size;
4705 }
4706 
4707 /* 3GPP TS 26.244 */
4709 {
4710  int lang;
4711  int64_t pos = avio_tell(pb);
4712  double latitude, longitude, altitude;
4713  int32_t latitude_fix, longitude_fix, altitude_fix;
4714  AVDictionaryEntry *t = get_metadata_lang(s, "location", &lang);
4715  const char *ptr, *place = "";
4716  char *end;
4717  static const char *astronomical_body = "earth";
4718  if (!t)
4719  return 0;
4720 
4721  ptr = t->value;
4722  latitude = strtod(ptr, &end);
4723  if (end == ptr) {
4724  av_log(s, AV_LOG_WARNING, "malformed location metadata\n");
4725  return 0;
4726  }
4727  ptr = end;
4728  longitude = strtod(ptr, &end);
4729  if (end == ptr) {
4730  av_log(s, AV_LOG_WARNING, "malformed location metadata\n");
4731  return 0;
4732  }
4733  ptr = end;
4734  altitude = strtod(ptr, &end);
4735  /* If no altitude was present, the default 0 should be fine */
4736  if (*end == '/')
4737  place = end + 1;
4738 
4739  latitude_fix = (int32_t) ((1 << 16) * latitude);
4740  longitude_fix = (int32_t) ((1 << 16) * longitude);
4741  altitude_fix = (int32_t) ((1 << 16) * altitude);
4742 
4743  avio_wb32(pb, 0); /* size */
4744  ffio_wfourcc(pb, "loci"); /* type */
4745  avio_wb32(pb, 0); /* version + flags */
4746  avio_wb16(pb, lang);
4747  avio_write(pb, place, strlen(place) + 1);
4748  avio_w8(pb, 0); /* role of place (0 == shooting location, 1 == real location, 2 == fictional location) */
4749  avio_wb32(pb, longitude_fix);
4750  avio_wb32(pb, latitude_fix);
4751  avio_wb32(pb, altitude_fix);
4752  avio_write(pb, astronomical_body, strlen(astronomical_body) + 1);
4753  avio_w8(pb, 0); /* additional notes, null terminated string */
4754 
4755  return update_size(pb, pos);
4756 }
4757 
4758 /* iTunes track or disc number */
4760  AVFormatContext *s, int disc)
4761 {
4762  AVDictionaryEntry *t = av_dict_get(s->metadata,
4763  disc ? "disc" : "track",
4764  NULL, 0);
4765  int size = 0, track = t ? atoi(t->value) : 0;
4766  if (track) {
4767  int tracks = 0;
4768  char *slash = strchr(t->value, '/');
4769  if (slash)
4770  tracks = atoi(slash + 1);
4771  avio_wb32(pb, 32); /* size */
4772  ffio_wfourcc(pb, disc ? "disk" : "trkn");
4773  avio_wb32(pb, 24); /* size */
4774  ffio_wfourcc(pb, "data");
4775  avio_wb32(pb, 0); // 8 bytes empty
4776  avio_wb32(pb, 0);
4777  avio_wb16(pb, 0); // empty
4778  avio_wb16(pb, track); // track / disc number
4779  avio_wb16(pb, tracks); // total track / disc number
4780  avio_wb16(pb, 0); // empty
4781  size = 32;
4782  }
4783  return size;
4784 }
4785 
4787  const char *name, const char *tag,
4788  int len)
4789 {
4790  AVDictionaryEntry *t = NULL;
4791  uint8_t num;
4792  int size = 24 + len;
4793 
4794  if (len != 1 && len != 4)
4795  return -1;
4796 
4797  if (!(t = av_dict_get(s->metadata, tag, NULL, 0)))
4798  return 0;
4799  num = atoi(t->value);
4800 
4801  avio_wb32(pb, size);
4802  ffio_wfourcc(pb, name);
4803  avio_wb32(pb, size - 8);
4804  ffio_wfourcc(pb, "data");
4805  avio_wb32(pb, 0x15);
4806  avio_wb32(pb, 0);
4807  if (len==4) avio_wb32(pb, num);
4808  else avio_w8 (pb, num);
4809 
4810  return size;
4811 }
4812 
4814 {
4815  MOVMuxContext *mov = s->priv_data;
4816  int64_t pos = 0;
4817 
4818  for (int i = 0; i < mov->nb_streams; i++) {
4819  MOVTrack *trk = &mov->tracks[i];
4820 
4821  if (!is_cover_image(trk->st) || trk->cover_image->size <= 0)
4822  continue;
4823 
4824  if (!pos) {
4825  pos = avio_tell(pb);
4826  avio_wb32(pb, 0);
4827  ffio_wfourcc(pb, "covr");
4828  }
4829  avio_wb32(pb, 16 + trk->cover_image->size);
4830  ffio_wfourcc(pb, "data");
4831  avio_wb32(pb, trk->tag);
4832  avio_wb32(pb , 0);
4833  avio_write(pb, trk->cover_image->data, trk->cover_image->size);
4834  }
4835 
4836  return pos ? update_size(pb, pos) : 0;
4837 }
4838 
4839 /* iTunes meta data list */
4841  AVFormatContext *s)
4842 {
4843  int64_t pos = avio_tell(pb);
4844  avio_wb32(pb, 0); /* size */
4845  ffio_wfourcc(pb, "ilst");
4846  mov_write_string_metadata(s, pb, "\251nam", "title" , 1);
4847  mov_write_string_metadata(s, pb, "\251ART", "artist" , 1);
4848  mov_write_string_metadata(s, pb, "aART", "album_artist", 1);
4849  mov_write_string_metadata(s, pb, "\251wrt", "composer" , 1);
4850  mov_write_string_metadata(s, pb, "\251alb", "album" , 1);
4851  mov_write_string_metadata(s, pb, "\251day", "date" , 1);
4852  if (!mov_write_string_metadata(s, pb, "\251too", "encoding_tool", 1)) {
4853  if (!(s->flags & AVFMT_FLAG_BITEXACT))
4854  mov_write_string_tag(pb, "\251too", LIBAVFORMAT_IDENT, 0, 1);
4855  }
4856  mov_write_string_metadata(s, pb, "\251cmt", "comment" , 1);
4857  mov_write_string_metadata(s, pb, "\251gen", "genre" , 1);
4858  mov_write_string_metadata(s, pb, "cprt", "copyright", 1);
4859  mov_write_string_metadata(s, pb, "\251grp", "grouping" , 1);
4860  mov_write_string_metadata(s, pb, "\251lyr", "lyrics" , 1);
4861  mov_write_string_metadata(s, pb, "desc", "description",1);
4862  mov_write_string_metadata(s, pb, "ldes", "synopsis" , 1);
4863  mov_write_string_metadata(s, pb, "tvsh", "show" , 1);
4864  mov_write_string_metadata(s, pb, "tven", "episode_id",1);
4865  mov_write_string_metadata(s, pb, "tvnn", "network" , 1);
4866  mov_write_string_metadata(s, pb, "keyw", "keywords" , 1);
4867  mov_write_int8_metadata (s, pb, "tves", "episode_sort",4);
4868  mov_write_int8_metadata (s, pb, "tvsn", "season_number",4);
4869  mov_write_int8_metadata (s, pb, "stik", "media_type",1);
4870  mov_write_int8_metadata (s, pb, "hdvd", "hd_video", 1);
4871  mov_write_int8_metadata (s, pb, "pgap", "gapless_playback",1);
4872  mov_write_int8_metadata (s, pb, "cpil", "compilation", 1);
4873  mov_write_covr(pb, s);
4874  mov_write_trkn_tag(pb, mov, s, 0); // track number
4875  mov_write_trkn_tag(pb, mov, s, 1); // disc number
4876  mov_write_tmpo_tag(pb, s);
4877  mov_write_custom_metadata(s, pb, "com.apple.iTunes", "DISCSUBTITLE", "disc_subtitle");
4878  return update_size(pb, pos);
4879 }
4880 
4882  AVFormatContext *s)
4883 {
4884  avio_wb32(pb, 33); /* size */
4885  ffio_wfourcc(pb, "hdlr");
4886  avio_wb32(pb, 0);
4887  avio_wb32(pb, 0);
4888  ffio_wfourcc(pb, "mdta");
4889  avio_wb32(pb, 0);
4890  avio_wb32(pb, 0);
4891  avio_wb32(pb, 0);
4892  avio_w8(pb, 0);
4893  return 33;
4894 }
4895 
4897  AVFormatContext *s)
4898 {
4899  const AVDictionaryEntry *t = NULL;
4900  int64_t pos = avio_tell(pb);
4901  int64_t curpos, entry_pos;
4902  int count = 0;
4903 
4904  avio_wb32(pb, 0); /* size */
4905  ffio_wfourcc(pb, "keys");
4906  avio_wb32(pb, 0);
4907  entry_pos = avio_tell(pb);
4908  avio_wb32(pb, 0); /* entry count */
4909 
4910  while (t = av_dict_iterate(s->metadata, t)) {
4911  size_t key_len = strlen(t->key);
4912  avio_wb32(pb, key_len + 8);
4913  ffio_wfourcc(pb, "mdta");
4914  avio_write(pb, t->key, key_len);
4915  count += 1;
4916  }
4917  curpos = avio_tell(pb);
4918  avio_seek(pb, entry_pos, SEEK_SET);
4919  avio_wb32(pb, count); // rewrite entry count
4920  avio_seek(pb, curpos, SEEK_SET);
4921 
4922  return update_size(pb, pos);
4923 }
4924 
4926  AVFormatContext *s)
4927 {
4928  const AVDictionaryEntry *t = NULL;
4929  int64_t pos = avio_tell(pb);
4930  int count = 1; /* keys are 1-index based */
4931 
4932  avio_wb32(pb, 0); /* size */
4933  ffio_wfourcc(pb, "ilst");
4934 
4935  while (t = av_dict_iterate(s->metadata, t)) {
4936  int64_t entry_pos = avio_tell(pb);
4937  avio_wb32(pb, 0); /* size */
4938  avio_wb32(pb, count); /* key */
4939  mov_write_string_data_tag(pb, t->value, 0, 1);
4940  update_size(pb, entry_pos);
4941  count += 1;
4942  }
4943  return update_size(pb, pos);
4944 }
4945 
4946 /* meta data tags */
4948  AVFormatContext *s)
4949 {
4950  int size = 0;
4951  int64_t pos = avio_tell(pb);
4952  avio_wb32(pb, 0); /* size */
4953  ffio_wfourcc(pb, "meta");
4954  avio_wb32(pb, 0);
4955  if (mov->flags & FF_MOV_FLAG_USE_MDTA) {
4956  mov_write_mdta_hdlr_tag(pb, mov, s);
4957  mov_write_mdta_keys_tag(pb, mov, s);
4958  mov_write_mdta_ilst_tag(pb, mov, s);
4959  } else if (mov->mode == MODE_AVIF) {
4960  mov_write_hdlr_tag(s, pb, &mov->tracks[0]);
4961  // We always write the primary item id as 1 since only one track is
4962  // supported for AVIF.
4963  mov_write_pitm_tag(pb, 1);
4964  mov_write_iloc_tag(pb, mov, s);
4965  mov_write_iinf_tag(pb, mov, s);
4966  if (mov->nb_streams > 1)
4967  mov_write_iref_tag(pb, mov, s);
4968  mov_write_iprp_tag(pb, mov, s);
4969  } else {
4970  /* iTunes metadata tag */
4971  mov_write_itunes_hdlr_tag(pb, mov, s);
4972  mov_write_ilst_tag(pb, mov, s);
4973  }
4974  size = update_size(pb, pos);
4975  return size;
4976 }
4977 
4979  const char *name, const char *key)
4980 {
4981  int len;
4982  AVDictionaryEntry *t;
4983 
4984  if (!(t = av_dict_get(s->metadata, key, NULL, 0)))
4985  return 0;
4986 
4987  len = strlen(t->value);
4988  if (len > 0) {
4989  int size = len + 8;
4990  avio_wb32(pb, size);
4991  ffio_wfourcc(pb, name);
4992  avio_write(pb, t->value, len);
4993  return size;
4994  }
4995  return 0;
4996 }
4997 
4998 static int ascii_to_wc(AVIOContext *pb, const uint8_t *b)
4999 {
5000  int val;
5001  while (*b) {
5002  GET_UTF8(val, *b++, return -1;)
5003  avio_wb16(pb, val);
5004  }
5005  avio_wb16(pb, 0x00);
5006  return 0;
5007 }
5008 
5009 static uint16_t language_code(const char *str)
5010 {
5011  return (((str[0] - 0x60) & 0x1F) << 10) +
5012  (((str[1] - 0x60) & 0x1F) << 5) +
5013  (( str[2] - 0x60) & 0x1F);
5014 }
5015 
5017  const char *tag, const char *str)
5018 {
5019  int64_t pos = avio_tell(pb);
5020  AVDictionaryEntry *t = av_dict_get(s->metadata, str, NULL, 0);
5021  if (!t || !utf8len(t->value))
5022  return 0;
5023  avio_wb32(pb, 0); /* size */
5024  ffio_wfourcc(pb, tag); /* type */
5025  avio_wb32(pb, 0); /* version + flags */
5026  if (!strcmp(tag, "yrrc"))
5027  avio_wb16(pb, atoi(t->value));
5028  else {
5029  avio_wb16(pb, language_code("eng")); /* language */
5030  avio_write(pb, t->value, strlen(t->value) + 1); /* UTF8 string value */
5031  if (!strcmp(tag, "albm") &&
5032  (t = av_dict_get(s->metadata, "track", NULL, 0)))
5033  avio_w8(pb, atoi(t->value));
5034  }
5035  return update_size(pb, pos);
5036 }
5037 
5039 {
5040  int64_t pos = avio_tell(pb);
5041  int i, nb_chapters = FFMIN(s->nb_chapters, 255);
5042 
5043  avio_wb32(pb, 0); // size
5044  ffio_wfourcc(pb, "chpl");
5045  avio_wb32(pb, 0x01000000); // version + flags
5046  avio_wb32(pb, 0); // unknown
5047  avio_w8(pb, nb_chapters);
5048 
5049  for (i = 0; i < nb_chapters; i++) {
5050  AVChapter *c = s->chapters[i];
5051  AVDictionaryEntry *t;
5052  avio_wb64(pb, av_rescale_q(c->start, c->time_base, (AVRational){1,10000000}));
5053 
5054  if ((t = av_dict_get(c->metadata, "title", NULL, 0))) {
5055  int len = FFMIN(strlen(t->value), 255);
5056  avio_w8(pb, len);
5057  avio_write(pb, t->value, len);
5058  } else
5059  avio_w8(pb, 0);
5060  }
5061  return update_size(pb, pos);
5062 }
5063 
5065  AVFormatContext *s)
5066 {
5067  AVIOContext *pb_buf;
5068  int ret, size;
5069  uint8_t *buf;
5070 
5071  ret = avio_open_dyn_buf(&pb_buf);
5072  if (ret < 0)
5073  return ret;
5074 
5075  if (mov->mode & MODE_3GP) {
5076  mov_write_3gp_udta_tag(pb_buf, s, "perf", "artist");
5077  mov_write_3gp_udta_tag(pb_buf, s, "titl", "title");
5078  mov_write_3gp_udta_tag(pb_buf, s, "auth", "author");
5079  mov_write_3gp_udta_tag(pb_buf, s, "gnre", "genre");
5080  mov_write_3gp_udta_tag(pb_buf, s, "dscp", "comment");
5081  mov_write_3gp_udta_tag(pb_buf, s, "albm", "album");
5082  mov_write_3gp_udta_tag(pb_buf, s, "cprt", "copyright");
5083  mov_write_3gp_udta_tag(pb_buf, s, "yrrc", "date");
5084  mov_write_loci_tag(s, pb_buf);
5085  } 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
5086  mov_write_string_metadata(s, pb_buf, "\251ART", "artist", 0);
5087  mov_write_string_metadata(s, pb_buf, "\251nam", "title", 0);
5088  mov_write_string_metadata(s, pb_buf, "\251aut", "author", 0);
5089  mov_write_string_metadata(s, pb_buf, "\251alb", "album", 0);
5090  mov_write_string_metadata(s, pb_buf, "\251day", "date", 0);
5091  mov_write_string_metadata(s, pb_buf, "\251swr", "encoder", 0);
5092  // currently ignored by mov.c
5093  mov_write_string_metadata(s, pb_buf, "\251des", "comment", 0);
5094  // add support for libquicktime, this atom is also actually read by mov.c
5095  mov_write_string_metadata(s, pb_buf, "\251cmt", "comment", 0);
5096  mov_write_string_metadata(s, pb_buf, "\251gen", "genre", 0);
5097  mov_write_string_metadata(s, pb_buf, "\251cpy", "copyright", 0);
5098  mov_write_string_metadata(s, pb_buf, "\251mak", "make", 0);
5099  mov_write_string_metadata(s, pb_buf, "\251mod", "model", 0);
5100  mov_write_string_metadata(s, pb_buf, "\251xyz", "location", 0);
5101  mov_write_string_metadata(s, pb_buf, "\251key", "keywords", 0);
5102  mov_write_raw_metadata_tag(s, pb_buf, "XMP_", "xmp");
5103  } else {
5104  /* iTunes meta data */
5105  mov_write_meta_tag(pb_buf, mov, s);
5106  mov_write_loci_tag(s, pb_buf);
5107  }
5108 
5109  if (s->nb_chapters && !(mov->flags & FF_MOV_FLAG_DISABLE_CHPL))
5110  mov_write_chpl_tag(pb_buf, s);
5111 
5112  if ((size = avio_get_dyn_buf(pb_buf, &buf)) > 0) {
5113  avio_wb32(pb, size + 8);
5114  ffio_wfourcc(pb, "udta");
5115  avio_write(pb, buf, size);
5116  }
5117  ffio_free_dyn_buf(&pb_buf);
5118 
5119  return 0;
5120 }
5121 
5123  const char *str, const char *lang, int type)
5124 {
5125  int len = utf8len(str) + 1;
5126  if (len <= 0)
5127  return;
5128  avio_wb16(pb, len * 2 + 10); /* size */
5129  avio_wb32(pb, type); /* type */
5130  avio_wb16(pb, language_code(lang)); /* language */
5131  avio_wb16(pb, 0x01); /* ? */
5132  ascii_to_wc(pb, str);
5133 }
5134 
5136 {
5137  AVDictionaryEntry *title = av_dict_get(s->metadata, "title", NULL, 0);
5138  int64_t pos, pos2;
5139 
5140  if (title) {
5141  pos = avio_tell(pb);
5142  avio_wb32(pb, 0); /* size placeholder*/
5143  ffio_wfourcc(pb, "uuid");
5144  ffio_wfourcc(pb, "USMT");
5145  avio_wb32(pb, 0x21d24fce); /* 96 bit UUID */
5146  avio_wb32(pb, 0xbb88695c);
5147  avio_wb32(pb, 0xfac9c740);
5148 
5149  pos2 = avio_tell(pb);
5150  avio_wb32(pb, 0); /* size placeholder*/
5151  ffio_wfourcc(pb, "MTDT");
5152  avio_wb16(pb, 4);
5153 
5154  // ?
5155  avio_wb16(pb, 0x0C); /* size */
5156  avio_wb32(pb, 0x0B); /* type */
5157  avio_wb16(pb, language_code("und")); /* language */
5158  avio_wb16(pb, 0x0); /* ? */
5159  avio_wb16(pb, 0x021C); /* data */
5160 
5161  if (!(s->flags & AVFMT_FLAG_BITEXACT))
5162  mov_write_psp_udta_tag(pb, LIBAVFORMAT_IDENT, "eng", 0x04);
5163  mov_write_psp_udta_tag(pb, title->value, "eng", 0x01);
5164  mov_write_psp_udta_tag(pb, "2006/04/01 11:11:11", "und", 0x03);
5165 
5166  update_size(pb, pos2);
5167  return update_size(pb, pos);
5168  }
5169 
5170  return 0;
5171 }
5172 
5174 {
5179  if (!sd)
5180  return 0;
5181 
5183  for (AVEncryptionInitInfo *copy = info; copy; copy = copy->next) {
5184  int64_t pos;
5185 
5186  if (!copy->data_size && !copy->num_key_ids)
5187  continue;
5188 
5189  pos = avio_tell(pb);
5190  avio_wb32(pb, 0); /* size placeholder */
5191  ffio_wfourcc(pb, "pssh");
5192  avio_w8(pb, 1); /* version */
5193  avio_wb24(pb, 0);
5194  for (int i = 0; i < copy->system_id_size; i++)
5195  avio_w8(pb, copy->system_id[i]);
5196  avio_wb32(pb, copy->num_key_ids);
5197  for (int i = 0; i < copy->num_key_ids; i++)
5198  for (int j = 0; j < copy->key_id_size; j++)
5199  avio_w8(pb, copy->key_ids[i][j]);
5200  avio_wb32(pb, copy->data_size);
5201  avio_write(pb, copy->data, copy->data_size);
5202  update_size(pb, pos);
5203  }
5204 
5206 
5207  return 0;
5208 }
5209 
5210 static void build_chunks(MOVTrack *trk)
5211 {
5212  int i;
5213  MOVIentry *chunk = &trk->cluster[0];
5214  uint64_t chunkSize = chunk->size;
5215  chunk->chunkNum = 1;
5216  if (trk->chunkCount)
5217  return;
5218  trk->chunkCount = 1;
5219  for (i = 1; i<trk->entry; i++){
5220  if (chunk->pos + chunkSize == trk->cluster[i].pos &&
5221  chunk->stsd_index == trk->cluster[i].stsd_index &&
5222  chunkSize + trk->cluster[i].size < (1<<20)){
5223  chunkSize += trk->cluster[i].size;
5224  chunk->samples_in_chunk += trk->cluster[i].entries;
5225  } else {
5226  trk->cluster[i].chunkNum = chunk->chunkNum+1;
5227  chunk=&trk->cluster[i];
5228  chunkSize = chunk->size;
5229  trk->chunkCount++;
5230  }
5231  }
5232 }
5233 
5234 /**
5235  * Assign track ids. If option "use_stream_ids_as_track_ids" is set,
5236  * the stream ids are used as track ids.
5237  *
5238  * This assumes mov->tracks and s->streams are in the same order and
5239  * there are no gaps in either of them (so mov->tracks[n] refers to
5240  * s->streams[n]).
5241  *
5242  * As an exception, there can be more entries in
5243  * s->streams than in mov->tracks, in which case new track ids are
5244  * generated (starting after the largest found stream id).
5245  */
5247 {
5248  int i;
5249 
5250  if (mov->track_ids_ok)
5251  return 0;
5252 
5253  if (mov->use_stream_ids_as_track_ids) {
5254  int next_generated_track_id = 0;
5255  for (i = 0; i < mov->nb_streams; i++) {
5256  AVStream *st = mov->tracks[i].st;
5257  if (st->id > next_generated_track_id)
5258  next_generated_track_id = st->id;
5259  }
5260 
5261  for (i = 0; i < mov->nb_tracks; i++) {
5262  if (mov->tracks[i].entry <= 0 && !(mov->flags & FF_MOV_FLAG_FRAGMENT))
5263  continue;
5264 
5265  mov->tracks[i].track_id = i >= mov->nb_streams ? ++next_generated_track_id : mov->tracks[i].st->id;
5266  }
5267  } else {
5268  int last_track_id = 0;
5269  for (i = 0; i < mov->nb_tracks; i++) {
5270  if (mov->tracks[i].entry <= 0 && !(mov->flags & FF_MOV_FLAG_FRAGMENT))
5271  continue;
5272 
5273  last_track_id =
5274  mov->tracks[i].track_id = (mov->tracks[i].st
5275  ? FFMAX(mov->tracks[i].st->index, last_track_id)
5276  : FFMAX(i, last_track_id)) + 1;
5277  }
5278  }
5279 
5280  mov->track_ids_ok = 1;
5281 
5282  return 0;
5283 }
5284 
5285 static int mov_find_tref_id(MOVMuxContext *mov, const MovTag *tag, uint32_t id)
5286 {
5287  for (int i = 0; i < tag->nb_id; i++) {
5288  if (tag->id[i] == id)
5289  return 1;
5290  }
5291  return 0;
5292 }
5293 
5294 static int mov_add_tref_id(MOVMuxContext *mov, MovTag *tag, uint32_t id)
5295 {
5296  int ret = mov_find_tref_id(mov, tag, id);
5297 
5298  if (!ret) {
5299  uint32_t *tmp = av_realloc_array(tag->id, tag->nb_id + 1, sizeof(*tag->id));
5300  if (!tmp)
5301  return AVERROR(ENOMEM);
5302  tag->id = tmp;
5303  tag->id[tag->nb_id++] = id;
5304  }
5305 
5306  return 0;
5307 }
5308 
5309 static MovTag *mov_find_tref_tag(MOVMuxContext *mov, const MOVTrack *trk, uint32_t name)
5310 {
5311  for (int i = 0; i < trk->nb_tref_tags; i++) {
5312  MovTag *entry = &trk->tref_tags[i];
5313 
5314  if (entry->name == name)
5315  return entry;
5316  }
5317  return NULL;
5318 }
5319 
5320 static MovTag *mov_add_tref_tag(MOVMuxContext *mov, MOVTrack *trk, uint32_t name)
5321 {
5322  MovTag *tag = mov_find_tref_tag(mov, trk, name);
5323 
5324  if (!tag) {
5325  MovTag *tmp = av_realloc_array(trk->tref_tags, trk->nb_tref_tags + 1,
5326  sizeof(*trk->tref_tags));
5327  if (!tmp)
5328  return NULL;
5329  trk->tref_tags = tmp;
5330  tag = &trk->tref_tags[trk->nb_tref_tags++];
5331  *tag = (MovTag){ .name = name };
5332  }
5333 
5334  return tag;
5335 }
5336 
5338  AVFormatContext *s)
5339 {
5340  int i;
5341  int64_t pos = avio_tell(pb);
5342  avio_wb32(pb, 0); /* size placeholder*/
5343  ffio_wfourcc(pb, "moov");
5344 
5345  mov_setup_track_ids(mov, s);
5346 
5347  for (i = 0; i < mov->nb_tracks; i++) {
5348  if (mov->tracks[i].entry <= 0 && !(mov->flags & FF_MOV_FLAG_FRAGMENT))
5349  continue;
5350 
5351  mov->tracks[i].time = mov->time;
5352 
5353  if (mov->tracks[i].entry)
5354  build_chunks(&mov->tracks[i]);
5355  }
5356 
5357  if (mov->chapter_track)
5358  for (i = 0; i < mov->nb_streams; i++) {
5359  MovTag *tag = mov_add_tref_tag(mov, &mov->tracks[i], MKTAG('c','h','a','p'));
5360  if (!tag)
5361  return AVERROR(ENOMEM);
5362 
5363  int ret = mov_add_tref_id(mov, tag, mov->tracks[mov->chapter_track].track_id);
5364  if (ret < 0)
5365  return ret;
5366  }
5367  for (i = 0; i < mov->nb_tracks; i++) {
5368  MOVTrack *track = &mov->tracks[i];
5369  if (track->tag == MKTAG('r','t','p',' ')) {
5370  MovTag *tag = mov_add_tref_tag(mov, track, MKTAG('h','i','n','t'));
5371  if (!tag)
5372  return AVERROR(ENOMEM);
5373 
5374  av_assert0(track->nb_src_track);
5375  int ret = mov_add_tref_id(mov, tag, mov->tracks[*track->src_track].track_id);
5376  if (ret < 0)
5377  return ret;
5378  } else if (track->tag == MKTAG('l','v','c','1') && track->nb_src_track) {
5379  MovTag *tag = mov_add_tref_tag(mov, track, MKTAG('s','b','a','s'));
5380  if (!tag)
5381  return AVERROR(ENOMEM);
5382 
5383  int ret = mov_add_tref_id(mov, tag, mov->tracks[*track->src_track].track_id);
5384  if (ret < 0)
5385  return ret;
5386  } else {
5387  if (track->par->codec_type == AVMEDIA_TYPE_AUDIO) {
5389  track->st->codecpar->nb_coded_side_data,
5391  if (sd && sd->size == sizeof(int)) {
5392  int *fallback = (int *)sd->data;
5393  if (*fallback >= 0 && *fallback < mov->nb_tracks) {
5394  MovTag *tag = mov_add_tref_tag(mov, track, MKTAG('f','a','l','l'));
5395  if (!tag)
5396  return AVERROR(ENOMEM);
5397 
5398  int ret = mov_add_tref_id(mov, tag, mov->tracks[*fallback].track_id);
5399  if (ret < 0)
5400  return ret;
5401  }
5402  }
5403  }
5404  for (int j = 0; j < track->nb_src_track; j++) {
5405  int src_trk = track->src_track[j];
5406  MovTag *tag = mov_add_tref_tag(mov, &mov->tracks[src_trk], track->tag);
5407  if (!tag)
5408  return AVERROR(ENOMEM);
5409  int ret = mov_add_tref_id(mov, tag, track->track_id);
5410  if (ret < 0)
5411  return ret;
5412  }
5413  if (mov->nb_meta_tmcd && track->nb_src_track) {
5414  /* Derive the duration from the first source track, matching
5415  * the convention used by get_pts_range() and the rtp/lvc1
5416  * branches above. The source may use a different timescale. */
5417  int src_trk = track->src_track[0];
5418  track->track_duration = av_rescale(mov->tracks[src_trk].track_duration,
5419  track->timescale,
5420  mov->tracks[src_trk].timescale);
5421  }
5422  }
5423  }
5424 
5425  mov_write_mvhd_tag(pb, mov);
5426  if (mov->mode != MODE_MOV && mov->mode != MODE_AVIF && !mov->iods_skip)
5427  mov_write_iods_tag(pb, mov);
5428  for (i = 0; i < mov->nb_tracks; i++) {
5429  if (mov->tracks[i].entry > 0 || mov->flags & FF_MOV_FLAG_FRAGMENT ||
5430  mov->mode == MODE_AVIF) {
5431  int ret = mov_write_trak_tag(s, pb, mov, &(mov->tracks[i]), i < mov->nb_streams ? mov->tracks[i].st : NULL);
5432  if (ret < 0)
5433  return ret;
5434  }
5435  }
5436  /* Don't write mvex for hybrid_fragmented during mov_write_trailer
5437  * (mov->moov_written != 0)
5438  */
5439  if (mov->flags & FF_MOV_FLAG_FRAGMENT &&
5441  mov_write_mvex_tag(pb, mov); /* QuickTime requires trak to precede this */
5442 
5443  if (mov->mode == MODE_PSP)
5445  else if (mov->mode != MODE_AVIF)
5446  mov_write_udta_tag(pb, mov, s);
5447  for (i = 0; i < mov->nb_streams; i++)
5448  mov_write_pssh_tag(pb, mov->tracks[i].st);
5449 
5450  return update_size(pb, pos);
5451 }
5452 
5453 static void param_write_int(AVIOContext *pb, const char *name, int value)
5454 {
5455  avio_printf(pb, "<param name=\"%s\" value=\"%d\" valuetype=\"data\"/>\n", name, value);
5456 }
5457 
5458 static void param_write_string(AVIOContext *pb, const char *name, const char *value)
5459 {
5460  avio_printf(pb, "<param name=\"%s\" value=\"%s\" valuetype=\"data\"/>\n", name, value);
5461 }
5462 
5463 static void param_write_hex(AVIOContext *pb, const char *name, const uint8_t *value, int len)
5464 {
5465  char buf[150];
5466  len = FFMIN(sizeof(buf) / 2 - 1, len);
5467  ff_data_to_hex(buf, value, len, 0);
5468  avio_printf(pb, "<param name=\"%s\" value=\"%s\" valuetype=\"data\"/>\n", name, buf);
5469 }
5470 
5472 {
5473  int64_t pos = avio_tell(pb);
5474  int i;
5475 
5476  static const AVUUID uuid = {
5477  0xa5, 0xd4, 0x0b, 0x30, 0xe8, 0x14, 0x11, 0xdd,
5478  0xba, 0x2f, 0x08, 0x00, 0x20, 0x0c, 0x9a, 0x66
5479  };
5480 
5481  avio_wb32(pb, 0);
5482  ffio_wfourcc(pb, "uuid");
5483  avio_write(pb, uuid, AV_UUID_LEN);
5484  avio_wb32(pb, 0);
5485 
5486  avio_printf(pb, "<?xml version=\"1.0\" encoding=\"utf-8\"?>\n");
5487  avio_printf(pb, "<smil xmlns=\"http://www.w3.org/2001/SMIL20/Language\">\n");
5488  avio_printf(pb, "<head>\n");
5489  if (!(mov->fc->flags & AVFMT_FLAG_BITEXACT))
5490  avio_printf(pb, "<meta name=\"creator\" content=\"%s\" />\n",
5492  avio_printf(pb, "</head>\n");
5493  avio_printf(pb, "<body>\n");
5494  avio_printf(pb, "<switch>\n");
5495 
5496  mov_setup_track_ids(mov, s);
5497 
5498  for (i = 0; i < mov->nb_tracks; i++) {
5499  MOVTrack *track = &mov->tracks[i];
5500  struct mpeg4_bit_rate_values bit_rates =
5502  const char *type;
5503  int track_id = track->track_id;
5504  char track_name_buf[32] = { 0 };
5505 
5506  AVStream *st = track->st;
5507  AVDictionaryEntry *lang = av_dict_get(st->metadata, "language", NULL,0);
5508 
5509  if (track->par->codec_type == AVMEDIA_TYPE_VIDEO && !is_cover_image(st)) {
5510  type = "video";
5511  } else if (track->par->codec_type == AVMEDIA_TYPE_AUDIO) {
5512  type = "audio";
5513  } else {
5514  continue;
5515  }
5516 
5517  avio_printf(pb, "<%s systemBitrate=\"%"PRIu32"\">\n", type,
5518  bit_rates.avg_bit_rate);
5519  param_write_int(pb, "systemBitrate", bit_rates.avg_bit_rate);
5520  param_write_int(pb, "trackID", track_id);
5521  param_write_string(pb, "systemLanguage", lang ? lang->value : "und");
5522 
5523  /* Build track name piece by piece: */
5524  /* 1. track type */
5525  av_strlcat(track_name_buf, type, sizeof(track_name_buf));
5526  /* 2. track language, if available */
5527  if (lang)
5528  av_strlcatf(track_name_buf, sizeof(track_name_buf),
5529  "_%s", lang->value);
5530  /* 3. special type suffix */
5531  /* "_cc" = closed captions, "_ad" = audio_description */
5533  av_strlcat(track_name_buf, "_cc", sizeof(track_name_buf));
5535  av_strlcat(track_name_buf, "_ad", sizeof(track_name_buf));
5536 
5537  param_write_string(pb, "trackName", track_name_buf);
5538 
5539  if (track->par->codec_type == AVMEDIA_TYPE_VIDEO) {
5540  if (track->par->codec_id == AV_CODEC_ID_H264) {
5541  uint8_t *ptr;
5542  int size = track->extradata_size[track->last_stsd_index];
5543  if (!ff_avc_write_annexb_extradata(track->extradata[track->last_stsd_index], &ptr,
5544  &size)) {
5545  param_write_hex(pb, "CodecPrivateData",
5546  ptr ? ptr : track->extradata[track->last_stsd_index],
5547  size);
5548  av_free(ptr);
5549  }
5550  param_write_string(pb, "FourCC", "H264");
5551  } else if (track->par->codec_id == AV_CODEC_ID_VC1) {
5552  param_write_string(pb, "FourCC", "WVC1");
5553  param_write_hex(pb, "CodecPrivateData", track->extradata[track->last_stsd_index],
5554  track->extradata_size[track->last_stsd_index]);
5555  }
5556  param_write_int(pb, "MaxWidth", track->par->width);
5557  param_write_int(pb, "MaxHeight", track->par->height);
5558  param_write_int(pb, "DisplayWidth", track->par->width);
5559  param_write_int(pb, "DisplayHeight", track->par->height);
5560  } else {
5561  if (track->par->codec_id == AV_CODEC_ID_AAC) {
5562  switch (track->par->profile) {
5563  case AV_PROFILE_AAC_HE_V2:
5564  param_write_string(pb, "FourCC", "AACP");
5565  break;
5566  case AV_PROFILE_AAC_HE:
5567  param_write_string(pb, "FourCC", "AACH");
5568  break;
5569  default:
5570  param_write_string(pb, "FourCC", "AACL");
5571  }
5572  } else if (track->par->codec_id == AV_CODEC_ID_WMAPRO) {
5573  param_write_string(pb, "FourCC", "WMAP");
5574  }
5575  param_write_hex(pb, "CodecPrivateData", track->extradata[track->last_stsd_index],
5576  track->extradata_size[track->last_stsd_index]);
5578  track->par->codec_id));
5579  param_write_int(pb, "Channels", track->par->ch_layout.nb_channels);
5580  param_write_int(pb, "SamplingRate", track->tag == MKTAG('i','a','m','f') ?
5581  0 : track->par->sample_rate);
5582  param_write_int(pb, "BitsPerSample", 16);
5583  param_write_int(pb, "PacketSize", track->par->block_align ?
5584  track->par->block_align : 4);
5585  }
5586  avio_printf(pb, "</%s>\n", type);
5587  }
5588  avio_printf(pb, "</switch>\n");
5589  avio_printf(pb, "</body>\n");
5590  avio_printf(pb, "</smil>\n");
5591 
5592  return update_size(pb, pos);
5593 }
5594 
5596 {
5597  avio_wb32(pb, 16);
5598  ffio_wfourcc(pb, "mfhd");
5599  avio_wb32(pb, 0);
5600  avio_wb32(pb, mov->fragments);
5601  return 0;
5602 }
5603 
5604 static uint32_t get_sample_flags(MOVTrack *track, MOVIentry *entry)
5605 {
5608 }
5609 
5611  MOVTrack *track, int64_t moof_offset)
5612 {
5613  int64_t pos = avio_tell(pb);
5616  if (!track->entry) {
5618  } else {
5620  }
5623  if (mov->flags & FF_MOV_FLAG_DEFAULT_BASE_MOOF) {
5626  }
5627  /* CMAF requires all values to be explicit in tfhd atoms */
5628  if (mov->flags & FF_MOV_FLAG_CMAF)
5630 
5631  /* Don't set a default sample size, the silverlight player refuses
5632  * to play files with that set. Don't set a default sample duration,
5633  * WMP freaks out if it is set. Don't set a base data offset, PIFF
5634  * file format says it MUST NOT be set. */
5635  if (track->mode == MODE_ISM)
5638 
5639  avio_wb32(pb, 0); /* size placeholder */
5640  ffio_wfourcc(pb, "tfhd");
5641  avio_w8(pb, 0); /* version */
5642  avio_wb24(pb, flags);
5643 
5644  avio_wb32(pb, track->track_id); /* track-id */
5646  avio_wb64(pb, moof_offset);
5647  if (flags & MOV_TFHD_STSD_ID) {
5648  avio_wb32(pb, 1);
5649  }
5651  track->default_duration = get_cluster_duration(track, 0);
5652  avio_wb32(pb, track->default_duration);
5653  }
5654  if (flags & MOV_TFHD_DEFAULT_SIZE) {
5655  track->default_size = track->entry ? track->cluster[0].size : 1;
5656  avio_wb32(pb, track->default_size);
5657  } else
5658  track->default_size = -1;
5659 
5660  if (flags & MOV_TFHD_DEFAULT_FLAGS) {
5661  /* Set the default flags based on the second sample, if available.
5662  * If the first sample is different, that can be signaled via a separate field. */
5663  if (track->entry > 1)
5664  track->default_sample_flags = get_sample_flags(track, &track->cluster[1]);
5665  else
5666  track->default_sample_flags =
5667  track->par->codec_type == AVMEDIA_TYPE_VIDEO ?
5670  avio_wb32(pb, track->default_sample_flags);
5671  }
5672 
5673  return update_size(pb, pos);
5674 }
5675 
5677  MOVTrack *track, int moof_size,
5678  int first, int end)
5679 {
5680  int64_t pos = avio_tell(pb);
5681  uint32_t flags = MOV_TRUN_DATA_OFFSET;
5682  int i;
5683 
5684  for (i = first; i < end; i++) {
5685  if (get_cluster_duration(track, i) != track->default_duration)
5687  if (track->cluster[i].size != track->default_size)
5689  if (i > first && get_sample_flags(track, &track->cluster[i]) != track->default_sample_flags)
5691  }
5692  if (!(flags & MOV_TRUN_SAMPLE_FLAGS) && track->entry > first &&
5693  get_sample_flags(track, &track->cluster[first]) != track->default_sample_flags)
5695  if (track->flags & MOV_TRACK_CTTS)
5697 
5698  avio_wb32(pb, 0); /* size placeholder */
5699  ffio_wfourcc(pb, "trun");
5701  avio_w8(pb, 1); /* version */
5702  else
5703  avio_w8(pb, 0); /* version */
5704  avio_wb24(pb, flags);
5705 
5706  avio_wb32(pb, end - first); /* sample count */
5707  if (mov->flags & FF_MOV_FLAG_OMIT_TFHD_OFFSET &&
5709  !mov->first_trun)
5710  avio_wb32(pb, 0); /* Later tracks follow immediately after the previous one */
5711  else
5712  avio_wb32(pb, moof_size + 8 + track->data_offset +
5713  track->cluster[first].pos); /* data offset */
5715  avio_wb32(pb, get_sample_flags(track, &track->cluster[first]));
5716 
5717  for (i = first; i < end; i++) {
5719  avio_wb32(pb, get_cluster_duration(track, i));
5721  avio_wb32(pb, track->cluster[i].size);
5723  avio_wb32(pb, get_sample_flags(track, &track->cluster[i]));
5724  if (flags & MOV_TRUN_SAMPLE_CTS)
5725  avio_wb32(pb, track->cluster[i].cts);
5726  }
5727 
5728  mov->first_trun = 0;
5729  return update_size(pb, pos);
5730 }
5731 
5732 static int mov_write_tfxd_tag(AVIOContext *pb, MOVTrack *track)
5733 {
5734  int64_t pos = avio_tell(pb);
5735  static const uint8_t uuid[] = {
5736  0x6d, 0x1d, 0x9b, 0x05, 0x42, 0xd5, 0x44, 0xe6,
5737  0x80, 0xe2, 0x14, 0x1d, 0xaf, 0xf7, 0x57, 0xb2
5738  };
5739 
5740  avio_wb32(pb, 0); /* size placeholder */
5741  ffio_wfourcc(pb, "uuid");
5742  avio_write(pb, uuid, AV_UUID_LEN);
5743  avio_w8(pb, 1);
5744  avio_wb24(pb, 0);
5745  avio_wb64(pb, track->cluster[0].dts + track->cluster[0].cts);
5746  avio_wb64(pb, track->end_pts -
5747  (track->cluster[0].dts + track->cluster[0].cts));
5748 
5749  return update_size(pb, pos);
5750 }
5751 
5753  MOVTrack *track, int entry)
5754 {
5755  int n = track->nb_frag_info - 1 - entry, i;
5756  int size = 8 + 16 + 4 + 1 + 16*n;
5757  static const uint8_t uuid[] = {
5758  0xd4, 0x80, 0x7e, 0xf2, 0xca, 0x39, 0x46, 0x95,
5759  0x8e, 0x54, 0x26, 0xcb, 0x9e, 0x46, 0xa7, 0x9f
5760  };
5761 
5762  if (entry < 0)
5763  return 0;
5764 
5765  avio_seek(pb, track->frag_info[entry].tfrf_offset, SEEK_SET);
5766  avio_wb32(pb, size);
5767  ffio_wfourcc(pb, "uuid");
5768  avio_write(pb, uuid, AV_UUID_LEN);
5769  avio_w8(pb, 1);
5770  avio_wb24(pb, 0);
5771  avio_w8(pb, n);
5772  for (i = 0; i < n; i++) {
5773  int index = entry + 1 + i;
5774  avio_wb64(pb, track->frag_info[index].time);
5775  avio_wb64(pb, track->frag_info[index].duration);
5776  }
5777  if (n < mov->ism_lookahead) {
5778  int free_size = 16 * (mov->ism_lookahead - n);
5779  avio_wb32(pb, free_size);
5780  ffio_wfourcc(pb, "free");
5781  ffio_fill(pb, 0, free_size - 8);
5782  }
5783 
5784  return 0;
5785 }
5786 
5788  MOVTrack *track)
5789 {
5790  int64_t pos = avio_tell(pb);
5791  int i;
5792  for (i = 0; i < mov->ism_lookahead; i++) {
5793  /* Update the tfrf tag for the last ism_lookahead fragments,
5794  * nb_frag_info - 1 is the next fragment to be written. */
5795  mov_write_tfrf_tag(pb, mov, track, track->nb_frag_info - 2 - i);
5796  }
5797  avio_seek(pb, pos, SEEK_SET);
5798  return 0;
5799 }
5800 
5801 static int mov_add_tfra_entries(AVIOContext *pb, MOVMuxContext *mov, int tracks,
5802  int size)
5803 {
5804  int i;
5805  for (i = 0; i < mov->nb_tracks; i++) {
5806  MOVTrack *track = &mov->tracks[i];
5808  if ((tracks >= 0 && i != tracks) || !track->entry)
5809  continue;
5810  track->nb_frag_info++;
5811  if (track->nb_frag_info >= track->frag_info_capacity) {
5812  unsigned new_capacity = track->nb_frag_info + MOV_FRAG_INFO_ALLOC_INCREMENT;
5813  if (av_reallocp_array(&track->frag_info,
5814  new_capacity,
5815  sizeof(*track->frag_info)))
5816  return AVERROR(ENOMEM);
5817  track->frag_info_capacity = new_capacity;
5818  }
5819  info = &track->frag_info[track->nb_frag_info - 1];
5820  info->offset = avio_tell(pb);
5821  info->size = size;
5822  // Try to recreate the original pts for the first packet
5823  // from the fields we have stored
5824  info->time = track->cluster[0].dts + track->cluster[0].cts;
5825  info->duration = track->end_pts -
5826  (track->cluster[0].dts + track->cluster[0].cts);
5827  // If the pts is less than zero, we will have trimmed
5828  // away parts of the media track using an edit list,
5829  // and the corresponding start presentation time is zero.
5830  if (info->time < 0) {
5831  info->duration += info->time;
5832  info->time = 0;
5833  }
5834  info->tfrf_offset = 0;
5835  mov_write_tfrf_tags(pb, mov, track);
5836  }
5837  return 0;
5838 }
5839 
5840 static void mov_prune_frag_info(MOVMuxContext *mov, int tracks, int max)
5841 {
5842  int i;
5843  for (i = 0; i < mov->nb_tracks; i++) {
5844  MOVTrack *track = &mov->tracks[i];
5845  if ((tracks >= 0 && i != tracks) || !track->entry)
5846  continue;
5847  if (track->nb_frag_info > max) {
5848  memmove(track->frag_info, track->frag_info + (track->nb_frag_info - max), max * sizeof(*track->frag_info));
5849  track->nb_frag_info = max;
5850  }
5851  }
5852 }
5853 
5854 static int mov_write_tfdt_tag(AVIOContext *pb, MOVTrack *track)
5855 {
5856  int64_t pos = avio_tell(pb);
5857 
5858  avio_wb32(pb, 0); /* size */
5859  ffio_wfourcc(pb, "tfdt");
5860  avio_w8(pb, 1); /* version */
5861  avio_wb24(pb, 0);
5862  avio_wb64(pb, track->cluster[0].dts - track->start_dts);
5863  return update_size(pb, pos);
5864 }
5865 
5867  MOVTrack *track, int64_t moof_offset,
5868  int moof_size)
5869 {
5870  int64_t pos = avio_tell(pb);
5871  int i, start = 0;
5872  avio_wb32(pb, 0); /* size placeholder */
5873  ffio_wfourcc(pb, "traf");
5874 
5875  mov_write_tfhd_tag(pb, mov, track, moof_offset);
5876  if (mov->mode != MODE_ISM)
5877  mov_write_tfdt_tag(pb, track);
5878  for (i = 1; i < track->entry; i++) {
5879  if (track->cluster[i].pos != track->cluster[i - 1].pos + track->cluster[i - 1].size) {
5880  mov_write_trun_tag(pb, mov, track, moof_size, start, i);
5881  start = i;
5882  }
5883  }
5884  mov_write_trun_tag(pb, mov, track, moof_size, start, track->entry);
5885  if (mov->mode == MODE_ISM) {
5886  mov_write_tfxd_tag(pb, track);
5887 
5888  if (mov->ism_lookahead) {
5889  int size = 16 + 4 + 1 + 16 * mov->ism_lookahead;
5890 
5891  if (track->nb_frag_info > 0) {
5892  MOVFragmentInfo *info = &track->frag_info[track->nb_frag_info - 1];
5893  if (!info->tfrf_offset)
5894  info->tfrf_offset = avio_tell(pb);
5895  }
5896  avio_wb32(pb, 8 + size);
5897  ffio_wfourcc(pb, "free");
5898  ffio_fill(pb, 0, size);
5899  }
5900  }
5901 
5902  if (track->cenc.aes_ctr && (mov->flags & FF_MOV_FLAG_FRAGMENT))
5903  ff_mov_cenc_write_stbl_atoms(&track->cenc, pb, moof_offset);
5904 
5905  return update_size(pb, pos);
5906 }
5907 
5909  int tracks, int moof_size)
5910 {
5911  int64_t pos = avio_tell(pb);
5912  int i;
5913 
5914  avio_wb32(pb, 0); /* size placeholder */
5915  ffio_wfourcc(pb, "moof");
5916  mov->first_trun = 1;
5917 
5918  mov_write_mfhd_tag(pb, mov);
5919  for (i = 0; i < mov->nb_tracks; i++) {
5920  MOVTrack *track = &mov->tracks[i];
5921  if (tracks >= 0 && i != tracks)
5922  continue;
5923  if (!track->entry)
5924  continue;
5925  if (track->cenc.aes_ctr && (mov->flags & FF_MOV_FLAG_FRAGMENT))
5926  mov_write_pssh_tag(pb, track->st);
5927  mov_write_traf_tag(pb, mov, track, pos, moof_size);
5928  }
5929 
5930  return update_size(pb, pos);
5931 }
5932 
5934  MOVTrack *track, int ref_size, int total_sidx_size)
5935 {
5936  int64_t pos = avio_tell(pb), offset_pos, end_pos;
5937  int64_t presentation_time, duration, offset;
5938  unsigned starts_with_SAP;
5939  int i, entries;
5940 
5941  if (track->entry) {
5942  entries = 1;
5943  presentation_time = track->cluster[0].dts + track->cluster[0].cts;
5944  duration = track->end_pts -
5945  (track->cluster[0].dts + track->cluster[0].cts);
5946  starts_with_SAP = track->cluster[0].flags & MOV_SYNC_SAMPLE;
5947 
5948  // pts<0 should be cut away using edts
5949  if (presentation_time < 0) {
5950  duration += presentation_time;
5951  presentation_time = 0;
5952  }
5953  } else {
5954  entries = track->nb_frag_info;
5955  if (entries <= 0)
5956  return 0;
5957  presentation_time = track->frag_info[0].time;
5958  }
5959 
5960  avio_wb32(pb, 0); /* size */
5961  ffio_wfourcc(pb, "sidx");
5962  avio_w8(pb, 1); /* version */
5963  avio_wb24(pb, 0);
5964  avio_wb32(pb, track->track_id); /* reference_ID */
5965  avio_wb32(pb, track->timescale); /* timescale */
5966  avio_wb64(pb, presentation_time); /* earliest_presentation_time */
5967  offset_pos = avio_tell(pb);
5968  avio_wb64(pb, 0); /* first_offset (offset to referenced moof) */
5969  avio_wb16(pb, 0); /* reserved */
5970 
5971  avio_wb16(pb, entries); /* reference_count */
5972  for (i = 0; i < entries; i++) {
5973  if (!track->entry) {
5974  if (i > 1 && track->frag_info[i].offset != track->frag_info[i - 1].offset + track->frag_info[i - 1].size) {
5975  av_log(NULL, AV_LOG_ERROR, "Non-consecutive fragments, writing incorrect sidx\n");
5976  }
5977  duration = track->frag_info[i].duration;
5978  ref_size = track->frag_info[i].size;
5979  starts_with_SAP = 1;
5980  }
5981  avio_wb32(pb, (0 << 31) | (ref_size & 0x7fffffff)); /* reference_type (0 = media) | referenced_size */
5982  avio_wb32(pb, duration); /* subsegment_duration */
5983  avio_wb32(pb, (starts_with_SAP << 31) | (0 << 28) | 0); /* starts_with_SAP | SAP_type | SAP_delta_time */
5984  }
5985 
5986  end_pos = avio_tell(pb);
5987  offset = pos + total_sidx_size - end_pos;
5988  avio_seek(pb, offset_pos, SEEK_SET);
5989  avio_wb64(pb, offset);
5990  avio_seek(pb, end_pos, SEEK_SET);
5991  return update_size(pb, pos);
5992 }
5993 
5995  int tracks, int ref_size)
5996 {
5997  int i, round, ret;
5998  AVIOContext *avio_buf;
5999  int total_size = 0;
6000  for (round = 0; round < 2; round++) {
6001  // First run one round to calculate the total size of all
6002  // sidx atoms.
6003  // This would be much simpler if we'd only write one sidx
6004  // atom, for the first track in the moof.
6005  if (round == 0) {
6006  if ((ret = ffio_open_null_buf(&avio_buf)) < 0)
6007  return ret;
6008  } else {
6009  avio_buf = pb;
6010  }
6011  for (i = 0; i < mov->nb_tracks; i++) {
6012  MOVTrack *track = &mov->tracks[i];
6013  if (tracks >= 0 && i != tracks)
6014  continue;
6015  // When writing a sidx for the full file, entry is 0, but
6016  // we want to include all tracks. ref_size is 0 in this case,
6017  // since we read it from frag_info instead.
6018  if (!track->entry && ref_size > 0)
6019  continue;
6020  total_size -= mov_write_sidx_tag(avio_buf, track, ref_size,
6021  total_size);
6022  }
6023  if (round == 0) {
6024  total_size = ffio_close_null_buf(avio_buf);
6025  if (total_size < 0)
6026  return total_size;
6027  }
6028  }
6029  return 0;
6030 }
6031 
6032 static int mov_write_prft_tag(AVIOContext *pb, MOVMuxContext *mov, int tracks)
6033 {
6034  int64_t pos = avio_tell(pb), pts_us, ntp_ts;
6035  MOVTrack *first_track;
6036  int flags = 24;
6037 
6038  /* PRFT should be associated with at most one track. So, choosing only the
6039  * first track. */
6040  if (tracks > 0)
6041  return 0;
6042  first_track = &(mov->tracks[0]);
6043 
6044  if (!first_track->entry) {
6045  av_log(mov->fc, AV_LOG_WARNING, "Unable to write PRFT, no entries in the track\n");
6046  return 0;
6047  }
6048 
6049  if (first_track->cluster[0].pts == AV_NOPTS_VALUE) {
6050  av_log(mov->fc, AV_LOG_WARNING, "Unable to write PRFT, first PTS is invalid\n");
6051  return 0;
6052  }
6053 
6054  if (mov->write_prft == MOV_PRFT_SRC_WALLCLOCK) {
6055  if (first_track->cluster[0].prft.wallclock) {
6056  /* Round the NTP time to whole milliseconds. */
6057  ntp_ts = ff_get_formatted_ntp_time((first_track->cluster[0].prft.wallclock / 1000) * 1000 +
6058  NTP_OFFSET_US);
6059  flags = first_track->cluster[0].prft.flags;
6060  } else
6062  } else if (mov->write_prft == MOV_PRFT_SRC_PTS) {
6063  pts_us = av_rescale_q(first_track->cluster[0].pts,
6064  first_track->st->time_base, AV_TIME_BASE_Q);
6065  ntp_ts = ff_get_formatted_ntp_time(pts_us + NTP_OFFSET_US);
6066  } else {
6067  av_log(mov->fc, AV_LOG_WARNING, "Unsupported PRFT box configuration: %d\n",
6068  mov->write_prft);
6069  return 0;
6070  }
6071 
6072  avio_wb32(pb, 0); // Size place holder
6073  ffio_wfourcc(pb, "prft"); // Type
6074  avio_w8(pb, 1); // Version
6075  avio_wb24(pb, flags); // Flags
6076  avio_wb32(pb, first_track->track_id); // reference track ID
6077  avio_wb64(pb, ntp_ts); // NTP time stamp
6078  avio_wb64(pb, first_track->cluster[0].pts); //media time
6079  return update_size(pb, pos);
6080 }
6081 
6082 static int mov_write_moof_tag(AVIOContext *pb, MOVMuxContext *mov, int tracks,
6083  int64_t mdat_size)
6084 {
6085  AVIOContext *avio_buf;
6086  int ret, moof_size;
6087 
6088  if ((ret = ffio_open_null_buf(&avio_buf)) < 0)
6089  return ret;
6090  mov_write_moof_tag_internal(avio_buf, mov, tracks, 0);
6091  moof_size = ffio_close_null_buf(avio_buf);
6092  if (moof_size < 0)
6093  return moof_size;
6094 
6095  if (mov->flags & FF_MOV_FLAG_DASH &&
6097  mov_write_sidx_tags(pb, mov, tracks, moof_size + 8 + mdat_size);
6098 
6099  if (mov->write_prft > MOV_PRFT_NONE && mov->write_prft < MOV_PRFT_NB)
6100  mov_write_prft_tag(pb, mov, tracks);
6101 
6102  if (mov->flags & FF_MOV_FLAG_GLOBAL_SIDX ||
6103  !(mov->flags & FF_MOV_FLAG_SKIP_TRAILER) ||
6104  mov->ism_lookahead) {
6105  if ((ret = mov_add_tfra_entries(pb, mov, tracks, moof_size + 8 + mdat_size)) < 0)
6106  return ret;
6107  if (!(mov->flags & FF_MOV_FLAG_GLOBAL_SIDX) &&
6109  mov_prune_frag_info(mov, tracks, mov->ism_lookahead + 1);
6110  }
6111  }
6112 
6113  return mov_write_moof_tag_internal(pb, mov, tracks, moof_size);
6114 }
6115 
6116 static int mov_write_tfra_tag(AVIOContext *pb, MOVTrack *track)
6117 {
6118  int64_t pos = avio_tell(pb);
6119  int i;
6120 
6121  avio_wb32(pb, 0); /* size placeholder */
6122  ffio_wfourcc(pb, "tfra");
6123  avio_w8(pb, 1); /* version */
6124  avio_wb24(pb, 0);
6125 
6126  avio_wb32(pb, track->track_id);
6127  avio_wb32(pb, 0); /* length of traf/trun/sample num */
6128  avio_wb32(pb, track->nb_frag_info);
6129  for (i = 0; i < track->nb_frag_info; i++) {
6130  avio_wb64(pb, track->frag_info[i].time);
6131  avio_wb64(pb, track->frag_info[i].offset + track->data_offset);
6132  avio_w8(pb, 1); /* traf number */
6133  avio_w8(pb, 1); /* trun number */
6134  avio_w8(pb, 1); /* sample number */
6135  }
6136 
6137  return update_size(pb, pos);
6138 }
6139 
6141 {
6142  AVIOContext *mfra_pb;
6143  int i, ret, sz;
6144  uint8_t *buf;
6145 
6146  ret = avio_open_dyn_buf(&mfra_pb);
6147  if (ret < 0)
6148  return ret;
6149 
6150  avio_wb32(mfra_pb, 0); /* size placeholder */
6151  ffio_wfourcc(mfra_pb, "mfra");
6152  /* An empty mfra atom is enough to indicate to the publishing point that
6153  * the stream has ended. */
6154  if (mov->flags & FF_MOV_FLAG_ISML)
6155  goto done_mfra;
6156 
6157  for (i = 0; i < mov->nb_tracks; i++) {
6158  MOVTrack *track = &mov->tracks[i];
6159  if (track->nb_frag_info)
6160  mov_write_tfra_tag(mfra_pb, track);
6161  }
6162 
6163  avio_wb32(mfra_pb, 16);
6164  ffio_wfourcc(mfra_pb, "mfro");
6165  avio_wb32(mfra_pb, 0); /* version + flags */
6166  avio_wb32(mfra_pb, avio_tell(mfra_pb) + 4);
6167 
6168 done_mfra:
6169 
6170  sz = update_size(mfra_pb, 0);
6171  ret = avio_get_dyn_buf(mfra_pb, &buf);
6172  avio_write(pb, buf, ret);
6173  ffio_free_dyn_buf(&mfra_pb);
6174 
6175  return sz;
6176 }
6177 
6179 {
6180  avio_wb32(pb, 8); // placeholder for extended size field (64 bit)
6181  ffio_wfourcc(pb, mov->mode == MODE_MOV ? "wide" : "free");
6182 
6183  mov->mdat_pos = avio_tell(pb);
6184  avio_wb32(pb, 0); /* size placeholder*/
6185  ffio_wfourcc(pb, "mdat");
6186  return 0;
6187 }
6188 
6190  int has_h264, int has_video, int write_minor)
6191 {
6192  MOVMuxContext *mov = s->priv_data;
6193  int minor = 0x200;
6194 
6195  if (mov->major_brand && strlen(mov->major_brand) >= 4)
6196  ffio_wfourcc(pb, mov->major_brand);
6197  else if (mov->mode == MODE_3GP) {
6198  ffio_wfourcc(pb, has_h264 ? "3gp6" : "3gp4");
6199  minor = has_h264 ? 0x100 : 0x200;
6200  } else if (mov->mode == MODE_AVIF) {
6201  ffio_wfourcc(pb, mov->is_animated_avif ? "avis" : "avif");
6202  minor = 0;
6203  } else if (mov->mode & MODE_3G2) {
6204  ffio_wfourcc(pb, has_h264 ? "3g2b" : "3g2a");
6205  minor = has_h264 ? 0x20000 : 0x10000;
6206  } else if (mov->mode == MODE_PSP)
6207  ffio_wfourcc(pb, "MSNV");
6208  else if (mov->mode == MODE_MP4 && mov->flags & FF_MOV_FLAG_FRAGMENT &&
6210  ffio_wfourcc(pb, "iso6"); // Required when using signed CTS offsets in trun boxes
6211  else if (mov->mode == MODE_MP4 && mov->flags & FF_MOV_FLAG_DEFAULT_BASE_MOOF)
6212  ffio_wfourcc(pb, "iso5"); // Required when using default-base-is-moof
6213  else if (mov->mode == MODE_MP4 && mov->flags & FF_MOV_FLAG_NEGATIVE_CTS_OFFSETS)
6214  ffio_wfourcc(pb, "iso4");
6215  else if (mov->mode == MODE_MP4)
6216  ffio_wfourcc(pb, "isom");
6217  else if (mov->mode == MODE_IPOD)
6218  ffio_wfourcc(pb, has_video ? "M4V ":"M4A ");
6219  else if (mov->mode == MODE_ISM)
6220  ffio_wfourcc(pb, "isml");
6221  else if (mov->mode == MODE_F4V)
6222  ffio_wfourcc(pb, "f4v ");
6223  else
6224  ffio_wfourcc(pb, "qt ");
6225 
6226  if (write_minor)
6227  avio_wb32(pb, minor);
6228 }
6229 
6231 {
6232  MOVMuxContext *mov = s->priv_data;
6233  int64_t pos = avio_tell(pb);
6234  int has_h264 = 0, has_av1 = 0, has_video = 0, has_dolby = 0, has_id3 = 0;
6235  int has_iamf = 0;
6236 
6237 #if CONFIG_IAMFENC
6238  for (int i = 0; i < s->nb_stream_groups; i++) {
6239  const AVStreamGroup *stg = s->stream_groups[i];
6240 
6243  has_iamf = 1;
6244  break;
6245  }
6246  }
6247 #endif
6248  for (int i = 0; i < mov->nb_streams; i++) {
6249  AVStream *st = mov->tracks[i].st;
6250  if (is_cover_image(st))
6251  continue;
6253  has_video = 1;
6254  if (st->codecpar->codec_id == AV_CODEC_ID_H264)
6255  has_h264 = 1;
6256  if (st->codecpar->codec_id == AV_CODEC_ID_AV1)
6257  has_av1 = 1;
6258  if (st->codecpar->codec_id == AV_CODEC_ID_AC3 ||
6264  has_dolby = 1;
6266  has_id3 = 1;
6267  }
6268 
6269  avio_wb32(pb, 0); /* size */
6270  ffio_wfourcc(pb, "ftyp");
6271 
6272  // Write major brand
6273  mov_write_ftyp_tag_internal(pb, s, has_h264, has_video, 1);
6274  // Write the major brand as the first compatible brand as well
6275  mov_write_ftyp_tag_internal(pb, s, has_h264, has_video, 0);
6276 
6277  // Write compatible brands, ensuring that we don't write the major brand as a
6278  // compatible brand a second time.
6279  if (mov->mode == MODE_ISM) {
6280  ffio_wfourcc(pb, "piff");
6281  } else if (mov->mode == MODE_AVIF) {
6282  const AVPixFmtDescriptor *pix_fmt_desc =
6283  av_pix_fmt_desc_get(s->streams[0]->codecpar->format);
6284  const int depth = pix_fmt_desc->comp[0].depth;
6285  if (mov->is_animated_avif) {
6286  // For animated AVIF, major brand is "avis". Add "avif" as a
6287  // compatible brand.
6288  ffio_wfourcc(pb, "avif");
6289  ffio_wfourcc(pb, "msf1");
6290  ffio_wfourcc(pb, "iso8");
6291  }
6292  ffio_wfourcc(pb, "mif1");
6293  ffio_wfourcc(pb, "miaf");
6294  if (depth == 8 || depth == 10) {
6295  // MA1B and MA1A brands are based on AV1 profile. Short hand for
6296  // computing that is based on chroma subsampling type. 420 chroma
6297  // subsampling is MA1B. 444 chroma subsampling is MA1A.
6298  if (!pix_fmt_desc->log2_chroma_w && !pix_fmt_desc->log2_chroma_h) {
6299  // 444 chroma subsampling.
6300  ffio_wfourcc(pb, "MA1A");
6301  } else {
6302  // 420 chroma subsampling.
6303  ffio_wfourcc(pb, "MA1B");
6304  }
6305  }
6306  } else if (mov->mode != MODE_MOV) {
6307  // We add tfdt atoms when fragmenting, signal this with the iso6 compatible
6308  // brand, if not already the major brand. This is compatible with users that
6309  // don't understand tfdt.
6310  if (mov->mode == MODE_MP4) {
6311  if (mov->flags & FF_MOV_FLAG_CMAF)
6312  ffio_wfourcc(pb, "cmfc");
6314  ffio_wfourcc(pb, "iso6");
6315  if (has_av1)
6316  ffio_wfourcc(pb, "av01");
6317  if (has_dolby)
6318  ffio_wfourcc(pb, "dby1");
6319  if (has_iamf)
6320  ffio_wfourcc(pb, "iamf");
6321  } else {
6322  if (mov->flags & FF_MOV_FLAG_FRAGMENT)
6323  ffio_wfourcc(pb, "iso6");
6325  ffio_wfourcc(pb, "iso5");
6326  else if (mov->flags & FF_MOV_FLAG_NEGATIVE_CTS_OFFSETS)
6327  ffio_wfourcc(pb, "iso4");
6328  }
6329  // Brands prior to iso5 can't be signaled when using default-base-is-moof
6330  if (!(mov->flags & FF_MOV_FLAG_DEFAULT_BASE_MOOF)) {
6331  // write isom for mp4 only if it it's not the major brand already.
6332  if (mov->mode != MODE_MP4 || mov->flags & FF_MOV_FLAG_NEGATIVE_CTS_OFFSETS)
6333  ffio_wfourcc(pb, "isom");
6334  ffio_wfourcc(pb, "iso2");
6335  if (has_h264)
6336  ffio_wfourcc(pb, "avc1");
6337  }
6338  }
6339 
6340  if (mov->mode == MODE_MP4)
6341  ffio_wfourcc(pb, "mp41");
6342 
6343  if (mov->flags & FF_MOV_FLAG_DASH && mov->flags & FF_MOV_FLAG_GLOBAL_SIDX)
6344  ffio_wfourcc(pb, "dash");
6345 
6346  if (has_id3)
6347  ffio_wfourcc(pb, "aid3");
6348 
6349  return update_size(pb, pos);
6350 }
6351 
6353 {
6354  AVStream *video_st = s->streams[0];
6355  AVCodecParameters *video_par = s->streams[0]->codecpar;
6356  AVCodecParameters *audio_par = s->streams[1]->codecpar;
6357  int audio_rate = audio_par->sample_rate;
6358  int64_t frame_rate = video_st->avg_frame_rate.den ?
6360  0;
6361  int audio_kbitrate = audio_par->bit_rate / 1000;
6362  int video_kbitrate = FFMIN(video_par->bit_rate / 1000, 800 - audio_kbitrate);
6363 
6364  if (frame_rate < 0 || frame_rate > INT32_MAX) {
6365  av_log(s, AV_LOG_ERROR, "Frame rate %f outside supported range\n", frame_rate / (double)0x10000);
6366  return AVERROR(EINVAL);
6367  }
6368 
6369  avio_wb32(pb, 0x94); /* size */
6370  ffio_wfourcc(pb, "uuid");
6371  ffio_wfourcc(pb, "PROF");
6372 
6373  avio_wb32(pb, 0x21d24fce); /* 96 bit UUID */
6374  avio_wb32(pb, 0xbb88695c);
6375  avio_wb32(pb, 0xfac9c740);
6376 
6377  avio_wb32(pb, 0x0); /* ? */
6378  avio_wb32(pb, 0x3); /* 3 sections ? */
6379 
6380  avio_wb32(pb, 0x14); /* size */
6381  ffio_wfourcc(pb, "FPRF");
6382  avio_wb32(pb, 0x0); /* ? */
6383  avio_wb32(pb, 0x0); /* ? */
6384  avio_wb32(pb, 0x0); /* ? */
6385 
6386  avio_wb32(pb, 0x2c); /* size */
6387  ffio_wfourcc(pb, "APRF"); /* audio */
6388  avio_wb32(pb, 0x0);
6389  avio_wb32(pb, 0x2); /* TrackID */
6390  ffio_wfourcc(pb, "mp4a");
6391  avio_wb32(pb, 0x20f);
6392  avio_wb32(pb, 0x0);
6393  avio_wb32(pb, audio_kbitrate);
6394  avio_wb32(pb, audio_kbitrate);
6395  avio_wb32(pb, audio_rate);
6396  avio_wb32(pb, audio_par->ch_layout.nb_channels);
6397 
6398  avio_wb32(pb, 0x34); /* size */
6399  ffio_wfourcc(pb, "VPRF"); /* video */
6400  avio_wb32(pb, 0x0);
6401  avio_wb32(pb, 0x1); /* TrackID */
6402  if (video_par->codec_id == AV_CODEC_ID_H264) {
6403  ffio_wfourcc(pb, "avc1");
6404  avio_wb16(pb, 0x014D);
6405  avio_wb16(pb, 0x0015);
6406  } else {
6407  ffio_wfourcc(pb, "mp4v");
6408  avio_wb16(pb, 0x0000);
6409  avio_wb16(pb, 0x0103);
6410  }
6411  avio_wb32(pb, 0x0);
6412  avio_wb32(pb, video_kbitrate);
6413  avio_wb32(pb, video_kbitrate);
6414  avio_wb32(pb, frame_rate);
6415  avio_wb32(pb, frame_rate);
6416  avio_wb16(pb, video_par->width);
6417  avio_wb16(pb, video_par->height);
6418  avio_wb32(pb, 0x010001); /* ? */
6419 
6420  return 0;
6421 }
6422 
6424 {
6425  MOVMuxContext *mov = s->priv_data;
6426  int i;
6427 
6428  mov_write_ftyp_tag(pb,s);
6429  if (mov->mode == MODE_PSP) {
6430  int video_streams_nb = 0, audio_streams_nb = 0, other_streams_nb = 0;
6431  for (i = 0; i < mov->nb_streams; i++) {
6432  AVStream *st = mov->tracks[i].st;
6433  if (is_cover_image(st))
6434  continue;
6436  video_streams_nb++;
6437  else if (st->codecpar->codec_type == AVMEDIA_TYPE_AUDIO)
6438  audio_streams_nb++;
6439  else
6440  other_streams_nb++;
6441  }
6442 
6443  if (video_streams_nb != 1 || audio_streams_nb != 1 || other_streams_nb) {
6444  av_log(s, AV_LOG_ERROR, "PSP mode need one video and one audio stream\n");
6445  return AVERROR(EINVAL);
6446  }
6447  return mov_write_uuidprof_tag(pb, s);
6448  }
6449  return 0;
6450 }
6451 
6452 static int mov_parse_mpeg2_frame(AVPacket *pkt, uint32_t *flags)
6453 {
6454  uint32_t c = -1;
6455  int i, closed_gop = 0;
6456 
6457  for (i = 0; i < pkt->size - 4; i++) {
6458  c = (c << 8) + pkt->data[i];
6459  if (c == 0x1b8) { // gop
6460  closed_gop = pkt->data[i + 4] >> 6 & 0x01;
6461  } else if (c == 0x100) { // pic
6462  int temp_ref = (pkt->data[i + 1] << 2) | (pkt->data[i + 2] >> 6);
6463  if (!temp_ref || closed_gop) // I picture is not reordered
6465  else
6467  break;
6468  }
6469  }
6470  return 0;
6471 }
6472 
6474 {
6475  const uint8_t *start, *next, *end = pkt->data + pkt->size;
6476  int seq = 0, entry = 0;
6477  int key = pkt->flags & AV_PKT_FLAG_KEY;
6478  start = find_next_marker(pkt->data, end);
6479  for (next = start; next < end; start = next) {
6480  next = find_next_marker(start + 4, end);
6481  switch (AV_RB32(start)) {
6482  case VC1_CODE_SEQHDR:
6483  seq = 1;
6484  break;
6485  case VC1_CODE_ENTRYPOINT:
6486  entry = 1;
6487  break;
6488  case VC1_CODE_SLICE:
6489  trk->vc1_info.slices = 1;
6490  break;
6491  }
6492  }
6493  if (!trk->entry && trk->vc1_info.first_packet_seen)
6494  trk->vc1_info.first_frag_written = 1;
6495  if (!trk->entry && !trk->vc1_info.first_frag_written) {
6496  /* First packet in first fragment */
6497  trk->vc1_info.first_packet_seq = seq;
6499  trk->vc1_info.first_packet_seen = 1;
6500  } else if ((seq && !trk->vc1_info.packet_seq) ||
6501  (entry && !trk->vc1_info.packet_entry)) {
6502  int i;
6503  for (i = 0; i < trk->entry; i++)
6504  trk->cluster[i].flags &= ~MOV_SYNC_SAMPLE;
6505  trk->has_keyframes = 0;
6506  if (seq)
6507  trk->vc1_info.packet_seq = 1;
6508  if (entry)
6509  trk->vc1_info.packet_entry = 1;
6510  if (!trk->vc1_info.first_frag_written) {
6511  /* First fragment */
6512  if ((!seq || trk->vc1_info.first_packet_seq) &&
6513  (!entry || trk->vc1_info.first_packet_entry)) {
6514  /* First packet had the same headers as this one, readd the
6515  * sync sample flag. */
6516  trk->cluster[0].flags |= MOV_SYNC_SAMPLE;
6517  trk->has_keyframes = 1;
6518  }
6519  }
6520  }
6521  if (trk->vc1_info.packet_seq && trk->vc1_info.packet_entry)
6522  key = seq && entry;
6523  else if (trk->vc1_info.packet_seq)
6524  key = seq;
6525  else if (trk->vc1_info.packet_entry)
6526  key = entry;
6527  if (key) {
6528  trk->cluster[trk->entry].flags |= MOV_SYNC_SAMPLE;
6529  trk->has_keyframes++;
6530  }
6531 }
6532 
6534 {
6535  int length;
6536 
6537  if (pkt->size < 8)
6538  return;
6539 
6540  length = (AV_RB16(pkt->data) & 0xFFF) * 2;
6541  if (length < 8 || length > pkt->size)
6542  return;
6543 
6544  if (AV_RB32(pkt->data + 4) == 0xF8726FBA) {
6545  trk->cluster[trk->entry].flags |= MOV_SYNC_SAMPLE;
6546  trk->has_keyframes++;
6547  }
6548 
6549  return;
6550 }
6551 
6553 {
6554  MOVMuxContext *mov = s->priv_data;
6555  int ret, buf_size;
6556  uint8_t *buf;
6557  int i, offset;
6558 
6559  if (!track->mdat_buf)
6560  return 0;
6561  if (!mov->mdat_buf) {
6562  if ((ret = avio_open_dyn_buf(&mov->mdat_buf)) < 0)
6563  return ret;
6564  }
6565  buf_size = avio_get_dyn_buf(track->mdat_buf, &buf);
6566 
6567  offset = avio_tell(mov->mdat_buf);
6568  avio_write(mov->mdat_buf, buf, buf_size);
6569  ffio_reset_dyn_buf(track->mdat_buf);
6570 
6571  for (i = track->entries_flushed; i < track->entry; i++)
6572  track->cluster[i].pos += offset;
6573  track->entries_flushed = track->entry;
6574  return 0;
6575 }
6576 
6578 {
6579  MOVMuxContext *mov = s->priv_data;
6580  AVPacket *squashed_packet = mov->pkt;
6581  int ret = AVERROR_BUG;
6582 
6583  switch (track->st->codecpar->codec_id) {
6584  case AV_CODEC_ID_TTML: {
6585  int had_packets = !!track->squashed_packet_queue.head;
6586 
6587  if ((ret = ff_mov_generate_squashed_ttml_packet(s, track, squashed_packet)) < 0) {
6588  goto finish_squash;
6589  }
6590 
6591  // We have generated a padding packet (no actual input packets in
6592  // queue) and its duration is zero. Skipping writing it.
6593  if (!had_packets && squashed_packet->duration == 0) {
6594  goto finish_squash;
6595  }
6596 
6597  track->end_reliable = 1;
6598  break;
6599  }
6600  default:
6601  ret = AVERROR(EINVAL);
6602  goto finish_squash;
6603  }
6604 
6605  squashed_packet->stream_index = track->st->index;
6606 
6607  ret = mov_write_single_packet(s, squashed_packet);
6608 
6609 finish_squash:
6610  av_packet_unref(squashed_packet);
6611 
6612  return ret;
6613 }
6614 
6616 {
6617  MOVMuxContext *mov = s->priv_data;
6618 
6619  for (int i = 0; i < mov->nb_streams; i++) {
6620  MOVTrack *track = &mov->tracks[i];
6621  int ret = AVERROR_BUG;
6622 
6623  if (track->squash_fragment_samples_to_one && !track->entry) {
6624  if ((ret = mov_write_squashed_packet(s, track)) < 0) {
6626  "Failed to write squashed packet for %s stream with "
6627  "index %d and track id %d. Error: %s\n",
6629  track->st->index, track->track_id,
6630  av_err2str(ret));
6631  return ret;
6632  }
6633  }
6634  }
6635 
6636  return 0;
6637 }
6638 
6640  int64_t ref_pos)
6641 {
6642  int i;
6643  if (!track->entry)
6644  return 0;
6645  if (mov->flags & FF_MOV_FLAG_HYBRID_FRAGMENTED) {
6646  for (i = 0; i < track->entry; i++)
6647  track->cluster[i].pos += ref_pos + track->data_offset;
6648  if (track->cluster_written == 0) {
6649  // First flush. Chunking for this fragment may already have been
6650  // done, either if we didn't use empty_moov, or if we did use
6651  // delay_moov. In either case, reset chunking here.
6652  for (i = 0; i < track->entry; i++) {
6653  track->cluster[i].chunkNum = 0;
6654  track->cluster[i].samples_in_chunk = track->cluster[i].entries;
6655  }
6656  }
6657  if (av_reallocp_array(&track->cluster_written,
6658  track->entry_written + track->entry,
6659  sizeof(*track->cluster)))
6660  return AVERROR(ENOMEM);
6661  memcpy(&track->cluster_written[track->entry_written],
6662  track->cluster, track->entry * sizeof(*track->cluster));
6663  track->entry_written += track->entry;
6664  }
6665  track->entry = 0;
6666  track->entries_flushed = 0;
6667  track->end_reliable = 0;
6668  return 0;
6669 }
6670 
6671 static int mov_flush_fragment(AVFormatContext *s, int force)
6672 {
6673  MOVMuxContext *mov = s->priv_data;
6674  int i, first_track = -1;
6675  int64_t mdat_size = 0, mdat_start = 0;
6676  int ret;
6677  int has_video = 0, starts_with_key = 0, first_video_track = 1;
6678 
6679  if (!(mov->flags & FF_MOV_FLAG_FRAGMENT))
6680  return 0;
6681 
6682  // Check if we have any tracks that require squashing.
6683  // In that case, we'll have to write the packet here.
6684  if ((ret = mov_write_squashed_packets(s)) < 0)
6685  return ret;
6686 
6687  // Try to fill in the duration of the last packet in each stream
6688  // from queued packets in the interleave queues. If the flushing
6689  // of fragments was triggered automatically by an AVPacket, we
6690  // already have reliable info for the end of that track, but other
6691  // tracks may need to be filled in.
6692  for (i = 0; i < mov->nb_streams; i++) {
6693  MOVTrack *track = &mov->tracks[i];
6694  if (!track->end_reliable) {
6695  const AVPacket *pkt = ff_interleaved_peek(s, i);
6696  if (pkt) {
6697  int64_t offset, dts, pts;
6699  pts = pkt->pts + offset;
6700  dts = pkt->dts + offset;
6701  if (track->dts_shift != AV_NOPTS_VALUE)
6702  dts += track->dts_shift;
6703  track->track_duration = dts - track->start_dts;
6704  if (pts != AV_NOPTS_VALUE)
6705  track->end_pts = pts;
6706  else
6707  track->end_pts = dts;
6708  if (!(pkt->flags & AV_PKT_FLAG_DISCARD))
6709  track->elst_end_pts = track->end_pts;
6710  }
6711  }
6712  }
6713 
6714  for (i = 0; i < mov->nb_tracks; i++) {
6715  MOVTrack *track = &mov->tracks[i];
6716  if (track->entry <= 1)
6717  continue;
6718  // Sample durations are calculated as the diff of dts values,
6719  // but for the last sample in a fragment, we don't know the dts
6720  // of the first sample in the next fragment, so we have to rely
6721  // on what was set as duration in the AVPacket. Not all callers
6722  // set this though, so we might want to replace it with an
6723  // estimate if it currently is zero.
6724  if (get_cluster_duration(track, track->entry - 1) != 0)
6725  continue;
6726  // Use the duration (i.e. dts diff) of the second last sample for
6727  // the last one. This is a wild guess (and fatal if it turns out
6728  // to be too long), but probably the best we can do - having a zero
6729  // duration is bad as well.
6730  track->track_duration += get_cluster_duration(track, track->entry - 2);
6731  track->end_pts += get_cluster_duration(track, track->entry - 2);
6732  if (!mov->missing_duration_warned) {
6734  "Estimating the duration of the last packet in a "
6735  "fragment, consider setting the duration field in "
6736  "AVPacket instead.\n");
6737  mov->missing_duration_warned = 1;
6738  }
6739  }
6740 
6741  if (!mov->moov_written) {
6742  int64_t pos = avio_tell(s->pb);
6743  uint8_t *buf;
6744  int buf_size, moov_size;
6745 
6746  for (i = 0; i < mov->nb_tracks; i++)
6747  if (!mov->tracks[i].entry && !is_cover_image(mov->tracks[i].st))
6748  break;
6749  /* Don't write the initial moov unless all tracks have data */
6750  if (i < mov->nb_tracks && !force)
6751  return 0;
6752 
6753  moov_size = get_moov_size(s);
6754  for (i = 0; i < mov->nb_tracks; i++)
6755  mov->tracks[i].data_offset = pos + moov_size + 8;
6756 
6758  if (mov->flags & FF_MOV_FLAG_DELAY_MOOV &&
6761  if ((ret = mov_write_moov_tag(s->pb, mov, s)) < 0)
6762  return ret;
6763 
6764  if (mov->flags & FF_MOV_FLAG_DELAY_MOOV) {
6765  if (mov->flags & FF_MOV_FLAG_GLOBAL_SIDX)
6766  mov->reserved_header_pos = avio_tell(s->pb);
6768  mov->moov_written = 1;
6769  return 0;
6770  }
6771 
6772  buf_size = avio_get_dyn_buf(mov->mdat_buf, &buf);
6773  avio_wb32(s->pb, buf_size + 8);
6774  ffio_wfourcc(s->pb, "mdat");
6775  avio_write(s->pb, buf, buf_size);
6777 
6778  if (mov->flags & FF_MOV_FLAG_GLOBAL_SIDX)
6779  mov->reserved_header_pos = avio_tell(s->pb);
6780 
6781  mov->moov_written = 1;
6782  mov->mdat_size = 0;
6783  for (i = 0; i < mov->nb_tracks; i++)
6784  mov_finish_fragment(mov, &mov->tracks[i], 0);
6786  return 0;
6787  }
6788 
6789  if (mov->frag_interleave) {
6790  for (i = 0; i < mov->nb_tracks; i++) {
6791  MOVTrack *track = &mov->tracks[i];
6792  int ret;
6793  if ((ret = mov_flush_fragment_interleaving(s, track)) < 0)
6794  return ret;
6795  }
6796 
6797  if (!mov->mdat_buf)
6798  return 0;
6799  mdat_size = avio_tell(mov->mdat_buf);
6800  }
6801 
6802  for (i = 0; i < mov->nb_tracks; i++) {
6803  MOVTrack *track = &mov->tracks[i];
6804  if (mov->flags & FF_MOV_FLAG_SEPARATE_MOOF || mov->frag_interleave)
6805  track->data_offset = 0;
6806  else
6807  track->data_offset = mdat_size;
6808  if (track->par->codec_type == AVMEDIA_TYPE_VIDEO) {
6809  has_video = 1;
6810  if (first_video_track) {
6811  if (track->entry)
6812  starts_with_key = track->cluster[0].flags & MOV_SYNC_SAMPLE;
6813  first_video_track = 0;
6814  }
6815  }
6816  if (!track->entry)
6817  continue;
6818  if (track->mdat_buf)
6819  mdat_size += avio_tell(track->mdat_buf);
6820  if (first_track < 0)
6821  first_track = i;
6822  }
6823 
6824  if (!mdat_size)
6825  return 0;
6826 
6827  avio_write_marker(s->pb,
6828  av_rescale(mov->tracks[first_track].cluster[0].dts, AV_TIME_BASE, mov->tracks[first_track].timescale),
6829  (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);
6830 
6831  for (i = first_track; i < mov->nb_tracks; i++) {
6832  MOVTrack *track = &mov->tracks[i];
6833  int buf_size, write_moof = 1, moof_tracks = -1;
6834  uint8_t *buf;
6835 
6836  if (!track->entry)
6837  continue;
6838  if (mov->flags & FF_MOV_FLAG_SEPARATE_MOOF) {
6839  mdat_size = avio_tell(track->mdat_buf);
6840  moof_tracks = i;
6841  } else {
6842  write_moof = i == first_track;
6843  }
6844 
6845  if (write_moof) {
6847 
6848  mov_write_moof_tag(s->pb, mov, moof_tracks, mdat_size);
6849  mov->fragments++;
6850 
6851  if (track->cenc.aes_ctr)
6852  ff_mov_cenc_flush(&track->cenc);
6853 
6854  avio_wb32(s->pb, mdat_size + 8);
6855  ffio_wfourcc(s->pb, "mdat");
6856  mdat_start = avio_tell(s->pb);
6857  }
6858 
6859  mov_finish_fragment(mov, &mov->tracks[i], mdat_start);
6860  if (!mov->frag_interleave) {
6861  if (!track->mdat_buf)
6862  continue;
6863  buf_size = avio_get_dyn_buf(track->mdat_buf, &buf);
6864  avio_write(s->pb, buf, buf_size);
6865  ffio_reset_dyn_buf(track->mdat_buf);
6866  } else {
6867  if (!mov->mdat_buf)
6868  continue;
6869  buf_size = avio_get_dyn_buf(mov->mdat_buf, &buf);
6870  avio_write(s->pb, buf, buf_size);
6872  }
6873  }
6874 
6875  mov->mdat_size = 0;
6876 
6878  return 0;
6879 }
6880 
6882 {
6883  MOVMuxContext *mov = s->priv_data;
6884  int had_moov = mov->moov_written;
6885  int ret = mov_flush_fragment(s, force);
6886  if (ret < 0)
6887  return ret;
6888  // If using delay_moov, the first flush only wrote the moov,
6889  // not the actual moof+mdat pair, thus flush once again.
6890  if (!had_moov && mov->flags & FF_MOV_FLAG_DELAY_MOOV)
6891  ret = mov_flush_fragment(s, force);
6892  return ret;
6893 }
6894 
6896 {
6897  int64_t ref;
6898  uint64_t duration;
6899 
6900  if (trk->entry) {
6901  ref = trk->cluster[trk->entry - 1].dts;
6902  } else if ( trk->start_dts != AV_NOPTS_VALUE
6903  && !trk->frag_discont) {
6904  ref = trk->start_dts + trk->track_duration;
6905  } else
6906  ref = pkt->dts; // Skip tests for the first packet
6907 
6908  if (trk->dts_shift != AV_NOPTS_VALUE) {
6909  /* With negative CTS offsets we have set an offset to the DTS,
6910  * reverse this for the check. */
6911  ref -= trk->dts_shift;
6912  }
6913 
6914  duration = pkt->dts - ref;
6915  if (pkt->dts < ref || duration >= INT_MAX) {
6916  av_log(s, AV_LOG_WARNING, "Packet duration: %"PRId64" / dts: %"PRId64" in stream %d is out of range\n",
6918 
6919  pkt->dts = ref + 1;
6920  pkt->pts = AV_NOPTS_VALUE;
6921  }
6922 
6923  if (pkt->duration < 0 || pkt->duration > INT_MAX) {
6924  av_log(s, AV_LOG_ERROR, "Application provided duration: %"PRId64" in stream %d is invalid\n", pkt->duration, pkt->stream_index);
6925  return AVERROR(EINVAL);
6926  }
6927  return 0;
6928 }
6929 
6931 {
6932  MOVMuxContext *mov = s->priv_data;
6933  AVIOContext *pb = s->pb;
6934  MOVTrack *trk;
6935  AVCodecParameters *par;
6937  unsigned int samples_in_chunk = 0;
6939  int size = pkt->size, ret = 0, offset = 0;
6940  size_t prft_size;
6941  uint8_t *reformatted_data = NULL;
6942 
6943  if (pkt->stream_index < s->nb_streams)
6944  trk = s->streams[pkt->stream_index]->priv_data;
6945  else // Timecode or chapter
6946  trk = &mov->tracks[pkt->stream_index];
6947  par = trk->par;
6948 
6949  ret = check_pkt(s, trk, pkt);
6950  if (ret < 0)
6951  return ret;
6952 
6953  if (pkt->pts != AV_NOPTS_VALUE &&
6954  (uint64_t)pkt->dts - pkt->pts != (int32_t)((uint64_t)pkt->dts - pkt->pts)) {
6955  av_log(s, AV_LOG_WARNING, "pts/dts pair unsupported\n");
6956  return AVERROR_PATCHWELCOME;
6957  }
6958 
6959  if (mov->flags & FF_MOV_FLAG_FRAGMENT || mov->mode == MODE_AVIF) {
6960  int ret;
6961  if (mov->moov_written || mov->flags & FF_MOV_FLAG_EMPTY_MOOV) {
6962  if (mov->frag_interleave && mov->fragments > 0) {
6963  if (trk->entry - trk->entries_flushed >= mov->frag_interleave) {
6964  if ((ret = mov_flush_fragment_interleaving(s, trk)) < 0)
6965  return ret;
6966  }
6967  }
6968 
6969  if (!trk->mdat_buf) {
6970  if ((ret = avio_open_dyn_buf(&trk->mdat_buf)) < 0)
6971  return ret;
6972  }
6973  pb = trk->mdat_buf;
6974  } else {
6975  if (!mov->mdat_buf) {
6976  if ((ret = avio_open_dyn_buf(&mov->mdat_buf)) < 0)
6977  return ret;
6978  }
6979  pb = mov->mdat_buf;
6980  }
6981  }
6982 
6983  if (par->codec_id == AV_CODEC_ID_AMR_NB) {
6984  /* We must find out how many AMR blocks there are in one packet */
6985  static const uint16_t packed_size[16] =
6986  {13, 14, 16, 18, 20, 21, 27, 32, 6, 0, 0, 0, 0, 0, 0, 1};
6987  int len = 0;
6988 
6989  while (len < size && samples_in_chunk < 100) {
6990  len += packed_size[(pkt->data[len] >> 3) & 0x0F];
6991  samples_in_chunk++;
6992  }
6993  if (samples_in_chunk > 1) {
6994  av_log(s, AV_LOG_ERROR, "fatal error, input is not a single packet, implement a AVParser for it\n");
6995  return -1;
6996  }
6997  } else if (par->codec_id == AV_CODEC_ID_ADPCM_MS ||
6999  samples_in_chunk = trk->par->frame_size;
7000  } else if (trk->sample_size)
7001  samples_in_chunk = size / trk->sample_size;
7002  else
7003  samples_in_chunk = 1;
7004 
7005  if (samples_in_chunk < 1) {
7006  av_log(s, AV_LOG_ERROR, "fatal error, input packet contains no samples\n");
7007  return AVERROR_PATCHWELCOME;
7008  }
7009 
7010  /* copy extradata if it exists */
7011  if (trk->extradata_size[0] == 0 && par->extradata_size > 0 &&
7012  !TAG_IS_AVCI(trk->tag) &&
7013  (par->codec_id != AV_CODEC_ID_DNXHD)) {
7014  trk->extradata[0] = av_memdup(par->extradata, par->extradata_size);
7015  if (!trk->extradata[0]) {
7016  ret = AVERROR(ENOMEM);
7017  goto err;
7018  }
7019  trk->extradata_size[0] = par->extradata_size;
7020  }
7021 
7022  if ((par->codec_id == AV_CODEC_ID_DNXHD ||
7023  par->codec_id == AV_CODEC_ID_H264 ||
7024  par->codec_id == AV_CODEC_ID_HEVC ||
7025  par->codec_id == AV_CODEC_ID_VVC ||
7026  par->codec_id == AV_CODEC_ID_VP9 ||
7027  par->codec_id == AV_CODEC_ID_EVC ||
7028  par->codec_id == AV_CODEC_ID_LCEVC ||
7029  par->codec_id == AV_CODEC_ID_TRUEHD) && !trk->extradata_size[0] &&
7030  !TAG_IS_AVCI(trk->tag)) {
7031  /* copy frame to create needed atoms */
7032  trk->extradata_size[0] = size;
7034  if (!trk->extradata[0]) {
7035  ret = AVERROR(ENOMEM);
7036  goto err;
7037  }
7038  memcpy(trk->extradata[0], pkt->data, size);
7039  memset(trk->extradata[0] + size, 0, AV_INPUT_BUFFER_PADDING_SIZE);
7040  }
7041 
7043  if (pkt->size && sd && sd->size > 0) {
7044  int i;
7045  for (i = 0; i < trk->stsd_count; i++) {
7046  if (trk->extradata_size[i] == sd->size && !memcmp(trk->extradata[i], sd->data, sd->size))
7047  break;
7048  }
7049 
7050  if (i < trk->stsd_count)
7051  trk->last_stsd_index = i;
7052  else if (trk->stsd_count <= INT_MAX - 1) {
7053  int new_count = trk->stsd_count + 1;
7054  uint8_t **extradata = av_realloc_array(trk->extradata, new_count, sizeof(*trk->extradata));
7055  if (!extradata)
7056  return AVERROR(ENOMEM);
7057  trk->extradata = extradata;
7058 
7059  int *extradata_size = av_realloc_array(trk->extradata_size, new_count, sizeof(*trk->extradata_size));
7060  if (!extradata_size)
7061  return AVERROR(ENOMEM);
7062  trk->extradata_size = extradata_size;
7063 
7064  trk->extradata[trk->stsd_count] = av_memdup(sd->data, sd->size);
7065  if (!trk->extradata[trk->stsd_count])
7066  return AVERROR(ENOMEM);
7067 
7068  trk->extradata_size[trk->stsd_count] = sd->size;
7069  trk->last_stsd_index = trk->stsd_count;
7070  trk->stsd_count = new_count;
7071  } else
7072  return AVERROR(ENOMEM);
7073  }
7074 
7075  if (par->codec_id == AV_CODEC_ID_AAC && pkt->size > 2 &&
7076  (AV_RB16(pkt->data) & 0xfff0) == 0xfff0) {
7077  if (!trk->st->nb_frames) {
7078  av_log(s, AV_LOG_ERROR, "Malformed AAC bitstream detected: "
7079  "use the audio bitstream filter 'aac_adtstoasc' to fix it "
7080  "('-bsf:a aac_adtstoasc' option with ffmpeg)\n");
7081  return -1;
7082  }
7083  av_log(s, AV_LOG_WARNING, "aac bitstream error\n");
7084  }
7085  if (par->codec_id == AV_CODEC_ID_H264 && trk->extradata_size[trk->last_stsd_index] > 0 &&
7086  *(uint8_t *)trk->extradata[trk->last_stsd_index] != 1 && !TAG_IS_AVCI(trk->tag)) {
7087  /* from x264 or from bytestream H.264 */
7088  /* NAL reformatting needed */
7089  if (trk->hint_track >= 0 && trk->hint_track < mov->nb_tracks) {
7090  ret = ff_nal_parse_units_buf(pkt->data, &reformatted_data,
7091  &size);
7092  if (ret < 0)
7093  return ret;
7094  avio_write(pb, reformatted_data, size);
7095  } else {
7096  if (trk->cenc.aes_ctr) {
7098  if (size < 0) {
7099  ret = size;
7100  goto err;
7101  }
7102  } else {
7103  size = ff_nal_parse_units(pb, pkt->data, pkt->size);
7104  }
7105  }
7106  } else if (par->codec_id == AV_CODEC_ID_HEVC && trk->extradata_size[trk->last_stsd_index] > 6 &&
7107  (AV_RB24(trk->extradata[trk->last_stsd_index]) == 1 || AV_RB32(trk->extradata[trk->last_stsd_index]) == 1)) {
7108  /* extradata is Annex B, assume the bitstream is too and convert it */
7109  int filter_ps = (trk->tag == MKTAG('h','v','c','1'));
7110  if (trk->hint_track >= 0 && trk->hint_track < mov->nb_tracks) {
7111  ret = ff_hevc_annexb2mp4_buf(pkt->data, &reformatted_data,
7112  &size, filter_ps, NULL);
7113  if (ret < 0)
7114  return ret;
7115  avio_write(pb, reformatted_data, size);
7116  } else {
7117  if (trk->cenc.aes_ctr) {
7119  if (size < 0) {
7120  ret = size;
7121  goto err;
7122  }
7123  } else {
7124  size = ff_hevc_annexb2mp4(pb, pkt->data, pkt->size, filter_ps, NULL);
7125  }
7126  }
7127  } else if (par->codec_id == AV_CODEC_ID_VVC && trk->extradata_size[trk->last_stsd_index] > 6 &&
7128  (AV_RB24(trk->extradata[trk->last_stsd_index]) == 1 || AV_RB32(trk->extradata[trk->last_stsd_index]) == 1)) {
7129  /* extradata is Annex B, assume the bitstream is too and convert it */
7130  if (trk->hint_track >= 0 && trk->hint_track < mov->nb_tracks) {
7131  ret = ff_vvc_annexb2mp4_buf(pkt->data, &reformatted_data,
7132  &size, 0, NULL);
7133  if (ret < 0)
7134  return ret;
7135  avio_write(pb, reformatted_data, size);
7136  } else {
7137  size = ff_vvc_annexb2mp4(pb, pkt->data, pkt->size, 0, NULL);
7138  }
7139  } else if (par->codec_id == AV_CODEC_ID_LCEVC && trk->extradata_size[trk->last_stsd_index] > 0 &&
7140  *(uint8_t *)trk->extradata[trk->last_stsd_index] != 1) {
7141  /* extradata is Annex B, assume the bitstream is too and convert it */
7142  if (trk->hint_track >= 0 && trk->hint_track < mov->nb_tracks) {
7143  ret = ff_nal_parse_units_buf(pkt->data, &reformatted_data, &size);
7144  if (ret < 0)
7145  return ret;
7146  avio_write(pb, reformatted_data, size);
7147  } else {
7148  if (trk->cenc.aes_ctr) {
7150  if (size < 0) {
7151  ret = size;
7152  goto err;
7153  }
7154  } else {
7155  size = ff_nal_parse_units(pb, pkt->data, pkt->size);
7156  }
7157  }
7158  } else if (par->codec_id == AV_CODEC_ID_AV1 && !trk->cenc.aes_ctr) {
7159  if (trk->hint_track >= 0 && trk->hint_track < mov->nb_tracks) {
7160  ret = ff_av1_filter_obus_buf(pkt->data, &reformatted_data,
7161  &size, &offset);
7162  if (ret < 0)
7163  return ret;
7164  avio_write(pb, reformatted_data, size);
7165  } else {
7166  size = ff_av1_filter_obus(pb, pkt->data, pkt->size);
7167  if (trk->mode == MODE_AVIF && !mov->avif_extent_length[pkt->stream_index]) {
7169  }
7170  }
7171 
7172  } else if (par->codec_id == AV_CODEC_ID_AC3 ||
7173  par->codec_id == AV_CODEC_ID_EAC3) {
7174  size = handle_eac3(mov, pkt, trk);
7175  if (size < 0)
7176  return size;
7177  else if (!size)
7178  goto end;
7179  avio_write(pb, pkt->data, size);
7180  } else if (par->codec_id == AV_CODEC_ID_EIA_608) {
7181  size = 8;
7182 
7183  for (int i = 0; i < pkt->size; i += 3) {
7184  if (pkt->data[i] == 0xFC) {
7185  size += 2;
7186  }
7187  }
7188  avio_wb32(pb, size);
7189  ffio_wfourcc(pb, "cdat");
7190  for (int i = 0; i < pkt->size; i += 3) {
7191  if (pkt->data[i] == 0xFC) {
7192  avio_w8(pb, pkt->data[i + 1]);
7193  avio_w8(pb, pkt->data[i + 2]);
7194  }
7195  }
7196  } else if (par->codec_id == AV_CODEC_ID_APV) {
7197  ff_isom_parse_apvc(trk->apv, pkt, s);
7198  avio_wb32(s->pb, pkt->size);
7199  size += 4;
7200 
7201  avio_write(s->pb, pkt->data, pkt->size);
7202  } else {
7203  if (trk->cenc.aes_ctr) {
7204  uint8_t *extradata = trk->extradata[trk->last_stsd_index];
7205  int extradata_size = trk->extradata_size[trk->last_stsd_index];
7206  if (par->codec_id == AV_CODEC_ID_H264 && extradata_size > 4) {
7207  int nal_size_length = (extradata[4] & 0x3) + 1;
7208  ret = ff_mov_cenc_avc_write_nal_units(s, &trk->cenc, nal_size_length, pb, pkt->data, size);
7209  } else if(par->codec_id == AV_CODEC_ID_HEVC && extradata_size > 21) {
7210  int nal_size_length = (extradata[21] & 0x3) + 1;
7211  ret = ff_mov_cenc_avc_write_nal_units(s, &trk->cenc, nal_size_length, pb, pkt->data, size);
7212  } else if(par->codec_id == AV_CODEC_ID_VVC) {
7214  } else if(par->codec_id == AV_CODEC_ID_AV1) {
7215  av_assert0(size == pkt->size);
7216  ret = ff_mov_cenc_av1_write_obus(s, &trk->cenc, pb, pkt);
7217  if (ret > 0) {
7218  size = ret;
7219  ret = 0;
7220  }
7221  } else {
7222  ret = ff_mov_cenc_write_packet(&trk->cenc, pb, pkt->data, size);
7223  }
7224 
7225  if (ret) {
7226  goto err;
7227  }
7228  } else {
7229  avio_write(pb, pkt->data, size);
7230  }
7231  }
7232 
7233  if (trk->entry >= trk->cluster_capacity) {
7234  unsigned new_capacity = trk->entry + MOV_INDEX_CLUSTER_SIZE;
7235  void *cluster = av_realloc_array(trk->cluster, new_capacity, sizeof(*trk->cluster));
7236  if (!cluster) {
7237  ret = AVERROR(ENOMEM);
7238  goto err;
7239  }
7240  trk->cluster = cluster;
7241  trk->cluster_capacity = new_capacity;
7242  }
7243 
7244  trk->cluster[trk->entry].pos = avio_tell(pb) - size;
7245  trk->cluster[trk->entry].stsd_index = trk->last_stsd_index;
7246  trk->cluster[trk->entry].samples_in_chunk = samples_in_chunk;
7247  trk->cluster[trk->entry].chunkNum = 0;
7248  trk->cluster[trk->entry].size = size;
7249  trk->cluster[trk->entry].entries = samples_in_chunk;
7250  trk->cluster[trk->entry].dts = pkt->dts;
7251  trk->cluster[trk->entry].pts = pkt->pts;
7252  if (!trk->squash_fragment_samples_to_one &&
7253  !trk->entry && trk->start_dts != AV_NOPTS_VALUE) {
7254  if (!trk->frag_discont) {
7255  /* First packet of a new fragment. We already wrote the duration
7256  * of the last packet of the previous fragment based on track_duration,
7257  * which might not exactly match our dts. Therefore adjust the dts
7258  * of this packet to be what the previous packets duration implies. */
7259  trk->cluster[trk->entry].dts = trk->start_dts + trk->track_duration;
7260  /* We also may have written the pts and the corresponding duration
7261  * in sidx/tfrf/tfxd tags; make sure the sidx pts and duration match up with
7262  * the next fragment. This means the cts of the first sample must
7263  * be the same in all fragments, unless end_pts was updated by
7264  * the packet causing the fragment to be written. */
7265  if ((mov->flags & FF_MOV_FLAG_DASH &&
7267  mov->mode == MODE_ISM)
7268  pkt->pts = pkt->dts + trk->end_pts - trk->cluster[trk->entry].dts;
7269  } else {
7270  /* New fragment, but discontinuous from previous fragments.
7271  * Pretend the duration sum of the earlier fragments is
7272  * pkt->dts - trk->start_dts. */
7273  trk->end_pts = trk->elst_end_pts = AV_NOPTS_VALUE;
7274  trk->frag_discont = 0;
7275  }
7276  }
7277 
7278  if (!trk->entry && trk->start_dts == AV_NOPTS_VALUE && !mov->use_editlist &&
7279  s->avoid_negative_ts == AVFMT_AVOID_NEG_TS_MAKE_ZERO) {
7280  /* Not using edit lists and shifting the first track to start from zero.
7281  * If the other streams start from a later timestamp, we won't be able
7282  * to signal the difference in starting time without an edit list.
7283  * Thus move the timestamp for this first sample to 0, increasing
7284  * its duration instead. */
7285  trk->cluster[trk->entry].dts = trk->start_dts = 0;
7286  }
7287  if (trk->start_dts == AV_NOPTS_VALUE) {
7288  trk->start_dts = pkt->dts;
7289  if (trk->frag_discont) {
7290  if (mov->use_editlist) {
7291  /* Pretend the whole stream started at pts=0, with earlier fragments
7292  * already written. If the stream started at pts=0, the duration sum
7293  * of earlier fragments would have been pkt->pts. */
7294  trk->start_dts = pkt->dts - pkt->pts;
7295  } else {
7296  /* Pretend the whole stream started at dts=0, with earlier fragments
7297  * already written, with a duration summing up to pkt->dts. */
7298  trk->start_dts = 0;
7299  }
7300  trk->frag_discont = 0;
7301  } else if (pkt->dts && mov->moov_written)
7303  "Track %d starts with a nonzero dts %"PRId64", while the moov "
7304  "already has been written. Set the delay_moov flag to handle "
7305  "this case.\n",
7306  pkt->stream_index, pkt->dts);
7307  }
7308 
7310  if (sd && sd->size >= 10 && trk->par->frame_size) {
7311  duration = FFMAX(av_rescale_q(trk->par->frame_size, (AVRational){ 1, trk->par->sample_rate },
7312  trk->st->time_base), duration);
7313  duration -= av_rescale_q(AV_RL32(sd->data + 4), (AVRational){ 1, trk->par->sample_rate },
7314  trk->st->time_base);
7315  if (duration < 0)
7316  return AVERROR_INVALIDDATA;
7317  }
7318 
7319  trk->track_duration = pkt->dts - trk->start_dts + pkt->duration;
7320  trk->last_sample_is_subtitle_end = 0;
7321 
7322  if (pkt->pts == AV_NOPTS_VALUE) {
7323  av_log(s, AV_LOG_WARNING, "pts has no value\n");
7324  pkt->pts = pkt->dts;
7325  }
7326  if (pkt->dts != pkt->pts)
7327  trk->flags |= MOV_TRACK_CTTS;
7328  trk->cluster[trk->entry].cts = pkt->pts - pkt->dts;
7329  trk->cluster[trk->entry].flags = 0;
7330  if (trk->start_cts == AV_NOPTS_VALUE || (pkt->dts <= 0 && trk->start_cts > pkt->pts - pkt->dts))
7331  trk->start_cts = pkt->pts - pkt->dts;
7332  if (trk->end_pts == AV_NOPTS_VALUE)
7333  trk->end_pts = trk->cluster[trk->entry].dts +
7334  trk->cluster[trk->entry].cts + duration;
7335  else
7336  trk->end_pts = FFMAX(trk->end_pts, trk->cluster[trk->entry].dts +
7337  trk->cluster[trk->entry].cts +
7338  duration);
7339  if (!(pkt->flags & AV_PKT_FLAG_DISCARD))
7340  trk->elst_end_pts = trk->end_pts;
7341 
7342  if (par->codec_id == AV_CODEC_ID_VC1) {
7343  mov_parse_vc1_frame(pkt, trk);
7344  } else if (par->codec_id == AV_CODEC_ID_TRUEHD) {
7346  } else if (pkt->flags & AV_PKT_FLAG_KEY) {
7347  if (mov->mode == MODE_MOV && par->codec_id == AV_CODEC_ID_MPEG2VIDEO &&
7348  trk->entry > 0) { // force sync sample for the first key frame
7350  if (trk->cluster[trk->entry].flags & MOV_PARTIAL_SYNC_SAMPLE)
7351  trk->flags |= MOV_TRACK_STPS;
7352  } else {
7353  trk->cluster[trk->entry].flags = MOV_SYNC_SAMPLE;
7354  }
7355  if (trk->cluster[trk->entry].flags & MOV_SYNC_SAMPLE)
7356  trk->has_keyframes++;
7357  }
7358  if (pkt->flags & AV_PKT_FLAG_DISPOSABLE) {
7359  trk->cluster[trk->entry].flags |= MOV_DISPOSABLE_SAMPLE;
7360  trk->has_disposable++;
7361  }
7362 
7364  if (prft && prft_size == sizeof(AVProducerReferenceTime))
7365  memcpy(&trk->cluster[trk->entry].prft, prft, prft_size);
7366  else
7367  memset(&trk->cluster[trk->entry].prft, 0, sizeof(AVProducerReferenceTime));
7368 
7369  trk->entry++;
7370  trk->sample_count += samples_in_chunk;
7371  mov->mdat_size += size;
7372 
7373  if (trk->hint_track >= 0 && trk->hint_track < mov->nb_tracks)
7375  reformatted_data ? reformatted_data + offset
7376  : NULL, size);
7377 
7378 end:
7379 err:
7380 
7381  if (pkt->data != reformatted_data)
7382  av_free(reformatted_data);
7383  return ret;
7384 }
7385 
7387 {
7388  MOVMuxContext *mov = s->priv_data;
7389  MOVTrack *trk = s->streams[pkt->stream_index]->priv_data;
7390  AVCodecParameters *par = trk->par;
7391  int64_t frag_duration = 0;
7392  int size = pkt->size;
7393 
7394  int ret = check_pkt(s, trk, pkt);
7395  if (ret < 0)
7396  return ret;
7397 
7398  if (mov->flags & FF_MOV_FLAG_FRAG_DISCONT) {
7399  for (int i = 0; i < mov->nb_streams; i++)
7400  mov->tracks[i].frag_discont = 1;
7402  }
7403 
7405  if (trk->dts_shift == AV_NOPTS_VALUE)
7406  trk->dts_shift = pkt->pts - pkt->dts;
7407  pkt->dts += trk->dts_shift;
7408  }
7409 
7410  if (trk->par->codec_id == AV_CODEC_ID_MP4ALS ||
7411  trk->par->codec_id == AV_CODEC_ID_AAC ||
7412  trk->par->codec_id == AV_CODEC_ID_AV1 ||
7413  trk->par->codec_id == AV_CODEC_ID_FLAC) {
7414  size_t side_size;
7415  uint8_t *side = av_packet_get_side_data(pkt, AV_PKT_DATA_NEW_EXTRADATA, &side_size);
7416  /* Overwrite extradata only on flush packets or when no extradata was available during init */
7417  if (side_size > 0 && (!pkt->size || !trk->extradata_size[trk->last_stsd_index])) {
7418  void *newextra = av_malloc(side_size + AV_INPUT_BUFFER_PADDING_SIZE);
7419  if (!newextra)
7420  return AVERROR(ENOMEM);
7421  memset((uint8_t*)newextra + side_size, 0, AV_INPUT_BUFFER_PADDING_SIZE);
7422  memcpy(newextra, side, side_size);
7423  av_free(trk->extradata[trk->last_stsd_index]);
7424  trk->extradata[trk->last_stsd_index] = newextra;
7425  trk->extradata_size[trk->last_stsd_index] = side_size;
7426  }
7427  }
7428 
7429  if (!pkt->size) {
7430  if (trk->start_dts == AV_NOPTS_VALUE && trk->frag_discont) {
7431  trk->start_dts = pkt->dts;
7432  if (pkt->pts != AV_NOPTS_VALUE)
7433  trk->start_cts = pkt->pts - pkt->dts;
7434  else
7435  trk->start_cts = 0;
7436  }
7437 
7438  return 0; /* Discard 0 sized packets */
7439  }
7440 
7441  if (trk->entry && pkt->stream_index < mov->nb_streams)
7442  frag_duration = av_rescale_q(pkt->dts - trk->cluster[0].dts,
7443  s->streams[pkt->stream_index]->time_base,
7444  AV_TIME_BASE_Q);
7445  if ((mov->max_fragment_duration &&
7446  frag_duration >= mov->max_fragment_duration) ||
7447  (mov->max_fragment_size && mov->mdat_size + size >= mov->max_fragment_size) ||
7448  (mov->flags & FF_MOV_FLAG_FRAG_KEYFRAME &&
7449  par->codec_type == AVMEDIA_TYPE_VIDEO &&
7450  trk->entry && pkt->flags & AV_PKT_FLAG_KEY) ||
7452  if (frag_duration >= mov->min_fragment_duration) {
7453  if (trk->entry) {
7454  // Set the duration of this track to line up with the next
7455  // sample in this track. This avoids relying on AVPacket
7456  // duration, but only helps for this particular track, not
7457  // for the other ones that are flushed at the same time.
7458  //
7459  // If we have trk->entry == 0, no fragment will be written
7460  // for this track, and we can't adjust the track end here.
7461  trk->track_duration = pkt->dts - trk->start_dts;
7462  if (pkt->pts != AV_NOPTS_VALUE)
7463  trk->end_pts = pkt->pts;
7464  else
7465  trk->end_pts = pkt->dts;
7466  if (!(pkt->flags & AV_PKT_FLAG_DISCARD))
7467  trk->elst_end_pts = trk->end_pts;
7468  trk->end_reliable = 1;
7469  }
7471  }
7472  }
7473 
7474  return ff_mov_write_packet(s, pkt);
7475 }
7476 
7478  int stream_index,
7479  int64_t dts) {
7480  MOVMuxContext *mov = s->priv_data;
7481  AVPacket *end = mov->pkt;
7482  uint8_t data[2] = {0};
7483  int ret;
7484 
7485  end->size = sizeof(data);
7486  end->data = data;
7487  end->pts = dts;
7488  end->dts = dts;
7489  end->duration = 0;
7490  end->stream_index = stream_index;
7491 
7492  ret = mov_write_single_packet(s, end);
7493  av_packet_unref(end);
7494 
7495  return ret;
7496 }
7497 
7498 #if CONFIG_IAMFENC
7499 static int mov_build_iamf_packet(AVFormatContext *s, MOVTrack *trk, AVPacket *pkt)
7500 {
7501  uint8_t *data;
7502  int ret;
7503 
7504  if (pkt->stream_index == trk->first_iamf_idx) {
7506  if (ret < 0)
7507  return ret;
7508  }
7509 
7511  s->streams[pkt->stream_index]->id, pkt);
7512  if (ret < 0)
7513  return ret;
7514 
7515  if (pkt->stream_index != trk->last_iamf_idx)
7516  return AVERROR(EAGAIN);
7517 
7518  ret = avio_close_dyn_buf(trk->iamf_buf, &data);
7519  trk->iamf_buf = NULL;
7520  if (!ret) {
7521  if (pkt->size) {
7522  // Either all or none of the packets for a single
7523  // IA Sample may be empty.
7524  av_log(s, AV_LOG_ERROR, "Unexpected packet from "
7525  "stream #%d\n", pkt->stream_index);
7527  }
7528  av_free(data);
7529  return ret;
7530  }
7531 
7532  av_buffer_unref(&pkt->buf);
7533  pkt->buf = av_buffer_create(data, ret, NULL, NULL, 0);
7534  if (!pkt->buf) {
7535  av_free(data);
7536  return AVERROR(ENOMEM);
7537  }
7538  pkt->data = data;
7539  pkt->size = ret;
7541 
7542  return avio_open_dyn_buf(&trk->iamf_buf);
7543 }
7544 #endif
7545 
7547 {
7548  int64_t pos = avio_tell(pb);
7549  const char *scheme_id_uri = "https://aomedia.org/emsg/ID3";
7550  const char *value = "";
7551 
7552  av_assert0(st->time_base.num == 1);
7553 
7554  avio_write_marker(pb,
7557 
7558  avio_wb32(pb, 0); /* size */
7559  ffio_wfourcc(pb, "emsg");
7560  avio_w8(pb, 1); /* version */
7561  avio_wb24(pb, 0);
7562  avio_wb32(pb, st->time_base.den); /* timescale */
7563  avio_wb64(pb, pkt->pts); /* presentation_time */
7564  avio_wb32(pb, 0xFFFFFFFFU); /* event_duration */
7565  avio_wb32(pb, 0); /* id */
7566  /* null terminated UTF8 strings */
7567  avio_write(pb, scheme_id_uri, strlen(scheme_id_uri) + 1);
7568  avio_write(pb, value, strlen(value) + 1);
7569  avio_write(pb, pkt->data, pkt->size);
7570 
7571  return update_size(pb, pos);
7572 }
7573 
7575 {
7576  MOVMuxContext *mov = s->priv_data;
7577  MOVTrack *trk;
7578 
7579  if (!pkt) {
7580  mov_flush_fragment(s, 1);
7581  return 1;
7582  }
7583 
7584  if (s->streams[pkt->stream_index]->codecpar->codec_id == AV_CODEC_ID_TIMED_ID3) {
7585  mov_write_emsg_tag(s->pb, s->streams[pkt->stream_index], pkt);
7586  return 0;
7587  }
7588 
7589  trk = s->streams[pkt->stream_index]->priv_data;
7590 
7591 #if CONFIG_IAMFENC
7592  if (trk->iamf) {
7593  int ret = mov_build_iamf_packet(s, trk, pkt);
7594  if (ret < 0) {
7595  if (ret == AVERROR(EAGAIN))
7596  return 0;
7597  av_log(s, AV_LOG_ERROR, "Error assembling an IAMF packet "
7598  "for stream #%d\n", trk->st->index);
7599  return ret;
7600  }
7601  }
7602 #endif
7603 
7604  if (is_cover_image(trk->st)) {
7605  int ret;
7606 
7607  if (trk->st->nb_frames >= 1) {
7608  if (trk->st->nb_frames == 1)
7609  av_log(s, AV_LOG_WARNING, "Got more than one picture in stream %d,"
7610  " ignoring.\n", pkt->stream_index);
7611  return 0;
7612  }
7613 
7614  if ((ret = av_packet_ref(trk->cover_image, pkt)) < 0)
7615  return ret;
7616 
7617  return 0;
7618  } else {
7619  int i;
7620 
7621  if (!pkt->size)
7622  return mov_write_single_packet(s, pkt); /* Passthrough. */
7623 
7624  /*
7625  * Subtitles require special handling.
7626  *
7627  * 1) For full compliance, every track must have a sample at
7628  * dts == 0, which is rarely true for subtitles. So, as soon
7629  * as we see any packet with dts > 0, write an empty subtitle
7630  * at dts == 0 for any subtitle track with no samples in it.
7631  *
7632  * 2) For each subtitle track, check if the current packet's
7633  * dts is past the duration of the last subtitle sample. If
7634  * so, we now need to write an end sample for that subtitle.
7635  *
7636  * This must be done conditionally to allow for subtitles that
7637  * immediately replace each other, in which case an end sample
7638  * is not needed, and is, in fact, actively harmful.
7639  *
7640  * 3) See mov_write_trailer for how the final end sample is
7641  * handled.
7642  */
7643  for (i = 0; i < mov->nb_tracks; i++) {
7644  MOVTrack *trk = &mov->tracks[i];
7645  int ret;
7646 
7647  if (trk->par->codec_id == AV_CODEC_ID_MOV_TEXT &&
7648  trk->track_duration < pkt->dts &&
7649  (trk->entry == 0 || !trk->last_sample_is_subtitle_end)) {
7651  if (ret < 0) return ret;
7652  trk->last_sample_is_subtitle_end = 1;
7653  }
7654  }
7655 
7656  if (trk->squash_fragment_samples_to_one) {
7657  /*
7658  * If the track has to have its samples squashed into one sample,
7659  * we just take it into the track's queue.
7660  * This will then be utilized as the samples get written in either
7661  * mov_flush_fragment or when the mux is finalized in
7662  * mov_write_trailer.
7663  */
7664  int ret = AVERROR_BUG;
7665 
7666  if (pkt->pts == AV_NOPTS_VALUE) {
7668  "Packets without a valid presentation timestamp are "
7669  "not supported with packet squashing!\n");
7670  return AVERROR(EINVAL);
7671  }
7672 
7673  /* The following will reset pkt and is only allowed to be used
7674  * because we return immediately. afterwards. */
7676  pkt, NULL, 0)) < 0) {
7677  return ret;
7678  }
7679 
7680  return 0;
7681  }
7682 
7683 
7684  if (trk->mode == MODE_MOV && trk->par->codec_type == AVMEDIA_TYPE_VIDEO) {
7685  AVPacket *opkt = pkt;
7686  int reshuffle_ret, ret;
7687  if (trk->is_unaligned_qt_rgb) {
7688  int64_t bpc = trk->par->bits_per_coded_sample != 15 ? trk->par->bits_per_coded_sample : 16;
7689  int expected_stride = ((trk->par->width * bpc + 15) >> 4)*2;
7690  reshuffle_ret = ff_reshuffle_raw_rgb(s, &pkt, trk->par, expected_stride);
7691  if (reshuffle_ret < 0)
7692  return reshuffle_ret;
7693  } else
7694  reshuffle_ret = 0;
7695  if (trk->par->format == AV_PIX_FMT_PAL8 && !trk->pal_done) {
7696  ret = ff_get_packet_palette(s, opkt, reshuffle_ret, trk->palette);
7697  if (ret < 0)
7698  goto fail;
7699  if (ret)
7700  trk->pal_done++;
7701  } else if (trk->par->codec_id == AV_CODEC_ID_RAWVIDEO &&
7702  (trk->par->format == AV_PIX_FMT_GRAY8 ||
7703  trk->par->format == AV_PIX_FMT_MONOBLACK)) {
7705  if (ret < 0)
7706  goto fail;
7707  for (i = 0; i < pkt->size; i++)
7708  pkt->data[i] = ~pkt->data[i];
7709  }
7710  if (reshuffle_ret) {
7712 fail:
7713  if (reshuffle_ret)
7714  av_packet_free(&pkt);
7715  return ret;
7716  }
7717  }
7718 
7719  return mov_write_single_packet(s, pkt);
7720  }
7721 }
7722 
7723 // QuickTime chapters involve an additional text track with the chapter names
7724 // as samples, and a tref pointing from the other tracks to the chapter one.
7725 static int mov_create_chapter_track(AVFormatContext *s, int tracknum)
7726 {
7727  static const uint8_t stub_header[] = {
7728  // TextSampleEntry
7729  0x00, 0x00, 0x00, 0x01, // displayFlags
7730  0x00, 0x00, // horizontal + vertical justification
7731  0x00, 0x00, 0x00, 0x00, // bgColourRed/Green/Blue/Alpha
7732  // BoxRecord
7733  0x00, 0x00, 0x00, 0x00, // defTextBoxTop/Left
7734  0x00, 0x00, 0x00, 0x00, // defTextBoxBottom/Right
7735  // StyleRecord
7736  0x00, 0x00, 0x00, 0x00, // startChar + endChar
7737  0x00, 0x01, // fontID
7738  0x00, 0x00, // fontStyleFlags + fontSize
7739  0x00, 0x00, 0x00, 0x00, // fgColourRed/Green/Blue/Alpha
7740  // FontTableBox
7741  0x00, 0x00, 0x00, 0x0D, // box size
7742  'f', 't', 'a', 'b', // box atom name
7743  0x00, 0x01, // entry count
7744  // FontRecord
7745  0x00, 0x01, // font ID
7746  0x00, // font name length
7747  };
7748  MOVMuxContext *mov = s->priv_data;
7749  MOVTrack *track = &mov->tracks[tracknum];
7750  AVPacket *pkt = mov->pkt;
7751  int i, len;
7752  int ret;
7753 
7754  track->mode = mov->mode;
7755  track->tag = MKTAG('t','e','x','t');
7756  track->timescale = mov->movie_timescale;
7757  track->par = avcodec_parameters_alloc();
7758  if (!track->par)
7759  return AVERROR(ENOMEM);
7761  ret = ff_alloc_extradata(track->par, sizeof(stub_header));
7762  if (ret < 0)
7763  return ret;
7764  memcpy(track->par->extradata, stub_header, sizeof(stub_header));
7765 
7766  if (track->extradata == NULL) {
7767  track->stsd_count = 1;
7768  track->extradata = av_calloc(1, sizeof(*track->extradata));
7769  track->extradata_size = av_calloc(1, sizeof(*track->extradata_size));
7770  if (!track->extradata || !track->extradata_size)
7771  return AVERROR(ENOMEM);
7772  }
7773 
7774  track->extradata[0] = av_memdup(stub_header, sizeof(stub_header));
7775  if (!track->extradata[0])
7776  return AVERROR(ENOMEM);
7777  track->extradata_size[0] = sizeof(stub_header);
7778 
7779  pkt->stream_index = tracknum;
7781 
7782  for (i = 0; i < s->nb_chapters; i++) {
7783  AVChapter *c = s->chapters[i];
7784  AVDictionaryEntry *t;
7785 
7786  int64_t end = av_rescale_q(c->end, c->time_base, (AVRational){1,mov->movie_timescale});
7787  pkt->pts = pkt->dts = av_rescale_q(c->start, c->time_base, (AVRational){1,mov->movie_timescale});
7788  pkt->duration = end - pkt->dts;
7789 
7790  if ((t = av_dict_get(c->metadata, "title", NULL, 0))) {
7791  static const char encd[12] = {
7792  0x00, 0x00, 0x00, 0x0C,
7793  'e', 'n', 'c', 'd',
7794  0x00, 0x00, 0x01, 0x00 };
7795  len = strlen(t->value);
7796  pkt->size = len + 2 + 12;
7797  pkt->data = av_malloc(pkt->size);
7798  if (!pkt->data) {
7800  return AVERROR(ENOMEM);
7801  }
7802  AV_WB16(pkt->data, len);
7803  memcpy(pkt->data + 2, t->value, len);
7804  memcpy(pkt->data + len + 2, encd, sizeof(encd));
7806  av_freep(&pkt->data);
7807  }
7808  }
7809 
7810  av_packet_unref(mov->pkt);
7811 
7812  return 0;
7813 }
7814 
7815 
7816 static int mov_check_timecode_track(AVFormatContext *s, AVTimecode *tc, AVStream *src_st, const char *tcstr)
7817 {
7818  int ret;
7819 
7820  /* compute the frame number */
7821  ret = av_timecode_init_from_string(tc, src_st->avg_frame_rate, tcstr, s);
7822  return ret;
7823 }
7824 
7825 static int mov_create_timecode_track(AVFormatContext *s, int index, int src_index, AVTimecode tc)
7826 {
7827  MOVMuxContext *mov = s->priv_data;
7828  MOVTrack *track = &mov->tracks[index];
7829  AVStream *src_st = mov->tracks[src_index].st;
7830  uint8_t data[4];
7831  AVPacket *pkt = mov->pkt;
7832  AVRational rate = src_st->avg_frame_rate;
7833  int ret;
7834 
7835  /* tmcd track based on video stream */
7836  track->mode = mov->mode;
7837  track->tag = MKTAG('t','m','c','d');
7838  track->src_track = av_malloc(sizeof(*track->src_track));
7839  if (!track->src_track)
7840  return AVERROR(ENOMEM);
7841  *track->src_track = src_index;
7842  track->nb_src_track = 1;
7843  track->timescale = mov->tracks[src_index].timescale;
7846 
7847  /* set st to src_st for metadata access*/
7848  track->st = src_st;
7849 
7850  /* encode context: tmcd data stream */
7851  track->par = avcodec_parameters_alloc();
7852  if (!track->par)
7853  return AVERROR(ENOMEM);
7854  track->par->codec_type = AVMEDIA_TYPE_DATA;
7855  track->par->codec_tag = track->tag;
7856  track->st->avg_frame_rate = rate;
7857 
7858  /* the tmcd track just contains one packet with the frame number */
7859  pkt->data = data;
7860  pkt->stream_index = index;
7862  pkt->pts = pkt->dts = av_rescale_q(tc.start, av_inv_q(rate), (AVRational){ 1, track->timescale });
7863  pkt->size = 4;
7864  AV_WB32(pkt->data, tc.start);
7867  return ret;
7868 }
7869 
7870 /*
7871  * st->disposition controls the "enabled" flag in the tkhd tag.
7872  * QuickTime will not play a track if it is not enabled. So make sure
7873  * that one track of each type (audio, video, subtitle) is enabled.
7874  *
7875  * Subtitles are special. For audio and video, setting "enabled" also
7876  * makes the track "default" (i.e. it is rendered when played). For
7877  * subtitles, an "enabled" subtitle is not rendered by default, but
7878  * if no subtitle is enabled, the subtitle menu in QuickTime will be
7879  * empty!
7880  */
7882 {
7883  MOVMuxContext *mov = s->priv_data;
7884  int i;
7885  int enabled[AVMEDIA_TYPE_NB];
7886  int first[AVMEDIA_TYPE_NB];
7887 
7888  for (i = 0; i < AVMEDIA_TYPE_NB; i++) {
7889  enabled[i] = 0;
7890  first[i] = -1;
7891  }
7892 
7893  for (i = 0; i < mov->nb_streams; i++) {
7894  AVStream *st = mov->tracks[i].st;
7895 
7898  is_cover_image(st))
7899  continue;
7900 
7901  if (first[st->codecpar->codec_type] < 0)
7902  first[st->codecpar->codec_type] = i;
7903  if (st->disposition & AV_DISPOSITION_DEFAULT) {
7904  mov->tracks[i].flags |= MOV_TRACK_ENABLED;
7905  enabled[st->codecpar->codec_type]++;
7906  }
7907  }
7908 
7909  for (i = 0; i < AVMEDIA_TYPE_NB; i++) {
7910  switch (i) {
7911  case AVMEDIA_TYPE_VIDEO:
7912  case AVMEDIA_TYPE_AUDIO:
7913  case AVMEDIA_TYPE_SUBTITLE:
7914  if (enabled[i] > 1)
7915  mov->per_stream_grouping = 1;
7916  if (!enabled[i] && first[i] >= 0)
7917  mov->tracks[first[i]].flags |= MOV_TRACK_ENABLED;
7918  break;
7919  }
7920  }
7921 }
7922 
7924 {
7925  MOVMuxContext *mov = s->priv_data;
7926 
7927  for (int i = 0; i < s->nb_streams; i++)
7928  s->streams[i]->priv_data = NULL;
7929 
7930  if (!mov->tracks)
7931  return;
7932 
7933  if (mov->chapter_track) {
7935  }
7936 
7937  for (int i = 0; i < mov->nb_tracks; i++) {
7938  MOVTrack *const track = &mov->tracks[i];
7939 
7940  if (track->tag == MKTAG('r','t','p',' '))
7941  ff_mov_close_hinting(track);
7942  else if (track->tag == MKTAG('t','m','c','d') && mov->nb_meta_tmcd)
7943  av_freep(&track->par);
7944  av_freep(&track->cluster);
7945  av_freep(&track->cluster_written);
7946  av_freep(&track->frag_info);
7947  av_packet_free(&track->cover_image);
7948 
7949  if (track->eac3_priv) {
7950  struct eac3_info *info = track->eac3_priv;
7951  av_packet_free(&info->pkt);
7952  av_freep(&track->eac3_priv);
7953  }
7954  for (int j = 0; j < track->stsd_count; j++)
7955  av_freep(&track->extradata[j]);
7956  av_freep(&track->extradata);
7957  av_freep(&track->extradata_size);
7958 
7959  for (int i = 0; i < track->nb_tref_tags; i++)
7960  av_freep(&track->tref_tags[i].id);
7961  av_freep(&track->tref_tags);
7962  av_freep(&track->src_track);
7963 
7964  ff_mov_cenc_free(&track->cenc);
7965  ffio_free_dyn_buf(&track->mdat_buf);
7966 
7967 #if CONFIG_IAMFENC
7968  ffio_free_dyn_buf(&track->iamf_buf);
7969  if (track->iamf)
7970  ff_iamf_uninit_context(track->iamf);
7971  av_freep(&track->iamf);
7972 #endif
7973  ff_isom_close_apvc(&track->apv);
7974 
7976  }
7977 
7978  av_freep(&mov->tracks);
7979  ffio_free_dyn_buf(&mov->mdat_buf);
7980 }
7981 
7982 static uint32_t rgb_to_yuv(uint32_t rgb)
7983 {
7984  uint8_t r, g, b;
7985  int y, cb, cr;
7986 
7987  r = (rgb >> 16) & 0xFF;
7988  g = (rgb >> 8) & 0xFF;
7989  b = (rgb ) & 0xFF;
7990 
7991  y = av_clip_uint8(( 16000 + 257 * r + 504 * g + 98 * b)/1000);
7992  cb = av_clip_uint8((128000 - 148 * r - 291 * g + 439 * b)/1000);
7993  cr = av_clip_uint8((128000 + 439 * r - 368 * g - 71 * b)/1000);
7994 
7995  return (y << 16) | (cr << 8) | cb;
7996 }
7997 
7999  AVStream *st)
8000 {
8001  int i, width = 720, height = 480;
8002  int have_palette = 0, have_size = 0;
8003  uint32_t palette[16];
8004  char *cur = st->codecpar->extradata;
8005 
8006  while (cur && *cur) {
8007  if (strncmp("palette:", cur, 8) == 0) {
8008  int i, count;
8009  count = sscanf(cur + 8,
8010  "%06"PRIx32", %06"PRIx32", %06"PRIx32", %06"PRIx32", "
8011  "%06"PRIx32", %06"PRIx32", %06"PRIx32", %06"PRIx32", "
8012  "%06"PRIx32", %06"PRIx32", %06"PRIx32", %06"PRIx32", "
8013  "%06"PRIx32", %06"PRIx32", %06"PRIx32", %06"PRIx32"",
8014  &palette[ 0], &palette[ 1], &palette[ 2], &palette[ 3],
8015  &palette[ 4], &palette[ 5], &palette[ 6], &palette[ 7],
8016  &palette[ 8], &palette[ 9], &palette[10], &palette[11],
8017  &palette[12], &palette[13], &palette[14], &palette[15]);
8018 
8019  for (i = 0; i < count; i++) {
8020  palette[i] = rgb_to_yuv(palette[i]);
8021  }
8022  have_palette = 1;
8023  } else if (!strncmp("size:", cur, 5)) {
8024  sscanf(cur + 5, "%dx%d", &width, &height);
8025  have_size = 1;
8026  }
8027  if (have_palette && have_size)
8028  break;
8029  cur += strcspn(cur, "\n\r");
8030  cur += strspn(cur, "\n\r");
8031  }
8032  if (have_palette) {
8034  if (!track->extradata[track->last_stsd_index])
8035  return AVERROR(ENOMEM);
8036  for (i = 0; i < 16; i++) {
8037  AV_WB32(track->extradata[track->last_stsd_index] + i * 4, palette[i]);
8038  }
8039  memset(track->extradata[track->last_stsd_index] + 16*4, 0, AV_INPUT_BUFFER_PADDING_SIZE);
8040  track->extradata_size[track->last_stsd_index] = 16 * 4;
8041  }
8042  st->codecpar->width = width;
8043  st->codecpar->height = track->height = height;
8044 
8045  return 0;
8046 }
8047 
8048 #if CONFIG_IAMFENC
8049 static int mov_init_iamf_track(AVFormatContext *s)
8050 {
8051  MOVMuxContext *mov = s->priv_data;
8052  MOVTrack *track;
8053  IAMFContext *iamf;
8054  int first_iamf_idx = INT_MAX, last_iamf_idx = 0;
8055  int nb_audio_elements = 0, nb_mix_presentations = 0;
8056  int ret;
8057 
8058  for (int i = 0; i < s->nb_stream_groups; i++) {
8059  const AVStreamGroup *stg = s->stream_groups[i];
8060 
8062  nb_audio_elements++;
8064  nb_mix_presentations++;
8065  }
8066 
8067  if (!nb_audio_elements && !nb_mix_presentations)
8068  return 0;
8069 
8070  if (nb_audio_elements < 1 || nb_audio_elements > 2 || nb_mix_presentations < 1) {
8071  av_log(s, AV_LOG_ERROR, "There must be >= 1 and <= 2 IAMF_AUDIO_ELEMENT and at least "
8072  "one IAMF_MIX_PRESENTATION stream groups to write a IMAF track\n");
8073  return AVERROR(EINVAL);
8074  }
8075 
8076  iamf = av_mallocz(sizeof(*iamf));
8077  if (!iamf)
8078  return AVERROR(ENOMEM);
8079 
8080 
8081  for (int i = 0; i < s->nb_stream_groups; i++) {
8082  const AVStreamGroup *stg = s->stream_groups[i];
8083  switch(stg->type) {
8085  for (int j = 0; j < stg->nb_streams; j++) {
8086  first_iamf_idx = FFMIN(stg->streams[j]->index, first_iamf_idx);
8087  last_iamf_idx = FFMAX(stg->streams[j]->index, last_iamf_idx);
8088  }
8089 
8090  ret = ff_iamf_add_audio_element(iamf, stg, s);
8091  break;
8093  ret = ff_iamf_add_mix_presentation(iamf, stg, s);
8094  break;
8095  default:
8096  av_assert0(0);
8097  }
8098  if (ret < 0) {
8099  ff_iamf_uninit_context(iamf);
8100  av_free(iamf);
8101  return ret;
8102  }
8103  }
8104 
8105  track = &mov->tracks[first_iamf_idx];
8106  track->iamf = iamf;
8107  track->first_iamf_idx = first_iamf_idx;
8108  track->last_iamf_idx = last_iamf_idx;
8109  track->tag = MKTAG('i','a','m','f');
8110 
8111  for (int i = 0; i < s->nb_stream_groups; i++) {
8112  AVStreamGroup *stg = s->stream_groups[i];
8114  continue;
8115  for (int j = 0; j < stg->nb_streams; j++)
8116  stg->streams[j]->priv_data = track;
8117  }
8118 
8119  ret = avio_open_dyn_buf(&track->iamf_buf);
8120  if (ret < 0)
8121  return ret;
8122 
8123  return 0;
8124 }
8125 #endif
8126 
8128 {
8129  MOVMuxContext *mov = s->priv_data;
8130  int has_iamf = 0;
8131  int i, ret;
8132 
8133  mov->fc = s;
8134  mov->pkt = ffformatcontext(s)->pkt;
8135 
8136  /* Default mode == MP4 */
8137  mov->mode = MODE_MP4;
8138 
8139 #define IS_MODE(muxer, config) (CONFIG_ ## config ## _MUXER && !strcmp(#muxer, s->oformat->name))
8140  if (IS_MODE(3gp, TGP)) mov->mode = MODE_3GP;
8141  else if (IS_MODE(3g2, TG2)) mov->mode = MODE_3GP|MODE_3G2;
8142  else if (IS_MODE(mov, MOV)) mov->mode = MODE_MOV;
8143  else if (IS_MODE(psp, PSP)) mov->mode = MODE_PSP;
8144  else if (IS_MODE(ipod, IPOD)) mov->mode = MODE_IPOD;
8145  else if (IS_MODE(ismv, ISMV)) mov->mode = MODE_ISM;
8146  else if (IS_MODE(f4v, F4V)) mov->mode = MODE_F4V;
8147  else if (IS_MODE(avif, AVIF)) mov->mode = MODE_AVIF;
8148 #undef IS_MODE
8149 
8150  if (mov->flags & FF_MOV_FLAG_DELAY_MOOV)
8151  mov->flags |= FF_MOV_FLAG_EMPTY_MOOV;
8152 
8153  if (mov->mode == MODE_AVIF)
8154  mov->flags |= FF_MOV_FLAG_DELAY_MOOV;
8155 
8156  /* Set the FRAGMENT flag if any of the fragmentation methods are
8157  * enabled. */
8158  if (mov->max_fragment_duration || mov->max_fragment_size ||
8159  mov->flags & (FF_MOV_FLAG_EMPTY_MOOV |
8163  mov->flags |= FF_MOV_FLAG_FRAGMENT;
8164 
8165  if (mov->flags & FF_MOV_FLAG_HYBRID_FRAGMENTED &&
8166  mov->flags & FF_MOV_FLAG_FASTSTART) {
8167  av_log(s, AV_LOG_ERROR, "Setting both hybrid_fragmented and faststart is not supported.\n");
8168  return AVERROR(EINVAL);
8169  }
8170 
8171  /* Set other implicit flags immediately */
8173  mov->flags |= FF_MOV_FLAG_FRAGMENT;
8174 
8175  if (mov->mode == MODE_ISM)
8178  if (mov->flags & FF_MOV_FLAG_DASH)
8181  if (mov->flags & FF_MOV_FLAG_CMAF)
8184 
8185  if (mov->flags & FF_MOV_FLAG_EMPTY_MOOV && s->flags & AVFMT_FLAG_AUTO_BSF) {
8186  av_log(s, AV_LOG_VERBOSE, "Empty MOOV enabled; disabling automatic bitstream filtering\n");
8187  s->flags &= ~AVFMT_FLAG_AUTO_BSF;
8188  }
8189 
8191  av_log(s, AV_LOG_WARNING, "Global SIDX enabled; Ignoring skip_sidx option\n");
8192  mov->flags &= ~FF_MOV_FLAG_SKIP_SIDX;
8193  }
8194 
8195  if (mov->flags & FF_MOV_FLAG_FASTSTART) {
8196  mov->reserved_moov_size = -1;
8197  }
8198 
8199  if (mov->use_editlist < 0) {
8200  mov->use_editlist = 1;
8201  if (mov->flags & FF_MOV_FLAG_FRAGMENT &&
8202  !(mov->flags & FF_MOV_FLAG_DELAY_MOOV)) {
8203  // If we can avoid needing an edit list by shifting the
8204  // tracks, prefer that over (trying to) write edit lists
8205  // in fragmented output.
8206  if (s->avoid_negative_ts == AVFMT_AVOID_NEG_TS_AUTO ||
8207  s->avoid_negative_ts == AVFMT_AVOID_NEG_TS_MAKE_ZERO)
8208  mov->use_editlist = 0;
8209  }
8210  }
8211  if (mov->flags & FF_MOV_FLAG_EMPTY_MOOV &&
8212  !(mov->flags & FF_MOV_FLAG_DELAY_MOOV) && mov->use_editlist)
8213  av_log(s, AV_LOG_WARNING, "No meaningful edit list will be written when using empty_moov without delay_moov\n");
8214 
8215  if (mov->flags & FF_MOV_FLAG_CMAF && mov->use_editlist)
8217 
8218  if (!mov->use_editlist && s->avoid_negative_ts == AVFMT_AVOID_NEG_TS_AUTO &&
8220  s->avoid_negative_ts = AVFMT_AVOID_NEG_TS_MAKE_ZERO;
8221 
8222  /* Clear the omit_tfhd_offset flag if default_base_moof is set;
8223  * if the latter is set that's enough and omit_tfhd_offset doesn't
8224  * add anything extra on top of that. */
8225  if (mov->flags & FF_MOV_FLAG_OMIT_TFHD_OFFSET &&
8228 
8229  if (mov->frag_interleave &&
8232  "Sample interleaving in fragments is mutually exclusive with "
8233  "omit_tfhd_offset and separate_moof\n");
8234  return AVERROR(EINVAL);
8235  }
8236 
8237  /* Non-seekable output is ok if using fragmentation. If ism_lookahead
8238  * is enabled, we don't support non-seekable output at all. */
8239  if (!(s->pb->seekable & AVIO_SEEKABLE_NORMAL) &&
8240  (!(mov->flags & FF_MOV_FLAG_FRAGMENT) || mov->ism_lookahead ||
8241  mov->mode == MODE_AVIF)) {
8242  av_log(s, AV_LOG_ERROR, "muxer does not support non seekable output\n");
8243  return AVERROR(EINVAL);
8244  }
8245 
8246  /* AVIF output must have at most two video streams (one for YUV and one for
8247  * alpha). */
8248  if (mov->mode == MODE_AVIF) {
8249  if (s->nb_streams > 2) {
8250  av_log(s, AV_LOG_ERROR, "AVIF output requires exactly one or two streams\n");
8251  return AVERROR(EINVAL);
8252  }
8253  if (s->streams[0]->codecpar->codec_type != AVMEDIA_TYPE_VIDEO &&
8254  (s->nb_streams > 1 && s->streams[1]->codecpar->codec_type != AVMEDIA_TYPE_VIDEO)) {
8255  av_log(s, AV_LOG_ERROR, "AVIF output supports only video streams\n");
8256  return AVERROR(EINVAL);
8257  }
8258  if (s->nb_streams > 1) {
8259  const AVPixFmtDescriptor *pixdesc =
8260  av_pix_fmt_desc_get(s->streams[1]->codecpar->format);
8261  if (pixdesc->nb_components != 1) {
8262  av_log(s, AV_LOG_ERROR, "Second stream for AVIF (alpha) output must have exactly one plane\n");
8263  return AVERROR(EINVAL);
8264  }
8265  }
8266  s->streams[0]->disposition |= AV_DISPOSITION_DEFAULT;
8267  }
8268 
8269  for (i = 0; i < s->nb_stream_groups; i++) {
8270  AVStreamGroup *stg = s->stream_groups[i];
8271 
8272  if (stg->type == AV_STREAM_GROUP_PARAMS_LCEVC) {
8273  if (stg->nb_streams != 2) {
8274  av_log(s, AV_LOG_ERROR, "Exactly two Streams are supported for Stream Groups of type LCEVC\n");
8275  return AVERROR(EINVAL);
8276  }
8278  if (lcevc->el_index > 1)
8279  return AVERROR(EINVAL);
8280  AVStream *st = stg->streams[lcevc->el_index];
8281  if (st->codecpar->codec_id != AV_CODEC_ID_LCEVC) {
8282  av_log(s, AV_LOG_ERROR, "Stream #%u is not an LCEVC stream\n", lcevc->el_index);
8283  return AVERROR(EINVAL);
8284  }
8285  }
8286 
8287 #if CONFIG_IAMFENC
8289  continue;
8290 
8291  for (int j = 0; j < stg->nb_streams; j++) {
8292  AVStream *st = stg->streams[j];
8293 
8294  if (st->priv_data) {
8295  av_log(s, AV_LOG_ERROR, "Stream %d is present in more than one Stream Group of type "
8296  "IAMF Audio Element\n", j);
8297  return AVERROR(EINVAL);
8298  }
8299  st->priv_data = st;
8300  }
8301  has_iamf = 1;
8302 
8303  if (!mov->nb_tracks) // We support one track for the entire IAMF structure
8304  mov->nb_tracks++;
8305 #endif
8306  }
8307 
8308  for (i = 0; i < s->nb_streams; i++) {
8309  AVStream *st = s->streams[i];
8310  if (st->priv_data)
8311  continue;
8312  // Don't produce a track in the output file for timed ID3 streams.
8313  if (st->codecpar->codec_id == AV_CODEC_ID_TIMED_ID3) {
8314  // Leave priv_data set to NULL for these AVStreams that don't
8315  // have a corresponding track.
8316  continue;
8317  }
8318  st->priv_data = st;
8319  mov->nb_tracks++;
8320  }
8321 
8322  mov->nb_streams = mov->nb_tracks;
8323 
8324  if (mov->mode & (MODE_MP4|MODE_MOV|MODE_IPOD) && s->nb_chapters)
8325  mov->chapter_track = mov->nb_tracks++;
8326 
8327  if (mov->flags & FF_MOV_FLAG_RTP_HINT) {
8328  for (i = 0; i < s->nb_streams; i++)
8329  if (rtp_hinting_needed(s->streams[i]))
8330  mov->nb_tracks++;
8331  }
8332 
8333  if (mov->write_btrt < 0) {
8334  mov->write_btrt = mov->mode == MODE_MP4;
8335  }
8336 
8337  if ( mov->write_tmcd == -1 && (mov->mode == MODE_MOV || mov->mode == MODE_MP4)
8338  || mov->write_tmcd == 1) {
8339  AVDictionaryEntry *global_tcr = av_dict_get(s->metadata, "timecode",
8340  NULL, 0);
8341 
8342  /* +1 tmcd track for each video stream with a timecode */
8343  for (i = 0; i < s->nb_streams; i++) {
8344  AVStream *st = s->streams[i];
8345  AVDictionaryEntry *t = global_tcr;
8346  if (st->codecpar->codec_type == AVMEDIA_TYPE_VIDEO &&
8347  (t || (t=av_dict_get(st->metadata, "timecode", NULL, 0)))) {
8348  AVTimecode tc;
8349  ret = mov_check_timecode_track(s, &tc, st, t->value);
8350  if (ret >= 0)
8351  mov->nb_meta_tmcd++;
8352  }
8353  }
8354 
8355  /* check if there is already a tmcd track to remux */
8356  if (mov->nb_meta_tmcd) {
8357  for (i = 0; i < s->nb_streams; i++) {
8358  AVStream *st = s->streams[i];
8359  if (st->codecpar->codec_tag == MKTAG('t','m','c','d')) {
8360  av_log(s, AV_LOG_WARNING, "You requested a copy of the original timecode track "
8361  "so timecode metadata are now ignored\n");
8362  mov->nb_meta_tmcd = 0;
8363  }
8364  }
8365  }
8366 
8367  mov->nb_tracks += mov->nb_meta_tmcd;
8368  }
8369 
8370  // Reserve an extra stream for chapters for the case where chapters
8371  // are written in the trailer
8372  mov->tracks = av_calloc(mov->nb_tracks + 1, sizeof(*mov->tracks));
8373  if (!mov->tracks)
8374  return AVERROR(ENOMEM);
8375 
8376  for (i = 0; i < mov->nb_tracks; i++) {
8377  MOVTrack *track = &mov->tracks[i];
8378 
8379  track->stsd_count = 1;
8380  track->extradata = av_calloc(track->stsd_count, sizeof(*track->extradata));
8381  track->extradata_size = av_calloc(track->stsd_count, sizeof(*track->extradata_size));
8382  if (!track->extradata || !track->extradata_size)
8383  return AVERROR(ENOMEM);
8384  }
8385 
8386  if (mov->encryption_scheme_str != NULL && strcmp(mov->encryption_scheme_str, "none") != 0) {
8387  if (strcmp(mov->encryption_scheme_str, "cenc-aes-ctr") == 0) {
8389 
8390  if (mov->encryption_key_len != AES_CTR_KEY_SIZE) {
8391  av_log(s, AV_LOG_ERROR, "Invalid encryption key len %d expected %d\n",
8393  return AVERROR(EINVAL);
8394  }
8395 
8396  if (mov->encryption_kid_len != CENC_KID_SIZE) {
8397  av_log(s, AV_LOG_ERROR, "Invalid encryption kid len %d expected %d\n",
8399  return AVERROR(EINVAL);
8400  }
8401  } else {
8402  av_log(s, AV_LOG_ERROR, "unsupported encryption scheme %s\n",
8403  mov->encryption_scheme_str);
8404  return AVERROR(EINVAL);
8405  }
8406  }
8407 
8408 #if CONFIG_IAMFENC
8409  ret = mov_init_iamf_track(s);
8410  if (ret < 0)
8411  return ret;
8412 #endif
8413 
8414  for (int j = 0, i = 0; j < s->nb_streams; j++) {
8415  AVStream *st = s->streams[j];
8416 
8417  if (st != st->priv_data) {
8418  if (has_iamf)
8419  i += has_iamf--;
8420  continue;
8421  }
8422  st->priv_data = &mov->tracks[i++];
8423  }
8424 
8425  AVRational movie_timescale = (AVRational) { 0, 1 };
8426  for (i = 0; i < s->nb_streams; i++) {
8427  AVStream *st= s->streams[i];
8428  MOVTrack *track = st->priv_data;
8429 
8430  if (!track)
8431  continue;
8432 
8433  if (!track->st) {
8434  track->st = st;
8435  track->par = st->codecpar;
8436  }
8437 
8438  movie_timescale = av_gcd_q(movie_timescale, st->time_base, INT_MAX, (AVRational){1,0});
8439  }
8440  if (!movie_timescale.den)
8441  movie_timescale = MOV_TIMESCALE_Q;
8442 
8443  if (!mov->movie_timescale)
8444  mov->movie_timescale = FFMAX(movie_timescale.den, MOV_TIMESCALE);
8445 
8446  for (i = 0; i < s->nb_streams; i++) {
8447  AVStream *st= s->streams[i];
8448  MOVTrack *track = st->priv_data;
8449  AVDictionaryEntry *lang = av_dict_get(st->metadata, "language", NULL,0);
8450 
8451  if (!track)
8452  continue;
8453 
8454  track->language = ff_mov_iso639_to_lang(lang?lang->value:"und", mov->mode!=MODE_MOV);
8455  if (track->language < 0)
8456  track->language = 32767; // Unspecified Macintosh language code
8457  track->mode = mov->mode;
8458  if (!track->tag)
8459  track->tag = mov_find_codec_tag(s, track);
8460  if (!track->tag) {
8461  av_log(s, AV_LOG_ERROR, "Could not find tag for codec %s in stream #%d, "
8462  "codec not currently supported in container\n",
8464  return AVERROR(EINVAL);
8465  }
8466  /* If hinting of this track is enabled by a later hint track,
8467  * this is updated. */
8468  track->hint_track = -1;
8469  track->start_dts = AV_NOPTS_VALUE;
8470  track->start_cts = AV_NOPTS_VALUE;
8471  track->end_pts = AV_NOPTS_VALUE;
8472  track->dts_shift = AV_NOPTS_VALUE;
8473  if (st->codecpar->codec_type == AVMEDIA_TYPE_VIDEO) {
8474  if (track->tag == MKTAG('m','x','3','p') || track->tag == MKTAG('m','x','3','n') ||
8475  track->tag == MKTAG('m','x','4','p') || track->tag == MKTAG('m','x','4','n') ||
8476  track->tag == MKTAG('m','x','5','p') || track->tag == MKTAG('m','x','5','n')) {
8477  if (st->codecpar->width != 720 || (st->codecpar->height != 608 && st->codecpar->height != 512)) {
8478  av_log(s, AV_LOG_ERROR, "D-10/IMX must use 720x608 or 720x512 video resolution\n");
8479  return AVERROR(EINVAL);
8480  }
8481  track->height = track->tag >> 24 == 'n' ? 486 : 576;
8482  }
8483  if (mov->video_track_timescale) {
8484  track->timescale = mov->video_track_timescale;
8485  if (mov->mode == MODE_ISM && mov->video_track_timescale != 10000000)
8486  av_log(s, AV_LOG_WARNING, "Warning: some tools, like mp4split, assume a timescale of 10000000 for ISMV.\n");
8487  } else {
8488  track->timescale = st->time_base.den;
8489  while(track->timescale < 10000)
8490  track->timescale *= 2;
8491  }
8492  if (st->codecpar->width > 65535 || st->codecpar->height > 65535) {
8493  av_log(s, AV_LOG_ERROR, "Resolution %dx%d too large for mov/mp4\n", st->codecpar->width, st->codecpar->height);
8494  return AVERROR(EINVAL);
8495  }
8496  if (track->mode == MODE_MOV && track->timescale > 100000)
8498  "WARNING codec timebase is very high. If duration is too long,\n"
8499  "file may not be playable by quicktime. Specify a shorter timebase\n"
8500  "or choose different container.\n");
8501  if (track->mode == MODE_MOV &&
8502  track->par->codec_id == AV_CODEC_ID_RAWVIDEO &&
8503  track->tag == MKTAG('r','a','w',' ')) {
8504  enum AVPixelFormat pix_fmt = track->par->format;
8505  if (pix_fmt == AV_PIX_FMT_NONE && track->par->bits_per_coded_sample == 1)
8507  track->is_unaligned_qt_rgb =
8510  pix_fmt == AV_PIX_FMT_PAL8 ||
8514  }
8515  if (track->par->codec_id == AV_CODEC_ID_VP9 && track->mode != MODE_MP4) {
8516  av_log(s, AV_LOG_ERROR, "%s only supported in MP4.\n", avcodec_get_name(track->par->codec_id));
8517  return AVERROR(EINVAL);
8518  } else if (track->par->codec_id == AV_CODEC_ID_AV1 &&
8519  track->mode != MODE_MP4 && track->mode != MODE_AVIF) {
8520  av_log(s, AV_LOG_ERROR, "%s only supported in MP4 and AVIF.\n", avcodec_get_name(track->par->codec_id));
8521  return AVERROR(EINVAL);
8522  } else if (track->par->codec_id == AV_CODEC_ID_VP8) {
8523  /* altref frames handling is not defined in the spec as of version v1.0,
8524  * so just forbid muxing VP8 streams altogether until a new version does */
8525  av_log(s, AV_LOG_ERROR, "VP8 muxing is currently not supported.\n");
8526  return AVERROR_PATCHWELCOME;
8527  } else if (track->par->codec_id == AV_CODEC_ID_APV) {
8528  ret = ff_isom_init_apvc(&track->apv, s);
8529  if (ret < 0)
8530  return ret;
8531  }
8532  if (is_cover_image(st)) {
8533  track->cover_image = av_packet_alloc();
8534  if (!track->cover_image)
8535  return AVERROR(ENOMEM);
8536  }
8537  } else if (st->codecpar->codec_type == AVMEDIA_TYPE_AUDIO) {
8538  track->timescale = st->codecpar->sample_rate;
8540  av_log(s, AV_LOG_WARNING, "track %d: codec frame size is not set\n", i);
8541  track->audio_vbr = 1;
8542  }else if (st->codecpar->codec_id == AV_CODEC_ID_ADPCM_MS ||
8545  if (!st->codecpar->block_align) {
8546  av_log(s, AV_LOG_ERROR, "track %d: codec block align is not set for adpcm\n", i);
8547  return AVERROR(EINVAL);
8548  }
8549  track->sample_size = st->codecpar->block_align;
8550  }else if (st->codecpar->frame_size > 1){ /* assume compressed audio */
8551  track->audio_vbr = 1;
8552  }else{
8553  track->sample_size = (av_get_bits_per_sample(st->codecpar->codec_id) >> 3) *
8555  }
8556  if (st->codecpar->codec_id == AV_CODEC_ID_ILBC ||
8558  track->audio_vbr = 1;
8559  }
8560  if (track->mode != MODE_MOV &&
8561  track->par->codec_id == AV_CODEC_ID_MP3 && track->timescale < 16000) {
8562  if (s->strict_std_compliance >= FF_COMPLIANCE_NORMAL) {
8563  av_log(s, AV_LOG_ERROR, "track %d: muxing mp3 at %dhz is not standard, to mux anyway set strict to -1\n",
8564  i, track->par->sample_rate);
8565  return AVERROR(EINVAL);
8566  } else {
8567  av_log(s, AV_LOG_WARNING, "track %d: muxing mp3 at %dhz is not standard in MP4\n",
8568  i, track->par->sample_rate);
8569  }
8570  }
8571  if (track->par->codec_id == AV_CODEC_ID_FLAC ||
8572  track->par->codec_id == AV_CODEC_ID_TRUEHD ||
8573  track->par->codec_id == AV_CODEC_ID_OPUS) {
8574  if (track->mode != MODE_MP4) {
8575  av_log(s, AV_LOG_ERROR, "%s only supported in MP4.\n", avcodec_get_name(track->par->codec_id));
8576  return AVERROR(EINVAL);
8577  }
8578  if (track->par->codec_id == AV_CODEC_ID_TRUEHD &&
8579  s->strict_std_compliance > FF_COMPLIANCE_EXPERIMENTAL) {
8581  "%s in MP4 support is experimental, add "
8582  "'-strict %d' if you want to use it.\n",
8584  return AVERROR_EXPERIMENTAL;
8585  }
8586  }
8587  } else if (st->codecpar->codec_type == AVMEDIA_TYPE_SUBTITLE) {
8588  track->timescale = st->time_base.den;
8589 
8590  if (track->par->codec_id == AV_CODEC_ID_TTML) {
8591  /* 14496-30 requires us to use a single sample per fragment
8592  for TTML, for which we define a per-track flag.
8593 
8594  We set the flag in case we are receiving TTML paragraphs
8595  from the input, in other words in case we are not doing
8596  stream copy. */
8599 
8600  if (track->mode != MODE_ISM &&
8601  track->par->codec_tag == MOV_ISMV_TTML_TAG &&
8602  s->strict_std_compliance > FF_COMPLIANCE_UNOFFICIAL) {
8604  "ISMV style TTML support with the 'dfxp' tag in "
8605  "non-ISMV formats is not officially supported. Add "
8606  "'-strict unofficial' if you want to use it.\n");
8607  return AVERROR_EXPERIMENTAL;
8608  }
8609  }
8610  } else if (st->codecpar->codec_type == AVMEDIA_TYPE_DATA) {
8611  track->timescale = st->time_base.den;
8612  } else {
8613  track->timescale = mov->movie_timescale;
8614  }
8615  if (!track->height)
8616  track->height = st->codecpar->height;
8617  /* The Protected Interoperable File Format (PIFF) standard, used by ISMV recommends but
8618  doesn't mandate a track timescale of 10,000,000. The muxer allows a custom timescale
8619  for video tracks, so if user-set, it isn't overwritten */
8620  if (mov->mode == MODE_ISM &&
8623  track->timescale = 10000000;
8624  }
8625 
8626  avpriv_set_pts_info(st, 64, 1, track->timescale);
8627 
8629  ret = ff_mov_cenc_init(&track->cenc, mov->encryption_key,
8630  (track->par->codec_id == AV_CODEC_ID_H264 || track->par->codec_id == AV_CODEC_ID_HEVC ||
8631  track->par->codec_id == AV_CODEC_ID_VVC || track->par->codec_id == AV_CODEC_ID_AV1),
8632  track->par->codec_id, s->flags & AVFMT_FLAG_BITEXACT);
8633  if (ret)
8634  return ret;
8635  }
8636  }
8637 
8638  for (i = 0; i < s->nb_stream_groups; i++) {
8639  AVStreamGroup *stg = s->stream_groups[i];
8640 
8641  switch (stg->type) {
8644  AVStream *st = stg->streams[lcevc->el_index];
8645  MOVTrack *track = st->priv_data;
8646 
8647  for (int j = 0; j < mov->nb_tracks; j++) {
8648  MOVTrack *trk = &mov->tracks[j];
8649 
8650  if (trk->st == stg->streams[!lcevc->el_index]) {
8651  track->src_track = av_malloc(sizeof(*track->src_track));
8652  if (!track->src_track)
8653  return AVERROR(ENOMEM);
8654  *track->src_track = j;
8655  track->nb_src_track = 1;
8656  break;
8657  }
8658  }
8659 
8660  track->par->width = lcevc->width;
8661  track->par->height = track->height = lcevc->height;
8662  break;
8663  }
8665  const AVStreamGroupTREF *tref = stg->params.tref;
8666  MOVTrack *track;
8667 
8668  if (tref->metadata_index >= stg->nb_streams)
8669  return AVERROR(EINVAL);
8670 
8671  track = stg->streams[tref->metadata_index]->priv_data;
8672  for (int j = 0; j < stg->nb_streams; j++) {
8673  const AVStream *st2 = stg->streams[j];
8674  int index = -1;
8675 
8676  if (j == tref->metadata_index)
8677  continue;
8678 
8679  for (int k = 0; k < mov->nb_tracks; k++) {
8680  if (mov->tracks[k].st != st2)
8681  continue;
8682  index = k;
8683  break;
8684  }
8685  if (index < 0)
8686  return AVERROR(EINVAL);
8687 
8688  int *tmp = av_realloc(track->src_track,
8689  (track->nb_src_track + 1) * sizeof(*track->src_track));
8690  if (!tmp)
8691  return AVERROR(ENOMEM);
8692  track->src_track = tmp;
8693  track->src_track[track->nb_src_track++] = index;
8694  }
8695  break;
8696  }
8697  default:
8698  break;
8699  }
8700  }
8701 
8702  /* fill src_track for tmcd tracks not covered by stream groups or
8703  * created by this muxer, retaining the old behavior of src_track
8704  * being arbitrarily 0. */
8705  for (i = 0; i < s->nb_streams; i++) {
8706  AVStream *st = s->streams[i];
8707  MOVTrack *track = st->priv_data;
8708  if (st->codecpar->codec_tag != MKTAG('t','m','c','d') ||
8709  track->nb_src_track)
8710  continue;
8711 
8712  track->src_track = av_malloc(sizeof(*track->src_track));
8713  if (!track->src_track)
8714  return AVERROR(ENOMEM);
8715  *track->src_track = 0;
8716  track->nb_src_track = 1;
8717  }
8718 
8719  enable_tracks(s);
8720  return 0;
8721 }
8722 
8724 {
8725  AVIOContext *pb = s->pb;
8726  MOVMuxContext *mov = s->priv_data;
8727  int ret, hint_track = 0, tmcd_track = 0, nb_tracks = mov->nb_streams;
8728 
8729  if (mov->mode & (MODE_MP4|MODE_MOV|MODE_IPOD) && s->nb_chapters)
8730  nb_tracks++;
8731 
8732  if (mov->flags & FF_MOV_FLAG_RTP_HINT) {
8733  hint_track = nb_tracks;
8734  for (int i = 0; i < mov->nb_streams; i++) {
8735  if (rtp_hinting_needed(mov->tracks[i].st))
8736  nb_tracks++;
8737  }
8738  }
8739 
8740  if (mov->nb_meta_tmcd)
8741  tmcd_track = nb_tracks;
8742 
8743  for (int i = 0; i < mov->nb_streams; i++) {
8744  MOVTrack *track = &mov->tracks[i];
8745  AVStream *st = track->st;
8746 
8747  /* copy extradata if it exists */
8748  if (st->codecpar->extradata_size) {
8751  else if (!TAG_IS_AVCI(track->tag) && st->codecpar->codec_id != AV_CODEC_ID_DNXHD) {
8752  track->extradata_size[track->last_stsd_index] = st->codecpar->extradata_size;
8753  track->extradata[track->last_stsd_index] =
8755  if (!track->extradata[track->last_stsd_index]) {
8756  return AVERROR(ENOMEM);
8757  }
8758  memcpy(track->extradata[track->last_stsd_index],
8759  st->codecpar->extradata, track->extradata_size[track->last_stsd_index]);
8760  memset(track->extradata[track->last_stsd_index] + track->extradata_size[track->last_stsd_index],
8762  }
8763  }
8764 
8765  if (st->codecpar->codec_type != AVMEDIA_TYPE_AUDIO ||
8768  continue;
8769 
8770  for (int j = 0; j < mov->nb_streams; j++) {
8771  AVStream *stj= mov->tracks[j].st;
8772  MOVTrack *trackj= &mov->tracks[j];
8773  if (j == i)
8774  continue;
8775 
8776  if (stj->codecpar->codec_type == AVMEDIA_TYPE_AUDIO &&
8777  (trackj->par->ch_layout.nb_channels != 1 ||
8780  )
8781  track->mono_as_fc = -1;
8782 
8783  if (stj->codecpar->codec_type == AVMEDIA_TYPE_AUDIO &&
8786  trackj->par->ch_layout.nb_channels == 1 && track->mono_as_fc >= 0
8787  )
8788  track->mono_as_fc++;
8789 
8790  if (stj->codecpar->codec_type != AVMEDIA_TYPE_AUDIO ||
8793  trackj->language != track->language ||
8794  trackj->tag != track->tag
8795  )
8796  continue;
8797  track->multichannel_as_mono++;
8798  }
8799  }
8800 
8801  if (!(mov->flags & FF_MOV_FLAG_DELAY_MOOV) ||
8803  if ((ret = mov_write_identification(pb, s)) < 0)
8804  return ret;
8805  }
8806 
8807  if (mov->reserved_moov_size){
8808  mov->reserved_header_pos = avio_tell(pb);
8809  if (mov->reserved_moov_size > 0)
8810  avio_skip(pb, mov->reserved_moov_size);
8811  }
8812 
8813  if (mov->flags & FF_MOV_FLAG_FRAGMENT) {
8814  /* If no fragmentation options have been set, set a default. */
8815  if (!(mov->flags & (FF_MOV_FLAG_FRAG_KEYFRAME |
8820  if (mov->flags & FF_MOV_FLAG_HYBRID_FRAGMENTED) {
8821  avio_wb32(pb, 8); // placeholder for extended size field (64 bit)
8822  ffio_wfourcc(pb, mov->mode == MODE_MOV ? "wide" : "free");
8823  mov->mdat_pos = avio_tell(pb);
8824  // The free/wide header that later will be converted into an
8825  // mdat, covering the initial moov and all the fragments.
8826  avio_wb32(pb, 0);
8827  ffio_wfourcc(pb, mov->mode == MODE_MOV ? "wide" : "free");
8828  // Write an ftyp atom, hidden in a free/wide. This is neither
8829  // exposed while the file is written, as fragmented, nor when the
8830  // file is finalized into non-fragmented form. However, this allows
8831  // accessing a pristine, sequential ftyp+moov init segment, even
8832  // after the file is finalized. It also allows dumping the whole
8833  // contents of the mdat box, to get the fragmented form of the
8834  // file.
8835  if ((ret = mov_write_identification(pb, s)) < 0)
8836  return ret;
8837  update_size(pb, mov->mdat_pos);
8838  }
8839  } else if (mov->mode != MODE_AVIF) {
8840  if (mov->flags & FF_MOV_FLAG_FASTSTART)
8841  mov->reserved_header_pos = avio_tell(pb);
8842  mov_write_mdat_tag(pb, mov);
8843  }
8844 
8846  if (mov->time)
8847  mov->time += 0x7C25B080; // 1970 based -> 1904 based
8848 
8849  if (mov->chapter_track)
8850  if ((ret = mov_create_chapter_track(s, mov->chapter_track)) < 0)
8851  return ret;
8852 
8853  if (mov->flags & FF_MOV_FLAG_RTP_HINT) {
8854  for (int i = 0; i < mov->nb_streams; i++) {
8855  if (rtp_hinting_needed(mov->tracks[i].st)) {
8856  if ((ret = ff_mov_init_hinting(s, hint_track, i)) < 0)
8857  return ret;
8858  hint_track++;
8859  }
8860  }
8861  }
8862 
8863  if (mov->nb_meta_tmcd) {
8864  const AVDictionaryEntry *t, *global_tcr = av_dict_get(s->metadata,
8865  "timecode", NULL, 0);
8866  /* Initialize the tmcd tracks */
8867  for (int i = 0; i < mov->nb_streams; i++) {
8868  AVStream *st = mov->tracks[i].st;
8869  t = global_tcr;
8870 
8871  if (st->codecpar->codec_type == AVMEDIA_TYPE_VIDEO) {
8872  AVTimecode tc;
8873  if (!t)
8874  t = av_dict_get(st->metadata, "timecode", NULL, 0);
8875  if (!t)
8876  continue;
8877  if (mov_check_timecode_track(s, &tc, st, t->value) < 0)
8878  continue;
8879  if ((ret = mov_create_timecode_track(s, tmcd_track, i, tc)) < 0)
8880  return ret;
8881  tmcd_track++;
8882  }
8883  }
8884  }
8885 
8886  avio_flush(pb);
8887 
8888  if (mov->flags & FF_MOV_FLAG_ISML)
8889  mov_write_isml_manifest(pb, mov, s);
8890 
8891  if (mov->flags & FF_MOV_FLAG_EMPTY_MOOV &&
8892  !(mov->flags & FF_MOV_FLAG_DELAY_MOOV)) {
8893  if ((ret = mov_write_moov_tag(pb, mov, s)) < 0)
8894  return ret;
8895  mov->moov_written = 1;
8896  if (mov->flags & FF_MOV_FLAG_GLOBAL_SIDX)
8897  mov->reserved_header_pos = avio_tell(pb);
8898  }
8899 
8900  return 0;
8901 }
8902 
8904 {
8905  int ret;
8906  AVIOContext *moov_buf;
8907  MOVMuxContext *mov = s->priv_data;
8908 
8909  if ((ret = ffio_open_null_buf(&moov_buf)) < 0)
8910  return ret;
8911  if ((ret = mov_write_moov_tag(moov_buf, mov, s)) < 0)
8912  return ret;
8913  return ffio_close_null_buf(moov_buf);
8914 }
8915 
8917 {
8918  int ret;
8919  AVIOContext *buf;
8920  MOVMuxContext *mov = s->priv_data;
8921 
8922  if ((ret = ffio_open_null_buf(&buf)) < 0)
8923  return ret;
8924  mov_write_sidx_tags(buf, mov, -1, 0);
8925  return ffio_close_null_buf(buf);
8926 }
8927 
8928 /*
8929  * This function gets the moov size if moved to the top of the file: the chunk
8930  * offset table can switch between stco (32-bit entries) to co64 (64-bit
8931  * entries) when the moov is moved to the beginning, so the size of the moov
8932  * would change. It also updates the chunk offset tables.
8933  */
8935 {
8936  int i, moov_size, moov_size2;
8937  MOVMuxContext *mov = s->priv_data;
8938 
8939  moov_size = get_moov_size(s);
8940  if (moov_size < 0)
8941  return moov_size;
8942 
8943  for (i = 0; i < mov->nb_tracks; i++)
8944  mov->tracks[i].data_offset += moov_size;
8945 
8946  moov_size2 = get_moov_size(s);
8947  if (moov_size2 < 0)
8948  return moov_size2;
8949 
8950  /* if the size changed, we just switched from stco to co64 and need to
8951  * update the offsets */
8952  if (moov_size2 != moov_size)
8953  for (i = 0; i < mov->nb_tracks; i++)
8954  mov->tracks[i].data_offset += moov_size2 - moov_size;
8955 
8956  return moov_size2;
8957 }
8958 
8960 {
8961  int i, sidx_size;
8962  MOVMuxContext *mov = s->priv_data;
8963 
8964  sidx_size = get_sidx_size(s);
8965  if (sidx_size < 0)
8966  return sidx_size;
8967 
8968  for (i = 0; i < mov->nb_tracks; i++)
8969  mov->tracks[i].data_offset += sidx_size;
8970 
8971  return sidx_size;
8972 }
8973 
8975 {
8976  int moov_size;
8977  MOVMuxContext *mov = s->priv_data;
8978 
8979  if (mov->flags & FF_MOV_FLAG_FRAGMENT)
8980  moov_size = compute_sidx_size(s);
8981  else
8982  moov_size = compute_moov_size(s);
8983  if (moov_size < 0)
8984  return moov_size;
8985 
8986  return ff_format_shift_data(s, mov->reserved_header_pos, moov_size);
8987 }
8988 
8990 {
8991  MOVMuxContext *mov = s->priv_data;
8992  AVIOContext *pb = s->pb;
8993 
8994  /* Write size of mdat tag */
8995  if (mov->mdat_size + 8 <= UINT32_MAX) {
8996  avio_seek(pb, mov->mdat_pos, SEEK_SET);
8997  avio_wb32(pb, mov->mdat_size + 8);
8999  ffio_wfourcc(pb, "mdat"); // overwrite the original free/wide into a mdat
9000  } else {
9001  /* overwrite 'wide' placeholder atom */
9002  avio_seek(pb, mov->mdat_pos - 8, SEEK_SET);
9003  /* special value: real atom size will be 64 bit value after
9004  * tag field */
9005  avio_wb32(pb, 1);
9006  ffio_wfourcc(pb, "mdat");
9007  avio_wb64(pb, mov->mdat_size + 16);
9008  }
9009 }
9010 
9012 {
9013  MOVMuxContext *mov = s->priv_data;
9014  AVIOContext *pb = s->pb;
9015  int res = 0;
9016  int i;
9017  int64_t moov_pos;
9018 
9019  /*
9020  * Before actually writing the trailer, make sure that there are no
9021  * dangling subtitles, that need a terminating sample.
9022  */
9023  for (i = 0; i < mov->nb_tracks; i++) {
9024  MOVTrack *trk = &mov->tracks[i];
9025  if (trk->par->codec_id == AV_CODEC_ID_MOV_TEXT &&
9028  trk->last_sample_is_subtitle_end = 1;
9029  }
9030  }
9031 
9032  // Check if we have any tracks that require squashing.
9033  // In that case, we'll have to write the packet here.
9034  if ((res = mov_write_squashed_packets(s)) < 0)
9035  return res;
9036 
9037  // If there were no chapters when the header was written, but there
9038  // are chapters now, write them in the trailer. This only works
9039  // when we are not doing fragments.
9040  if (!mov->chapter_track && !(mov->flags & FF_MOV_FLAG_FRAGMENT)) {
9041  if (mov->mode & (MODE_MP4|MODE_MOV|MODE_IPOD) && s->nb_chapters) {
9042  mov->chapter_track = mov->nb_tracks++;
9043  if ((res = mov_create_chapter_track(s, mov->chapter_track)) < 0)
9044  return res;
9045  }
9046  }
9047 
9048  if (!(mov->flags & FF_MOV_FLAG_FRAGMENT) ||
9050  if (mov->flags & FF_MOV_FLAG_HYBRID_FRAGMENTED) {
9052  mov->mdat_size = avio_tell(pb) - mov->mdat_pos - 8;
9053  for (i = 0; i < mov->nb_tracks; i++) {
9054  MOVTrack *track = &mov->tracks[i];
9055  track->data_offset = 0;
9056  av_free(track->cluster);
9057  track->cluster = track->cluster_written;
9058  track->entry = track->entry_written;
9059  track->cluster_written = NULL;
9060  track->entry_written = 0;
9061  track->chunkCount = 0; // Force build_chunks to rebuild the list of chunks
9062  }
9063  // Clear the empty_moov flag, as we do want the moov to include
9064  // all the samples at this point.
9065  mov->flags &= ~FF_MOV_FLAG_EMPTY_MOOV;
9066  }
9067 
9068  moov_pos = avio_tell(pb);
9069 
9070  if (!(mov->flags & FF_MOV_FLAG_HYBRID_FRAGMENTED))
9072 
9073  avio_seek(pb, mov->reserved_moov_size > 0 ? mov->reserved_header_pos : moov_pos, SEEK_SET);
9074 
9075  if (mov->flags & FF_MOV_FLAG_FASTSTART) {
9076  av_log(s, AV_LOG_INFO, "Starting second pass: moving the moov atom to the beginning of the file\n");
9077  res = shift_data(s);
9078  if (res < 0)
9079  return res;
9080  avio_seek(pb, mov->reserved_header_pos, SEEK_SET);
9081  if ((res = mov_write_moov_tag(pb, mov, s)) < 0)
9082  return res;
9083  } else if (mov->reserved_moov_size > 0) {
9084  int64_t size;
9085  if ((res = mov_write_moov_tag(pb, mov, s)) < 0)
9086  return res;
9087  size = mov->reserved_moov_size - (avio_tell(pb) - mov->reserved_header_pos);
9088  if (size < 8){
9089  av_log(s, AV_LOG_ERROR, "reserved_moov_size is too small, needed %"PRId64" additional\n", 8-size);
9090  return AVERROR(EINVAL);
9091  }
9092  avio_wb32(pb, size);
9093  ffio_wfourcc(pb, "free");
9094  ffio_fill(pb, 0, size - 8);
9095  avio_seek(pb, moov_pos, SEEK_SET);
9096  } else {
9097  if ((res = mov_write_moov_tag(pb, mov, s)) < 0)
9098  return res;
9099  }
9100 
9101  if (mov->flags & FF_MOV_FLAG_HYBRID_FRAGMENTED) {
9102  // With hybrid fragmentation, only write the mdat size (hiding
9103  // the original moov and all the fragments within the mdat)
9104  // after we've successfully written the complete moov, to avoid
9105  // risk for an unreadable file if writing the final moov fails.
9107  }
9108 
9109  res = 0;
9110  } else {
9112  for (i = 0; i < mov->nb_tracks; i++)
9113  mov->tracks[i].data_offset = 0;
9114  if (mov->flags & FF_MOV_FLAG_GLOBAL_SIDX) {
9115  int64_t end;
9116  av_log(s, AV_LOG_INFO, "Starting second pass: inserting sidx atoms\n");
9117  res = shift_data(s);
9118  if (res < 0)
9119  return res;
9120  end = avio_tell(pb);
9121  avio_seek(pb, mov->reserved_header_pos, SEEK_SET);
9122  mov_write_sidx_tags(pb, mov, -1, 0);
9123  avio_seek(pb, end, SEEK_SET);
9124  }
9125  if (!(mov->flags & FF_MOV_FLAG_SKIP_TRAILER)) {
9127  res = mov_write_mfra_tag(pb, mov);
9128  if (res < 0)
9129  return res;
9130  }
9131  }
9132 
9133  return res;
9134 }
9135 
9137  const AVPacket *pkt)
9138 {
9139  int ret = 1;
9140 
9141  if (st->codecpar->codec_id == AV_CODEC_ID_AAC) {
9142  if (pkt->size > 2 && (AV_RB16(pkt->data) & 0xfff0) == 0xfff0)
9143  ret = ff_stream_add_bitstream_filter(st, "aac_adtstoasc", NULL);
9144  } else if (st->codecpar->codec_id == AV_CODEC_ID_VP9) {
9145  ret = ff_stream_add_bitstream_filter(st, "vp9_superframe", NULL);
9146  }
9147 
9148  return ret;
9149 }
9150 
9151 #if CONFIG_AVIF_MUXER
9152 static int avif_write_trailer(AVFormatContext *s)
9153 {
9154  AVIOContext *pb = s->pb;
9155  MOVMuxContext *mov = s->priv_data;
9156  int64_t pos_backup, extent_offsets[2];
9157  uint8_t *buf;
9158  int buf_size, moov_size;
9159 
9160  if (mov->moov_written) return 0;
9161 
9162  mov->is_animated_avif = s->streams[0]->nb_frames > 1;
9163  if (mov->is_animated_avif && mov->nb_streams > 1) {
9164  // For animated avif with alpha channel, we need to write a tref tag
9165  // with type "auxl".
9166  MovTag *tag = mov_add_tref_tag(mov, &mov->tracks[1], MKTAG('a', 'u', 'x', 'l'));
9167  if (!tag)
9168  return AVERROR(ENOMEM);
9169 
9170  int ret = mov_add_tref_id(mov, tag, 1);
9171  if (ret < 0)
9172  return ret;
9173  }
9175  mov_write_meta_tag(pb, mov, s);
9176 
9177  moov_size = get_moov_size(s);
9178  for (int i = 0; i < mov->nb_tracks; i++)
9179  mov->tracks[i].data_offset = avio_tell(pb) + moov_size + 8;
9180 
9181  if (mov->is_animated_avif) {
9182  int ret;
9183  if ((ret = mov_write_moov_tag(pb, mov, s)) < 0)
9184  return ret;
9185  }
9186 
9187  buf_size = avio_get_dyn_buf(mov->mdat_buf, &buf);
9188  avio_wb32(pb, buf_size + 8);
9189  ffio_wfourcc(pb, "mdat");
9190 
9191  // The offset for the YUV planes is the starting position of mdat.
9192  extent_offsets[0] = avio_tell(pb);
9193  // The offset for alpha plane is YUV offset + YUV size.
9194  extent_offsets[1] = extent_offsets[0] + mov->avif_extent_length[0];
9195 
9196  avio_write(pb, buf, buf_size);
9197 
9198  // write extent offsets.
9199  pos_backup = avio_tell(pb);
9200  for (int i = 0; i < mov->nb_streams; i++) {
9201  if (extent_offsets[i] != (uint32_t)extent_offsets[i]) {
9202  av_log(s, AV_LOG_ERROR, "extent offset does not fit in 32 bits\n");
9203  return AVERROR_INVALIDDATA;
9204  }
9205  avio_seek(pb, mov->avif_extent_pos[i], SEEK_SET);
9206  avio_wb32(pb, extent_offsets[i]); /* rewrite offset */
9207  }
9208  avio_seek(pb, pos_backup, SEEK_SET);
9209 
9210  return 0;
9211 }
9212 #endif
9213 
9214 #if CONFIG_TGP_MUXER || CONFIG_TG2_MUXER
9215 static const AVCodecTag codec_3gp_tags[] = {
9216  { AV_CODEC_ID_H263, MKTAG('s','2','6','3') },
9217  { AV_CODEC_ID_H264, MKTAG('a','v','c','1') },
9218  { AV_CODEC_ID_MPEG4, MKTAG('m','p','4','v') },
9219  { AV_CODEC_ID_AAC, MKTAG('m','p','4','a') },
9220  { AV_CODEC_ID_AMR_NB, MKTAG('s','a','m','r') },
9221  { AV_CODEC_ID_AMR_WB, MKTAG('s','a','w','b') },
9222  { AV_CODEC_ID_MOV_TEXT, MKTAG('t','x','3','g') },
9223  { AV_CODEC_ID_NONE, 0 },
9224 };
9225 static const AVCodecTag *const codec_3gp_tags_list[] = { codec_3gp_tags, NULL };
9226 #endif
9227 
9228 static const AVCodecTag codec_mp4_tags[] = {
9229  { AV_CODEC_ID_MPEG4, MKTAG('m', 'p', '4', 'v') },
9230  { AV_CODEC_ID_H264, MKTAG('a', 'v', 'c', '1') },
9231  { AV_CODEC_ID_H264, MKTAG('a', 'v', 'c', '3') },
9232  { AV_CODEC_ID_HEVC, MKTAG('h', 'e', 'v', '1') },
9233  { AV_CODEC_ID_HEVC, MKTAG('h', 'v', 'c', '1') },
9234  { AV_CODEC_ID_HEVC, MKTAG('d', 'v', 'h', '1') },
9235  { AV_CODEC_ID_VVC, MKTAG('v', 'v', 'c', '1') },
9236  { AV_CODEC_ID_VVC, MKTAG('v', 'v', 'i', '1') },
9237  { AV_CODEC_ID_EVC, MKTAG('e', 'v', 'c', '1') },
9238  { AV_CODEC_ID_LCEVC, MKTAG('l', 'v', 'c', '1') },
9239  { AV_CODEC_ID_APV, MKTAG('a', 'p', 'v', '1') },
9240  { AV_CODEC_ID_MPEG2VIDEO, MKTAG('m', 'p', '4', 'v') },
9241  { AV_CODEC_ID_MPEG1VIDEO, MKTAG('m', 'p', '4', 'v') },
9242  { AV_CODEC_ID_MJPEG, MKTAG('m', 'p', '4', 'v') },
9243  { AV_CODEC_ID_PNG, MKTAG('m', 'p', '4', 'v') },
9244  { AV_CODEC_ID_JPEG2000, MKTAG('m', 'p', '4', 'v') },
9245  { AV_CODEC_ID_VC1, MKTAG('v', 'c', '-', '1') },
9246  { AV_CODEC_ID_DIRAC, MKTAG('d', 'r', 'a', 'c') },
9247  { AV_CODEC_ID_TSCC2, MKTAG('m', 'p', '4', 'v') },
9248  { AV_CODEC_ID_VP9, MKTAG('v', 'p', '0', '9') },
9249  { AV_CODEC_ID_AV1, MKTAG('a', 'v', '0', '1') },
9250  { AV_CODEC_ID_AAC, MKTAG('m', 'p', '4', 'a') },
9251  { AV_CODEC_ID_ALAC, MKTAG('a', 'l', 'a', 'c') },
9252  { AV_CODEC_ID_MP4ALS, MKTAG('m', 'p', '4', 'a') },
9253  { AV_CODEC_ID_MP3, MKTAG('m', 'p', '4', 'a') },
9254  { AV_CODEC_ID_MP2, MKTAG('m', 'p', '4', 'a') },
9255  { AV_CODEC_ID_AC3, MKTAG('a', 'c', '-', '3') },
9256  { AV_CODEC_ID_EAC3, MKTAG('e', 'c', '-', '3') },
9257  { AV_CODEC_ID_DTS, MKTAG('m', 'p', '4', 'a') },
9258  { AV_CODEC_ID_TRUEHD, MKTAG('m', 'l', 'p', 'a') },
9259  { AV_CODEC_ID_FLAC, MKTAG('f', 'L', 'a', 'C') },
9260  { AV_CODEC_ID_OPUS, MKTAG('O', 'p', 'u', 's') },
9261  { AV_CODEC_ID_VORBIS, MKTAG('m', 'p', '4', 'a') },
9262  { AV_CODEC_ID_QCELP, MKTAG('m', 'p', '4', 'a') },
9263  { AV_CODEC_ID_EVRC, MKTAG('m', 'p', '4', 'a') },
9264  { AV_CODEC_ID_DVD_SUBTITLE, MKTAG('m', 'p', '4', 's') },
9265  { AV_CODEC_ID_MOV_TEXT, MKTAG('t', 'x', '3', 'g') },
9266  { AV_CODEC_ID_BIN_DATA, MKTAG('g', 'p', 'm', 'd') },
9267  { AV_CODEC_ID_MPEGH_3D_AUDIO, MKTAG('m', 'h', 'm', '1') },
9270  { AV_CODEC_ID_FFV1, MKTAG('F', 'F', 'V', '1') },
9271 
9272  /* ISO/IEC 23003-5 integer formats */
9279  /* ISO/IEC 23003-5 floating-point formats */
9284 
9285  { AV_CODEC_ID_AVS3, MKTAG('a', 'v', 's', '3') },
9286 
9287  { AV_CODEC_ID_NONE, 0 },
9288 };
9289 #if CONFIG_MP4_MUXER || CONFIG_PSP_MUXER
9290 static const AVCodecTag *const mp4_codec_tags_list[] = { codec_mp4_tags, NULL };
9291 #endif
9292 
9293 static const AVCodecTag codec_ism_tags[] = {
9294  { AV_CODEC_ID_WMAPRO , MKTAG('w', 'm', 'a', ' ') },
9296  { AV_CODEC_ID_NONE , 0 },
9297 };
9298 
9299 static const AVCodecTag codec_ipod_tags[] = {
9300  { AV_CODEC_ID_H264, MKTAG('a','v','c','1') },
9301  { AV_CODEC_ID_MPEG4, MKTAG('m','p','4','v') },
9302  { AV_CODEC_ID_AAC, MKTAG('m','p','4','a') },
9303  { AV_CODEC_ID_ALAC, MKTAG('a','l','a','c') },
9304  { AV_CODEC_ID_AC3, MKTAG('a','c','-','3') },
9305  { AV_CODEC_ID_MOV_TEXT, MKTAG('t','x','3','g') },
9306  { AV_CODEC_ID_MOV_TEXT, MKTAG('t','e','x','t') },
9307  { AV_CODEC_ID_NONE, 0 },
9308 };
9309 
9310 static const AVCodecTag codec_f4v_tags[] = {
9311  { AV_CODEC_ID_MP3, MKTAG('.','m','p','3') },
9312  { AV_CODEC_ID_AAC, MKTAG('m','p','4','a') },
9313  { AV_CODEC_ID_H264, MKTAG('a','v','c','1') },
9314  { AV_CODEC_ID_VP6A, MKTAG('V','P','6','A') },
9315  { AV_CODEC_ID_VP6F, MKTAG('V','P','6','F') },
9316  { AV_CODEC_ID_NONE, 0 },
9317 };
9318 
9319 #if CONFIG_AVIF_MUXER
9320 
9321 static const AVOption avif_options[] = {
9322  { "movie_timescale", "set movie timescale", offsetof(MOVMuxContext, movie_timescale), AV_OPT_TYPE_INT, {.i64 = MOV_TIMESCALE}, 1, INT_MAX, AV_OPT_FLAG_ENCODING_PARAM},
9323  { "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 },
9324  { NULL },
9325 };
9326 static const AVCodecTag codec_avif_tags[] = {
9327  { AV_CODEC_ID_AV1, MKTAG('a','v','0','1') },
9328  { AV_CODEC_ID_NONE, 0 },
9329 };
9330 static const AVCodecTag *const codec_avif_tags_list[] = { codec_avif_tags, NULL };
9331 
9332 static const AVClass mov_avif_muxer_class = {
9333  .class_name = "avif muxer",
9334  .item_name = av_default_item_name,
9335  .option = avif_options,
9336  .version = LIBAVUTIL_VERSION_INT,
9337 };
9338 #endif
9339 
9340 #if CONFIG_MOV_MUXER
9341 const FFOutputFormat ff_mov_muxer = {
9342  .p.name = "mov",
9343  .p.long_name = NULL_IF_CONFIG_SMALL("QuickTime / MOV"),
9344  .p.extensions = "mov",
9345  .priv_data_size = sizeof(MOVMuxContext),
9346  .p.audio_codec = AV_CODEC_ID_AAC,
9347  .p.video_codec = CONFIG_LIBX264_ENCODER ?
9349  .init = mov_init,
9350  .write_header = mov_write_header,
9351  .write_packet = mov_write_packet,
9352  .write_trailer = mov_write_trailer,
9353  .deinit = mov_free,
9355  .p.codec_tag = (const AVCodecTag* const []){
9357  },
9358  .check_bitstream = mov_check_bitstream,
9359  .p.priv_class = &mov_isobmff_muxer_class,
9360  .flags_internal = FF_OFMT_FLAG_ALLOW_FLUSH,
9361 };
9362 #endif
9363 #if CONFIG_TGP_MUXER
9364 const FFOutputFormat ff_tgp_muxer = {
9365  .p.name = "3gp",
9366  .p.long_name = NULL_IF_CONFIG_SMALL("3GP (3GPP file format)"),
9367  .p.extensions = "3gp",
9368  .priv_data_size = sizeof(MOVMuxContext),
9369  .p.audio_codec = AV_CODEC_ID_AMR_NB,
9370  .p.video_codec = AV_CODEC_ID_H263,
9371  .init = mov_init,
9372  .write_header = mov_write_header,
9373  .write_packet = mov_write_packet,
9374  .write_trailer = mov_write_trailer,
9375  .deinit = mov_free,
9377  .p.codec_tag = codec_3gp_tags_list,
9378  .check_bitstream = mov_check_bitstream,
9379  .p.priv_class = &mov_isobmff_muxer_class,
9380  .flags_internal = FF_OFMT_FLAG_ALLOW_FLUSH,
9381 };
9382 #endif
9383 #if CONFIG_MP4_MUXER
9384 const FFOutputFormat ff_mp4_muxer = {
9385  .p.name = "mp4",
9386  .p.long_name = NULL_IF_CONFIG_SMALL("MP4 (MPEG-4 Part 14)"),
9387  .p.mime_type = "video/mp4",
9388  .p.extensions = "mp4",
9389  .priv_data_size = sizeof(MOVMuxContext),
9390  .p.audio_codec = AV_CODEC_ID_AAC,
9391  .p.video_codec = CONFIG_LIBX264_ENCODER ?
9393  .init = mov_init,
9394  .write_header = mov_write_header,
9395  .write_packet = mov_write_packet,
9396  .write_trailer = mov_write_trailer,
9397  .deinit = mov_free,
9399  .p.codec_tag = mp4_codec_tags_list,
9400  .check_bitstream = mov_check_bitstream,
9401  .p.priv_class = &mov_isobmff_muxer_class,
9402  .flags_internal = FF_OFMT_FLAG_ALLOW_FLUSH,
9403 };
9404 #endif
9405 #if CONFIG_PSP_MUXER
9406 const FFOutputFormat ff_psp_muxer = {
9407  .p.name = "psp",
9408  .p.long_name = NULL_IF_CONFIG_SMALL("PSP MP4 (MPEG-4 Part 14)"),
9409  .p.extensions = "mp4,psp",
9410  .priv_data_size = sizeof(MOVMuxContext),
9411  .p.audio_codec = AV_CODEC_ID_AAC,
9412  .p.video_codec = CONFIG_LIBX264_ENCODER ?
9414  .init = mov_init,
9415  .write_header = mov_write_header,
9416  .write_packet = mov_write_packet,
9417  .write_trailer = mov_write_trailer,
9418  .deinit = mov_free,
9420  .p.codec_tag = mp4_codec_tags_list,
9421  .check_bitstream = mov_check_bitstream,
9422  .p.priv_class = &mov_isobmff_muxer_class,
9423  .flags_internal = FF_OFMT_FLAG_ALLOW_FLUSH,
9424 };
9425 #endif
9426 #if CONFIG_TG2_MUXER
9427 const FFOutputFormat ff_tg2_muxer = {
9428  .p.name = "3g2",
9429  .p.long_name = NULL_IF_CONFIG_SMALL("3GP2 (3GPP2 file format)"),
9430  .p.extensions = "3g2",
9431  .priv_data_size = sizeof(MOVMuxContext),
9432  .p.audio_codec = AV_CODEC_ID_AMR_NB,
9433  .p.video_codec = AV_CODEC_ID_H263,
9434  .init = mov_init,
9435  .write_header = mov_write_header,
9436  .write_packet = mov_write_packet,
9437  .write_trailer = mov_write_trailer,
9438  .deinit = mov_free,
9440  .p.codec_tag = codec_3gp_tags_list,
9441  .check_bitstream = mov_check_bitstream,
9442  .p.priv_class = &mov_isobmff_muxer_class,
9443  .flags_internal = FF_OFMT_FLAG_ALLOW_FLUSH,
9444 };
9445 #endif
9446 #if CONFIG_IPOD_MUXER
9447 const FFOutputFormat ff_ipod_muxer = {
9448  .p.name = "ipod",
9449  .p.long_name = NULL_IF_CONFIG_SMALL("iPod H.264 MP4 (MPEG-4 Part 14)"),
9450  .p.mime_type = "video/mp4",
9451  .p.extensions = "m4v,m4a,m4b",
9452  .priv_data_size = sizeof(MOVMuxContext),
9453  .p.audio_codec = AV_CODEC_ID_AAC,
9454  .p.video_codec = AV_CODEC_ID_H264,
9455  .init = mov_init,
9456  .write_header = mov_write_header,
9457  .write_packet = mov_write_packet,
9458  .write_trailer = mov_write_trailer,
9459  .deinit = mov_free,
9461  .p.codec_tag = (const AVCodecTag* const []){ codec_ipod_tags, 0 },
9462  .check_bitstream = mov_check_bitstream,
9463  .p.priv_class = &mov_isobmff_muxer_class,
9464  .flags_internal = FF_OFMT_FLAG_ALLOW_FLUSH,
9465 };
9466 #endif
9467 #if CONFIG_ISMV_MUXER
9468 const FFOutputFormat ff_ismv_muxer = {
9469  .p.name = "ismv",
9470  .p.long_name = NULL_IF_CONFIG_SMALL("ISMV/ISMA (Smooth Streaming)"),
9471  .p.mime_type = "video/mp4",
9472  .p.extensions = "ismv,isma",
9473  .priv_data_size = sizeof(MOVMuxContext),
9474  .p.audio_codec = AV_CODEC_ID_AAC,
9475  .p.video_codec = AV_CODEC_ID_H264,
9476  .init = mov_init,
9477  .write_header = mov_write_header,
9478  .write_packet = mov_write_packet,
9479  .write_trailer = mov_write_trailer,
9480  .deinit = mov_free,
9482  .p.codec_tag = (const AVCodecTag* const []){
9484  .check_bitstream = mov_check_bitstream,
9485  .p.priv_class = &mov_isobmff_muxer_class,
9486  .flags_internal = FF_OFMT_FLAG_ALLOW_FLUSH,
9487 };
9488 #endif
9489 #if CONFIG_F4V_MUXER
9490 const FFOutputFormat ff_f4v_muxer = {
9491  .p.name = "f4v",
9492  .p.long_name = NULL_IF_CONFIG_SMALL("F4V Adobe Flash Video"),
9493  .p.mime_type = "application/f4v",
9494  .p.extensions = "f4v",
9495  .priv_data_size = sizeof(MOVMuxContext),
9496  .p.audio_codec = AV_CODEC_ID_AAC,
9497  .p.video_codec = AV_CODEC_ID_H264,
9498  .init = mov_init,
9499  .write_header = mov_write_header,
9500  .write_packet = mov_write_packet,
9501  .write_trailer = mov_write_trailer,
9502  .deinit = mov_free,
9503  .p.flags = AVFMT_GLOBALHEADER,
9504  .p.codec_tag = (const AVCodecTag* const []){ codec_f4v_tags, 0 },
9505  .check_bitstream = mov_check_bitstream,
9506  .p.priv_class = &mov_isobmff_muxer_class,
9507  .flags_internal = FF_OFMT_FLAG_ALLOW_FLUSH,
9508 };
9509 #endif
9510 #if CONFIG_AVIF_MUXER
9511 const FFOutputFormat ff_avif_muxer = {
9512  .p.name = "avif",
9513  .p.long_name = NULL_IF_CONFIG_SMALL("AVIF"),
9514  .p.mime_type = "image/avif",
9515  .p.extensions = "avif",
9516  .priv_data_size = sizeof(MOVMuxContext),
9517  .p.video_codec = AV_CODEC_ID_AV1,
9518  .init = mov_init,
9519  .write_header = mov_write_header,
9520  .write_packet = mov_write_packet,
9521  .write_trailer = avif_write_trailer,
9522  .deinit = mov_free,
9523  .p.flags = AVFMT_GLOBALHEADER,
9524  .p.codec_tag = codec_avif_tags_list,
9525  .p.priv_class = &mov_avif_muxer_class,
9526  .flags_internal = FF_OFMT_FLAG_ALLOW_FLUSH,
9527 };
9528 #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:9293
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:5866
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:4274
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:3902
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:5337
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:3548
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:4614
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:4336
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:6140
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:5064
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:5801
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:5016
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:7386
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:5676
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:4498
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:5604
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:4356
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:3856
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:6881
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:4445
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:3988
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:8127
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:7881
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:4881
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:4978
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
ff_isom_write_lvcc
int ff_isom_write_lvcc(AVIOContext *pb, const uint8_t *data, int len)
Definition: lcevc.c:251
MOV_TIMESCALE
#define MOV_TIMESCALE
Definition: movenc.h:33
co64_required
static int co64_required(const MOVTrack *track)
Definition: movenc.c:177
mov_write_aux_tag
static int mov_write_aux_tag(AVIOContext *pb, const char *aux_type)
Definition: movenc.c: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:4563
mov_write_header
static int mov_write_header(AVFormatContext *s)
Definition: movenc.c:8723
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:4708
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:8916
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:3557
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:4998
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:5854
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:5285
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:4474
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:3881
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:4668
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:4487
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:3918
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:6230
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_write_lvcc_tag
static int mov_write_lvcc_tag(AVIOContext *pb, MOVTrack *track)
Definition: movenc.c:1693
mov_setup_track_ids
static int mov_setup_track_ids(MOVMuxContext *mov, AVFormatContext *s)
Assign track ids.
Definition: movenc.c:5246
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:6639
mov_write_iref_tag
static int mov_write_iref_tag(AVIOContext *pb, MOVMuxContext *mov, AVFormatContext *s)
Definition: movenc.c:3706
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:5173
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:458
AVRational::num
int num
Numerator.
Definition: rational.h:59
AV_CH_LAYOUT_STEREO
#define AV_CH_LAYOUT_STEREO
Definition: channel_layout.h:218
vpcc.h
MOV_CH_LAYOUT_MONO
@ MOV_CH_LAYOUT_MONO
Definition: mov_chan.h:56
mov_get_dv_codec_tag
static int mov_get_dv_codec_tag(AVFormatContext *s, MOVTrack *track)
Definition: movenc.c: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:5840
av_get_bits_per_sample
int av_get_bits_per_sample(enum AVCodecID codec_id)
Return codec bits per sample.
Definition: utils.c:541
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:4690
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:4389
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:9011
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:7546
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:5038
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
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:6116
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:4759
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:3753
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:3658
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:6452
mov_write_tcmi_tag
static int mov_write_tcmi_tag(AVIOContext *pb, MOVTrack *track)
Definition: movenc.c:3464
build_chunks
static void build_chunks(MOVTrack *trk)
Definition: movenc.c:5210
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:4131
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:3563
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:5595
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:5122
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:8934
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:3648
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:7816
codec_f4v_tags
static const AVCodecTag codec_f4v_tags[]
Definition: movenc.c:9310
mov_create_timecode_track
static int mov_create_timecode_track(AVFormatContext *s, int index, int src_index, AVTimecode tc)
Definition: movenc.c:7825
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:7574
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:8903
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:1249
rtp_hinting_needed
static int rtp_hinting_needed(const AVStream *st)
Definition: movenc.c:191
mov_get_apv_codec_tag
static int mov_get_apv_codec_tag(AVFormatContext *s, MOVTrack *track)
Definition: movenc.c:2041
check_pkt
static int check_pkt(AVFormatContext *s, MOVTrack *trk, AVPacket *pkt)
Definition: movenc.c:6895
VC1_CODE_SEQHDR
@ VC1_CODE_SEQHDR
Definition: vc1_common.h:40
ff_isom_write_hvcc
int ff_isom_write_hvcc(AVIOContext *pb, const uint8_t *data, int size, int ps_array_completeness, void *logctx)
Writes HEVC extradata (parameter sets and declarative SEI NAL units with nuh_layer_id == 0,...
Definition: hevc.c:1398
ffio_close_null_buf
int ffio_close_null_buf(AVIOContext *s)
Close a null buffer.
Definition: aviobuf.c:1472
AV_PIX_FMT_MONOBLACK
@ AV_PIX_FMT_MONOBLACK
Y , 1bpp, 0 is black, 1 is white, in each byte pixels are ordered from the msb to the lsb.
Definition: pixfmt.h:83
mov_write_squashed_packets
static int mov_write_squashed_packets(AVFormatContext *s)
Definition: movenc.c:6615
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:5908
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:5320
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:4296
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:3448
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:3819
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:5453
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:4579
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:5471
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:7477
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:3400
cid
uint16_t cid
Definition: mxfenc.c:2335
compute_sidx_size
static int compute_sidx_size(AVFormatContext *s)
Definition: movenc.c:8959
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:446
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:9299
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:4896
avio.h
mov_write_uuid_tag_psp
static int mov_write_uuid_tag_psp(AVIOContext *pb, MOVTrack *mov)
Definition: movenc.c:4256
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:9228
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:4643
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:3974
mov_create_dvd_sub_decoder_specific_info
static int mov_create_dvd_sub_decoder_specific_info(MOVTrack *track, AVStream *st)
Definition: movenc.c:7998
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:3486
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:3893
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:4310
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:4925
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:4947
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:8974
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:3681
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:7923
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:4813
avcodec_get_name
const char * avcodec_get_name(enum AVCodecID id)
Get the name of a codec.
Definition: utils.c:406
AV_CODEC_ID_MJPEG
@ AV_CODEC_ID_MJPEG
Definition: codec_id.h: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:3794
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:6352
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:3439
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:6930
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
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:4600
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:71
eac3_info::data_rate
uint16_t data_rate
Definition: movenc.c:390
avpriv_ac3_parse_header
int avpriv_ac3_parse_header(AC3HeaderInfo **phdr, const uint8_t *buf, size_t size)
Definition: ac3_parser.c:491
AV_CODEC_ID_PCM_F64BE
@ AV_CODEC_ID_PCM_F64BE
Definition: codec_id.h:352
mov_write_mdat_size
static void mov_write_mdat_size(AVFormatContext *s)
Definition: movenc.c:8989
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:6533
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:5309
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:4096
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:9136
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:5610
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:6082
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:4786
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:3737
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:4239
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:578
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:6671
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:3456
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:7982
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:7725
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:4679
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:6189
mov_write_prft_tag
static int mov_write_prft_tag(AVIOContext *pb, MOVMuxContext *mov, int tracks)
Definition: movenc.c:6032
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:6423
mov_write_sidx_tags
static int mov_write_sidx_tags(AVIOContext *pb, MOVMuxContext *mov, int tracks, int ref_size)
Definition: movenc.c:5994
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:4840
mov_flush_fragment_interleaving
static int mov_flush_fragment_interleaving(AVFormatContext *s, MOVTrack *track)
Definition: movenc.c:6552
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:3909
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:3955
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:3725
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:5463
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:5135
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:5009
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:3770
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:3538
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:6473
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:6577
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:3804
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:5458
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:1405
AVERROR_INVALIDDATA
#define AVERROR_INVALIDDATA
Invalid data found when processing input.
Definition: error.h:61
ff_mov_track_kind_table
const struct MP4TrackKindMapping ff_mov_track_kind_table[]
Definition: isom.c: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:6178
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:5752
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:5294
mov_write_tfrf_tags
static int mov_write_tfrf_tags(AVIOContext *pb, MOVMuxContext *mov, MOVTrack *track)
Definition: movenc.c:5787
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:5732
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:1201
AV_RB16
uint64_t_TMPL AV_WL64 unsigned int_TMPL AV_WL32 unsigned int_TMPL AV_WL24 unsigned int_TMPL AV_WL16 uint64_t_TMPL AV_WB64 unsigned int_TMPL AV_WB32 unsigned int_TMPL AV_WB24 unsigned int_TMPL AV_RB16
Definition: bytestream.h:98
MOVTrack::nb_frag_info
int nb_frag_info
Definition: movenc.h: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:5933
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