FFmpeg
movenc.c
Go to the documentation of this file.
1 /*
2  * MOV, 3GP, MP4 muxer
3  * Copyright (c) 2003 Thomas Raivio
4  * Copyright (c) 2004 Gildas Bazin <gbazin at videolan dot org>
5  * Copyright (c) 2009 Baptiste Coudurier <baptiste dot coudurier at gmail dot com>
6  *
7  * This file is part of FFmpeg.
8  *
9  * FFmpeg is free software; you can redistribute it and/or
10  * modify it under the terms of the GNU Lesser General Public
11  * License as published by the Free Software Foundation; either
12  * version 2.1 of the License, or (at your option) any later version.
13  *
14  * FFmpeg is distributed in the hope that it will be useful,
15  * but WITHOUT ANY WARRANTY; without even the implied warranty of
16  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
17  * Lesser General Public License for more details.
18  *
19  * You should have received a copy of the GNU Lesser General Public
20  * License along with FFmpeg; if not, write to the Free Software
21  * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
22  */
23 
24 #include "config_components.h"
25 
26 #include <stdint.h>
27 #include <inttypes.h>
28 
29 #include "movenc.h"
30 #include "avformat.h"
31 #include "avio_internal.h"
32 #include "dovi_isom.h"
33 #include "riff.h"
34 #include "avio.h"
35 #include "iamf_writer.h"
36 #include "isom.h"
37 #include "av1.h"
38 #include "avc.h"
39 #include "evc.h"
40 #include "apv.h"
41 #include "lcevc.h"
43 #include "libavcodec/dnxhddata.h"
44 #include "libavcodec/flac.h"
45 #include "libavcodec/get_bits.h"
46 
47 #include "libavcodec/internal.h"
48 #include "libavcodec/put_bits.h"
49 #include "libavcodec/vc1_common.h"
50 #include "libavcodec/raw.h"
51 #include "internal.h"
52 #include "libavutil/avstring.h"
54 #include "libavutil/csp.h"
55 #include "libavutil/intfloat.h"
56 #include "libavutil/mathematics.h"
57 #include "libavutil/libm.h"
58 #include "libavutil/mem.h"
59 #include "libavutil/opt.h"
60 #include "libavutil/dict.h"
61 #include "libavutil/pixdesc.h"
62 #include "libavutil/stereo3d.h"
63 #include "libavutil/timecode.h"
64 #include "libavutil/dovi_meta.h"
65 #include "libavutil/uuid.h"
66 #include "hevc.h"
67 #include "rtpenc.h"
68 #include "nal.h"
69 #include "mov_chan.h"
70 #include "movenc_ttml.h"
71 #include "mux.h"
72 #include "rawutils.h"
73 #include "ttmlenc.h"
74 #include "version.h"
75 #include "vpcc.h"
76 #include "vvc.h"
77 
78 static const AVOption options[] = {
79  { "brand", "Override major brand", offsetof(MOVMuxContext, major_brand), AV_OPT_TYPE_STRING, {.str = NULL}, .flags = AV_OPT_FLAG_ENCODING_PARAM },
80  { "empty_hdlr_name", "write zero-length name string in hdlr atoms within mdia and minf atoms", offsetof(MOVMuxContext, empty_hdlr_name), AV_OPT_TYPE_BOOL, {.i64 = 0}, 0, 1, AV_OPT_FLAG_ENCODING_PARAM},
81  { "encryption_key", "The media encryption key (hex)", offsetof(MOVMuxContext, encryption_key), AV_OPT_TYPE_BINARY, .flags = AV_OPT_FLAG_ENCODING_PARAM },
82  { "encryption_kid", "The media encryption key identifier (hex)", offsetof(MOVMuxContext, encryption_kid), AV_OPT_TYPE_BINARY, .flags = AV_OPT_FLAG_ENCODING_PARAM },
83  { "encryption_scheme", "Configures the encryption scheme, allowed values are none, cenc-aes-ctr", offsetof(MOVMuxContext, encryption_scheme_str), AV_OPT_TYPE_STRING, {.str = NULL}, .flags = AV_OPT_FLAG_ENCODING_PARAM },
84  { "frag_duration", "Maximum fragment duration", offsetof(MOVMuxContext, max_fragment_duration), AV_OPT_TYPE_INT, {.i64 = 0}, 0, INT_MAX, AV_OPT_FLAG_ENCODING_PARAM},
85  { "frag_interleave", "Interleave samples within fragments (max number of consecutive samples, lower is tighter interleaving, but with more overhead)", offsetof(MOVMuxContext, frag_interleave), AV_OPT_TYPE_INT, {.i64 = 0}, 0, INT_MAX, AV_OPT_FLAG_ENCODING_PARAM },
86  { "frag_size", "Maximum fragment size", offsetof(MOVMuxContext, max_fragment_size), AV_OPT_TYPE_INT, {.i64 = 0}, 0, INT_MAX, AV_OPT_FLAG_ENCODING_PARAM},
87  { "fragment_index", "Fragment number of the next fragment", offsetof(MOVMuxContext, fragments), AV_OPT_TYPE_INT, {.i64 = 1}, 1, INT_MAX, AV_OPT_FLAG_ENCODING_PARAM},
88  { "iods_audio_profile", "iods audio profile atom.", offsetof(MOVMuxContext, iods_audio_profile), AV_OPT_TYPE_INT, {.i64 = -1}, -1, 255, AV_OPT_FLAG_ENCODING_PARAM},
89  { "iods_video_profile", "iods video profile atom.", offsetof(MOVMuxContext, iods_video_profile), AV_OPT_TYPE_INT, {.i64 = -1}, -1, 255, AV_OPT_FLAG_ENCODING_PARAM},
90  { "ism_lookahead", "Number of lookahead entries for ISM files", offsetof(MOVMuxContext, ism_lookahead), AV_OPT_TYPE_INT, {.i64 = 0}, 0, 255, AV_OPT_FLAG_ENCODING_PARAM},
91  { "movflags", "MOV muxer flags", offsetof(MOVMuxContext, flags), AV_OPT_TYPE_FLAGS, {.i64 = 0}, INT_MIN, INT_MAX, AV_OPT_FLAG_ENCODING_PARAM, .unit = "movflags" },
92  { "cmaf", "Write CMAF compatible fragmented MP4", 0, AV_OPT_TYPE_CONST, {.i64 = FF_MOV_FLAG_CMAF}, INT_MIN, INT_MAX, AV_OPT_FLAG_ENCODING_PARAM, .unit = "movflags" },
93  { "dash", "Write DASH compatible fragmented MP4", 0, AV_OPT_TYPE_CONST, {.i64 = FF_MOV_FLAG_DASH}, INT_MIN, INT_MAX, AV_OPT_FLAG_ENCODING_PARAM, .unit = "movflags" },
94  { "default_base_moof", "Set the default-base-is-moof flag in tfhd atoms", 0, AV_OPT_TYPE_CONST, {.i64 = FF_MOV_FLAG_DEFAULT_BASE_MOOF}, INT_MIN, INT_MAX, AV_OPT_FLAG_ENCODING_PARAM, .unit = "movflags" },
95  { "delay_moov", "Delay writing the initial moov until the first fragment is cut, or until the first fragment flush", 0, AV_OPT_TYPE_CONST, {.i64 = FF_MOV_FLAG_DELAY_MOOV}, INT_MIN, INT_MAX, AV_OPT_FLAG_ENCODING_PARAM, .unit = "movflags" },
96  { "disable_chpl", "Disable Nero chapter atom", 0, AV_OPT_TYPE_CONST, {.i64 = FF_MOV_FLAG_DISABLE_CHPL}, INT_MIN, INT_MAX, AV_OPT_FLAG_ENCODING_PARAM, .unit = "movflags" },
97  { "empty_moov", "Make the initial moov atom empty", 0, AV_OPT_TYPE_CONST, {.i64 = FF_MOV_FLAG_EMPTY_MOOV}, INT_MIN, INT_MAX, AV_OPT_FLAG_ENCODING_PARAM, .unit = "movflags" },
98  { "faststart", "Run a second pass to put the index (moov atom) at the beginning of the file", 0, AV_OPT_TYPE_CONST, {.i64 = FF_MOV_FLAG_FASTSTART}, INT_MIN, INT_MAX, AV_OPT_FLAG_ENCODING_PARAM, .unit = "movflags" },
99  { "frag_custom", "Flush fragments on caller requests", 0, AV_OPT_TYPE_CONST, {.i64 = FF_MOV_FLAG_FRAG_CUSTOM}, INT_MIN, INT_MAX, AV_OPT_FLAG_ENCODING_PARAM, .unit = "movflags" },
100  { "frag_discont", "Signal that the next fragment is discontinuous from earlier ones", 0, AV_OPT_TYPE_CONST, {.i64 = FF_MOV_FLAG_FRAG_DISCONT}, INT_MIN, INT_MAX, AV_OPT_FLAG_ENCODING_PARAM, .unit = "movflags" },
101  { "frag_every_frame", "Fragment at every frame", 0, AV_OPT_TYPE_CONST, {.i64 = FF_MOV_FLAG_FRAG_EVERY_FRAME}, INT_MIN, INT_MAX, AV_OPT_FLAG_ENCODING_PARAM, .unit = "movflags" },
102  { "frag_keyframe", "Fragment at video keyframes", 0, AV_OPT_TYPE_CONST, {.i64 = FF_MOV_FLAG_FRAG_KEYFRAME}, INT_MIN, INT_MAX, AV_OPT_FLAG_ENCODING_PARAM, .unit = "movflags" },
103  { "global_sidx", "Write a global sidx index at the start of the file", 0, AV_OPT_TYPE_CONST, {.i64 = FF_MOV_FLAG_GLOBAL_SIDX}, INT_MIN, INT_MAX, AV_OPT_FLAG_ENCODING_PARAM, .unit = "movflags" },
104  { "isml", "Create a live smooth streaming feed (for pushing to a publishing point)", 0, AV_OPT_TYPE_CONST, {.i64 = FF_MOV_FLAG_ISML}, INT_MIN, INT_MAX, AV_OPT_FLAG_ENCODING_PARAM, .unit = "movflags" },
105  { "moov_size", "maximum moov size so it can be placed at the begin", offsetof(MOVMuxContext, reserved_moov_size), AV_OPT_TYPE_INT, {.i64 = 0}, 0, INT_MAX, AV_OPT_FLAG_ENCODING_PARAM, .unit = 0 },
106  { "negative_cts_offsets", "Use negative CTS offsets (reducing the need for edit lists)", 0, AV_OPT_TYPE_CONST, {.i64 = FF_MOV_FLAG_NEGATIVE_CTS_OFFSETS}, INT_MIN, INT_MAX, AV_OPT_FLAG_ENCODING_PARAM, .unit = "movflags" },
107  { "omit_tfhd_offset", "Omit the base data offset in tfhd atoms", 0, AV_OPT_TYPE_CONST, {.i64 = FF_MOV_FLAG_OMIT_TFHD_OFFSET}, INT_MIN, INT_MAX, AV_OPT_FLAG_ENCODING_PARAM, .unit = "movflags" },
108  { "prefer_icc", "If writing colr atom prioritise usage of ICC profile if it exists in stream packet side data", 0, AV_OPT_TYPE_CONST, {.i64 = FF_MOV_FLAG_PREFER_ICC}, INT_MIN, INT_MAX, AV_OPT_FLAG_ENCODING_PARAM, .unit = "movflags" },
109  { "rtphint", "Add RTP hint tracks", 0, AV_OPT_TYPE_CONST, {.i64 = FF_MOV_FLAG_RTP_HINT}, INT_MIN, INT_MAX, AV_OPT_FLAG_ENCODING_PARAM, .unit = "movflags" },
110  { "separate_moof", "Write separate moof/mdat atoms for each track", 0, AV_OPT_TYPE_CONST, {.i64 = FF_MOV_FLAG_SEPARATE_MOOF}, INT_MIN, INT_MAX, AV_OPT_FLAG_ENCODING_PARAM, .unit = "movflags" },
111  { "skip_sidx", "Skip writing of sidx atom", 0, AV_OPT_TYPE_CONST, {.i64 = FF_MOV_FLAG_SKIP_SIDX}, INT_MIN, INT_MAX, AV_OPT_FLAG_ENCODING_PARAM, .unit = "movflags" },
112  { "skip_trailer", "Skip writing the mfra/tfra/mfro trailer for fragmented files", 0, AV_OPT_TYPE_CONST, {.i64 = FF_MOV_FLAG_SKIP_TRAILER}, INT_MIN, INT_MAX, AV_OPT_FLAG_ENCODING_PARAM, .unit = "movflags" },
113  { "use_metadata_tags", "Use mdta atom for metadata.", 0, AV_OPT_TYPE_CONST, {.i64 = FF_MOV_FLAG_USE_MDTA}, INT_MIN, INT_MAX, AV_OPT_FLAG_ENCODING_PARAM, .unit = "movflags" },
114  { "write_colr", "Write colr atom even if the color info is unspecified (Experimental, may be renamed or changed, do not use from scripts)", 0, AV_OPT_TYPE_CONST, {.i64 = FF_MOV_FLAG_WRITE_COLR}, INT_MIN, INT_MAX, AV_OPT_FLAG_ENCODING_PARAM, .unit = "movflags" },
115  { "write_gama", "Write deprecated gama atom", 0, AV_OPT_TYPE_CONST, {.i64 = FF_MOV_FLAG_WRITE_GAMA}, INT_MIN, INT_MAX, AV_OPT_FLAG_ENCODING_PARAM, .unit = "movflags" },
116  { "hybrid_fragmented", "For recoverability, write a fragmented file that is converted to non-fragmented at the end.", 0, AV_OPT_TYPE_CONST, {.i64 = FF_MOV_FLAG_HYBRID_FRAGMENTED}, INT_MIN, INT_MAX, AV_OPT_FLAG_ENCODING_PARAM, .unit = "movflags" },
117  { "min_frag_duration", "Minimum fragment duration", offsetof(MOVMuxContext, min_fragment_duration), AV_OPT_TYPE_INT, {.i64 = 0}, 0, INT_MAX, AV_OPT_FLAG_ENCODING_PARAM},
118  { "mov_gamma", "gamma value for gama atom", offsetof(MOVMuxContext, gamma), AV_OPT_TYPE_FLOAT, {.dbl = 0.0 }, 0.0, 10, AV_OPT_FLAG_ENCODING_PARAM},
119  { "movie_timescale", "set movie timescale", offsetof(MOVMuxContext, movie_timescale), AV_OPT_TYPE_INT, {.i64 = MOV_TIMESCALE}, 1, INT_MAX, AV_OPT_FLAG_ENCODING_PARAM},
120  FF_RTP_FLAG_OPTS(MOVMuxContext, rtp_flags),
121  { "skip_iods", "Skip writing iods atom.", offsetof(MOVMuxContext, iods_skip), AV_OPT_TYPE_BOOL, {.i64 = 1}, 0, 1, AV_OPT_FLAG_ENCODING_PARAM},
122  { "use_editlist", "use edit list", offsetof(MOVMuxContext, use_editlist), AV_OPT_TYPE_BOOL, {.i64 = -1}, -1, 1, AV_OPT_FLAG_ENCODING_PARAM},
123  { "use_stream_ids_as_track_ids", "use stream ids as track ids", offsetof(MOVMuxContext, use_stream_ids_as_track_ids), AV_OPT_TYPE_BOOL, {.i64 = 0}, 0, 1, AV_OPT_FLAG_ENCODING_PARAM},
124  { "video_track_timescale", "set timescale of all video tracks", offsetof(MOVMuxContext, video_track_timescale), AV_OPT_TYPE_INT, {.i64 = 0}, 0, INT_MAX, AV_OPT_FLAG_ENCODING_PARAM},
125  { "write_btrt", "force or disable writing btrt", offsetof(MOVMuxContext, write_btrt), AV_OPT_TYPE_BOOL, {.i64 = -1}, -1, 1, AV_OPT_FLAG_ENCODING_PARAM},
126  { "write_prft", "Write producer reference time box with specified time source", offsetof(MOVMuxContext, write_prft), AV_OPT_TYPE_INT, {.i64 = MOV_PRFT_NONE}, 0, MOV_PRFT_NB-1, AV_OPT_FLAG_ENCODING_PARAM, .unit = "prft"},
127  { "pts", NULL, 0, AV_OPT_TYPE_CONST, {.i64 = MOV_PRFT_SRC_PTS}, 0, 0, AV_OPT_FLAG_ENCODING_PARAM, .unit = "prft"},
128  { "wallclock", NULL, 0, AV_OPT_TYPE_CONST, {.i64 = MOV_PRFT_SRC_WALLCLOCK}, 0, 0, AV_OPT_FLAG_ENCODING_PARAM, .unit = "prft"},
129  { "write_tmcd", "force or disable writing tmcd", offsetof(MOVMuxContext, write_tmcd), AV_OPT_TYPE_BOOL, {.i64 = -1}, -1, 1, AV_OPT_FLAG_ENCODING_PARAM},
130  { NULL },
131 };
132 
134  .class_name = "mov/mp4/tgp/psp/tg2/ipod/ismv/f4v muxer",
135  .item_name = av_default_item_name,
136  .option = options,
137  .version = LIBAVUTIL_VERSION_INT,
138 };
139 
140 static int get_moov_size(AVFormatContext *s);
142 
143 static int utf8len(const uint8_t *b)
144 {
145  int len = 0;
146  int val;
147  while (*b) {
148  GET_UTF8(val, *b++, return -1;)
149  len++;
150  }
151  return len;
152 }
153 
154 //FIXME support 64 bit variant with wide placeholders
156 {
157  int64_t curpos = avio_tell(pb);
158  avio_seek(pb, pos, SEEK_SET);
159  avio_wb32(pb, curpos - pos); /* rewrite size */
160  avio_seek(pb, curpos, SEEK_SET);
161 
162  return curpos - pos;
163 }
164 
166 {
167  int64_t curpos = avio_tell(pb);
168  avio_seek(pb, pos, SEEK_SET);
169  avio_wb32(pb, curpos - pos); /* rewrite size */
170  avio_skip(pb, 4);
171  avio_w8(pb, version); /* rewrite version */
172  avio_seek(pb, curpos, SEEK_SET);
173 
174  return curpos - pos;
175 }
176 
177 static int co64_required(const MOVTrack *track)
178 {
179  if (track->entry > 0 && track->cluster[track->entry - 1].pos + track->data_offset > UINT32_MAX)
180  return 1;
181  return 0;
182 }
183 
184 static int is_cover_image(const AVStream *st)
185 {
186  /* Eg. AV_DISPOSITION_ATTACHED_PIC | AV_DISPOSITION_TIMED_THUMBNAILS
187  * is encoded as sparse video track */
188  return st && st->disposition == AV_DISPOSITION_ATTACHED_PIC;
189 }
190 
191 static int rtp_hinting_needed(const AVStream *st)
192 {
193  /* Add hint tracks for each real audio and video stream */
194  if (is_cover_image(st))
195  return 0;
196  return st->codecpar->codec_type == AVMEDIA_TYPE_VIDEO ||
198 }
199 
200 /* Chunk offset atom */
201 static int mov_write_stco_tag(AVIOContext *pb, MOVTrack *track)
202 {
203  int i;
204  int mode64 = co64_required(track); // use 32 bit size variant if possible
205  int64_t pos = avio_tell(pb);
206  avio_wb32(pb, 0); /* size */
207  if (mode64)
208  ffio_wfourcc(pb, "co64");
209  else
210  ffio_wfourcc(pb, "stco");
211  avio_wb32(pb, 0); /* version & flags */
212  avio_wb32(pb, track->chunkCount); /* entry count */
213  for (i = 0; i < track->entry; i++) {
214  if (!track->cluster[i].chunkNum)
215  continue;
216  if (mode64 == 1)
217  avio_wb64(pb, track->cluster[i].pos + track->data_offset);
218  else
219  avio_wb32(pb, track->cluster[i].pos + track->data_offset);
220  }
221  return update_size(pb, pos);
222 }
223 
224 /* Sample size atom */
225 static int mov_write_stsz_tag(AVIOContext *pb, MOVTrack *track)
226 {
227  int equalChunks = 1;
228  int i, j, entries = 0, tst = -1, oldtst = -1;
229 
230  int64_t pos = avio_tell(pb);
231  avio_wb32(pb, 0); /* size */
232  ffio_wfourcc(pb, "stsz");
233  avio_wb32(pb, 0); /* version & flags */
234 
235  for (i = 0; i < track->entry; i++) {
236  tst = track->cluster[i].size / track->cluster[i].entries;
237  if (oldtst != -1 && tst != oldtst)
238  equalChunks = 0;
239  oldtst = tst;
240  entries += track->cluster[i].entries;
241  }
242  if (equalChunks && track->entry) {
243  int sSize = track->entry ? track->cluster[0].size / track->cluster[0].entries : 0;
244  sSize = FFMAX(1, sSize); // adpcm mono case could make sSize == 0
245  avio_wb32(pb, sSize); // sample size
246  avio_wb32(pb, entries); // sample count
247  } else {
248  avio_wb32(pb, 0); // sample size
249  avio_wb32(pb, entries); // sample count
250  for (i = 0; i < track->entry; i++) {
251  for (j = 0; j < track->cluster[i].entries; j++) {
252  avio_wb32(pb, track->cluster[i].size /
253  track->cluster[i].entries);
254  }
255  }
256  }
257  return update_size(pb, pos);
258 }
259 
260 /* Sample to chunk atom */
261 static int mov_write_stsc_tag(AVIOContext *pb, MOVTrack *track)
262 {
263  int index = 0, oldidx = -1, oldval = -1, i;
264  int64_t entryPos, curpos;
265 
266  int64_t pos = avio_tell(pb);
267  avio_wb32(pb, 0); /* size */
268  ffio_wfourcc(pb, "stsc");
269  avio_wb32(pb, 0); // version & flags
270  entryPos = avio_tell(pb);
271  avio_wb32(pb, track->chunkCount); // entry count
272  for (i = 0; i < track->entry; i++) {
273  if ((oldval != track->cluster[i].samples_in_chunk ||
274  oldidx != track->cluster[i].stsd_index) && track->cluster[i].chunkNum) {
275  avio_wb32(pb, track->cluster[i].chunkNum); // first chunk
276  avio_wb32(pb, track->cluster[i].samples_in_chunk); // samples per chunk
277  avio_wb32(pb, track->cluster[i].stsd_index + 1); // sample description index
278  oldval = track->cluster[i].samples_in_chunk;
279  oldidx = track->cluster[i].stsd_index;
280  index++;
281  }
282  }
283  curpos = avio_tell(pb);
284  avio_seek(pb, entryPos, SEEK_SET);
285  avio_wb32(pb, index); // rewrite size
286  avio_seek(pb, curpos, SEEK_SET);
287 
288  return update_size(pb, pos);
289 }
290 
291 /* Sync sample atom */
292 static int mov_write_stss_tag(AVIOContext *pb, MOVTrack *track, uint32_t flag)
293 {
294  int64_t curpos, entryPos;
295  int i, index = 0;
296  int64_t pos = avio_tell(pb);
297  avio_wb32(pb, 0); // size
298  ffio_wfourcc(pb, flag == MOV_SYNC_SAMPLE ? "stss" : "stps");
299  avio_wb32(pb, 0); // version & flags
300  entryPos = avio_tell(pb);
301  avio_wb32(pb, track->entry); // entry count
302  for (i = 0; i < track->entry; i++) {
303  if (track->cluster[i].flags & flag) {
304  avio_wb32(pb, i + 1);
305  index++;
306  }
307  }
308  curpos = avio_tell(pb);
309  avio_seek(pb, entryPos, SEEK_SET);
310  avio_wb32(pb, index); // rewrite size
311  avio_seek(pb, curpos, SEEK_SET);
312  return update_size(pb, pos);
313 }
314 
315 /* Sample dependency atom */
316 static int mov_write_sdtp_tag(AVIOContext *pb, MOVTrack *track)
317 {
318  int i;
319  uint8_t leading, dependent, reference, redundancy;
320  int64_t pos = avio_tell(pb);
321  avio_wb32(pb, 0); // size
322  ffio_wfourcc(pb, "sdtp");
323  avio_wb32(pb, 0); // version & flags
324  for (i = 0; i < track->entry; i++) {
325  dependent = MOV_SAMPLE_DEPENDENCY_YES;
326  leading = reference = redundancy = MOV_SAMPLE_DEPENDENCY_UNKNOWN;
327  if (track->cluster[i].flags & MOV_DISPOSABLE_SAMPLE) {
328  reference = MOV_SAMPLE_DEPENDENCY_NO;
329  }
330  if (track->cluster[i].flags & MOV_SYNC_SAMPLE) {
331  dependent = MOV_SAMPLE_DEPENDENCY_NO;
332  }
333  avio_w8(pb, (leading << 6) | (dependent << 4) |
334  (reference << 2) | redundancy);
335  }
336  return update_size(pb, pos);
337 }
338 
339 #if CONFIG_IAMFENC
340 static int mov_write_iacb_tag(AVFormatContext *s, AVIOContext *pb, MOVTrack *track)
341 {
342  AVIOContext *dyn_bc;
343  int64_t pos = avio_tell(pb);
344  uint8_t *dyn_buf = NULL;
345  int dyn_size;
346  int ret = avio_open_dyn_buf(&dyn_bc);
347  if (ret < 0)
348  return ret;
349 
350  avio_wb32(pb, 0);
351  ffio_wfourcc(pb, "iacb");
352  avio_w8(pb, 1); // configurationVersion
353 
354  ret = ff_iamf_write_descriptors(track->iamf, dyn_bc, s);
355  if (ret < 0) {
356  ffio_free_dyn_buf(&dyn_bc);
357  return ret;
358  }
359 
360  dyn_size = avio_close_dyn_buf(dyn_bc, &dyn_buf);
361  ffio_write_leb(pb, dyn_size);
362  avio_write(pb, dyn_buf, dyn_size);
363  av_free(dyn_buf);
364 
365  return update_size(pb, pos);
366 }
367 #endif
368 
369 static int mov_write_amr_tag(AVIOContext *pb, MOVTrack *track)
370 {
371  avio_wb32(pb, 0x11); /* size */
372  if (track->mode == MODE_MOV) ffio_wfourcc(pb, "samr");
373  else ffio_wfourcc(pb, "damr");
374  ffio_wfourcc(pb, "FFMP");
375  avio_w8(pb, 0); /* decoder version */
376 
377  avio_wb16(pb, 0x81FF); /* Mode set (all modes for AMR_NB) */
378  avio_w8(pb, 0x00); /* Mode change period (no restriction) */
379  avio_w8(pb, 0x01); /* Frames per sample */
380  return 0x11;
381 }
382 
383 struct eac3_info {
385  uint8_t ec3_done;
386  uint8_t num_blocks;
387 
388  /* Layout of the EC3SpecificBox */
389  /* maximum bitrate */
390  uint16_t data_rate;
392  /* number of independent substreams */
393  uint8_t num_ind_sub;
394  struct {
395  /* sample rate code (see ff_ac3_sample_rate_tab) 2 bits */
396  uint8_t fscod;
397  /* bit stream identification 5 bits */
398  uint8_t bsid;
399  /* one bit reserved */
400  /* audio service mixing (not supported yet) 1 bit */
401  /* bit stream mode 3 bits */
402  uint8_t bsmod;
403  /* audio coding mode 3 bits */
404  uint8_t acmod;
405  /* sub woofer on 1 bit */
406  uint8_t lfeon;
407  /* 3 bits reserved */
408  /* number of dependent substreams associated with this substream 4 bits */
409  uint8_t num_dep_sub;
410  /* channel locations of the dependent substream(s), if any, 9 bits */
411  uint16_t chan_loc;
412  /* if there is no dependent substream, then one bit reserved instead */
413  } substream[1]; /* TODO: support 8 independent substreams */
414  /* indicates the decoding complexity, 8 bits */
416 };
417 
419 {
420  struct eac3_info *info = track->eac3_priv;
421  PutBitContext pbc;
422  uint8_t buf[3];
423 
424  if (!info || !info->ec3_done) {
426  "Cannot write moov atom before AC3 packets."
427  " Set the delay_moov flag to fix this.\n");
428  return AVERROR(EINVAL);
429  }
430 
431  if (info->substream[0].bsid > 8) {
433  "RealAudio AC-3/DolbyNet with bsid %d is not defined by the "
434  "ISOBMFF specification in ETSI TS 102 366!\n",
435  info->substream[0].bsid);
436  return AVERROR(EINVAL);
437  }
438 
439  if (info->ac3_bit_rate_code < 0) {
441  "No valid AC3 bit rate code for data rate of %d!\n",
442  info->data_rate);
443  return AVERROR(EINVAL);
444  }
445 
446  avio_wb32(pb, 11);
447  ffio_wfourcc(pb, "dac3");
448 
449  init_put_bits(&pbc, buf, sizeof(buf));
450  put_bits(&pbc, 2, info->substream[0].fscod);
451  put_bits(&pbc, 5, info->substream[0].bsid);
452  put_bits(&pbc, 3, info->substream[0].bsmod);
453  put_bits(&pbc, 3, info->substream[0].acmod);
454  put_bits(&pbc, 1, info->substream[0].lfeon);
455  put_bits(&pbc, 5, info->ac3_bit_rate_code); // bit_rate_code
456  put_bits(&pbc, 5, 0); // reserved
457 
458  flush_put_bits(&pbc);
459  avio_write(pb, buf, sizeof(buf));
460 
461  return 11;
462 }
463 
464 static int handle_eac3(MOVMuxContext *mov, AVPacket *pkt, MOVTrack *track)
465 {
466  AC3HeaderInfo *hdr = NULL;
467  struct eac3_info *info;
468  int num_blocks, ret;
469 
470  if (!track->eac3_priv) {
471  if (!(track->eac3_priv = av_mallocz(sizeof(*info))))
472  return AVERROR(ENOMEM);
473 
474  ((struct eac3_info *)track->eac3_priv)->ac3_bit_rate_code = -1;
475  }
476  info = track->eac3_priv;
477 
478  if (!info->pkt && !(info->pkt = av_packet_alloc()))
479  return AVERROR(ENOMEM);
480 
481  if ((ret = avpriv_ac3_parse_header(&hdr, pkt->data, pkt->size)) < 0) {
482  if (ret == AVERROR(ENOMEM))
483  goto end;
484 
485  /* drop the packets until we see a good one */
486  if (!track->entry) {
487  av_log(mov->fc, AV_LOG_WARNING, "Dropping invalid packet from start of the stream\n");
488  ret = 0;
489  } else
491  goto end;
492  }
493 
494  info->data_rate = FFMAX(info->data_rate, hdr->bit_rate / 1000);
495  info->ac3_bit_rate_code = FFMAX(info->ac3_bit_rate_code,
496  hdr->ac3_bit_rate_code);
497  info->complexity_index_type_a = hdr->complexity_index_type_a;
498 
499  num_blocks = hdr->num_blocks;
500 
501  if (!info->ec3_done) {
502  /* AC-3 substream must be the first one */
503  if (hdr->bitstream_id <= 10 && hdr->substreamid != 0) {
504  ret = AVERROR(EINVAL);
505  goto end;
506  }
507 
508  /* this should always be the case, given that our AC-3 parser
509  * concatenates dependent frames to their independent parent */
512  /* substream ids must be incremental */
513  if (hdr->substreamid > info->num_ind_sub + 1) {
514  ret = AVERROR(EINVAL);
515  goto end;
516  }
517 
518  if (hdr->substreamid == info->num_ind_sub + 1) {
519  //info->num_ind_sub++;
520  avpriv_request_sample(mov->fc, "Multiple independent substreams");
522  goto end;
523  } else if (hdr->substreamid < info->num_ind_sub ||
524  hdr->substreamid == 0 && info->substream[0].bsid) {
525  info->ec3_done = 1;
526  goto concatenate;
527  }
528  } else {
529  if (hdr->substreamid != 0) {
530  avpriv_request_sample(mov->fc, "Multiple non EAC3 independent substreams");
532  goto end;
533  }
534  }
535 
536  /* fill the info needed for the "dec3" atom */
537  info->substream[hdr->substreamid].fscod = hdr->sr_code;
538  info->substream[hdr->substreamid].bsid = hdr->bitstream_id;
539  info->substream[hdr->substreamid].bsmod = hdr->bitstream_mode;
540  info->substream[hdr->substreamid].acmod = hdr->channel_mode;
541  info->substream[hdr->substreamid].lfeon = hdr->lfe_on;
542 
543  if (track->par->codec_id == AV_CODEC_ID_AC3) {
544  // with AC-3 we only require the information of a single packet,
545  // so we can finish as soon as the basic values of the bit stream
546  // have been set to the track's informational structure.
547  info->ec3_done = 1;
548  goto concatenate;
549  }
550 
551  /* Parse dependent substream(s), if any */
552  if (pkt->size != hdr->frame_size) {
553  int cumul_size = hdr->frame_size;
554  int parent = hdr->substreamid;
555 
556  while (cumul_size != pkt->size) {
557  ret = avpriv_ac3_parse_header(&hdr, pkt->data + cumul_size, pkt->size - cumul_size);
558  if (ret < 0)
559  goto end;
561  ret = AVERROR(EINVAL);
562  goto end;
563  }
564  info->substream[parent].num_dep_sub++;
565  ret /= 8;
566 
567  /* get the dependent stream channel map, if exists */
568  if (hdr->channel_map_present)
569  info->substream[parent].chan_loc |= (hdr->channel_map >> 5) & 0x1f;
570  else
571  info->substream[parent].chan_loc |= hdr->channel_mode;
572  cumul_size += hdr->frame_size;
573  }
574  }
575  }
576 
577 concatenate:
578  if (!info->num_blocks && num_blocks == 6) {
579  ret = pkt->size;
580  goto end;
581  }
582  else if (info->num_blocks + num_blocks > 6) {
584  goto end;
585  }
586 
587  if (!info->num_blocks) {
588  ret = av_packet_ref(info->pkt, pkt);
589  if (!ret)
590  info->num_blocks = num_blocks;
591  goto end;
592  } else {
593  if ((ret = av_grow_packet(info->pkt, pkt->size)) < 0)
594  goto end;
595  memcpy(info->pkt->data + info->pkt->size - pkt->size, pkt->data, pkt->size);
596  info->num_blocks += num_blocks;
597  info->pkt->duration += pkt->duration;
598  if (info->num_blocks != 6)
599  goto end;
601  av_packet_move_ref(pkt, info->pkt);
602  info->num_blocks = 0;
603  }
604  ret = pkt->size;
605 
606 end:
607  av_free(hdr);
608 
609  return ret;
610 }
611 
613 {
614  PutBitContext pbc;
615  uint8_t *buf;
616  struct eac3_info *info;
617  int size, i;
618 
619  if (!track->eac3_priv) {
621  "Cannot write moov atom before EAC3 packets parsed.\n");
622  return AVERROR(EINVAL);
623  }
624 
625  info = track->eac3_priv;
626  size = 2 + (4 * (info->num_ind_sub + 1)) + (2 * !!info->complexity_index_type_a);
627  buf = av_malloc(size);
628  if (!buf) {
629  return AVERROR(ENOMEM);
630  }
631 
632  init_put_bits(&pbc, buf, size);
633  put_bits(&pbc, 13, info->data_rate);
634  put_bits(&pbc, 3, info->num_ind_sub);
635  for (i = 0; i <= info->num_ind_sub; i++) {
636  put_bits(&pbc, 2, info->substream[i].fscod);
637  put_bits(&pbc, 5, info->substream[i].bsid);
638  put_bits(&pbc, 1, 0); /* reserved */
639  put_bits(&pbc, 1, 0); /* asvc */
640  put_bits(&pbc, 3, info->substream[i].bsmod);
641  put_bits(&pbc, 3, info->substream[i].acmod);
642  put_bits(&pbc, 1, info->substream[i].lfeon);
643  put_bits(&pbc, 3, 0); /* reserved */
644  put_bits(&pbc, 4, info->substream[i].num_dep_sub);
645  if (!info->substream[i].num_dep_sub) {
646  put_bits(&pbc, 1, 0); /* reserved */
647  } else {
648  put_bits(&pbc, 9, info->substream[i].chan_loc);
649  }
650  }
651  if (info->complexity_index_type_a) {
652  put_bits(&pbc, 7, 0); /* reserved */
653  put_bits(&pbc, 1, 1); // flag_eac3_extension_type_a
654  put_bits(&pbc, 8, info->complexity_index_type_a);
655  }
656  flush_put_bits(&pbc);
657  size = put_bytes_output(&pbc);
658 
659  avio_wb32(pb, size + 8);
660  ffio_wfourcc(pb, "dec3");
661  avio_write(pb, buf, size);
662 
663  av_free(buf);
664 
665  return size;
666 }
667 
668 /**
669  * This function writes extradata "as is".
670  * Extradata must be formatted like a valid atom (with size and tag).
671  */
673 {
674  avio_write(pb, track->extradata[track->last_stsd_index], track->extradata_size[track->last_stsd_index]);
675  return track->extradata_size[track->last_stsd_index];
676 }
677 
679 {
680  avio_wb32(pb, 10);
681  ffio_wfourcc(pb, "enda");
682  avio_wb16(pb, 1); /* little endian */
683  return 10;
684 }
685 
687 {
688  avio_wb32(pb, 10);
689  ffio_wfourcc(pb, "enda");
690  avio_wb16(pb, 0); /* big endian */
691  return 10;
692 }
693 
694 static void put_descr(AVIOContext *pb, int tag, unsigned int size)
695 {
696  int i = 3;
697  avio_w8(pb, tag);
698  for (; i > 0; i--)
699  avio_w8(pb, (size >> (7 * i)) | 0x80);
700  avio_w8(pb, size & 0x7F);
701 }
702 
703 static unsigned compute_avg_bitrate(MOVTrack *track)
704 {
705  uint64_t size = 0;
706  int i;
707  if (!track->track_duration)
708  return 0;
709  for (i = 0; i < track->entry; i++)
710  size += track->cluster[i].size;
711  return size * 8 * track->timescale / track->track_duration;
712 }
713 
715  uint32_t buffer_size; ///< Size of the decoding buffer for the elementary stream in bytes.
716  uint32_t max_bit_rate; ///< Maximum rate in bits/second over any window of one second.
717  uint32_t avg_bit_rate; ///< Average rate in bits/second over the entire presentation.
718 };
719 
721 {
722  const AVPacketSideData *sd = track->st ?
724  track->st->codecpar->nb_coded_side_data,
726  AVCPBProperties *props = sd ? (AVCPBProperties *)sd->data : NULL;
727  struct mpeg4_bit_rate_values bit_rates = { 0 };
728 
729  bit_rates.avg_bit_rate = compute_avg_bitrate(track);
730  if (!bit_rates.avg_bit_rate) {
731  // if the average bit rate cannot be calculated at this point, such as
732  // in the case of fragmented MP4, utilize the following values as
733  // fall-back in priority order:
734  //
735  // 1. average bit rate property
736  // 2. bit rate (usually average over the whole clip)
737  // 3. maximum bit rate property
738 
739  if (props && props->avg_bitrate) {
740  bit_rates.avg_bit_rate = props->avg_bitrate;
741  } else if (track->par->bit_rate) {
742  bit_rates.avg_bit_rate = track->par->bit_rate;
743  } else if (props && props->max_bitrate) {
744  bit_rates.avg_bit_rate = props->max_bitrate;
745  }
746  }
747 
748  // (FIXME should be max rate in any 1 sec window)
749  bit_rates.max_bit_rate = FFMAX(track->par->bit_rate,
750  bit_rates.avg_bit_rate);
751 
752  // utilize values from properties if we have them available
753  if (props) {
754  // no avg_bitrate signals that the track is VBR
755  if (!props->avg_bitrate)
756  bit_rates.avg_bit_rate = props->avg_bitrate;
757  bit_rates.max_bit_rate = FFMAX(bit_rates.max_bit_rate,
758  props->max_bitrate);
759  bit_rates.buffer_size = props->buffer_size / 8;
760  }
761 
762  return bit_rates;
763 }
764 
765 static int mov_write_esds_tag(AVIOContext *pb, MOVTrack *track) // Basic
766 {
767  struct mpeg4_bit_rate_values bit_rates = calculate_mpeg4_bit_rates(track);
768  int64_t pos = avio_tell(pb);
769  int decoder_specific_info_len = track->extradata_size[track->last_stsd_index] ?
770  5 + track->extradata_size[track->last_stsd_index] : 0;
771 
772  avio_wb32(pb, 0); // size
773  ffio_wfourcc(pb, "esds");
774  avio_wb32(pb, 0); // Version
775 
776  // ES descriptor
777  put_descr(pb, 0x03, 3 + 5+13 + decoder_specific_info_len + 5+1);
778  avio_wb16(pb, track->track_id);
779  avio_w8(pb, 0x00); // flags (= no flags)
780 
781  // DecoderConfig descriptor
782  put_descr(pb, 0x04, 13 + decoder_specific_info_len);
783 
784  // Object type indication
785  if ((track->par->codec_id == AV_CODEC_ID_MP2 ||
786  track->par->codec_id == AV_CODEC_ID_MP3) &&
787  track->par->sample_rate > 24000)
788  avio_w8(pb, 0x6B); // 11172-3
789  else
791 
792  // the following fields is made of 6 bits to identify the streamtype (4 for video, 5 for audio)
793  // plus 1 bit to indicate upstream and 1 bit set to 1 (reserved)
794  if (track->par->codec_id == AV_CODEC_ID_DVD_SUBTITLE)
795  avio_w8(pb, (0x38 << 2) | 1); // flags (= NeroSubpicStream)
796  else if (track->par->codec_type == AVMEDIA_TYPE_AUDIO)
797  avio_w8(pb, 0x15); // flags (= Audiostream)
798  else
799  avio_w8(pb, 0x11); // flags (= Visualstream)
800 
801  avio_wb24(pb, bit_rates.buffer_size); // Buffersize DB
802  avio_wb32(pb, bit_rates.max_bit_rate); // maxbitrate
803  avio_wb32(pb, bit_rates.avg_bit_rate);
804 
805  if (track->extradata_size[track->last_stsd_index]) {
806  // DecoderSpecific info descriptor
807  put_descr(pb, 0x05, track->extradata_size[track->last_stsd_index]);
808  avio_write(pb, track->extradata[track->last_stsd_index],
809  track->extradata_size[track->last_stsd_index]);
810  }
811 
812  // SL descriptor
813  put_descr(pb, 0x06, 1);
814  avio_w8(pb, 0x02);
815  return update_size(pb, pos);
816 }
817 
819 {
820  return codec_id == AV_CODEC_ID_PCM_S24LE ||
824 }
825 
827 {
828  return codec_id == AV_CODEC_ID_PCM_S24BE ||
832 }
833 
835 {
836  int ret;
837  int64_t pos = avio_tell(pb);
838  avio_wb32(pb, 0);
839  avio_wl32(pb, track->tag); // store it byteswapped
840  track->par->codec_tag = av_bswap16(track->tag >> 16);
841  if ((ret = ff_put_wav_header(s, pb, track->par, 0)) < 0)
842  return ret;
843  return update_size(pb, pos);
844 }
845 
847 {
848  int ret;
849  int64_t pos = avio_tell(pb);
850  avio_wb32(pb, 0);
851  ffio_wfourcc(pb, "wfex");
853  return ret;
854  return update_size(pb, pos);
855 }
856 
857 static int mov_write_dfla_tag(AVIOContext *pb, MOVTrack *track)
858 {
859  int64_t pos = avio_tell(pb);
860  avio_wb32(pb, 0);
861  ffio_wfourcc(pb, "dfLa");
862  avio_w8(pb, 0); /* version */
863  avio_wb24(pb, 0); /* flags */
864 
865  /* Expect the encoder to pass a METADATA_BLOCK_TYPE_STREAMINFO. */
867  return AVERROR_INVALIDDATA;
868 
869  /* TODO: Write other METADATA_BLOCK_TYPEs if the encoder makes them available. */
870  avio_w8(pb, 1 << 7 | FLAC_METADATA_TYPE_STREAMINFO); /* LastMetadataBlockFlag << 7 | BlockType */
871  avio_wb24(pb, track->extradata_size[track->last_stsd_index]); /* Length */
872  avio_write(pb, track->extradata[track->last_stsd_index], track->extradata_size[track->last_stsd_index]); /* BlockData[Length] */
873 
874  return update_size(pb, pos);
875 }
876 
878 {
879  int64_t pos = avio_tell(pb);
880  int channels, channel_map;
881  avio_wb32(pb, 0);
882  ffio_wfourcc(pb, "dOps");
883  avio_w8(pb, 0); /* Version */
884  if (track->extradata_size[track->last_stsd_index] < 19) {
885  av_log(s, AV_LOG_ERROR, "invalid extradata size\n");
886  return AVERROR_INVALIDDATA;
887  }
888  /* extradata contains an Ogg OpusHead, other than byte-ordering and
889  OpusHead's preceding magic/version, OpusSpecificBox is currently
890  identical. */
891  channels = AV_RB8(track->extradata[track->last_stsd_index] + 9);
892  channel_map = AV_RB8(track->extradata[track->last_stsd_index] + 18);
893 
894  avio_w8(pb, channels); /* OuputChannelCount */
895  avio_wb16(pb, AV_RL16(track->extradata[track->last_stsd_index] + 10)); /* PreSkip */
896  avio_wb32(pb, AV_RL32(track->extradata[track->last_stsd_index] + 12)); /* InputSampleRate */
897  avio_wb16(pb, AV_RL16(track->extradata[track->last_stsd_index] + 16)); /* OutputGain */
898  avio_w8(pb, channel_map); /* ChannelMappingFamily */
899  /* Write the rest of the header out without byte-swapping. */
900  if (channel_map) {
901  if (track->extradata_size[track->last_stsd_index] < 21 + channels) {
902  av_log(s, AV_LOG_ERROR, "invalid extradata size\n");
903  return AVERROR_INVALIDDATA;
904  }
905  avio_write(pb, track->extradata[track->last_stsd_index] + 19, 2 + channels); /* ChannelMappingTable */
906  }
907 
908  return update_size(pb, pos);
909 }
910 
912 {
913  int64_t pos = avio_tell(pb);
914  int length;
915  avio_wb32(pb, 0);
916  ffio_wfourcc(pb, "dmlp");
917 
918  if (track->extradata_size[track->last_stsd_index] < 20) {
920  "Cannot write moov atom before TrueHD packets."
921  " Set the delay_moov flag to fix this.\n");
922  return AVERROR(EINVAL);
923  }
924 
925  length = (AV_RB16(track->extradata[track->last_stsd_index]) & 0xFFF) * 2;
926  if (length < 20 || length > track->extradata_size[track->last_stsd_index])
927  return AVERROR_INVALIDDATA;
928 
929  // Only TrueHD is supported
930  if (AV_RB32(track->extradata[track->last_stsd_index] + 4) != 0xF8726FBA)
931  return AVERROR_INVALIDDATA;
932 
933  avio_wb32(pb, AV_RB32(track->extradata[track->last_stsd_index] + 8)); /* format_info */
934  avio_wb16(pb, AV_RB16(track->extradata[track->last_stsd_index] + 18) << 1); /* peak_data_rate */
935  avio_wb32(pb, 0); /* reserved */
936 
937  return update_size(pb, pos);
938 }
939 
941 {
942  const AVDictionaryEntry *str = av_dict_get(track->st->metadata, "SA3D", NULL, 0);
943  AVChannelLayout ch_layout = { 0 };
944  int64_t pos;
945  int ambisonic_order, ambi_channels, non_diegetic_channels;
946  int i, ret;
947 
948  if (!str)
949  return 0;
950 
951  ret = av_channel_layout_from_string(&ch_layout, str->value);
952  if (ret < 0) {
953  if (ret == AVERROR(EINVAL)) {
954 invalid:
955  av_log(s, AV_LOG_ERROR, "Invalid SA3D layout: \"%s\"\n", str->value);
956  ret = 0;
957  }
958  av_channel_layout_uninit(&ch_layout);
959  return ret;
960  }
961 
962  if (track->st->codecpar->ch_layout.nb_channels != ch_layout.nb_channels)
963  goto invalid;
964 
965  ambisonic_order = av_channel_layout_ambisonic_order(&ch_layout);
966  if (ambisonic_order < 0)
967  goto invalid;
968 
969  ambi_channels = (ambisonic_order + 1LL) * (ambisonic_order + 1LL);
970  non_diegetic_channels = ch_layout.nb_channels - ambi_channels;
971  if (non_diegetic_channels &&
972  (non_diegetic_channels != 2 ||
974  goto invalid;
975 
976  av_log(s, AV_LOG_VERBOSE, "Inserting SA3D box with layout: \"%s\"\n", str->value);
977 
978  pos = avio_tell(pb);
979 
980  avio_wb32(pb, 0); // Size
981  ffio_wfourcc(pb, "SA3D");
982  avio_w8(pb, 0); // version
983  avio_w8(pb, (!!non_diegetic_channels) << 7); // head_locked_stereo and ambisonic_type
984  avio_wb32(pb, ambisonic_order); // ambisonic_order
985  avio_w8(pb, 0); // ambisonic_channel_ordering
986  avio_w8(pb, 0); // ambisonic_normalization
987  avio_wb32(pb, ch_layout.nb_channels); // num_channels
988  for (i = 0; i < ambi_channels; i++)
990  for (; i < ch_layout.nb_channels; i++)
991  avio_wb32(pb, av_channel_layout_channel_from_index(&ch_layout, i) + ambi_channels);
992 
993  av_channel_layout_uninit(&ch_layout);
994 
995  return update_size(pb, pos);
996 }
997 
999 {
1000  uint32_t layout_tag, bitmap, *channel_desc;
1001  int64_t pos = avio_tell(pb);
1002  int num_desc, ret;
1003 
1004  if (track->multichannel_as_mono)
1005  return 0;
1006 
1007  ret = ff_mov_get_channel_layout_tag(track->par, &layout_tag,
1008  &bitmap, &channel_desc);
1009 
1010  if (ret < 0) {
1011  if (ret == AVERROR(ENOSYS)) {
1012  av_log(s, AV_LOG_WARNING, "not writing 'chan' tag due to "
1013  "lack of channel information\n");
1014  ret = 0;
1015  }
1016 
1017  return ret;
1018  }
1019 
1020  if (layout_tag == MOV_CH_LAYOUT_MONO && track->mono_as_fc > 0) {
1021  av_assert0(!channel_desc);
1022  channel_desc = av_malloc(sizeof(*channel_desc));
1023  if (!channel_desc)
1024  return AVERROR(ENOMEM);
1025 
1026  layout_tag = 0;
1027  bitmap = 0;
1028  *channel_desc = 3; // channel label "Center"
1029  }
1030 
1031  num_desc = layout_tag ? 0 : track->par->ch_layout.nb_channels;
1032 
1033  avio_wb32(pb, 0); // Size
1034  ffio_wfourcc(pb, "chan"); // Type
1035  avio_w8(pb, 0); // Version
1036  avio_wb24(pb, 0); // Flags
1037  avio_wb32(pb, layout_tag); // mChannelLayoutTag
1038  avio_wb32(pb, bitmap); // mChannelBitmap
1039  avio_wb32(pb, num_desc); // mNumberChannelDescriptions
1040 
1041  for (int i = 0; i < num_desc; i++) {
1042  avio_wb32(pb, channel_desc[i]); // mChannelLabel
1043  avio_wb32(pb, 0); // mChannelFlags
1044  avio_wl32(pb, 0); // mCoordinates[0]
1045  avio_wl32(pb, 0); // mCoordinates[1]
1046  avio_wl32(pb, 0); // mCoordinates[2]
1047  }
1048 
1049  av_free(channel_desc);
1050 
1051  return update_size(pb, pos);
1052 }
1053 
1055 {
1056  int64_t pos = avio_tell(pb);
1057 
1058  avio_wb32(pb, 0); /* size */
1059  ffio_wfourcc(pb, "wave");
1060 
1061  if (track->par->codec_id != AV_CODEC_ID_QDM2) {
1062  avio_wb32(pb, 12); /* size */
1063  ffio_wfourcc(pb, "frma");
1064  avio_wl32(pb, track->tag);
1065  }
1066 
1067  if (track->par->codec_id == AV_CODEC_ID_AAC) {
1068  /* useless atom needed by mplayer, ipod, not needed by quicktime */
1069  avio_wb32(pb, 12); /* size */
1070  ffio_wfourcc(pb, "mp4a");
1071  avio_wb32(pb, 0);
1072  mov_write_esds_tag(pb, track);
1073  } else if (mov_pcm_le_gt16(track->par->codec_id)) {
1074  mov_write_enda_tag(pb);
1075  } else if (mov_pcm_be_gt16(track->par->codec_id)) {
1077  } else if (track->par->codec_id == AV_CODEC_ID_AMR_NB) {
1078  mov_write_amr_tag(pb, track);
1079  } else if (track->par->codec_id == AV_CODEC_ID_AC3) {
1080  mov_write_ac3_tag(s, pb, track);
1081  } else if (track->par->codec_id == AV_CODEC_ID_EAC3) {
1082  mov_write_eac3_tag(s, pb, track);
1083  } else if (track->par->codec_id == AV_CODEC_ID_ALAC ||
1084  track->par->codec_id == AV_CODEC_ID_QDM2) {
1085  mov_write_extradata_tag(pb, track);
1086  } else if (track->par->codec_id == AV_CODEC_ID_ADPCM_MS ||
1087  track->par->codec_id == AV_CODEC_ID_ADPCM_IMA_WAV) {
1088  mov_write_ms_tag(s, pb, track);
1089  }
1090 
1091  avio_wb32(pb, 8); /* size */
1092  avio_wb32(pb, 0); /* null tag */
1093 
1094  return update_size(pb, pos);
1095 }
1096 
1097 static int mov_write_dvc1_structs(MOVTrack *track, uint8_t *buf)
1098 {
1099  uint8_t *unescaped;
1100  const uint8_t *start, *next, *end = track->extradata[track->last_stsd_index] +
1101  track->extradata_size[track->last_stsd_index];
1102  int unescaped_size, seq_found = 0;
1103  int level = 0, interlace = 0;
1104  int packet_seq = track->vc1_info.packet_seq;
1105  int packet_entry = track->vc1_info.packet_entry;
1106  int slices = track->vc1_info.slices;
1107  PutBitContext pbc;
1108 
1109  if (track->start_dts == AV_NOPTS_VALUE) {
1110  /* No packets written yet, vc1_info isn't authoritative yet. */
1111  /* Assume inline sequence and entry headers. */
1112  packet_seq = packet_entry = 1;
1114  "moov atom written before any packets, unable to write correct "
1115  "dvc1 atom. Set the delay_moov flag to fix this.\n");
1116  }
1117 
1119  if (!unescaped)
1120  return AVERROR(ENOMEM);
1121  start = find_next_marker(track->extradata[track->last_stsd_index], end);
1122  for (next = start; next < end; start = next) {
1123  GetBitContext gb;
1124  int size;
1125  next = find_next_marker(start + 4, end);
1126  size = next - start - 4;
1127  if (size <= 0)
1128  continue;
1129  unescaped_size = vc1_unescape_buffer(start + 4, size, unescaped);
1130  init_get_bits(&gb, unescaped, 8 * unescaped_size);
1131  if (AV_RB32(start) == VC1_CODE_SEQHDR) {
1132  int profile = get_bits(&gb, 2);
1133  if (profile != PROFILE_ADVANCED) {
1134  av_free(unescaped);
1135  return AVERROR(ENOSYS);
1136  }
1137  seq_found = 1;
1138  level = get_bits(&gb, 3);
1139  /* chromaformat, frmrtq_postproc, bitrtq_postproc, postprocflag,
1140  * width, height */
1141  skip_bits_long(&gb, 2 + 3 + 5 + 1 + 2*12);
1142  skip_bits(&gb, 1); /* broadcast */
1143  interlace = get_bits1(&gb);
1144  skip_bits(&gb, 4); /* tfcntrflag, finterpflag, reserved, psf */
1145  }
1146  }
1147  if (!seq_found) {
1148  av_free(unescaped);
1149  return AVERROR(ENOSYS);
1150  }
1151 
1152  init_put_bits(&pbc, buf, 7);
1153  /* VC1DecSpecStruc */
1154  put_bits(&pbc, 4, 12); /* profile - advanced */
1155  put_bits(&pbc, 3, level);
1156  put_bits(&pbc, 1, 0); /* reserved */
1157  /* VC1AdvDecSpecStruc */
1158  put_bits(&pbc, 3, level);
1159  put_bits(&pbc, 1, 0); /* cbr */
1160  put_bits(&pbc, 6, 0); /* reserved */
1161  put_bits(&pbc, 1, !interlace); /* no interlace */
1162  put_bits(&pbc, 1, !packet_seq); /* no multiple seq */
1163  put_bits(&pbc, 1, !packet_entry); /* no multiple entry */
1164  put_bits(&pbc, 1, !slices); /* no slice code */
1165  put_bits(&pbc, 1, 0); /* no bframe */
1166  put_bits(&pbc, 1, 0); /* reserved */
1167 
1168  /* framerate */
1169  if (track->st->avg_frame_rate.num > 0 && track->st->avg_frame_rate.den > 0)
1170  put_bits32(&pbc, track->st->avg_frame_rate.num / track->st->avg_frame_rate.den);
1171  else
1172  put_bits32(&pbc, 0xffffffff);
1173 
1174  flush_put_bits(&pbc);
1175 
1176  av_free(unescaped);
1177 
1178  return 0;
1179 }
1180 
1181 static int mov_write_dvc1_tag(AVIOContext *pb, MOVTrack *track)
1182 {
1183  uint8_t buf[7] = { 0 };
1184  int ret;
1185 
1186  if ((ret = mov_write_dvc1_structs(track, buf)) < 0)
1187  return ret;
1188 
1189  avio_wb32(pb, track->extradata_size[track->last_stsd_index] + 8 + sizeof(buf));
1190  ffio_wfourcc(pb, "dvc1");
1191  avio_write(pb, buf, sizeof(buf));
1192  avio_write(pb, track->extradata[track->last_stsd_index],
1193  track->extradata_size[track->last_stsd_index]);
1194 
1195  return 0;
1196 }
1197 
1198 static int mov_write_glbl_tag(AVIOContext *pb, MOVTrack *track)
1199 {
1200  avio_wb32(pb, track->extradata_size[track->last_stsd_index] + 8);
1201  ffio_wfourcc(pb, "glbl");
1202  avio_write(pb, track->extradata[track->last_stsd_index],
1203  track->extradata_size[track->last_stsd_index]);
1204  return 8 + track->extradata_size[track->last_stsd_index];
1205 }
1206 
1207 /**
1208  * Compute flags for 'lpcm' tag.
1209  * See CoreAudioTypes and AudioStreamBasicDescription at Apple.
1210  */
1212 {
1213  switch (codec_id) {
1214  case AV_CODEC_ID_PCM_F32BE:
1215  case AV_CODEC_ID_PCM_F64BE:
1216  return 11;
1217  case AV_CODEC_ID_PCM_F32LE:
1218  case AV_CODEC_ID_PCM_F64LE:
1219  return 9;
1220  case AV_CODEC_ID_PCM_U8:
1221  return 10;
1222  case AV_CODEC_ID_PCM_S16BE:
1223  case AV_CODEC_ID_PCM_S24BE:
1224  case AV_CODEC_ID_PCM_S32BE:
1225  return 14;
1226  case AV_CODEC_ID_PCM_S8:
1227  case AV_CODEC_ID_PCM_S16LE:
1228  case AV_CODEC_ID_PCM_S24LE:
1229  case AV_CODEC_ID_PCM_S32LE:
1230  return 12;
1231  default:
1232  return 0;
1233  }
1234 }
1235 
1236 static int get_cluster_duration(MOVTrack *track, int cluster_idx)
1237 {
1238  int64_t next_dts;
1239 
1240  if (cluster_idx >= track->entry)
1241  return 0;
1242 
1243  if (cluster_idx + 1 == track->entry)
1244  next_dts = track->track_duration + track->start_dts;
1245  else
1246  next_dts = track->cluster[cluster_idx + 1].dts;
1247 
1248  next_dts -= track->cluster[cluster_idx].dts;
1249 
1250  av_assert0(next_dts >= 0);
1251  av_assert0(next_dts <= INT_MAX);
1252 
1253  return next_dts;
1254 }
1255 
1257 {
1258  int i, first_duration;
1259 
1260  /* use 1 for raw PCM */
1261  if (!track->audio_vbr)
1262  return 1;
1263 
1264  /* check to see if duration is constant for all clusters */
1265  if (!track->entry)
1266  return 0;
1267  first_duration = get_cluster_duration(track, 0);
1268  for (i = 1; i < track->entry; i++) {
1269  if (get_cluster_duration(track, i) != first_duration)
1270  return 0;
1271  }
1272  return first_duration;
1273 }
1274 
1275 static int mov_write_btrt_tag(AVIOContext *pb, MOVTrack *track)
1276 {
1277  int64_t pos = avio_tell(pb);
1278  struct mpeg4_bit_rate_values bit_rates = calculate_mpeg4_bit_rates(track);
1279  if (!bit_rates.max_bit_rate && !bit_rates.avg_bit_rate &&
1280  !bit_rates.buffer_size)
1281  // no useful data to be written, skip
1282  return 0;
1283 
1284  avio_wb32(pb, 0); /* size */
1285  ffio_wfourcc(pb, "btrt");
1286 
1287  avio_wb32(pb, bit_rates.buffer_size);
1288  avio_wb32(pb, bit_rates.max_bit_rate);
1289  avio_wb32(pb, bit_rates.avg_bit_rate);
1290 
1291  return update_size(pb, pos);
1292 }
1293 
1295 {
1296  int64_t pos = avio_tell(pb);
1297  int config = 0;
1298  int ret;
1299  uint8_t *speaker_pos = NULL;
1300  const AVChannelLayout *layout = &track->par->ch_layout;
1301 
1303  if (ret || !config) {
1304  config = 0;
1305  speaker_pos = av_malloc(layout->nb_channels);
1306  if (!speaker_pos)
1307  return AVERROR(ENOMEM);
1309  speaker_pos, layout->nb_channels);
1310  if (ret) {
1311  char buf[128] = {0};
1312 
1313  av_freep(&speaker_pos);
1314  av_channel_layout_describe(layout, buf, sizeof(buf));
1315  av_log(s, AV_LOG_ERROR, "unsupported channel layout %s\n", buf);
1316  return ret;
1317  }
1318  }
1319 
1320  avio_wb32(pb, 0); /* size */
1321  ffio_wfourcc(pb, "chnl");
1322  avio_wb32(pb, 0); /* version & flags */
1323 
1324  avio_w8(pb, 1); /* stream_structure */
1325  avio_w8(pb, config);
1326  if (config) {
1327  avio_wb64(pb, 0);
1328  } else {
1329  avio_write(pb, speaker_pos, layout->nb_channels);
1330  av_freep(&speaker_pos);
1331  }
1332 
1333  return update_size(pb, pos);
1334 }
1335 
1337 {
1338  int64_t pos = avio_tell(pb);
1339  int format_flags;
1340  int sample_size;
1341 
1342  avio_wb32(pb, 0); /* size */
1343  ffio_wfourcc(pb, "pcmC");
1344  avio_wb32(pb, 0); /* version & flags */
1345 
1346  /* 0x01: indicates little-endian format */
1347  format_flags = (track->par->codec_id == AV_CODEC_ID_PCM_F32LE ||
1348  track->par->codec_id == AV_CODEC_ID_PCM_F64LE ||
1349  track->par->codec_id == AV_CODEC_ID_PCM_S16LE ||
1350  track->par->codec_id == AV_CODEC_ID_PCM_S24LE ||
1351  track->par->codec_id == AV_CODEC_ID_PCM_S32LE);
1352  avio_w8(pb, format_flags);
1353  sample_size = track->par->bits_per_raw_sample;
1354  if (!sample_size)
1355  sample_size = av_get_exact_bits_per_sample(track->par->codec_id);
1356  av_assert0(sample_size);
1357  avio_w8(pb, sample_size);
1358 
1359  return update_size(pb, pos);
1360 }
1361 
1362 static int mov_write_srat_tag(AVIOContext *pb, MOVTrack *track)
1363 {
1364  int64_t pos = avio_tell(pb);
1365  avio_wb32(pb, 0); /* size */
1366  ffio_wfourcc(pb, "srat");
1367  avio_wb32(pb, 0); /* version & flags */
1368 
1369  avio_wb32(pb, track->par->sample_rate);
1370 
1371  return update_size(pb, pos);
1372 }
1373 
1375 {
1376  int64_t pos = avio_tell(pb);
1377  int version = 0;
1378  uint32_t tag = track->tag;
1379  int ret = 0;
1380 
1381  if (track->mode == MODE_MOV) {
1382  if (track->par->sample_rate > UINT16_MAX || !track->par->ch_layout.nb_channels ||
1383  track->par->ch_layout.nb_channels > 2) {
1384  if (mov_get_lpcm_flags(track->par->codec_id))
1385  tag = AV_RL32("lpcm");
1386  version = 2;
1387  } else if (track->audio_vbr || mov_pcm_le_gt16(track->par->codec_id) ||
1388  mov_pcm_be_gt16(track->par->codec_id) ||
1389  track->par->codec_id == AV_CODEC_ID_ADPCM_MS ||
1390  track->par->codec_id == AV_CODEC_ID_ADPCM_IMA_WAV ||
1391  track->par->codec_id == AV_CODEC_ID_QDM2) {
1392  version = 1;
1393  }
1394  } else if (track->mode == MODE_MP4) {
1395  if (track->par->sample_rate > UINT16_MAX &&
1397  version = 1;
1398  }
1399 
1400  avio_wb32(pb, 0); /* size */
1401  if (mov->encryption_scheme != MOV_ENC_NONE) {
1402  ffio_wfourcc(pb, "enca");
1403  } else {
1404  avio_wl32(pb, tag); // store it byteswapped
1405  }
1406  avio_wb32(pb, 0); /* Reserved */
1407  avio_wb16(pb, 0); /* Reserved */
1408  avio_wb16(pb, 1); /* Data-reference index, XXX == 1 */
1409 
1410  /* SoundDescription */
1411  avio_wb16(pb, version); /* Version */
1412  avio_wb16(pb, 0); /* Revision level */
1413  avio_wb32(pb, 0); /* Reserved */
1414 
1415  if (version == 2) {
1416  avio_wb16(pb, 3);
1417  avio_wb16(pb, 16);
1418  avio_wb16(pb, 0xfffe);
1419  avio_wb16(pb, 0);
1420  avio_wb32(pb, 0x00010000);
1421  avio_wb32(pb, 72);
1422  avio_wb64(pb, av_double2int(track->par->sample_rate));
1423  avio_wb32(pb, track->par->ch_layout.nb_channels);
1424  avio_wb32(pb, 0x7F000000);
1426  avio_wb32(pb, mov_get_lpcm_flags(track->par->codec_id));
1427  avio_wb32(pb, track->sample_size);
1428  avio_wb32(pb, get_samples_per_packet(track));
1429  } else {
1430  unsigned sample_rate = track->par->sample_rate;
1431 
1432  if (track->mode == MODE_MOV) {
1433  avio_wb16(pb, track->par->ch_layout.nb_channels);
1434  if (track->par->codec_id == AV_CODEC_ID_PCM_U8 ||
1435  track->par->codec_id == AV_CODEC_ID_PCM_S8)
1436  avio_wb16(pb, 8); /* bits per sample */
1437  else if (track->par->codec_id == AV_CODEC_ID_ADPCM_G726)
1438  avio_wb16(pb, track->par->bits_per_coded_sample);
1439  else
1440  avio_wb16(pb, 16);
1441  avio_wb16(pb, track->audio_vbr ? -2 : 0); /* compression ID */
1442  } else { /* reserved for mp4/3gp */
1443  avio_wb16(pb, track->tag == MKTAG('i', 'a', 'm', 'f') ?
1444  0 : track->par->ch_layout.nb_channels);
1445  if (track->par->codec_id == AV_CODEC_ID_FLAC ||
1446  track->par->codec_id == AV_CODEC_ID_ALAC) {
1447  avio_wb16(pb, track->par->bits_per_raw_sample);
1448  } else {
1449  avio_wb16(pb, 16);
1450  }
1451  avio_wb16(pb, 0);
1452 
1453  while (sample_rate > UINT16_MAX)
1454  sample_rate >>= 1;
1455  }
1456 
1457  avio_wb16(pb, 0); /* packet size (= 0) */
1458  if (track->tag == MKTAG('i','a','m','f'))
1459  avio_wb16(pb, 0); /* samplerate must be 0 for IAMF */
1460  else if (track->par->codec_id == AV_CODEC_ID_OPUS)
1461  avio_wb16(pb, 48000);
1462  else if (track->par->codec_id == AV_CODEC_ID_TRUEHD)
1463  avio_wb32(pb, track->par->sample_rate);
1464  else
1465  avio_wb16(pb, sample_rate);
1466 
1467  if (track->par->codec_id != AV_CODEC_ID_TRUEHD)
1468  avio_wb16(pb, 0); /* Reserved */
1469  }
1470 
1471  if (track->mode == MODE_MOV && version == 1) { /* SoundDescription V1 extended info */
1472  if (mov_pcm_le_gt16(track->par->codec_id) ||
1473  mov_pcm_be_gt16(track->par->codec_id))
1474  avio_wb32(pb, 1); /* must be 1 for uncompressed formats */
1475  else
1476  avio_wb32(pb, track->par->frame_size); /* Samples per packet */
1477  avio_wb32(pb, track->sample_size / track->par->ch_layout.nb_channels); /* Bytes per packet */
1478  avio_wb32(pb, track->sample_size); /* Bytes per frame */
1479  avio_wb32(pb, 2); /* Bytes per sample */
1480  }
1481 
1482  if (track->mode == MODE_MOV &&
1483  (track->par->codec_id == AV_CODEC_ID_AAC ||
1484  track->par->codec_id == AV_CODEC_ID_AC3 ||
1485  track->par->codec_id == AV_CODEC_ID_EAC3 ||
1486  track->par->codec_id == AV_CODEC_ID_AMR_NB ||
1487  track->par->codec_id == AV_CODEC_ID_ALAC ||
1488  track->par->codec_id == AV_CODEC_ID_ADPCM_MS ||
1489  track->par->codec_id == AV_CODEC_ID_ADPCM_IMA_WAV ||
1490  track->par->codec_id == AV_CODEC_ID_QDM2 ||
1491  (mov_pcm_le_gt16(track->par->codec_id) && version==1) ||
1492  (mov_pcm_be_gt16(track->par->codec_id) && version==1)))
1493  ret = mov_write_wave_tag(s, pb, track);
1494  else if (track->tag == MKTAG('m','p','4','a'))
1495  ret = mov_write_esds_tag(pb, track);
1496 #if CONFIG_IAMFENC
1497  else if (track->tag == MKTAG('i','a','m','f'))
1498  ret = mov_write_iacb_tag(mov->fc, pb, track);
1499 #endif
1500  else if (track->par->codec_id == AV_CODEC_ID_AMR_NB)
1501  ret = mov_write_amr_tag(pb, track);
1502  else if (track->par->codec_id == AV_CODEC_ID_AC3)
1503  ret = mov_write_ac3_tag(s, pb, track);
1504  else if (track->par->codec_id == AV_CODEC_ID_EAC3)
1505  ret = mov_write_eac3_tag(s, pb, track);
1506  else if (track->par->codec_id == AV_CODEC_ID_ALAC)
1507  ret = mov_write_extradata_tag(pb, track);
1508  else if (track->par->codec_id == AV_CODEC_ID_WMAPRO)
1509  ret = mov_write_wfex_tag(s, pb, track);
1510  else if (track->par->codec_id == AV_CODEC_ID_FLAC)
1511  ret = mov_write_dfla_tag(pb, track);
1512  else if (track->par->codec_id == AV_CODEC_ID_OPUS)
1513  ret = mov_write_dops_tag(s, pb, track);
1514  else if (track->par->codec_id == AV_CODEC_ID_TRUEHD)
1515  ret = mov_write_dmlp_tag(s, pb, track);
1516  else if (tag == MOV_MP4_IPCM_TAG || tag == MOV_MP4_FPCM_TAG) {
1517  if (track->par->sample_rate > UINT16_MAX)
1518  mov_write_srat_tag(pb, track);
1519  if (track->par->ch_layout.nb_channels > 1)
1520  ret = mov_write_chnl_tag(s, pb, track);
1521  if (ret < 0)
1522  return ret;
1523  ret = mov_write_pcmc_tag(s, pb, track);
1524  } else if (track->extradata_size[track->last_stsd_index] > 0)
1525  ret = mov_write_glbl_tag(pb, track);
1526 
1527  if (ret < 0)
1528  return ret;
1529 
1530  if (track->mode == MODE_MP4 && track->par->codec_type == AVMEDIA_TYPE_AUDIO
1531  && ((ret = mov_write_SA3D_tag(s, pb, track)) < 0)) {
1532  return ret;
1533  }
1534 
1535  if (track->mode == MODE_MOV && track->par->codec_type == AVMEDIA_TYPE_AUDIO
1536  && ((ret = mov_write_chan_tag(s, pb, track)) < 0)) {
1537  return ret;
1538  }
1539 
1540  if (mov->encryption_scheme != MOV_ENC_NONE
1541  && ((ret = ff_mov_cenc_write_sinf_tag(track, pb, mov->encryption_kid)) < 0)) {
1542  return ret;
1543  }
1544 
1545  if (mov->write_btrt &&
1546  ((ret = mov_write_btrt_tag(pb, track)) < 0))
1547  return ret;
1548 
1549  if (track->mode == MODE_MP4)
1550  track->entry_version = version;
1551 
1552  ret = update_size(pb, pos);
1553  return ret;
1554 }
1555 
1557 {
1558  avio_wb32(pb, 0xf); /* size */
1559  ffio_wfourcc(pb, "d263");
1560  ffio_wfourcc(pb, "FFMP");
1561  avio_w8(pb, 0); /* decoder version */
1562  /* FIXME use AVCodecContext level/profile, when encoder will set values */
1563  avio_w8(pb, 0xa); /* level */
1564  avio_w8(pb, 0); /* profile */
1565  return 0xf;
1566 }
1567 
1568 static int mov_write_av1c_tag(AVIOContext *pb, MOVTrack *track)
1569 {
1570  int64_t pos = avio_tell(pb);
1571 
1572  avio_wb32(pb, 0);
1573  ffio_wfourcc(pb, "av1C");
1574  ff_isom_write_av1c(pb, track->extradata[track->last_stsd_index],
1575  track->extradata_size[track->last_stsd_index], track->mode != MODE_AVIF);
1576  return update_size(pb, pos);
1577 }
1578 
1579 static int mov_write_avcc_tag(AVIOContext *pb, MOVTrack *track)
1580 {
1581  int64_t pos = avio_tell(pb);
1582 
1583  avio_wb32(pb, 0);
1584  ffio_wfourcc(pb, "avcC");
1585  ff_isom_write_avcc(pb, track->extradata[track->last_stsd_index],
1586  track->extradata_size[track->last_stsd_index]);
1587  return update_size(pb, pos);
1588 }
1589 
1590 /* AVS3 Intelligent Media Coding
1591  * Information Technology - Intelligent Media Coding
1592  * Part 6: Intelligent Media Format
1593  */
1594 static int mov_write_av3c(AVIOContext *pb, const uint8_t *data, int len)
1595 {
1596  if (len < 4)
1597  return AVERROR_INVALIDDATA;
1598 
1599  if (data[0] == 1) {
1600  // In Avs3DecoderConfigurationRecord format
1601  avio_write(pb, data, len);
1602  return 0;
1603  }
1604 
1605  avio_w8(pb, 1); // version
1606  avio_wb16(pb, len); // sequence_header_length
1607  avio_write(pb, data, len); // sequence_header
1608  avio_w8(pb, 0xFC); // Only support library_dependency_idc = 0
1609 
1610  return 0;
1611 }
1612 
1613 static int mov_write_av3c_tag(AVIOContext *pb, MOVTrack *track)
1614 {
1615  int64_t pos = avio_tell(pb);
1616  avio_wb32(pb, 0);
1617  ffio_wfourcc(pb, "av3c");
1618  mov_write_av3c(pb, track->extradata[track->last_stsd_index],
1619  track->extradata_size[track->last_stsd_index]);
1620  return update_size(pb, pos);
1621 }
1622 
1624 {
1625  int64_t pos = avio_tell(pb);
1626 
1627  avio_wb32(pb, 0);
1628  ffio_wfourcc(pb, "vpcC");
1629  ff_isom_write_vpcc(s, pb, track->extradata[track->last_stsd_index],
1630  track->extradata_size[track->last_stsd_index], track->par);
1631  return update_size(pb, pos);
1632 }
1633 
1635 {
1636  int64_t pos = avio_tell(pb);
1637 
1638  avio_wb32(pb, 0);
1639  ffio_wfourcc(pb, "hvcC");
1640  if (track->tag == MKTAG('h','v','c','1'))
1641  ff_isom_write_hvcc(pb, track->extradata[track->last_stsd_index],
1642  track->extradata_size[track->last_stsd_index], 1, s);
1643  else
1644  ff_isom_write_hvcc(pb, track->extradata[track->last_stsd_index],
1645  track->extradata_size[track->last_stsd_index], 0, s);
1646  return update_size(pb, pos);
1647 }
1648 
1650 {
1651  int64_t pos = avio_tell(pb);
1652  int ret;
1653 
1654  avio_wb32(pb, 0);
1655  ffio_wfourcc(pb, "lhvC");
1656  if (track->tag == MKTAG('h','v','c','1'))
1657  ret = ff_isom_write_lhvc(pb, track->extradata[track->last_stsd_index],
1658  track->extradata_size[track->last_stsd_index], 1, s);
1659  else
1660  ret = ff_isom_write_lhvc(pb, track->extradata[track->last_stsd_index],
1661  track->extradata_size[track->last_stsd_index], 0, s);
1662 
1663  if (ret < 0) {
1664  avio_seek(pb, pos, SEEK_SET);
1665  return ret;
1666  }
1667 
1668  return update_size(pb, pos);
1669 }
1670 
1671 static int mov_write_evcc_tag(AVIOContext *pb, MOVTrack *track)
1672 {
1673  int64_t pos = avio_tell(pb);
1674 
1675  avio_wb32(pb, 0);
1676  ffio_wfourcc(pb, "evcC");
1677 
1678  if (track->tag == MKTAG('e','v','c','1'))
1679  ff_isom_write_evcc(pb, track->extradata[track->last_stsd_index],
1680  track->extradata_size[track->last_stsd_index], 1);
1681  else
1682  ff_isom_write_evcc(pb, track->extradata[track->last_stsd_index],
1683  track->extradata_size[track->last_stsd_index], 0);
1684 
1685  return update_size(pb, pos);
1686 }
1687 
1688 static int mov_write_lvcc_tag(AVIOContext *pb, MOVTrack *track)
1689 {
1690  int64_t pos = avio_tell(pb);
1691 
1692  avio_wb32(pb, 0);
1693  ffio_wfourcc(pb, "lvcC");
1694 
1695  ff_isom_write_lvcc(pb, track->extradata[track->last_stsd_index],
1696  track->extradata_size[track->last_stsd_index]);
1697 
1698  return update_size(pb, pos);
1699 }
1700 
1701 static int mov_write_vvcc_tag(AVIOContext *pb, MOVTrack *track)
1702 {
1703  int64_t pos = avio_tell(pb);
1704 
1705  avio_wb32(pb, 0);
1706  ffio_wfourcc(pb, "vvcC");
1707 
1708  avio_w8 (pb, 0); /* version */
1709  avio_wb24(pb, 0); /* flags */
1710 
1711  if (track->tag == MKTAG('v','v','c','1'))
1712  ff_isom_write_vvcc(pb, track->extradata[track->last_stsd_index],
1713  track->extradata_size[track->last_stsd_index], 1);
1714  else
1715  ff_isom_write_vvcc(pb, track->extradata[track->last_stsd_index],
1716  track->extradata_size[track->last_stsd_index], 0);
1717  return update_size(pb, pos);
1718 }
1719 
1721 {
1722  int64_t pos = avio_tell(pb);
1723 
1724  avio_wb32(pb, 0);
1725  ffio_wfourcc(pb, "apvC");
1726 
1727  avio_w8 (pb, 0); /* version */
1728  avio_wb24(pb, 0); /* flags */
1729 
1730  ff_isom_write_apvc(pb, track->apv, s);
1731 
1732  return update_size(pb, pos);
1733 }
1734 
1735 /* also used by all avid codecs (dv, imx, meridien) and their variants */
1736 /* https://community.avid.com/forums/t/136517.aspx */
1737 static int mov_write_avid_tag(AVIOContext *pb, MOVTrack *track)
1738 {
1739  int interlaced;
1740  int cid;
1741  int display_width = track->par->width;
1742  const uint8_t *extradata;
1743 
1744  if (track->extradata[track->last_stsd_index] && track->extradata_size[track->last_stsd_index] > 0x29) {
1745  if (ff_dnxhd_parse_header_prefix(track->extradata[track->last_stsd_index]) != 0) {
1746  /* looks like a DNxHD bit stream */
1747  extradata = track->extradata[track->last_stsd_index];
1748  } else {
1749  av_log(NULL, AV_LOG_WARNING, "Could not locate DNxHD bit stream in vos_data\n");
1750  return 0;
1751  }
1752  } else {
1753  av_log(NULL, AV_LOG_WARNING, "Could not locate DNxHD bit stream, vos_data too small\n");
1754  return 0;
1755  }
1756 
1757  cid = AV_RB32(extradata + 0x28);
1758 
1759  avio_wb32(pb, 24); /* size */
1760  ffio_wfourcc(pb, "ACLR");
1761  ffio_wfourcc(pb, "ACLR");
1762  ffio_wfourcc(pb, "0001");
1763  // 1: CCIR (supercolors will be dropped, 16 will be displayed as black)
1764  // 2: FullRange (0 will be displayed as black, 16 will be displayed as dark grey)
1765  if (track->par->color_range == AVCOL_RANGE_MPEG || /* Legal range (16-235) */
1767  avio_wb32(pb, 1);
1768  } else {
1769  avio_wb32(pb, 2);
1770  }
1771  avio_wb32(pb, 0); /* reserved */
1772 
1773  if (track->tag == MKTAG('A','V','d','h')) {
1774  int alp = extradata[0x07] & 1;
1775  int pma = (extradata[0x07] >> 2) & 1;
1776  int sbd = (extradata[0x21] >> 5) & 3;
1777  int ssc = (extradata[0x2C] >> 5) & 3;
1778  int clv = (extradata[0x2C] >> 1) & 3;
1779  int clf = extradata[0x2C] & 1;
1780 
1781  avio_wb32(pb, 32);
1782  ffio_wfourcc(pb, "ADHR");
1783  ffio_wfourcc(pb, "0001");
1784  avio_wb32(pb, cid); // Compression ID
1785  // 0: 4:2:2 Sub Sampling
1786  // 1: 4:2:0 Sub Sampling
1787  // 2: 4:4:4 Sub Sampling
1788  avio_wb32(pb, ssc); // Sub Sampling Control
1789  // 1: 8-bits per sample
1790  // 2: 10-bits per sample
1791  // 3: 12-bits per sample
1792  avio_wb32(pb, sbd); // Sample Bit Depth
1793  // 0: Bitstream is encoded using the YCBCR format rules and tables
1794  // 1: Bitstream is encoded using the RGB format rules and tables – only Compression IDs 1256, 1270
1795  avio_wb16(pb, clf); // Color Format
1796  // 0: ITU-R BT.709
1797  // 1: ITU-R BT.2020
1798  // 2: ITU-R BT.2020 C
1799  // 3: Out-of-band
1800  avio_wb16(pb, clv); // Color Volume
1801  // 0: Alpha channel not present
1802  // 1: Alpha channel present
1803  avio_wb16(pb, alp); // Alpha Present
1804  // 0: Alpha has not been applied to video channels
1805  // 1: Alpha has been applied to the video channels prior to encoding
1806  avio_wb16(pb, pma); // Pre-Multiplied Alpha
1807  return 0;
1808  }
1809 
1810  interlaced = extradata[5] & 2;
1811 
1812  avio_wb32(pb, 24); /* size */
1813  ffio_wfourcc(pb, "APRG");
1814  ffio_wfourcc(pb, "APRG");
1815  ffio_wfourcc(pb, "0001");
1816  // 1 for progressive or 2 for interlaced
1817  if (interlaced)
1818  avio_wb32(pb, 2);
1819  else
1820  avio_wb32(pb, 1);
1821  avio_wb32(pb, 0); /* reserved */
1822 
1823  avio_wb32(pb, 120); /* size */
1824  ffio_wfourcc(pb, "ARES");
1825  ffio_wfourcc(pb, "ARES");
1826  ffio_wfourcc(pb, "0001");
1827  avio_wb32(pb, cid); /* cid */
1828  if ( track->par->sample_aspect_ratio.num > 0
1829  && track->par->sample_aspect_ratio.den > 0)
1830  display_width = display_width * track->par->sample_aspect_ratio.num / track->par->sample_aspect_ratio.den;
1831  avio_wb32(pb, display_width); // field width
1832  if (interlaced) {
1833  avio_wb32(pb, track->par->height / 2); // field height
1834  avio_wb32(pb, 2); // num fields
1835  avio_wb32(pb, 0); // num black lines (must be 0)
1836  // 4: HD1080i
1837  // 5: HD1080P
1838  // 6: HD720P
1839  avio_wb32(pb, 4); // video format
1840  } else {
1841  avio_wb32(pb, track->par->height);
1842  avio_wb32(pb, 1); // num fields
1843  avio_wb32(pb, 0);
1844  if (track->par->height == 1080)
1845  avio_wb32(pb, 5);
1846  else
1847  avio_wb32(pb, 6);
1848  }
1849  /* padding */
1850  ffio_fill(pb, 0, 10 * 8);
1851 
1852  return 0;
1853 }
1854 
1855 static int mov_write_dpxe_tag(AVIOContext *pb, MOVTrack *track)
1856 {
1857  avio_wb32(pb, 12);
1858  ffio_wfourcc(pb, "DpxE");
1859  if (track->extradata_size[track->last_stsd_index] >= 12 &&
1860  !memcmp(&track->extradata[track->last_stsd_index][4], "DpxE", 4)) {
1861  avio_wb32(pb, track->extradata[track->last_stsd_index][11]);
1862  } else {
1863  avio_wb32(pb, 1);
1864  }
1865  return 0;
1866 }
1867 
1869 {
1870  int tag;
1871 
1872  if (track->par->width == 720) { /* SD */
1873  if (track->par->height == 480) { /* NTSC */
1874  if (track->par->format == AV_PIX_FMT_YUV422P) tag = MKTAG('d','v','5','n');
1875  else tag = MKTAG('d','v','c',' ');
1876  }else if (track->par->format == AV_PIX_FMT_YUV422P) tag = MKTAG('d','v','5','p');
1877  else if (track->par->format == AV_PIX_FMT_YUV420P) tag = MKTAG('d','v','c','p');
1878  else tag = MKTAG('d','v','p','p');
1879  } else if (track->par->height == 720) { /* HD 720 line */
1880  if (track->st->time_base.den == 50) tag = MKTAG('d','v','h','q');
1881  else tag = MKTAG('d','v','h','p');
1882  } else if (track->par->height == 1080) { /* HD 1080 line */
1883  if (track->st->time_base.den == 25) tag = MKTAG('d','v','h','5');
1884  else tag = MKTAG('d','v','h','6');
1885  } else {
1886  av_log(s, AV_LOG_ERROR, "unsupported height for dv codec\n");
1887  return 0;
1888  }
1889 
1890  return tag;
1891 }
1892 
1894 {
1895  AVRational rational_framerate = st->avg_frame_rate;
1896  int rate = 0;
1897  if (rational_framerate.den != 0)
1898  rate = av_q2d(rational_framerate);
1899  return rate;
1900 }
1901 
1903 {
1904  int tag = track->par->codec_tag;
1906  AVStream *st = track->st;
1907  int rate = defined_frame_rate(s, st);
1908 
1909  if (!tag)
1910  tag = MKTAG('m', '2', 'v', '1'); //fallback tag
1911 
1912  if (track->par->format == AV_PIX_FMT_YUV420P) {
1913  if (track->par->width == 1280 && track->par->height == 720) {
1914  if (!interlaced) {
1915  if (rate == 24) tag = MKTAG('x','d','v','4');
1916  else if (rate == 25) tag = MKTAG('x','d','v','5');
1917  else if (rate == 30) tag = MKTAG('x','d','v','1');
1918  else if (rate == 50) tag = MKTAG('x','d','v','a');
1919  else if (rate == 60) tag = MKTAG('x','d','v','9');
1920  }
1921  } else if (track->par->width == 1440 && track->par->height == 1080) {
1922  if (!interlaced) {
1923  if (rate == 24) tag = MKTAG('x','d','v','6');
1924  else if (rate == 25) tag = MKTAG('x','d','v','7');
1925  else if (rate == 30) tag = MKTAG('x','d','v','8');
1926  } else {
1927  if (rate == 25) tag = MKTAG('x','d','v','3');
1928  else if (rate == 30) tag = MKTAG('x','d','v','2');
1929  }
1930  } else if (track->par->width == 1920 && track->par->height == 1080) {
1931  if (!interlaced) {
1932  if (rate == 24) tag = MKTAG('x','d','v','d');
1933  else if (rate == 25) tag = MKTAG('x','d','v','e');
1934  else if (rate == 30) tag = MKTAG('x','d','v','f');
1935  } else {
1936  if (rate == 25) tag = MKTAG('x','d','v','c');
1937  else if (rate == 30) tag = MKTAG('x','d','v','b');
1938  }
1939  }
1940  } else if (track->par->format == AV_PIX_FMT_YUV422P) {
1941  if (track->par->width == 1280 && track->par->height == 720) {
1942  if (!interlaced) {
1943  if (rate == 24) tag = MKTAG('x','d','5','4');
1944  else if (rate == 25) tag = MKTAG('x','d','5','5');
1945  else if (rate == 30) tag = MKTAG('x','d','5','1');
1946  else if (rate == 50) tag = MKTAG('x','d','5','a');
1947  else if (rate == 60) tag = MKTAG('x','d','5','9');
1948  }
1949  } else if (track->par->width == 1920 && track->par->height == 1080) {
1950  if (!interlaced) {
1951  if (rate == 24) tag = MKTAG('x','d','5','d');
1952  else if (rate == 25) tag = MKTAG('x','d','5','e');
1953  else if (rate == 30) tag = MKTAG('x','d','5','f');
1954  } else {
1955  if (rate == 25) tag = MKTAG('x','d','5','c');
1956  else if (rate == 30) tag = MKTAG('x','d','5','b');
1957  }
1958  }
1959  }
1960 
1961  return tag;
1962 }
1963 
1965 {
1966  int tag = track->par->codec_tag;
1968  AVStream *st = track->st;
1969  int rate = defined_frame_rate(s, st);
1970 
1971  if (!tag)
1972  tag = MKTAG('a', 'v', 'c', 'i'); //fallback tag
1973 
1974  if (track->par->profile == AV_PROFILE_UNKNOWN ||
1975  !(track->par->profile & AV_PROFILE_H264_INTRA))
1976  return tag;
1977 
1978  if (track->par->format == AV_PIX_FMT_YUV420P10) {
1979  if (track->par->width == 960 && track->par->height == 720) {
1980  if (!interlaced) {
1981  if (rate == 24) tag = MKTAG('a','i','5','p');
1982  else if (rate == 25) tag = MKTAG('a','i','5','q');
1983  else if (rate == 30) tag = MKTAG('a','i','5','p');
1984  else if (rate == 50) tag = MKTAG('a','i','5','q');
1985  else if (rate == 60) tag = MKTAG('a','i','5','p');
1986  }
1987  } else if (track->par->width == 1440 && track->par->height == 1080) {
1988  if (!interlaced) {
1989  if (rate == 24) tag = MKTAG('a','i','5','3');
1990  else if (rate == 25) tag = MKTAG('a','i','5','2');
1991  else if (rate == 30) tag = MKTAG('a','i','5','3');
1992  } else {
1993  if (rate == 50) tag = MKTAG('a','i','5','5');
1994  else if (rate == 60) tag = MKTAG('a','i','5','6');
1995  }
1996  }
1997  } else if (track->par->format == AV_PIX_FMT_YUV422P10) {
1998  if (track->par->width == 1280 && track->par->height == 720) {
1999  if (!interlaced) {
2000  if (rate == 24) tag = MKTAG('a','i','1','p');
2001  else if (rate == 25) tag = MKTAG('a','i','1','q');
2002  else if (rate == 30) tag = MKTAG('a','i','1','p');
2003  else if (rate == 50) tag = MKTAG('a','i','1','q');
2004  else if (rate == 60) tag = MKTAG('a','i','1','p');
2005  }
2006  } else if (track->par->width == 1920 && track->par->height == 1080) {
2007  if (!interlaced) {
2008  if (rate == 24) tag = MKTAG('a','i','1','3');
2009  else if (rate == 25) tag = MKTAG('a','i','1','2');
2010  else if (rate == 30) tag = MKTAG('a','i','1','3');
2011  } else {
2012  if (rate == 25) tag = MKTAG('a','i','1','5');
2013  else if (rate == 50) tag = MKTAG('a','i','1','5');
2014  else if (rate == 60) tag = MKTAG('a','i','1','6');
2015  }
2016  } else if ( track->par->width == 4096 && track->par->height == 2160
2017  || track->par->width == 3840 && track->par->height == 2160
2018  || track->par->width == 2048 && track->par->height == 1080) {
2019  tag = MKTAG('a','i','v','x');
2020  }
2021  }
2022 
2023  return tag;
2024 }
2025 
2027 {
2028  int tag = track->par->codec_tag;
2029 
2030  if (!tag)
2031  tag = MKTAG('e', 'v', 'c', '1');
2032 
2033  return tag;
2034 }
2035 
2037 {
2038  int tag = track->par->codec_tag;
2039 
2040  if (!tag)
2041  tag = MKTAG('a', 'p', 'v', '1');
2042 
2043  return tag;
2044 }
2045 
2046 
2047 static const struct {
2049  uint32_t tag;
2050  unsigned bps;
2051 } mov_pix_fmt_tags[] = {
2052  { AV_PIX_FMT_YUYV422, MKTAG('y','u','v','2'), 0 },
2053  { AV_PIX_FMT_YUYV422, MKTAG('y','u','v','s'), 0 },
2054  { AV_PIX_FMT_UYVY422, MKTAG('2','v','u','y'), 0 },
2055  { AV_PIX_FMT_VYU444, MKTAG('v','3','0','8'), 0 },
2056  { AV_PIX_FMT_UYVA, MKTAG('v','4','0','8'), 0 },
2057  { AV_PIX_FMT_V30XLE, MKTAG('v','4','1','0'), 0 },
2058  { AV_PIX_FMT_RGB555BE,MKTAG('r','a','w',' '), 16 },
2059  { AV_PIX_FMT_RGB555LE,MKTAG('L','5','5','5'), 16 },
2060  { AV_PIX_FMT_RGB565LE,MKTAG('L','5','6','5'), 16 },
2061  { AV_PIX_FMT_RGB565BE,MKTAG('B','5','6','5'), 16 },
2062  { AV_PIX_FMT_GRAY16BE,MKTAG('b','1','6','g'), 16 },
2063  { AV_PIX_FMT_RGB24, MKTAG('r','a','w',' '), 24 },
2064  { AV_PIX_FMT_BGR24, MKTAG('2','4','B','G'), 24 },
2065  { AV_PIX_FMT_ARGB, MKTAG('r','a','w',' '), 32 },
2066  { AV_PIX_FMT_BGRA, MKTAG('B','G','R','A'), 32 },
2067  { AV_PIX_FMT_RGBA, MKTAG('R','G','B','A'), 32 },
2068  { AV_PIX_FMT_ABGR, MKTAG('A','B','G','R'), 32 },
2069  { AV_PIX_FMT_RGB48BE, MKTAG('b','4','8','r'), 48 },
2070 };
2071 
2073 {
2074  int tag = MKTAG('A','V','d','n');
2075  if (track->par->profile != AV_PROFILE_UNKNOWN &&
2076  track->par->profile != AV_PROFILE_DNXHD)
2077  tag = MKTAG('A','V','d','h');
2078  return tag;
2079 }
2080 
2082 {
2083  int tag = track->par->codec_tag;
2084  int i;
2085  enum AVPixelFormat pix_fmt;
2086 
2087  for (i = 0; i < FF_ARRAY_ELEMS(mov_pix_fmt_tags); i++) {
2088  if (track->par->format == mov_pix_fmt_tags[i].pix_fmt) {
2089  tag = mov_pix_fmt_tags[i].tag;
2091  if (track->par->codec_tag == mov_pix_fmt_tags[i].tag)
2092  break;
2093  }
2094  }
2095 
2097  track->par->bits_per_coded_sample);
2098  if (tag == MKTAG('r','a','w',' ') &&
2099  track->par->format != pix_fmt &&
2100  track->par->format != AV_PIX_FMT_GRAY8 &&
2101  track->par->format != AV_PIX_FMT_NONE)
2102  av_log(s, AV_LOG_ERROR, "%s rawvideo cannot be written to mov, output file will be unreadable\n",
2103  av_get_pix_fmt_name(track->par->format));
2104  return tag;
2105 }
2106 
2107 static unsigned int mov_get_codec_tag(AVFormatContext *s, MOVTrack *track)
2108 {
2109  unsigned int tag = track->par->codec_tag;
2110 
2111  // "rtp " is used to distinguish internally created RTP-hint tracks
2112  // (with rtp_ctx) from other tracks.
2113  if (tag == MKTAG('r','t','p',' '))
2114  tag = 0;
2115  if (!tag || (s->strict_std_compliance >= FF_COMPLIANCE_NORMAL &&
2116  (track->par->codec_id == AV_CODEC_ID_DVVIDEO ||
2117  track->par->codec_id == AV_CODEC_ID_RAWVIDEO ||
2118  track->par->codec_id == AV_CODEC_ID_H263 ||
2119  track->par->codec_id == AV_CODEC_ID_H264 ||
2120  track->par->codec_id == AV_CODEC_ID_DNXHD ||
2121  track->par->codec_id == AV_CODEC_ID_MPEG2VIDEO ||
2122  av_get_bits_per_sample(track->par->codec_id)))) { // pcm audio
2123  if (track->par->codec_id == AV_CODEC_ID_DVVIDEO)
2124  tag = mov_get_dv_codec_tag(s, track);
2125  else if (track->par->codec_id == AV_CODEC_ID_RAWVIDEO)
2126  tag = mov_get_rawvideo_codec_tag(s, track);
2127  else if (track->par->codec_id == AV_CODEC_ID_MPEG2VIDEO)
2129  else if (track->par->codec_id == AV_CODEC_ID_H264)
2130  tag = mov_get_h264_codec_tag(s, track);
2131  else if (track->par->codec_id == AV_CODEC_ID_EVC)
2132  tag = mov_get_evc_codec_tag(s, track);
2133  else if (track->par->codec_id == AV_CODEC_ID_APV)
2134  tag = mov_get_apv_codec_tag(s, track);
2135  else if (track->par->codec_id == AV_CODEC_ID_DNXHD)
2136  tag = mov_get_dnxhd_codec_tag(s, track);
2137  else if (track->par->codec_type == AVMEDIA_TYPE_VIDEO) {
2139  if (!tag) { // if no mac fcc found, try with Microsoft tags
2141  if (tag)
2142  av_log(s, AV_LOG_WARNING, "Using MS style video codec tag, "
2143  "the file may be unplayable!\n");
2144  }
2145  } else if (track->par->codec_type == AVMEDIA_TYPE_AUDIO) {
2147  if (!tag) { // if no mac fcc found, try with Microsoft tags
2148  int ms_tag = ff_codec_get_tag(ff_codec_wav_tags, track->par->codec_id);
2149  if (ms_tag) {
2150  tag = MKTAG('m', 's', ((ms_tag >> 8) & 0xff), (ms_tag & 0xff));
2151  av_log(s, AV_LOG_WARNING, "Using MS style audio codec tag, "
2152  "the file may be unplayable!\n");
2153  }
2154  }
2155  } else if (track->par->codec_type == AVMEDIA_TYPE_SUBTITLE)
2157  }
2158 
2159  return tag;
2160 }
2161 
2163  { AV_CODEC_ID_MJPEG, 0xD },
2164  { AV_CODEC_ID_PNG, 0xE },
2165  { AV_CODEC_ID_BMP, 0x1B },
2166  { AV_CODEC_ID_NONE, 0 },
2167 };
2168 
2169 static unsigned int validate_codec_tag(const AVCodecTag *const *tags,
2170  unsigned int tag, int codec_id)
2171 {
2172  int i;
2173 
2174  /**
2175  * Check that tag + id is in the table
2176  */
2177  for (i = 0; tags && tags[i]; i++) {
2178  const AVCodecTag *codec_tags = tags[i];
2179  while (codec_tags->id != AV_CODEC_ID_NONE) {
2180  if (ff_toupper4(codec_tags->tag) == ff_toupper4(tag) &&
2181  codec_tags->id == codec_id)
2182  return codec_tags->tag;
2183  codec_tags++;
2184  }
2185  }
2186  return 0;
2187 }
2188 
2189 static unsigned int mov_find_codec_tag(AVFormatContext *s, MOVTrack *track)
2190 {
2191  if (is_cover_image(track->st))
2193 
2194  if (track->mode == MODE_IPOD)
2195  if (!av_match_ext(s->url, "m4a") &&
2196  !av_match_ext(s->url, "m4v") &&
2197  !av_match_ext(s->url, "m4b"))
2198  av_log(s, AV_LOG_WARNING, "Warning, extension is not .m4a nor .m4v "
2199  "Quicktime/Ipod might not play the file\n");
2200 
2201  if (track->mode == MODE_MOV) {
2202  return mov_get_codec_tag(s, track);
2203  } else
2204  return validate_codec_tag(s->oformat->codec_tag, track->par->codec_tag,
2205  track->par->codec_id);
2206 }
2207 
2208 /** Write uuid atom.
2209  * Needed to make file play in iPods running newest firmware
2210  * goes after avcC atom in moov.trak.mdia.minf.stbl.stsd.avc1
2211  */
2213 {
2214  avio_wb32(pb, 28);
2215  ffio_wfourcc(pb, "uuid");
2216  avio_wb32(pb, 0x6b6840f2);
2217  avio_wb32(pb, 0x5f244fc5);
2218  avio_wb32(pb, 0xba39a51b);
2219  avio_wb32(pb, 0xcf0323f3);
2220  avio_wb32(pb, 0x0);
2221  return 28;
2222 }
2223 
2224 static const uint16_t fiel_data[] = {
2225  0x0000, 0x0100, 0x0201, 0x0206, 0x0209, 0x020e
2226 };
2227 
2228 static int mov_write_fiel_tag(AVIOContext *pb, MOVTrack *track, int field_order)
2229 {
2230  unsigned mov_field_order = 0;
2231  if (field_order < FF_ARRAY_ELEMS(fiel_data))
2232  mov_field_order = fiel_data[field_order];
2233  else
2234  return 0;
2235  avio_wb32(pb, 10);
2236  ffio_wfourcc(pb, "fiel");
2237  avio_wb16(pb, mov_field_order);
2238  return 10;
2239 }
2240 
2242 {
2243  MOVMuxContext *mov = s->priv_data;
2244  int ret = AVERROR_BUG;
2245  int64_t pos = avio_tell(pb);
2246  avio_wb32(pb, 0); /* size */
2247  avio_wl32(pb, track->tag); // store it byteswapped
2248  avio_wb32(pb, 0); /* Reserved */
2249  avio_wb16(pb, 0); /* Reserved */
2250  avio_wb16(pb, 1); /* Data-reference index */
2251 
2252  if (track->par->codec_id == AV_CODEC_ID_DVD_SUBTITLE)
2253  mov_write_esds_tag(pb, track);
2254  else if (track->par->codec_id == AV_CODEC_ID_TTML) {
2255  switch (track->par->codec_tag) {
2256  case MOV_ISMV_TTML_TAG:
2257  // ISMV dfxp requires no extradata.
2258  break;
2259  case MOV_MP4_TTML_TAG:
2260  // As specified in 14496-30, XMLSubtitleSampleEntry
2261  // Namespace
2262  avio_put_str(pb, "http://www.w3.org/ns/ttml");
2263  // Empty schema_location
2264  avio_w8(pb, 0);
2265  // Empty auxiliary_mime_types
2266  avio_w8(pb, 0);
2267  break;
2268  default:
2270  "Unknown codec tag '%s' utilized for TTML stream with "
2271  "index %d (track id %d)!\n",
2272  av_fourcc2str(track->par->codec_tag), track->st->index,
2273  track->track_id);
2274  return AVERROR(EINVAL);
2275  }
2276  } else if (track->extradata_size[track->last_stsd_index])
2277  avio_write(pb, track->extradata[track->last_stsd_index], track->extradata_size[track->last_stsd_index]);
2278 
2279  if (mov->write_btrt &&
2280  ((ret = mov_write_btrt_tag(pb, track)) < 0))
2281  return ret;
2282 
2283  return update_size(pb, pos);
2284 }
2285 
2287 {
2288  int8_t stereo_mode;
2289 
2290  if (stereo_3d->flags != 0) {
2291  av_log(s, AV_LOG_WARNING, "Unsupported stereo_3d flags %x. st3d not written.\n", stereo_3d->flags);
2292  return 0;
2293  }
2294 
2295  switch (stereo_3d->type) {
2296  case AV_STEREO3D_2D:
2297  stereo_mode = 0;
2298  break;
2299  case AV_STEREO3D_TOPBOTTOM:
2300  stereo_mode = 1;
2301  break;
2303  stereo_mode = 2;
2304  break;
2305  default:
2306  av_log(s, AV_LOG_WARNING, "Unsupported stereo_3d type %s. st3d not written.\n", av_stereo3d_type_name(stereo_3d->type));
2307  return 0;
2308  }
2309  avio_wb32(pb, 13); /* size */
2310  ffio_wfourcc(pb, "st3d");
2311  avio_wb32(pb, 0); /* version = 0 & flags = 0 */
2312  avio_w8(pb, stereo_mode);
2313  return 13;
2314 }
2315 
2317 {
2318  int64_t sv3d_pos, svhd_pos, proj_pos;
2319  const char* metadata_source = s->flags & AVFMT_FLAG_BITEXACT ? "Lavf" : LIBAVFORMAT_IDENT;
2320 
2321  if (spherical_mapping->projection != AV_SPHERICAL_EQUIRECTANGULAR &&
2322  spherical_mapping->projection != AV_SPHERICAL_EQUIRECTANGULAR_TILE &&
2323  spherical_mapping->projection != AV_SPHERICAL_CUBEMAP) {
2324  av_log(s, AV_LOG_WARNING, "Unsupported projection %d. sv3d not written.\n", spherical_mapping->projection);
2325  return 0;
2326  }
2327 
2328  sv3d_pos = avio_tell(pb);
2329  avio_wb32(pb, 0); /* size */
2330  ffio_wfourcc(pb, "sv3d");
2331 
2332  svhd_pos = avio_tell(pb);
2333  avio_wb32(pb, 0); /* size */
2334  ffio_wfourcc(pb, "svhd");
2335  avio_wb32(pb, 0); /* version = 0 & flags = 0 */
2336  avio_put_str(pb, metadata_source);
2337  update_size(pb, svhd_pos);
2338 
2339  proj_pos = avio_tell(pb);
2340  avio_wb32(pb, 0); /* size */
2341  ffio_wfourcc(pb, "proj");
2342 
2343  avio_wb32(pb, 24); /* size */
2344  ffio_wfourcc(pb, "prhd");
2345  avio_wb32(pb, 0); /* version = 0 & flags = 0 */
2346  avio_wb32(pb, spherical_mapping->yaw);
2347  avio_wb32(pb, spherical_mapping->pitch);
2348  avio_wb32(pb, spherical_mapping->roll);
2349 
2350  switch (spherical_mapping->projection) {
2353  avio_wb32(pb, 28); /* size */
2354  ffio_wfourcc(pb, "equi");
2355  avio_wb32(pb, 0); /* version = 0 & flags = 0 */
2356  avio_wb32(pb, spherical_mapping->bound_top);
2357  avio_wb32(pb, spherical_mapping->bound_bottom);
2358  avio_wb32(pb, spherical_mapping->bound_left);
2359  avio_wb32(pb, spherical_mapping->bound_right);
2360  break;
2361  case AV_SPHERICAL_CUBEMAP:
2362  avio_wb32(pb, 20); /* size */
2363  ffio_wfourcc(pb, "cbmp");
2364  avio_wb32(pb, 0); /* version = 0 & flags = 0 */
2365  avio_wb32(pb, 0); /* layout */
2366  avio_wb32(pb, spherical_mapping->padding); /* padding */
2367  break;
2368  }
2369  update_size(pb, proj_pos);
2370 
2371  return update_size(pb, sv3d_pos);
2372 }
2373 
2374 static inline int64_t rescale_rational(AVRational q, int b)
2375 {
2376  return av_rescale(q.num, b, q.den);
2377 }
2378 
2380  const AVStereo3D *stereo3d)
2381 {
2382  if (!stereo3d->horizontal_field_of_view.num)
2383  return;
2384 
2385  avio_wb32(pb, 12); /* size */
2386  ffio_wfourcc(pb, "hfov");
2387  avio_wb32(pb, rescale_rational(stereo3d->horizontal_field_of_view, 1000));
2388 }
2389 
2391  const AVSphericalMapping *spherical_mapping)
2392 {
2393  avio_wb32(pb, 24); /* size */
2394  ffio_wfourcc(pb, "proj");
2395  avio_wb32(pb, 16); /* size */
2396  ffio_wfourcc(pb, "prji");
2397  avio_wb32(pb, 0); /* version + flags */
2398 
2399  switch (spherical_mapping->projection) {
2401  ffio_wfourcc(pb, "rect");
2402  break;
2404  ffio_wfourcc(pb, "equi");
2405  break;
2407  ffio_wfourcc(pb, "hequ");
2408  break;
2409  case AV_SPHERICAL_FISHEYE:
2410  ffio_wfourcc(pb, "fish");
2411  break;
2412  default:
2413  av_assert0(0);
2414  }
2415 }
2416 
2418  const AVStereo3D *stereo3d)
2419 {
2420  int64_t pos = avio_tell(pb);
2421  int view = 0;
2422 
2423  avio_wb32(pb, 0); /* size */
2424  ffio_wfourcc(pb, "eyes");
2425 
2426  // stri is mandatory
2427  avio_wb32(pb, 13); /* size */
2428  ffio_wfourcc(pb, "stri");
2429  avio_wb32(pb, 0); /* version + flags */
2430  switch (stereo3d->view) {
2431  case AV_STEREO3D_VIEW_LEFT:
2432  view |= 1 << 0;
2433  break;
2435  view |= 1 << 1;
2436  break;
2438  view |= (1 << 0) | (1 << 1);
2439  break;
2440  }
2441  view |= !!(stereo3d->flags & AV_STEREO3D_FLAG_INVERT) << 3;
2442  avio_w8(pb, view);
2443 
2444  // hero is optional
2445  if (stereo3d->primary_eye != AV_PRIMARY_EYE_NONE) {
2446  avio_wb32(pb, 13); /* size */
2447  ffio_wfourcc(pb, "hero");
2448  avio_wb32(pb, 0); /* version + flags */
2449  avio_w8(pb, stereo3d->primary_eye);
2450  }
2451 
2452  // it's not clear if cams is mandatory or optional
2453  if (stereo3d->baseline) {
2454  avio_wb32(pb, 24); /* size */
2455  ffio_wfourcc(pb, "cams");
2456  avio_wb32(pb, 16); /* size */
2457  ffio_wfourcc(pb, "blin");
2458  avio_wb32(pb, 0); /* version + flags */
2459  avio_wb32(pb, stereo3d->baseline);
2460  }
2461 
2462  // it's not clear if cmfy is mandatory or optional
2463  if (stereo3d->horizontal_disparity_adjustment.num) {
2464  avio_wb32(pb, 24); /* size */
2465  ffio_wfourcc(pb, "cmfy");
2466  avio_wb32(pb, 16); /* size */
2467  ffio_wfourcc(pb, "dadj");
2468  avio_wb32(pb, 0); /* version + flags */
2470  }
2471 
2472  return update_size(pb, pos);
2473 }
2474 
2476  const AVStereo3D *stereo3d,
2477  const AVSphericalMapping *spherical_mapping)
2478 {
2479  int64_t pos;
2480 
2481  if (spherical_mapping &&
2482  spherical_mapping->projection != AV_SPHERICAL_RECTILINEAR &&
2483  spherical_mapping->projection != AV_SPHERICAL_EQUIRECTANGULAR &&
2484  spherical_mapping->projection != AV_SPHERICAL_HALF_EQUIRECTANGULAR &&
2485  spherical_mapping->projection != AV_SPHERICAL_FISHEYE) {
2486  av_log(s, AV_LOG_WARNING, "Unsupported projection %d. proj not written.\n",
2487  spherical_mapping->projection);
2488  spherical_mapping = NULL;
2489  }
2490 
2491  if (stereo3d && (stereo3d->type == AV_STEREO3D_2D ||
2492  (!(stereo3d->flags & AV_STEREO3D_FLAG_INVERT) &&
2493  stereo3d->view == AV_STEREO3D_VIEW_UNSPEC &&
2494  stereo3d->primary_eye == AV_PRIMARY_EYE_NONE &&
2495  !stereo3d->baseline &&
2496  !stereo3d->horizontal_disparity_adjustment.num))) {
2497  av_log(s, AV_LOG_WARNING, "Unsupported stereo 3d metadata. eyes not written.\n");
2498  stereo3d = NULL;
2499  }
2500 
2501  if (!spherical_mapping && !stereo3d)
2502  return 0;
2503 
2504  pos = avio_tell(pb);
2505  avio_wb32(pb, 0); /* size */
2506  ffio_wfourcc(pb, "vexu");
2507 
2508  if (spherical_mapping)
2509  mov_write_vexu_proj_tag(s, pb, spherical_mapping);
2510 
2511  if (stereo3d)
2512  mov_write_eyes_tag(s, pb, stereo3d);
2513 
2514  return update_size(pb, pos);
2515 }
2516 
2518 {
2519  uint8_t buf[ISOM_DVCC_DVVC_SIZE];
2520 
2521  avio_wb32(pb, 32); /* size = 8 + 24 */
2522  if (dovi->dv_profile > 10)
2523  ffio_wfourcc(pb, "dvwC");
2524  else if (dovi->dv_profile > 7)
2525  ffio_wfourcc(pb, "dvvC");
2526  else
2527  ffio_wfourcc(pb, "dvcC");
2528 
2529  ff_isom_put_dvcc_dvvc(s, buf, dovi);
2530  avio_write(pb, buf, sizeof(buf));
2531 
2532  return 32; /* 8 + 24 */
2533 }
2534 
2535 static int mov_write_clap_tag(AVIOContext *pb, MOVTrack *track,
2536  uint32_t top, uint32_t bottom,
2537  uint32_t left, uint32_t right)
2538 {
2539  uint32_t cropped_width = track->par->width - left - right;
2540  uint32_t cropped_height = track->height - top - bottom;
2541  AVRational horizOff =
2542  av_sub_q((AVRational) { track->par->width - cropped_width, 2 },
2543  (AVRational) { left, 1 });
2544  AVRational vertOff =
2545  av_sub_q((AVRational) { track->height - cropped_height, 2 },
2546  (AVRational) { top, 1 });
2547 
2548  avio_wb32(pb, 40);
2549  ffio_wfourcc(pb, "clap");
2550  avio_wb32(pb, cropped_width); /* apertureWidthN */
2551  avio_wb32(pb, 1); /* apertureWidthD */
2552  avio_wb32(pb, cropped_height); /* apertureHeightN */
2553  avio_wb32(pb, 1); /* apertureHeightD */
2554 
2555  avio_wb32(pb, -horizOff.num);
2556  avio_wb32(pb, horizOff.den);
2557  avio_wb32(pb, -vertOff.num);
2558  avio_wb32(pb, vertOff.den);
2559 
2560  return 40;
2561 }
2562 
2563 static int mov_write_pasp_tag(AVIOContext *pb, MOVTrack *track)
2564 {
2565  AVRational sar;
2566  av_reduce(&sar.num, &sar.den, track->par->sample_aspect_ratio.num,
2567  track->par->sample_aspect_ratio.den, INT_MAX);
2568 
2569  avio_wb32(pb, 16);
2570  ffio_wfourcc(pb, "pasp");
2571  avio_wb32(pb, sar.num);
2572  avio_wb32(pb, sar.den);
2573  return 16;
2574 }
2575 
2576 static int mov_write_gama_tag(AVFormatContext *s, AVIOContext *pb, MOVTrack *track, double gamma)
2577 {
2578  uint32_t gama = 0;
2579  if (gamma <= 0.0)
2580  gamma = av_csp_approximate_eotf_gamma(track->par->color_trc);
2581  av_log(s, AV_LOG_DEBUG, "gamma value %g\n", gamma);
2582 
2583  if (gamma > 1e-6) {
2584  gama = (uint32_t)lrint((double)(1<<16) * gamma);
2585  av_log(s, AV_LOG_DEBUG, "writing gama value %"PRId32"\n", gama);
2586 
2587  av_assert0(track->mode == MODE_MOV);
2588  avio_wb32(pb, 12);
2589  ffio_wfourcc(pb, "gama");
2590  avio_wb32(pb, gama);
2591  return 12;
2592  } else {
2593  av_log(s, AV_LOG_WARNING, "gamma value unknown, unable to write gama atom\n");
2594  }
2595  return 0;
2596 }
2597 
2598 static int mov_write_colr_tag(AVIOContext *pb, MOVTrack *track, int prefer_icc)
2599 {
2600  int64_t pos = avio_tell(pb);
2601 
2602  // Ref (MOV): https://developer.apple.com/library/mac/technotes/tn2162/_index.html#//apple_ref/doc/uid/DTS40013070-CH1-TNTAG9
2603  // Ref (MP4): ISO/IEC 14496-12:2012
2604 
2605  if (prefer_icc) {
2607  track->st->codecpar->nb_coded_side_data,
2609 
2610  if (sd) {
2611  avio_wb32(pb, 12 + sd->size);
2612  ffio_wfourcc(pb, "colr");
2613  ffio_wfourcc(pb, "prof");
2614  avio_write(pb, sd->data, sd->size);
2615  return 12 + sd->size;
2616  }
2617  else {
2618  av_log(NULL, AV_LOG_INFO, "no ICC profile found, will write nclx/nclc colour info instead\n");
2619  }
2620  }
2621 
2622  /* We should only ever be called for MOV, MP4 and AVIF. */
2623  av_assert0(track->mode == MODE_MOV || track->mode == MODE_MP4 ||
2624  track->mode == MODE_AVIF);
2625 
2626  avio_wb32(pb, 0); /* size */
2627  ffio_wfourcc(pb, "colr");
2628  if (track->mode == MODE_MP4 || track->mode == MODE_AVIF)
2629  ffio_wfourcc(pb, "nclx");
2630  else
2631  ffio_wfourcc(pb, "nclc");
2632  // Do not try to guess the color info if it is AVCOL_PRI_UNSPECIFIED.
2633  // e.g., Dolby Vision for Apple devices should be set to AVCOL_PRI_UNSPECIFIED. See
2634  // https://developer.apple.com/av-foundation/High-Dynamic-Range-Metadata-for-Apple-Devices.pdf
2635  avio_wb16(pb, track->par->color_primaries);
2636  avio_wb16(pb, track->par->color_trc);
2637  avio_wb16(pb, track->par->color_space);
2638  if (track->mode == MODE_MP4 || track->mode == MODE_AVIF) {
2639  int full_range = track->par->color_range == AVCOL_RANGE_JPEG;
2640  avio_w8(pb, full_range << 7);
2641  }
2642 
2643  return update_size(pb, pos);
2644 }
2645 
2646 static int mov_write_clli_tag(AVIOContext *pb, MOVTrack *track)
2647 {
2648  const AVPacketSideData *side_data;
2649  const AVContentLightMetadata *content_light_metadata;
2650 
2651  side_data = av_packet_side_data_get(track->st->codecpar->coded_side_data,
2652  track->st->codecpar->nb_coded_side_data,
2654  if (!side_data) {
2655  return 0;
2656  }
2657  content_light_metadata = (const AVContentLightMetadata*)side_data->data;
2658 
2659  avio_wb32(pb, 12); // size
2660  ffio_wfourcc(pb, "clli");
2661  avio_wb16(pb, content_light_metadata->MaxCLL);
2662  avio_wb16(pb, content_light_metadata->MaxFALL);
2663  return 12;
2664 }
2665 
2666 static int mov_write_mdcv_tag(AVIOContext *pb, MOVTrack *track)
2667 {
2668  const int chroma_den = 50000;
2669  const int luma_den = 10000;
2670  const AVPacketSideData *side_data;
2672 
2673  side_data = av_packet_side_data_get(track->st->codecpar->coded_side_data,
2674  track->st->codecpar->nb_coded_side_data,
2676  if (side_data)
2677  metadata = (const AVMasteringDisplayMetadata*)side_data->data;
2678  if (!metadata || !metadata->has_primaries || !metadata->has_luminance) {
2679  return 0;
2680  }
2681 
2682  avio_wb32(pb, 32); // size
2683  ffio_wfourcc(pb, "mdcv");
2684  avio_wb16(pb, rescale_rational(metadata->display_primaries[1][0], chroma_den));
2685  avio_wb16(pb, rescale_rational(metadata->display_primaries[1][1], chroma_den));
2686  avio_wb16(pb, rescale_rational(metadata->display_primaries[2][0], chroma_den));
2687  avio_wb16(pb, rescale_rational(metadata->display_primaries[2][1], chroma_den));
2688  avio_wb16(pb, rescale_rational(metadata->display_primaries[0][0], chroma_den));
2689  avio_wb16(pb, rescale_rational(metadata->display_primaries[0][1], chroma_den));
2690  avio_wb16(pb, rescale_rational(metadata->white_point[0], chroma_den));
2691  avio_wb16(pb, rescale_rational(metadata->white_point[1], chroma_den));
2692  avio_wb32(pb, rescale_rational(metadata->max_luminance, luma_den));
2693  avio_wb32(pb, rescale_rational(metadata->min_luminance, luma_den));
2694  return 32;
2695 }
2696 
2697 static int mov_write_amve_tag(AVIOContext *pb, MOVTrack *track)
2698 {
2699  const int illuminance_den = 10000;
2700  const int ambient_den = 50000;
2701  const AVPacketSideData *side_data;
2702  const AVAmbientViewingEnvironment *ambient;
2703 
2704 
2705  side_data = av_packet_side_data_get(track->st->codecpar->coded_side_data,
2706  track->st->codecpar->nb_coded_side_data,
2708 
2709  if (!side_data)
2710  return 0;
2711 
2712  ambient = (const AVAmbientViewingEnvironment*)side_data->data;
2713  if (!ambient || !ambient->ambient_illuminance.num)
2714  return 0;
2715 
2716  avio_wb32(pb, 16); // size
2717  ffio_wfourcc(pb, "amve");
2718  avio_wb32(pb, rescale_rational(ambient->ambient_illuminance, illuminance_den));
2719  avio_wb16(pb, rescale_rational(ambient->ambient_light_x, ambient_den));
2720  avio_wb16(pb, rescale_rational(ambient->ambient_light_y, ambient_den));
2721  return 16;
2722 }
2723 
2724 static void find_compressor(char * compressor_name, int len, MOVTrack *track)
2725 {
2726  AVDictionaryEntry *encoder;
2727  int xdcam_res = (track->par->width == 1280 && track->par->height == 720)
2728  || (track->par->width == 1440 && track->par->height == 1080)
2729  || (track->par->width == 1920 && track->par->height == 1080);
2730 
2731  if ((track->mode == MODE_AVIF ||
2732  track->mode == MODE_MOV ||
2733  track->mode == MODE_MP4) &&
2734  (encoder = av_dict_get(track->st->metadata, "encoder", NULL, 0))) {
2735  av_strlcpy(compressor_name, encoder->value, 32);
2736  } else if (track->par->codec_id == AV_CODEC_ID_MPEG2VIDEO && xdcam_res) {
2738  AVStream *st = track->st;
2739  int rate = defined_frame_rate(NULL, st);
2740  av_strlcatf(compressor_name, len, "XDCAM");
2741  if (track->par->format == AV_PIX_FMT_YUV422P) {
2742  av_strlcatf(compressor_name, len, " HD422");
2743  } else if(track->par->width == 1440) {
2744  av_strlcatf(compressor_name, len, " HD");
2745  } else
2746  av_strlcatf(compressor_name, len, " EX");
2747 
2748  av_strlcatf(compressor_name, len, " %d%c", track->par->height, interlaced ? 'i' : 'p');
2749 
2750  av_strlcatf(compressor_name, len, "%d", rate * (interlaced + 1));
2751  }
2752 }
2753 
2755 {
2756  int64_t pos = avio_tell(pb);
2757  // Write sane defaults:
2758  // all_ref_pics_intra = 0 : all samples can use any type of reference.
2759  // intra_pred_used = 1 : intra prediction may or may not be used.
2760  // max_ref_per_pic = 15 : reserved value to indicate that any number of
2761  // reference images can be used.
2762  uint8_t ccstValue = (0 << 7) | /* all_ref_pics_intra */
2763  (1 << 6) | /* intra_pred_used */
2764  (15 << 2); /* max_ref_per_pic */
2765  avio_wb32(pb, 0); /* size */
2766  ffio_wfourcc(pb, "ccst");
2767  avio_wb32(pb, 0); /* Version & flags */
2768  avio_w8(pb, ccstValue);
2769  avio_wb24(pb, 0); /* reserved */
2770  return update_size(pb, pos);
2771 }
2772 
2773 static int mov_write_aux_tag(AVIOContext *pb, const char *aux_type)
2774 {
2775  int64_t pos = avio_tell(pb);
2776  avio_wb32(pb, 0); /* size */
2777  ffio_wfourcc(pb, aux_type);
2778  avio_wb32(pb, 0); /* Version & flags */
2779  avio_write(pb, "urn:mpeg:mpegB:cicp:systems:auxiliary:alpha\0", 44);
2780  return update_size(pb, pos);
2781 }
2782 
2784 {
2785  int ret = AVERROR_BUG;
2786  int64_t pos = avio_tell(pb);
2787  const AVPacketSideData *sd;
2788  char compressor_name[32] = { 0 };
2789  int avid = 0;
2790 
2791  int uncompressed_ycbcr = ((track->par->codec_id == AV_CODEC_ID_RAWVIDEO && track->par->format == AV_PIX_FMT_UYVY422)
2792  || (track->par->codec_id == AV_CODEC_ID_RAWVIDEO && track->par->format == AV_PIX_FMT_YUYV422)
2793  || (track->par->codec_id == AV_CODEC_ID_RAWVIDEO && track->par->format == AV_PIX_FMT_VYU444)
2794  || (track->par->codec_id == AV_CODEC_ID_RAWVIDEO && track->par->format == AV_PIX_FMT_UYVA)
2795  || (track->par->codec_id == AV_CODEC_ID_RAWVIDEO && track->par->format == AV_PIX_FMT_V30XLE)
2797  || track->par->codec_id == AV_CODEC_ID_V308
2798  || track->par->codec_id == AV_CODEC_ID_V408
2799  || track->par->codec_id == AV_CODEC_ID_V410
2800 #endif
2801  || track->par->codec_id == AV_CODEC_ID_V210);
2802 
2803  avio_wb32(pb, 0); /* size */
2804  if (mov->encryption_scheme != MOV_ENC_NONE) {
2805  ffio_wfourcc(pb, "encv");
2806  } else {
2807  avio_wl32(pb, track->tag); // store it byteswapped
2808  }
2809  avio_wb32(pb, 0); /* Reserved */
2810  avio_wb16(pb, 0); /* Reserved */
2811  avio_wb16(pb, 1); /* Data-reference index */
2812 
2813  if (uncompressed_ycbcr) {
2814  avio_wb16(pb, 2); /* Codec stream version */
2815  } else {
2816  avio_wb16(pb, 0); /* Codec stream version */
2817  }
2818  avio_wb16(pb, 0); /* Codec stream revision (=0) */
2819  if (track->mode == MODE_MOV) {
2820  ffio_wfourcc(pb, "FFMP"); /* Vendor */
2821  if (track->par->codec_id == AV_CODEC_ID_RAWVIDEO || uncompressed_ycbcr) {
2822  avio_wb32(pb, 0); /* Temporal Quality */
2823  avio_wb32(pb, 0x400); /* Spatial Quality = lossless*/
2824  } else {
2825  avio_wb32(pb, 0x200); /* Temporal Quality = normal */
2826  avio_wb32(pb, 0x200); /* Spatial Quality = normal */
2827  }
2828  } else {
2829  ffio_fill(pb, 0, 3 * 4); /* Reserved */
2830  }
2831  avio_wb16(pb, track->par->width); /* Video width */
2832  avio_wb16(pb, track->height); /* Video height */
2833  avio_wb32(pb, 0x00480000); /* Horizontal resolution 72dpi */
2834  avio_wb32(pb, 0x00480000); /* Vertical resolution 72dpi */
2835  avio_wb32(pb, 0); /* Data size (= 0) */
2836  avio_wb16(pb, 1); /* Frame count (= 1) */
2837 
2838  find_compressor(compressor_name, 32, track);
2839  avio_w8(pb, strlen(compressor_name));
2840  avio_write(pb, compressor_name, 31);
2841 
2842  if (track->mode == MODE_MOV &&
2843  (track->par->codec_id == AV_CODEC_ID_V410 || track->par->codec_id == AV_CODEC_ID_V210))
2844  avio_wb16(pb, 0x18);
2845  else if (track->mode == MODE_MOV && track->par->bits_per_coded_sample)
2846  avio_wb16(pb, track->par->bits_per_coded_sample |
2847  (track->par->format == AV_PIX_FMT_GRAY8 ? 0x20 : 0));
2848  else
2849  avio_wb16(pb, 0x18); /* Reserved */
2850 
2851  if (track->mode == MODE_MOV && track->par->format == AV_PIX_FMT_PAL8) {
2852  int pal_size, i;
2853  avio_wb16(pb, 0); /* Color table ID */
2854  avio_wb32(pb, 0); /* Color table seed */
2855  avio_wb16(pb, 0x8000); /* Color table flags */
2856  if (track->par->bits_per_coded_sample < 0 || track->par->bits_per_coded_sample > 8)
2857  return AVERROR(EINVAL);
2858  pal_size = 1 << track->par->bits_per_coded_sample;
2859  avio_wb16(pb, pal_size - 1); /* Color table size (zero-relative) */
2860  for (i = 0; i < pal_size; i++) {
2861  uint32_t rgb = track->palette[i];
2862  uint16_t r = (rgb >> 16) & 0xff;
2863  uint16_t g = (rgb >> 8) & 0xff;
2864  uint16_t b = rgb & 0xff;
2865  avio_wb16(pb, 0);
2866  avio_wb16(pb, (r << 8) | r);
2867  avio_wb16(pb, (g << 8) | g);
2868  avio_wb16(pb, (b << 8) | b);
2869  }
2870  } else
2871  avio_wb16(pb, 0xffff); /* Reserved */
2872 
2873  if (track->tag == MKTAG('m','p','4','v'))
2874  mov_write_esds_tag(pb, track);
2875  else if (track->par->codec_id == AV_CODEC_ID_H263)
2876  mov_write_d263_tag(pb);
2877  else if (track->par->codec_id == AV_CODEC_ID_AVUI ||
2878  track->par->codec_id == AV_CODEC_ID_SVQ3) {
2879  mov_write_extradata_tag(pb, track);
2880  avio_wb32(pb, 0);
2881  } else if (track->par->codec_id == AV_CODEC_ID_DNXHD) {
2882  mov_write_avid_tag(pb, track);
2883  avid = 1;
2884  } else if (track->par->codec_id == AV_CODEC_ID_HEVC) {
2885  mov_write_hvcc_tag(mov->fc, pb, track);
2886  if (track->st->disposition & AV_DISPOSITION_MULTILAYER) {
2887  ret = mov_write_lhvc_tag(mov->fc, pb, track);
2888  if (ret < 0)
2889  av_log(mov->fc, AV_LOG_WARNING, "Not writing 'lhvC' atom for multilayer stream.\n");
2890  }
2891  } else if (track->par->codec_id == AV_CODEC_ID_VVC)
2892  mov_write_vvcc_tag(pb, track);
2893  else if (track->par->codec_id == AV_CODEC_ID_H264 && !TAG_IS_AVCI(track->tag)) {
2894  mov_write_avcc_tag(pb, track);
2895  if (track->mode == MODE_IPOD)
2897  }
2898  else if (track->par->codec_id ==AV_CODEC_ID_EVC) {
2899  mov_write_evcc_tag(pb, track);
2900  } else if (track->par->codec_id == AV_CODEC_ID_LCEVC) {
2901  mov_write_lvcc_tag(pb, track);
2902  } else if (track->par->codec_id ==AV_CODEC_ID_APV) {
2903  mov_write_apvc_tag(mov->fc, pb, track);
2904  } else if (track->par->codec_id == AV_CODEC_ID_VP9) {
2905  mov_write_vpcc_tag(mov->fc, pb, track);
2906  } else if (track->par->codec_id == AV_CODEC_ID_AV1) {
2907  mov_write_av1c_tag(pb, track);
2908  } else if (track->par->codec_id == AV_CODEC_ID_VC1 && track->extradata_size[track->last_stsd_index] > 0)
2909  mov_write_dvc1_tag(pb, track);
2910  else if (track->par->codec_id == AV_CODEC_ID_VP6F ||
2911  track->par->codec_id == AV_CODEC_ID_VP6A) {
2912  /* Don't write any potential extradata here - the cropping
2913  * is signalled via the normal width/height fields. */
2914  } else if (track->par->codec_id == AV_CODEC_ID_R10K) {
2915  if (track->par->codec_tag == MKTAG('R','1','0','k'))
2916  mov_write_dpxe_tag(pb, track);
2917  } else if (track->par->codec_id == AV_CODEC_ID_AVS3) {
2918  mov_write_av3c_tag(pb, track);
2919  } else if (track->extradata_size[track->last_stsd_index] > 0)
2920  mov_write_glbl_tag(pb, track);
2921 
2922  if (track->par->codec_id != AV_CODEC_ID_H264 &&
2923  track->par->codec_id != AV_CODEC_ID_MPEG4 &&
2924  track->par->codec_id != AV_CODEC_ID_DNXHD) {
2925  int field_order = track->par->field_order;
2926 
2927  if (field_order != AV_FIELD_UNKNOWN)
2928  mov_write_fiel_tag(pb, track, field_order);
2929  }
2930 
2931  if (mov->flags & FF_MOV_FLAG_WRITE_GAMA) {
2932  if (track->mode == MODE_MOV)
2933  mov_write_gama_tag(s, pb, track, mov->gamma);
2934  else
2935  av_log(mov->fc, AV_LOG_WARNING, "Not writing 'gama' atom. Format is not MOV.\n");
2936  }
2937  if (track->mode == MODE_MOV || track->mode == MODE_MP4 || track->mode == MODE_AVIF) {
2938  int has_color_info = track->par->color_primaries != AVCOL_PRI_UNSPECIFIED &&
2939  track->par->color_trc != AVCOL_TRC_UNSPECIFIED &&
2941  if (has_color_info || mov->flags & FF_MOV_FLAG_WRITE_COLR ||
2944  int prefer_icc = mov->flags & FF_MOV_FLAG_PREFER_ICC || !has_color_info;
2945  mov_write_colr_tag(pb, track, prefer_icc);
2946  }
2947  } else if (mov->flags & FF_MOV_FLAG_WRITE_COLR) {
2948  av_log(mov->fc, AV_LOG_WARNING, "Not writing 'colr' atom. Format is not MOV or MP4 or AVIF.\n");
2949  }
2950 
2951  if (track->mode == MODE_MOV || track->mode == MODE_MP4) {
2952  mov_write_clli_tag(pb, track);
2953  mov_write_mdcv_tag(pb, track);
2954  mov_write_amve_tag(pb, track);
2955  }
2956 
2957  if (track->mode == MODE_MP4 && mov->fc->strict_std_compliance <= FF_COMPLIANCE_UNOFFICIAL) {
2959  track->st->codecpar->nb_coded_side_data,
2961  const AVPacketSideData *spherical_mapping = av_packet_side_data_get(track->st->codecpar->coded_side_data,
2962  track->st->codecpar->nb_coded_side_data,
2964  if (stereo_3d)
2965  mov_write_st3d_tag(s, pb, (AVStereo3D*)stereo_3d->data);
2966  if (spherical_mapping)
2967  mov_write_sv3d_tag(mov->fc, pb, (AVSphericalMapping*)spherical_mapping->data);
2968  }
2969 
2970  if (track->mode == MODE_MOV || (track->mode == MODE_MP4 &&
2972  const AVStereo3D *stereo3d = NULL;
2973  const AVSphericalMapping *spherical_mapping = NULL;
2974 
2976  track->st->codecpar->nb_coded_side_data,
2978  if (sd)
2979  stereo3d = (AVStereo3D *)sd->data;
2980 
2982  track->st->codecpar->nb_coded_side_data,
2984  if (sd)
2985  spherical_mapping = (AVSphericalMapping *)sd->data;
2986 
2987  if (stereo3d || spherical_mapping)
2988  mov_write_vexu_tag(s, pb, stereo3d, spherical_mapping);
2989  if (stereo3d)
2990  mov_write_hfov_tag(s, pb, stereo3d);
2991  }
2992 
2993  if (track->mode == MODE_MP4) {
2995  track->st->codecpar->nb_coded_side_data,
2997  if (dovi && mov->fc->strict_std_compliance <= FF_COMPLIANCE_UNOFFICIAL) {
2999  } else if (dovi) {
3000  av_log(mov->fc, AV_LOG_WARNING, "Not writing 'dvcC'/'dvvC' box. Requires -strict unofficial.\n");
3001  }
3002  }
3003 
3004  if (track->par->sample_aspect_ratio.den && track->par->sample_aspect_ratio.num) {
3005  mov_write_pasp_tag(pb, track);
3006  }
3007 
3009  track->st->codecpar->nb_coded_side_data,
3011  if (sd && sd->size >= sizeof(uint32_t) * 4) {
3012  uint64_t top = AV_RL32(sd->data + 0);
3013  uint64_t bottom = AV_RL32(sd->data + 4);
3014  uint64_t left = AV_RL32(sd->data + 8);
3015  uint64_t right = AV_RL32(sd->data + 12);
3016 
3017  if ((left + right) >= track->par->width ||
3018  (top + bottom) >= track->height) {
3019  av_log(s, AV_LOG_ERROR, "Invalid cropping dimensions in stream side data\n");
3020  return AVERROR(EINVAL);
3021  }
3022  if (top || bottom || left || right)
3023  mov_write_clap_tag(pb, track, top, bottom, left, right);
3024  } else if (uncompressed_ycbcr)
3025  mov_write_clap_tag(pb, track, 0, 0, 0, 0);
3026 
3027  if (mov->encryption_scheme != MOV_ENC_NONE) {
3028  ff_mov_cenc_write_sinf_tag(track, pb, mov->encryption_kid);
3029  }
3030 
3031  if (mov->write_btrt &&
3032  ((ret = mov_write_btrt_tag(pb, track)) < 0))
3033  return ret;
3034 
3035  /* extra padding for avid stsd */
3036  /* https://developer.apple.com/library/mac/documentation/QuickTime/QTFF/QTFFChap2/qtff2.html#//apple_ref/doc/uid/TP40000939-CH204-61112 */
3037  if (avid)
3038  avio_wb32(pb, 0);
3039 
3040  if (track->mode == MODE_AVIF) {
3041  mov_write_ccst_tag(pb);
3042  if (mov->nb_streams > 0 && track == &mov->tracks[1])
3043  mov_write_aux_tag(pb, "auxi");
3044  }
3045 
3046  return update_size(pb, pos);
3047 }
3048 
3049 static int mov_write_rtp_tag(AVIOContext *pb, MOVTrack *track)
3050 {
3051  int64_t pos = avio_tell(pb);
3052  avio_wb32(pb, 0); /* size */
3053  ffio_wfourcc(pb, "rtp ");
3054  avio_wb32(pb, 0); /* Reserved */
3055  avio_wb16(pb, 0); /* Reserved */
3056  avio_wb16(pb, 1); /* Data-reference index */
3057 
3058  avio_wb16(pb, 1); /* Hint track version */
3059  avio_wb16(pb, 1); /* Highest compatible version */
3060  avio_wb32(pb, track->max_packet_size); /* Max packet size */
3061 
3062  avio_wb32(pb, 12); /* size */
3063  ffio_wfourcc(pb, "tims");
3064  avio_wb32(pb, track->timescale);
3065 
3066  return update_size(pb, pos);
3067 }
3068 
3069 static int mov_write_source_reference_tag(AVIOContext *pb, MOVTrack *track, const char *reel_name)
3070 {
3071  uint64_t str_size =strlen(reel_name);
3072  int64_t pos = avio_tell(pb);
3073 
3074  if (str_size >= UINT16_MAX){
3075  av_log(NULL, AV_LOG_ERROR, "reel_name length %"PRIu64" is too large\n", str_size);
3076  avio_wb16(pb, 0);
3077  return AVERROR(EINVAL);
3078  }
3079 
3080  avio_wb32(pb, 0); /* size */
3081  ffio_wfourcc(pb, "name"); /* Data format */
3082  avio_wb16(pb, str_size); /* string size */
3083  avio_wb16(pb, track->language); /* langcode */
3084  avio_write(pb, reel_name, str_size); /* reel name */
3085  return update_size(pb,pos);
3086 }
3087 
3088 static int mov_write_tmcd_tag(AVIOContext *pb, MOVTrack *track)
3089 {
3090  int64_t pos = avio_tell(pb);
3091 #if 1
3092  int frame_duration;
3093  int nb_frames;
3094  AVDictionaryEntry *t = NULL;
3095 
3096  if (!track->st->avg_frame_rate.num || !track->st->avg_frame_rate.den) {
3097  av_log(NULL, AV_LOG_ERROR, "avg_frame_rate not set for tmcd track.\n");
3098  return AVERROR(EINVAL);
3099  } else {
3100  frame_duration = av_rescale(track->timescale, track->st->avg_frame_rate.den, track->st->avg_frame_rate.num);
3101  nb_frames = ROUNDED_DIV(track->st->avg_frame_rate.num, track->st->avg_frame_rate.den);
3102  }
3103 
3104  if (nb_frames > 255) {
3105  av_log(NULL, AV_LOG_ERROR, "fps %d is too large\n", nb_frames);
3106  return AVERROR(EINVAL);
3107  }
3108 
3109  avio_wb32(pb, 0); /* size */
3110  ffio_wfourcc(pb, "tmcd"); /* Data format */
3111  avio_wb32(pb, 0); /* Reserved */
3112  avio_wb32(pb, 1); /* Data reference index */
3113  avio_wb32(pb, 0); /* Flags */
3114  avio_wb32(pb, track->timecode_flags); /* Flags (timecode) */
3115  avio_wb32(pb, track->timescale); /* Timescale */
3116  avio_wb32(pb, frame_duration); /* Frame duration */
3117  avio_w8(pb, nb_frames); /* Number of frames */
3118  avio_w8(pb, 0); /* Reserved */
3119 
3120  t = av_dict_get(track->st->metadata, "reel_name", NULL, 0);
3121  if (t && utf8len(t->value) && track->mode != MODE_MP4)
3122  mov_write_source_reference_tag(pb, track, t->value);
3123  else
3124  avio_wb16(pb, 0); /* zero size */
3125 #else
3126 
3127  avio_wb32(pb, 0); /* size */
3128  ffio_wfourcc(pb, "tmcd"); /* Data format */
3129  avio_wb32(pb, 0); /* Reserved */
3130  avio_wb32(pb, 1); /* Data reference index */
3131  if (track->par->extradata_size)
3132  avio_write(pb, track->par->extradata, track->par->extradata_size);
3133 #endif
3134  return update_size(pb, pos);
3135 }
3136 
3137 static int mov_write_gpmd_tag(AVIOContext *pb, const MOVTrack *track)
3138 {
3139  int64_t pos = avio_tell(pb);
3140  avio_wb32(pb, 0); /* size */
3141  ffio_wfourcc(pb, "gpmd");
3142  avio_wb32(pb, 0); /* Reserved */
3143  avio_wb16(pb, 0); /* Reserved */
3144  avio_wb16(pb, 1); /* Data-reference index */
3145  avio_wb32(pb, 0); /* Reserved */
3146  return update_size(pb, pos);
3147 }
3148 
3150 {
3151  int64_t pos = avio_tell(pb);
3152  int ret = 0;
3153  avio_wb32(pb, 0); /* size */
3154  ffio_wfourcc(pb, "stsd");
3155  avio_wb32(pb, 0); /* version & flags */
3156  avio_wb32(pb, track->stsd_count);
3157 
3158  int stsd_index_back = track->last_stsd_index;
3159  for (track->last_stsd_index = 0;
3160  track->last_stsd_index < track->stsd_count;
3161  track->last_stsd_index++) {
3162  if (track->par->codec_type == AVMEDIA_TYPE_VIDEO)
3163  ret = mov_write_video_tag(s, pb, mov, track);
3164  else if (track->par->codec_type == AVMEDIA_TYPE_AUDIO)
3165  ret = mov_write_audio_tag(s, pb, mov, track);
3166  else if (track->par->codec_type == AVMEDIA_TYPE_SUBTITLE)
3167  ret = mov_write_subtitle_tag(s, pb, track);
3168  else if (track->par->codec_tag == MKTAG('r','t','p',' '))
3169  ret = mov_write_rtp_tag(pb, track);
3170  else if (track->par->codec_tag == MKTAG('t','m','c','d'))
3171  ret = mov_write_tmcd_tag(pb, track);
3172  else if (track->par->codec_tag == MKTAG('g','p','m','d'))
3173  ret = mov_write_gpmd_tag(pb, track);
3174 
3175  if (ret < 0)
3176  return ret;
3177  }
3178 
3179  track->last_stsd_index = stsd_index_back;
3180 
3181  return update_size_and_version(pb, pos, track->entry_version);
3182 }
3183 
3185 {
3186  MOVMuxContext *mov = s->priv_data;
3187  MOVCtts *ctts_entries;
3188  uint32_t entries = 0;
3189  uint32_t atom_size;
3190  int i;
3191 
3192  ctts_entries = av_malloc_array((track->entry + 1), sizeof(*ctts_entries)); /* worst case */
3193  if (!ctts_entries)
3194  return AVERROR(ENOMEM);
3195  ctts_entries[0].count = 1;
3196  ctts_entries[0].offset = track->cluster[0].cts;
3197  for (i = 1; i < track->entry; i++) {
3198  if (track->cluster[i].cts == ctts_entries[entries].offset) {
3199  ctts_entries[entries].count++; /* compress */
3200  } else {
3201  entries++;
3202  ctts_entries[entries].offset = track->cluster[i].cts;
3203  ctts_entries[entries].count = 1;
3204  }
3205  }
3206  entries++; /* last one */
3207  atom_size = 16 + (entries * 8);
3208  avio_wb32(pb, atom_size); /* size */
3209  ffio_wfourcc(pb, "ctts");
3211  avio_w8(pb, 1); /* version */
3212  else
3213  avio_w8(pb, 0); /* version */
3214  avio_wb24(pb, 0); /* flags */
3215  avio_wb32(pb, entries); /* entry count */
3216  for (i = 0; i < entries; i++) {
3217  avio_wb32(pb, ctts_entries[i].count);
3218  avio_wb32(pb, ctts_entries[i].offset);
3219  }
3220  av_free(ctts_entries);
3221  return atom_size;
3222 }
3223 
3224 /* Time to sample atom */
3225 static int mov_write_stts_tag(AVIOContext *pb, MOVTrack *track)
3226 {
3227  MOVStts *stts_entries = NULL;
3228  uint32_t entries = -1;
3229  uint32_t atom_size;
3230  int i;
3231 
3232  if (track->par->codec_type == AVMEDIA_TYPE_AUDIO && !track->audio_vbr) {
3233  stts_entries = av_malloc(sizeof(*stts_entries)); /* one entry */
3234  if (!stts_entries)
3235  return AVERROR(ENOMEM);
3236  stts_entries[0].count = track->sample_count;
3237  stts_entries[0].duration = 1;
3238  entries = 1;
3239  } else {
3240  if (track->entry) {
3241  stts_entries = av_malloc_array(track->entry, sizeof(*stts_entries)); /* worst case */
3242  if (!stts_entries)
3243  return AVERROR(ENOMEM);
3244  }
3245  for (i = 0; i < track->entry; i++) {
3246  int duration = get_cluster_duration(track, i);
3247 #if CONFIG_IAMFENC
3248  if (track->iamf && track->par->codec_id == AV_CODEC_ID_OPUS)
3249  duration = av_rescale(duration, 48000, track->par->sample_rate);
3250 #endif
3251  if (i && duration == stts_entries[entries].duration) {
3252  stts_entries[entries].count++; /* compress */
3253  } else {
3254  entries++;
3255  stts_entries[entries].duration = duration;
3256  stts_entries[entries].count = 1;
3257  }
3258  }
3259  entries++; /* last one */
3260  }
3261  atom_size = 16 + (entries * 8);
3262  avio_wb32(pb, atom_size); /* size */
3263  ffio_wfourcc(pb, "stts");
3264  avio_wb32(pb, 0); /* version & flags */
3265  avio_wb32(pb, entries); /* entry count */
3266  for (i = 0; i < entries; i++) {
3267  avio_wb32(pb, stts_entries[i].count);
3268  avio_wb32(pb, stts_entries[i].duration);
3269  }
3270  av_free(stts_entries);
3271  return atom_size;
3272 }
3273 
3275 {
3276  avio_wb32(pb, 28); /* size */
3277  ffio_wfourcc(pb, "dref");
3278  avio_wb32(pb, 0); /* version & flags */
3279  avio_wb32(pb, 1); /* entry count */
3280 
3281  avio_wb32(pb, 0xc); /* size */
3282  //FIXME add the alis and rsrc atom
3283  ffio_wfourcc(pb, "url ");
3284  avio_wb32(pb, 1); /* version & flags */
3285 
3286  return 28;
3287 }
3288 
3290 {
3291  struct sgpd_entry {
3292  int count;
3293  int16_t roll_distance;
3294  int group_description_index;
3295  };
3296 
3297  struct sgpd_entry *sgpd_entries = NULL;
3298  int entries = -1;
3299  int group = 0;
3300  int i, j;
3301 
3302  const int OPUS_SEEK_PREROLL_MS = 80;
3303  int roll_samples = av_rescale_q(OPUS_SEEK_PREROLL_MS,
3304  (AVRational){1, 1000},
3305  (AVRational){1, 48000});
3306 
3307  if (!track->entry)
3308  return 0;
3309 
3310  sgpd_entries = av_malloc_array(track->entry, sizeof(*sgpd_entries));
3311  if (!sgpd_entries)
3312  return AVERROR(ENOMEM);
3313 
3315 
3316  if (track->par->codec_id == AV_CODEC_ID_OPUS) {
3317  for (i = 0; i < track->entry; i++) {
3318  int roll_samples_remaining = roll_samples;
3319  int distance = 0;
3320  for (j = i - 1; j >= 0; j--) {
3321  roll_samples_remaining -= get_cluster_duration(track, j);
3322  distance++;
3323  if (roll_samples_remaining <= 0)
3324  break;
3325  }
3326  /* We don't have enough preceding samples to compute a valid
3327  roll_distance here, so this sample can't be independently
3328  decoded. */
3329  if (roll_samples_remaining > 0)
3330  distance = 0;
3331  /* Verify distance is a maximum of 32 (2.5ms) packets. */
3332  if (distance > 32)
3333  return AVERROR_INVALIDDATA;
3334  if (i && distance == sgpd_entries[entries].roll_distance) {
3335  sgpd_entries[entries].count++;
3336  } else {
3337  entries++;
3338  sgpd_entries[entries].count = 1;
3339  sgpd_entries[entries].roll_distance = distance;
3340  sgpd_entries[entries].group_description_index = distance ? ++group : 0;
3341  }
3342  }
3343  } else {
3344  entries++;
3345  sgpd_entries[entries].count = track->sample_count;
3346  sgpd_entries[entries].roll_distance = 1;
3347  sgpd_entries[entries].group_description_index = ++group;
3348  }
3349  entries++;
3350 
3351  if (!group) {
3352  av_free(sgpd_entries);
3353  return 0;
3354  }
3355 
3356  /* Write sgpd tag */
3357  avio_wb32(pb, 24 + (group * 2)); /* size */
3358  ffio_wfourcc(pb, "sgpd");
3359  avio_wb32(pb, 1 << 24); /* fullbox */
3360  ffio_wfourcc(pb, "roll");
3361  avio_wb32(pb, 2); /* default_length */
3362  avio_wb32(pb, group); /* entry_count */
3363  for (i = 0; i < entries; i++) {
3364  if (sgpd_entries[i].group_description_index) {
3365  avio_wb16(pb, -sgpd_entries[i].roll_distance); /* roll_distance */
3366  }
3367  }
3368 
3369  /* Write sbgp tag */
3370  avio_wb32(pb, 20 + (entries * 8)); /* size */
3371  ffio_wfourcc(pb, "sbgp");
3372  avio_wb32(pb, 0); /* fullbox */
3373  ffio_wfourcc(pb, "roll");
3374  avio_wb32(pb, entries); /* entry_count */
3375  for (i = 0; i < entries; i++) {
3376  avio_wb32(pb, sgpd_entries[i].count); /* sample_count */
3377  avio_wb32(pb, sgpd_entries[i].group_description_index); /* group_description_index */
3378  }
3379 
3380  av_free(sgpd_entries);
3381  return 0;
3382 }
3383 
3385 {
3386  int64_t pos = avio_tell(pb);
3387  int ret = 0;
3388 
3389  avio_wb32(pb, 0); /* size */
3390  ffio_wfourcc(pb, "stbl");
3391  if ((ret = mov_write_stsd_tag(s, pb, mov, track)) < 0)
3392  return ret;
3393  mov_write_stts_tag(pb, track);
3394  if ((track->par->codec_type == AVMEDIA_TYPE_VIDEO ||
3395  track->par->codec_id == AV_CODEC_ID_TRUEHD ||
3397  (track->par->codec_id == AV_CODEC_ID_AAC && track->par->profile == AV_PROFILE_AAC_USAC) ||
3398  track->par->codec_tag == MKTAG('r','t','p',' ')) &&
3399  track->has_keyframes && track->has_keyframes < track->entry)
3400  mov_write_stss_tag(pb, track, MOV_SYNC_SAMPLE);
3401  if (track->par->codec_type == AVMEDIA_TYPE_VIDEO && track->has_disposable && track->entry)
3402  mov_write_sdtp_tag(pb, track);
3403  if (track->mode == MODE_MOV && track->flags & MOV_TRACK_STPS)
3405  if (track->par->codec_type == AVMEDIA_TYPE_VIDEO &&
3406  track->flags & MOV_TRACK_CTTS && track->entry) {
3407 
3408  if ((ret = mov_write_ctts_tag(s, pb, track)) < 0)
3409  return ret;
3410  }
3411  mov_write_stsc_tag(pb, track);
3412  mov_write_stsz_tag(pb, track);
3413  mov_write_stco_tag(pb, track);
3414  if (track->cenc.aes_ctr && !(mov->flags & FF_MOV_FLAG_FRAGMENT)) {
3415  ff_mov_cenc_write_stbl_atoms(&track->cenc, pb, 0);
3416  }
3417  if (track->par->codec_id == AV_CODEC_ID_OPUS || track->par->codec_id == AV_CODEC_ID_AAC) {
3418  mov_preroll_write_stbl_atoms(pb, track);
3419  }
3420  return update_size(pb, pos);
3421 }
3422 
3424 {
3425  int64_t pos = avio_tell(pb);
3426  avio_wb32(pb, 0); /* size */
3427  ffio_wfourcc(pb, "dinf");
3428  mov_write_dref_tag(pb);
3429  return update_size(pb, pos);
3430 }
3431 
3433 {
3434  avio_wb32(pb, 12);
3435  ffio_wfourcc(pb, "nmhd");
3436  avio_wb32(pb, 0);
3437  return 12;
3438 }
3439 
3441 {
3442  avio_wb32(pb, 12);
3443  ffio_wfourcc(pb, "sthd");
3444  avio_wb32(pb, 0);
3445  return 12;
3446 }
3447 
3448 static int mov_write_tcmi_tag(AVIOContext *pb, MOVTrack *track)
3449 {
3450  int64_t pos = avio_tell(pb);
3451  const char *font = "Lucida Grande";
3452  avio_wb32(pb, 0); /* size */
3453  ffio_wfourcc(pb, "tcmi"); /* timecode media information atom */
3454  avio_wb32(pb, 0); /* version & flags */
3455  avio_wb16(pb, 0); /* text font */
3456  avio_wb16(pb, 0); /* text face */
3457  avio_wb16(pb, 12); /* text size */
3458  avio_wb16(pb, 0); /* (unknown, not in the QT specs...) */
3459  avio_wb16(pb, 0x0000); /* text color (red) */
3460  avio_wb16(pb, 0x0000); /* text color (green) */
3461  avio_wb16(pb, 0x0000); /* text color (blue) */
3462  avio_wb16(pb, 0xffff); /* background color (red) */
3463  avio_wb16(pb, 0xffff); /* background color (green) */
3464  avio_wb16(pb, 0xffff); /* background color (blue) */
3465  avio_w8(pb, strlen(font)); /* font len (part of the pascal string) */
3466  avio_write(pb, font, strlen(font)); /* font name */
3467  return update_size(pb, pos);
3468 }
3469 
3470 static int mov_write_gmhd_tag(AVIOContext *pb, MOVTrack *track)
3471 {
3472  int64_t pos = avio_tell(pb);
3473  avio_wb32(pb, 0); /* size */
3474  ffio_wfourcc(pb, "gmhd");
3475  avio_wb32(pb, 0x18); /* gmin size */
3476  ffio_wfourcc(pb, "gmin");/* generic media info */
3477  avio_wb32(pb, 0); /* version & flags */
3478  avio_wb16(pb, 0x40); /* graphics mode = */
3479  avio_wb16(pb, 0x8000); /* opColor (r?) */
3480  avio_wb16(pb, 0x8000); /* opColor (g?) */
3481  avio_wb16(pb, 0x8000); /* opColor (b?) */
3482  avio_wb16(pb, 0); /* balance */
3483  avio_wb16(pb, 0); /* reserved */
3484 
3485  /*
3486  * This special text atom is required for
3487  * Apple Quicktime chapters. The contents
3488  * don't appear to be documented, so the
3489  * bytes are copied verbatim.
3490  */
3491  if (track->tag != MKTAG('c','6','0','8')) {
3492  avio_wb32(pb, 0x2C); /* size */
3493  ffio_wfourcc(pb, "text");
3494  avio_wb16(pb, 0x01);
3495  avio_wb32(pb, 0x00);
3496  avio_wb32(pb, 0x00);
3497  avio_wb32(pb, 0x00);
3498  avio_wb32(pb, 0x01);
3499  avio_wb32(pb, 0x00);
3500  avio_wb32(pb, 0x00);
3501  avio_wb32(pb, 0x00);
3502  avio_wb32(pb, 0x00004000);
3503  avio_wb16(pb, 0x0000);
3504  }
3505 
3506  if (track->par->codec_tag == MKTAG('t','m','c','d')) {
3507  int64_t tmcd_pos = avio_tell(pb);
3508  avio_wb32(pb, 0); /* size */
3509  ffio_wfourcc(pb, "tmcd");
3510  mov_write_tcmi_tag(pb, track);
3511  update_size(pb, tmcd_pos);
3512  } else if (track->par->codec_tag == MKTAG('g','p','m','d')) {
3513  int64_t gpmd_pos = avio_tell(pb);
3514  avio_wb32(pb, 0); /* size */
3515  ffio_wfourcc(pb, "gpmd");
3516  avio_wb32(pb, 0); /* version */
3517  update_size(pb, gpmd_pos);
3518  }
3519  return update_size(pb, pos);
3520 }
3521 
3523 {
3524  avio_wb32(pb, 16); /* size */
3525  ffio_wfourcc(pb, "smhd");
3526  avio_wb32(pb, 0); /* version & flags */
3527  avio_wb16(pb, 0); /* reserved (balance, normally = 0) */
3528  avio_wb16(pb, 0); /* reserved */
3529  return 16;
3530 }
3531 
3533 {
3534  avio_wb32(pb, 0x14); /* size (always 0x14) */
3535  ffio_wfourcc(pb, "vmhd");
3536  avio_wb32(pb, 0x01); /* version & flags */
3537  avio_wb64(pb, 0); /* reserved (graphics mode = copy) */
3538  return 0x14;
3539 }
3540 
3541 static int is_clcp_track(MOVTrack *track)
3542 {
3543  return track->tag == MKTAG('c','7','0','8') ||
3544  track->tag == MKTAG('c','6','0','8');
3545 }
3546 
3548 {
3549  MOVMuxContext *mov = s->priv_data;
3550  const char *hdlr, *descr = NULL, *hdlr_type = NULL;
3551  int64_t pos = avio_tell(pb);
3552  size_t descr_len;
3553 
3554  hdlr = "dhlr";
3555  hdlr_type = "url ";
3556  descr = "DataHandler";
3557 
3558  if (track) {
3559  hdlr = (track->mode == MODE_MOV) ? "mhlr" : "\0\0\0\0";
3560  if (track->par->codec_type == AVMEDIA_TYPE_VIDEO) {
3561  if (track->mode == MODE_AVIF) {
3562  hdlr_type = (track == &mov->tracks[0]) ? "pict" : "auxv";
3563  descr = "PictureHandler";
3564  } else {
3565  hdlr_type = "vide";
3566  descr = "VideoHandler";
3567  }
3568  } else if (track->par->codec_type == AVMEDIA_TYPE_AUDIO) {
3569  hdlr_type = "soun";
3570  descr = "SoundHandler";
3571  } else if (track->par->codec_type == AVMEDIA_TYPE_SUBTITLE) {
3572  if (is_clcp_track(track)) {
3573  hdlr_type = "clcp";
3574  descr = "ClosedCaptionHandler";
3575  } else {
3576  if (track->tag == MKTAG('t','x','3','g')) {
3577  hdlr_type = "sbtl";
3578  } else if (track->tag == MKTAG('m','p','4','s')) {
3579  hdlr_type = "subp";
3580  } else if (track->tag == MOV_MP4_TTML_TAG) {
3581  hdlr_type = "subt";
3582  } else {
3583  hdlr_type = "text";
3584  }
3585  descr = "SubtitleHandler";
3586  }
3587  } else if (track->par->codec_tag == MKTAG('r','t','p',' ')) {
3588  hdlr_type = "hint";
3589  descr = "HintHandler";
3590  } else if (track->par->codec_tag == MKTAG('t','m','c','d')) {
3591  hdlr_type = "tmcd";
3592  descr = "TimeCodeHandler";
3593  } else if (track->par->codec_tag == MKTAG('g','p','m','d')) {
3594  hdlr_type = "meta";
3595  descr = "GoPro MET"; // GoPro Metadata
3596  } else {
3598  "Unknown hdlr_type for %s, writing dummy values\n",
3599  av_fourcc2str(track->par->codec_tag));
3600  }
3601  if (track->st) {
3602  // hdlr.name is used by some players to identify the content title
3603  // of the track. So if an alternate handler description is
3604  // specified, use it.
3605  AVDictionaryEntry *t;
3606  t = av_dict_get(track->st->metadata, "handler_name", NULL, 0);
3607  if (t && utf8len(t->value))
3608  descr = t->value;
3609  }
3610  }
3611 
3612  if (mov->empty_hdlr_name) /* expressly allowed by QTFF and not prohibited in ISO 14496-12 8.4.3.3 */
3613  descr = "";
3614 
3615  avio_wb32(pb, 0); /* size */
3616  ffio_wfourcc(pb, "hdlr");
3617  avio_wb32(pb, 0); /* Version & flags */
3618  avio_write(pb, hdlr, 4); /* handler */
3619  ffio_wfourcc(pb, hdlr_type); /* handler type */
3620  avio_wb32(pb, 0); /* reserved */
3621  avio_wb32(pb, 0); /* reserved */
3622  avio_wb32(pb, 0); /* reserved */
3623  descr_len = strlen(descr);
3624  if (!track || track->mode == MODE_MOV)
3625  avio_w8(pb, descr_len); /* pascal string */
3626  avio_write(pb, descr, descr_len); /* handler description */
3627  if (track && track->mode != MODE_MOV)
3628  avio_w8(pb, 0); /* c string */
3629  return update_size(pb, pos);
3630 }
3631 
3632 static int mov_write_pitm_tag(AVIOContext *pb, int item_id)
3633 {
3634  int64_t pos = avio_tell(pb);
3635  avio_wb32(pb, 0); /* size */
3636  ffio_wfourcc(pb, "pitm");
3637  avio_wb32(pb, 0); /* Version & flags */
3638  avio_wb16(pb, item_id); /* item_id */
3639  return update_size(pb, pos);
3640 }
3641 
3643 {
3644  int64_t pos = avio_tell(pb);
3645  avio_wb32(pb, 0); /* size */
3646  ffio_wfourcc(pb, "iloc");
3647  avio_wb32(pb, 0); /* Version & flags */
3648  avio_w8(pb, (4 << 4) + 4); /* offset_size(4) and length_size(4) */
3649  avio_w8(pb, 0); /* base_offset_size(4) and reserved(4) */
3650  avio_wb16(pb, mov->nb_streams); /* item_count */
3651 
3652  for (int i = 0; i < mov->nb_streams; i++) {
3653  avio_wb16(pb, i + 1); /* item_id */
3654  avio_wb16(pb, 0); /* data_reference_index */
3655  avio_wb16(pb, 1); /* extent_count */
3656  mov->avif_extent_pos[i] = avio_tell(pb);
3657  avio_wb32(pb, 0); /* extent_offset (written later) */
3658  // For animated AVIF, we simply write the first packet's size.
3659  avio_wb32(pb, mov->avif_extent_length[i]); /* extent_length */
3660  }
3661 
3662  return update_size(pb, pos);
3663 }
3664 
3666 {
3667  int64_t iinf_pos = avio_tell(pb);
3668  avio_wb32(pb, 0); /* size */
3669  ffio_wfourcc(pb, "iinf");
3670  avio_wb32(pb, 0); /* Version & flags */
3671  avio_wb16(pb, mov->nb_streams); /* entry_count */
3672 
3673  for (int i = 0; i < mov->nb_streams; i++) {
3674  int64_t infe_pos = avio_tell(pb);
3675  avio_wb32(pb, 0); /* size */
3676  ffio_wfourcc(pb, "infe");
3677  avio_w8(pb, 0x2); /* Version */
3678  avio_wb24(pb, 0); /* flags */
3679  avio_wb16(pb, i + 1); /* item_id */
3680  avio_wb16(pb, 0); /* item_protection_index */
3681  avio_write(pb, "av01", 4); /* item_type */
3682  avio_write(pb, !i ? "Color\0" : "Alpha\0", 6); /* item_name */
3683  update_size(pb, infe_pos);
3684  }
3685 
3686  return update_size(pb, iinf_pos);
3687 }
3688 
3689 
3691 {
3692  int64_t auxl_pos;
3693  int64_t iref_pos = avio_tell(pb);
3694  avio_wb32(pb, 0); /* size */
3695  ffio_wfourcc(pb, "iref");
3696  avio_wb32(pb, 0); /* Version & flags */
3697 
3698  auxl_pos = avio_tell(pb);
3699  avio_wb32(pb, 0); /* size */
3700  ffio_wfourcc(pb, "auxl");
3701  avio_wb16(pb, 2); /* from_item_ID */
3702  avio_wb16(pb, 1); /* reference_count */
3703  avio_wb16(pb, 1); /* to_item_ID */
3704  update_size(pb, auxl_pos);
3705 
3706  return update_size(pb, iref_pos);
3707 }
3708 
3710  int stream_index)
3711 {
3712  int64_t pos = avio_tell(pb);
3713  avio_wb32(pb, 0); /* size */
3714  ffio_wfourcc(pb, "ispe");
3715  avio_wb32(pb, 0); /* Version & flags */
3716  avio_wb32(pb, s->streams[stream_index]->codecpar->width); /* image_width */
3717  avio_wb32(pb, s->streams[stream_index]->codecpar->height); /* image_height */
3718  return update_size(pb, pos);
3719 }
3720 
3722  int stream_index)
3723 {
3724  int64_t pos = avio_tell(pb);
3725  const AVPixFmtDescriptor *pixdesc =
3726  av_pix_fmt_desc_get(s->streams[stream_index]->codecpar->format);
3727  avio_wb32(pb, 0); /* size */
3728  ffio_wfourcc(pb, "pixi");
3729  avio_wb32(pb, 0); /* Version & flags */
3730  avio_w8(pb, pixdesc->nb_components); /* num_channels */
3731  for (int i = 0; i < pixdesc->nb_components; ++i) {
3732  avio_w8(pb, pixdesc->comp[i].depth); /* bits_per_channel */
3733  }
3734  return update_size(pb, pos);
3735 }
3736 
3738 {
3739  int64_t pos = avio_tell(pb);
3740  avio_wb32(pb, 0); /* size */
3741  ffio_wfourcc(pb, "ipco");
3742  for (int i = 0; i < mov->nb_streams; i++) {
3743  mov_write_ispe_tag(pb, mov, s, i);
3744  mov_write_pixi_tag(pb, mov, s, i);
3745  mov_write_av1c_tag(pb, &mov->tracks[i]);
3746  if (!i)
3747  mov_write_colr_tag(pb, &mov->tracks[0], 0);
3748  else
3749  mov_write_aux_tag(pb, "auxC");
3750  }
3751  return update_size(pb, pos);
3752 }
3753 
3755 {
3756  int64_t pos = avio_tell(pb);
3757  avio_wb32(pb, 0); /* size */
3758  ffio_wfourcc(pb, "ipma");
3759  avio_wb32(pb, 0); /* Version & flags */
3760  avio_wb32(pb, mov->nb_streams); /* entry_count */
3761 
3762  for (int i = 0, index = 1; i < mov->nb_streams; i++) {
3763  avio_wb16(pb, i + 1); /* item_ID */
3764  avio_w8(pb, 4); /* association_count */
3765 
3766  // ispe association.
3767  avio_w8(pb, index++); /* essential and property_index */
3768  // pixi association.
3769  avio_w8(pb, index++); /* essential and property_index */
3770  // av1C association.
3771  avio_w8(pb, 0x80 | index++); /* essential and property_index */
3772  // colr/auxC association.
3773  avio_w8(pb, index++); /* essential and property_index */
3774  }
3775  return update_size(pb, pos);
3776 }
3777 
3779 {
3780  int64_t pos = avio_tell(pb);
3781  avio_wb32(pb, 0); /* size */
3782  ffio_wfourcc(pb, "iprp");
3783  mov_write_ipco_tag(pb, mov, s);
3784  mov_write_ipma_tag(pb, mov, s);
3785  return update_size(pb, pos);
3786 }
3787 
3789 {
3790  /* This atom must be present, but leaving the values at zero
3791  * seems harmless. */
3792  avio_wb32(pb, 28); /* size */
3793  ffio_wfourcc(pb, "hmhd");
3794  avio_wb32(pb, 0); /* version, flags */
3795  avio_wb16(pb, 0); /* maxPDUsize */
3796  avio_wb16(pb, 0); /* avgPDUsize */
3797  avio_wb32(pb, 0); /* maxbitrate */
3798  avio_wb32(pb, 0); /* avgbitrate */
3799  avio_wb32(pb, 0); /* reserved */
3800  return 28;
3801 }
3802 
3804 {
3805  int64_t pos = avio_tell(pb);
3806  int ret;
3807 
3808  avio_wb32(pb, 0); /* size */
3809  ffio_wfourcc(pb, "minf");
3810  if (track->par->codec_type == AVMEDIA_TYPE_VIDEO)
3811  mov_write_vmhd_tag(pb);
3812  else if (track->par->codec_type == AVMEDIA_TYPE_AUDIO)
3813  mov_write_smhd_tag(pb);
3814  else if (track->par->codec_type == AVMEDIA_TYPE_SUBTITLE) {
3815  if (track->tag == MKTAG('t','e','x','t') || is_clcp_track(track)) {
3816  mov_write_gmhd_tag(pb, track);
3817  } else if (track->tag == MOV_MP4_TTML_TAG) {
3818  mov_write_sthd_tag(pb);
3819  } else {
3820  mov_write_nmhd_tag(pb);
3821  }
3822  } else if (track->tag == MKTAG('r','t','p',' ')) {
3823  mov_write_hmhd_tag(pb);
3824  } else if (track->tag == MKTAG('t','m','c','d')) {
3825  if (track->mode != MODE_MOV)
3826  mov_write_nmhd_tag(pb);
3827  else
3828  mov_write_gmhd_tag(pb, track);
3829  } else if (track->tag == MKTAG('g','p','m','d')) {
3830  mov_write_gmhd_tag(pb, track);
3831  }
3832  if (track->mode == MODE_MOV) /* ISO 14496-12 8.4.3.1 specifies hdlr only within mdia or meta boxes */
3833  mov_write_hdlr_tag(s, pb, NULL);
3834  mov_write_dinf_tag(pb);
3835  if ((ret = mov_write_stbl_tag(s, pb, mov, track)) < 0)
3836  return ret;
3837  return update_size(pb, pos);
3838 }
3839 
3840 static void get_pts_range(MOVMuxContext *mov, MOVTrack *track,
3841  int64_t *start, int64_t *end, int elst)
3842 {
3843  if (track->tag == MKTAG('t','m','c','d') && mov->nb_meta_tmcd && track->nb_src_track) {
3844  // tmcd tracks gets track_duration set in mov_write_moov_tag from
3845  // another track's duration, while the end_pts may be left at zero.
3846  // Calculate the pts duration for that track instead.
3847  get_pts_range(mov, &mov->tracks[*track->src_track], start, end, elst);
3848  *start = av_rescale(*start, track->timescale,
3849  mov->tracks[*track->src_track].timescale);
3850  *end = av_rescale(*end, track->timescale,
3851  mov->tracks[*track->src_track].timescale);
3852  return;
3853  }
3854  if (track->end_pts != AV_NOPTS_VALUE &&
3855  track->start_dts != AV_NOPTS_VALUE &&
3856  track->start_cts != AV_NOPTS_VALUE) {
3857  *start = track->start_dts + track->start_cts;
3858  *end = elst ? track->elst_end_pts : track->end_pts;
3859  return;
3860  }
3861  *start = 0;
3862  *end = track->track_duration;
3863 }
3864 
3866 {
3867  int64_t start, end;
3868  get_pts_range(mov, track, &start, &end, 0);
3869  return end - start;
3870 }
3871 
3872 // Calculate the actual duration of the track, after edits.
3873 // If it starts with a pts < 0, that is removed by the edit list.
3874 // If it starts with a pts > 0, the edit list adds a delay before that.
3875 // Thus, with edit lists enabled, the post-edit output of the file is
3876 // starting with pts=0.
3878 {
3879  int64_t start, end;
3880  get_pts_range(mov, track, &start, &end, 0);
3881  if (mov->use_editlist != 0)
3882  start = 0;
3883  return end - start;
3884 }
3885 
3887 {
3888  int64_t start, end;
3889  get_pts_range(mov, track, &start, &end, 1);
3890  return end - start;
3891 }
3892 
3894 {
3895  if (track && track->mode == MODE_ISM)
3896  return 1;
3897  if (duration < INT32_MAX)
3898  return 0;
3899  return 1;
3900 }
3901 
3903  MOVTrack *track)
3904 {
3906  int version = mov_mdhd_mvhd_tkhd_version(mov, track, duration);
3907 
3908  (version == 1) ? avio_wb32(pb, 44) : avio_wb32(pb, 32); /* size */
3909  ffio_wfourcc(pb, "mdhd");
3910  avio_w8(pb, version);
3911  avio_wb24(pb, 0); /* flags */
3912  if (version == 1) {
3913  avio_wb64(pb, track->time);
3914  avio_wb64(pb, track->time);
3915  } else {
3916  avio_wb32(pb, track->time); /* creation time */
3917  avio_wb32(pb, track->time); /* modification time */
3918  }
3919  avio_wb32(pb, track->timescale); /* time scale (sample rate for audio) */
3920  if (!track->entry && mov->mode == MODE_ISM)
3921  (version == 1) ? avio_wb64(pb, UINT64_C(0xffffffffffffffff)) : avio_wb32(pb, 0xffffffff);
3922  else if (!track->entry)
3923  (version == 1) ? avio_wb64(pb, 0) : avio_wb32(pb, 0);
3924  else
3925  (version == 1) ? avio_wb64(pb, duration) : avio_wb32(pb, duration); /* duration */
3926  avio_wb16(pb, track->language); /* language */
3927  avio_wb16(pb, 0); /* reserved (quality) */
3928 
3929  if (version != 0 && track->mode == MODE_MOV) {
3931  "FATAL error, file duration too long for timebase, this file will not be\n"
3932  "playable with QuickTime. Choose a different timebase with "
3933  "-video_track_timescale or a different container format\n");
3934  }
3935 
3936  return 32;
3937 }
3938 
3940  MOVMuxContext *mov, MOVTrack *track)
3941 {
3942  int64_t pos = avio_tell(pb);
3943  int ret;
3944 
3945  avio_wb32(pb, 0); /* size */
3946  ffio_wfourcc(pb, "mdia");
3947  mov_write_mdhd_tag(pb, mov, track);
3948  mov_write_hdlr_tag(s, pb, track);
3949  if ((ret = mov_write_minf_tag(s, pb, mov, track)) < 0)
3950  return ret;
3951  return update_size(pb, pos);
3952 }
3953 
3954 /* transformation matrix
3955  |a b u|
3956  |c d v|
3957  |tx ty w| */
3958 static void write_matrix(AVIOContext *pb, int16_t a, int16_t b, int16_t c,
3959  int16_t d, int16_t tx, int16_t ty)
3960 {
3961  avio_wb32(pb, a << 16); /* 16.16 format */
3962  avio_wb32(pb, b << 16); /* 16.16 format */
3963  avio_wb32(pb, 0); /* u in 2.30 format */
3964  avio_wb32(pb, c << 16); /* 16.16 format */
3965  avio_wb32(pb, d << 16); /* 16.16 format */
3966  avio_wb32(pb, 0); /* v in 2.30 format */
3967  avio_wb32(pb, tx << 16); /* 16.16 format */
3968  avio_wb32(pb, ty << 16); /* 16.16 format */
3969  avio_wb32(pb, 1 << 30); /* w in 2.30 format */
3970 }
3971 
3973  MOVTrack *track, AVStream *st)
3974 {
3976  mov->movie_timescale, track->timescale,
3977  AV_ROUND_UP);
3978  int version;
3980  int group = 0;
3981 
3982  uint32_t *display_matrix = NULL;
3983  int i;
3984 
3985  if (mov->mode == MODE_AVIF)
3986  if (!mov->avif_loop_count)
3987  duration = INT64_MAX;
3988  else
3989  duration *= mov->avif_loop_count;
3990 
3991  if (st) {
3992  const AVPacketSideData *sd;
3993  if (mov->per_stream_grouping)
3994  group = st->index;
3995  else
3996  group = st->codecpar->codec_type;
3997 
4001  if (sd && sd->size == 9 * sizeof(*display_matrix))
4002  display_matrix = (uint32_t *)sd->data;
4003  }
4004 
4005  if (track->flags & MOV_TRACK_ENABLED)
4007 
4009 
4010  (version == 1) ? avio_wb32(pb, 104) : avio_wb32(pb, 92); /* size */
4011  ffio_wfourcc(pb, "tkhd");
4012  avio_w8(pb, version);
4013  avio_wb24(pb, flags);
4014  if (version == 1) {
4015  avio_wb64(pb, track->time);
4016  avio_wb64(pb, track->time);
4017  } else {
4018  avio_wb32(pb, track->time); /* creation time */
4019  avio_wb32(pb, track->time); /* modification time */
4020  }
4021  avio_wb32(pb, track->track_id); /* track-id */
4022  avio_wb32(pb, 0); /* reserved */
4023  if (!track->entry && mov->mode == MODE_ISM)
4024  (version == 1) ? avio_wb64(pb, UINT64_C(0xffffffffffffffff)) : avio_wb32(pb, 0xffffffff);
4025  else if (!track->entry)
4026  (version == 1) ? avio_wb64(pb, 0) : avio_wb32(pb, 0);
4027  else
4028  (version == 1) ? avio_wb64(pb, duration) : avio_wb32(pb, duration);
4029 
4030  avio_wb32(pb, 0); /* reserved */
4031  avio_wb32(pb, 0); /* reserved */
4032  avio_wb16(pb, 0); /* layer */
4033  avio_wb16(pb, group); /* alternate group) */
4034  /* Volume, only for audio */
4035  if (track->par->codec_type == AVMEDIA_TYPE_AUDIO)
4036  avio_wb16(pb, 0x0100);
4037  else
4038  avio_wb16(pb, 0);
4039  avio_wb16(pb, 0); /* reserved */
4040 
4041  /* Matrix structure */
4042  if (display_matrix) {
4043  for (i = 0; i < 9; i++)
4044  avio_wb32(pb, display_matrix[i]);
4045  } else {
4046  write_matrix(pb, 1, 0, 0, 1, 0, 0);
4047  }
4048  /* Track width and height, for visual only */
4049  if (st && (track->par->codec_type == AVMEDIA_TYPE_VIDEO ||
4050  track->par->codec_type == AVMEDIA_TYPE_SUBTITLE)) {
4051  int64_t track_width_1616;
4052  if (track->mode == MODE_MOV || track->mode == MODE_AVIF) {
4053  track_width_1616 = track->par->width * 0x10000ULL;
4054  } else {
4055  track_width_1616 = av_rescale(st->sample_aspect_ratio.num,
4056  track->par->width * 0x10000LL,
4057  st->sample_aspect_ratio.den);
4058  if (!track_width_1616 ||
4059  track->height != track->par->height ||
4060  track_width_1616 > UINT32_MAX)
4061  track_width_1616 = track->par->width * 0x10000ULL;
4062  }
4063  if (track_width_1616 > UINT32_MAX) {
4064  av_log(mov->fc, AV_LOG_WARNING, "track width is too large\n");
4065  track_width_1616 = 0;
4066  }
4067  avio_wb32(pb, track_width_1616);
4068  if (track->height > 0xFFFF) {
4069  av_log(mov->fc, AV_LOG_WARNING, "track height is too large\n");
4070  avio_wb32(pb, 0);
4071  } else
4072  avio_wb32(pb, track->height * 0x10000U);
4073  } else {
4074  avio_wb32(pb, 0);
4075  avio_wb32(pb, 0);
4076  }
4077  return 0x5c;
4078 }
4079 
4080 static int mov_write_tapt_tag(AVIOContext *pb, MOVTrack *track)
4081 {
4083  track->par->sample_aspect_ratio.den);
4084 
4085  int64_t pos = avio_tell(pb);
4086 
4087  avio_wb32(pb, 0); /* size */
4088  ffio_wfourcc(pb, "tapt");
4089 
4090  avio_wb32(pb, 20);
4091  ffio_wfourcc(pb, "clef");
4092  avio_wb32(pb, 0);
4093  avio_wb32(pb, width << 16);
4094  avio_wb32(pb, track->par->height << 16);
4095 
4096  avio_wb32(pb, 20);
4097  ffio_wfourcc(pb, "prof");
4098  avio_wb32(pb, 0);
4099  avio_wb32(pb, width << 16);
4100  avio_wb32(pb, track->par->height << 16);
4101 
4102  avio_wb32(pb, 20);
4103  ffio_wfourcc(pb, "enof");
4104  avio_wb32(pb, 0);
4105  avio_wb32(pb, track->par->width << 16);
4106  avio_wb32(pb, track->par->height << 16);
4107 
4108  return update_size(pb, pos);
4109 }
4110 
4111 // This box is written in the following cases:
4112 // * Seems important for the psp playback. Without it the movie seems to hang.
4113 // * Used for specifying the looping behavior of animated AVIF (as specified
4114 // in Section 9.6 of the HEIF specification ISO/IEC 23008-12).
4116  MOVTrack *track)
4117 {
4119  mov->movie_timescale, track->timescale,
4120  AV_ROUND_UP);
4121  int version = duration < INT32_MAX ? 0 : 1;
4122  int entry_size, entry_count, size;
4123  int64_t delay, start_ct = track->start_cts;
4124  int64_t start_dts = track->start_dts;
4125  int flags = 0;
4126 
4127  if (track->entry) {
4128  if (start_dts != track->cluster[0].dts || (start_ct != track->cluster[0].cts && track->cluster[0].dts >= 0)) {
4129 
4130  av_log(mov->fc, AV_LOG_DEBUG,
4131  "EDTS using dts:%"PRId64" cts:%d instead of dts:%"PRId64" cts:%"PRId64" tid:%d\n",
4132  track->cluster[0].dts, track->cluster[0].cts,
4133  start_dts, start_ct, track->track_id);
4134  start_dts = track->cluster[0].dts;
4135  start_ct = track->cluster[0].cts;
4136  }
4137  }
4138 
4139  delay = av_rescale_rnd(start_dts + start_ct, mov->movie_timescale,
4140  track->timescale, AV_ROUND_DOWN);
4141 
4142  if (mov->mode == MODE_AVIF) {
4143  delay = 0;
4144  // Section 9.6.3 of ISO/IEC 23008-12: flags specifies repetition of the
4145  // edit list as follows: (flags & 1) equal to 0 specifies that the edit
4146  // list is not repeated, while (flags & 1) equal to 1 specifies that the
4147  // edit list is repeated.
4148  flags = mov->avif_loop_count != 1;
4149  start_ct = 0;
4150  }
4151 
4152  version |= delay < INT32_MAX ? 0 : 1;
4153 
4154  entry_size = (version == 1) ? 20 : 12;
4155  entry_count = 1 + (delay > 0);
4156  size = 24 + entry_count * entry_size;
4157 
4158  /* write the atom data */
4159  avio_wb32(pb, size);
4160  ffio_wfourcc(pb, "edts");
4161  avio_wb32(pb, size - 8);
4162  ffio_wfourcc(pb, "elst");
4163  avio_w8(pb, version);
4164  avio_wb24(pb, flags); /* flags */
4165 
4166  avio_wb32(pb, entry_count);
4167  if (delay > 0) { /* add an empty edit to delay presentation */
4168  /* In the positive delay case, the delay includes the cts
4169  * offset, and the second edit list entry below trims out
4170  * the same amount from the actual content. This makes sure
4171  * that the offset last sample is included in the edit
4172  * list duration as well. */
4173  if (version == 1) {
4174  avio_wb64(pb, delay);
4175  avio_wb64(pb, -1);
4176  } else {
4177  avio_wb32(pb, delay);
4178  avio_wb32(pb, -1);
4179  }
4180  avio_wb32(pb, 0x00010000);
4181  } else if (mov->mode != MODE_AVIF) {
4182  /* Avoid accidentally ending up with start_ct = -1 which has got a
4183  * special meaning. Normally start_ct should end up positive or zero
4184  * here, but use FFMIN in case dts is a small positive integer
4185  * rounded to 0 when represented in movie timescale units. */
4186  av_assert0(av_rescale_rnd(start_dts, mov->movie_timescale, track->timescale, AV_ROUND_DOWN) <= 0);
4187  start_ct = -FFMIN(start_dts, 0);
4188 
4189 #if CONFIG_IAMFENC
4190  if (track->iamf && track->par->codec_id == AV_CODEC_ID_OPUS)
4191  start_ct = av_rescale(start_ct, 48000, track->par->sample_rate);
4192 #endif
4193  /* Note, this delay is calculated from the pts of the first sample,
4194  * ensuring that we don't reduce the duration for cases with
4195  * dts<0 pts=0. */
4196  duration += delay;
4197  }
4198 
4199  /* For fragmented files, we don't know the full length yet. Setting
4200  * duration to 0 allows us to only specify the offset, including
4201  * the rest of the content (from all future fragments) without specifying
4202  * an explicit duration.
4203  *
4204  * For hybrid_fragmented during mov_write_trailer (mov->moov_written != 0),
4205  * don't reset duration to zero.
4206  */
4207  if (mov->flags & FF_MOV_FLAG_FRAGMENT &&
4209  duration = 0;
4210 
4211  /* duration */
4212  if (version == 1) {
4213  avio_wb64(pb, duration);
4214  avio_wb64(pb, start_ct);
4215  } else {
4216  avio_wb32(pb, duration);
4217  avio_wb32(pb, start_ct);
4218  }
4219  avio_wb32(pb, 0x00010000);
4220  return size;
4221 }
4222 
4223 static int mov_write_tref_tag(AVIOContext *pb, MOVTrack *track)
4224 {
4225  int64_t pos = avio_tell(pb);
4226  avio_wb32(pb, 0); // size placeholder
4227  ffio_wfourcc(pb, "tref");
4228 
4229  for (int i = 0; i < track->nb_tref_tags; i++) {
4230  MovTag *tag = &track->tref_tags[i];
4231  avio_wb32(pb, 8 + tag->nb_id * sizeof(*tag->id)); // size (subatom)
4232  avio_wl32(pb, tag->name);
4233  for (int j = 0; j < tag->nb_id; j++)
4234  avio_wb32(pb, tag->id[j]);
4235  }
4236  return update_size(pb, pos);
4237 }
4238 
4239 // goes at the end of each track! ... Critical for PSP playback ("Incompatible data" without it)
4241 {
4242  avio_wb32(pb, 0x34); /* size ... reports as 28 in mp4box! */
4243  ffio_wfourcc(pb, "uuid");
4244  ffio_wfourcc(pb, "USMT");
4245  avio_wb32(pb, 0x21d24fce);
4246  avio_wb32(pb, 0xbb88695c);
4247  avio_wb32(pb, 0xfac9c740);
4248  avio_wb32(pb, 0x1c); // another size here!
4249  ffio_wfourcc(pb, "MTDT");
4250  avio_wb32(pb, 0x00010012);
4251  avio_wb32(pb, 0x0a);
4252  avio_wb32(pb, 0x55c40000);
4253  avio_wb32(pb, 0x1);
4254  avio_wb32(pb, 0x0);
4255  return 0x34;
4256 }
4257 
4258 static int mov_write_udta_sdp(AVIOContext *pb, MOVTrack *track)
4259 {
4260  AVFormatContext *ctx = track->rtp_ctx;
4261  char buf[1000] = "";
4262  int len;
4263 
4264  av_assert0(track->nb_src_track);
4265  ff_sdp_write_media(buf, sizeof(buf), ctx->streams[0], *track->src_track,
4266  NULL, NULL, 0, 0, ctx);
4267  av_strlcatf(buf, sizeof(buf), "a=control:streamid=%d\r\n", track->track_id);
4268  len = strlen(buf);
4269 
4270  avio_wb32(pb, len + 24);
4271  ffio_wfourcc(pb, "udta");
4272  avio_wb32(pb, len + 16);
4273  ffio_wfourcc(pb, "hnti");
4274  avio_wb32(pb, len + 8);
4275  ffio_wfourcc(pb, "sdp ");
4276  avio_write(pb, buf, len);
4277  return len + 24;
4278 }
4279 
4281  const char *tag, const char *str)
4282 {
4283  int64_t pos = avio_tell(pb);
4284  AVDictionaryEntry *t = av_dict_get(st->metadata, str, NULL, 0);
4285  if (!t || !utf8len(t->value))
4286  return 0;
4287 
4288  avio_wb32(pb, 0); /* size */
4289  ffio_wfourcc(pb, tag); /* type */
4290  avio_write(pb, t->value, strlen(t->value)); /* UTF8 string value */
4291  return update_size(pb, pos);
4292 }
4293 
4294 static int mov_write_track_kind(AVIOContext *pb, const char *scheme_uri,
4295  const char *value)
4296 {
4297  int64_t pos = avio_tell(pb);
4298 
4299  /* Box|FullBox basics */
4300  avio_wb32(pb, 0); /* size placeholder */
4301  ffio_wfourcc(pb, (const unsigned char *)"kind");
4302  avio_w8(pb, 0); /* version = 0 */
4303  avio_wb24(pb, 0); /* flags = 0 */
4304 
4305  /* Required null-terminated scheme URI */
4306  avio_write(pb, (const unsigned char *)scheme_uri,
4307  strlen(scheme_uri));
4308  avio_w8(pb, 0);
4309 
4310  /* Optional value string */
4311  if (value && value[0])
4312  avio_write(pb, (const unsigned char *)value,
4313  strlen(value));
4314 
4315  avio_w8(pb, 0);
4316 
4317  return update_size(pb, pos);
4318 }
4319 
4321 {
4322  int ret = AVERROR_BUG;
4323 
4324  for (int i = 0; ff_mov_track_kind_table[i].scheme_uri; i++) {
4326 
4327  for (int j = 0; map.value_maps[j].disposition; j++) {
4328  const struct MP4TrackKindValueMapping value_map = map.value_maps[j];
4329  if (!(st->disposition & value_map.disposition))
4330  continue;
4331 
4332  if ((ret = mov_write_track_kind(pb, map.scheme_uri, value_map.value)) < 0)
4333  return ret;
4334  }
4335  }
4336 
4337  return 0;
4338 }
4339 
4341  AVStream *st)
4342 {
4343  AVIOContext *pb_buf;
4344  int ret, size;
4345  uint8_t *buf;
4346 
4347  if (!st)
4348  return 0;
4349 
4350  ret = avio_open_dyn_buf(&pb_buf);
4351  if (ret < 0)
4352  return ret;
4353 
4354  if (mov->mode & (MODE_MP4|MODE_MOV))
4355  mov_write_track_metadata(pb_buf, st, "name", "title");
4356 
4357  if (mov->mode & MODE_MP4) {
4358  if ((ret = mov_write_track_kinds(pb_buf, st)) < 0)
4359  goto end;
4360  }
4361 
4362  if ((size = avio_get_dyn_buf(pb_buf, &buf)) > 0) {
4363  avio_wb32(pb, size + 8);
4364  ffio_wfourcc(pb, "udta");
4365  avio_write(pb, buf, size);
4366  }
4367 end:
4368  ffio_free_dyn_buf(&pb_buf);
4369 
4370  return ret;
4371 }
4372 
4374  MOVTrack *track, AVStream *st)
4375 {
4376  int64_t pos = avio_tell(pb);
4377  int entry_backup = track->entry;
4378  int chunk_backup = track->chunkCount;
4379  int ret;
4380 
4381  /* If we want to have an empty moov, but some samples already have been
4382  * buffered (delay_moov), pretend that no samples have been written yet. */
4383  if (mov->flags & FF_MOV_FLAG_EMPTY_MOOV)
4384  track->chunkCount = track->entry = 0;
4385 
4386  avio_wb32(pb, 0); /* size */
4387  ffio_wfourcc(pb, "trak");
4388  mov_write_tkhd_tag(pb, mov, track, st);
4389 
4390  av_assert2(mov->use_editlist >= 0);
4391 
4392  if (track->start_dts != AV_NOPTS_VALUE) {
4393  if (mov->use_editlist)
4394  mov_write_edts_tag(pb, mov, track); // PSP Movies and several other cases require edts box
4395  else if ((track->entry && track->cluster[0].dts) || track->mode == MODE_PSP || is_clcp_track(track))
4396  av_log(mov->fc, AV_LOG_WARNING,
4397  "Not writing any edit list even though one would have been required\n");
4398  }
4399 
4400  if (mov->is_animated_avif)
4401  mov_write_edts_tag(pb, mov, track);
4402 
4403  if (track->nb_tref_tags)
4404  mov_write_tref_tag(pb, track);
4405 
4406  if ((ret = mov_write_mdia_tag(s, pb, mov, track)) < 0)
4407  return ret;
4408  if (track->mode == MODE_PSP)
4409  mov_write_uuid_tag_psp(pb, track); // PSP Movies require this uuid box
4410  if (track->tag == MKTAG('r','t','p',' '))
4411  mov_write_udta_sdp(pb, track);
4412  if (track->mode == MODE_MOV) {
4413  if (track->par->codec_type == AVMEDIA_TYPE_VIDEO) {
4414  double sample_aspect_ratio = av_q2d(st->sample_aspect_ratio);
4415  if (st->sample_aspect_ratio.num && 1.0 != sample_aspect_ratio) {
4416  mov_write_tapt_tag(pb, track);
4417  }
4418  }
4419  if (is_clcp_track(track) && st->sample_aspect_ratio.num) {
4420  mov_write_tapt_tag(pb, track);
4421  }
4422  }
4423  mov_write_track_udta_tag(pb, mov, st);
4424  track->entry = entry_backup;
4425  track->chunkCount = chunk_backup;
4426  return update_size(pb, pos);
4427 }
4428 
4430 {
4431  int i, has_audio = 0, has_video = 0;
4432  int64_t pos = avio_tell(pb);
4433  int audio_profile = mov->iods_audio_profile;
4434  int video_profile = mov->iods_video_profile;
4435  for (i = 0; i < mov->nb_tracks; i++) {
4436  if (mov->tracks[i].entry > 0 || mov->flags & FF_MOV_FLAG_EMPTY_MOOV) {
4437  has_audio |= mov->tracks[i].par->codec_type == AVMEDIA_TYPE_AUDIO;
4438  has_video |= mov->tracks[i].par->codec_type == AVMEDIA_TYPE_VIDEO;
4439  }
4440  }
4441  if (audio_profile < 0)
4442  audio_profile = 0xFF - has_audio;
4443  if (video_profile < 0)
4444  video_profile = 0xFF - has_video;
4445  avio_wb32(pb, 0x0); /* size */
4446  ffio_wfourcc(pb, "iods");
4447  avio_wb32(pb, 0); /* version & flags */
4448  put_descr(pb, 0x10, 7);
4449  avio_wb16(pb, 0x004f);
4450  avio_w8(pb, 0xff);
4451  avio_w8(pb, 0xff);
4452  avio_w8(pb, audio_profile);
4453  avio_w8(pb, video_profile);
4454  avio_w8(pb, 0xff);
4455  return update_size(pb, pos);
4456 }
4457 
4458 static int mov_write_trex_tag(AVIOContext *pb, MOVTrack *track)
4459 {
4460  avio_wb32(pb, 0x20); /* size */
4461  ffio_wfourcc(pb, "trex");
4462  avio_wb32(pb, 0); /* version & flags */
4463  avio_wb32(pb, track->track_id); /* track ID */
4464  avio_wb32(pb, 1); /* default sample description index */
4465  avio_wb32(pb, 0); /* default sample duration */
4466  avio_wb32(pb, 0); /* default sample size */
4467  avio_wb32(pb, 0); /* default sample flags */
4468  return 0;
4469 }
4470 
4472 {
4473  int64_t pos = avio_tell(pb);
4474  int i;
4475  avio_wb32(pb, 0x0); /* size */
4476  ffio_wfourcc(pb, "mvex");
4477  for (i = 0; i < mov->nb_tracks; i++)
4478  mov_write_trex_tag(pb, &mov->tracks[i]);
4479  return update_size(pb, pos);
4480 }
4481 
4483 {
4484  int max_track_id = 1, i;
4485  int64_t max_track_len = 0;
4486  int version;
4487  int timescale;
4488 
4489  for (i = 0; i < mov->nb_tracks; i++) {
4490  if (mov->tracks[i].entry > 0 && mov->tracks[i].timescale) {
4491  int64_t max_track_len_temp = av_rescale_rnd(
4492  calc_pts_duration(mov, &mov->tracks[i]),
4493  mov->movie_timescale,
4494  mov->tracks[i].timescale,
4495  AV_ROUND_UP);
4496  if (max_track_len < max_track_len_temp)
4497  max_track_len = max_track_len_temp;
4498  if (max_track_id < mov->tracks[i].track_id)
4499  max_track_id = mov->tracks[i].track_id;
4500  }
4501  }
4502  /* If using delay_moov, make sure the output is the same as if no
4503  * samples had been written yet. */
4504  if (mov->flags & FF_MOV_FLAG_EMPTY_MOOV) {
4505  max_track_len = 0;
4506  max_track_id = 1;
4507  }
4508 
4509  version = mov_mdhd_mvhd_tkhd_version(mov, NULL, max_track_len);
4510  avio_wb32(pb, version == 1 ? 120 : 108); /* size */
4511 
4512  ffio_wfourcc(pb, "mvhd");
4513  avio_w8(pb, version);
4514  avio_wb24(pb, 0); /* flags */
4515  if (version == 1) {
4516  avio_wb64(pb, mov->time);
4517  avio_wb64(pb, mov->time);
4518  } else {
4519  avio_wb32(pb, mov->time); /* creation time */
4520  avio_wb32(pb, mov->time); /* modification time */
4521  }
4522 
4523  timescale = mov->movie_timescale;
4524  if (mov->mode == MODE_AVIF && !timescale)
4525  timescale = mov->tracks[0].timescale;
4526 
4527  avio_wb32(pb, timescale);
4528  (version == 1) ? avio_wb64(pb, max_track_len) : avio_wb32(pb, max_track_len); /* duration of longest track */
4529 
4530  avio_wb32(pb, 0x00010000); /* reserved (preferred rate) 1.0 = normal */
4531  avio_wb16(pb, 0x0100); /* reserved (preferred volume) 1.0 = normal */
4532  ffio_fill(pb, 0, 2 + 2 * 4); /* reserved */
4533 
4534  /* Matrix structure */
4535  write_matrix(pb, 1, 0, 0, 1, 0, 0);
4536 
4537  avio_wb32(pb, 0); /* reserved (preview time) */
4538  avio_wb32(pb, 0); /* reserved (preview duration) */
4539  avio_wb32(pb, 0); /* reserved (poster time) */
4540  avio_wb32(pb, 0); /* reserved (selection time) */
4541  avio_wb32(pb, 0); /* reserved (selection duration) */
4542  avio_wb32(pb, 0); /* reserved (current time) */
4543  avio_wb32(pb, max_track_id + 1); /* Next track id */
4544  return 0x6c;
4545 }
4546 
4548  AVFormatContext *s)
4549 {
4550  avio_wb32(pb, 33); /* size */
4551  ffio_wfourcc(pb, "hdlr");
4552  avio_wb32(pb, 0);
4553  avio_wb32(pb, 0);
4554  ffio_wfourcc(pb, "mdir");
4555  ffio_wfourcc(pb, "appl");
4556  avio_wb32(pb, 0);
4557  avio_wb32(pb, 0);
4558  avio_w8(pb, 0);
4559  return 33;
4560 }
4561 
4562 /* helper function to write a data tag with the specified string as data */
4563 static int mov_write_string_data_tag(AVIOContext *pb, const char *data, int lang, int long_style)
4564 {
4565  size_t data_len = strlen(data);
4566  if (long_style) {
4567  int size = 16 + data_len;
4568  avio_wb32(pb, size); /* size */
4569  ffio_wfourcc(pb, "data");
4570  avio_wb32(pb, 1);
4571  avio_wb32(pb, 0);
4572  avio_write(pb, data, data_len);
4573  return size;
4574  } else {
4575  avio_wb16(pb, data_len); /* string length */
4576  if (!lang)
4577  lang = ff_mov_iso639_to_lang("und", 1);
4578  avio_wb16(pb, lang);
4579  avio_write(pb, data, data_len);
4580  return data_len + 4;
4581  }
4582 }
4583 
4584 static int mov_write_string_tag(AVIOContext *pb, const char *name,
4585  const char *value, int lang, int long_style)
4586 {
4587  int size = 0;
4588  if (value && value[0]) {
4589  int64_t pos = avio_tell(pb);
4590  avio_wb32(pb, 0); /* size */
4591  ffio_wfourcc(pb, name);
4592  mov_write_string_data_tag(pb, value, lang, long_style);
4593  size = update_size(pb, pos);
4594  }
4595  return size;
4596 }
4597 
4598 static int mov_write_freeform_tag(AVIOContext *pb, const char *mean,
4599  const char *name, const char *data)
4600 {
4601  if (!data || !data[0])
4602  return 0;
4603 
4604  static const char stub_flags[4] = {0, 0, 0, 0};
4605 
4606  int64_t entry_pos = avio_tell(pb);
4607  avio_wb32(pb, 0); /* size */
4608  ffio_wfourcc(pb, "----"); /* freeform */
4609 
4610  size_t mean_len = strlen(mean);
4611  avio_wb32(pb, 12 + mean_len);
4612  ffio_wfourcc(pb, "mean");
4613  avio_write(pb, &stub_flags[0], sizeof(stub_flags));
4614  avio_write(pb, mean, mean_len);
4615 
4616  size_t name_len = strlen(name);
4617  avio_wb32(pb, 12 + name_len);
4618  ffio_wfourcc(pb, "name");
4619  avio_write(pb, &stub_flags[0], sizeof(stub_flags));
4620  avio_write(pb, name, name_len);
4621 
4622  mov_write_string_data_tag(pb, data, 0, 1);
4623 
4624  return update_size(pb, entry_pos);
4625 }
4626 
4628  const char *tag, int *lang)
4629 {
4630  int l, len, len2;
4631  AVDictionaryEntry *t, *t2 = NULL;
4632  char tag2[16];
4633 
4634  *lang = 0;
4635 
4636  if (!(t = av_dict_get(s->metadata, tag, NULL, 0)))
4637  return NULL;
4638 
4639  len = strlen(t->key);
4640  snprintf(tag2, sizeof(tag2), "%s-", tag);
4641  while ((t2 = av_dict_get(s->metadata, tag2, t2, AV_DICT_IGNORE_SUFFIX))) {
4642  len2 = strlen(t2->key);
4643  if (len2 == len + 4 && !strcmp(t->value, t2->value)
4644  && (l = ff_mov_iso639_to_lang(&t2->key[len2 - 3], 1)) >= 0) {
4645  *lang = l;
4646  return t;
4647  }
4648  }
4649  return t;
4650 }
4651 
4653  const char *name, const char *tag,
4654  int long_style)
4655 {
4656  int lang;
4657  AVDictionaryEntry *t = get_metadata_lang(s, tag, &lang);
4658  if (!t)
4659  return 0;
4660  return mov_write_string_tag(pb, name, t->value, lang, long_style);
4661 }
4662 
4664  const char *mean, const char *name,
4665  const char *tag)
4666 {
4667  AVDictionaryEntry *t = av_dict_get(s->metadata, tag, NULL, 0);
4668  if (!t)
4669  return 0;
4670  return mov_write_freeform_tag(pb, mean, name, t->value);
4671 }
4672 
4673 /* iTunes bpm number */
4675 {
4676  AVDictionaryEntry *t = av_dict_get(s->metadata, "tmpo", NULL, 0);
4677  int size = 0, tmpo = t ? atoi(t->value) : 0;
4678  if (tmpo) {
4679  size = 26;
4680  avio_wb32(pb, size);
4681  ffio_wfourcc(pb, "tmpo");
4682  avio_wb32(pb, size-8); /* size */
4683  ffio_wfourcc(pb, "data");
4684  avio_wb32(pb, 0x15); //type specifier
4685  avio_wb32(pb, 0);
4686  avio_wb16(pb, tmpo); // data
4687  }
4688  return size;
4689 }
4690 
4691 /* 3GPP TS 26.244 */
4693 {
4694  int lang;
4695  int64_t pos = avio_tell(pb);
4696  double latitude, longitude, altitude;
4697  int32_t latitude_fix, longitude_fix, altitude_fix;
4698  AVDictionaryEntry *t = get_metadata_lang(s, "location", &lang);
4699  const char *ptr, *place = "";
4700  char *end;
4701  static const char *astronomical_body = "earth";
4702  if (!t)
4703  return 0;
4704 
4705  ptr = t->value;
4706  latitude = strtod(ptr, &end);
4707  if (end == ptr) {
4708  av_log(s, AV_LOG_WARNING, "malformed location metadata\n");
4709  return 0;
4710  }
4711  ptr = end;
4712  longitude = strtod(ptr, &end);
4713  if (end == ptr) {
4714  av_log(s, AV_LOG_WARNING, "malformed location metadata\n");
4715  return 0;
4716  }
4717  ptr = end;
4718  altitude = strtod(ptr, &end);
4719  /* If no altitude was present, the default 0 should be fine */
4720  if (*end == '/')
4721  place = end + 1;
4722 
4723  latitude_fix = (int32_t) ((1 << 16) * latitude);
4724  longitude_fix = (int32_t) ((1 << 16) * longitude);
4725  altitude_fix = (int32_t) ((1 << 16) * altitude);
4726 
4727  avio_wb32(pb, 0); /* size */
4728  ffio_wfourcc(pb, "loci"); /* type */
4729  avio_wb32(pb, 0); /* version + flags */
4730  avio_wb16(pb, lang);
4731  avio_write(pb, place, strlen(place) + 1);
4732  avio_w8(pb, 0); /* role of place (0 == shooting location, 1 == real location, 2 == fictional location) */
4733  avio_wb32(pb, longitude_fix);
4734  avio_wb32(pb, latitude_fix);
4735  avio_wb32(pb, altitude_fix);
4736  avio_write(pb, astronomical_body, strlen(astronomical_body) + 1);
4737  avio_w8(pb, 0); /* additional notes, null terminated string */
4738 
4739  return update_size(pb, pos);
4740 }
4741 
4742 /* iTunes track or disc number */
4744  AVFormatContext *s, int disc)
4745 {
4746  AVDictionaryEntry *t = av_dict_get(s->metadata,
4747  disc ? "disc" : "track",
4748  NULL, 0);
4749  int size = 0, track = t ? atoi(t->value) : 0;
4750  if (track) {
4751  int tracks = 0;
4752  char *slash = strchr(t->value, '/');
4753  if (slash)
4754  tracks = atoi(slash + 1);
4755  avio_wb32(pb, 32); /* size */
4756  ffio_wfourcc(pb, disc ? "disk" : "trkn");
4757  avio_wb32(pb, 24); /* size */
4758  ffio_wfourcc(pb, "data");
4759  avio_wb32(pb, 0); // 8 bytes empty
4760  avio_wb32(pb, 0);
4761  avio_wb16(pb, 0); // empty
4762  avio_wb16(pb, track); // track / disc number
4763  avio_wb16(pb, tracks); // total track / disc number
4764  avio_wb16(pb, 0); // empty
4765  size = 32;
4766  }
4767  return size;
4768 }
4769 
4771  const char *name, const char *tag,
4772  int len)
4773 {
4774  AVDictionaryEntry *t = NULL;
4775  uint8_t num;
4776  int size = 24 + len;
4777 
4778  if (len != 1 && len != 4)
4779  return -1;
4780 
4781  if (!(t = av_dict_get(s->metadata, tag, NULL, 0)))
4782  return 0;
4783  num = atoi(t->value);
4784 
4785  avio_wb32(pb, size);
4786  ffio_wfourcc(pb, name);
4787  avio_wb32(pb, size - 8);
4788  ffio_wfourcc(pb, "data");
4789  avio_wb32(pb, 0x15);
4790  avio_wb32(pb, 0);
4791  if (len==4) avio_wb32(pb, num);
4792  else avio_w8 (pb, num);
4793 
4794  return size;
4795 }
4796 
4798 {
4799  MOVMuxContext *mov = s->priv_data;
4800  int64_t pos = 0;
4801 
4802  for (int i = 0; i < mov->nb_streams; i++) {
4803  MOVTrack *trk = &mov->tracks[i];
4804 
4805  if (!is_cover_image(trk->st) || trk->cover_image->size <= 0)
4806  continue;
4807 
4808  if (!pos) {
4809  pos = avio_tell(pb);
4810  avio_wb32(pb, 0);
4811  ffio_wfourcc(pb, "covr");
4812  }
4813  avio_wb32(pb, 16 + trk->cover_image->size);
4814  ffio_wfourcc(pb, "data");
4815  avio_wb32(pb, trk->tag);
4816  avio_wb32(pb , 0);
4817  avio_write(pb, trk->cover_image->data, trk->cover_image->size);
4818  }
4819 
4820  return pos ? update_size(pb, pos) : 0;
4821 }
4822 
4823 /* iTunes meta data list */
4825  AVFormatContext *s)
4826 {
4827  int64_t pos = avio_tell(pb);
4828  avio_wb32(pb, 0); /* size */
4829  ffio_wfourcc(pb, "ilst");
4830  mov_write_string_metadata(s, pb, "\251nam", "title" , 1);
4831  mov_write_string_metadata(s, pb, "\251ART", "artist" , 1);
4832  mov_write_string_metadata(s, pb, "aART", "album_artist", 1);
4833  mov_write_string_metadata(s, pb, "\251wrt", "composer" , 1);
4834  mov_write_string_metadata(s, pb, "\251alb", "album" , 1);
4835  mov_write_string_metadata(s, pb, "\251day", "date" , 1);
4836  if (!mov_write_string_metadata(s, pb, "\251too", "encoding_tool", 1)) {
4837  if (!(s->flags & AVFMT_FLAG_BITEXACT))
4838  mov_write_string_tag(pb, "\251too", LIBAVFORMAT_IDENT, 0, 1);
4839  }
4840  mov_write_string_metadata(s, pb, "\251cmt", "comment" , 1);
4841  mov_write_string_metadata(s, pb, "\251gen", "genre" , 1);
4842  mov_write_string_metadata(s, pb, "cprt", "copyright", 1);
4843  mov_write_string_metadata(s, pb, "\251grp", "grouping" , 1);
4844  mov_write_string_metadata(s, pb, "\251lyr", "lyrics" , 1);
4845  mov_write_string_metadata(s, pb, "desc", "description",1);
4846  mov_write_string_metadata(s, pb, "ldes", "synopsis" , 1);
4847  mov_write_string_metadata(s, pb, "tvsh", "show" , 1);
4848  mov_write_string_metadata(s, pb, "tven", "episode_id",1);
4849  mov_write_string_metadata(s, pb, "tvnn", "network" , 1);
4850  mov_write_string_metadata(s, pb, "keyw", "keywords" , 1);
4851  mov_write_int8_metadata (s, pb, "tves", "episode_sort",4);
4852  mov_write_int8_metadata (s, pb, "tvsn", "season_number",4);
4853  mov_write_int8_metadata (s, pb, "stik", "media_type",1);
4854  mov_write_int8_metadata (s, pb, "hdvd", "hd_video", 1);
4855  mov_write_int8_metadata (s, pb, "pgap", "gapless_playback",1);
4856  mov_write_int8_metadata (s, pb, "cpil", "compilation", 1);
4857  mov_write_covr(pb, s);
4858  mov_write_trkn_tag(pb, mov, s, 0); // track number
4859  mov_write_trkn_tag(pb, mov, s, 1); // disc number
4860  mov_write_tmpo_tag(pb, s);
4861  mov_write_custom_metadata(s, pb, "com.apple.iTunes", "DISCSUBTITLE", "disc_subtitle");
4862  return update_size(pb, pos);
4863 }
4864 
4866  AVFormatContext *s)
4867 {
4868  avio_wb32(pb, 33); /* size */
4869  ffio_wfourcc(pb, "hdlr");
4870  avio_wb32(pb, 0);
4871  avio_wb32(pb, 0);
4872  ffio_wfourcc(pb, "mdta");
4873  avio_wb32(pb, 0);
4874  avio_wb32(pb, 0);
4875  avio_wb32(pb, 0);
4876  avio_w8(pb, 0);
4877  return 33;
4878 }
4879 
4881  AVFormatContext *s)
4882 {
4883  const AVDictionaryEntry *t = NULL;
4884  int64_t pos = avio_tell(pb);
4885  int64_t curpos, entry_pos;
4886  int count = 0;
4887 
4888  avio_wb32(pb, 0); /* size */
4889  ffio_wfourcc(pb, "keys");
4890  avio_wb32(pb, 0);
4891  entry_pos = avio_tell(pb);
4892  avio_wb32(pb, 0); /* entry count */
4893 
4894  while (t = av_dict_iterate(s->metadata, t)) {
4895  size_t key_len = strlen(t->key);
4896  avio_wb32(pb, key_len + 8);
4897  ffio_wfourcc(pb, "mdta");
4898  avio_write(pb, t->key, key_len);
4899  count += 1;
4900  }
4901  curpos = avio_tell(pb);
4902  avio_seek(pb, entry_pos, SEEK_SET);
4903  avio_wb32(pb, count); // rewrite entry count
4904  avio_seek(pb, curpos, SEEK_SET);
4905 
4906  return update_size(pb, pos);
4907 }
4908 
4910  AVFormatContext *s)
4911 {
4912  const AVDictionaryEntry *t = NULL;
4913  int64_t pos = avio_tell(pb);
4914  int count = 1; /* keys are 1-index based */
4915 
4916  avio_wb32(pb, 0); /* size */
4917  ffio_wfourcc(pb, "ilst");
4918 
4919  while (t = av_dict_iterate(s->metadata, t)) {
4920  int64_t entry_pos = avio_tell(pb);
4921  avio_wb32(pb, 0); /* size */
4922  avio_wb32(pb, count); /* key */
4923  mov_write_string_data_tag(pb, t->value, 0, 1);
4924  update_size(pb, entry_pos);
4925  count += 1;
4926  }
4927  return update_size(pb, pos);
4928 }
4929 
4930 /* meta data tags */
4932  AVFormatContext *s)
4933 {
4934  int size = 0;
4935  int64_t pos = avio_tell(pb);
4936  avio_wb32(pb, 0); /* size */
4937  ffio_wfourcc(pb, "meta");
4938  avio_wb32(pb, 0);
4939  if (mov->flags & FF_MOV_FLAG_USE_MDTA) {
4940  mov_write_mdta_hdlr_tag(pb, mov, s);
4941  mov_write_mdta_keys_tag(pb, mov, s);
4942  mov_write_mdta_ilst_tag(pb, mov, s);
4943  } else if (mov->mode == MODE_AVIF) {
4944  mov_write_hdlr_tag(s, pb, &mov->tracks[0]);
4945  // We always write the primary item id as 1 since only one track is
4946  // supported for AVIF.
4947  mov_write_pitm_tag(pb, 1);
4948  mov_write_iloc_tag(pb, mov, s);
4949  mov_write_iinf_tag(pb, mov, s);
4950  if (mov->nb_streams > 1)
4951  mov_write_iref_tag(pb, mov, s);
4952  mov_write_iprp_tag(pb, mov, s);
4953  } else {
4954  /* iTunes metadata tag */
4955  mov_write_itunes_hdlr_tag(pb, mov, s);
4956  mov_write_ilst_tag(pb, mov, s);
4957  }
4958  size = update_size(pb, pos);
4959  return size;
4960 }
4961 
4963  const char *name, const char *key)
4964 {
4965  int len;
4966  AVDictionaryEntry *t;
4967 
4968  if (!(t = av_dict_get(s->metadata, key, NULL, 0)))
4969  return 0;
4970 
4971  len = strlen(t->value);
4972  if (len > 0) {
4973  int size = len + 8;
4974  avio_wb32(pb, size);
4975  ffio_wfourcc(pb, name);
4976  avio_write(pb, t->value, len);
4977  return size;
4978  }
4979  return 0;
4980 }
4981 
4982 static int ascii_to_wc(AVIOContext *pb, const uint8_t *b)
4983 {
4984  int val;
4985  while (*b) {
4986  GET_UTF8(val, *b++, return -1;)
4987  avio_wb16(pb, val);
4988  }
4989  avio_wb16(pb, 0x00);
4990  return 0;
4991 }
4992 
4993 static uint16_t language_code(const char *str)
4994 {
4995  return (((str[0] - 0x60) & 0x1F) << 10) +
4996  (((str[1] - 0x60) & 0x1F) << 5) +
4997  (( str[2] - 0x60) & 0x1F);
4998 }
4999 
5001  const char *tag, const char *str)
5002 {
5003  int64_t pos = avio_tell(pb);
5004  AVDictionaryEntry *t = av_dict_get(s->metadata, str, NULL, 0);
5005  if (!t || !utf8len(t->value))
5006  return 0;
5007  avio_wb32(pb, 0); /* size */
5008  ffio_wfourcc(pb, tag); /* type */
5009  avio_wb32(pb, 0); /* version + flags */
5010  if (!strcmp(tag, "yrrc"))
5011  avio_wb16(pb, atoi(t->value));
5012  else {
5013  avio_wb16(pb, language_code("eng")); /* language */
5014  avio_write(pb, t->value, strlen(t->value) + 1); /* UTF8 string value */
5015  if (!strcmp(tag, "albm") &&
5016  (t = av_dict_get(s->metadata, "track", NULL, 0)))
5017  avio_w8(pb, atoi(t->value));
5018  }
5019  return update_size(pb, pos);
5020 }
5021 
5023 {
5024  int64_t pos = avio_tell(pb);
5025  int i, nb_chapters = FFMIN(s->nb_chapters, 255);
5026 
5027  avio_wb32(pb, 0); // size
5028  ffio_wfourcc(pb, "chpl");
5029  avio_wb32(pb, 0x01000000); // version + flags
5030  avio_wb32(pb, 0); // unknown
5031  avio_w8(pb, nb_chapters);
5032 
5033  for (i = 0; i < nb_chapters; i++) {
5034  AVChapter *c = s->chapters[i];
5035  AVDictionaryEntry *t;
5036  avio_wb64(pb, av_rescale_q(c->start, c->time_base, (AVRational){1,10000000}));
5037 
5038  if ((t = av_dict_get(c->metadata, "title", NULL, 0))) {
5039  int len = FFMIN(strlen(t->value), 255);
5040  avio_w8(pb, len);
5041  avio_write(pb, t->value, len);
5042  } else
5043  avio_w8(pb, 0);
5044  }
5045  return update_size(pb, pos);
5046 }
5047 
5049  AVFormatContext *s)
5050 {
5051  AVIOContext *pb_buf;
5052  int ret, size;
5053  uint8_t *buf;
5054 
5055  ret = avio_open_dyn_buf(&pb_buf);
5056  if (ret < 0)
5057  return ret;
5058 
5059  if (mov->mode & MODE_3GP) {
5060  mov_write_3gp_udta_tag(pb_buf, s, "perf", "artist");
5061  mov_write_3gp_udta_tag(pb_buf, s, "titl", "title");
5062  mov_write_3gp_udta_tag(pb_buf, s, "auth", "author");
5063  mov_write_3gp_udta_tag(pb_buf, s, "gnre", "genre");
5064  mov_write_3gp_udta_tag(pb_buf, s, "dscp", "comment");
5065  mov_write_3gp_udta_tag(pb_buf, s, "albm", "album");
5066  mov_write_3gp_udta_tag(pb_buf, s, "cprt", "copyright");
5067  mov_write_3gp_udta_tag(pb_buf, s, "yrrc", "date");
5068  mov_write_loci_tag(s, pb_buf);
5069  } 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
5070  mov_write_string_metadata(s, pb_buf, "\251ART", "artist", 0);
5071  mov_write_string_metadata(s, pb_buf, "\251nam", "title", 0);
5072  mov_write_string_metadata(s, pb_buf, "\251aut", "author", 0);
5073  mov_write_string_metadata(s, pb_buf, "\251alb", "album", 0);
5074  mov_write_string_metadata(s, pb_buf, "\251day", "date", 0);
5075  mov_write_string_metadata(s, pb_buf, "\251swr", "encoder", 0);
5076  // currently ignored by mov.c
5077  mov_write_string_metadata(s, pb_buf, "\251des", "comment", 0);
5078  // add support for libquicktime, this atom is also actually read by mov.c
5079  mov_write_string_metadata(s, pb_buf, "\251cmt", "comment", 0);
5080  mov_write_string_metadata(s, pb_buf, "\251gen", "genre", 0);
5081  mov_write_string_metadata(s, pb_buf, "\251cpy", "copyright", 0);
5082  mov_write_string_metadata(s, pb_buf, "\251mak", "make", 0);
5083  mov_write_string_metadata(s, pb_buf, "\251mod", "model", 0);
5084  mov_write_string_metadata(s, pb_buf, "\251xyz", "location", 0);
5085  mov_write_string_metadata(s, pb_buf, "\251key", "keywords", 0);
5086  mov_write_raw_metadata_tag(s, pb_buf, "XMP_", "xmp");
5087  } else {
5088  /* iTunes meta data */
5089  mov_write_meta_tag(pb_buf, mov, s);
5090  mov_write_loci_tag(s, pb_buf);
5091  }
5092 
5093  if (s->nb_chapters && !(mov->flags & FF_MOV_FLAG_DISABLE_CHPL))
5094  mov_write_chpl_tag(pb_buf, s);
5095 
5096  if ((size = avio_get_dyn_buf(pb_buf, &buf)) > 0) {
5097  avio_wb32(pb, size + 8);
5098  ffio_wfourcc(pb, "udta");
5099  avio_write(pb, buf, size);
5100  }
5101  ffio_free_dyn_buf(&pb_buf);
5102 
5103  return 0;
5104 }
5105 
5107  const char *str, const char *lang, int type)
5108 {
5109  int len = utf8len(str) + 1;
5110  if (len <= 0)
5111  return;
5112  avio_wb16(pb, len * 2 + 10); /* size */
5113  avio_wb32(pb, type); /* type */
5114  avio_wb16(pb, language_code(lang)); /* language */
5115  avio_wb16(pb, 0x01); /* ? */
5116  ascii_to_wc(pb, str);
5117 }
5118 
5120 {
5121  AVDictionaryEntry *title = av_dict_get(s->metadata, "title", NULL, 0);
5122  int64_t pos, pos2;
5123 
5124  if (title) {
5125  pos = avio_tell(pb);
5126  avio_wb32(pb, 0); /* size placeholder*/
5127  ffio_wfourcc(pb, "uuid");
5128  ffio_wfourcc(pb, "USMT");
5129  avio_wb32(pb, 0x21d24fce); /* 96 bit UUID */
5130  avio_wb32(pb, 0xbb88695c);
5131  avio_wb32(pb, 0xfac9c740);
5132 
5133  pos2 = avio_tell(pb);
5134  avio_wb32(pb, 0); /* size placeholder*/
5135  ffio_wfourcc(pb, "MTDT");
5136  avio_wb16(pb, 4);
5137 
5138  // ?
5139  avio_wb16(pb, 0x0C); /* size */
5140  avio_wb32(pb, 0x0B); /* type */
5141  avio_wb16(pb, language_code("und")); /* language */
5142  avio_wb16(pb, 0x0); /* ? */
5143  avio_wb16(pb, 0x021C); /* data */
5144 
5145  if (!(s->flags & AVFMT_FLAG_BITEXACT))
5146  mov_write_psp_udta_tag(pb, LIBAVFORMAT_IDENT, "eng", 0x04);
5147  mov_write_psp_udta_tag(pb, title->value, "eng", 0x01);
5148  mov_write_psp_udta_tag(pb, "2006/04/01 11:11:11", "und", 0x03);
5149 
5150  update_size(pb, pos2);
5151  return update_size(pb, pos);
5152  }
5153 
5154  return 0;
5155 }
5156 
5158 {
5163  if (!sd)
5164  return 0;
5165 
5167  for (AVEncryptionInitInfo *copy = info; copy; copy = copy->next) {
5168  int64_t pos;
5169 
5170  if (!copy->data_size && !copy->num_key_ids)
5171  continue;
5172 
5173  pos = avio_tell(pb);
5174  avio_wb32(pb, 0); /* size placeholder */
5175  ffio_wfourcc(pb, "pssh");
5176  avio_w8(pb, 1); /* version */
5177  avio_wb24(pb, 0);
5178  for (int i = 0; i < copy->system_id_size; i++)
5179  avio_w8(pb, copy->system_id[i]);
5180  avio_wb32(pb, copy->num_key_ids);
5181  for (int i = 0; i < copy->num_key_ids; i++)
5182  for (int j = 0; j < copy->key_id_size; j++)
5183  avio_w8(pb, copy->key_ids[i][j]);
5184  avio_wb32(pb, copy->data_size);
5185  avio_write(pb, copy->data, copy->data_size);
5186  update_size(pb, pos);
5187  }
5188 
5190 
5191  return 0;
5192 }
5193 
5194 static void build_chunks(MOVTrack *trk)
5195 {
5196  int i;
5197  MOVIentry *chunk = &trk->cluster[0];
5198  uint64_t chunkSize = chunk->size;
5199  chunk->chunkNum = 1;
5200  if (trk->chunkCount)
5201  return;
5202  trk->chunkCount = 1;
5203  for (i = 1; i<trk->entry; i++){
5204  if (chunk->pos + chunkSize == trk->cluster[i].pos &&
5205  chunk->stsd_index == trk->cluster[i].stsd_index &&
5206  chunkSize + trk->cluster[i].size < (1<<20)){
5207  chunkSize += trk->cluster[i].size;
5208  chunk->samples_in_chunk += trk->cluster[i].entries;
5209  } else {
5210  trk->cluster[i].chunkNum = chunk->chunkNum+1;
5211  chunk=&trk->cluster[i];
5212  chunkSize = chunk->size;
5213  trk->chunkCount++;
5214  }
5215  }
5216 }
5217 
5218 /**
5219  * Assign track ids. If option "use_stream_ids_as_track_ids" is set,
5220  * the stream ids are used as track ids.
5221  *
5222  * This assumes mov->tracks and s->streams are in the same order and
5223  * there are no gaps in either of them (so mov->tracks[n] refers to
5224  * s->streams[n]).
5225  *
5226  * As an exception, there can be more entries in
5227  * s->streams than in mov->tracks, in which case new track ids are
5228  * generated (starting after the largest found stream id).
5229  */
5231 {
5232  int i;
5233 
5234  if (mov->track_ids_ok)
5235  return 0;
5236 
5237  if (mov->use_stream_ids_as_track_ids) {
5238  int next_generated_track_id = 0;
5239  for (i = 0; i < mov->nb_streams; i++) {
5240  AVStream *st = mov->tracks[i].st;
5241  if (st->id > next_generated_track_id)
5242  next_generated_track_id = st->id;
5243  }
5244 
5245  for (i = 0; i < mov->nb_tracks; i++) {
5246  if (mov->tracks[i].entry <= 0 && !(mov->flags & FF_MOV_FLAG_FRAGMENT))
5247  continue;
5248 
5249  mov->tracks[i].track_id = i >= mov->nb_streams ? ++next_generated_track_id : mov->tracks[i].st->id;
5250  }
5251  } else {
5252  int last_track_id = 0;
5253  for (i = 0; i < mov->nb_tracks; i++) {
5254  if (mov->tracks[i].entry <= 0 && !(mov->flags & FF_MOV_FLAG_FRAGMENT))
5255  continue;
5256 
5257  last_track_id =
5258  mov->tracks[i].track_id = (mov->tracks[i].st
5259  ? FFMAX(mov->tracks[i].st->index, last_track_id)
5260  : FFMAX(i, last_track_id)) + 1;
5261  }
5262  }
5263 
5264  mov->track_ids_ok = 1;
5265 
5266  return 0;
5267 }
5268 
5269 static int mov_find_tref_id(MOVMuxContext *mov, const MovTag *tag, uint32_t id)
5270 {
5271  for (int i = 0; i < tag->nb_id; i++) {
5272  if (tag->id[i] == id)
5273  return 1;
5274  }
5275  return 0;
5276 }
5277 
5278 static int mov_add_tref_id(MOVMuxContext *mov, MovTag *tag, uint32_t id)
5279 {
5280  int ret = mov_find_tref_id(mov, tag, id);
5281 
5282  if (!ret) {
5283  uint32_t *tmp = av_realloc_array(tag->id, tag->nb_id + 1, sizeof(*tag->id));
5284  if (!tmp)
5285  return AVERROR(ENOMEM);
5286  tag->id = tmp;
5287  tag->id[tag->nb_id++] = id;
5288  }
5289 
5290  return 0;
5291 }
5292 
5293 static MovTag *mov_find_tref_tag(MOVMuxContext *mov, const MOVTrack *trk, uint32_t name)
5294 {
5295  for (int i = 0; i < trk->nb_tref_tags; i++) {
5296  MovTag *entry = &trk->tref_tags[i];
5297 
5298  if (entry->name == name)
5299  return entry;
5300  }
5301  return NULL;
5302 }
5303 
5304 static MovTag *mov_add_tref_tag(MOVMuxContext *mov, MOVTrack *trk, uint32_t name)
5305 {
5306  MovTag *tag = mov_find_tref_tag(mov, trk, name);
5307 
5308  if (!tag) {
5309  MovTag *tmp = av_realloc_array(trk->tref_tags, trk->nb_tref_tags + 1,
5310  sizeof(*trk->tref_tags));
5311  if (!tmp)
5312  return NULL;
5313  trk->tref_tags = tmp;
5314  tag = &trk->tref_tags[trk->nb_tref_tags++];
5315  *tag = (MovTag){ .name = name };
5316  }
5317 
5318  return tag;
5319 }
5320 
5322  AVFormatContext *s)
5323 {
5324  int i;
5325  int64_t pos = avio_tell(pb);
5326  avio_wb32(pb, 0); /* size placeholder*/
5327  ffio_wfourcc(pb, "moov");
5328 
5329  mov_setup_track_ids(mov, s);
5330 
5331  for (i = 0; i < mov->nb_tracks; i++) {
5332  if (mov->tracks[i].entry <= 0 && !(mov->flags & FF_MOV_FLAG_FRAGMENT))
5333  continue;
5334 
5335  mov->tracks[i].time = mov->time;
5336 
5337  if (mov->tracks[i].entry)
5338  build_chunks(&mov->tracks[i]);
5339  }
5340 
5341  if (mov->chapter_track)
5342  for (i = 0; i < mov->nb_streams; i++) {
5343  MovTag *tag = mov_add_tref_tag(mov, &mov->tracks[i], MKTAG('c','h','a','p'));
5344  if (!tag)
5345  return AVERROR(ENOMEM);
5346 
5347  int ret = mov_add_tref_id(mov, tag, mov->tracks[mov->chapter_track].track_id);
5348  if (ret < 0)
5349  return ret;
5350  }
5351  for (i = 0; i < mov->nb_tracks; i++) {
5352  MOVTrack *track = &mov->tracks[i];
5353  if (track->tag == MKTAG('r','t','p',' ')) {
5354  MovTag *tag = mov_add_tref_tag(mov, track, MKTAG('h','i','n','t'));
5355  if (!tag)
5356  return AVERROR(ENOMEM);
5357 
5358  av_assert0(track->nb_src_track);
5359  int ret = mov_add_tref_id(mov, tag, mov->tracks[*track->src_track].track_id);
5360  if (ret < 0)
5361  return ret;
5362  } else if (track->tag == MKTAG('l','v','c','1') && track->nb_src_track) {
5363  MovTag *tag = mov_add_tref_tag(mov, track, MKTAG('s','b','a','s'));
5364  if (!tag)
5365  return AVERROR(ENOMEM);
5366 
5367  int ret = mov_add_tref_id(mov, tag, mov->tracks[*track->src_track].track_id);
5368  if (ret < 0)
5369  return ret;
5370  } else {
5371  if (track->par->codec_type == AVMEDIA_TYPE_AUDIO) {
5373  track->st->codecpar->nb_coded_side_data,
5375  if (sd && sd->size == sizeof(int)) {
5376  int *fallback = (int *)sd->data;
5377  if (*fallback >= 0 && *fallback < mov->nb_tracks) {
5378  MovTag *tag = mov_add_tref_tag(mov, track, MKTAG('f','a','l','l'));
5379  if (!tag)
5380  return AVERROR(ENOMEM);
5381 
5382  int ret = mov_add_tref_id(mov, tag, mov->tracks[*fallback].track_id);
5383  if (ret < 0)
5384  return ret;
5385  }
5386  }
5387  }
5388  for (int j = 0; j < track->nb_src_track; j++) {
5389  int src_trk = track->src_track[j];
5390  MovTag *tag = mov_add_tref_tag(mov, &mov->tracks[src_trk], track->tag);
5391  if (!tag)
5392  return AVERROR(ENOMEM);
5393  int ret = mov_add_tref_id(mov, tag, track->track_id);
5394  if (ret < 0)
5395  return ret;
5396  }
5397  if (track->nb_src_track) {
5398  /* Derive the duration from the first source track, matching
5399  * the convention used by get_pts_range() and the rtp/lvc1
5400  * branches above. The source may use a different timescale. */
5401  int src_trk = track->src_track[0];
5402  track->track_duration = av_rescale(mov->tracks[src_trk].track_duration,
5403  track->timescale,
5404  mov->tracks[src_trk].timescale);
5405  }
5406  }
5407  }
5408 
5409  mov_write_mvhd_tag(pb, mov);
5410  if (mov->mode != MODE_MOV && mov->mode != MODE_AVIF && !mov->iods_skip)
5411  mov_write_iods_tag(pb, mov);
5412  for (i = 0; i < mov->nb_tracks; i++) {
5413  if (mov->tracks[i].entry > 0 || mov->flags & FF_MOV_FLAG_FRAGMENT ||
5414  mov->mode == MODE_AVIF) {
5415  int ret = mov_write_trak_tag(s, pb, mov, &(mov->tracks[i]), i < mov->nb_streams ? mov->tracks[i].st : NULL);
5416  if (ret < 0)
5417  return ret;
5418  }
5419  }
5420  /* Don't write mvex for hybrid_fragmented during mov_write_trailer
5421  * (mov->moov_written != 0)
5422  */
5423  if (mov->flags & FF_MOV_FLAG_FRAGMENT &&
5425  mov_write_mvex_tag(pb, mov); /* QuickTime requires trak to precede this */
5426 
5427  if (mov->mode == MODE_PSP)
5429  else if (mov->mode != MODE_AVIF)
5430  mov_write_udta_tag(pb, mov, s);
5431  for (i = 0; i < mov->nb_streams; i++)
5432  mov_write_pssh_tag(pb, mov->tracks[i].st);
5433 
5434  return update_size(pb, pos);
5435 }
5436 
5437 static void param_write_int(AVIOContext *pb, const char *name, int value)
5438 {
5439  avio_printf(pb, "<param name=\"%s\" value=\"%d\" valuetype=\"data\"/>\n", name, value);
5440 }
5441 
5442 static void param_write_string(AVIOContext *pb, const char *name, const char *value)
5443 {
5444  avio_printf(pb, "<param name=\"%s\" value=\"%s\" valuetype=\"data\"/>\n", name, value);
5445 }
5446 
5447 static void param_write_hex(AVIOContext *pb, const char *name, const uint8_t *value, int len)
5448 {
5449  char buf[150];
5450  len = FFMIN(sizeof(buf) / 2 - 1, len);
5451  ff_data_to_hex(buf, value, len, 0);
5452  avio_printf(pb, "<param name=\"%s\" value=\"%s\" valuetype=\"data\"/>\n", name, buf);
5453 }
5454 
5456 {
5457  int64_t pos = avio_tell(pb);
5458  int i;
5459 
5460  static const AVUUID uuid = {
5461  0xa5, 0xd4, 0x0b, 0x30, 0xe8, 0x14, 0x11, 0xdd,
5462  0xba, 0x2f, 0x08, 0x00, 0x20, 0x0c, 0x9a, 0x66
5463  };
5464 
5465  avio_wb32(pb, 0);
5466  ffio_wfourcc(pb, "uuid");
5467  avio_write(pb, uuid, AV_UUID_LEN);
5468  avio_wb32(pb, 0);
5469 
5470  avio_printf(pb, "<?xml version=\"1.0\" encoding=\"utf-8\"?>\n");
5471  avio_printf(pb, "<smil xmlns=\"http://www.w3.org/2001/SMIL20/Language\">\n");
5472  avio_printf(pb, "<head>\n");
5473  if (!(mov->fc->flags & AVFMT_FLAG_BITEXACT))
5474  avio_printf(pb, "<meta name=\"creator\" content=\"%s\" />\n",
5476  avio_printf(pb, "</head>\n");
5477  avio_printf(pb, "<body>\n");
5478  avio_printf(pb, "<switch>\n");
5479 
5480  mov_setup_track_ids(mov, s);
5481 
5482  for (i = 0; i < mov->nb_tracks; i++) {
5483  MOVTrack *track = &mov->tracks[i];
5484  struct mpeg4_bit_rate_values bit_rates =
5486  const char *type;
5487  int track_id = track->track_id;
5488  char track_name_buf[32] = { 0 };
5489 
5490  AVStream *st = track->st;
5491  AVDictionaryEntry *lang = av_dict_get(st->metadata, "language", NULL,0);
5492 
5493  if (track->par->codec_type == AVMEDIA_TYPE_VIDEO && !is_cover_image(st)) {
5494  type = "video";
5495  } else if (track->par->codec_type == AVMEDIA_TYPE_AUDIO) {
5496  type = "audio";
5497  } else {
5498  continue;
5499  }
5500 
5501  avio_printf(pb, "<%s systemBitrate=\"%"PRIu32"\">\n", type,
5502  bit_rates.avg_bit_rate);
5503  param_write_int(pb, "systemBitrate", bit_rates.avg_bit_rate);
5504  param_write_int(pb, "trackID", track_id);
5505  param_write_string(pb, "systemLanguage", lang ? lang->value : "und");
5506 
5507  /* Build track name piece by piece: */
5508  /* 1. track type */
5509  av_strlcat(track_name_buf, type, sizeof(track_name_buf));
5510  /* 2. track language, if available */
5511  if (lang)
5512  av_strlcatf(track_name_buf, sizeof(track_name_buf),
5513  "_%s", lang->value);
5514  /* 3. special type suffix */
5515  /* "_cc" = closed captions, "_ad" = audio_description */
5517  av_strlcat(track_name_buf, "_cc", sizeof(track_name_buf));
5519  av_strlcat(track_name_buf, "_ad", sizeof(track_name_buf));
5520 
5521  param_write_string(pb, "trackName", track_name_buf);
5522 
5523  if (track->par->codec_type == AVMEDIA_TYPE_VIDEO) {
5524  if (track->par->codec_id == AV_CODEC_ID_H264) {
5525  uint8_t *ptr;
5526  int size = track->extradata_size[track->last_stsd_index];
5527  if (!ff_avc_write_annexb_extradata(track->extradata[track->last_stsd_index], &ptr,
5528  &size)) {
5529  param_write_hex(pb, "CodecPrivateData",
5530  ptr ? ptr : track->extradata[track->last_stsd_index],
5531  size);
5532  av_free(ptr);
5533  }
5534  param_write_string(pb, "FourCC", "H264");
5535  } else if (track->par->codec_id == AV_CODEC_ID_VC1) {
5536  param_write_string(pb, "FourCC", "WVC1");
5537  param_write_hex(pb, "CodecPrivateData", track->extradata[track->last_stsd_index],
5538  track->extradata_size[track->last_stsd_index]);
5539  }
5540  param_write_int(pb, "MaxWidth", track->par->width);
5541  param_write_int(pb, "MaxHeight", track->par->height);
5542  param_write_int(pb, "DisplayWidth", track->par->width);
5543  param_write_int(pb, "DisplayHeight", track->par->height);
5544  } else {
5545  if (track->par->codec_id == AV_CODEC_ID_AAC) {
5546  switch (track->par->profile) {
5547  case AV_PROFILE_AAC_HE_V2:
5548  param_write_string(pb, "FourCC", "AACP");
5549  break;
5550  case AV_PROFILE_AAC_HE:
5551  param_write_string(pb, "FourCC", "AACH");
5552  break;
5553  default:
5554  param_write_string(pb, "FourCC", "AACL");
5555  }
5556  } else if (track->par->codec_id == AV_CODEC_ID_WMAPRO) {
5557  param_write_string(pb, "FourCC", "WMAP");
5558  }
5559  param_write_hex(pb, "CodecPrivateData", track->extradata[track->last_stsd_index],
5560  track->extradata_size[track->last_stsd_index]);
5562  track->par->codec_id));
5563  param_write_int(pb, "Channels", track->par->ch_layout.nb_channels);
5564  param_write_int(pb, "SamplingRate", track->tag == MKTAG('i','a','m','f') ?
5565  0 : track->par->sample_rate);
5566  param_write_int(pb, "BitsPerSample", 16);
5567  param_write_int(pb, "PacketSize", track->par->block_align ?
5568  track->par->block_align : 4);
5569  }
5570  avio_printf(pb, "</%s>\n", type);
5571  }
5572  avio_printf(pb, "</switch>\n");
5573  avio_printf(pb, "</body>\n");
5574  avio_printf(pb, "</smil>\n");
5575 
5576  return update_size(pb, pos);
5577 }
5578 
5580 {
5581  avio_wb32(pb, 16);
5582  ffio_wfourcc(pb, "mfhd");
5583  avio_wb32(pb, 0);
5584  avio_wb32(pb, mov->fragments);
5585  return 0;
5586 }
5587 
5588 static uint32_t get_sample_flags(MOVTrack *track, MOVIentry *entry)
5589 {
5592 }
5593 
5595  MOVTrack *track, int64_t moof_offset)
5596 {
5597  int64_t pos = avio_tell(pb);
5600  if (!track->entry) {
5602  } else {
5604  }
5607  if (mov->flags & FF_MOV_FLAG_DEFAULT_BASE_MOOF) {
5610  }
5611  /* CMAF requires all values to be explicit in tfhd atoms */
5612  if (mov->flags & FF_MOV_FLAG_CMAF)
5614 
5615  /* Don't set a default sample size, the silverlight player refuses
5616  * to play files with that set. Don't set a default sample duration,
5617  * WMP freaks out if it is set. Don't set a base data offset, PIFF
5618  * file format says it MUST NOT be set. */
5619  if (track->mode == MODE_ISM)
5622 
5623  avio_wb32(pb, 0); /* size placeholder */
5624  ffio_wfourcc(pb, "tfhd");
5625  avio_w8(pb, 0); /* version */
5626  avio_wb24(pb, flags);
5627 
5628  avio_wb32(pb, track->track_id); /* track-id */
5630  avio_wb64(pb, moof_offset);
5631  if (flags & MOV_TFHD_STSD_ID) {
5632  avio_wb32(pb, 1);
5633  }
5635  track->default_duration = get_cluster_duration(track, 0);
5636  avio_wb32(pb, track->default_duration);
5637  }
5638  if (flags & MOV_TFHD_DEFAULT_SIZE) {
5639  track->default_size = track->entry ? track->cluster[0].size : 1;
5640  avio_wb32(pb, track->default_size);
5641  } else
5642  track->default_size = -1;
5643 
5644  if (flags & MOV_TFHD_DEFAULT_FLAGS) {
5645  /* Set the default flags based on the second sample, if available.
5646  * If the first sample is different, that can be signaled via a separate field. */
5647  if (track->entry > 1)
5648  track->default_sample_flags = get_sample_flags(track, &track->cluster[1]);
5649  else
5650  track->default_sample_flags =
5651  track->par->codec_type == AVMEDIA_TYPE_VIDEO ?
5654  avio_wb32(pb, track->default_sample_flags);
5655  }
5656 
5657  return update_size(pb, pos);
5658 }
5659 
5661  MOVTrack *track, int moof_size,
5662  int first, int end)
5663 {
5664  int64_t pos = avio_tell(pb);
5665  uint32_t flags = MOV_TRUN_DATA_OFFSET;
5666  int i;
5667 
5668  for (i = first; i < end; i++) {
5669  if (get_cluster_duration(track, i) != track->default_duration)
5671  if (track->cluster[i].size != track->default_size)
5673  if (i > first && get_sample_flags(track, &track->cluster[i]) != track->default_sample_flags)
5675  }
5676  if (!(flags & MOV_TRUN_SAMPLE_FLAGS) && track->entry > first &&
5677  get_sample_flags(track, &track->cluster[first]) != track->default_sample_flags)
5679  if (track->flags & MOV_TRACK_CTTS)
5681 
5682  avio_wb32(pb, 0); /* size placeholder */
5683  ffio_wfourcc(pb, "trun");
5685  avio_w8(pb, 1); /* version */
5686  else
5687  avio_w8(pb, 0); /* version */
5688  avio_wb24(pb, flags);
5689 
5690  avio_wb32(pb, end - first); /* sample count */
5691  if (mov->flags & FF_MOV_FLAG_OMIT_TFHD_OFFSET &&
5693  !mov->first_trun)
5694  avio_wb32(pb, 0); /* Later tracks follow immediately after the previous one */
5695  else
5696  avio_wb32(pb, moof_size + 8 + track->data_offset +
5697  track->cluster[first].pos); /* data offset */
5699  avio_wb32(pb, get_sample_flags(track, &track->cluster[first]));
5700 
5701  for (i = first; i < end; i++) {
5703  avio_wb32(pb, get_cluster_duration(track, i));
5705  avio_wb32(pb, track->cluster[i].size);
5707  avio_wb32(pb, get_sample_flags(track, &track->cluster[i]));
5708  if (flags & MOV_TRUN_SAMPLE_CTS)
5709  avio_wb32(pb, track->cluster[i].cts);
5710  }
5711 
5712  mov->first_trun = 0;
5713  return update_size(pb, pos);
5714 }
5715 
5716 static int mov_write_tfxd_tag(AVIOContext *pb, MOVTrack *track)
5717 {
5718  int64_t pos = avio_tell(pb);
5719  static const uint8_t uuid[] = {
5720  0x6d, 0x1d, 0x9b, 0x05, 0x42, 0xd5, 0x44, 0xe6,
5721  0x80, 0xe2, 0x14, 0x1d, 0xaf, 0xf7, 0x57, 0xb2
5722  };
5723 
5724  avio_wb32(pb, 0); /* size placeholder */
5725  ffio_wfourcc(pb, "uuid");
5726  avio_write(pb, uuid, AV_UUID_LEN);
5727  avio_w8(pb, 1);
5728  avio_wb24(pb, 0);
5729  avio_wb64(pb, track->cluster[0].dts + track->cluster[0].cts);
5730  avio_wb64(pb, track->end_pts -
5731  (track->cluster[0].dts + track->cluster[0].cts));
5732 
5733  return update_size(pb, pos);
5734 }
5735 
5737  MOVTrack *track, int entry)
5738 {
5739  int n = track->nb_frag_info - 1 - entry, i;
5740  int size = 8 + 16 + 4 + 1 + 16*n;
5741  static const uint8_t uuid[] = {
5742  0xd4, 0x80, 0x7e, 0xf2, 0xca, 0x39, 0x46, 0x95,
5743  0x8e, 0x54, 0x26, 0xcb, 0x9e, 0x46, 0xa7, 0x9f
5744  };
5745 
5746  if (entry < 0)
5747  return 0;
5748 
5749  avio_seek(pb, track->frag_info[entry].tfrf_offset, SEEK_SET);
5750  avio_wb32(pb, size);
5751  ffio_wfourcc(pb, "uuid");
5752  avio_write(pb, uuid, AV_UUID_LEN);
5753  avio_w8(pb, 1);
5754  avio_wb24(pb, 0);
5755  avio_w8(pb, n);
5756  for (i = 0; i < n; i++) {
5757  int index = entry + 1 + i;
5758  avio_wb64(pb, track->frag_info[index].time);
5759  avio_wb64(pb, track->frag_info[index].duration);
5760  }
5761  if (n < mov->ism_lookahead) {
5762  int free_size = 16 * (mov->ism_lookahead - n);
5763  avio_wb32(pb, free_size);
5764  ffio_wfourcc(pb, "free");
5765  ffio_fill(pb, 0, free_size - 8);
5766  }
5767 
5768  return 0;
5769 }
5770 
5772  MOVTrack *track)
5773 {
5774  int64_t pos = avio_tell(pb);
5775  int i;
5776  for (i = 0; i < mov->ism_lookahead; i++) {
5777  /* Update the tfrf tag for the last ism_lookahead fragments,
5778  * nb_frag_info - 1 is the next fragment to be written. */
5779  mov_write_tfrf_tag(pb, mov, track, track->nb_frag_info - 2 - i);
5780  }
5781  avio_seek(pb, pos, SEEK_SET);
5782  return 0;
5783 }
5784 
5785 static int mov_add_tfra_entries(AVIOContext *pb, MOVMuxContext *mov, int tracks,
5786  int size)
5787 {
5788  int i;
5789  for (i = 0; i < mov->nb_tracks; i++) {
5790  MOVTrack *track = &mov->tracks[i];
5792  if ((tracks >= 0 && i != tracks) || !track->entry)
5793  continue;
5794  track->nb_frag_info++;
5795  if (track->nb_frag_info >= track->frag_info_capacity) {
5796  unsigned new_capacity = track->nb_frag_info + MOV_FRAG_INFO_ALLOC_INCREMENT;
5797  if (av_reallocp_array(&track->frag_info,
5798  new_capacity,
5799  sizeof(*track->frag_info)))
5800  return AVERROR(ENOMEM);
5801  track->frag_info_capacity = new_capacity;
5802  }
5803  info = &track->frag_info[track->nb_frag_info - 1];
5804  info->offset = avio_tell(pb);
5805  info->size = size;
5806  // Try to recreate the original pts for the first packet
5807  // from the fields we have stored
5808  info->time = track->cluster[0].dts + track->cluster[0].cts;
5809  info->duration = track->end_pts -
5810  (track->cluster[0].dts + track->cluster[0].cts);
5811  // If the pts is less than zero, we will have trimmed
5812  // away parts of the media track using an edit list,
5813  // and the corresponding start presentation time is zero.
5814  if (info->time < 0) {
5815  info->duration += info->time;
5816  info->time = 0;
5817  }
5818  info->tfrf_offset = 0;
5819  mov_write_tfrf_tags(pb, mov, track);
5820  }
5821  return 0;
5822 }
5823 
5824 static void mov_prune_frag_info(MOVMuxContext *mov, int tracks, int max)
5825 {
5826  int i;
5827  for (i = 0; i < mov->nb_tracks; i++) {
5828  MOVTrack *track = &mov->tracks[i];
5829  if ((tracks >= 0 && i != tracks) || !track->entry)
5830  continue;
5831  if (track->nb_frag_info > max) {
5832  memmove(track->frag_info, track->frag_info + (track->nb_frag_info - max), max * sizeof(*track->frag_info));
5833  track->nb_frag_info = max;
5834  }
5835  }
5836 }
5837 
5838 static int mov_write_tfdt_tag(AVIOContext *pb, MOVTrack *track)
5839 {
5840  int64_t pos = avio_tell(pb);
5841 
5842  avio_wb32(pb, 0); /* size */
5843  ffio_wfourcc(pb, "tfdt");
5844  avio_w8(pb, 1); /* version */
5845  avio_wb24(pb, 0);
5846  avio_wb64(pb, track->cluster[0].dts - track->start_dts);
5847  return update_size(pb, pos);
5848 }
5849 
5851  MOVTrack *track, int64_t moof_offset,
5852  int moof_size)
5853 {
5854  int64_t pos = avio_tell(pb);
5855  int i, start = 0;
5856  avio_wb32(pb, 0); /* size placeholder */
5857  ffio_wfourcc(pb, "traf");
5858 
5859  mov_write_tfhd_tag(pb, mov, track, moof_offset);
5860  if (mov->mode != MODE_ISM)
5861  mov_write_tfdt_tag(pb, track);
5862  for (i = 1; i < track->entry; i++) {
5863  if (track->cluster[i].pos != track->cluster[i - 1].pos + track->cluster[i - 1].size) {
5864  mov_write_trun_tag(pb, mov, track, moof_size, start, i);
5865  start = i;
5866  }
5867  }
5868  mov_write_trun_tag(pb, mov, track, moof_size, start, track->entry);
5869  if (mov->mode == MODE_ISM) {
5870  mov_write_tfxd_tag(pb, track);
5871 
5872  if (mov->ism_lookahead) {
5873  int size = 16 + 4 + 1 + 16 * mov->ism_lookahead;
5874 
5875  if (track->nb_frag_info > 0) {
5876  MOVFragmentInfo *info = &track->frag_info[track->nb_frag_info - 1];
5877  if (!info->tfrf_offset)
5878  info->tfrf_offset = avio_tell(pb);
5879  }
5880  avio_wb32(pb, 8 + size);
5881  ffio_wfourcc(pb, "free");
5882  ffio_fill(pb, 0, size);
5883  }
5884  }
5885 
5886  if (track->cenc.aes_ctr && (mov->flags & FF_MOV_FLAG_FRAGMENT))
5887  ff_mov_cenc_write_stbl_atoms(&track->cenc, pb, moof_offset);
5888 
5889  return update_size(pb, pos);
5890 }
5891 
5893  int tracks, int moof_size)
5894 {
5895  int64_t pos = avio_tell(pb);
5896  int i;
5897 
5898  avio_wb32(pb, 0); /* size placeholder */
5899  ffio_wfourcc(pb, "moof");
5900  mov->first_trun = 1;
5901 
5902  mov_write_mfhd_tag(pb, mov);
5903  for (i = 0; i < mov->nb_tracks; i++) {
5904  MOVTrack *track = &mov->tracks[i];
5905  if (tracks >= 0 && i != tracks)
5906  continue;
5907  if (!track->entry)
5908  continue;
5909  if (track->cenc.aes_ctr && (mov->flags & FF_MOV_FLAG_FRAGMENT))
5910  mov_write_pssh_tag(pb, track->st);
5911  mov_write_traf_tag(pb, mov, track, pos, moof_size);
5912  }
5913 
5914  return update_size(pb, pos);
5915 }
5916 
5918  MOVTrack *track, int ref_size, int total_sidx_size)
5919 {
5920  int64_t pos = avio_tell(pb), offset_pos, end_pos;
5921  int64_t presentation_time, duration, offset;
5922  unsigned starts_with_SAP;
5923  int i, entries;
5924 
5925  if (track->entry) {
5926  entries = 1;
5927  presentation_time = track->cluster[0].dts + track->cluster[0].cts;
5928  duration = track->end_pts -
5929  (track->cluster[0].dts + track->cluster[0].cts);
5930  starts_with_SAP = track->cluster[0].flags & MOV_SYNC_SAMPLE;
5931 
5932  // pts<0 should be cut away using edts
5933  if (presentation_time < 0) {
5934  duration += presentation_time;
5935  presentation_time = 0;
5936  }
5937  } else {
5938  entries = track->nb_frag_info;
5939  if (entries <= 0)
5940  return 0;
5941  presentation_time = track->frag_info[0].time;
5942  }
5943 
5944  avio_wb32(pb, 0); /* size */
5945  ffio_wfourcc(pb, "sidx");
5946  avio_w8(pb, 1); /* version */
5947  avio_wb24(pb, 0);
5948  avio_wb32(pb, track->track_id); /* reference_ID */
5949  avio_wb32(pb, track->timescale); /* timescale */
5950  avio_wb64(pb, presentation_time); /* earliest_presentation_time */
5951  offset_pos = avio_tell(pb);
5952  avio_wb64(pb, 0); /* first_offset (offset to referenced moof) */
5953  avio_wb16(pb, 0); /* reserved */
5954 
5955  avio_wb16(pb, entries); /* reference_count */
5956  for (i = 0; i < entries; i++) {
5957  if (!track->entry) {
5958  if (i > 1 && track->frag_info[i].offset != track->frag_info[i - 1].offset + track->frag_info[i - 1].size) {
5959  av_log(NULL, AV_LOG_ERROR, "Non-consecutive fragments, writing incorrect sidx\n");
5960  }
5961  duration = track->frag_info[i].duration;
5962  ref_size = track->frag_info[i].size;
5963  starts_with_SAP = 1;
5964  }
5965  avio_wb32(pb, (0 << 31) | (ref_size & 0x7fffffff)); /* reference_type (0 = media) | referenced_size */
5966  avio_wb32(pb, duration); /* subsegment_duration */
5967  avio_wb32(pb, (starts_with_SAP << 31) | (0 << 28) | 0); /* starts_with_SAP | SAP_type | SAP_delta_time */
5968  }
5969 
5970  end_pos = avio_tell(pb);
5971  offset = pos + total_sidx_size - end_pos;
5972  avio_seek(pb, offset_pos, SEEK_SET);
5973  avio_wb64(pb, offset);
5974  avio_seek(pb, end_pos, SEEK_SET);
5975  return update_size(pb, pos);
5976 }
5977 
5979  int tracks, int ref_size)
5980 {
5981  int i, round, ret;
5982  AVIOContext *avio_buf;
5983  int total_size = 0;
5984  for (round = 0; round < 2; round++) {
5985  // First run one round to calculate the total size of all
5986  // sidx atoms.
5987  // This would be much simpler if we'd only write one sidx
5988  // atom, for the first track in the moof.
5989  if (round == 0) {
5990  if ((ret = ffio_open_null_buf(&avio_buf)) < 0)
5991  return ret;
5992  } else {
5993  avio_buf = pb;
5994  }
5995  for (i = 0; i < mov->nb_tracks; i++) {
5996  MOVTrack *track = &mov->tracks[i];
5997  if (tracks >= 0 && i != tracks)
5998  continue;
5999  // When writing a sidx for the full file, entry is 0, but
6000  // we want to include all tracks. ref_size is 0 in this case,
6001  // since we read it from frag_info instead.
6002  if (!track->entry && ref_size > 0)
6003  continue;
6004  total_size -= mov_write_sidx_tag(avio_buf, track, ref_size,
6005  total_size);
6006  }
6007  if (round == 0) {
6008  total_size = ffio_close_null_buf(avio_buf);
6009  if (total_size < 0)
6010  return total_size;
6011  }
6012  }
6013  return 0;
6014 }
6015 
6016 static int mov_write_prft_tag(AVIOContext *pb, MOVMuxContext *mov, int tracks)
6017 {
6018  int64_t pos = avio_tell(pb), pts_us, ntp_ts;
6019  MOVTrack *first_track;
6020  int flags = 24;
6021 
6022  /* PRFT should be associated with at most one track. So, choosing only the
6023  * first track. */
6024  if (tracks > 0)
6025  return 0;
6026  first_track = &(mov->tracks[0]);
6027 
6028  if (!first_track->entry) {
6029  av_log(mov->fc, AV_LOG_WARNING, "Unable to write PRFT, no entries in the track\n");
6030  return 0;
6031  }
6032 
6033  if (first_track->cluster[0].pts == AV_NOPTS_VALUE) {
6034  av_log(mov->fc, AV_LOG_WARNING, "Unable to write PRFT, first PTS is invalid\n");
6035  return 0;
6036  }
6037 
6038  if (mov->write_prft == MOV_PRFT_SRC_WALLCLOCK) {
6039  if (first_track->cluster[0].prft.wallclock) {
6040  /* Round the NTP time to whole milliseconds. */
6041  ntp_ts = ff_get_formatted_ntp_time((first_track->cluster[0].prft.wallclock / 1000) * 1000 +
6042  NTP_OFFSET_US);
6043  flags = first_track->cluster[0].prft.flags;
6044  } else
6046  } else if (mov->write_prft == MOV_PRFT_SRC_PTS) {
6047  pts_us = av_rescale_q(first_track->cluster[0].pts,
6048  first_track->st->time_base, AV_TIME_BASE_Q);
6049  ntp_ts = ff_get_formatted_ntp_time(pts_us + NTP_OFFSET_US);
6050  } else {
6051  av_log(mov->fc, AV_LOG_WARNING, "Unsupported PRFT box configuration: %d\n",
6052  mov->write_prft);
6053  return 0;
6054  }
6055 
6056  avio_wb32(pb, 0); // Size place holder
6057  ffio_wfourcc(pb, "prft"); // Type
6058  avio_w8(pb, 1); // Version
6059  avio_wb24(pb, flags); // Flags
6060  avio_wb32(pb, first_track->track_id); // reference track ID
6061  avio_wb64(pb, ntp_ts); // NTP time stamp
6062  avio_wb64(pb, first_track->cluster[0].pts); //media time
6063  return update_size(pb, pos);
6064 }
6065 
6066 static int mov_write_moof_tag(AVIOContext *pb, MOVMuxContext *mov, int tracks,
6067  int64_t mdat_size)
6068 {
6069  AVIOContext *avio_buf;
6070  int ret, moof_size;
6071 
6072  if ((ret = ffio_open_null_buf(&avio_buf)) < 0)
6073  return ret;
6074  mov_write_moof_tag_internal(avio_buf, mov, tracks, 0);
6075  moof_size = ffio_close_null_buf(avio_buf);
6076  if (moof_size < 0)
6077  return moof_size;
6078 
6079  if (mov->flags & FF_MOV_FLAG_DASH &&
6081  mov_write_sidx_tags(pb, mov, tracks, moof_size + 8 + mdat_size);
6082 
6083  if (mov->write_prft > MOV_PRFT_NONE && mov->write_prft < MOV_PRFT_NB)
6084  mov_write_prft_tag(pb, mov, tracks);
6085 
6086  if (mov->flags & FF_MOV_FLAG_GLOBAL_SIDX ||
6087  !(mov->flags & FF_MOV_FLAG_SKIP_TRAILER) ||
6088  mov->ism_lookahead) {
6089  if ((ret = mov_add_tfra_entries(pb, mov, tracks, moof_size + 8 + mdat_size)) < 0)
6090  return ret;
6091  if (!(mov->flags & FF_MOV_FLAG_GLOBAL_SIDX) &&
6093  mov_prune_frag_info(mov, tracks, mov->ism_lookahead + 1);
6094  }
6095  }
6096 
6097  return mov_write_moof_tag_internal(pb, mov, tracks, moof_size);
6098 }
6099 
6100 static int mov_write_tfra_tag(AVIOContext *pb, MOVTrack *track)
6101 {
6102  int64_t pos = avio_tell(pb);
6103  int i;
6104 
6105  avio_wb32(pb, 0); /* size placeholder */
6106  ffio_wfourcc(pb, "tfra");
6107  avio_w8(pb, 1); /* version */
6108  avio_wb24(pb, 0);
6109 
6110  avio_wb32(pb, track->track_id);
6111  avio_wb32(pb, 0); /* length of traf/trun/sample num */
6112  avio_wb32(pb, track->nb_frag_info);
6113  for (i = 0; i < track->nb_frag_info; i++) {
6114  avio_wb64(pb, track->frag_info[i].time);
6115  avio_wb64(pb, track->frag_info[i].offset + track->data_offset);
6116  avio_w8(pb, 1); /* traf number */
6117  avio_w8(pb, 1); /* trun number */
6118  avio_w8(pb, 1); /* sample number */
6119  }
6120 
6121  return update_size(pb, pos);
6122 }
6123 
6125 {
6126  AVIOContext *mfra_pb;
6127  int i, ret, sz;
6128  uint8_t *buf;
6129 
6130  ret = avio_open_dyn_buf(&mfra_pb);
6131  if (ret < 0)
6132  return ret;
6133 
6134  avio_wb32(mfra_pb, 0); /* size placeholder */
6135  ffio_wfourcc(mfra_pb, "mfra");
6136  /* An empty mfra atom is enough to indicate to the publishing point that
6137  * the stream has ended. */
6138  if (mov->flags & FF_MOV_FLAG_ISML)
6139  goto done_mfra;
6140 
6141  for (i = 0; i < mov->nb_tracks; i++) {
6142  MOVTrack *track = &mov->tracks[i];
6143  if (track->nb_frag_info)
6144  mov_write_tfra_tag(mfra_pb, track);
6145  }
6146 
6147  avio_wb32(mfra_pb, 16);
6148  ffio_wfourcc(mfra_pb, "mfro");
6149  avio_wb32(mfra_pb, 0); /* version + flags */
6150  avio_wb32(mfra_pb, avio_tell(mfra_pb) + 4);
6151 
6152 done_mfra:
6153 
6154  sz = update_size(mfra_pb, 0);
6155  ret = avio_get_dyn_buf(mfra_pb, &buf);
6156  avio_write(pb, buf, ret);
6157  ffio_free_dyn_buf(&mfra_pb);
6158 
6159  return sz;
6160 }
6161 
6163 {
6164  avio_wb32(pb, 8); // placeholder for extended size field (64 bit)
6165  ffio_wfourcc(pb, mov->mode == MODE_MOV ? "wide" : "free");
6166 
6167  mov->mdat_pos = avio_tell(pb);
6168  avio_wb32(pb, 0); /* size placeholder*/
6169  ffio_wfourcc(pb, "mdat");
6170  return 0;
6171 }
6172 
6174  int has_h264, int has_video, int write_minor)
6175 {
6176  MOVMuxContext *mov = s->priv_data;
6177  int minor = 0x200;
6178 
6179  if (mov->major_brand && strlen(mov->major_brand) >= 4)
6180  ffio_wfourcc(pb, mov->major_brand);
6181  else if (mov->mode == MODE_3GP) {
6182  ffio_wfourcc(pb, has_h264 ? "3gp6" : "3gp4");
6183  minor = has_h264 ? 0x100 : 0x200;
6184  } else if (mov->mode == MODE_AVIF) {
6185  ffio_wfourcc(pb, mov->is_animated_avif ? "avis" : "avif");
6186  minor = 0;
6187  } else if (mov->mode & MODE_3G2) {
6188  ffio_wfourcc(pb, has_h264 ? "3g2b" : "3g2a");
6189  minor = has_h264 ? 0x20000 : 0x10000;
6190  } else if (mov->mode == MODE_PSP)
6191  ffio_wfourcc(pb, "MSNV");
6192  else if (mov->mode == MODE_MP4 && mov->flags & FF_MOV_FLAG_FRAGMENT &&
6194  ffio_wfourcc(pb, "iso6"); // Required when using signed CTS offsets in trun boxes
6195  else if (mov->mode == MODE_MP4 && mov->flags & FF_MOV_FLAG_DEFAULT_BASE_MOOF)
6196  ffio_wfourcc(pb, "iso5"); // Required when using default-base-is-moof
6197  else if (mov->mode == MODE_MP4 && mov->flags & FF_MOV_FLAG_NEGATIVE_CTS_OFFSETS)
6198  ffio_wfourcc(pb, "iso4");
6199  else if (mov->mode == MODE_MP4)
6200  ffio_wfourcc(pb, "isom");
6201  else if (mov->mode == MODE_IPOD)
6202  ffio_wfourcc(pb, has_video ? "M4V ":"M4A ");
6203  else if (mov->mode == MODE_ISM)
6204  ffio_wfourcc(pb, "isml");
6205  else if (mov->mode == MODE_F4V)
6206  ffio_wfourcc(pb, "f4v ");
6207  else
6208  ffio_wfourcc(pb, "qt ");
6209 
6210  if (write_minor)
6211  avio_wb32(pb, minor);
6212 }
6213 
6215 {
6216  MOVMuxContext *mov = s->priv_data;
6217  int64_t pos = avio_tell(pb);
6218  int has_h264 = 0, has_av1 = 0, has_video = 0, has_dolby = 0, has_id3 = 0;
6219  int has_iamf = 0;
6220 
6221 #if CONFIG_IAMFENC
6222  for (int i = 0; i < s->nb_stream_groups; i++) {
6223  const AVStreamGroup *stg = s->stream_groups[i];
6224 
6227  has_iamf = 1;
6228  break;
6229  }
6230  }
6231 #endif
6232  for (int i = 0; i < mov->nb_streams; i++) {
6233  AVStream *st = mov->tracks[i].st;
6234  if (is_cover_image(st))
6235  continue;
6237  has_video = 1;
6238  if (st->codecpar->codec_id == AV_CODEC_ID_H264)
6239  has_h264 = 1;
6240  if (st->codecpar->codec_id == AV_CODEC_ID_AV1)
6241  has_av1 = 1;
6242  if (st->codecpar->codec_id == AV_CODEC_ID_AC3 ||
6248  has_dolby = 1;
6250  has_id3 = 1;
6251  }
6252 
6253  avio_wb32(pb, 0); /* size */
6254  ffio_wfourcc(pb, "ftyp");
6255 
6256  // Write major brand
6257  mov_write_ftyp_tag_internal(pb, s, has_h264, has_video, 1);
6258  // Write the major brand as the first compatible brand as well
6259  mov_write_ftyp_tag_internal(pb, s, has_h264, has_video, 0);
6260 
6261  // Write compatible brands, ensuring that we don't write the major brand as a
6262  // compatible brand a second time.
6263  if (mov->mode == MODE_ISM) {
6264  ffio_wfourcc(pb, "piff");
6265  } else if (mov->mode == MODE_AVIF) {
6266  const AVPixFmtDescriptor *pix_fmt_desc =
6267  av_pix_fmt_desc_get(s->streams[0]->codecpar->format);
6268  const int depth = pix_fmt_desc->comp[0].depth;
6269  if (mov->is_animated_avif) {
6270  // For animated AVIF, major brand is "avis". Add "avif" as a
6271  // compatible brand.
6272  ffio_wfourcc(pb, "avif");
6273  ffio_wfourcc(pb, "msf1");
6274  ffio_wfourcc(pb, "iso8");
6275  }
6276  ffio_wfourcc(pb, "mif1");
6277  ffio_wfourcc(pb, "miaf");
6278  if (depth == 8 || depth == 10) {
6279  // MA1B and MA1A brands are based on AV1 profile. Short hand for
6280  // computing that is based on chroma subsampling type. 420 chroma
6281  // subsampling is MA1B. 444 chroma subsampling is MA1A.
6282  if (!pix_fmt_desc->log2_chroma_w && !pix_fmt_desc->log2_chroma_h) {
6283  // 444 chroma subsampling.
6284  ffio_wfourcc(pb, "MA1A");
6285  } else {
6286  // 420 chroma subsampling.
6287  ffio_wfourcc(pb, "MA1B");
6288  }
6289  }
6290  } else if (mov->mode != MODE_MOV) {
6291  // We add tfdt atoms when fragmenting, signal this with the iso6 compatible
6292  // brand, if not already the major brand. This is compatible with users that
6293  // don't understand tfdt.
6294  if (mov->mode == MODE_MP4) {
6295  if (mov->flags & FF_MOV_FLAG_CMAF)
6296  ffio_wfourcc(pb, "cmfc");
6298  ffio_wfourcc(pb, "iso6");
6299  if (has_av1)
6300  ffio_wfourcc(pb, "av01");
6301  if (has_dolby)
6302  ffio_wfourcc(pb, "dby1");
6303  if (has_iamf)
6304  ffio_wfourcc(pb, "iamf");
6305  } else {
6306  if (mov->flags & FF_MOV_FLAG_FRAGMENT)
6307  ffio_wfourcc(pb, "iso6");
6309  ffio_wfourcc(pb, "iso5");
6310  else if (mov->flags & FF_MOV_FLAG_NEGATIVE_CTS_OFFSETS)
6311  ffio_wfourcc(pb, "iso4");
6312  }
6313  // Brands prior to iso5 can't be signaled when using default-base-is-moof
6314  if (!(mov->flags & FF_MOV_FLAG_DEFAULT_BASE_MOOF)) {
6315  // write isom for mp4 only if it it's not the major brand already.
6316  if (mov->mode != MODE_MP4 || mov->flags & FF_MOV_FLAG_NEGATIVE_CTS_OFFSETS)
6317  ffio_wfourcc(pb, "isom");
6318  ffio_wfourcc(pb, "iso2");
6319  if (has_h264)
6320  ffio_wfourcc(pb, "avc1");
6321  }
6322  }
6323 
6324  if (mov->mode == MODE_MP4)
6325  ffio_wfourcc(pb, "mp41");
6326 
6327  if (mov->flags & FF_MOV_FLAG_DASH && mov->flags & FF_MOV_FLAG_GLOBAL_SIDX)
6328  ffio_wfourcc(pb, "dash");
6329 
6330  if (has_id3)
6331  ffio_wfourcc(pb, "aid3");
6332 
6333  return update_size(pb, pos);
6334 }
6335 
6337 {
6338  AVStream *video_st = s->streams[0];
6339  AVCodecParameters *video_par = s->streams[0]->codecpar;
6340  AVCodecParameters *audio_par = s->streams[1]->codecpar;
6341  int audio_rate = audio_par->sample_rate;
6342  int64_t frame_rate = video_st->avg_frame_rate.den ?
6344  0;
6345  int audio_kbitrate = audio_par->bit_rate / 1000;
6346  int video_kbitrate = FFMIN(video_par->bit_rate / 1000, 800 - audio_kbitrate);
6347 
6348  if (frame_rate < 0 || frame_rate > INT32_MAX) {
6349  av_log(s, AV_LOG_ERROR, "Frame rate %f outside supported range\n", frame_rate / (double)0x10000);
6350  return AVERROR(EINVAL);
6351  }
6352 
6353  avio_wb32(pb, 0x94); /* size */
6354  ffio_wfourcc(pb, "uuid");
6355  ffio_wfourcc(pb, "PROF");
6356 
6357  avio_wb32(pb, 0x21d24fce); /* 96 bit UUID */
6358  avio_wb32(pb, 0xbb88695c);
6359  avio_wb32(pb, 0xfac9c740);
6360 
6361  avio_wb32(pb, 0x0); /* ? */
6362  avio_wb32(pb, 0x3); /* 3 sections ? */
6363 
6364  avio_wb32(pb, 0x14); /* size */
6365  ffio_wfourcc(pb, "FPRF");
6366  avio_wb32(pb, 0x0); /* ? */
6367  avio_wb32(pb, 0x0); /* ? */
6368  avio_wb32(pb, 0x0); /* ? */
6369 
6370  avio_wb32(pb, 0x2c); /* size */
6371  ffio_wfourcc(pb, "APRF"); /* audio */
6372  avio_wb32(pb, 0x0);
6373  avio_wb32(pb, 0x2); /* TrackID */
6374  ffio_wfourcc(pb, "mp4a");
6375  avio_wb32(pb, 0x20f);
6376  avio_wb32(pb, 0x0);
6377  avio_wb32(pb, audio_kbitrate);
6378  avio_wb32(pb, audio_kbitrate);
6379  avio_wb32(pb, audio_rate);
6380  avio_wb32(pb, audio_par->ch_layout.nb_channels);
6381 
6382  avio_wb32(pb, 0x34); /* size */
6383  ffio_wfourcc(pb, "VPRF"); /* video */
6384  avio_wb32(pb, 0x0);
6385  avio_wb32(pb, 0x1); /* TrackID */
6386  if (video_par->codec_id == AV_CODEC_ID_H264) {
6387  ffio_wfourcc(pb, "avc1");
6388  avio_wb16(pb, 0x014D);
6389  avio_wb16(pb, 0x0015);
6390  } else {
6391  ffio_wfourcc(pb, "mp4v");
6392  avio_wb16(pb, 0x0000);
6393  avio_wb16(pb, 0x0103);
6394  }
6395  avio_wb32(pb, 0x0);
6396  avio_wb32(pb, video_kbitrate);
6397  avio_wb32(pb, video_kbitrate);
6398  avio_wb32(pb, frame_rate);
6399  avio_wb32(pb, frame_rate);
6400  avio_wb16(pb, video_par->width);
6401  avio_wb16(pb, video_par->height);
6402  avio_wb32(pb, 0x010001); /* ? */
6403 
6404  return 0;
6405 }
6406 
6408 {
6409  MOVMuxContext *mov = s->priv_data;
6410  int i;
6411 
6412  mov_write_ftyp_tag(pb,s);
6413  if (mov->mode == MODE_PSP) {
6414  int video_streams_nb = 0, audio_streams_nb = 0, other_streams_nb = 0;
6415  for (i = 0; i < mov->nb_streams; i++) {
6416  AVStream *st = mov->tracks[i].st;
6417  if (is_cover_image(st))
6418  continue;
6420  video_streams_nb++;
6421  else if (st->codecpar->codec_type == AVMEDIA_TYPE_AUDIO)
6422  audio_streams_nb++;
6423  else
6424  other_streams_nb++;
6425  }
6426 
6427  if (video_streams_nb != 1 || audio_streams_nb != 1 || other_streams_nb) {
6428  av_log(s, AV_LOG_ERROR, "PSP mode need one video and one audio stream\n");
6429  return AVERROR(EINVAL);
6430  }
6431  return mov_write_uuidprof_tag(pb, s);
6432  }
6433  return 0;
6434 }
6435 
6436 static int mov_parse_mpeg2_frame(AVPacket *pkt, uint32_t *flags)
6437 {
6438  uint32_t c = -1;
6439  int i, closed_gop = 0;
6440 
6441  for (i = 0; i < pkt->size - 4; i++) {
6442  c = (c << 8) + pkt->data[i];
6443  if (c == 0x1b8) { // gop
6444  closed_gop = pkt->data[i + 4] >> 6 & 0x01;
6445  } else if (c == 0x100) { // pic
6446  int temp_ref = (pkt->data[i + 1] << 2) | (pkt->data[i + 2] >> 6);
6447  if (!temp_ref || closed_gop) // I picture is not reordered
6449  else
6451  break;
6452  }
6453  }
6454  return 0;
6455 }
6456 
6458 {
6459  const uint8_t *start, *next, *end = pkt->data + pkt->size;
6460  int seq = 0, entry = 0;
6461  int key = pkt->flags & AV_PKT_FLAG_KEY;
6462  start = find_next_marker(pkt->data, end);
6463  for (next = start; next < end; start = next) {
6464  next = find_next_marker(start + 4, end);
6465  switch (AV_RB32(start)) {
6466  case VC1_CODE_SEQHDR:
6467  seq = 1;
6468  break;
6469  case VC1_CODE_ENTRYPOINT:
6470  entry = 1;
6471  break;
6472  case VC1_CODE_SLICE:
6473  trk->vc1_info.slices = 1;
6474  break;
6475  }
6476  }
6477  if (!trk->entry && trk->vc1_info.first_packet_seen)
6478  trk->vc1_info.first_frag_written = 1;
6479  if (!trk->entry && !trk->vc1_info.first_frag_written) {
6480  /* First packet in first fragment */
6481  trk->vc1_info.first_packet_seq = seq;
6483  trk->vc1_info.first_packet_seen = 1;
6484  } else if ((seq && !trk->vc1_info.packet_seq) ||
6485  (entry && !trk->vc1_info.packet_entry)) {
6486  int i;
6487  for (i = 0; i < trk->entry; i++)
6488  trk->cluster[i].flags &= ~MOV_SYNC_SAMPLE;
6489  trk->has_keyframes = 0;
6490  if (seq)
6491  trk->vc1_info.packet_seq = 1;
6492  if (entry)
6493  trk->vc1_info.packet_entry = 1;
6494  if (!trk->vc1_info.first_frag_written) {
6495  /* First fragment */
6496  if ((!seq || trk->vc1_info.first_packet_seq) &&
6497  (!entry || trk->vc1_info.first_packet_entry)) {
6498  /* First packet had the same headers as this one, readd the
6499  * sync sample flag. */
6500  trk->cluster[0].flags |= MOV_SYNC_SAMPLE;
6501  trk->has_keyframes = 1;
6502  }
6503  }
6504  }
6505  if (trk->vc1_info.packet_seq && trk->vc1_info.packet_entry)
6506  key = seq && entry;
6507  else if (trk->vc1_info.packet_seq)
6508  key = seq;
6509  else if (trk->vc1_info.packet_entry)
6510  key = entry;
6511  if (key) {
6512  trk->cluster[trk->entry].flags |= MOV_SYNC_SAMPLE;
6513  trk->has_keyframes++;
6514  }
6515 }
6516 
6518 {
6519  int length;
6520 
6521  if (pkt->size < 8)
6522  return;
6523 
6524  length = (AV_RB16(pkt->data) & 0xFFF) * 2;
6525  if (length < 8 || length > pkt->size)
6526  return;
6527 
6528  if (AV_RB32(pkt->data + 4) == 0xF8726FBA) {
6529  trk->cluster[trk->entry].flags |= MOV_SYNC_SAMPLE;
6530  trk->has_keyframes++;
6531  }
6532 
6533  return;
6534 }
6535 
6537 {
6538  MOVMuxContext *mov = s->priv_data;
6539  int ret, buf_size;
6540  uint8_t *buf;
6541  int i, offset;
6542 
6543  if (!track->mdat_buf)
6544  return 0;
6545  if (!mov->mdat_buf) {
6546  if ((ret = avio_open_dyn_buf(&mov->mdat_buf)) < 0)
6547  return ret;
6548  }
6549  buf_size = avio_get_dyn_buf(track->mdat_buf, &buf);
6550 
6551  offset = avio_tell(mov->mdat_buf);
6552  avio_write(mov->mdat_buf, buf, buf_size);
6553  ffio_reset_dyn_buf(track->mdat_buf);
6554 
6555  for (i = track->entries_flushed; i < track->entry; i++)
6556  track->cluster[i].pos += offset;
6557  track->entries_flushed = track->entry;
6558  return 0;
6559 }
6560 
6562 {
6563  MOVMuxContext *mov = s->priv_data;
6564  AVPacket *squashed_packet = mov->pkt;
6565  int ret = AVERROR_BUG;
6566 
6567  switch (track->st->codecpar->codec_id) {
6568  case AV_CODEC_ID_TTML: {
6569  int had_packets = !!track->squashed_packet_queue.head;
6570 
6571  if ((ret = ff_mov_generate_squashed_ttml_packet(s, track, squashed_packet)) < 0) {
6572  goto finish_squash;
6573  }
6574 
6575  // We have generated a padding packet (no actual input packets in
6576  // queue) and its duration is zero. Skipping writing it.
6577  if (!had_packets && squashed_packet->duration == 0) {
6578  goto finish_squash;
6579  }
6580 
6581  track->end_reliable = 1;
6582  break;
6583  }
6584  default:
6585  ret = AVERROR(EINVAL);
6586  goto finish_squash;
6587  }
6588 
6589  squashed_packet->stream_index = track->st->index;
6590 
6591  ret = mov_write_single_packet(s, squashed_packet);
6592 
6593 finish_squash:
6594  av_packet_unref(squashed_packet);
6595 
6596  return ret;
6597 }
6598 
6600 {
6601  MOVMuxContext *mov = s->priv_data;
6602 
6603  for (int i = 0; i < mov->nb_streams; i++) {
6604  MOVTrack *track = &mov->tracks[i];
6605  int ret = AVERROR_BUG;
6606 
6607  if (track->squash_fragment_samples_to_one && !track->entry) {
6608  if ((ret = mov_write_squashed_packet(s, track)) < 0) {
6610  "Failed to write squashed packet for %s stream with "
6611  "index %d and track id %d. Error: %s\n",
6613  track->st->index, track->track_id,
6614  av_err2str(ret));
6615  return ret;
6616  }
6617  }
6618  }
6619 
6620  return 0;
6621 }
6622 
6624  int64_t ref_pos)
6625 {
6626  int i;
6627  if (!track->entry)
6628  return 0;
6629  if (mov->flags & FF_MOV_FLAG_HYBRID_FRAGMENTED) {
6630  for (i = 0; i < track->entry; i++)
6631  track->cluster[i].pos += ref_pos + track->data_offset;
6632  if (track->cluster_written == 0) {
6633  // First flush. Chunking for this fragment may already have been
6634  // done, either if we didn't use empty_moov, or if we did use
6635  // delay_moov. In either case, reset chunking here.
6636  for (i = 0; i < track->entry; i++) {
6637  track->cluster[i].chunkNum = 0;
6638  track->cluster[i].samples_in_chunk = track->cluster[i].entries;
6639  }
6640  }
6641  if (av_reallocp_array(&track->cluster_written,
6642  track->entry_written + track->entry,
6643  sizeof(*track->cluster)))
6644  return AVERROR(ENOMEM);
6645  memcpy(&track->cluster_written[track->entry_written],
6646  track->cluster, track->entry * sizeof(*track->cluster));
6647  track->entry_written += track->entry;
6648  }
6649  track->entry = 0;
6650  track->entries_flushed = 0;
6651  track->end_reliable = 0;
6652  return 0;
6653 }
6654 
6655 static int mov_flush_fragment(AVFormatContext *s, int force)
6656 {
6657  MOVMuxContext *mov = s->priv_data;
6658  int i, first_track = -1;
6659  int64_t mdat_size = 0, mdat_start = 0;
6660  int ret;
6661  int has_video = 0, starts_with_key = 0, first_video_track = 1;
6662 
6663  if (!(mov->flags & FF_MOV_FLAG_FRAGMENT))
6664  return 0;
6665 
6666  // Check if we have any tracks that require squashing.
6667  // In that case, we'll have to write the packet here.
6668  if ((ret = mov_write_squashed_packets(s)) < 0)
6669  return ret;
6670 
6671  // Try to fill in the duration of the last packet in each stream
6672  // from queued packets in the interleave queues. If the flushing
6673  // of fragments was triggered automatically by an AVPacket, we
6674  // already have reliable info for the end of that track, but other
6675  // tracks may need to be filled in.
6676  for (i = 0; i < mov->nb_streams; i++) {
6677  MOVTrack *track = &mov->tracks[i];
6678  if (!track->end_reliable) {
6679  const AVPacket *pkt = ff_interleaved_peek(s, i);
6680  if (pkt) {
6681  int64_t offset, dts, pts;
6683  pts = pkt->pts + offset;
6684  dts = pkt->dts + offset;
6685  if (track->dts_shift != AV_NOPTS_VALUE)
6686  dts += track->dts_shift;
6687  track->track_duration = dts - track->start_dts;
6688  if (pts != AV_NOPTS_VALUE)
6689  track->end_pts = pts;
6690  else
6691  track->end_pts = dts;
6692  if (!(pkt->flags & AV_PKT_FLAG_DISCARD))
6693  track->elst_end_pts = track->end_pts;
6694  }
6695  }
6696  }
6697 
6698  for (i = 0; i < mov->nb_tracks; i++) {
6699  MOVTrack *track = &mov->tracks[i];
6700  if (track->entry <= 1)
6701  continue;
6702  // Sample durations are calculated as the diff of dts values,
6703  // but for the last sample in a fragment, we don't know the dts
6704  // of the first sample in the next fragment, so we have to rely
6705  // on what was set as duration in the AVPacket. Not all callers
6706  // set this though, so we might want to replace it with an
6707  // estimate if it currently is zero.
6708  if (get_cluster_duration(track, track->entry - 1) != 0)
6709  continue;
6710  // Use the duration (i.e. dts diff) of the second last sample for
6711  // the last one. This is a wild guess (and fatal if it turns out
6712  // to be too long), but probably the best we can do - having a zero
6713  // duration is bad as well.
6714  track->track_duration += get_cluster_duration(track, track->entry - 2);
6715  track->end_pts += get_cluster_duration(track, track->entry - 2);
6716  if (!mov->missing_duration_warned) {
6718  "Estimating the duration of the last packet in a "
6719  "fragment, consider setting the duration field in "
6720  "AVPacket instead.\n");
6721  mov->missing_duration_warned = 1;
6722  }
6723  }
6724 
6725  if (!mov->moov_written) {
6726  int64_t pos = avio_tell(s->pb);
6727  uint8_t *buf;
6728  int buf_size, moov_size;
6729 
6730  for (i = 0; i < mov->nb_tracks; i++)
6731  if (!mov->tracks[i].entry && !is_cover_image(mov->tracks[i].st))
6732  break;
6733  /* Don't write the initial moov unless all tracks have data */
6734  if (i < mov->nb_tracks && !force)
6735  return 0;
6736 
6737  moov_size = get_moov_size(s);
6738  for (i = 0; i < mov->nb_tracks; i++)
6739  mov->tracks[i].data_offset = pos + moov_size + 8;
6740 
6742  if (mov->flags & FF_MOV_FLAG_DELAY_MOOV &&
6745  if ((ret = mov_write_moov_tag(s->pb, mov, s)) < 0)
6746  return ret;
6747 
6748  if (mov->flags & FF_MOV_FLAG_DELAY_MOOV) {
6749  if (mov->flags & FF_MOV_FLAG_GLOBAL_SIDX)
6750  mov->reserved_header_pos = avio_tell(s->pb);
6752  mov->moov_written = 1;
6753  return 0;
6754  }
6755 
6756  buf_size = avio_get_dyn_buf(mov->mdat_buf, &buf);
6757  avio_wb32(s->pb, buf_size + 8);
6758  ffio_wfourcc(s->pb, "mdat");
6759  avio_write(s->pb, buf, buf_size);
6761 
6762  if (mov->flags & FF_MOV_FLAG_GLOBAL_SIDX)
6763  mov->reserved_header_pos = avio_tell(s->pb);
6764 
6765  mov->moov_written = 1;
6766  mov->mdat_size = 0;
6767  for (i = 0; i < mov->nb_tracks; i++)
6768  mov_finish_fragment(mov, &mov->tracks[i], 0);
6770  return 0;
6771  }
6772 
6773  if (mov->frag_interleave) {
6774  for (i = 0; i < mov->nb_tracks; i++) {
6775  MOVTrack *track = &mov->tracks[i];
6776  int ret;
6777  if ((ret = mov_flush_fragment_interleaving(s, track)) < 0)
6778  return ret;
6779  }
6780 
6781  if (!mov->mdat_buf)
6782  return 0;
6783  mdat_size = avio_tell(mov->mdat_buf);
6784  }
6785 
6786  for (i = 0; i < mov->nb_tracks; i++) {
6787  MOVTrack *track = &mov->tracks[i];
6788  if (mov->flags & FF_MOV_FLAG_SEPARATE_MOOF || mov->frag_interleave)
6789  track->data_offset = 0;
6790  else
6791  track->data_offset = mdat_size;
6792  if (track->par->codec_type == AVMEDIA_TYPE_VIDEO) {
6793  has_video = 1;
6794  if (first_video_track) {
6795  if (track->entry)
6796  starts_with_key = track->cluster[0].flags & MOV_SYNC_SAMPLE;
6797  first_video_track = 0;
6798  }
6799  }
6800  if (!track->entry)
6801  continue;
6802  if (track->mdat_buf)
6803  mdat_size += avio_tell(track->mdat_buf);
6804  if (first_track < 0)
6805  first_track = i;
6806  }
6807 
6808  if (!mdat_size)
6809  return 0;
6810 
6811  avio_write_marker(s->pb,
6812  av_rescale(mov->tracks[first_track].cluster[0].dts, AV_TIME_BASE, mov->tracks[first_track].timescale),
6813  (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);
6814 
6815  for (i = first_track; i < mov->nb_tracks; i++) {
6816  MOVTrack *track = &mov->tracks[i];
6817  int buf_size, write_moof = 1, moof_tracks = -1;
6818  uint8_t *buf;
6819 
6820  if (!track->entry)
6821  continue;
6822  if (mov->flags & FF_MOV_FLAG_SEPARATE_MOOF) {
6823  mdat_size = avio_tell(track->mdat_buf);
6824  moof_tracks = i;
6825  } else {
6826  write_moof = i == first_track;
6827  }
6828 
6829  if (write_moof) {
6831 
6832  mov_write_moof_tag(s->pb, mov, moof_tracks, mdat_size);
6833  mov->fragments++;
6834 
6835  if (track->cenc.aes_ctr)
6836  ff_mov_cenc_flush(&track->cenc);
6837 
6838  avio_wb32(s->pb, mdat_size + 8);
6839  ffio_wfourcc(s->pb, "mdat");
6840  mdat_start = avio_tell(s->pb);
6841  }
6842 
6843  mov_finish_fragment(mov, &mov->tracks[i], mdat_start);
6844  if (!mov->frag_interleave) {
6845  if (!track->mdat_buf)
6846  continue;
6847  buf_size = avio_get_dyn_buf(track->mdat_buf, &buf);
6848  avio_write(s->pb, buf, buf_size);
6849  ffio_reset_dyn_buf(track->mdat_buf);
6850  } else {
6851  if (!mov->mdat_buf)
6852  continue;
6853  buf_size = avio_get_dyn_buf(mov->mdat_buf, &buf);
6854  avio_write(s->pb, buf, buf_size);
6856  }
6857  }
6858 
6859  mov->mdat_size = 0;
6860 
6862  return 0;
6863 }
6864 
6866 {
6867  MOVMuxContext *mov = s->priv_data;
6868  int had_moov = mov->moov_written;
6869  int ret = mov_flush_fragment(s, force);
6870  if (ret < 0)
6871  return ret;
6872  // If using delay_moov, the first flush only wrote the moov,
6873  // not the actual moof+mdat pair, thus flush once again.
6874  if (!had_moov && mov->flags & FF_MOV_FLAG_DELAY_MOOV)
6875  ret = mov_flush_fragment(s, force);
6876  return ret;
6877 }
6878 
6880 {
6881  int64_t ref;
6882  uint64_t duration;
6883 
6884  if (trk->entry) {
6885  ref = trk->cluster[trk->entry - 1].dts;
6886  } else if ( trk->start_dts != AV_NOPTS_VALUE
6887  && !trk->frag_discont) {
6888  ref = trk->start_dts + trk->track_duration;
6889  } else
6890  ref = pkt->dts; // Skip tests for the first packet
6891 
6892  if (trk->dts_shift != AV_NOPTS_VALUE) {
6893  /* With negative CTS offsets we have set an offset to the DTS,
6894  * reverse this for the check. */
6895  ref -= trk->dts_shift;
6896  }
6897 
6898  duration = pkt->dts - ref;
6899  if (pkt->dts < ref || duration >= INT_MAX) {
6900  av_log(s, AV_LOG_WARNING, "Packet duration: %"PRId64" / dts: %"PRId64" in stream %d is out of range\n",
6902 
6903  pkt->dts = ref + 1;
6904  pkt->pts = AV_NOPTS_VALUE;
6905  }
6906 
6907  if (pkt->duration < 0 || pkt->duration > INT_MAX) {
6908  av_log(s, AV_LOG_ERROR, "Application provided duration: %"PRId64" in stream %d is invalid\n", pkt->duration, pkt->stream_index);
6909  return AVERROR(EINVAL);
6910  }
6911  return 0;
6912 }
6913 
6915 {
6916  MOVMuxContext *mov = s->priv_data;
6917  AVIOContext *pb = s->pb;
6918  MOVTrack *trk;
6919  AVCodecParameters *par;
6921  unsigned int samples_in_chunk = 0;
6922  int size = pkt->size, ret = 0, offset = 0;
6923  size_t prft_size;
6924  uint8_t *reformatted_data = NULL;
6925 
6926  if (pkt->stream_index < s->nb_streams)
6927  trk = s->streams[pkt->stream_index]->priv_data;
6928  else // Timecode or chapter
6929  trk = &mov->tracks[pkt->stream_index];
6930  par = trk->par;
6931 
6932  ret = check_pkt(s, trk, pkt);
6933  if (ret < 0)
6934  return ret;
6935 
6936  if (pkt->pts != AV_NOPTS_VALUE &&
6937  (uint64_t)pkt->dts - pkt->pts != (int32_t)((uint64_t)pkt->dts - pkt->pts)) {
6938  av_log(s, AV_LOG_WARNING, "pts/dts pair unsupported\n");
6939  return AVERROR_PATCHWELCOME;
6940  }
6941 
6942  if (mov->flags & FF_MOV_FLAG_FRAGMENT || mov->mode == MODE_AVIF) {
6943  int ret;
6944  if (mov->moov_written || mov->flags & FF_MOV_FLAG_EMPTY_MOOV) {
6945  if (mov->frag_interleave && mov->fragments > 0) {
6946  if (trk->entry - trk->entries_flushed >= mov->frag_interleave) {
6947  if ((ret = mov_flush_fragment_interleaving(s, trk)) < 0)
6948  return ret;
6949  }
6950  }
6951 
6952  if (!trk->mdat_buf) {
6953  if ((ret = avio_open_dyn_buf(&trk->mdat_buf)) < 0)
6954  return ret;
6955  }
6956  pb = trk->mdat_buf;
6957  } else {
6958  if (!mov->mdat_buf) {
6959  if ((ret = avio_open_dyn_buf(&mov->mdat_buf)) < 0)
6960  return ret;
6961  }
6962  pb = mov->mdat_buf;
6963  }
6964  }
6965 
6966  if (par->codec_id == AV_CODEC_ID_AMR_NB) {
6967  /* We must find out how many AMR blocks there are in one packet */
6968  static const uint16_t packed_size[16] =
6969  {13, 14, 16, 18, 20, 21, 27, 32, 6, 0, 0, 0, 0, 0, 0, 1};
6970  int len = 0;
6971 
6972  while (len < size && samples_in_chunk < 100) {
6973  len += packed_size[(pkt->data[len] >> 3) & 0x0F];
6974  samples_in_chunk++;
6975  }
6976  if (samples_in_chunk > 1) {
6977  av_log(s, AV_LOG_ERROR, "fatal error, input is not a single packet, implement a AVParser for it\n");
6978  return -1;
6979  }
6980  } else if (par->codec_id == AV_CODEC_ID_ADPCM_MS ||
6982  samples_in_chunk = trk->par->frame_size;
6983  } else if (trk->sample_size)
6984  samples_in_chunk = size / trk->sample_size;
6985  else
6986  samples_in_chunk = 1;
6987 
6988  if (samples_in_chunk < 1) {
6989  av_log(s, AV_LOG_ERROR, "fatal error, input packet contains no samples\n");
6990  return AVERROR_PATCHWELCOME;
6991  }
6992 
6993  /* copy extradata if it exists */
6994  if (trk->extradata_size[0] == 0 && par->extradata_size > 0 &&
6995  !TAG_IS_AVCI(trk->tag) &&
6996  (par->codec_id != AV_CODEC_ID_DNXHD)) {
6997  trk->extradata[0] = av_memdup(par->extradata, par->extradata_size);
6998  if (!trk->extradata[0]) {
6999  ret = AVERROR(ENOMEM);
7000  goto err;
7001  }
7002  trk->extradata_size[0] = par->extradata_size;
7003  }
7004 
7005  if ((par->codec_id == AV_CODEC_ID_DNXHD ||
7006  par->codec_id == AV_CODEC_ID_H264 ||
7007  par->codec_id == AV_CODEC_ID_HEVC ||
7008  par->codec_id == AV_CODEC_ID_VVC ||
7009  par->codec_id == AV_CODEC_ID_VP9 ||
7010  par->codec_id == AV_CODEC_ID_EVC ||
7011  par->codec_id == AV_CODEC_ID_LCEVC ||
7012  par->codec_id == AV_CODEC_ID_TRUEHD) && !trk->extradata_size[0] &&
7013  !TAG_IS_AVCI(trk->tag)) {
7014  /* copy frame to create needed atoms */
7015  trk->extradata_size[0] = size;
7017  if (!trk->extradata[0]) {
7018  ret = AVERROR(ENOMEM);
7019  goto err;
7020  }
7021  memcpy(trk->extradata[0], pkt->data, size);
7022  memset(trk->extradata[0] + size, 0, AV_INPUT_BUFFER_PADDING_SIZE);
7023  }
7024 
7026  if (pkt->size && sd && sd->size > 0) {
7027  int i;
7028  for (i = 0; i < trk->stsd_count; i++) {
7029  if (trk->extradata_size[i] == sd->size && !memcmp(trk->extradata[i], sd->data, sd->size))
7030  break;
7031  }
7032 
7033  if (i < trk->stsd_count)
7034  trk->last_stsd_index = i;
7035  else if (trk->stsd_count <= INT_MAX - 1) {
7036  int new_count = trk->stsd_count + 1;
7037  uint8_t **extradata = av_realloc_array(trk->extradata, new_count, sizeof(*trk->extradata));
7038  if (!extradata)
7039  return AVERROR(ENOMEM);
7040  trk->extradata = extradata;
7041 
7042  int *extradata_size = av_realloc_array(trk->extradata_size, new_count, sizeof(*trk->extradata_size));
7043  if (!extradata_size)
7044  return AVERROR(ENOMEM);
7045  trk->extradata_size = extradata_size;
7046 
7047  trk->extradata[trk->stsd_count] = av_memdup(sd->data, sd->size);
7048  if (!trk->extradata[trk->stsd_count])
7049  return AVERROR(ENOMEM);
7050 
7051  trk->extradata_size[trk->stsd_count] = sd->size;
7052  trk->last_stsd_index = trk->stsd_count;
7053  trk->stsd_count = new_count;
7054  } else
7055  return AVERROR(ENOMEM);
7056  }
7057 
7058  if (par->codec_id == AV_CODEC_ID_AAC && pkt->size > 2 &&
7059  (AV_RB16(pkt->data) & 0xfff0) == 0xfff0) {
7060  if (!trk->st->nb_frames) {
7061  av_log(s, AV_LOG_ERROR, "Malformed AAC bitstream detected: "
7062  "use the audio bitstream filter 'aac_adtstoasc' to fix it "
7063  "('-bsf:a aac_adtstoasc' option with ffmpeg)\n");
7064  return -1;
7065  }
7066  av_log(s, AV_LOG_WARNING, "aac bitstream error\n");
7067  }
7068  if (par->codec_id == AV_CODEC_ID_H264 && trk->extradata_size[trk->last_stsd_index] > 0 &&
7069  *(uint8_t *)trk->extradata[trk->last_stsd_index] != 1 && !TAG_IS_AVCI(trk->tag)) {
7070  /* from x264 or from bytestream H.264 */
7071  /* NAL reformatting needed */
7072  if (trk->hint_track >= 0 && trk->hint_track < mov->nb_tracks) {
7073  ret = ff_nal_parse_units_buf(pkt->data, &reformatted_data,
7074  &size);
7075  if (ret < 0)
7076  return ret;
7077  avio_write(pb, reformatted_data, size);
7078  } else {
7079  if (trk->cenc.aes_ctr) {
7081  if (size < 0) {
7082  ret = size;
7083  goto err;
7084  }
7085  } else {
7086  size = ff_nal_parse_units(pb, pkt->data, pkt->size);
7087  }
7088  }
7089  } else if (par->codec_id == AV_CODEC_ID_HEVC && trk->extradata_size[trk->last_stsd_index] > 6 &&
7090  (AV_RB24(trk->extradata[trk->last_stsd_index]) == 1 || AV_RB32(trk->extradata[trk->last_stsd_index]) == 1)) {
7091  /* extradata is Annex B, assume the bitstream is too and convert it */
7092  int filter_ps = (trk->tag == MKTAG('h','v','c','1'));
7093  if (trk->hint_track >= 0 && trk->hint_track < mov->nb_tracks) {
7094  ret = ff_hevc_annexb2mp4_buf(pkt->data, &reformatted_data,
7095  &size, filter_ps, NULL);
7096  if (ret < 0)
7097  return ret;
7098  avio_write(pb, reformatted_data, size);
7099  } else {
7100  if (trk->cenc.aes_ctr) {
7102  if (size < 0) {
7103  ret = size;
7104  goto err;
7105  }
7106  } else {
7107  size = ff_hevc_annexb2mp4(pb, pkt->data, pkt->size, filter_ps, NULL);
7108  }
7109  }
7110  } else if (par->codec_id == AV_CODEC_ID_VVC && trk->extradata_size[trk->last_stsd_index] > 6 &&
7111  (AV_RB24(trk->extradata[trk->last_stsd_index]) == 1 || AV_RB32(trk->extradata[trk->last_stsd_index]) == 1)) {
7112  /* extradata is Annex B, assume the bitstream is too and convert it */
7113  if (trk->hint_track >= 0 && trk->hint_track < mov->nb_tracks) {
7114  ret = ff_vvc_annexb2mp4_buf(pkt->data, &reformatted_data,
7115  &size, 0, NULL);
7116  if (ret < 0)
7117  return ret;
7118  avio_write(pb, reformatted_data, size);
7119  } else {
7120  size = ff_vvc_annexb2mp4(pb, pkt->data, pkt->size, 0, NULL);
7121  }
7122  } else if (par->codec_id == AV_CODEC_ID_LCEVC && trk->extradata_size[trk->last_stsd_index] > 0 &&
7123  *(uint8_t *)trk->extradata[trk->last_stsd_index] != 1) {
7124  /* extradata is Annex B, assume the bitstream is too and convert it */
7125  if (trk->hint_track >= 0 && trk->hint_track < mov->nb_tracks) {
7126  ret = ff_nal_parse_units_buf(pkt->data, &reformatted_data, &size);
7127  if (ret < 0)
7128  return ret;
7129  avio_write(pb, reformatted_data, size);
7130  } else {
7131  if (trk->cenc.aes_ctr) {
7133  if (size < 0) {
7134  ret = size;
7135  goto err;
7136  }
7137  } else {
7138  size = ff_nal_parse_units(pb, pkt->data, pkt->size);
7139  }
7140  }
7141  } else if (par->codec_id == AV_CODEC_ID_AV1 && !trk->cenc.aes_ctr) {
7142  if (trk->hint_track >= 0 && trk->hint_track < mov->nb_tracks) {
7143  ret = ff_av1_filter_obus_buf(pkt->data, &reformatted_data,
7144  &size, &offset);
7145  if (ret < 0)
7146  return ret;
7147  avio_write(pb, reformatted_data, size);
7148  } else {
7149  size = ff_av1_filter_obus(pb, pkt->data, pkt->size);
7150  if (trk->mode == MODE_AVIF && !mov->avif_extent_length[pkt->stream_index]) {
7152  }
7153  }
7154 
7155  } else if (par->codec_id == AV_CODEC_ID_AC3 ||
7156  par->codec_id == AV_CODEC_ID_EAC3) {
7157  size = handle_eac3(mov, pkt, trk);
7158  if (size < 0)
7159  return size;
7160  else if (!size)
7161  goto end;
7162  avio_write(pb, pkt->data, size);
7163  } else if (par->codec_id == AV_CODEC_ID_EIA_608) {
7164  size = 8;
7165 
7166  for (int i = 0; i < pkt->size; i += 3) {
7167  if (pkt->data[i] == 0xFC) {
7168  size += 2;
7169  }
7170  }
7171  avio_wb32(pb, size);
7172  ffio_wfourcc(pb, "cdat");
7173  for (int i = 0; i < pkt->size; i += 3) {
7174  if (pkt->data[i] == 0xFC) {
7175  avio_w8(pb, pkt->data[i + 1]);
7176  avio_w8(pb, pkt->data[i + 2]);
7177  }
7178  }
7179  } else if (par->codec_id == AV_CODEC_ID_APV) {
7180  ff_isom_parse_apvc(trk->apv, pkt, s);
7181  avio_wb32(s->pb, pkt->size);
7182  size += 4;
7183 
7184  avio_write(s->pb, pkt->data, pkt->size);
7185  } else {
7186  if (trk->cenc.aes_ctr) {
7187  uint8_t *extradata = trk->extradata[trk->last_stsd_index];
7188  int extradata_size = trk->extradata_size[trk->last_stsd_index];
7189  if (par->codec_id == AV_CODEC_ID_H264 && extradata_size > 4) {
7190  int nal_size_length = (extradata[4] & 0x3) + 1;
7191  ret = ff_mov_cenc_avc_write_nal_units(s, &trk->cenc, nal_size_length, pb, pkt->data, size);
7192  } else if(par->codec_id == AV_CODEC_ID_HEVC && extradata_size > 21) {
7193  int nal_size_length = (extradata[21] & 0x3) + 1;
7194  ret = ff_mov_cenc_avc_write_nal_units(s, &trk->cenc, nal_size_length, pb, pkt->data, size);
7195  } else if(par->codec_id == AV_CODEC_ID_VVC) {
7197  } else if(par->codec_id == AV_CODEC_ID_AV1) {
7198  av_assert0(size == pkt->size);
7199  ret = ff_mov_cenc_av1_write_obus(s, &trk->cenc, pb, pkt);
7200  if (ret > 0) {
7201  size = ret;
7202  ret = 0;
7203  }
7204  } else {
7205  ret = ff_mov_cenc_write_packet(&trk->cenc, pb, pkt->data, size);
7206  }
7207 
7208  if (ret) {
7209  goto err;
7210  }
7211  } else {
7212  avio_write(pb, pkt->data, size);
7213  }
7214  }
7215 
7216  if (trk->entry >= trk->cluster_capacity) {
7217  unsigned new_capacity = trk->entry + MOV_INDEX_CLUSTER_SIZE;
7218  void *cluster = av_realloc_array(trk->cluster, new_capacity, sizeof(*trk->cluster));
7219  if (!cluster) {
7220  ret = AVERROR(ENOMEM);
7221  goto err;
7222  }
7223  trk->cluster = cluster;
7224  trk->cluster_capacity = new_capacity;
7225  }
7226 
7227  trk->cluster[trk->entry].pos = avio_tell(pb) - size;
7228  trk->cluster[trk->entry].stsd_index = trk->last_stsd_index;
7229  trk->cluster[trk->entry].samples_in_chunk = samples_in_chunk;
7230  trk->cluster[trk->entry].chunkNum = 0;
7231  trk->cluster[trk->entry].size = size;
7232  trk->cluster[trk->entry].entries = samples_in_chunk;
7233  trk->cluster[trk->entry].dts = pkt->dts;
7234  trk->cluster[trk->entry].pts = pkt->pts;
7235  if (!trk->squash_fragment_samples_to_one &&
7236  !trk->entry && trk->start_dts != AV_NOPTS_VALUE) {
7237  if (!trk->frag_discont) {
7238  /* First packet of a new fragment. We already wrote the duration
7239  * of the last packet of the previous fragment based on track_duration,
7240  * which might not exactly match our dts. Therefore adjust the dts
7241  * of this packet to be what the previous packets duration implies. */
7242  trk->cluster[trk->entry].dts = trk->start_dts + trk->track_duration;
7243  /* We also may have written the pts and the corresponding duration
7244  * in sidx/tfrf/tfxd tags; make sure the sidx pts and duration match up with
7245  * the next fragment. This means the cts of the first sample must
7246  * be the same in all fragments, unless end_pts was updated by
7247  * the packet causing the fragment to be written. */
7248  if ((mov->flags & FF_MOV_FLAG_DASH &&
7250  mov->mode == MODE_ISM)
7251  pkt->pts = pkt->dts + trk->end_pts - trk->cluster[trk->entry].dts;
7252  } else {
7253  /* New fragment, but discontinuous from previous fragments.
7254  * Pretend the duration sum of the earlier fragments is
7255  * pkt->dts - trk->start_dts. */
7256  trk->end_pts = trk->elst_end_pts = AV_NOPTS_VALUE;
7257  trk->frag_discont = 0;
7258  }
7259  }
7260 
7261  if (!trk->entry && trk->start_dts == AV_NOPTS_VALUE && !mov->use_editlist &&
7262  s->avoid_negative_ts == AVFMT_AVOID_NEG_TS_MAKE_ZERO) {
7263  /* Not using edit lists and shifting the first track to start from zero.
7264  * If the other streams start from a later timestamp, we won't be able
7265  * to signal the difference in starting time without an edit list.
7266  * Thus move the timestamp for this first sample to 0, increasing
7267  * its duration instead. */
7268  trk->cluster[trk->entry].dts = trk->start_dts = 0;
7269  }
7270  if (trk->start_dts == AV_NOPTS_VALUE) {
7271  trk->start_dts = pkt->dts;
7272  if (trk->frag_discont) {
7273  if (mov->use_editlist) {
7274  /* Pretend the whole stream started at pts=0, with earlier fragments
7275  * already written. If the stream started at pts=0, the duration sum
7276  * of earlier fragments would have been pkt->pts. */
7277  trk->start_dts = pkt->dts - pkt->pts;
7278  } else {
7279  /* Pretend the whole stream started at dts=0, with earlier fragments
7280  * already written, with a duration summing up to pkt->dts. */
7281  trk->start_dts = 0;
7282  }
7283  trk->frag_discont = 0;
7284  } else if (pkt->dts && mov->moov_written)
7286  "Track %d starts with a nonzero dts %"PRId64", while the moov "
7287  "already has been written. Set the delay_moov flag to handle "
7288  "this case.\n",
7289  pkt->stream_index, pkt->dts);
7290  }
7291  trk->track_duration = pkt->dts - trk->start_dts + pkt->duration;
7292  trk->last_sample_is_subtitle_end = 0;
7293 
7294  if (pkt->pts == AV_NOPTS_VALUE) {
7295  av_log(s, AV_LOG_WARNING, "pts has no value\n");
7296  pkt->pts = pkt->dts;
7297  }
7298  if (pkt->dts != pkt->pts)
7299  trk->flags |= MOV_TRACK_CTTS;
7300  trk->cluster[trk->entry].cts = pkt->pts - pkt->dts;
7301  trk->cluster[trk->entry].flags = 0;
7302  if (trk->start_cts == AV_NOPTS_VALUE || (pkt->dts <= 0 && trk->start_cts > pkt->pts - pkt->dts))
7303  trk->start_cts = pkt->pts - pkt->dts;
7304  if (trk->end_pts == AV_NOPTS_VALUE)
7305  trk->end_pts = trk->cluster[trk->entry].dts +
7306  trk->cluster[trk->entry].cts + pkt->duration;
7307  else
7308  trk->end_pts = FFMAX(trk->end_pts, trk->cluster[trk->entry].dts +
7309  trk->cluster[trk->entry].cts +
7310  pkt->duration);
7311  if (!(pkt->flags & AV_PKT_FLAG_DISCARD))
7312  trk->elst_end_pts = trk->end_pts;
7313 
7314  if (par->codec_id == AV_CODEC_ID_VC1) {
7315  mov_parse_vc1_frame(pkt, trk);
7316  } else if (par->codec_id == AV_CODEC_ID_TRUEHD) {
7318  } else if (pkt->flags & AV_PKT_FLAG_KEY) {
7319  if (mov->mode == MODE_MOV && par->codec_id == AV_CODEC_ID_MPEG2VIDEO &&
7320  trk->entry > 0) { // force sync sample for the first key frame
7322  if (trk->cluster[trk->entry].flags & MOV_PARTIAL_SYNC_SAMPLE)
7323  trk->flags |= MOV_TRACK_STPS;
7324  } else {
7325  trk->cluster[trk->entry].flags = MOV_SYNC_SAMPLE;
7326  }
7327  if (trk->cluster[trk->entry].flags & MOV_SYNC_SAMPLE)
7328  trk->has_keyframes++;
7329  }
7330  if (pkt->flags & AV_PKT_FLAG_DISPOSABLE) {
7331  trk->cluster[trk->entry].flags |= MOV_DISPOSABLE_SAMPLE;
7332  trk->has_disposable++;
7333  }
7334 
7336  if (prft && prft_size == sizeof(AVProducerReferenceTime))
7337  memcpy(&trk->cluster[trk->entry].prft, prft, prft_size);
7338  else
7339  memset(&trk->cluster[trk->entry].prft, 0, sizeof(AVProducerReferenceTime));
7340 
7341  trk->entry++;
7342  trk->sample_count += samples_in_chunk;
7343  mov->mdat_size += size;
7344 
7345  if (trk->hint_track >= 0 && trk->hint_track < mov->nb_tracks)
7347  reformatted_data ? reformatted_data + offset
7348  : NULL, size);
7349 
7350 end:
7351 err:
7352 
7353  if (pkt->data != reformatted_data)
7354  av_free(reformatted_data);
7355  return ret;
7356 }
7357 
7359 {
7360  MOVMuxContext *mov = s->priv_data;
7361  MOVTrack *trk = s->streams[pkt->stream_index]->priv_data;
7362  AVCodecParameters *par = trk->par;
7363  int64_t frag_duration = 0;
7364  int size = pkt->size;
7365 
7366  int ret = check_pkt(s, trk, pkt);
7367  if (ret < 0)
7368  return ret;
7369 
7370  if (mov->flags & FF_MOV_FLAG_FRAG_DISCONT) {
7371  for (int i = 0; i < mov->nb_streams; i++)
7372  mov->tracks[i].frag_discont = 1;
7374  }
7375 
7377  if (trk->dts_shift == AV_NOPTS_VALUE)
7378  trk->dts_shift = pkt->pts - pkt->dts;
7379  pkt->dts += trk->dts_shift;
7380  }
7381 
7382  if (trk->par->codec_id == AV_CODEC_ID_MP4ALS ||
7383  trk->par->codec_id == AV_CODEC_ID_AAC ||
7384  trk->par->codec_id == AV_CODEC_ID_AV1 ||
7385  trk->par->codec_id == AV_CODEC_ID_FLAC) {
7386  size_t side_size;
7387  uint8_t *side = av_packet_get_side_data(pkt, AV_PKT_DATA_NEW_EXTRADATA, &side_size);
7388  /* Overwrite extradata only on flush packets or when no extradata was available during init */
7389  if (side_size > 0 && (!pkt->size || !trk->extradata_size[trk->last_stsd_index])) {
7390  void *newextra = av_malloc(side_size + AV_INPUT_BUFFER_PADDING_SIZE);
7391  if (!newextra)
7392  return AVERROR(ENOMEM);
7393  memset((uint8_t*)newextra + side_size, 0, AV_INPUT_BUFFER_PADDING_SIZE);
7394  memcpy(newextra, side, side_size);
7395  av_free(trk->extradata[trk->last_stsd_index]);
7396  trk->extradata[trk->last_stsd_index] = newextra;
7397  trk->extradata_size[trk->last_stsd_index] = side_size;
7398  }
7399  }
7400 
7401  if (!pkt->size) {
7402  if (trk->start_dts == AV_NOPTS_VALUE && trk->frag_discont) {
7403  trk->start_dts = pkt->dts;
7404  if (pkt->pts != AV_NOPTS_VALUE)
7405  trk->start_cts = pkt->pts - pkt->dts;
7406  else
7407  trk->start_cts = 0;
7408  }
7409 
7410  return 0; /* Discard 0 sized packets */
7411  }
7412 
7413  if (trk->entry && pkt->stream_index < mov->nb_streams)
7414  frag_duration = av_rescale_q(pkt->dts - trk->cluster[0].dts,
7415  s->streams[pkt->stream_index]->time_base,
7416  AV_TIME_BASE_Q);
7417  if ((mov->max_fragment_duration &&
7418  frag_duration >= mov->max_fragment_duration) ||
7419  (mov->max_fragment_size && mov->mdat_size + size >= mov->max_fragment_size) ||
7420  (mov->flags & FF_MOV_FLAG_FRAG_KEYFRAME &&
7421  par->codec_type == AVMEDIA_TYPE_VIDEO &&
7422  trk->entry && pkt->flags & AV_PKT_FLAG_KEY) ||
7424  if (frag_duration >= mov->min_fragment_duration) {
7425  if (trk->entry) {
7426  // Set the duration of this track to line up with the next
7427  // sample in this track. This avoids relying on AVPacket
7428  // duration, but only helps for this particular track, not
7429  // for the other ones that are flushed at the same time.
7430  //
7431  // If we have trk->entry == 0, no fragment will be written
7432  // for this track, and we can't adjust the track end here.
7433  trk->track_duration = pkt->dts - trk->start_dts;
7434  if (pkt->pts != AV_NOPTS_VALUE)
7435  trk->end_pts = pkt->pts;
7436  else
7437  trk->end_pts = pkt->dts;
7438  if (!(pkt->flags & AV_PKT_FLAG_DISCARD))
7439  trk->elst_end_pts = trk->end_pts;
7440  trk->end_reliable = 1;
7441  }
7443  }
7444  }
7445 
7446  return ff_mov_write_packet(s, pkt);
7447 }
7448 
7450  int stream_index,
7451  int64_t dts) {
7452  MOVMuxContext *mov = s->priv_data;
7453  AVPacket *end = mov->pkt;
7454  uint8_t data[2] = {0};
7455  int ret;
7456 
7457  end->size = sizeof(data);
7458  end->data = data;
7459  end->pts = dts;
7460  end->dts = dts;
7461  end->duration = 0;
7462  end->stream_index = stream_index;
7463 
7464  ret = mov_write_single_packet(s, end);
7465  av_packet_unref(end);
7466 
7467  return ret;
7468 }
7469 
7470 #if CONFIG_IAMFENC
7471 static int mov_build_iamf_packet(AVFormatContext *s, MOVTrack *trk, AVPacket *pkt)
7472 {
7473  uint8_t *data;
7474  int ret;
7475 
7476  if (pkt->stream_index == trk->first_iamf_idx) {
7478  if (ret < 0)
7479  return ret;
7480  }
7481 
7483  s->streams[pkt->stream_index]->id, pkt);
7484  if (ret < 0)
7485  return ret;
7486 
7487  if (pkt->stream_index != trk->last_iamf_idx)
7488  return AVERROR(EAGAIN);
7489 
7490  ret = avio_close_dyn_buf(trk->iamf_buf, &data);
7491  trk->iamf_buf = NULL;
7492  if (!ret) {
7493  if (pkt->size) {
7494  // Either all or none of the packets for a single
7495  // IA Sample may be empty.
7496  av_log(s, AV_LOG_ERROR, "Unexpected packet from "
7497  "stream #%d\n", pkt->stream_index);
7499  }
7500  av_free(data);
7501  return ret;
7502  }
7503 
7504  av_buffer_unref(&pkt->buf);
7505  pkt->buf = av_buffer_create(data, ret, NULL, NULL, 0);
7506  if (!pkt->buf) {
7507  av_free(data);
7508  return AVERROR(ENOMEM);
7509  }
7510  pkt->data = data;
7511  pkt->size = ret;
7513 
7514  return avio_open_dyn_buf(&trk->iamf_buf);
7515 }
7516 #endif
7517 
7519 {
7520  int64_t pos = avio_tell(pb);
7521  const char *scheme_id_uri = "https://aomedia.org/emsg/ID3";
7522  const char *value = "";
7523 
7524  av_assert0(st->time_base.num == 1);
7525 
7526  avio_write_marker(pb,
7529 
7530  avio_wb32(pb, 0); /* size */
7531  ffio_wfourcc(pb, "emsg");
7532  avio_w8(pb, 1); /* version */
7533  avio_wb24(pb, 0);
7534  avio_wb32(pb, st->time_base.den); /* timescale */
7535  avio_wb64(pb, pkt->pts); /* presentation_time */
7536  avio_wb32(pb, 0xFFFFFFFFU); /* event_duration */
7537  avio_wb32(pb, 0); /* id */
7538  /* null terminated UTF8 strings */
7539  avio_write(pb, scheme_id_uri, strlen(scheme_id_uri) + 1);
7540  avio_write(pb, value, strlen(value) + 1);
7541  avio_write(pb, pkt->data, pkt->size);
7542 
7543  return update_size(pb, pos);
7544 }
7545 
7547 {
7548  MOVMuxContext *mov = s->priv_data;
7549  MOVTrack *trk;
7550 
7551  if (!pkt) {
7552  mov_flush_fragment(s, 1);
7553  return 1;
7554  }
7555 
7556  if (s->streams[pkt->stream_index]->codecpar->codec_id == AV_CODEC_ID_TIMED_ID3) {
7557  mov_write_emsg_tag(s->pb, s->streams[pkt->stream_index], pkt);
7558  return 0;
7559  }
7560 
7561  trk = s->streams[pkt->stream_index]->priv_data;
7562 
7563 #if CONFIG_IAMFENC
7564  if (trk->iamf) {
7565  int ret = mov_build_iamf_packet(s, trk, pkt);
7566  if (ret < 0) {
7567  if (ret == AVERROR(EAGAIN))
7568  return 0;
7569  av_log(s, AV_LOG_ERROR, "Error assembling an IAMF packet "
7570  "for stream #%d\n", trk->st->index);
7571  return ret;
7572  }
7573  }
7574 #endif
7575 
7576  if (is_cover_image(trk->st)) {
7577  int ret;
7578 
7579  if (trk->st->nb_frames >= 1) {
7580  if (trk->st->nb_frames == 1)
7581  av_log(s, AV_LOG_WARNING, "Got more than one picture in stream %d,"
7582  " ignoring.\n", pkt->stream_index);
7583  return 0;
7584  }
7585 
7586  if ((ret = av_packet_ref(trk->cover_image, pkt)) < 0)
7587  return ret;
7588 
7589  return 0;
7590  } else {
7591  int i;
7592 
7593  if (!pkt->size)
7594  return mov_write_single_packet(s, pkt); /* Passthrough. */
7595 
7596  /*
7597  * Subtitles require special handling.
7598  *
7599  * 1) For full compliance, every track must have a sample at
7600  * dts == 0, which is rarely true for subtitles. So, as soon
7601  * as we see any packet with dts > 0, write an empty subtitle
7602  * at dts == 0 for any subtitle track with no samples in it.
7603  *
7604  * 2) For each subtitle track, check if the current packet's
7605  * dts is past the duration of the last subtitle sample. If
7606  * so, we now need to write an end sample for that subtitle.
7607  *
7608  * This must be done conditionally to allow for subtitles that
7609  * immediately replace each other, in which case an end sample
7610  * is not needed, and is, in fact, actively harmful.
7611  *
7612  * 3) See mov_write_trailer for how the final end sample is
7613  * handled.
7614  */
7615  for (i = 0; i < mov->nb_tracks; i++) {
7616  MOVTrack *trk = &mov->tracks[i];
7617  int ret;
7618 
7619  if (trk->par->codec_id == AV_CODEC_ID_MOV_TEXT &&
7620  trk->track_duration < pkt->dts &&
7621  (trk->entry == 0 || !trk->last_sample_is_subtitle_end)) {
7623  if (ret < 0) return ret;
7624  trk->last_sample_is_subtitle_end = 1;
7625  }
7626  }
7627 
7628  if (trk->squash_fragment_samples_to_one) {
7629  /*
7630  * If the track has to have its samples squashed into one sample,
7631  * we just take it into the track's queue.
7632  * This will then be utilized as the samples get written in either
7633  * mov_flush_fragment or when the mux is finalized in
7634  * mov_write_trailer.
7635  */
7636  int ret = AVERROR_BUG;
7637 
7638  if (pkt->pts == AV_NOPTS_VALUE) {
7640  "Packets without a valid presentation timestamp are "
7641  "not supported with packet squashing!\n");
7642  return AVERROR(EINVAL);
7643  }
7644 
7645  /* The following will reset pkt and is only allowed to be used
7646  * because we return immediately. afterwards. */
7648  pkt, NULL, 0)) < 0) {
7649  return ret;
7650  }
7651 
7652  return 0;
7653  }
7654 
7655 
7656  if (trk->mode == MODE_MOV && trk->par->codec_type == AVMEDIA_TYPE_VIDEO) {
7657  AVPacket *opkt = pkt;
7658  int reshuffle_ret, ret;
7659  if (trk->is_unaligned_qt_rgb) {
7660  int64_t bpc = trk->par->bits_per_coded_sample != 15 ? trk->par->bits_per_coded_sample : 16;
7661  int expected_stride = ((trk->par->width * bpc + 15) >> 4)*2;
7662  reshuffle_ret = ff_reshuffle_raw_rgb(s, &pkt, trk->par, expected_stride);
7663  if (reshuffle_ret < 0)
7664  return reshuffle_ret;
7665  } else
7666  reshuffle_ret = 0;
7667  if (trk->par->format == AV_PIX_FMT_PAL8 && !trk->pal_done) {
7668  ret = ff_get_packet_palette(s, opkt, reshuffle_ret, trk->palette);
7669  if (ret < 0)
7670  goto fail;
7671  if (ret)
7672  trk->pal_done++;
7673  } else if (trk->par->codec_id == AV_CODEC_ID_RAWVIDEO &&
7674  (trk->par->format == AV_PIX_FMT_GRAY8 ||
7675  trk->par->format == AV_PIX_FMT_MONOBLACK)) {
7677  if (ret < 0)
7678  goto fail;
7679  for (i = 0; i < pkt->size; i++)
7680  pkt->data[i] = ~pkt->data[i];
7681  }
7682  if (reshuffle_ret) {
7684 fail:
7685  if (reshuffle_ret)
7686  av_packet_free(&pkt);
7687  return ret;
7688  }
7689  }
7690 
7691  return mov_write_single_packet(s, pkt);
7692  }
7693 }
7694 
7695 // QuickTime chapters involve an additional text track with the chapter names
7696 // as samples, and a tref pointing from the other tracks to the chapter one.
7697 static int mov_create_chapter_track(AVFormatContext *s, int tracknum)
7698 {
7699  static const uint8_t stub_header[] = {
7700  // TextSampleEntry
7701  0x00, 0x00, 0x00, 0x01, // displayFlags
7702  0x00, 0x00, // horizontal + vertical justification
7703  0x00, 0x00, 0x00, 0x00, // bgColourRed/Green/Blue/Alpha
7704  // BoxRecord
7705  0x00, 0x00, 0x00, 0x00, // defTextBoxTop/Left
7706  0x00, 0x00, 0x00, 0x00, // defTextBoxBottom/Right
7707  // StyleRecord
7708  0x00, 0x00, 0x00, 0x00, // startChar + endChar
7709  0x00, 0x01, // fontID
7710  0x00, 0x00, // fontStyleFlags + fontSize
7711  0x00, 0x00, 0x00, 0x00, // fgColourRed/Green/Blue/Alpha
7712  // FontTableBox
7713  0x00, 0x00, 0x00, 0x0D, // box size
7714  'f', 't', 'a', 'b', // box atom name
7715  0x00, 0x01, // entry count
7716  // FontRecord
7717  0x00, 0x01, // font ID
7718  0x00, // font name length
7719  };
7720  MOVMuxContext *mov = s->priv_data;
7721  MOVTrack *track = &mov->tracks[tracknum];
7722  AVPacket *pkt = mov->pkt;
7723  int i, len;
7724  int ret;
7725 
7726  track->mode = mov->mode;
7727  track->tag = MKTAG('t','e','x','t');
7728  track->timescale = mov->movie_timescale;
7729  track->par = avcodec_parameters_alloc();
7730  if (!track->par)
7731  return AVERROR(ENOMEM);
7733  ret = ff_alloc_extradata(track->par, sizeof(stub_header));
7734  if (ret < 0)
7735  return ret;
7736  memcpy(track->par->extradata, stub_header, sizeof(stub_header));
7737 
7738  if (track->extradata == NULL) {
7739  track->stsd_count = 1;
7740  track->extradata = av_calloc(1, sizeof(*track->extradata));
7741  track->extradata_size = av_calloc(1, sizeof(*track->extradata_size));
7742  if (!track->extradata || !track->extradata_size)
7743  return AVERROR(ENOMEM);
7744  }
7745 
7746  track->extradata[0] = av_memdup(stub_header, sizeof(stub_header));
7747  if (!track->extradata[0])
7748  return AVERROR(ENOMEM);
7749  track->extradata_size[0] = sizeof(stub_header);
7750 
7751  pkt->stream_index = tracknum;
7753 
7754  for (i = 0; i < s->nb_chapters; i++) {
7755  AVChapter *c = s->chapters[i];
7756  AVDictionaryEntry *t;
7757 
7758  int64_t end = av_rescale_q(c->end, c->time_base, (AVRational){1,mov->movie_timescale});
7759  pkt->pts = pkt->dts = av_rescale_q(c->start, c->time_base, (AVRational){1,mov->movie_timescale});
7760  pkt->duration = end - pkt->dts;
7761 
7762  if ((t = av_dict_get(c->metadata, "title", NULL, 0))) {
7763  static const char encd[12] = {
7764  0x00, 0x00, 0x00, 0x0C,
7765  'e', 'n', 'c', 'd',
7766  0x00, 0x00, 0x01, 0x00 };
7767  len = strlen(t->value);
7768  pkt->size = len + 2 + 12;
7769  pkt->data = av_malloc(pkt->size);
7770  if (!pkt->data) {
7772  return AVERROR(ENOMEM);
7773  }
7774  AV_WB16(pkt->data, len);
7775  memcpy(pkt->data + 2, t->value, len);
7776  memcpy(pkt->data + len + 2, encd, sizeof(encd));
7778  av_freep(&pkt->data);
7779  }
7780  }
7781 
7782  av_packet_unref(mov->pkt);
7783 
7784  return 0;
7785 }
7786 
7787 
7788 static int mov_check_timecode_track(AVFormatContext *s, AVTimecode *tc, AVStream *src_st, const char *tcstr)
7789 {
7790  int ret;
7791 
7792  /* compute the frame number */
7793  ret = av_timecode_init_from_string(tc, src_st->avg_frame_rate, tcstr, s);
7794  return ret;
7795 }
7796 
7797 static int mov_create_timecode_track(AVFormatContext *s, int index, int src_index, AVTimecode tc)
7798 {
7799  MOVMuxContext *mov = s->priv_data;
7800  MOVTrack *track = &mov->tracks[index];
7801  AVStream *src_st = mov->tracks[src_index].st;
7802  uint8_t data[4];
7803  AVPacket *pkt = mov->pkt;
7804  AVRational rate = src_st->avg_frame_rate;
7805  int ret;
7806 
7807  /* tmcd track based on video stream */
7808  track->mode = mov->mode;
7809  track->tag = MKTAG('t','m','c','d');
7810  track->src_track = av_malloc(sizeof(*track->src_track));
7811  if (!track->src_track)
7812  return AVERROR(ENOMEM);
7813  *track->src_track = src_index;
7814  track->nb_src_track = 1;
7815  track->timescale = mov->tracks[src_index].timescale;
7818 
7819  /* set st to src_st for metadata access*/
7820  track->st = src_st;
7821 
7822  /* encode context: tmcd data stream */
7823  track->par = avcodec_parameters_alloc();
7824  if (!track->par)
7825  return AVERROR(ENOMEM);
7826  track->par->codec_type = AVMEDIA_TYPE_DATA;
7827  track->par->codec_tag = track->tag;
7828  track->st->avg_frame_rate = rate;
7829 
7830  /* the tmcd track just contains one packet with the frame number */
7831  pkt->data = data;
7832  pkt->stream_index = index;
7834  pkt->pts = pkt->dts = av_rescale_q(tc.start, av_inv_q(rate), (AVRational){1,mov->movie_timescale});
7835  pkt->size = 4;
7836  AV_WB32(pkt->data, tc.start);
7839  return ret;
7840 }
7841 
7842 /*
7843  * st->disposition controls the "enabled" flag in the tkhd tag.
7844  * QuickTime will not play a track if it is not enabled. So make sure
7845  * that one track of each type (audio, video, subtitle) is enabled.
7846  *
7847  * Subtitles are special. For audio and video, setting "enabled" also
7848  * makes the track "default" (i.e. it is rendered when played). For
7849  * subtitles, an "enabled" subtitle is not rendered by default, but
7850  * if no subtitle is enabled, the subtitle menu in QuickTime will be
7851  * empty!
7852  */
7854 {
7855  MOVMuxContext *mov = s->priv_data;
7856  int i;
7857  int enabled[AVMEDIA_TYPE_NB];
7858  int first[AVMEDIA_TYPE_NB];
7859 
7860  for (i = 0; i < AVMEDIA_TYPE_NB; i++) {
7861  enabled[i] = 0;
7862  first[i] = -1;
7863  }
7864 
7865  for (i = 0; i < mov->nb_streams; i++) {
7866  AVStream *st = mov->tracks[i].st;
7867 
7870  is_cover_image(st))
7871  continue;
7872 
7873  if (first[st->codecpar->codec_type] < 0)
7874  first[st->codecpar->codec_type] = i;
7875  if (st->disposition & AV_DISPOSITION_DEFAULT) {
7876  mov->tracks[i].flags |= MOV_TRACK_ENABLED;
7877  enabled[st->codecpar->codec_type]++;
7878  }
7879  }
7880 
7881  for (i = 0; i < AVMEDIA_TYPE_NB; i++) {
7882  switch (i) {
7883  case AVMEDIA_TYPE_VIDEO:
7884  case AVMEDIA_TYPE_AUDIO:
7885  case AVMEDIA_TYPE_SUBTITLE:
7886  if (enabled[i] > 1)
7887  mov->per_stream_grouping = 1;
7888  if (!enabled[i] && first[i] >= 0)
7889  mov->tracks[first[i]].flags |= MOV_TRACK_ENABLED;
7890  break;
7891  }
7892  }
7893 }
7894 
7896 {
7897  MOVMuxContext *mov = s->priv_data;
7898 
7899  for (int i = 0; i < s->nb_streams; i++)
7900  s->streams[i]->priv_data = NULL;
7901 
7902  if (!mov->tracks)
7903  return;
7904 
7905  if (mov->chapter_track) {
7907  }
7908 
7909  for (int i = 0; i < mov->nb_tracks; i++) {
7910  MOVTrack *const track = &mov->tracks[i];
7911 
7912  if (track->tag == MKTAG('r','t','p',' '))
7913  ff_mov_close_hinting(track);
7914  else if (track->tag == MKTAG('t','m','c','d') && mov->nb_meta_tmcd)
7915  av_freep(&track->par);
7916  av_freep(&track->cluster);
7917  av_freep(&track->cluster_written);
7918  av_freep(&track->frag_info);
7919  av_packet_free(&track->cover_image);
7920 
7921  if (track->eac3_priv) {
7922  struct eac3_info *info = track->eac3_priv;
7923  av_packet_free(&info->pkt);
7924  av_freep(&track->eac3_priv);
7925  }
7926  for (int j = 0; j < track->stsd_count; j++)
7927  av_freep(&track->extradata[j]);
7928  av_freep(&track->extradata);
7929  av_freep(&track->extradata_size);
7930 
7931  for (int i = 0; i < track->nb_tref_tags; i++)
7932  av_freep(&track->tref_tags[i].id);
7933  av_freep(&track->tref_tags);
7934  av_freep(&track->src_track);
7935 
7936  ff_mov_cenc_free(&track->cenc);
7937  ffio_free_dyn_buf(&track->mdat_buf);
7938 
7939 #if CONFIG_IAMFENC
7940  ffio_free_dyn_buf(&track->iamf_buf);
7941  if (track->iamf)
7942  ff_iamf_uninit_context(track->iamf);
7943  av_freep(&track->iamf);
7944 #endif
7945  ff_isom_close_apvc(&track->apv);
7946 
7948  }
7949 
7950  av_freep(&mov->tracks);
7951  ffio_free_dyn_buf(&mov->mdat_buf);
7952 }
7953 
7954 static uint32_t rgb_to_yuv(uint32_t rgb)
7955 {
7956  uint8_t r, g, b;
7957  int y, cb, cr;
7958 
7959  r = (rgb >> 16) & 0xFF;
7960  g = (rgb >> 8) & 0xFF;
7961  b = (rgb ) & 0xFF;
7962 
7963  y = av_clip_uint8(( 16000 + 257 * r + 504 * g + 98 * b)/1000);
7964  cb = av_clip_uint8((128000 - 148 * r - 291 * g + 439 * b)/1000);
7965  cr = av_clip_uint8((128000 + 439 * r - 368 * g - 71 * b)/1000);
7966 
7967  return (y << 16) | (cr << 8) | cb;
7968 }
7969 
7971  AVStream *st)
7972 {
7973  int i, width = 720, height = 480;
7974  int have_palette = 0, have_size = 0;
7975  uint32_t palette[16];
7976  char *cur = st->codecpar->extradata;
7977 
7978  while (cur && *cur) {
7979  if (strncmp("palette:", cur, 8) == 0) {
7980  int i, count;
7981  count = sscanf(cur + 8,
7982  "%06"PRIx32", %06"PRIx32", %06"PRIx32", %06"PRIx32", "
7983  "%06"PRIx32", %06"PRIx32", %06"PRIx32", %06"PRIx32", "
7984  "%06"PRIx32", %06"PRIx32", %06"PRIx32", %06"PRIx32", "
7985  "%06"PRIx32", %06"PRIx32", %06"PRIx32", %06"PRIx32"",
7986  &palette[ 0], &palette[ 1], &palette[ 2], &palette[ 3],
7987  &palette[ 4], &palette[ 5], &palette[ 6], &palette[ 7],
7988  &palette[ 8], &palette[ 9], &palette[10], &palette[11],
7989  &palette[12], &palette[13], &palette[14], &palette[15]);
7990 
7991  for (i = 0; i < count; i++) {
7992  palette[i] = rgb_to_yuv(palette[i]);
7993  }
7994  have_palette = 1;
7995  } else if (!strncmp("size:", cur, 5)) {
7996  sscanf(cur + 5, "%dx%d", &width, &height);
7997  have_size = 1;
7998  }
7999  if (have_palette && have_size)
8000  break;
8001  cur += strcspn(cur, "\n\r");
8002  cur += strspn(cur, "\n\r");
8003  }
8004  if (have_palette) {
8006  if (!track->extradata[track->last_stsd_index])
8007  return AVERROR(ENOMEM);
8008  for (i = 0; i < 16; i++) {
8009  AV_WB32(track->extradata[track->last_stsd_index] + i * 4, palette[i]);
8010  }
8011  memset(track->extradata[track->last_stsd_index] + 16*4, 0, AV_INPUT_BUFFER_PADDING_SIZE);
8012  track->extradata_size[track->last_stsd_index] = 16 * 4;
8013  }
8014  st->codecpar->width = width;
8015  st->codecpar->height = track->height = height;
8016 
8017  return 0;
8018 }
8019 
8020 #if CONFIG_IAMFENC
8021 static int mov_init_iamf_track(AVFormatContext *s)
8022 {
8023  MOVMuxContext *mov = s->priv_data;
8024  MOVTrack *track;
8025  IAMFContext *iamf;
8026  int first_iamf_idx = INT_MAX, last_iamf_idx = 0;
8027  int nb_audio_elements = 0, nb_mix_presentations = 0;
8028  int ret;
8029 
8030  for (int i = 0; i < s->nb_stream_groups; i++) {
8031  const AVStreamGroup *stg = s->stream_groups[i];
8032 
8034  nb_audio_elements++;
8036  nb_mix_presentations++;
8037  }
8038 
8039  if (!nb_audio_elements && !nb_mix_presentations)
8040  return 0;
8041 
8042  if (nb_audio_elements < 1 || nb_audio_elements > 2 || nb_mix_presentations < 1) {
8043  av_log(s, AV_LOG_ERROR, "There must be >= 1 and <= 2 IAMF_AUDIO_ELEMENT and at least "
8044  "one IAMF_MIX_PRESENTATION stream groups to write a IMAF track\n");
8045  return AVERROR(EINVAL);
8046  }
8047 
8048  iamf = av_mallocz(sizeof(*iamf));
8049  if (!iamf)
8050  return AVERROR(ENOMEM);
8051 
8052 
8053  for (int i = 0; i < s->nb_stream_groups; i++) {
8054  const AVStreamGroup *stg = s->stream_groups[i];
8055  switch(stg->type) {
8057  for (int j = 0; j < stg->nb_streams; j++) {
8058  first_iamf_idx = FFMIN(stg->streams[j]->index, first_iamf_idx);
8059  last_iamf_idx = FFMAX(stg->streams[j]->index, last_iamf_idx);
8060  }
8061 
8062  ret = ff_iamf_add_audio_element(iamf, stg, s);
8063  break;
8065  ret = ff_iamf_add_mix_presentation(iamf, stg, s);
8066  break;
8067  default:
8068  av_assert0(0);
8069  }
8070  if (ret < 0) {
8071  ff_iamf_uninit_context(iamf);
8072  av_free(iamf);
8073  return ret;
8074  }
8075  }
8076 
8077  track = &mov->tracks[first_iamf_idx];
8078  track->iamf = iamf;
8079  track->first_iamf_idx = first_iamf_idx;
8080  track->last_iamf_idx = last_iamf_idx;
8081  track->tag = MKTAG('i','a','m','f');
8082 
8083  for (int i = 0; i < s->nb_stream_groups; i++) {
8084  AVStreamGroup *stg = s->stream_groups[i];
8086  continue;
8087  for (int j = 0; j < stg->nb_streams; j++)
8088  stg->streams[j]->priv_data = track;
8089  }
8090 
8091  ret = avio_open_dyn_buf(&track->iamf_buf);
8092  if (ret < 0)
8093  return ret;
8094 
8095  return 0;
8096 }
8097 #endif
8098 
8100 {
8101  MOVMuxContext *mov = s->priv_data;
8102  int has_iamf = 0;
8103  int i, ret;
8104 
8105  mov->fc = s;
8106  mov->pkt = ffformatcontext(s)->pkt;
8107 
8108  /* Default mode == MP4 */
8109  mov->mode = MODE_MP4;
8110 
8111 #define IS_MODE(muxer, config) (CONFIG_ ## config ## _MUXER && !strcmp(#muxer, s->oformat->name))
8112  if (IS_MODE(3gp, TGP)) mov->mode = MODE_3GP;
8113  else if (IS_MODE(3g2, TG2)) mov->mode = MODE_3GP|MODE_3G2;
8114  else if (IS_MODE(mov, MOV)) mov->mode = MODE_MOV;
8115  else if (IS_MODE(psp, PSP)) mov->mode = MODE_PSP;
8116  else if (IS_MODE(ipod, IPOD)) mov->mode = MODE_IPOD;
8117  else if (IS_MODE(ismv, ISMV)) mov->mode = MODE_ISM;
8118  else if (IS_MODE(f4v, F4V)) mov->mode = MODE_F4V;
8119  else if (IS_MODE(avif, AVIF)) mov->mode = MODE_AVIF;
8120 #undef IS_MODE
8121 
8122  if (mov->flags & FF_MOV_FLAG_DELAY_MOOV)
8123  mov->flags |= FF_MOV_FLAG_EMPTY_MOOV;
8124 
8125  if (mov->mode == MODE_AVIF)
8126  mov->flags |= FF_MOV_FLAG_DELAY_MOOV;
8127 
8128  /* Set the FRAGMENT flag if any of the fragmentation methods are
8129  * enabled. */
8130  if (mov->max_fragment_duration || mov->max_fragment_size ||
8131  mov->flags & (FF_MOV_FLAG_EMPTY_MOOV |
8135  mov->flags |= FF_MOV_FLAG_FRAGMENT;
8136 
8137  if (mov->flags & FF_MOV_FLAG_HYBRID_FRAGMENTED &&
8138  mov->flags & FF_MOV_FLAG_FASTSTART) {
8139  av_log(s, AV_LOG_ERROR, "Setting both hybrid_fragmented and faststart is not supported.\n");
8140  return AVERROR(EINVAL);
8141  }
8142 
8143  /* Set other implicit flags immediately */
8145  mov->flags |= FF_MOV_FLAG_FRAGMENT;
8146 
8147  if (mov->mode == MODE_ISM)
8150  if (mov->flags & FF_MOV_FLAG_DASH)
8153  if (mov->flags & FF_MOV_FLAG_CMAF)
8156 
8157  if (mov->flags & FF_MOV_FLAG_EMPTY_MOOV && s->flags & AVFMT_FLAG_AUTO_BSF) {
8158  av_log(s, AV_LOG_VERBOSE, "Empty MOOV enabled; disabling automatic bitstream filtering\n");
8159  s->flags &= ~AVFMT_FLAG_AUTO_BSF;
8160  }
8161 
8163  av_log(s, AV_LOG_WARNING, "Global SIDX enabled; Ignoring skip_sidx option\n");
8164  mov->flags &= ~FF_MOV_FLAG_SKIP_SIDX;
8165  }
8166 
8167  if (mov->flags & FF_MOV_FLAG_FASTSTART) {
8168  mov->reserved_moov_size = -1;
8169  }
8170 
8171  if (mov->use_editlist < 0) {
8172  mov->use_editlist = 1;
8173  if (mov->flags & FF_MOV_FLAG_FRAGMENT &&
8174  !(mov->flags & FF_MOV_FLAG_DELAY_MOOV)) {
8175  // If we can avoid needing an edit list by shifting the
8176  // tracks, prefer that over (trying to) write edit lists
8177  // in fragmented output.
8178  if (s->avoid_negative_ts == AVFMT_AVOID_NEG_TS_AUTO ||
8179  s->avoid_negative_ts == AVFMT_AVOID_NEG_TS_MAKE_ZERO)
8180  mov->use_editlist = 0;
8181  }
8182  }
8183  if (mov->flags & FF_MOV_FLAG_EMPTY_MOOV &&
8184  !(mov->flags & FF_MOV_FLAG_DELAY_MOOV) && mov->use_editlist)
8185  av_log(s, AV_LOG_WARNING, "No meaningful edit list will be written when using empty_moov without delay_moov\n");
8186 
8187  if (!mov->use_editlist && s->avoid_negative_ts == AVFMT_AVOID_NEG_TS_AUTO &&
8189  s->avoid_negative_ts = AVFMT_AVOID_NEG_TS_MAKE_ZERO;
8190 
8191  /* Clear the omit_tfhd_offset flag if default_base_moof is set;
8192  * if the latter is set that's enough and omit_tfhd_offset doesn't
8193  * add anything extra on top of that. */
8194  if (mov->flags & FF_MOV_FLAG_OMIT_TFHD_OFFSET &&
8197 
8198  if (mov->frag_interleave &&
8201  "Sample interleaving in fragments is mutually exclusive with "
8202  "omit_tfhd_offset and separate_moof\n");
8203  return AVERROR(EINVAL);
8204  }
8205 
8206  /* Non-seekable output is ok if using fragmentation. If ism_lookahead
8207  * is enabled, we don't support non-seekable output at all. */
8208  if (!(s->pb->seekable & AVIO_SEEKABLE_NORMAL) &&
8209  (!(mov->flags & FF_MOV_FLAG_FRAGMENT) || mov->ism_lookahead ||
8210  mov->mode == MODE_AVIF)) {
8211  av_log(s, AV_LOG_ERROR, "muxer does not support non seekable output\n");
8212  return AVERROR(EINVAL);
8213  }
8214 
8215  /* AVIF output must have at most two video streams (one for YUV and one for
8216  * alpha). */
8217  if (mov->mode == MODE_AVIF) {
8218  if (s->nb_streams > 2) {
8219  av_log(s, AV_LOG_ERROR, "AVIF output requires exactly one or two streams\n");
8220  return AVERROR(EINVAL);
8221  }
8222  if (s->streams[0]->codecpar->codec_type != AVMEDIA_TYPE_VIDEO &&
8223  (s->nb_streams > 1 && s->streams[1]->codecpar->codec_type != AVMEDIA_TYPE_VIDEO)) {
8224  av_log(s, AV_LOG_ERROR, "AVIF output supports only video streams\n");
8225  return AVERROR(EINVAL);
8226  }
8227  if (s->nb_streams > 1) {
8228  const AVPixFmtDescriptor *pixdesc =
8229  av_pix_fmt_desc_get(s->streams[1]->codecpar->format);
8230  if (pixdesc->nb_components != 1) {
8231  av_log(s, AV_LOG_ERROR, "Second stream for AVIF (alpha) output must have exactly one plane\n");
8232  return AVERROR(EINVAL);
8233  }
8234  }
8235  s->streams[0]->disposition |= AV_DISPOSITION_DEFAULT;
8236  }
8237 
8238  for (i = 0; i < s->nb_stream_groups; i++) {
8239  AVStreamGroup *stg = s->stream_groups[i];
8240 
8241  if (stg->type == AV_STREAM_GROUP_PARAMS_LCEVC) {
8242  if (stg->nb_streams != 2) {
8243  av_log(s, AV_LOG_ERROR, "Exactly two Streams are supported for Stream Groups of type LCEVC\n");
8244  return AVERROR(EINVAL);
8245  }
8246  AVStreamGroupLCEVC *lcevc = stg->params.lcevc;
8247  if (lcevc->lcevc_index > 1)
8248  return AVERROR(EINVAL);
8249  AVStream *st = stg->streams[lcevc->lcevc_index];
8250  if (st->codecpar->codec_id != AV_CODEC_ID_LCEVC) {
8251  av_log(s, AV_LOG_ERROR, "Stream #%u is not an LCEVC stream\n", lcevc->lcevc_index);
8252  return AVERROR(EINVAL);
8253  }
8254  }
8255 
8256 #if CONFIG_IAMFENC
8258  continue;
8259 
8260  for (int j = 0; j < stg->nb_streams; j++) {
8261  AVStream *st = stg->streams[j];
8262 
8263  if (st->priv_data) {
8264  av_log(s, AV_LOG_ERROR, "Stream %d is present in more than one Stream Group of type "
8265  "IAMF Audio Element\n", j);
8266  return AVERROR(EINVAL);
8267  }
8268  st->priv_data = st;
8269  }
8270  has_iamf = 1;
8271 
8272  if (!mov->nb_tracks) // We support one track for the entire IAMF structure
8273  mov->nb_tracks++;
8274 #endif
8275  }
8276 
8277  for (i = 0; i < s->nb_streams; i++) {
8278  AVStream *st = s->streams[i];
8279  if (st->priv_data)
8280  continue;
8281  // Don't produce a track in the output file for timed ID3 streams.
8282  if (st->codecpar->codec_id == AV_CODEC_ID_TIMED_ID3) {
8283  // Leave priv_data set to NULL for these AVStreams that don't
8284  // have a corresponding track.
8285  continue;
8286  }
8287  st->priv_data = st;
8288  mov->nb_tracks++;
8289  }
8290 
8291  mov->nb_streams = mov->nb_tracks;
8292 
8293  if (mov->mode & (MODE_MP4|MODE_MOV|MODE_IPOD) && s->nb_chapters)
8294  mov->chapter_track = mov->nb_tracks++;
8295 
8296  if (mov->flags & FF_MOV_FLAG_RTP_HINT) {
8297  for (i = 0; i < s->nb_streams; i++)
8298  if (rtp_hinting_needed(s->streams[i]))
8299  mov->nb_tracks++;
8300  }
8301 
8302  if (mov->write_btrt < 0) {
8303  mov->write_btrt = mov->mode == MODE_MP4;
8304  }
8305 
8306  if ( mov->write_tmcd == -1 && (mov->mode == MODE_MOV || mov->mode == MODE_MP4)
8307  || mov->write_tmcd == 1) {
8308  AVDictionaryEntry *global_tcr = av_dict_get(s->metadata, "timecode",
8309  NULL, 0);
8310 
8311  /* +1 tmcd track for each video stream with a timecode */
8312  for (i = 0; i < s->nb_streams; i++) {
8313  AVStream *st = s->streams[i];
8314  AVDictionaryEntry *t = global_tcr;
8315  if (st->codecpar->codec_type == AVMEDIA_TYPE_VIDEO &&
8316  (t || (t=av_dict_get(st->metadata, "timecode", NULL, 0)))) {
8317  AVTimecode tc;
8318  ret = mov_check_timecode_track(s, &tc, st, t->value);
8319  if (ret >= 0)
8320  mov->nb_meta_tmcd++;
8321  }
8322  }
8323 
8324  /* check if there is already a tmcd track to remux */
8325  if (mov->nb_meta_tmcd) {
8326  for (i = 0; i < s->nb_streams; i++) {
8327  AVStream *st = s->streams[i];
8328  if (st->codecpar->codec_tag == MKTAG('t','m','c','d')) {
8329  av_log(s, AV_LOG_WARNING, "You requested a copy of the original timecode track "
8330  "so timecode metadata are now ignored\n");
8331  mov->nb_meta_tmcd = 0;
8332  }
8333  }
8334  }
8335 
8336  mov->nb_tracks += mov->nb_meta_tmcd;
8337  }
8338 
8339  // Reserve an extra stream for chapters for the case where chapters
8340  // are written in the trailer
8341  mov->tracks = av_calloc(mov->nb_tracks + 1, sizeof(*mov->tracks));
8342  if (!mov->tracks)
8343  return AVERROR(ENOMEM);
8344 
8345  for (i = 0; i < mov->nb_tracks; i++) {
8346  MOVTrack *track = &mov->tracks[i];
8347 
8348  track->stsd_count = 1;
8349  track->extradata = av_calloc(track->stsd_count, sizeof(*track->extradata));
8350  track->extradata_size = av_calloc(track->stsd_count, sizeof(*track->extradata_size));
8351  if (!track->extradata || !track->extradata_size)
8352  return AVERROR(ENOMEM);
8353  }
8354 
8355  if (mov->encryption_scheme_str != NULL && strcmp(mov->encryption_scheme_str, "none") != 0) {
8356  if (strcmp(mov->encryption_scheme_str, "cenc-aes-ctr") == 0) {
8358 
8359  if (mov->encryption_key_len != AES_CTR_KEY_SIZE) {
8360  av_log(s, AV_LOG_ERROR, "Invalid encryption key len %d expected %d\n",
8362  return AVERROR(EINVAL);
8363  }
8364 
8365  if (mov->encryption_kid_len != CENC_KID_SIZE) {
8366  av_log(s, AV_LOG_ERROR, "Invalid encryption kid len %d expected %d\n",
8368  return AVERROR(EINVAL);
8369  }
8370  } else {
8371  av_log(s, AV_LOG_ERROR, "unsupported encryption scheme %s\n",
8372  mov->encryption_scheme_str);
8373  return AVERROR(EINVAL);
8374  }
8375  }
8376 
8377 #if CONFIG_IAMFENC
8378  ret = mov_init_iamf_track(s);
8379  if (ret < 0)
8380  return ret;
8381 #endif
8382 
8383  for (int j = 0, i = 0; j < s->nb_streams; j++) {
8384  AVStream *st = s->streams[j];
8385 
8386  if (st != st->priv_data) {
8387  if (has_iamf)
8388  i += has_iamf--;
8389  continue;
8390  }
8391  st->priv_data = &mov->tracks[i++];
8392  }
8393 
8394  for (i = 0; i < s->nb_streams; i++) {
8395  AVStream *st= s->streams[i];
8396  MOVTrack *track = st->priv_data;
8397  AVDictionaryEntry *lang = av_dict_get(st->metadata, "language", NULL,0);
8398 
8399  if (!track)
8400  continue;
8401 
8402  if (!track->st) {
8403  track->st = st;
8404  track->par = st->codecpar;
8405  }
8406  track->language = ff_mov_iso639_to_lang(lang?lang->value:"und", mov->mode!=MODE_MOV);
8407  if (track->language < 0)
8408  track->language = 32767; // Unspecified Macintosh language code
8409  track->mode = mov->mode;
8410  if (!track->tag)
8411  track->tag = mov_find_codec_tag(s, track);
8412  if (!track->tag) {
8413  av_log(s, AV_LOG_ERROR, "Could not find tag for codec %s in stream #%d, "
8414  "codec not currently supported in container\n",
8416  return AVERROR(EINVAL);
8417  }
8418  /* If hinting of this track is enabled by a later hint track,
8419  * this is updated. */
8420  track->hint_track = -1;
8421  track->start_dts = AV_NOPTS_VALUE;
8422  track->start_cts = AV_NOPTS_VALUE;
8423  track->end_pts = AV_NOPTS_VALUE;
8424  track->dts_shift = AV_NOPTS_VALUE;
8425  if (st->codecpar->codec_type == AVMEDIA_TYPE_VIDEO) {
8426  if (track->tag == MKTAG('m','x','3','p') || track->tag == MKTAG('m','x','3','n') ||
8427  track->tag == MKTAG('m','x','4','p') || track->tag == MKTAG('m','x','4','n') ||
8428  track->tag == MKTAG('m','x','5','p') || track->tag == MKTAG('m','x','5','n')) {
8429  if (st->codecpar->width != 720 || (st->codecpar->height != 608 && st->codecpar->height != 512)) {
8430  av_log(s, AV_LOG_ERROR, "D-10/IMX must use 720x608 or 720x512 video resolution\n");
8431  return AVERROR(EINVAL);
8432  }
8433  track->height = track->tag >> 24 == 'n' ? 486 : 576;
8434  }
8435  if (mov->video_track_timescale) {
8436  track->timescale = mov->video_track_timescale;
8437  if (mov->mode == MODE_ISM && mov->video_track_timescale != 10000000)
8438  av_log(s, AV_LOG_WARNING, "Warning: some tools, like mp4split, assume a timescale of 10000000 for ISMV.\n");
8439  } else {
8440  track->timescale = st->time_base.den;
8441  while(track->timescale < 10000)
8442  track->timescale *= 2;
8443  }
8444  if (st->codecpar->width > 65535 || st->codecpar->height > 65535) {
8445  av_log(s, AV_LOG_ERROR, "Resolution %dx%d too large for mov/mp4\n", st->codecpar->width, st->codecpar->height);
8446  return AVERROR(EINVAL);
8447  }
8448  if (track->mode == MODE_MOV && track->timescale > 100000)
8450  "WARNING codec timebase is very high. If duration is too long,\n"
8451  "file may not be playable by quicktime. Specify a shorter timebase\n"
8452  "or choose different container.\n");
8453  if (track->mode == MODE_MOV &&
8454  track->par->codec_id == AV_CODEC_ID_RAWVIDEO &&
8455  track->tag == MKTAG('r','a','w',' ')) {
8456  enum AVPixelFormat pix_fmt = track->par->format;
8457  if (pix_fmt == AV_PIX_FMT_NONE && track->par->bits_per_coded_sample == 1)
8459  track->is_unaligned_qt_rgb =
8462  pix_fmt == AV_PIX_FMT_PAL8 ||
8466  }
8467  if (track->par->codec_id == AV_CODEC_ID_VP9 && track->mode != MODE_MP4) {
8468  av_log(s, AV_LOG_ERROR, "%s only supported in MP4.\n", avcodec_get_name(track->par->codec_id));
8469  return AVERROR(EINVAL);
8470  } else if (track->par->codec_id == AV_CODEC_ID_AV1 &&
8471  track->mode != MODE_MP4 && track->mode != MODE_AVIF) {
8472  av_log(s, AV_LOG_ERROR, "%s only supported in MP4 and AVIF.\n", avcodec_get_name(track->par->codec_id));
8473  return AVERROR(EINVAL);
8474  } else if (track->par->codec_id == AV_CODEC_ID_VP8) {
8475  /* altref frames handling is not defined in the spec as of version v1.0,
8476  * so just forbid muxing VP8 streams altogether until a new version does */
8477  av_log(s, AV_LOG_ERROR, "VP8 muxing is currently not supported.\n");
8478  return AVERROR_PATCHWELCOME;
8479  } else if (track->par->codec_id == AV_CODEC_ID_APV) {
8480  ret = ff_isom_init_apvc(&track->apv, s);
8481  if (ret < 0)
8482  return ret;
8483  }
8484  if (is_cover_image(st)) {
8485  track->cover_image = av_packet_alloc();
8486  if (!track->cover_image)
8487  return AVERROR(ENOMEM);
8488  }
8489  } else if (st->codecpar->codec_type == AVMEDIA_TYPE_AUDIO) {
8490  track->timescale = st->codecpar->sample_rate;
8492  av_log(s, AV_LOG_WARNING, "track %d: codec frame size is not set\n", i);
8493  track->audio_vbr = 1;
8494  }else if (st->codecpar->codec_id == AV_CODEC_ID_ADPCM_MS ||
8497  if (!st->codecpar->block_align) {
8498  av_log(s, AV_LOG_ERROR, "track %d: codec block align is not set for adpcm\n", i);
8499  return AVERROR(EINVAL);
8500  }
8501  track->sample_size = st->codecpar->block_align;
8502  }else if (st->codecpar->frame_size > 1){ /* assume compressed audio */
8503  track->audio_vbr = 1;
8504  }else{
8505  track->sample_size = (av_get_bits_per_sample(st->codecpar->codec_id) >> 3) *
8507  }
8508  if (st->codecpar->codec_id == AV_CODEC_ID_ILBC ||
8510  track->audio_vbr = 1;
8511  }
8512  if (track->mode != MODE_MOV &&
8513  track->par->codec_id == AV_CODEC_ID_MP3 && track->timescale < 16000) {
8514  if (s->strict_std_compliance >= FF_COMPLIANCE_NORMAL) {
8515  av_log(s, AV_LOG_ERROR, "track %d: muxing mp3 at %dhz is not standard, to mux anyway set strict to -1\n",
8516  i, track->par->sample_rate);
8517  return AVERROR(EINVAL);
8518  } else {
8519  av_log(s, AV_LOG_WARNING, "track %d: muxing mp3 at %dhz is not standard in MP4\n",
8520  i, track->par->sample_rate);
8521  }
8522  }
8523  if (track->par->codec_id == AV_CODEC_ID_FLAC ||
8524  track->par->codec_id == AV_CODEC_ID_TRUEHD ||
8525  track->par->codec_id == AV_CODEC_ID_OPUS) {
8526  if (track->mode != MODE_MP4) {
8527  av_log(s, AV_LOG_ERROR, "%s only supported in MP4.\n", avcodec_get_name(track->par->codec_id));
8528  return AVERROR(EINVAL);
8529  }
8530  if (track->par->codec_id == AV_CODEC_ID_TRUEHD &&
8531  s->strict_std_compliance > FF_COMPLIANCE_EXPERIMENTAL) {
8533  "%s in MP4 support is experimental, add "
8534  "'-strict %d' if you want to use it.\n",
8536  return AVERROR_EXPERIMENTAL;
8537  }
8538  }
8539  } else if (st->codecpar->codec_type == AVMEDIA_TYPE_SUBTITLE) {
8540  track->timescale = st->time_base.den;
8541 
8542  if (track->par->codec_id == AV_CODEC_ID_TTML) {
8543  /* 14496-30 requires us to use a single sample per fragment
8544  for TTML, for which we define a per-track flag.
8545 
8546  We set the flag in case we are receiving TTML paragraphs
8547  from the input, in other words in case we are not doing
8548  stream copy. */
8551 
8552  if (track->mode != MODE_ISM &&
8553  track->par->codec_tag == MOV_ISMV_TTML_TAG &&
8554  s->strict_std_compliance > FF_COMPLIANCE_UNOFFICIAL) {
8556  "ISMV style TTML support with the 'dfxp' tag in "
8557  "non-ISMV formats is not officially supported. Add "
8558  "'-strict unofficial' if you want to use it.\n");
8559  return AVERROR_EXPERIMENTAL;
8560  }
8561  }
8562  } else if (st->codecpar->codec_type == AVMEDIA_TYPE_DATA) {
8563  track->timescale = st->time_base.den;
8564  } else {
8565  track->timescale = mov->movie_timescale;
8566  }
8567  if (!track->height)
8568  track->height = st->codecpar->height;
8569  /* The Protected Interoperable File Format (PIFF) standard, used by ISMV recommends but
8570  doesn't mandate a track timescale of 10,000,000. The muxer allows a custom timescale
8571  for video tracks, so if user-set, it isn't overwritten */
8572  if (mov->mode == MODE_ISM &&
8575  track->timescale = 10000000;
8576  }
8577 
8578  avpriv_set_pts_info(st, 64, 1, track->timescale);
8579 
8581  ret = ff_mov_cenc_init(&track->cenc, mov->encryption_key,
8582  (track->par->codec_id == AV_CODEC_ID_H264 || track->par->codec_id == AV_CODEC_ID_HEVC ||
8583  track->par->codec_id == AV_CODEC_ID_VVC || track->par->codec_id == AV_CODEC_ID_AV1),
8584  track->par->codec_id, s->flags & AVFMT_FLAG_BITEXACT);
8585  if (ret)
8586  return ret;
8587  }
8588  }
8589 
8590  for (i = 0; i < s->nb_stream_groups; i++) {
8591  AVStreamGroup *stg = s->stream_groups[i];
8592 
8593  switch (stg->type) {
8595  AVStreamGroupLCEVC *lcevc = stg->params.lcevc;
8596  AVStream *st = stg->streams[lcevc->lcevc_index];
8597  MOVTrack *track = st->priv_data;
8598 
8599  for (int j = 0; j < mov->nb_tracks; j++) {
8600  MOVTrack *trk = &mov->tracks[j];
8601 
8602  if (trk->st == stg->streams[!lcevc->lcevc_index]) {
8603  track->src_track = av_malloc(sizeof(*track->src_track));
8604  if (!track->src_track)
8605  return AVERROR(ENOMEM);
8606  *track->src_track = j;
8607  track->nb_src_track = 1;
8608  break;
8609  }
8610  }
8611 
8612  track->par->width = lcevc->width;
8613  track->par->height = track->height = lcevc->height;
8614  break;
8615  }
8617  const AVStreamGroupTREF *tref = stg->params.tref;
8618  MOVTrack *track;
8619 
8620  if (tref->metadata_index >= stg->nb_streams)
8621  return AVERROR(EINVAL);
8622 
8623  track = stg->streams[tref->metadata_index]->priv_data;
8624  for (int j = 0; j < stg->nb_streams; j++) {
8625  const AVStream *st2 = stg->streams[j];
8626  int index = -1;
8627 
8628  if (j == tref->metadata_index)
8629  continue;
8630 
8631  for (int k = 0; k < mov->nb_tracks; k++) {
8632  if (mov->tracks[k].st != st2)
8633  continue;
8634  index = k;
8635  break;
8636  }
8637  if (index < 0)
8638  return AVERROR(EINVAL);
8639 
8640  int *tmp = av_realloc(track->src_track,
8641  (track->nb_src_track + 1) * sizeof(*track->src_track));
8642  if (!tmp)
8643  return AVERROR(ENOMEM);
8644  track->src_track = tmp;
8645  track->src_track[track->nb_src_track++] = index;
8646  }
8647  break;
8648  }
8649  default:
8650  break;
8651  }
8652  }
8653 
8654  /* fill src_track for tmcd tracks not covered by stream groups or
8655  * created by this muxer, retaining the old behavior of src_track
8656  * being arbitrarily 0. */
8657  for (i = 0; i < s->nb_streams; i++) {
8658  AVStream *st = s->streams[i];
8659  MOVTrack *track = st->priv_data;
8660  if (st->codecpar->codec_tag != MKTAG('t','m','c','d') ||
8661  track->nb_src_track)
8662  continue;
8663 
8664  track->src_track = av_malloc(sizeof(*track->src_track));
8665  if (!track->src_track)
8666  return AVERROR(ENOMEM);
8667  *track->src_track = 0;
8668  track->nb_src_track = 1;
8669  }
8670 
8671  enable_tracks(s);
8672  return 0;
8673 }
8674 
8676 {
8677  AVIOContext *pb = s->pb;
8678  MOVMuxContext *mov = s->priv_data;
8679  int ret, hint_track = 0, tmcd_track = 0, nb_tracks = mov->nb_streams;
8680 
8681  if (mov->mode & (MODE_MP4|MODE_MOV|MODE_IPOD) && s->nb_chapters)
8682  nb_tracks++;
8683 
8684  if (mov->flags & FF_MOV_FLAG_RTP_HINT) {
8685  hint_track = nb_tracks;
8686  for (int i = 0; i < mov->nb_streams; i++) {
8687  if (rtp_hinting_needed(mov->tracks[i].st))
8688  nb_tracks++;
8689  }
8690  }
8691 
8692  if (mov->nb_meta_tmcd)
8693  tmcd_track = nb_tracks;
8694 
8695  for (int i = 0; i < mov->nb_streams; i++) {
8696  MOVTrack *track = &mov->tracks[i];
8697  AVStream *st = track->st;
8698 
8699  /* copy extradata if it exists */
8700  if (st->codecpar->extradata_size) {
8703  else if (!TAG_IS_AVCI(track->tag) && st->codecpar->codec_id != AV_CODEC_ID_DNXHD) {
8704  track->extradata_size[track->last_stsd_index] = st->codecpar->extradata_size;
8705  track->extradata[track->last_stsd_index] =
8707  if (!track->extradata[track->last_stsd_index]) {
8708  return AVERROR(ENOMEM);
8709  }
8710  memcpy(track->extradata[track->last_stsd_index],
8711  st->codecpar->extradata, track->extradata_size[track->last_stsd_index]);
8712  memset(track->extradata[track->last_stsd_index] + track->extradata_size[track->last_stsd_index],
8714  }
8715  }
8716 
8717  if (st->codecpar->codec_type != AVMEDIA_TYPE_AUDIO ||
8720  continue;
8721 
8722  for (int j = 0; j < mov->nb_streams; j++) {
8723  AVStream *stj= mov->tracks[j].st;
8724  MOVTrack *trackj= &mov->tracks[j];
8725  if (j == i)
8726  continue;
8727 
8728  if (stj->codecpar->codec_type == AVMEDIA_TYPE_AUDIO &&
8729  (trackj->par->ch_layout.nb_channels != 1 ||
8732  )
8733  track->mono_as_fc = -1;
8734 
8735  if (stj->codecpar->codec_type == AVMEDIA_TYPE_AUDIO &&
8738  trackj->par->ch_layout.nb_channels == 1 && track->mono_as_fc >= 0
8739  )
8740  track->mono_as_fc++;
8741 
8742  if (stj->codecpar->codec_type != AVMEDIA_TYPE_AUDIO ||
8745  trackj->language != track->language ||
8746  trackj->tag != track->tag
8747  )
8748  continue;
8749  track->multichannel_as_mono++;
8750  }
8751  }
8752 
8753  if (!(mov->flags & FF_MOV_FLAG_DELAY_MOOV) ||
8755  if ((ret = mov_write_identification(pb, s)) < 0)
8756  return ret;
8757  }
8758 
8759  if (mov->reserved_moov_size){
8760  mov->reserved_header_pos = avio_tell(pb);
8761  if (mov->reserved_moov_size > 0)
8762  avio_skip(pb, mov->reserved_moov_size);
8763  }
8764 
8765  if (mov->flags & FF_MOV_FLAG_FRAGMENT) {
8766  /* If no fragmentation options have been set, set a default. */
8767  if (!(mov->flags & (FF_MOV_FLAG_FRAG_KEYFRAME |
8772  if (mov->flags & FF_MOV_FLAG_HYBRID_FRAGMENTED) {
8773  avio_wb32(pb, 8); // placeholder for extended size field (64 bit)
8774  ffio_wfourcc(pb, mov->mode == MODE_MOV ? "wide" : "free");
8775  mov->mdat_pos = avio_tell(pb);
8776  // The free/wide header that later will be converted into an
8777  // mdat, covering the initial moov and all the fragments.
8778  avio_wb32(pb, 0);
8779  ffio_wfourcc(pb, mov->mode == MODE_MOV ? "wide" : "free");
8780  // Write an ftyp atom, hidden in a free/wide. This is neither
8781  // exposed while the file is written, as fragmented, nor when the
8782  // file is finalized into non-fragmented form. However, this allows
8783  // accessing a pristine, sequential ftyp+moov init segment, even
8784  // after the file is finalized. It also allows dumping the whole
8785  // contents of the mdat box, to get the fragmented form of the
8786  // file.
8787  if ((ret = mov_write_identification(pb, s)) < 0)
8788  return ret;
8789  update_size(pb, mov->mdat_pos);
8790  }
8791  } else if (mov->mode != MODE_AVIF) {
8792  if (mov->flags & FF_MOV_FLAG_FASTSTART)
8793  mov->reserved_header_pos = avio_tell(pb);
8794  mov_write_mdat_tag(pb, mov);
8795  }
8796 
8798  if (mov->time)
8799  mov->time += 0x7C25B080; // 1970 based -> 1904 based
8800 
8801  if (mov->chapter_track)
8802  if ((ret = mov_create_chapter_track(s, mov->chapter_track)) < 0)
8803  return ret;
8804 
8805  if (mov->flags & FF_MOV_FLAG_RTP_HINT) {
8806  for (int i = 0; i < mov->nb_streams; i++) {
8807  if (rtp_hinting_needed(mov->tracks[i].st)) {
8808  if ((ret = ff_mov_init_hinting(s, hint_track, i)) < 0)
8809  return ret;
8810  hint_track++;
8811  }
8812  }
8813  }
8814 
8815  if (mov->nb_meta_tmcd) {
8816  const AVDictionaryEntry *t, *global_tcr = av_dict_get(s->metadata,
8817  "timecode", NULL, 0);
8818  /* Initialize the tmcd tracks */
8819  for (int i = 0; i < mov->nb_streams; i++) {
8820  AVStream *st = mov->tracks[i].st;
8821  t = global_tcr;
8822 
8823  if (st->codecpar->codec_type == AVMEDIA_TYPE_VIDEO) {
8824  AVTimecode tc;
8825  if (!t)
8826  t = av_dict_get(st->metadata, "timecode", NULL, 0);
8827  if (!t)
8828  continue;
8829  if (mov_check_timecode_track(s, &tc, st, t->value) < 0)
8830  continue;
8831  if ((ret = mov_create_timecode_track(s, tmcd_track, i, tc)) < 0)
8832  return ret;
8833  tmcd_track++;
8834  }
8835  }
8836  }
8837 
8838  avio_flush(pb);
8839 
8840  if (mov->flags & FF_MOV_FLAG_ISML)
8841  mov_write_isml_manifest(pb, mov, s);
8842 
8843  if (mov->flags & FF_MOV_FLAG_EMPTY_MOOV &&
8844  !(mov->flags & FF_MOV_FLAG_DELAY_MOOV)) {
8845  if ((ret = mov_write_moov_tag(pb, mov, s)) < 0)
8846  return ret;
8847  mov->moov_written = 1;
8848  if (mov->flags & FF_MOV_FLAG_GLOBAL_SIDX)
8849  mov->reserved_header_pos = avio_tell(pb);
8850  }
8851 
8852  return 0;
8853 }
8854 
8856 {
8857  int ret;
8858  AVIOContext *moov_buf;
8859  MOVMuxContext *mov = s->priv_data;
8860 
8861  if ((ret = ffio_open_null_buf(&moov_buf)) < 0)
8862  return ret;
8863  if ((ret = mov_write_moov_tag(moov_buf, mov, s)) < 0)
8864  return ret;
8865  return ffio_close_null_buf(moov_buf);
8866 }
8867 
8869 {
8870  int ret;
8871  AVIOContext *buf;
8872  MOVMuxContext *mov = s->priv_data;
8873 
8874  if ((ret = ffio_open_null_buf(&buf)) < 0)
8875  return ret;
8876  mov_write_sidx_tags(buf, mov, -1, 0);
8877  return ffio_close_null_buf(buf);
8878 }
8879 
8880 /*
8881  * This function gets the moov size if moved to the top of the file: the chunk
8882  * offset table can switch between stco (32-bit entries) to co64 (64-bit
8883  * entries) when the moov is moved to the beginning, so the size of the moov
8884  * would change. It also updates the chunk offset tables.
8885  */
8887 {
8888  int i, moov_size, moov_size2;
8889  MOVMuxContext *mov = s->priv_data;
8890 
8891  moov_size = get_moov_size(s);
8892  if (moov_size < 0)
8893  return moov_size;
8894 
8895  for (i = 0; i < mov->nb_tracks; i++)
8896  mov->tracks[i].data_offset += moov_size;
8897 
8898  moov_size2 = get_moov_size(s);
8899  if (moov_size2 < 0)
8900  return moov_size2;
8901 
8902  /* if the size changed, we just switched from stco to co64 and need to
8903  * update the offsets */
8904  if (moov_size2 != moov_size)
8905  for (i = 0; i < mov->nb_tracks; i++)
8906  mov->tracks[i].data_offset += moov_size2 - moov_size;
8907 
8908  return moov_size2;
8909 }
8910 
8912 {
8913  int i, sidx_size;
8914  MOVMuxContext *mov = s->priv_data;
8915 
8916  sidx_size = get_sidx_size(s);
8917  if (sidx_size < 0)
8918  return sidx_size;
8919 
8920  for (i = 0; i < mov->nb_tracks; i++)
8921  mov->tracks[i].data_offset += sidx_size;
8922 
8923  return sidx_size;
8924 }
8925 
8927 {
8928  int moov_size;
8929  MOVMuxContext *mov = s->priv_data;
8930 
8931  if (mov->flags & FF_MOV_FLAG_FRAGMENT)
8932  moov_size = compute_sidx_size(s);
8933  else
8934  moov_size = compute_moov_size(s);
8935  if (moov_size < 0)
8936  return moov_size;
8937 
8938  return ff_format_shift_data(s, mov->reserved_header_pos, moov_size);
8939 }
8940 
8942 {
8943  MOVMuxContext *mov = s->priv_data;
8944  AVIOContext *pb = s->pb;
8945 
8946  /* Write size of mdat tag */
8947  if (mov->mdat_size + 8 <= UINT32_MAX) {
8948  avio_seek(pb, mov->mdat_pos, SEEK_SET);
8949  avio_wb32(pb, mov->mdat_size + 8);
8951  ffio_wfourcc(pb, "mdat"); // overwrite the original free/wide into a mdat
8952  } else {
8953  /* overwrite 'wide' placeholder atom */
8954  avio_seek(pb, mov->mdat_pos - 8, SEEK_SET);
8955  /* special value: real atom size will be 64 bit value after
8956  * tag field */
8957  avio_wb32(pb, 1);
8958  ffio_wfourcc(pb, "mdat");
8959  avio_wb64(pb, mov->mdat_size + 16);
8960  }
8961 }
8962 
8964 {
8965  MOVMuxContext *mov = s->priv_data;
8966  AVIOContext *pb = s->pb;
8967  int res = 0;
8968  int i;
8969  int64_t moov_pos;
8970 
8971  /*
8972  * Before actually writing the trailer, make sure that there are no
8973  * dangling subtitles, that need a terminating sample.
8974  */
8975  for (i = 0; i < mov->nb_tracks; i++) {
8976  MOVTrack *trk = &mov->tracks[i];
8977  if (trk->par->codec_id == AV_CODEC_ID_MOV_TEXT &&
8980  trk->last_sample_is_subtitle_end = 1;
8981  }
8982  }
8983 
8984  // Check if we have any tracks that require squashing.
8985  // In that case, we'll have to write the packet here.
8986  if ((res = mov_write_squashed_packets(s)) < 0)
8987  return res;
8988 
8989  // If there were no chapters when the header was written, but there
8990  // are chapters now, write them in the trailer. This only works
8991  // when we are not doing fragments.
8992  if (!mov->chapter_track && !(mov->flags & FF_MOV_FLAG_FRAGMENT)) {
8993  if (mov->mode & (MODE_MP4|MODE_MOV|MODE_IPOD) && s->nb_chapters) {
8994  mov->chapter_track = mov->nb_tracks++;
8995  if ((res = mov_create_chapter_track(s, mov->chapter_track)) < 0)
8996  return res;
8997  }
8998  }
8999 
9000  if (!(mov->flags & FF_MOV_FLAG_FRAGMENT) ||
9002  if (mov->flags & FF_MOV_FLAG_HYBRID_FRAGMENTED) {
9004  mov->mdat_size = avio_tell(pb) - mov->mdat_pos - 8;
9005  for (i = 0; i < mov->nb_tracks; i++) {
9006  MOVTrack *track = &mov->tracks[i];
9007  track->data_offset = 0;
9008  av_free(track->cluster);
9009  track->cluster = track->cluster_written;
9010  track->entry = track->entry_written;
9011  track->cluster_written = NULL;
9012  track->entry_written = 0;
9013  track->chunkCount = 0; // Force build_chunks to rebuild the list of chunks
9014  }
9015  // Clear the empty_moov flag, as we do want the moov to include
9016  // all the samples at this point.
9017  mov->flags &= ~FF_MOV_FLAG_EMPTY_MOOV;
9018  }
9019 
9020  moov_pos = avio_tell(pb);
9021 
9022  if (!(mov->flags & FF_MOV_FLAG_HYBRID_FRAGMENTED))
9024 
9025  avio_seek(pb, mov->reserved_moov_size > 0 ? mov->reserved_header_pos : moov_pos, SEEK_SET);
9026 
9027  if (mov->flags & FF_MOV_FLAG_FASTSTART) {
9028  av_log(s, AV_LOG_INFO, "Starting second pass: moving the moov atom to the beginning of the file\n");
9029  res = shift_data(s);
9030  if (res < 0)
9031  return res;
9032  avio_seek(pb, mov->reserved_header_pos, SEEK_SET);
9033  if ((res = mov_write_moov_tag(pb, mov, s)) < 0)
9034  return res;
9035  } else if (mov->reserved_moov_size > 0) {
9036  int64_t size;
9037  if ((res = mov_write_moov_tag(pb, mov, s)) < 0)
9038  return res;
9039  size = mov->reserved_moov_size - (avio_tell(pb) - mov->reserved_header_pos);
9040  if (size < 8){
9041  av_log(s, AV_LOG_ERROR, "reserved_moov_size is too small, needed %"PRId64" additional\n", 8-size);
9042  return AVERROR(EINVAL);
9043  }
9044  avio_wb32(pb, size);
9045  ffio_wfourcc(pb, "free");
9046  ffio_fill(pb, 0, size - 8);
9047  avio_seek(pb, moov_pos, SEEK_SET);
9048  } else {
9049  if ((res = mov_write_moov_tag(pb, mov, s)) < 0)
9050  return res;
9051  }
9052 
9053  if (mov->flags & FF_MOV_FLAG_HYBRID_FRAGMENTED) {
9054  // With hybrid fragmentation, only write the mdat size (hiding
9055  // the original moov and all the fragments within the mdat)
9056  // after we've successfully written the complete moov, to avoid
9057  // risk for an unreadable file if writing the final moov fails.
9059  }
9060 
9061  res = 0;
9062  } else {
9064  for (i = 0; i < mov->nb_tracks; i++)
9065  mov->tracks[i].data_offset = 0;
9066  if (mov->flags & FF_MOV_FLAG_GLOBAL_SIDX) {
9067  int64_t end;
9068  av_log(s, AV_LOG_INFO, "Starting second pass: inserting sidx atoms\n");
9069  res = shift_data(s);
9070  if (res < 0)
9071  return res;
9072  end = avio_tell(pb);
9073  avio_seek(pb, mov->reserved_header_pos, SEEK_SET);
9074  mov_write_sidx_tags(pb, mov, -1, 0);
9075  avio_seek(pb, end, SEEK_SET);
9076  }
9077  if (!(mov->flags & FF_MOV_FLAG_SKIP_TRAILER)) {
9079  res = mov_write_mfra_tag(pb, mov);
9080  if (res < 0)
9081  return res;
9082  }
9083  }
9084 
9085  return res;
9086 }
9087 
9089  const AVPacket *pkt)
9090 {
9091  int ret = 1;
9092 
9093  if (st->codecpar->codec_id == AV_CODEC_ID_AAC) {
9094  if (pkt->size > 2 && (AV_RB16(pkt->data) & 0xfff0) == 0xfff0)
9095  ret = ff_stream_add_bitstream_filter(st, "aac_adtstoasc", NULL);
9096  } else if (st->codecpar->codec_id == AV_CODEC_ID_VP9) {
9097  ret = ff_stream_add_bitstream_filter(st, "vp9_superframe", NULL);
9098  }
9099 
9100  return ret;
9101 }
9102 
9103 #if CONFIG_AVIF_MUXER
9104 static int avif_write_trailer(AVFormatContext *s)
9105 {
9106  AVIOContext *pb = s->pb;
9107  MOVMuxContext *mov = s->priv_data;
9108  int64_t pos_backup, extent_offsets[2];
9109  uint8_t *buf;
9110  int buf_size, moov_size;
9111 
9112  if (mov->moov_written) return 0;
9113 
9114  mov->is_animated_avif = s->streams[0]->nb_frames > 1;
9115  if (mov->is_animated_avif && mov->nb_streams > 1) {
9116  // For animated avif with alpha channel, we need to write a tref tag
9117  // with type "auxl".
9118  MovTag *tag = mov_add_tref_tag(mov, &mov->tracks[1], MKTAG('a', 'u', 'x', 'l'));
9119  if (!tag)
9120  return AVERROR(ENOMEM);
9121 
9122  int ret = mov_add_tref_id(mov, tag, 1);
9123  if (ret < 0)
9124  return ret;
9125  }
9127  mov_write_meta_tag(pb, mov, s);
9128 
9129  moov_size = get_moov_size(s);
9130  for (int i = 0; i < mov->nb_tracks; i++)
9131  mov->tracks[i].data_offset = avio_tell(pb) + moov_size + 8;
9132 
9133  if (mov->is_animated_avif) {
9134  int ret;
9135  if ((ret = mov_write_moov_tag(pb, mov, s)) < 0)
9136  return ret;
9137  }
9138 
9139  buf_size = avio_get_dyn_buf(mov->mdat_buf, &buf);
9140  avio_wb32(pb, buf_size + 8);
9141  ffio_wfourcc(pb, "mdat");
9142 
9143  // The offset for the YUV planes is the starting position of mdat.
9144  extent_offsets[0] = avio_tell(pb);
9145  // The offset for alpha plane is YUV offset + YUV size.
9146  extent_offsets[1] = extent_offsets[0] + mov->avif_extent_length[0];
9147 
9148  avio_write(pb, buf, buf_size);
9149 
9150  // write extent offsets.
9151  pos_backup = avio_tell(pb);
9152  for (int i = 0; i < mov->nb_streams; i++) {
9153  if (extent_offsets[i] != (uint32_t)extent_offsets[i]) {
9154  av_log(s, AV_LOG_ERROR, "extent offset does not fit in 32 bits\n");
9155  return AVERROR_INVALIDDATA;
9156  }
9157  avio_seek(pb, mov->avif_extent_pos[i], SEEK_SET);
9158  avio_wb32(pb, extent_offsets[i]); /* rewrite offset */
9159  }
9160  avio_seek(pb, pos_backup, SEEK_SET);
9161 
9162  return 0;
9163 }
9164 #endif
9165 
9166 #if CONFIG_TGP_MUXER || CONFIG_TG2_MUXER
9167 static const AVCodecTag codec_3gp_tags[] = {
9168  { AV_CODEC_ID_H263, MKTAG('s','2','6','3') },
9169  { AV_CODEC_ID_H264, MKTAG('a','v','c','1') },
9170  { AV_CODEC_ID_MPEG4, MKTAG('m','p','4','v') },
9171  { AV_CODEC_ID_AAC, MKTAG('m','p','4','a') },
9172  { AV_CODEC_ID_AMR_NB, MKTAG('s','a','m','r') },
9173  { AV_CODEC_ID_AMR_WB, MKTAG('s','a','w','b') },
9174  { AV_CODEC_ID_MOV_TEXT, MKTAG('t','x','3','g') },
9175  { AV_CODEC_ID_NONE, 0 },
9176 };
9177 static const AVCodecTag *const codec_3gp_tags_list[] = { codec_3gp_tags, NULL };
9178 #endif
9179 
9180 static const AVCodecTag codec_mp4_tags[] = {
9181  { AV_CODEC_ID_MPEG4, MKTAG('m', 'p', '4', 'v') },
9182  { AV_CODEC_ID_H264, MKTAG('a', 'v', 'c', '1') },
9183  { AV_CODEC_ID_H264, MKTAG('a', 'v', 'c', '3') },
9184  { AV_CODEC_ID_HEVC, MKTAG('h', 'e', 'v', '1') },
9185  { AV_CODEC_ID_HEVC, MKTAG('h', 'v', 'c', '1') },
9186  { AV_CODEC_ID_HEVC, MKTAG('d', 'v', 'h', '1') },
9187  { AV_CODEC_ID_VVC, MKTAG('v', 'v', 'c', '1') },
9188  { AV_CODEC_ID_VVC, MKTAG('v', 'v', 'i', '1') },
9189  { AV_CODEC_ID_EVC, MKTAG('e', 'v', 'c', '1') },
9190  { AV_CODEC_ID_LCEVC, MKTAG('l', 'v', 'c', '1') },
9191  { AV_CODEC_ID_APV, MKTAG('a', 'p', 'v', '1') },
9192  { AV_CODEC_ID_MPEG2VIDEO, MKTAG('m', 'p', '4', 'v') },
9193  { AV_CODEC_ID_MPEG1VIDEO, MKTAG('m', 'p', '4', 'v') },
9194  { AV_CODEC_ID_MJPEG, MKTAG('m', 'p', '4', 'v') },
9195  { AV_CODEC_ID_PNG, MKTAG('m', 'p', '4', 'v') },
9196  { AV_CODEC_ID_JPEG2000, MKTAG('m', 'p', '4', 'v') },
9197  { AV_CODEC_ID_VC1, MKTAG('v', 'c', '-', '1') },
9198  { AV_CODEC_ID_DIRAC, MKTAG('d', 'r', 'a', 'c') },
9199  { AV_CODEC_ID_TSCC2, MKTAG('m', 'p', '4', 'v') },
9200  { AV_CODEC_ID_VP9, MKTAG('v', 'p', '0', '9') },
9201  { AV_CODEC_ID_AV1, MKTAG('a', 'v', '0', '1') },
9202  { AV_CODEC_ID_AAC, MKTAG('m', 'p', '4', 'a') },
9203  { AV_CODEC_ID_ALAC, MKTAG('a', 'l', 'a', 'c') },
9204  { AV_CODEC_ID_MP4ALS, MKTAG('m', 'p', '4', 'a') },
9205  { AV_CODEC_ID_MP3, MKTAG('m', 'p', '4', 'a') },
9206  { AV_CODEC_ID_MP2, MKTAG('m', 'p', '4', 'a') },
9207  { AV_CODEC_ID_AC3, MKTAG('a', 'c', '-', '3') },
9208  { AV_CODEC_ID_EAC3, MKTAG('e', 'c', '-', '3') },
9209  { AV_CODEC_ID_DTS, MKTAG('m', 'p', '4', 'a') },
9210  { AV_CODEC_ID_TRUEHD, MKTAG('m', 'l', 'p', 'a') },
9211  { AV_CODEC_ID_FLAC, MKTAG('f', 'L', 'a', 'C') },
9212  { AV_CODEC_ID_OPUS, MKTAG('O', 'p', 'u', 's') },
9213  { AV_CODEC_ID_VORBIS, MKTAG('m', 'p', '4', 'a') },
9214  { AV_CODEC_ID_QCELP, MKTAG('m', 'p', '4', 'a') },
9215  { AV_CODEC_ID_EVRC, MKTAG('m', 'p', '4', 'a') },
9216  { AV_CODEC_ID_DVD_SUBTITLE, MKTAG('m', 'p', '4', 's') },
9217  { AV_CODEC_ID_MOV_TEXT, MKTAG('t', 'x', '3', 'g') },
9218  { AV_CODEC_ID_BIN_DATA, MKTAG('g', 'p', 'm', 'd') },
9219  { AV_CODEC_ID_MPEGH_3D_AUDIO, MKTAG('m', 'h', 'm', '1') },
9222  { AV_CODEC_ID_FFV1, MKTAG('F', 'F', 'V', '1') },
9223 
9224  /* ISO/IEC 23003-5 integer formats */
9231  /* ISO/IEC 23003-5 floating-point formats */
9236 
9237  { AV_CODEC_ID_AVS3, MKTAG('a', 'v', 's', '3') },
9238 
9239  { AV_CODEC_ID_NONE, 0 },
9240 };
9241 #if CONFIG_MP4_MUXER || CONFIG_PSP_MUXER
9242 static const AVCodecTag *const mp4_codec_tags_list[] = { codec_mp4_tags, NULL };
9243 #endif
9244 
9245 static const AVCodecTag codec_ism_tags[] = {
9246  { AV_CODEC_ID_WMAPRO , MKTAG('w', 'm', 'a', ' ') },
9248  { AV_CODEC_ID_NONE , 0 },
9249 };
9250 
9251 static const AVCodecTag codec_ipod_tags[] = {
9252  { AV_CODEC_ID_H264, MKTAG('a','v','c','1') },
9253  { AV_CODEC_ID_MPEG4, MKTAG('m','p','4','v') },
9254  { AV_CODEC_ID_AAC, MKTAG('m','p','4','a') },
9255  { AV_CODEC_ID_ALAC, MKTAG('a','l','a','c') },
9256  { AV_CODEC_ID_AC3, MKTAG('a','c','-','3') },
9257  { AV_CODEC_ID_MOV_TEXT, MKTAG('t','x','3','g') },
9258  { AV_CODEC_ID_MOV_TEXT, MKTAG('t','e','x','t') },
9259  { AV_CODEC_ID_NONE, 0 },
9260 };
9261 
9262 static const AVCodecTag codec_f4v_tags[] = {
9263  { AV_CODEC_ID_MP3, MKTAG('.','m','p','3') },
9264  { AV_CODEC_ID_AAC, MKTAG('m','p','4','a') },
9265  { AV_CODEC_ID_H264, MKTAG('a','v','c','1') },
9266  { AV_CODEC_ID_VP6A, MKTAG('V','P','6','A') },
9267  { AV_CODEC_ID_VP6F, MKTAG('V','P','6','F') },
9268  { AV_CODEC_ID_NONE, 0 },
9269 };
9270 
9271 #if CONFIG_AVIF_MUXER
9272 
9273 static const AVOption avif_options[] = {
9274  { "movie_timescale", "set movie timescale", offsetof(MOVMuxContext, movie_timescale), AV_OPT_TYPE_INT, {.i64 = MOV_TIMESCALE}, 1, INT_MAX, AV_OPT_FLAG_ENCODING_PARAM},
9275  { "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 },
9276  { NULL },
9277 };
9278 static const AVCodecTag codec_avif_tags[] = {
9279  { AV_CODEC_ID_AV1, MKTAG('a','v','0','1') },
9280  { AV_CODEC_ID_NONE, 0 },
9281 };
9282 static const AVCodecTag *const codec_avif_tags_list[] = { codec_avif_tags, NULL };
9283 
9284 static const AVClass mov_avif_muxer_class = {
9285  .class_name = "avif muxer",
9286  .item_name = av_default_item_name,
9287  .option = avif_options,
9288  .version = LIBAVUTIL_VERSION_INT,
9289 };
9290 #endif
9291 
9292 #if CONFIG_MOV_MUXER
9293 const FFOutputFormat ff_mov_muxer = {
9294  .p.name = "mov",
9295  .p.long_name = NULL_IF_CONFIG_SMALL("QuickTime / MOV"),
9296  .p.extensions = "mov",
9297  .priv_data_size = sizeof(MOVMuxContext),
9298  .p.audio_codec = AV_CODEC_ID_AAC,
9299  .p.video_codec = CONFIG_LIBX264_ENCODER ?
9301  .init = mov_init,
9302  .write_header = mov_write_header,
9303  .write_packet = mov_write_packet,
9304  .write_trailer = mov_write_trailer,
9305  .deinit = mov_free,
9307  .p.codec_tag = (const AVCodecTag* const []){
9309  },
9310  .check_bitstream = mov_check_bitstream,
9311  .p.priv_class = &mov_isobmff_muxer_class,
9312  .flags_internal = FF_OFMT_FLAG_ALLOW_FLUSH,
9313 };
9314 #endif
9315 #if CONFIG_TGP_MUXER
9316 const FFOutputFormat ff_tgp_muxer = {
9317  .p.name = "3gp",
9318  .p.long_name = NULL_IF_CONFIG_SMALL("3GP (3GPP file format)"),
9319  .p.extensions = "3gp",
9320  .priv_data_size = sizeof(MOVMuxContext),
9321  .p.audio_codec = AV_CODEC_ID_AMR_NB,
9322  .p.video_codec = AV_CODEC_ID_H263,
9323  .init = mov_init,
9324  .write_header = mov_write_header,
9325  .write_packet = mov_write_packet,
9326  .write_trailer = mov_write_trailer,
9327  .deinit = mov_free,
9329  .p.codec_tag = codec_3gp_tags_list,
9330  .check_bitstream = mov_check_bitstream,
9331  .p.priv_class = &mov_isobmff_muxer_class,
9332  .flags_internal = FF_OFMT_FLAG_ALLOW_FLUSH,
9333 };
9334 #endif
9335 #if CONFIG_MP4_MUXER
9336 const FFOutputFormat ff_mp4_muxer = {
9337  .p.name = "mp4",
9338  .p.long_name = NULL_IF_CONFIG_SMALL("MP4 (MPEG-4 Part 14)"),
9339  .p.mime_type = "video/mp4",
9340  .p.extensions = "mp4",
9341  .priv_data_size = sizeof(MOVMuxContext),
9342  .p.audio_codec = AV_CODEC_ID_AAC,
9343  .p.video_codec = CONFIG_LIBX264_ENCODER ?
9345  .init = mov_init,
9346  .write_header = mov_write_header,
9347  .write_packet = mov_write_packet,
9348  .write_trailer = mov_write_trailer,
9349  .deinit = mov_free,
9351  .p.codec_tag = mp4_codec_tags_list,
9352  .check_bitstream = mov_check_bitstream,
9353  .p.priv_class = &mov_isobmff_muxer_class,
9354  .flags_internal = FF_OFMT_FLAG_ALLOW_FLUSH,
9355 };
9356 #endif
9357 #if CONFIG_PSP_MUXER
9358 const FFOutputFormat ff_psp_muxer = {
9359  .p.name = "psp",
9360  .p.long_name = NULL_IF_CONFIG_SMALL("PSP MP4 (MPEG-4 Part 14)"),
9361  .p.extensions = "mp4,psp",
9362  .priv_data_size = sizeof(MOVMuxContext),
9363  .p.audio_codec = AV_CODEC_ID_AAC,
9364  .p.video_codec = CONFIG_LIBX264_ENCODER ?
9366  .init = mov_init,
9367  .write_header = mov_write_header,
9368  .write_packet = mov_write_packet,
9369  .write_trailer = mov_write_trailer,
9370  .deinit = mov_free,
9372  .p.codec_tag = mp4_codec_tags_list,
9373  .check_bitstream = mov_check_bitstream,
9374  .p.priv_class = &mov_isobmff_muxer_class,
9375  .flags_internal = FF_OFMT_FLAG_ALLOW_FLUSH,
9376 };
9377 #endif
9378 #if CONFIG_TG2_MUXER
9379 const FFOutputFormat ff_tg2_muxer = {
9380  .p.name = "3g2",
9381  .p.long_name = NULL_IF_CONFIG_SMALL("3GP2 (3GPP2 file format)"),
9382  .p.extensions = "3g2",
9383  .priv_data_size = sizeof(MOVMuxContext),
9384  .p.audio_codec = AV_CODEC_ID_AMR_NB,
9385  .p.video_codec = AV_CODEC_ID_H263,
9386  .init = mov_init,
9387  .write_header = mov_write_header,
9388  .write_packet = mov_write_packet,
9389  .write_trailer = mov_write_trailer,
9390  .deinit = mov_free,
9392  .p.codec_tag = codec_3gp_tags_list,
9393  .check_bitstream = mov_check_bitstream,
9394  .p.priv_class = &mov_isobmff_muxer_class,
9395  .flags_internal = FF_OFMT_FLAG_ALLOW_FLUSH,
9396 };
9397 #endif
9398 #if CONFIG_IPOD_MUXER
9399 const FFOutputFormat ff_ipod_muxer = {
9400  .p.name = "ipod",
9401  .p.long_name = NULL_IF_CONFIG_SMALL("iPod H.264 MP4 (MPEG-4 Part 14)"),
9402  .p.mime_type = "video/mp4",
9403  .p.extensions = "m4v,m4a,m4b",
9404  .priv_data_size = sizeof(MOVMuxContext),
9405  .p.audio_codec = AV_CODEC_ID_AAC,
9406  .p.video_codec = AV_CODEC_ID_H264,
9407  .init = mov_init,
9408  .write_header = mov_write_header,
9409  .write_packet = mov_write_packet,
9410  .write_trailer = mov_write_trailer,
9411  .deinit = mov_free,
9413  .p.codec_tag = (const AVCodecTag* const []){ codec_ipod_tags, 0 },
9414  .check_bitstream = mov_check_bitstream,
9415  .p.priv_class = &mov_isobmff_muxer_class,
9416  .flags_internal = FF_OFMT_FLAG_ALLOW_FLUSH,
9417 };
9418 #endif
9419 #if CONFIG_ISMV_MUXER
9420 const FFOutputFormat ff_ismv_muxer = {
9421  .p.name = "ismv",
9422  .p.long_name = NULL_IF_CONFIG_SMALL("ISMV/ISMA (Smooth Streaming)"),
9423  .p.mime_type = "video/mp4",
9424  .p.extensions = "ismv,isma",
9425  .priv_data_size = sizeof(MOVMuxContext),
9426  .p.audio_codec = AV_CODEC_ID_AAC,
9427  .p.video_codec = AV_CODEC_ID_H264,
9428  .init = mov_init,
9429  .write_header = mov_write_header,
9430  .write_packet = mov_write_packet,
9431  .write_trailer = mov_write_trailer,
9432  .deinit = mov_free,
9434  .p.codec_tag = (const AVCodecTag* const []){
9436  .check_bitstream = mov_check_bitstream,
9437  .p.priv_class = &mov_isobmff_muxer_class,
9438  .flags_internal = FF_OFMT_FLAG_ALLOW_FLUSH,
9439 };
9440 #endif
9441 #if CONFIG_F4V_MUXER
9442 const FFOutputFormat ff_f4v_muxer = {
9443  .p.name = "f4v",
9444  .p.long_name = NULL_IF_CONFIG_SMALL("F4V Adobe Flash Video"),
9445  .p.mime_type = "application/f4v",
9446  .p.extensions = "f4v",
9447  .priv_data_size = sizeof(MOVMuxContext),
9448  .p.audio_codec = AV_CODEC_ID_AAC,
9449  .p.video_codec = AV_CODEC_ID_H264,
9450  .init = mov_init,
9451  .write_header = mov_write_header,
9452  .write_packet = mov_write_packet,
9453  .write_trailer = mov_write_trailer,
9454  .deinit = mov_free,
9455  .p.flags = AVFMT_GLOBALHEADER,
9456  .p.codec_tag = (const AVCodecTag* const []){ codec_f4v_tags, 0 },
9457  .check_bitstream = mov_check_bitstream,
9458  .p.priv_class = &mov_isobmff_muxer_class,
9459  .flags_internal = FF_OFMT_FLAG_ALLOW_FLUSH,
9460 };
9461 #endif
9462 #if CONFIG_AVIF_MUXER
9463 const FFOutputFormat ff_avif_muxer = {
9464  .p.name = "avif",
9465  .p.long_name = NULL_IF_CONFIG_SMALL("AVIF"),
9466  .p.mime_type = "image/avif",
9467  .p.extensions = "avif",
9468  .priv_data_size = sizeof(MOVMuxContext),
9469  .p.video_codec = AV_CODEC_ID_AV1,
9470  .init = mov_init,
9471  .write_header = mov_write_header,
9472  .write_packet = mov_write_packet,
9473  .write_trailer = avif_write_trailer,
9474  .deinit = mov_free,
9475  .p.flags = AVFMT_GLOBALHEADER,
9476  .p.codec_tag = codec_avif_tags_list,
9477  .p.priv_class = &mov_avif_muxer_class,
9478  .flags_internal = FF_OFMT_FLAG_ALLOW_FLUSH,
9479 };
9480 #endif
AV_CODEC_ID_PCM_S16LE
@ AV_CODEC_ID_PCM_S16LE
Definition: codec_id.h:339
flags
const SwsFlags flags[]
Definition: swscale.c:72
codec_ism_tags
static const AVCodecTag codec_ism_tags[]
Definition: movenc.c:9245
ff_isom_write_vpcc
int ff_isom_write_vpcc(void *logctx, AVIOContext *pb, const uint8_t *data, int len, const AVCodecParameters *par)
Writes VP codec configuration to the provided AVIOContext.
Definition: vpcc.c:204
MOVTrack::height
int height
active picture (w/o VBI) height for D-10/IMX
Definition: movenc.h:133
MOVMuxContext::mdat_pos
int64_t mdat_pos
Definition: movenc.h:218
MOVTrack::elst_end_pts
int64_t elst_end_pts
Definition: movenc.h:139
mov_write_traf_tag
static int mov_write_traf_tag(AVIOContext *pb, MOVMuxContext *mov, MOVTrack *track, int64_t moof_offset, int moof_size)
Definition: movenc.c:5850
AV_CODEC_ID_EIA_608
@ AV_CODEC_ID_EIA_608
Definition: codec_id.h:583
AV_PKT_DATA_DISPLAYMATRIX
@ AV_PKT_DATA_DISPLAYMATRIX
This side data contains a 3x3 transformation matrix describing an affine transformation that needs to...
Definition: packet.h:105
AV_ROUND_UP
@ AV_ROUND_UP
Round toward +infinity.
Definition: mathematics.h:134
av_packet_unref
void av_packet_unref(AVPacket *pkt)
Wipe the packet.
Definition: packet.c:433
eac3_info
Definition: movenc.c:383
MOVMuxContext::nb_tracks
int nb_tracks
Definition: movenc.h:215
MOVMuxContext::fc
AVFormatContext * fc
Definition: movenc.h:246
MOVTrack::end_pts
int64_t end_pts
Definition: movenc.h:138
MOVMuxContext::iods_audio_profile
int iods_audio_profile
Definition: movenc.h:227
MODE_PSP
#define MODE_PSP
Definition: movenc.h:40
mov_write_udta_sdp
static int mov_write_udta_sdp(AVIOContext *pb, MOVTrack *track)
Definition: movenc.c:4258
AVMEDIA_TYPE_SUBTITLE
@ AVMEDIA_TYPE_SUBTITLE
Definition: avutil.h:203
AV_CODEC_ID_VP6F
@ AV_CODEC_ID_VP6F
Definition: codec_id.h:144
FF_MOV_FLAG_GLOBAL_SIDX
#define FF_MOV_FLAG_GLOBAL_SIDX
Definition: movenc.h:291
skip_bits_long
static void skip_bits_long(GetBitContext *s, int n)
Skips the specified number of bits.
Definition: get_bits.h:280
AV_LOG_WARNING
#define AV_LOG_WARNING
Something somehow does not look correct.
Definition: log.h:216
MOV_TFHD_DEFAULT_FLAGS
#define MOV_TFHD_DEFAULT_FLAGS
Definition: isom.h:412
MODE_IPOD
#define MODE_IPOD
Definition: movenc.h:43
MODE_MP4
#define MODE_MP4
Definition: movenc.h:37
AV_CODEC_ID_PCM_F32BE
@ AV_CODEC_ID_PCM_F32BE
Definition: codec_id.h:359
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:384
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:2072
calc_elst_duration
static int64_t calc_elst_duration(MOVMuxContext *mov, MOVTrack *track)
Definition: movenc.c:3886
name
it s the only field you need to keep assuming you have a context There is some magic you don t need to care about around this just let it vf default minimum maximum flags name is the option name
Definition: writing_filters.txt:88
LIBAVFORMAT_IDENT
#define LIBAVFORMAT_IDENT
Definition: version.h:45
PacketList::head
PacketListEntry * head
Definition: packet_internal.h:34
AV_CODEC_ID_ADPCM_IMA_QT
@ AV_CODEC_ID_ADPCM_IMA_QT
Definition: codec_id.h:378
AVERROR_EXPERIMENTAL
#define AVERROR_EXPERIMENTAL
Requested feature is flagged experimental. Set strict_std_compliance if you really want to use it.
Definition: error.h:74
movenc_ttml.h
entry
#define entry
Definition: aom_film_grain_template.c:66
eac3_info::num_dep_sub
uint8_t num_dep_sub
Definition: movenc.c:409
MOVTrack::chunkCount
long chunkCount
Definition: movenc.h:110
MOVTrack::cluster_written
MOVIentry * cluster_written
Definition: movenc.h:130
level
uint8_t level
Definition: svq3.c:208
AV_CODEC_ID_AC3
@ AV_CODEC_ID_AC3
Definition: codec_id.h:464
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:5321
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:2417
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:3532
MOVFragmentInfo::tfrf_offset
int64_t tfrf_offset
Definition: movenc.h:83
mov_write_freeform_tag
static int mov_write_freeform_tag(AVIOContext *pb, const char *mean, const char *name, const char *data)
Definition: movenc.c:4598
AV_PKT_DATA_AMBIENT_VIEWING_ENVIRONMENT
@ AV_PKT_DATA_AMBIENT_VIEWING_ENVIRONMENT
Ambient viewing environment metadata, as defined by H.274.
Definition: packet.h:327
AVOutputFormat::name
const char * name
Definition: avformat.h: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:4320
MOVTrack::squash_fragment_samples_to_one
unsigned int squash_fragment_samples_to_one
Definition: movenc.h:186
MOVMuxContext::mode
int mode
Definition: movenc.h:212
AV_PROFILE_H264_INTRA
#define AV_PROFILE_H264_INTRA
Definition: defs.h:108
FF_MOV_FLAG_FRAG_KEYFRAME
#define FF_MOV_FLAG_FRAG_KEYFRAME
Definition: movenc.h:280
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:6124
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:5048
AV_STREAM_GROUP_PARAMS_LCEVC
@ AV_STREAM_GROUP_PARAMS_LCEVC
Definition: avformat.h:1110
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:5785
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:5000
ffio_wfourcc
static av_always_inline void ffio_wfourcc(AVIOContext *pb, const uint8_t *s)
Definition: avio_internal.h:124
AV_CODEC_ID_V308
@ AV_CODEC_ID_V308
Definition: codec_id.h:260
AVUUID
uint8_t AVUUID[AV_UUID_LEN]
Definition: uuid.h:60
put_bytes_output
static int put_bytes_output(const PutBitContext *s)
Definition: put_bits.h:99
FF_MOV_FLAG_HYBRID_FRAGMENTED
#define FF_MOV_FLAG_HYBRID_FRAGMENTED
Definition: movenc.h:301
cb
static double cb(void *priv, double x, double y)
Definition: vf_geq.c:247
mpeg4_bit_rate_values::buffer_size
uint32_t buffer_size
Size of the decoding buffer for the elementary stream in bytes.
Definition: movenc.c:715
ff_mp4_obj_type
const AVCodecTag ff_mp4_obj_type[]
Definition: isom.c:34
MOVMuxContext::encryption_scheme
MOVEncryptionScheme encryption_scheme
Definition: movenc.h:257
FF_MOV_FLAG_WRITE_COLR
#define FF_MOV_FLAG_WRITE_COLR
Definition: movenc.h:292
AV_PKT_DATA_FRAME_CROPPING
@ AV_PKT_DATA_FRAME_CROPPING
The number of pixels to discard from the top/bottom/left/right border of the decoded frame to obtain ...
Definition: packet.h:340
mov_write_single_packet
static int mov_write_single_packet(AVFormatContext *s, AVPacket *pkt)
Definition: movenc.c:7358
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:5660
MOVTrack::mode
int mode
Definition: movenc.h:94
mov_write_mvhd_tag
static int mov_write_mvhd_tag(AVIOContext *pb, MOVMuxContext *mov)
Definition: movenc.c:4482
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:5588
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:4340
MOVIentry
Definition: movenc.h:48
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
FF_MOV_FLAG_SKIP_TRAILER
#define FF_MOV_FLAG_SKIP_TRAILER
Definition: movenc.h:295
mov_write_gama_tag
static int mov_write_gama_tag(AVFormatContext *s, AVIOContext *pb, MOVTrack *track, double gamma)
Definition: movenc.c:2576
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
AV_PKT_DATA_MASTERING_DISPLAY_METADATA
@ AV_PKT_DATA_MASTERING_DISPLAY_METADATA
Mastering display metadata (based on SMPTE-2086:2014).
Definition: packet.h:219
MOVFragmentInfo::size
int size
Definition: movenc.h:84
AV_PKT_FLAG_DISCARD
#define AV_PKT_FLAG_DISCARD
Flag is used to discard packets which are required to maintain valid decoder state but are not requir...
Definition: packet.h:657
IS_MODE
#define IS_MODE(muxer, config)
MOVFragmentInfo
Definition: movenc.h:79
MOVTrack::last_iamf_idx
int last_iamf_idx
Definition: movenc.h:192
eac3_info::substream
struct eac3_info::@492 substream[1]
AV_TIME_BASE_Q
#define AV_TIME_BASE_Q
Internal time base represented as fractional value.
Definition: avutil.h:263
AV_CODEC_ID_DIRAC
@ AV_CODEC_ID_DIRAC
Definition: codec_id.h:168
AVCodecTag::id
enum AVCodecID id
Definition: internal.h:43
eac3_info::num_blocks
uint8_t num_blocks
Definition: movenc.c:386
int64_t
long long int64_t
Definition: coverity.c:34
av_grow_packet
int av_grow_packet(AVPacket *pkt, int grow_by)
Increase packet size, correctly zeroing padding.
Definition: packet.c:121
mov_write_ms_tag
static int mov_write_ms_tag(AVFormatContext *s, AVIOContext *pb, MOVTrack *track)
Definition: movenc.c:834
init_put_bits
static void init_put_bits(PutBitContext *s, uint8_t *buffer, int buffer_size)
Initialize the PutBitContext s.
Definition: put_bits.h:62
MOVTrack::iamf_buf
AVIOContext * iamf_buf
Definition: movenc.h:193
mov_auto_flush_fragment
static int mov_auto_flush_fragment(AVFormatContext *s, int force)
Definition: movenc.c:6865
AV_CODEC_ID_RAWVIDEO
@ AV_CODEC_ID_RAWVIDEO
Definition: codec_id.h:65
mov_pcm_le_gt16
static int mov_pcm_le_gt16(enum AVCodecID codec_id)
Definition: movenc.c:818
vvc.h
ff_vvc_annexb2mp4
int ff_vvc_annexb2mp4(AVIOContext *pb, const uint8_t *buf_in, int size, int filter_ps, int *ps_count)
Writes Annex B formatted H.266/VVC NAL units to the provided AVIOContext.
Definition: vvc.c:810
ff_get_formatted_ntp_time
uint64_t ff_get_formatted_ntp_time(uint64_t ntp_time_us)
Get the NTP time stamp formatted as per the RFC-5905.
Definition: utils.c:262
AV_DISPOSITION_DEFAULT
#define AV_DISPOSITION_DEFAULT
The stream should be chosen by default among other streams of the same type, unless the user has expl...
Definition: avformat.h:620
MOVMuxContext::min_fragment_duration
int min_fragment_duration
Definition: movenc.h:232
AV_CODEC_ID_MPEG4
@ AV_CODEC_ID_MPEG4
Definition: codec_id.h:64
MOVMuxContext::avif_extent_length
int avif_extent_length[2]
Definition: movenc.h:272
AVContentLightMetadata::MaxCLL
unsigned MaxCLL
Max content light level (cd/m^2).
Definition: mastering_display_metadata.h:111
ff_isom_write_vvcc
int ff_isom_write_vvcc(AVIOContext *pb, const uint8_t *data, int size, int ps_array_completeness)
Writes H.266/VVC extradata (parameter sets, declarative SEI NAL units) to the provided AVIOContext.
Definition: vvc.c:879
MODE_MOV
#define MODE_MOV
Definition: movenc.h:38
MOVMuxContext::encryption_scheme_str
char * encryption_scheme_str
Definition: movenc.h:256
FF_MOV_FLAG_FRAG_CUSTOM
#define FF_MOV_FLAG_FRAG_CUSTOM
Definition: movenc.h:282
av_encryption_init_info_free
void av_encryption_init_info_free(AVEncryptionInitInfo *info)
Frees the given encryption init info object.
Definition: encryption_info.c:216
mov_write_enda_tag
static int mov_write_enda_tag(AVIOContext *pb)
Definition: movenc.c:678
mov_write_apvc_tag
static int mov_write_apvc_tag(AVFormatContext *s, AVIOContext *pb, MOVTrack *track)
Definition: movenc.c:1720
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:1352
av_channel_layout_ambisonic_order
int av_channel_layout_ambisonic_order(const AVChannelLayout *channel_layout)
Return the order if the layout is n-th order standard-order ambisonic.
Definition: channel_layout.c:486
MOVCtts
Definition: isom.h:68
AVPacketSideData
This structure stores auxiliary information for decoding, presenting, or otherwise processing the cod...
Definition: packet.h:416
AVCOL_RANGE_JPEG
@ AVCOL_RANGE_JPEG
Full range content.
Definition: pixfmt.h:777
AVFormatContext::strict_std_compliance
int strict_std_compliance
Allow non-standard and experimental extension.
Definition: avformat.h:1643
mov_write_iods_tag
static int mov_write_iods_tag(AVIOContext *pb, MOVMuxContext *mov)
Definition: movenc.c:4429
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:3972
internal.h
AVPacket::data
uint8_t * data
Definition: packet.h:595
AV_PKT_DATA_ENCRYPTION_INIT_INFO
@ AV_PKT_DATA_ENCRYPTION_INIT_INFO
This side data is encryption initialization data.
Definition: packet.h:246
AVComponentDescriptor::depth
int depth
Number of bits in the component.
Definition: pixdesc.h:57
mov_init
static int mov_init(AVFormatContext *s)
Definition: movenc.c:8099
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:7853
mov_write_ccst_tag
static int mov_write_ccst_tag(AVIOContext *pb)
Definition: movenc.c:2754
AVOption
AVOption.
Definition: opt.h:429
MOVFragmentInfo::duration
int64_t duration
Definition: movenc.h:82
b
#define b
Definition: input.c:43
AVCOL_TRC_UNSPECIFIED
@ AVCOL_TRC_UNSPECIFIED
Definition: pixfmt.h:669
mov_write_mdta_hdlr_tag
static int mov_write_mdta_hdlr_tag(AVIOContext *pb, MOVMuxContext *mov, AVFormatContext *s)
Definition: movenc.c:4865
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:4962
AVStream::avg_frame_rate
AVRational avg_frame_rate
Average framerate.
Definition: avformat.h:836
MOVTrack::flags
uint32_t flags
Definition: movenc.h:116
data
const char data[16]
Definition: mxf.c:149
AV_PIX_FMT_MONOWHITE
@ AV_PIX_FMT_MONOWHITE
Y , 1bpp, 0 is white, 1 is black, in each byte pixels are ordered from the msb to the lsb.
Definition: pixfmt.h:82
AVTimecode::flags
uint32_t flags
flags such as drop frame, +24 hours support, ...
Definition: timecode.h:43
AV_CODEC_ID_ALAC
@ AV_CODEC_ID_ALAC
Definition: codec_id.h:477
MOVTrack::tag
int tag
stsd fourcc
Definition: movenc.h:123
mov_pix_fmt_tags
static const struct @491 mov_pix_fmt_tags[]
MOVTrack::pal_done
int pal_done
Definition: movenc.h:182
AV_PIX_FMT_YUV420P10
#define AV_PIX_FMT_YUV420P10
Definition: pixfmt.h:539
AV_DICT_IGNORE_SUFFIX
#define AV_DICT_IGNORE_SUFFIX
Return first entry in a dictionary whose first part corresponds to the search key,...
Definition: dict.h:75
AV_CODEC_ID_AMR_NB
@ AV_CODEC_ID_AMR_NB
Definition: codec_id.h:442
AVStreamGroupTREF::metadata_index
unsigned int metadata_index
Index of the metadata stream in the AVStreamGroup.
Definition: avformat.h:1102
MOVIentry::dts
int64_t dts
Definition: movenc.h:50
ff_isom_write_lvcc
int ff_isom_write_lvcc(AVIOContext *pb, const uint8_t *data, int len)
Definition: lcevc.c:251
MOV_TIMESCALE
#define MOV_TIMESCALE
Definition: movenc.h:33
co64_required
static int co64_required(const MOVTrack *track)
Definition: movenc.c:177
mov_write_aux_tag
static int mov_write_aux_tag(AVIOContext *pb, const char *aux_type)
Definition: movenc.c:2773
MOVMuxContext::encryption_key
uint8_t * encryption_key
Definition: movenc.h:258
ff_toupper4
unsigned int ff_toupper4(unsigned int x)
Definition: to_upper4.h:29
ff_parse_creation_time_metadata
int ff_parse_creation_time_metadata(AVFormatContext *s, int64_t *timestamp, int return_seconds)
Parse creation_time in AVFormatContext metadata if exists and warn if the parsing fails.
Definition: mux_utils.c:137
AV_LOG_VERBOSE
#define AV_LOG_VERBOSE
Detailed information.
Definition: log.h:226
ff_codec_wav_tags
const AVCodecTag ff_codec_wav_tags[]
Definition: riff.c:530
MOVIentry::flags
uint32_t flags
Definition: movenc.h:61
mov_write_itunes_hdlr_tag
static int mov_write_itunes_hdlr_tag(AVIOContext *pb, MOVMuxContext *mov, AVFormatContext *s)
Definition: movenc.c:4547
mov_write_header
static int mov_write_header(AVFormatContext *s)
Definition: movenc.c:8675
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:2316
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:4692
AVPacket::duration
int64_t duration
Duration of this packet in AVStream->time_base units, 0 if unknown.
Definition: packet.h:613
get_sidx_size
static int get_sidx_size(AVFormatContext *s)
Definition: movenc.c:8868
AVStreamGroup::tref
struct AVStreamGroupTREF * tref
Definition: avformat.h:1154
AVCodecParameters::codec_tag
uint32_t codec_tag
Additional information about the codec (corresponds to the AVI FOURCC).
Definition: codec_par.h:61
AV_SPHERICAL_EQUIRECTANGULAR_TILE
@ AV_SPHERICAL_EQUIRECTANGULAR_TILE
Video represents a portion of a sphere mapped on a flat surface using equirectangular projection.
Definition: spherical.h:68
AVStereo3D::baseline
uint32_t baseline
The distance between the centres of the lenses of the camera system, in micrometers.
Definition: stereo3d.h:228
max
#define max(a, b)
Definition: cuda_runtime.h:33
FF_MOV_FLAG_WRITE_GAMA
#define FF_MOV_FLAG_WRITE_GAMA
Definition: movenc.h:293
mathematics.h
FF_COMPLIANCE_EXPERIMENTAL
#define FF_COMPLIANCE_EXPERIMENTAL
Allow nonstandardized experimental things.
Definition: defs.h:62
mov_write_d263_tag
static int mov_write_d263_tag(AVIOContext *pb)
Definition: movenc.c:1556
MOVTrack::track_id
int track_id
Definition: movenc.h:122
AV_CODEC_ID_FLAC
@ AV_CODEC_ID_FLAC
Definition: codec_id.h:473
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:2224
av_sub_q
AVRational av_sub_q(AVRational b, AVRational c)
Subtract one rational from another.
Definition: rational.c:101
ff_mov_init_hinting
int ff_mov_init_hinting(AVFormatContext *s, int index, int src_index)
Definition: movenchint.c:30
ff_isom_write_apvc
void ff_isom_write_apvc(AVIOContext *pb, const APVDecoderConfigurationRecord *apvc, void *logctx)
Definition: apv.c:80
ff_mov_get_channel_layout_tag
int ff_mov_get_channel_layout_tag(const AVCodecParameters *par, uint32_t *layout, uint32_t *bitmap, uint32_t **pchannel_desc)
Get the channel layout tag for the specified codec id and channel layout.
Definition: mov_chan.c:463
AVChannelLayout::nb_channels
int nb_channels
Number of channels in this layout.
Definition: channel_layout.h:329
mov_write_srat_tag
static int mov_write_srat_tag(AVIOContext *pb, MOVTrack *track)
Definition: movenc.c:1362
AV_SPHERICAL_EQUIRECTANGULAR
@ AV_SPHERICAL_EQUIRECTANGULAR
Video represents a sphere mapped on a flat surface using equirectangular projection.
Definition: spherical.h:52
intfloat.h
mov_write_rtp_tag
static int mov_write_rtp_tag(AVIOContext *pb, MOVTrack *track)
Definition: movenc.c:3049
MOVTrack::track_duration
int64_t track_duration
Definition: movenc.h:99
MOV_SAMPLE_DEPENDENCY_UNKNOWN
#define MOV_SAMPLE_DEPENDENCY_UNKNOWN
Definition: isom.h:438
is_clcp_track
static int is_clcp_track(MOVTrack *track)
Definition: movenc.c:3541
AV_CODEC_ID_R10K
@ AV_CODEC_ID_R10K
Definition: codec_id.h:197
codec_cover_image_tags
static const AVCodecTag codec_cover_image_tags[]
Definition: movenc.c:2162
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:505
AV_STEREO3D_VIEW_UNSPEC
@ AV_STEREO3D_VIEW_UNSPEC
Content is unspecified.
Definition: stereo3d.h:168
avio_get_dyn_buf
int avio_get_dyn_buf(AVIOContext *s, uint8_t **pbuffer)
Return the written size and a pointer to the buffer.
Definition: aviobuf.c:1377
tf_sess_config.config
config
Definition: tf_sess_config.py:33
AV_PKT_FLAG_KEY
#define AV_PKT_FLAG_KEY
The packet contains a keyframe.
Definition: packet.h:650
MOVTrack::dts_shift
int64_t dts_shift
Definition: movenc.h:141
init_get_bits
static int init_get_bits(GetBitContext *s, const uint8_t *buffer, int bit_size)
Initialize GetBitContext.
Definition: get_bits.h:517
ff_get_muxer_ts_offset
int ff_get_muxer_ts_offset(AVFormatContext *s, int stream_index, int64_t *offset)
Definition: mux.c:1027
av_packet_free
void av_packet_free(AVPacket **pkt)
Free the packet, if the packet is reference counted, it will be unreferenced first.
Definition: packet.c:74
MOVIentry::entries
unsigned int entries
Definition: movenc.h:56
AV_PIX_FMT_RGB555BE
@ AV_PIX_FMT_RGB555BE
packed RGB 5:5:5, 16bpp, (msb)1X 5R 5G 5B(lsb), big-endian , X=unused/undefined
Definition: pixfmt.h:114
MOVMuxContext::write_prft
MOVPrftBox write_prft
Definition: movenc.h:267
MOVTrack::first_frag_written
int first_frag_written
Definition: movenc.h:171
ascii_to_wc
static int ascii_to_wc(AVIOContext *pb, const uint8_t *b)
Definition: movenc.c:4982
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:443
AV_CODEC_ID_BIN_DATA
@ AV_CODEC_ID_BIN_DATA
Definition: codec_id.h:614
MOVMuxContext::mdat_size
uint64_t mdat_size
Definition: movenc.h:219
mov_write_chnl_tag
static int mov_write_chnl_tag(AVFormatContext *s, AVIOContext *pb, MOVTrack *track)
Definition: movenc.c:1294
MOVMuxContext::write_tmcd
int write_tmcd
Definition: movenc.h:266
OPUS_SEEK_PREROLL_MS
#define OPUS_SEEK_PREROLL_MS
Definition: oggparseopus.c:36
FF_MOV_FLAG_CMAF
#define FF_MOV_FLAG_CMAF
Definition: movenc.h:299
mov_write_tfdt_tag
static int mov_write_tfdt_tag(AVIOContext *pb, MOVTrack *track)
Definition: movenc.c:5838
MOVTrack::frag_info
MOVFragmentInfo * frag_info
Definition: movenc.h:164
mov_write_wave_tag
static int mov_write_wave_tag(AVFormatContext *s, AVIOContext *pb, MOVTrack *track)
Definition: movenc.c:1054
find_next_marker
static const av_always_inline uint8_t * find_next_marker(const uint8_t *src, const uint8_t *end)
Find VC-1 marker in buffer.
Definition: vc1_common.h:59
mov_find_tref_id
static int mov_find_tref_id(MOVMuxContext *mov, const MovTag *tag, uint32_t id)
Definition: movenc.c:5269
AV_CODEC_ID_MPEGH_3D_AUDIO
@ AV_CODEC_ID_MPEGH_3D_AUDIO
Definition: codec_id.h:552
MOV_PRFT_SRC_PTS
@ MOV_PRFT_SRC_PTS
Definition: movenc.h:206
MOVTrack
Definition: movenc.h:93
av_memdup
void * av_memdup(const void *p, size_t size)
Duplicate a buffer with av_malloc().
Definition: mem.c:304
AVContentLightMetadata
Content light level needed by to transmit HDR over HDMI (CTA-861.3).
Definition: mastering_display_metadata.h:107
AV_PKT_DATA_DOVI_CONF
@ AV_PKT_DATA_DOVI_CONF
DOVI configuration ref: dolby-vision-bitstreams-within-the-iso-base-media-file-format-v2....
Definition: packet.h:280
MOVFragmentInfo::offset
int64_t offset
Definition: movenc.h:80
AVStereo3D::horizontal_field_of_view
AVRational horizontal_field_of_view
Horizontal field of view, in degrees.
Definition: stereo3d.h:239
skip_bits
static void skip_bits(GetBitContext *s, int n)
Definition: get_bits.h:383
AVCodecParameters::color_primaries
enum AVColorPrimaries color_primaries
Definition: codec_par.h:190
avio_write_marker
void avio_write_marker(AVIOContext *s, int64_t time, enum AVIODataMarkerType type)
Mark the written bytestream as a specific type.
Definition: aviobuf.c:464
AV_PIX_FMT_GRAY16BE
@ AV_PIX_FMT_GRAY16BE
Y , 16bpp, big-endian.
Definition: pixfmt.h:104
AV_STEREO3D_SIDEBYSIDE
@ AV_STEREO3D_SIDEBYSIDE
Views are next to each other.
Definition: stereo3d.h:64
AVPacketSideData::size
size_t size
Definition: packet.h:418
mov_write_trex_tag
static int mov_write_trex_tag(AVIOContext *pb, MOVTrack *track)
Definition: movenc.c:4458
get_bits
static unsigned int get_bits(GetBitContext *s, int n)
Read 1-25 bits.
Definition: get_bits.h:337
FF_MOV_FLAG_FRAG_EVERY_FRAME
#define FF_MOV_FLAG_FRAG_EVERY_FRAME
Definition: movenc.h:297
mov_write_dvc1_tag
static int mov_write_dvc1_tag(AVIOContext *pb, MOVTrack *track)
Definition: movenc.c:1181
rgb
Definition: rpzaenc.c:60
MOVTrack::entry_version
int entry_version
Definition: movenc.h:95
put_descr
static void put_descr(AVIOContext *pb, int tag, unsigned int size)
Definition: movenc.c:694
eac3_info::ac3_bit_rate_code
int8_t ac3_bit_rate_code
Definition: movenc.c:391
mov_write_vexu_proj_tag
static void mov_write_vexu_proj_tag(AVFormatContext *s, AVIOContext *pb, const AVSphericalMapping *spherical_mapping)
Definition: movenc.c:2390
MOV_ENC_NONE
@ MOV_ENC_NONE
Definition: movenc.h:199
MODE_ISM
#define MODE_ISM
Definition: movenc.h:44
get_pts_range
static void get_pts_range(MOVMuxContext *mov, MOVTrack *track, int64_t *start, int64_t *end, int elst)
Definition: movenc.c:3840
mov_write_pcmc_tag
static int mov_write_pcmc_tag(AVFormatContext *s, AVIOContext *pb, MOVTrack *track)
Definition: movenc.c:1336
AV_STEREO3D_VIEW_PACKED
@ AV_STEREO3D_VIEW_PACKED
Frame contains two packed views.
Definition: stereo3d.h:153
avpriv_set_pts_info
void avpriv_set_pts_info(AVStream *st, int pts_wrap_bits, unsigned int pts_num, unsigned int pts_den)
Set the time base and wrapping info for a given stream.
Definition: avformat.c:900
AV_OPT_TYPE_BINARY
@ AV_OPT_TYPE_BINARY
Underlying C type is a uint8_t* that is either NULL or points to an array allocated with the av_mallo...
Definition: opt.h:286
calc_samples_pts_duration
static int64_t calc_samples_pts_duration(MOVMuxContext *mov, MOVTrack *track)
Definition: movenc.c:3865
AC3HeaderInfo::complexity_index_type_a
uint8_t complexity_index_type_a
Definition: ac3_parser_internal.h:81
FF_MOV_FLAG_DEFAULT_BASE_MOOF
#define FF_MOV_FLAG_DEFAULT_BASE_MOOF
Definition: movenc.h:287
mov_write_audio_tag
static int mov_write_audio_tag(AVFormatContext *s, AVIOContext *pb, MOVMuxContext *mov, MOVTrack *track)
Definition: movenc.c:1374
eac3_info::acmod
uint8_t acmod
Definition: movenc.c:404
MOV_TRACK_CTTS
#define MOV_TRACK_CTTS
Definition: movenc.h:113
AV_CODEC_ID_PCM_S16BE
@ AV_CODEC_ID_PCM_S16BE
Definition: codec_id.h:340
defined_frame_rate
static int defined_frame_rate(AVFormatContext *s, AVStream *st)
Definition: movenc.c:1893
MOV_FRAG_SAMPLE_FLAG_IS_NON_SYNC
#define MOV_FRAG_SAMPLE_FLAG_IS_NON_SYNC
Definition: isom.h:424
fail
#define fail()
Definition: checkasm.h:225
mov_write_gpmd_tag
static int mov_write_gpmd_tag(AVIOContext *pb, const MOVTrack *track)
Definition: movenc.c:3137
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:4652
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:1455
MOVMuxContext::use_editlist
int use_editlist
Definition: movenc.h:250
mov_write_mvex_tag
static int mov_write_mvex_tag(AVIOContext *pb, MOVMuxContext *mov)
Definition: movenc.c:4471
timecode.h
MOV_TRACK_STPS
#define MOV_TRACK_STPS
Definition: movenc.h:114
eac3_info::chan_loc
uint16_t chan_loc
Definition: movenc.c:411
mov_write_dref_tag
static int mov_write_dref_tag(AVIOContext *pb)
Definition: movenc.c:3274
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:3902
mov_write_video_tag
static int mov_write_video_tag(AVFormatContext *s, AVIOContext *pb, MOVMuxContext *mov, MOVTrack *track)
Definition: movenc.c:2783
AC3HeaderInfo
Definition: ac3_parser_internal.h:34
mov_write_evcc_tag
static int mov_write_evcc_tag(AVIOContext *pb, MOVTrack *track)
Definition: movenc.c:1671
MOVTrack::frag_discont
int frag_discont
Definition: movenc.h:160
mov_get_rawvideo_codec_tag
static int mov_get_rawvideo_codec_tag(AVFormatContext *s, MOVTrack *track)
Definition: movenc.c:2081
mov_write_esds_tag
static int mov_write_esds_tag(AVIOContext *pb, MOVTrack *track)
Definition: movenc.c:765
AC3HeaderInfo::frame_size
uint16_t frame_size
Definition: ac3_parser_internal.h:62
avio_tell
static av_always_inline int64_t avio_tell(AVIOContext *s)
ftell() equivalent for AVIOContext.
Definition: avio.h:494
MOVTrack::first_packet_entry
int first_packet_entry
Definition: movenc.h:169
mov_write_ftyp_tag
static int mov_write_ftyp_tag(AVIOContext *pb, AVFormatContext *s)
Definition: movenc.c:6214
EAC3_FRAME_TYPE_DEPENDENT
@ EAC3_FRAME_TYPE_DEPENDENT
Definition: ac3defs.h:112
AVChapter
Definition: avformat.h:1243
MOV_TRUN_SAMPLE_DURATION
#define MOV_TRUN_SAMPLE_DURATION
Definition: isom.h:418
val
static double val(void *priv, double ch)
Definition: aeval.c:77
compute_avg_bitrate
static unsigned compute_avg_bitrate(MOVTrack *track)
Definition: movenc.c:703
MOVTrack::apv
struct APVDecoderConfigurationRecord * apv
Definition: movenc.h:195
MOVIentry::size
unsigned int size
Definition: movenc.h:52
validate_codec_tag
static unsigned int validate_codec_tag(const AVCodecTag *const *tags, unsigned int tag, int codec_id)
Definition: movenc.c:2169
MOVTrack::mdat_buf
AVIOContext * mdat_buf
Definition: movenc.h:158
MOVTrack::cluster
MOVIentry * cluster
Definition: movenc.h:129
AVFMT_AVOID_NEG_TS_MAKE_ZERO
#define AVFMT_AVOID_NEG_TS_MAKE_ZERO
Shift timestamps so that they start at 0.
Definition: avformat.h:1677
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:1688
mov_setup_track_ids
static int mov_setup_track_ids(MOVMuxContext *mov, AVFormatContext *s)
Assign track ids.
Definition: movenc.c:5230
pts
static int64_t pts
Definition: transcode_aac.c:644
AVStreamGroupLCEVC
AVStreamGroupLCEVC is meant to define the relation between video streams and a data stream containing...
Definition: avformat.h:1072
MOV_SYNC_SAMPLE
#define MOV_SYNC_SAMPLE
Definition: movenc.h:58
FF_MOV_FLAG_USE_MDTA
#define FF_MOV_FLAG_USE_MDTA
Definition: movenc.h:294
AV_CODEC_ID_MP3
@ AV_CODEC_ID_MP3
preferred ID for decoding MPEG audio layer 1, 2 or 3
Definition: codec_id.h:462
mov_finish_fragment
static int mov_finish_fragment(MOVMuxContext *mov, MOVTrack *track, int64_t ref_pos)
Definition: movenc.c:6623
mov_write_iref_tag
static int mov_write_iref_tag(AVIOContext *pb, MOVMuxContext *mov, AVFormatContext *s)
Definition: movenc.c:3690
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:5157
MOVMuxContext::iods_video_profile
int iods_video_profile
Definition: movenc.h:226
av_reduce
int av_reduce(int *dst_num, int *dst_den, int64_t num, int64_t den, int64_t max)
Reduce a fraction.
Definition: rational.c:35
MOV_PRFT_NB
@ MOV_PRFT_NB
Definition: movenc.h:207
ff_data_to_hex
char * ff_data_to_hex(char *buf, const uint8_t *src, int size, int lowercase)
Write hexadecimal string corresponding to given binary data.
Definition: utils.c:458
AVRational::num
int num
Numerator.
Definition: rational.h:59
AV_CH_LAYOUT_STEREO
#define AV_CH_LAYOUT_STEREO
Definition: channel_layout.h:218
vpcc.h
MOV_CH_LAYOUT_MONO
@ MOV_CH_LAYOUT_MONO
Definition: mov_chan.h:56
mov_get_dv_codec_tag
static int mov_get_dv_codec_tag(AVFormatContext *s, MOVTrack *track)
Definition: movenc.c:1868
MOVIentry::prft
AVProducerReferenceTime prft
Definition: movenc.h:62
MOV_FRAG_SAMPLE_FLAG_DEPENDS_YES
#define MOV_FRAG_SAMPLE_FLAG_DEPENDS_YES
Definition: isom.h:431
MovTag
Definition: movenc.h:87
MOV_TRUN_DATA_OFFSET
#define MOV_TRUN_DATA_OFFSET
Definition: isom.h:416
eac3_info::lfeon
uint8_t lfeon
Definition: movenc.c:406
handle_eac3
static int handle_eac3(MOVMuxContext *mov, AVPacket *pkt, MOVTrack *track)
Definition: movenc.c:464
CENC_KID_SIZE
#define CENC_KID_SIZE
Definition: movenccenc.h:30
raw.h
ff_psp_muxer
const FFOutputFormat ff_psp_muxer
ff_mov_cenc_free
void ff_mov_cenc_free(MOVMuxCencContext *ctx)
Free a CENC context.
Definition: movenccenc.c:639
ff_isom_write_evcc
int ff_isom_write_evcc(AVIOContext *pb, const uint8_t *data, int size, int ps_array_completeness)
Writes EVC sample metadata to the provided AVIOContext.
Definition: evc.c:298
dnxhddata.h
mov_prune_frag_info
static void mov_prune_frag_info(MOVMuxContext *mov, int tracks, int max)
Definition: movenc.c:5824
av_get_bits_per_sample
int av_get_bits_per_sample(enum AVCodecID codec_id)
Return codec bits per sample.
Definition: utils.c:549
GET_UTF8
#define GET_UTF8(val, GET_BYTE, ERROR)
Convert a UTF-8 character (up to 4 bytes) to its 32-bit UCS-4 encoded form.
Definition: common.h:488
AVCodecParameters::color_trc
enum AVColorTransferCharacteristic color_trc
Definition: codec_par.h:191
MOVTrack::st
AVStream * st
Definition: movenc.h:124
avio_close_dyn_buf
int avio_close_dyn_buf(AVIOContext *s, uint8_t **pbuffer)
Return the written size and a pointer to the buffer.
Definition: aviobuf.c:1410
mov_write_tmpo_tag
static int mov_write_tmpo_tag(AVIOContext *pb, AVFormatContext *s)
Definition: movenc.c:4674
ff_mp4_muxer
const FFOutputFormat ff_mp4_muxer
MOVTrack::nb_tref_tags
int nb_tref_tags
Definition: movenc.h:134
mov_write_trak_tag
static int mov_write_trak_tag(AVFormatContext *s, AVIOContext *pb, MOVMuxContext *mov, MOVTrack *track, AVStream *st)
Definition: movenc.c:4373
AV_CODEC_ID_PCM_S8
@ AV_CODEC_ID_PCM_S8
Definition: codec_id.h:343
first
trying all byte sequences megabyte in length and selecting the best looking sequence will yield cases to try But first
Definition: rate_distortion.txt:12
MODE_AVIF
#define MODE_AVIF
Definition: movenc.h:46
pix_fmt
enum AVPixelFormat pix_fmt
Definition: movenc.c:2048
lrint
#define lrint
Definition: tablegen.h:53
eac3_info::pkt
AVPacket * pkt
Definition: movenc.c:384
eac3_info::bsmod
uint8_t bsmod
Definition: movenc.c:402
MOVTrack::palette
uint32_t palette[AVPALETTE_COUNT]
Definition: movenc.h:181
pkt
static AVPacket * pkt
Definition: movenc.c:60
AV_LOG_ERROR
#define AV_LOG_ERROR
Something went wrong and cannot losslessly be recovered.
Definition: log.h:210
FF_MOV_FLAG_FRAG_DISCONT
#define FF_MOV_FLAG_FRAG_DISCONT
Definition: movenc.h:289
mov_write_trailer
static int mov_write_trailer(AVFormatContext *s)
Definition: movenc.c:8963
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
AVStreamGroup::params
union AVStreamGroup::@448 params
Group type-specific parameters.
AVCodecTag
Definition: internal.h:42
mov_write_emsg_tag
static int mov_write_emsg_tag(AVIOContext *pb, AVStream *st, AVPacket *pkt)
Definition: movenc.c:7518
MOVTrack::squashed_packet_queue
PacketList squashed_packet_queue
Definition: movenc.h:188
MOVTrack::mono_as_fc
int mono_as_fc
Definition: movenc.h:126
MOVMuxContext::encryption_kid_len
int encryption_kid_len
Definition: movenc.h:261
MOVMuxContext::pkt
AVPacket * pkt
Definition: movenc.h:248
duration
static int64_t duration
Definition: movenc.c:65
AV_FIELD_UNKNOWN
@ AV_FIELD_UNKNOWN
Definition: defs.h:212
AVCodecParameters::frame_size
int frame_size
Audio frame size, if known.
Definition: codec_par.h:227
av_dict_get
AVDictionaryEntry * av_dict_get(const AVDictionary *m, const char *key, const AVDictionaryEntry *prev, int flags)
Get a dictionary entry with matching key.
Definition: dict.c:60
avio_open_dyn_buf
int avio_open_dyn_buf(AVIOContext **s)
Open a write only memory stream.
Definition: aviobuf.c:1365
av_channel_layout_describe
int av_channel_layout_describe(const AVChannelLayout *channel_layout, char *buf, size_t buf_size)
Get a human-readable string describing the channel layout properties.
Definition: channel_layout.c:654
AES_CTR_KEY_SIZE
#define AES_CTR_KEY_SIZE
Definition: aes_ctr.h:35
AV_STREAM_GROUP_PARAMS_IAMF_MIX_PRESENTATION
@ AV_STREAM_GROUP_PARAMS_IAMF_MIX_PRESENTATION
Definition: avformat.h:1108
MOVMuxContext::chapter_track
int chapter_track
qt chapter track number
Definition: movenc.h:217
FF_MOV_FLAG_FRAGMENT
#define FF_MOV_FLAG_FRAGMENT
Definition: movenc.h:278
full_range
bool full_range
Definition: hwcontext_videotoolbox.c:47
AV_CODEC_ID_ADPCM_G726
@ AV_CODEC_ID_ADPCM_G726
Definition: codec_id.h:389
VC1_CODE_SLICE
@ VC1_CODE_SLICE
Definition: vc1_common.h:36
ff_iamf_add_audio_element
int ff_iamf_add_audio_element(IAMFContext *iamf, const AVStreamGroup *stg, void *log_ctx)
Definition: iamf_writer.c:223
stereo3d.h
s
#define s(width, name)
Definition: cbs_vp9.c:198
MOV_TFHD_DEFAULT_BASE_IS_MOOF
#define MOV_TFHD_DEFAULT_BASE_IS_MOOF
Definition: isom.h:414
AV_CODEC_ID_BMP
@ AV_CODEC_ID_BMP
Definition: codec_id.h:130
mov_write_chpl_tag
static int mov_write_chpl_tag(AVIOContext *pb, AVFormatContext *s)
Definition: movenc.c:5022
AV_CODEC_ID_EVC
@ AV_CODEC_ID_EVC
Definition: codec_id.h:325
AV_CODEC_ID_WMAPRO
@ AV_CODEC_ID_WMAPRO
Definition: codec_id.h:498
MOV_TFHD_DEFAULT_DURATION
#define MOV_TFHD_DEFAULT_DURATION
Definition: isom.h:410
MOVMuxContext::movie_timescale
int movie_timescale
Definition: movenc.h:269
MOVCtts::count
unsigned int count
Definition: isom.h:69
av_realloc_array
void * av_realloc_array(void *ptr, size_t nmemb, size_t size)
Definition: mem.c:217
AVFormatContext::flags
int flags
Flags modifying the (de)muxer behaviour.
Definition: avformat.h:1435
AVCodecParameters::sample_aspect_ratio
AVRational sample_aspect_ratio
The aspect ratio (width/height) which a single pixel should have when displayed.
Definition: codec_par.h:161
FF_MOV_FLAG_DELAY_MOOV
#define FF_MOV_FLAG_DELAY_MOOV
Definition: movenc.h:290
mov_write_av3c
static int mov_write_av3c(AVIOContext *pb, const uint8_t *data, int len)
Definition: movenc.c:1594
g
const char * g
Definition: vf_curves.c:128
mov_write_ac3_tag
static int mov_write_ac3_tag(AVFormatContext *s, AVIOContext *pb, MOVTrack *track)
Definition: movenc.c:418
MOVMuxContext::per_stream_grouping
int per_stream_grouping
Definition: movenc.h:245
AVDictionaryEntry::key
char * key
Definition: dict.h:91
AVSphericalMapping::bound_top
uint32_t bound_top
Distance from the top edge.
Definition: spherical.h:186
AVMEDIA_TYPE_AUDIO
@ AVMEDIA_TYPE_AUDIO
Definition: avutil.h:201
AV_CODEC_ID_VP9
@ AV_CODEC_ID_VP9
Definition: codec_id.h:222
AVCodecParameters::width
int width
The width of the video frame in pixels.
Definition: codec_par.h:143
AV_CODEC_ID_MP2
@ AV_CODEC_ID_MP2
Definition: codec_id.h:461
ff_av1_filter_obus_buf
int ff_av1_filter_obus_buf(const uint8_t *in, uint8_t **out, int *size, int *offset)
Filter out AV1 OBUs not meant to be present in ISOBMFF sample data and return the result in a data bu...
Definition: av1.c:88
MOV_TRUN_FIRST_SAMPLE_FLAGS
#define MOV_TRUN_FIRST_SAMPLE_FLAGS
Definition: isom.h:417
MOVTrack::stsd_count
int stsd_count
Definition: movenc.h:103
av_q2d
static double av_q2d(AVRational a)
Convert an AVRational to a double.
Definition: rational.h:104
MOVMuxContext::nb_meta_tmcd
int nb_meta_tmcd
number of new created tmcd track based on metadata (aka not data copy)
Definition: movenc.h:216
utf8len
static int utf8len(const uint8_t *b)
Definition: movenc.c:143
info
MIPS optimizations info
Definition: mips.txt:2
mov_write_tfra_tag
static int mov_write_tfra_tag(AVIOContext *pb, MOVTrack *track)
Definition: movenc.c:6100
MOVStts::duration
unsigned int duration
Definition: isom.h:65
av_match_ext
int av_match_ext(const char *filename, const char *extensions)
Return a positive value if the given filename has one of the given extensions, 0 otherwise.
Definition: format.c:41
MOVTrack::timecode_flags
uint32_t timecode_flags
Definition: movenc.h:120
MOVIentry::pts
int64_t pts
Definition: movenc.h:51
MOVTrack::has_disposable
int has_disposable
Definition: movenc.h:112
FF_MOV_FLAG_NEGATIVE_CTS_OFFSETS
#define FF_MOV_FLAG_NEGATIVE_CTS_OFFSETS
Definition: movenc.h:296
av_assert0
#define av_assert0(cond)
assert() equivalent, that is always enabled.
Definition: avassert.h:42
MODE_F4V
#define MODE_F4V
Definition: movenc.h:45
AVMEDIA_TYPE_NB
@ AVMEDIA_TYPE_NB
Definition: avutil.h:205
EAC3_FRAME_TYPE_INDEPENDENT
@ EAC3_FRAME_TYPE_INDEPENDENT
Definition: ac3defs.h:111
mov_write_trkn_tag
static int mov_write_trkn_tag(AVIOContext *pb, MOVMuxContext *mov, AVFormatContext *s, int disc)
Definition: movenc.c:4743
MOVTrack::entry_written
int entry_written
Definition: movenc.h:96
ff_isom_put_dvcc_dvvc
void ff_isom_put_dvcc_dvvc(void *logctx, uint8_t out[ISOM_DVCC_DVVC_SIZE], const AVDOVIDecoderConfigurationRecord *dovi)
Definition: dovi_isom.c:89
FF_MOV_FLAG_PREFER_ICC
#define FF_MOV_FLAG_PREFER_ICC
Definition: movenc.h:300
PROFILE_ADVANCED
@ PROFILE_ADVANCED
Definition: vc1_common.h:52
ff_nal_parse_units
int ff_nal_parse_units(AVIOContext *pb, const uint8_t *buf_in, int size)
Definition: nal.c:113
MOVMuxContext::encryption_kid
uint8_t * encryption_kid
Definition: movenc.h:260
AV_LOG_DEBUG
#define AV_LOG_DEBUG
Stuff which is only useful for libav* developers.
Definition: log.h:231
AVPacketSideData::data
uint8_t * data
Definition: packet.h:417
AVDOVIDecoderConfigurationRecord::dv_profile
uint8_t dv_profile
Definition: dovi_meta.h:58
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:3737
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:3642
AV_RL16
uint64_t_TMPL AV_WL64 unsigned int_TMPL AV_WL32 unsigned int_TMPL AV_WL24 unsigned int_TMPL AV_RL16
Definition: bytestream.h:94
AV_PKT_DATA_STEREO3D
@ AV_PKT_DATA_STEREO3D
This side data should be associated with a video stream and contains Stereoscopic 3D information in f...
Definition: packet.h:111
MOVMuxContext::frag_interleave
int frag_interleave
Definition: movenc.h:253
ffio_write_leb
void ffio_write_leb(AVIOContext *s, unsigned val)
Definition: aviobuf.c:947
av_rescale_q
int64_t av_rescale_q(int64_t a, AVRational bq, AVRational cq)
Rescale a 64-bit integer by 2 rational numbers.
Definition: mathematics.c:142
channel_map
static const uint8_t channel_map[8][8]
Definition: atrac3plusdec.c:52
AVPixFmtDescriptor::log2_chroma_w
uint8_t log2_chroma_w
Amount to shift the luma width right to find the chroma width.
Definition: pixdesc.h:80
MOVTrack::max_packet_size
uint32_t max_packet_size
Definition: movenc.h:149
MOVTrack::sample_size
long sample_size
Definition: movenc.h:109
codec_id
enum AVCodecID codec_id
Definition: vaapi_decode.c:410
AV_PIX_FMT_YUV420P
@ AV_PIX_FMT_YUV420P
planar YUV 4:2:0, 12bpp, (1 Cr & Cb sample per 2x2 Y samples)
Definition: pixfmt.h:73
AV_CODEC_ID_SVQ3
@ AV_CODEC_ID_SVQ3
Definition: codec_id.h:75
key
const char * key
Definition: hwcontext_opencl.c:189
AVCodecParameters::nb_coded_side_data
int nb_coded_side_data
Amount of entries in coded_side_data.
Definition: codec_par.h:88
AVMEDIA_TYPE_DATA
@ AVMEDIA_TYPE_DATA
Opaque data information usually continuous.
Definition: avutil.h:202
av_mallocz
#define av_mallocz(s)
Definition: tableprint_vlc.h:31
MOVIentry::pos
uint64_t pos
Definition: movenc.h:49
mov_parse_mpeg2_frame
static int mov_parse_mpeg2_frame(AVPacket *pkt, uint32_t *flags)
Definition: movenc.c:6436
mov_write_tcmi_tag
static int mov_write_tcmi_tag(AVIOContext *pb, MOVTrack *track)
Definition: movenc.c:3448
build_chunks
static void build_chunks(MOVTrack *trk)
Definition: movenc.c:5194
MOV_PRFT_NONE
@ MOV_PRFT_NONE
Definition: movenc.h:204
AVCOL_PRI_UNSPECIFIED
@ AVCOL_PRI_UNSPECIFIED
Definition: pixfmt.h:639
mov_write_edts_tag
static int mov_write_edts_tag(AVIOContext *pb, MOVMuxContext *mov, MOVTrack *track)
Definition: movenc.c:4115
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:2598
AV_CODEC_ID_H264
@ AV_CODEC_ID_H264
Definition: codec_id.h:79
PutBitContext
Definition: put_bits.h:50
mov_write_hdlr_tag
static int mov_write_hdlr_tag(AVFormatContext *s, AVIOContext *pb, MOVTrack *track)
Definition: movenc.c:3547
MOVMuxContext::time
int64_t time
Definition: movenc.h:213
tmp
static uint8_t tmp[40]
Definition: aes_ctr.c:52
MOVTrack::packet_entry
int packet_entry
Definition: movenc.h:173
AV_PIX_FMT_RGBA
@ AV_PIX_FMT_RGBA
packed RGBA 8:8:8:8, 32bpp, RGBARGBA...
Definition: pixfmt.h:100
AVStereo3D::flags
int flags
Additional information about the frame packing.
Definition: stereo3d.h:212
AV_CODEC_ID_PNG
@ AV_CODEC_ID_PNG
Definition: codec_id.h:113
AV_CODEC_ID_AVUI
@ AV_CODEC_ID_AVUI
Definition: codec_id.h:257
FF_MOV_FLAG_RTP_HINT
#define FF_MOV_FLAG_RTP_HINT
Definition: movenc.h:277
if
if(ret)
Definition: filter_design.txt:179
mov_write_mfhd_tag
static int mov_write_mfhd_tag(AVIOContext *pb, MOVMuxContext *mov)
Definition: movenc.c:5579
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:5106
mov_write_vpcc_tag
static int mov_write_vpcc_tag(AVFormatContext *s, AVIOContext *pb, MOVTrack *track)
Definition: movenc.c:1623
avio_flush
void avio_flush(AVIOContext *s)
Force flushing of buffered data.
Definition: aviobuf.c:228
MOVMuxContext::use_stream_ids_as_track_ids
int use_stream_ids_as_track_ids
Definition: movenc.h:263
avpriv_packet_list_free
void avpriv_packet_list_free(PacketList *pkt_buf)
Wipe the list and unref all the packets in it.
Definition: packet.c:610
MOVTrack::sample_count
long sample_count
Definition: movenc.h:108
MOVTrack::start_dts
int64_t start_dts
Definition: movenc.h:136
AV_CODEC_ID_AVS3
@ AV_CODEC_ID_AVS3
Definition: codec_id.h:250
AVFormatContext
Format I/O context.
Definition: avformat.h:1284
MOVMuxContext::iods_skip
int iods_skip
Definition: movenc.h:225
mov_isobmff_muxer_class
static const AVClass mov_isobmff_muxer_class
Definition: movenc.c:133
calculate_mpeg4_bit_rates
static struct mpeg4_bit_rate_values calculate_mpeg4_bit_rates(MOVTrack *track)
Definition: movenc.c:720
evc.h
AVStreamGroupLCEVC::height
int height
Height of the final image for presentation.
Definition: avformat.h:1086
options
static const AVOption options[]
Definition: movenc.c:78
AVPacket::buf
AVBufferRef * buf
A reference to the reference-counted buffer where the packet data is stored.
Definition: packet.h:578
AVStream::codecpar
AVCodecParameters * codecpar
Codec parameters associated with this stream.
Definition: avformat.h:770
compute_moov_size
static int compute_moov_size(AVFormatContext *s)
Definition: movenc.c:8886
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:3632
av_buffer_unref
void av_buffer_unref(AVBufferRef **buf)
Free a given reference and automatically free the buffer if there are no more references to it.
Definition: buffer.c:139
mov_pcm_be_gt16
static int mov_pcm_be_gt16(enum AVCodecID codec_id)
Definition: movenc.c:826
AV_CODEC_ID_AV1
@ AV_CODEC_ID_AV1
Definition: codec_id.h:284
AVPixFmtDescriptor::nb_components
uint8_t nb_components
The number of components each pixel has, (1-4)
Definition: pixdesc.h:71
AVEncryptionInitInfo
This describes info used to initialize an encryption key system.
Definition: encryption_info.h:88
isom.h
AV_CODEC_ID_TIMED_ID3
@ AV_CODEC_ID_TIMED_ID3
Definition: codec_id.h:613
mov_check_timecode_track
static int mov_check_timecode_track(AVFormatContext *s, AVTimecode *tc, AVStream *src_st, const char *tcstr)
Definition: movenc.c:7788
codec_f4v_tags
static const AVCodecTag codec_f4v_tags[]
Definition: movenc.c:9262
mov_create_timecode_track
static int mov_create_timecode_track(AVFormatContext *s, int index, int src_index, AVTimecode tc)
Definition: movenc.c:7797
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:7546
MP4TrackKindValueMapping::disposition
int disposition
Definition: isom.h:488
mov_write_stsc_tag
static int mov_write_stsc_tag(AVIOContext *pb, MOVTrack *track)
Definition: movenc.c:261
AV_WB16
#define AV_WB16(p, v)
Definition: intreadwrite.h:401
avpriv_packet_list_put
int avpriv_packet_list_put(PacketList *packet_buffer, AVPacket *pkt, int(*copy)(AVPacket *dst, const AVPacket *src), int flags)
Append an AVPacket to the list.
Definition: packet.c:547
AVIO_DATA_MARKER_TRAILER
@ AVIO_DATA_MARKER_TRAILER
Trailer data, which doesn't contain actual content, but only for finalizing the output file.
Definition: avio.h:139
AV_PIX_FMT_YUYV422
@ AV_PIX_FMT_YUYV422
packed YUV 4:2:2, 16bpp, Y0 Cb Y1 Cr
Definition: pixfmt.h:74
get_moov_size
static int get_moov_size(AVFormatContext *s)
Definition: movenc.c:8855
vc1_unescape_buffer
static av_always_inline int vc1_unescape_buffer(const uint8_t *src, int size, uint8_t *dst)
Definition: vc1_common.h:70
MOVMuxContext::encryption_key_len
int encryption_key_len
Definition: movenc.h:259
AV_CODEC_ID_MOV_TEXT
@ AV_CODEC_ID_MOV_TEXT
Definition: codec_id.h:578
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:2036
check_pkt
static int check_pkt(AVFormatContext *s, MOVTrack *trk, AVPacket *pkt)
Definition: movenc.c:6879
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:6599
MOVMuxContext::max_fragment_size
int max_fragment_size
Definition: movenc.h:233
ROUNDED_DIV
#define ROUNDED_DIV(a, b)
Definition: common.h:58
AV_CODEC_ID_DVD_SUBTITLE
@ AV_CODEC_ID_DVD_SUBTITLE
Definition: codec_id.h:573
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:5892
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:2535
avc.h
MOVTrack::cenc
MOVMuxCencContext cenc
Definition: movenc.h:179
AVStreamGroupTREF
AVStreamGroupTREF is meant to define the relation between video, audio, or subtitle streams,...
Definition: avformat.h:1096
options
Definition: swscale.c:45
TAG_IS_AVCI
#define TAG_IS_AVCI(tag)
Definition: isom.h:442
AC3HeaderInfo::substreamid
int substreamid
substream identification
Definition: ac3_parser_internal.h:46
MOVTrack::last_sample_is_subtitle_end
int last_sample_is_subtitle_end
Definition: movenc.h:100
VC1_CODE_ENTRYPOINT
@ VC1_CODE_ENTRYPOINT
Definition: vc1_common.h:39
AVStream::metadata
AVDictionary * metadata
Definition: avformat.h:827
get_cluster_duration
static int get_cluster_duration(MOVTrack *track, int cluster_idx)
Definition: movenc.c:1236
FLAC_STREAMINFO_SIZE
#define FLAC_STREAMINFO_SIZE
Definition: flac.h:32
FFOutputFormat
Definition: mux.h:61
mov_write_pasp_tag
static int mov_write_pasp_tag(AVIOContext *pb, MOVTrack *track)
Definition: movenc.c:2563
MOV_SAMPLE_DEPENDENCY_NO
#define MOV_SAMPLE_DEPENDENCY_NO
Definition: isom.h:440
MOVMuxContext
Definition: movenc.h:210
mov_add_tref_tag
static MovTag * mov_add_tref_tag(MOVMuxContext *mov, MOVTrack *trk, uint32_t name)
Definition: movenc.c:5304
ff_iamf_add_mix_presentation
int ff_iamf_add_mix_presentation(IAMFContext *iamf, const AVStreamGroup *stg, void *log_ctx)
Definition: iamf_writer.c:433
MOVMuxContext::missing_duration_warned
int missing_duration_warned
Definition: movenc.h:254
MOVTrack::data_offset
int64_t data_offset
Definition: movenc.h:159
mov_write_track_metadata
static int mov_write_track_metadata(AVIOContext *pb, AVStream *st, const char *tag, const char *str)
Definition: movenc.c:4280
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:2697
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:709
ff_codec_movvideo_tags
const AVCodecTag ff_codec_movvideo_tags[]
Definition: isom_tags.c:29
AV_PIX_FMT_YUV422P10
#define AV_PIX_FMT_YUV422P10
Definition: pixfmt.h:540
mov_get_lpcm_flags
static int mov_get_lpcm_flags(enum AVCodecID codec_id)
Compute flags for 'lpcm' tag.
Definition: movenc.c:1211
ffio_fill
void ffio_fill(AVIOContext *s, int b, int64_t count)
Definition: aviobuf.c:192
MOVIentry::cts
int cts
Definition: movenc.h:57
AV_DISPOSITION_MULTILAYER
#define AV_DISPOSITION_MULTILAYER
The video stream contains multiple layers, e.g.
Definition: avformat.h:717
AV_CODEC_ID_QDM2
@ AV_CODEC_ID_QDM2
Definition: codec_id.h:480
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:3432
AVProducerReferenceTime
This structure supplies correlation between a packet timestamp and a wall clock production time.
Definition: defs.h:331
av_packet_ref
int av_packet_ref(AVPacket *dst, const AVPacket *src)
Setup a new reference to the data described by a given packet.
Definition: packet.c:441
MOVTrack::nb_src_track
int nb_src_track
Definition: movenc.h:144
AVCodecParameters::ch_layout
AVChannelLayout ch_layout
The channel layout and number of channels.
Definition: codec_par.h:207
mov_get_codec_tag
static unsigned int mov_get_codec_tag(AVFormatContext *s, MOVTrack *track)
Definition: movenc.c:2107
av_packet_move_ref
void av_packet_move_ref(AVPacket *dst, AVPacket *src)
Move every field in src to dst and reset src.
Definition: packet.c:490
mov_write_minf_tag
static int mov_write_minf_tag(AVFormatContext *s, AVIOContext *pb, MOVMuxContext *mov, MOVTrack *track)
Definition: movenc.c:3803
mov_write_SA3D_tag
static int mov_write_SA3D_tag(AVFormatContext *s, AVIOContext *pb, MOVTrack *track)
Definition: movenc.c:940
AV_CODEC_ID_VP6A
@ AV_CODEC_ID_VP6A
Definition: codec_id.h:158
MOVTrack::packet_seq
int packet_seq
Definition: movenc.h:172
param_write_int
static void param_write_int(AVIOContext *pb, const char *name, int value)
Definition: movenc.c:5437
FF_MOV_FLAG_DISABLE_CHPL
#define FF_MOV_FLAG_DISABLE_CHPL
Definition: movenc.h:286
mov_write_ctts_tag
static int mov_write_ctts_tag(AVFormatContext *s, AVIOContext *pb, MOVTrack *track)
Definition: movenc.c:3184
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:4563
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:506
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:5455
MOVMuxContext::empty_hdlr_name
int empty_hdlr_name
Definition: movenc.h:268
ff_codec_movaudio_tags
const AVCodecTag ff_codec_movaudio_tags[]
Definition: isom_tags.c:311
AV_OPT_FLAG_ENCODING_PARAM
#define AV_OPT_FLAG_ENCODING_PARAM
A generic parameter which can be set by the user for muxing or encoding.
Definition: opt.h:352
index
int index
Definition: gxfenc.c:90
c
Undefined Behavior In the C some operations are like signed integer dereferencing freed accessing outside allocated Undefined Behavior must not occur in a C it is not safe even if the output of undefined operations is unused The unsafety may seem nit picking but Optimizing compilers have in fact optimized code on the assumption that no undefined Behavior occurs Optimizing code based on wrong assumptions can and has in some cases lead to effects beyond the output of computations The signed integer overflow problem in speed critical code Code which is highly optimized and works with signed integers sometimes has the problem that often the output of the computation does not c
Definition: undefined.txt:32
mov_write_subtitle_end_packet
static int mov_write_subtitle_end_packet(AVFormatContext *s, int stream_index, int64_t dts)
Definition: movenc.c:7449
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:3384
cid
uint16_t cid
Definition: mxfenc.c:2335
compute_sidx_size
static int compute_sidx_size(AVFormatContext *s)
Definition: movenc.c:8911
MOVStts
Definition: isom.h:63
AC3HeaderInfo::num_blocks
int num_blocks
number of audio blocks
Definition: ac3_parser_internal.h:51
AV_CODEC_ID_MPEG1VIDEO
@ AV_CODEC_ID_MPEG1VIDEO
Definition: codec_id.h:53
av_buffer_create
AVBufferRef * av_buffer_create(uint8_t *data, size_t size, void(*free)(void *opaque, uint8_t *data), void *opaque, int flags)
Create an AVBuffer from an existing array.
Definition: buffer.c:55
ff_ipod_muxer
const FFOutputFormat ff_ipod_muxer
find_compressor
static void find_compressor(char *compressor_name, int len, MOVTrack *track)
Definition: movenc.c:2724
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:49
av_packet_side_data_get
const AVPacketSideData * av_packet_side_data_get(const AVPacketSideData *sd, int nb_sd, enum AVPacketSideDataType type)
Get side information from a side data array.
Definition: packet.c:645
AV_CODEC_ID_EAC3
@ AV_CODEC_ID_EAC3
Definition: codec_id.h:501
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:463
ff_mov_get_channel_config_from_layout
int ff_mov_get_channel_config_from_layout(const AVChannelLayout *layout, int *config)
Get ISO/IEC 23001-8 ChannelConfiguration from AVChannelLayout.
Definition: mov_chan.c:673
AVStereo3D::primary_eye
enum AVStereo3DPrimaryEye primary_eye
Which eye is the primary eye when rendering in 2D.
Definition: stereo3d.h:222
AV_ROUND_DOWN
@ AV_ROUND_DOWN
Round toward -infinity.
Definition: mathematics.h:133
AV_UUID_LEN
#define AV_UUID_LEN
Definition: uuid.h:57
av_rescale_rnd
int64_t av_rescale_rnd(int64_t a, int64_t b, int64_t c, enum AVRounding rnd)
Rescale a 64-bit integer with specified rounding.
Definition: mathematics.c:58
AV_CODEC_ID_QCELP
@ AV_CODEC_ID_QCELP
Definition: codec_id.h:485
AV_SPHERICAL_HALF_EQUIRECTANGULAR
@ AV_SPHERICAL_HALF_EQUIRECTANGULAR
Video frame displays as a 180 degree equirectangular projection.
Definition: spherical.h:73
av_get_exact_bits_per_sample
int av_get_exact_bits_per_sample(enum AVCodecID codec_id)
Return codec bits per sample.
Definition: utils.c:454
ff_mov_generate_squashed_ttml_packet
int ff_mov_generate_squashed_ttml_packet(AVFormatContext *s, MOVTrack *track, AVPacket *pkt)
Definition: movenc_ttml.c:236
AV_CODEC_ID_FFV1
@ AV_CODEC_ID_FFV1
Definition: codec_id.h:85
AVIOContext
Bytestream IO Context.
Definition: avio.h:160
AV_CODEC_ID_PCM_S24LE
@ AV_CODEC_ID_PCM_S24LE
Definition: codec_id.h:351
AV_PIX_FMT_RGB24
@ AV_PIX_FMT_RGB24
packed RGB 8:8:8, 24bpp, RGBRGB...
Definition: pixfmt.h:75
AV_SPHERICAL_CUBEMAP
@ AV_SPHERICAL_CUBEMAP
Video frame is split into 6 faces of a cube, and arranged on a 3x2 layout.
Definition: spherical.h:61
ffio_reset_dyn_buf
void ffio_reset_dyn_buf(AVIOContext *s)
Reset a dynamic buffer.
Definition: aviobuf.c:1399
ff_mov_cenc_av1_write_obus
int ff_mov_cenc_av1_write_obus(AVFormatContext *s, MOVMuxCencContext *ctx, AVIOContext *pb, const AVPacket *pkt)
Definition: movenccenc.c:387
ac3_parser_internal.h
AVPacket::size
int size
Definition: packet.h:596
NULL_IF_CONFIG_SMALL
#define NULL_IF_CONFIG_SMALL(x)
Return NULL if CONFIG_SMALL is true, otherwise the argument without modification.
Definition: internal.h:94
avpriv_pix_fmt_find
enum AVPixelFormat avpriv_pix_fmt_find(enum PixelFormatTagLists list, unsigned fourcc)
Definition: raw.c:78
AV_STREAM_GROUP_PARAMS_TREF
@ AV_STREAM_GROUP_PARAMS_TREF
Definition: avformat.h:1111
codec_ipod_tags
static const AVCodecTag codec_ipod_tags[]
Definition: movenc.c:9251
copy
static void copy(const float *p1, float *p2, const int length)
Definition: vf_vaguedenoiser.c:186
FF_OFMT_FLAG_ALLOW_FLUSH
#define FF_OFMT_FLAG_ALLOW_FLUSH
This flag indicates that the muxer stores data internally and supports flushing it.
Definition: mux.h:38
ff_isom_write_avcc
int ff_isom_write_avcc(AVIOContext *pb, const uint8_t *data, int len)
Definition: avc.c:31
height
#define height
Definition: dsp.h:89
AC3HeaderInfo::channel_map_present
uint8_t channel_map_present
Definition: ac3_parser_internal.h:49
MOVTrack::cover_image
AVPacket * cover_image
Definition: movenc.h:156
AVChannelLayout
An AVChannelLayout holds information about the channel layout of audio data.
Definition: channel_layout.h:319
MOVFragmentInfo::time
int64_t time
Definition: movenc.h:81
AVSphericalMapping::bound_right
uint32_t bound_right
Distance from the right edge.
Definition: spherical.h:187
mov_write_dpxe_tag
static int mov_write_dpxe_tag(AVIOContext *pb, MOVTrack *track)
Definition: movenc.c:1855
mov_write_vvcc_tag
static int mov_write_vvcc_tag(AVIOContext *pb, MOVTrack *track)
Definition: movenc.c:1701
FF_MOV_FLAG_FASTSTART
#define FF_MOV_FLAG_FASTSTART
Definition: movenc.h:284
mpeg4_bit_rate_values::avg_bit_rate
uint32_t avg_bit_rate
Average rate in bits/second over the entire presentation.
Definition: movenc.c:717
MOVTrack::language
int language
Definition: movenc.h:121
i
#define i(width, name, range_min, range_max)
Definition: cbs_h264.c:63
av_err2str
#define av_err2str(errnum)
Convenience macro, the return value should be used only directly in function arguments but never stan...
Definition: error.h:122
MOVMuxContext::first_trun
int first_trun
Definition: movenc.h:236
MOVMuxContext::ism_lookahead
int ism_lookahead
Definition: movenc.h:234
ff_vvc_annexb2mp4_buf
int ff_vvc_annexb2mp4_buf(const uint8_t *buf_in, uint8_t **buf_out, int *size, int filter_ps, int *ps_count)
Writes Annex B formatted H.266/VVC NAL units to a data buffer.
Definition: vvc.c:858
mov_write_eac3_tag
static int mov_write_eac3_tag(AVFormatContext *s, AVIOContext *pb, MOVTrack *track)
Definition: movenc.c:612
update_size_and_version
static int64_t update_size_and_version(AVIOContext *pb, int64_t pos, int version)
Definition: movenc.c:165
uuid.h
mov_write_hfov_tag
static void mov_write_hfov_tag(AVFormatContext *s, AVIOContext *pb, const AVStereo3D *stereo3d)
Definition: movenc.c:2379
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:465
bps
unsigned bps
Definition: movenc.c:2050
MOVTrack::default_sample_flags
uint32_t default_sample_flags
Definition: movenc.h:152
ff_nal_parse_units_buf
int ff_nal_parse_units_buf(const uint8_t *buf_in, uint8_t **buf, int *size)
Definition: nal.c:133
mov_write_vexu_tag
static int mov_write_vexu_tag(AVFormatContext *s, AVIOContext *pb, const AVStereo3D *stereo3d, const AVSphericalMapping *spherical_mapping)
Definition: movenc.c:2475
ff_mov_cenc_write_packet
int ff_mov_cenc_write_packet(MOVMuxCencContext *ctx, AVIOContext *pb, const uint8_t *buf_in, int size)
Write a fully encrypted packet.
Definition: movenccenc.c:173
AC3HeaderInfo::lfe_on
uint8_t lfe_on
Definition: ac3_parser_internal.h:44
mpeg4_bit_rate_values
Definition: movenc.c:714
AV_CODEC_ID_H263
@ AV_CODEC_ID_H263
Definition: codec_id.h:56
MOV_TFHD_STSD_ID
#define MOV_TFHD_STSD_ID
Definition: isom.h:409
ff_iamf_uninit_context
void ff_iamf_uninit_context(IAMFContext *c)
Definition: iamf.c:172
size
int size
Definition: twinvq_data.h:10344
MOVMuxContext::avif_extent_pos
int64_t avif_extent_pos[2]
Definition: movenc.h:271
mov_write_mdta_keys_tag
static int mov_write_mdta_keys_tag(AVIOContext *pb, MOVMuxContext *mov, AVFormatContext *s)
Definition: movenc.c:4880
AV_CODEC_ID_V408
@ AV_CODEC_ID_V408
Definition: codec_id.h:261
avio.h
mov_write_uuid_tag_psp
static int mov_write_uuid_tag_psp(AVIOContext *pb, MOVTrack *mov)
Definition: movenc.c:4240
video_st
static AVStream * video_st
Definition: movenc.c:61
AV_NOPTS_VALUE
#define AV_NOPTS_VALUE
Undefined timestamp value.
Definition: avutil.h:247
NTP_OFFSET_US
#define NTP_OFFSET_US
Definition: internal.h:419
codec_mp4_tags
static const AVCodecTag codec_mp4_tags[]
Definition: movenc.c:9180
ff_iamf_write_parameter_blocks
int ff_iamf_write_parameter_blocks(const IAMFContext *iamf, AVIOContext *pb, const AVPacket *pkt, void *log_ctx)
Definition: iamf_writer.c:1172
AV_RB32
uint64_t_TMPL AV_WL64 unsigned int_TMPL AV_WL32 unsigned int_TMPL AV_WL24 unsigned int_TMPL AV_WL16 uint64_t_TMPL AV_WB64 unsigned int_TMPL AV_RB32
Definition: bytestream.h:96
AV_CODEC_ID_V210
@ AV_CODEC_ID_V210
Definition: codec_id.h:179
mov_write_lhvc_tag
static int mov_write_lhvc_tag(AVFormatContext *s, AVIOContext *pb, MOVTrack *track)
Definition: movenc.c:1649
get_metadata_lang
static AVDictionaryEntry * get_metadata_lang(AVFormatContext *s, const char *tag, int *lang)
Definition: movenc.c:4627
FF_MOV_FLAG_ISML
#define FF_MOV_FLAG_ISML
Definition: movenc.h:283
FF_PUT_WAV_HEADER_FORCE_WAVEFORMATEX
#define FF_PUT_WAV_HEADER_FORCE_WAVEFORMATEX
Tell ff_put_wav_header() to use WAVEFORMATEX even for PCM codecs.
Definition: riff.h:53
AVCodecParameters::profile
int profile
Codec-specific bitstream restrictions that the stream conforms to.
Definition: codec_par.h:135
write_matrix
static void write_matrix(AVIOContext *pb, int16_t a, int16_t b, int16_t c, int16_t d, int16_t tx, int16_t ty)
Definition: movenc.c:3958
mov_create_dvd_sub_decoder_specific_info
static int mov_create_dvd_sub_decoder_specific_info(MOVTrack *track, AVStream *st)
Definition: movenc.c:7970
AV_CODEC_ID_OPUS
@ AV_CODEC_ID_OPUS
Definition: codec_id.h:521
MOVMuxContext::reserved_header_pos
int64_t reserved_header_pos
Definition: movenc.h:241
MOVTrack::audio_vbr
int audio_vbr
Definition: movenc.h:132
mov_write_gmhd_tag
static int mov_write_gmhd_tag(AVIOContext *pb, MOVTrack *track)
Definition: movenc.c:3470
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:3149
AVMEDIA_TYPE_UNKNOWN
@ AVMEDIA_TYPE_UNKNOWN
Usually treated as AVMEDIA_TYPE_DATA.
Definition: avutil.h:199
AVStream::sample_aspect_ratio
AVRational sample_aspect_ratio
sample aspect ratio (0 if unknown)
Definition: avformat.h:825
mov_write_tmcd_tag
static int mov_write_tmcd_tag(AVIOContext *pb, MOVTrack *track)
Definition: movenc.c:3088
mov_write_dmlp_tag
static int mov_write_dmlp_tag(AVFormatContext *s, AVIOContext *pb, MOVTrack *track)
Definition: movenc.c:911
AVIO_DATA_MARKER_SYNC_POINT
@ AVIO_DATA_MARKER_SYNC_POINT
A point in the output bytestream where a decoder can start decoding (i.e.
Definition: avio.h:121
MOVTrack::end_reliable
int end_reliable
Definition: movenc.h:140
ff_mov_iso639_to_lang
int ff_mov_iso639_to_lang(const char lang[4], int mp4)
Definition: isom.c:233
calc_pts_duration
static int64_t calc_pts_duration(MOVMuxContext *mov, MOVTrack *track)
Definition: movenc.c:3877
dovi_isom.h
AV_DISPOSITION_HEARING_IMPAIRED
#define AV_DISPOSITION_HEARING_IMPAIRED
The stream is intended for hearing impaired audiences.
Definition: avformat.h:657
ff_isom_write_av1c
int ff_isom_write_av1c(AVIOContext *pb, const uint8_t *buf, int size, int write_seq_header)
Writes AV1 extradata (Sequence Header and Metadata OBUs) to the provided AVIOContext.
Definition: av1.c:399
AVPacket::dts
int64_t dts
Decompression timestamp in AVStream->time_base units; the time at which the packet is decompressed.
Definition: packet.h:594
avio_write
void avio_write(AVIOContext *s, const unsigned char *buf, int size)
Definition: aviobuf.c:206
avio_wb32
void avio_wb32(AVIOContext *s, unsigned int val)
Definition: aviobuf.c:368
FF_COMPLIANCE_NORMAL
#define FF_COMPLIANCE_NORMAL
Definition: defs.h:60
AVSphericalMapping::padding
uint32_t padding
Number of pixels to pad from the edge of each cube face.
Definition: spherical.h:200
a
The reader does not expect b to be semantically here and if the code is changed by maybe adding a a division or other the signedness will almost certainly be mistaken To avoid this confusion a new type was SUINT is the C unsigned type but it holds a signed int to use the same example SUINT a
Definition: undefined.txt:41
MOVTrack::slices
int slices
Definition: movenc.h:174
av_reallocp_array
int av_reallocp_array(void *ptr, size_t nmemb, size_t size)
Allocate, reallocate an array through a pointer to a pointer.
Definition: mem.c:225
mov_get_evc_codec_tag
static int mov_get_evc_codec_tag(AVFormatContext *s, MOVTrack *track)
Definition: movenc.c:2026
AV_PRIMARY_EYE_NONE
@ AV_PRIMARY_EYE_NONE
Neither eye.
Definition: stereo3d.h:178
MOV_MP4_FPCM_TAG
#define MOV_MP4_FPCM_TAG
Definition: isom.h:484
avio_wl32
void avio_wl32(AVIOContext *s, unsigned int val)
Definition: aviobuf.c:360
csp.h
AV_CODEC_ID_VVC
@ AV_CODEC_ID_VVC
Definition: codec_id.h:252
MOVTrack::first_packet_seen
int first_packet_seen
Definition: movenc.h:170
mov_write_subtitle_tag
static int mov_write_subtitle_tag(AVFormatContext *s, AVIOContext *pb, MOVTrack *track)
Definition: movenc.c:2241
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:4294
offset
it s the only field you need to keep assuming you have a context There is some magic you don t need to care about around this just let it vf offset
Definition: writing_filters.txt:86
AVStreamGroupLCEVC::lcevc_index
unsigned int lcevc_index
Index of the LCEVC data stream in AVStreamGroup.
Definition: avformat.h:1078
AVStreamGroup::lcevc
struct AVStreamGroupLCEVC * lcevc
Definition: avformat.h:1153
AV_CODEC_ID_LCEVC
@ AV_CODEC_ID_LCEVC
Definition: codec_id.h:616
AC3HeaderInfo::bitstream_mode
uint8_t bitstream_mode
Definition: ac3_parser_internal.h:42
AVPacket::flags
int flags
A combination of AV_PKT_FLAG values.
Definition: packet.h:601
av_packet_alloc
AVPacket * av_packet_alloc(void)
Allocate an AVPacket and set its fields to default values.
Definition: packet.c:63
xf
#define xf(width, name, var, range_min, range_max, subs,...)
Definition: cbs_av1.c:622
FF_COMPLIANCE_UNOFFICIAL
#define FF_COMPLIANCE_UNOFFICIAL
Allow unofficial extensions.
Definition: defs.h:61
MOVTrack::start_cts
int64_t start_cts
Definition: movenc.h:137
AVCodecParameters::avcodec_parameters_alloc
AVCodecParameters * avcodec_parameters_alloc(void)
Allocate a new AVCodecParameters and set its fields to default values (unknown/invalid/0).
Definition: codec_par.c:57
version
version
Definition: libkvazaar.c:313
AV_STREAM_GROUP_PARAMS_IAMF_AUDIO_ELEMENT
@ AV_STREAM_GROUP_PARAMS_IAMF_AUDIO_ELEMENT
Definition: avformat.h:1107
mov_write_avid_tag
static int mov_write_avid_tag(AVIOContext *pb, MOVTrack *track)
Definition: movenc.c:1737
mov_write_mdta_ilst_tag
static int mov_write_mdta_ilst_tag(AVIOContext *pb, MOVMuxContext *mov, AVFormatContext *s)
Definition: movenc.c:4909
AV_STEREO3D_FLAG_INVERT
#define AV_STEREO3D_FLAG_INVERT
Inverted views, Right/Bottom represents the left view.
Definition: stereo3d.h:194
MOVIentry::chunkNum
unsigned int chunkNum
Chunk number if the current entry is a chunk start otherwise 0.
Definition: movenc.h:55
AVStreamGroup::streams
AVStream ** streams
A list of streams in the group.
Definition: avformat.h:1185
vc1_common.h
mov_write_meta_tag
static int mov_write_meta_tag(AVIOContext *pb, MOVMuxContext *mov, AVFormatContext *s)
Definition: movenc.c:4931
FF_MOV_FLAG_OMIT_TFHD_OFFSET
#define FF_MOV_FLAG_OMIT_TFHD_OFFSET
Definition: movenc.h:285
MOV_MP4_IPCM_TAG
#define MOV_MP4_IPCM_TAG
Definition: isom.h:485
MOV_DISPOSABLE_SAMPLE
#define MOV_DISPOSABLE_SAMPLE
Definition: movenc.h:60
shift_data
static int shift_data(AVFormatContext *s)
Definition: movenc.c:8926
mov_write_dvc1_structs
static int mov_write_dvc1_structs(MOVTrack *track, uint8_t *buf)
Definition: movenc.c:1097
av_channel_layout_compare
int av_channel_layout_compare(const AVChannelLayout *chl, const AVChannelLayout *chl1)
Check whether two channel layouts are semantically the same, i.e.
Definition: channel_layout.c:811
mov_write_iinf_tag
static int mov_write_iinf_tag(AVIOContext *pb, MOVMuxContext *mov, AVFormatContext *s)
Definition: movenc.c:3665
AC3HeaderInfo::ac3_bit_rate_code
int8_t ac3_bit_rate_code
Definition: ac3_parser_internal.h:64
AV_CODEC_ID_TSCC2
@ AV_CODEC_ID_TSCC2
Definition: codec_id.h:218
AV_LOG_INFO
#define AV_LOG_INFO
Standard information.
Definition: log.h:221
mov_free
static void mov_free(AVFormatContext *s)
Definition: movenc.c:7895
MODE_3GP
#define MODE_3GP
Definition: movenc.h:39
MOVTrack::time
uint64_t time
Definition: movenc.h:98
FF_MOV_FLAG_SKIP_SIDX
#define FF_MOV_FLAG_SKIP_SIDX
Definition: movenc.h:298
AV_PIX_FMT_ARGB
@ AV_PIX_FMT_ARGB
packed ARGB 8:8:8:8, 32bpp, ARGBARGB...
Definition: pixfmt.h:99
AV_OPT_TYPE_FLOAT
@ AV_OPT_TYPE_FLOAT
Underlying C type is float.
Definition: opt.h:271
apv.h
ff_mov_add_hinted_packet
int ff_mov_add_hinted_packet(AVFormatContext *s, AVPacket *pkt, int track_index, int sample, uint8_t *sample_data, int sample_size)
Definition: movenchint.c:405
AV_SPHERICAL_RECTILINEAR
@ AV_SPHERICAL_RECTILINEAR
Video frame displays on a flat, rectangular 2D surface.
Definition: spherical.h:78
layout
Filter the word “frame” indicates either a video frame or a group of audio as stored in an AVFrame structure Format for each input and each output the list of supported formats For video that means pixel format For audio that means channel layout
Definition: filter_design.txt:18
mov_write_covr
static int mov_write_covr(AVIOContext *pb, AVFormatContext *s)
Definition: movenc.c:4797
avcodec_get_name
const char * avcodec_get_name(enum AVCodecID id)
Get the name of a codec.
Definition: utils.c:406
AV_CODEC_ID_MJPEG
@ AV_CODEC_ID_MJPEG
Definition: codec_id.h:59
MOVTrack::hint_track
int hint_track
the track that hints this track, -1 if no hint track is set
Definition: movenc.h:143
MOVTrack::has_keyframes
int has_keyframes
Definition: movenc.h:111
AV_PIX_FMT_UYVA
@ AV_PIX_FMT_UYVA
packed UYVA 4:4:4:4, 32bpp (1 Cr & Cb sample per 1x1 Y & A samples), UYVAUYVA...
Definition: pixfmt.h:444
av_double2int
static av_always_inline uint64_t av_double2int(double f)
Reinterpret a double as a 64-bit integer.
Definition: intfloat.h:70
mov_write_iprp_tag
static int mov_write_iprp_tag(AVIOContext *pb, MOVMuxContext *mov, AVFormatContext *s)
Definition: movenc.c:3778
interlaced
uint8_t interlaced
Definition: mxfenc.c:2336
MOVTrack::entry
int entry
Definition: movenc.h:96
av_assert2
#define av_assert2(cond)
assert() equivalent, that does lie in speed critical code.
Definition: avassert.h:68
mov_write_uuidprof_tag
static int mov_write_uuidprof_tag(AVIOContext *pb, AVFormatContext *s)
Definition: movenc.c:6336
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:3423
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:1613
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:279
AV_CODEC_ID_NONE
@ AV_CODEC_ID_NONE
Definition: codec_id.h:50
AVPacket::pts
int64_t pts
Presentation timestamp in AVStream->time_base units; the time at which the decompressed packet will b...
Definition: packet.h:588
avio_internal.h
ff_mov_write_packet
int ff_mov_write_packet(AVFormatContext *s, AVPacket *pkt)
Definition: movenc.c:6914
MOVCtts::offset
int offset
Definition: isom.h:70
round
static av_always_inline av_const double round(double x)
Definition: libm.h:446
MOVMuxContext::nb_streams
int nb_streams
Definition: movenc.h:214
av_packet_get_side_data
uint8_t * av_packet_get_side_data(const AVPacket *pkt, enum AVPacketSideDataType type, size_t *size)
Get side information from packet.
Definition: packet.c:252
AV_SPHERICAL_FISHEYE
@ AV_SPHERICAL_FISHEYE
Fisheye projection (Apple).
Definition: spherical.h:84
AV_CODEC_ID_EVRC
@ AV_CODEC_ID_EVRC
Definition: codec_id.h:532
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:1579
AV_TIME_BASE
#define AV_TIME_BASE
Internal time base represented as integer.
Definition: avutil.h:253
MOVMuxContext::fragments
int fragments
Definition: movenc.h:230
AVCodecParameters::block_align
int block_align
The number of bytes per coded audio frame, required by some formats.
Definition: codec_par.h:221
AV_CODEC_ID_TTML
@ AV_CODEC_ID_TTML
Definition: codec_id.h:597
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:1902
MOV_PRFT_SRC_WALLCLOCK
@ MOV_PRFT_SRC_WALLCLOCK
Definition: movenc.h:205
AV_PKT_DATA_ICC_PROFILE
@ AV_PKT_DATA_ICC_PROFILE
ICC profile data consisting of an opaque octet buffer following the format described by ISO 15076-1.
Definition: packet.h:271
AV_STEREO3D_TOPBOTTOM
@ AV_STEREO3D_TOPBOTTOM
Views are on top of each other.
Definition: stereo3d.h:76
ff_mov_cenc_flush
void ff_mov_cenc_flush(MOVMuxCencContext *ctx)
Clear subsample data.
Definition: movenccenc.c:633
MOVTrack::extradata_size
int * extradata_size
Definition: movenc.h:106
mov_write_string_tag
static int mov_write_string_tag(AVIOContext *pb, const char *name, const char *value, int lang, int long_style)
Definition: movenc.c:4584
MOVTrack::first_packet_seq
int first_packet_seq
Definition: movenc.h:168
ff_get_packet_palette
int ff_get_packet_palette(AVFormatContext *s, AVPacket *pkt, int ret, uint32_t *palette)
Retrieves the palette from a packet, either from side data, or appended to the video data in the pack...
Definition: rawutils.c:71
eac3_info::data_rate
uint16_t data_rate
Definition: movenc.c:390
avpriv_ac3_parse_header
int avpriv_ac3_parse_header(AC3HeaderInfo **phdr, const uint8_t *buf, size_t size)
Definition: ac3_parser.c:491
AV_CODEC_ID_PCM_F64BE
@ AV_CODEC_ID_PCM_F64BE
Definition: codec_id.h:361
mov_write_mdat_size
static void mov_write_mdat_size(AVFormatContext *s)
Definition: movenc.c:8941
AV_CODEC_ID_HEVC
@ AV_CODEC_ID_HEVC
Definition: codec_id.h:228
value
it s the only field you need to keep assuming you have a context There is some magic you don t need to care about around this just let it vf default value
Definition: writing_filters.txt:86
MOVMuxContext::video_track_timescale
int video_track_timescale
Definition: movenc.h:238
mov_write_stss_tag
static int mov_write_stss_tag(AVIOContext *pb, MOVTrack *track, uint32_t flag)
Definition: movenc.c:292
MOV_TIMECODE_FLAG_DROPFRAME
#define MOV_TIMECODE_FLAG_DROPFRAME
Definition: movenc.h:117
FFMIN
#define FFMIN(a, b)
Definition: macros.h:49
mov_parse_truehd_frame
static void mov_parse_truehd_frame(AVPacket *pkt, MOVTrack *trk)
Definition: movenc.c:6517
AV_CODEC_ID_DVVIDEO
@ AV_CODEC_ID_DVVIDEO
Definition: codec_id.h:76
AV_CODEC_ID_PCM_S32BE
@ AV_CODEC_ID_PCM_S32BE
Definition: codec_id.h:348
AC3HeaderInfo::channel_map
uint16_t channel_map
Definition: ac3_parser_internal.h:50
MOVMuxContext::max_fragment_duration
int max_fragment_duration
Definition: movenc.h:231
ff_mov_cenc_init
int ff_mov_cenc_init(MOVMuxCencContext *ctx, uint8_t *encryption_key, int use_subsamples, enum AVCodecID codec_id, int bitexact)
Initialize a CENC context.
Definition: movenccenc.c:600
MOVTrack::rtp_ctx
AVFormatContext * rtp_ctx
the format context for the hinting rtp muxer
Definition: movenc.h:146
av_inv_q
static av_always_inline AVRational av_inv_q(AVRational q)
Invert a rational.
Definition: rational.h:159
AV_CODEC_ID_VC1
@ AV_CODEC_ID_VC1
Definition: codec_id.h:122
mov_find_tref_tag
static MovTag * mov_find_tref_tag(MOVMuxContext *mov, const MOVTrack *trk, uint32_t name)
Definition: movenc.c:5293
AVCodecParameters::color_range
enum AVColorRange color_range
Additional colorspace characteristics.
Definition: codec_par.h:189
AVMasteringDisplayMetadata
Mastering display metadata capable of representing the color volume of the display used to master the...
Definition: mastering_display_metadata.h:38
len
int len
Definition: vorbis_enc_data.h:426
AV_CODEC_ID_JPEG2000
@ AV_CODEC_ID_JPEG2000
Definition: codec_id.h:140
MOV_TFHD_DEFAULT_SIZE
#define MOV_TFHD_DEFAULT_SIZE
Definition: isom.h:411
mov_write_tapt_tag
static int mov_write_tapt_tag(AVIOContext *pb, MOVTrack *track)
Definition: movenc.c:4080
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:9088
MOV_SAMPLE_DEPENDENCY_YES
#define MOV_SAMPLE_DEPENDENCY_YES
Definition: isom.h:439
av_rescale
int64_t av_rescale(int64_t a, int64_t b, int64_t c)
Rescale a 64-bit integer with rounding to nearest.
Definition: mathematics.c:129
AVCodecParameters::coded_side_data
AVPacketSideData * coded_side_data
Additional data associated with the entire stream.
Definition: codec_par.h:83
nal.h
AVCOL_RANGE_MPEG
@ AVCOL_RANGE_MPEG
Narrow or limited range content.
Definition: pixfmt.h:760
av_calloc
void * av_calloc(size_t nmemb, size_t size)
Definition: mem.c:264
MOVTrack::iamf
struct IAMFContext * iamf
Definition: movenc.h:190
AVCodecParameters::field_order
enum AVFieldOrder field_order
The order of the fields in interlaced video.
Definition: codec_par.h:182
update_size
static int64_t update_size(AVIOContext *pb, int64_t pos)
Definition: movenc.c:155
MP4TrackKindValueMapping
Definition: isom.h:487
ff_tgp_muxer
const FFOutputFormat ff_tgp_muxer
AVFMT_TS_NEGATIVE
#define AVFMT_TS_NEGATIVE
Format allows muxing negative timestamps.
Definition: avformat.h: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:5594
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:3225
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:6066
AV_PROFILE_DNXHD
#define AV_PROFILE_DNXHD
Definition: defs.h:80
tag
uint32_t tag
Definition: movenc.c:2049
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:1452
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:332
mov_get_h264_codec_tag
static int mov_get_h264_codec_tag(AVFormatContext *s, MOVTrack *track)
Definition: movenc.c:1964
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:4770
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:3721
ff_dnxhd_parse_header_prefix
static av_always_inline uint64_t ff_dnxhd_parse_header_prefix(const uint8_t *buf)
Definition: dnxhddata.h:85
ff_mov_cenc_write_sinf_tag
int ff_mov_cenc_write_sinf_tag(MOVTrack *track, AVIOContext *pb, uint8_t *kid)
Write the sinf atom, contained inside stsd.
Definition: movenccenc.c:568
av_strlcat
size_t av_strlcat(char *dst, const char *src, size_t size)
Append the string src to the string dst, but to a total length of no more than size - 1 bytes,...
Definition: avstring.c:95
MOVMuxContext::track_ids_ok
int track_ids_ok
Definition: movenc.h:264
AVSphericalMapping::pitch
int32_t pitch
Rotation around the right vector [-90, 90].
Definition: spherical.h:145
mov_write_hvcc_tag
static int mov_write_hvcc_tag(AVFormatContext *s, AVIOContext *pb, MOVTrack *track)
Definition: movenc.c:1634
ff_av1_filter_obus
int ff_av1_filter_obus(AVIOContext *pb, const uint8_t *buf, int size)
Filter out AV1 OBUs not meant to be present in ISOBMFF sample data and write the resulting bitstream ...
Definition: av1.c:83
rawutils.h
ff_isom_close_apvc
void ff_isom_close_apvc(APVDecoderConfigurationRecord **papvc)
Definition: apv.c:375
MOVTrack::entries_flushed
int entries_flushed
Definition: movenc.h:161
MOV_TKHD_FLAG_IN_MOVIE
#define MOV_TKHD_FLAG_IN_MOVIE
Definition: isom.h:434
AVStereo3D::type
enum AVStereo3DType type
How views are packed within the video.
Definition: stereo3d.h:207
FF_MOV_FLAG_DASH
#define FF_MOV_FLAG_DASH
Definition: movenc.h:288
mov_write_tref_tag
static int mov_write_tref_tag(AVIOContext *pb, MOVTrack *track)
Definition: movenc.c:4223
mov_write_uuid_tag_ipod
static int mov_write_uuid_tag_ipod(AVIOContext *pb)
Write uuid atom.
Definition: movenc.c:2212
pos
unsigned int pos
Definition: spdifenc.c:414
MOVMuxCencContext::aes_ctr
struct AVAESCTR * aes_ctr
Definition: movenccenc.h:41
avformat.h
dovi_meta.h
dict.h
AVPacket::side_data
AVPacketSideData * side_data
Additional packet data that can be provided by the container.
Definition: packet.h:606
MOVMuxContext::is_animated_avif
int is_animated_avif
Definition: movenc.h:273
flag
#define flag(name)
Definition: cbs_av1.c:496
AV_INPUT_BUFFER_PADDING_SIZE
#define AV_INPUT_BUFFER_PADDING_SIZE
Definition: defs.h:40
id
enum AVCodecID id
Definition: dts2pts.c:550
left
Tag MUST be and< 10hcoeff half pel interpolation filter coefficients, hcoeff[0] are the 2 middle coefficients[1] are the next outer ones and so on, resulting in a filter like:...eff[2], hcoeff[1], hcoeff[0], hcoeff[0], hcoeff[1], hcoeff[2] ... the sign of the coefficients is not explicitly stored but alternates after each coeff and coeff[0] is positive, so ...,+,-,+,-,+,+,-,+,-,+,... hcoeff[0] is not explicitly stored but found by subtracting the sum of all stored coefficients with signs from 32 hcoeff[0]=32 - hcoeff[1] - hcoeff[2] - ... a good choice for hcoeff and htaps is htaps=6 hcoeff={40,-10, 2} an alternative which requires more computations at both encoder and decoder side and may or may not be better is htaps=8 hcoeff={42,-14, 6,-2}ref_frames minimum of the number of available reference frames and max_ref_frames for example the first frame after a key frame always has ref_frames=1spatial_decomposition_type wavelet type 0 is a 9/7 symmetric compact integer wavelet 1 is a 5/3 symmetric compact integer wavelet others are reserved stored as delta from last, last is reset to 0 if always_reset||keyframeqlog quality(logarithmic quantizer scale) stored as delta from last, last is reset to 0 if always_reset||keyframemv_scale stored as delta from last, last is reset to 0 if always_reset||keyframe FIXME check that everything works fine if this changes between framesqbias dequantization bias stored as delta from last, last is reset to 0 if always_reset||keyframeblock_max_depth maximum depth of the block tree stored as delta from last, last is reset to 0 if always_reset||keyframequant_table quantization tableHighlevel bitstream structure:==============================--------------------------------------------|Header|--------------------------------------------|------------------------------------|||Block0||||split?||||yes no||||......... intra?||||:Block01 :yes no||||:Block02 :....... ..........||||:Block03 ::y DC ::ref index:||||:Block04 ::cb DC ::motion x :||||......... :cr DC ::motion y :||||....... ..........|||------------------------------------||------------------------------------|||Block1|||...|--------------------------------------------|------------ ------------ ------------|||Y subbands||Cb subbands||Cr subbands||||--- ---||--- ---||--- ---|||||LL0||HL0||||LL0||HL0||||LL0||HL0|||||--- ---||--- ---||--- ---||||--- ---||--- ---||--- ---|||||LH0||HH0||||LH0||HH0||||LH0||HH0|||||--- ---||--- ---||--- ---||||--- ---||--- ---||--- ---|||||HL1||LH1||||HL1||LH1||||HL1||LH1|||||--- ---||--- ---||--- ---||||--- ---||--- ---||--- ---|||||HH1||HL2||||HH1||HL2||||HH1||HL2|||||...||...||...|||------------ ------------ ------------|--------------------------------------------Decoding process:=================------------|||Subbands|------------||||------------|Intra DC||||LL0 subband prediction ------------|\ Dequantization ------------------- \||Reference frames|\ IDWT|------- -------|Motion \|||Frame 0||Frame 1||Compensation . OBMC v -------|------- -------|--------------. \------> Frame n output Frame Frame<----------------------------------/|...|------------------- Range Coder:============Binary Range Coder:------------------- The implemented range coder is an adapted version based upon "Range encoding: an algorithm for removing redundancy from a digitised message." by G. N. N. Martin. The symbols encoded by the Snow range coder are bits(0|1). The associated probabilities are not fix but change depending on the symbol mix seen so far. bit seen|new state ---------+----------------------------------------------- 0|256 - state_transition_table[256 - old_state];1|state_transition_table[old_state];state_transition_table={ 0, 0, 0, 0, 0, 0, 0, 0, 20, 21, 22, 23, 24, 25, 26, 27, 28, 29, 30, 31, 32, 33, 34, 35, 36, 37, 37, 38, 39, 40, 41, 42, 43, 44, 45, 46, 47, 48, 49, 50, 51, 52, 53, 54, 55, 56, 56, 57, 58, 59, 60, 61, 62, 63, 64, 65, 66, 67, 68, 69, 70, 71, 72, 73, 74, 75, 75, 76, 77, 78, 79, 80, 81, 82, 83, 84, 85, 86, 87, 88, 89, 90, 91, 92, 93, 94, 94, 95, 96, 97, 98, 99, 100, 101, 102, 103, 104, 105, 106, 107, 108, 109, 110, 111, 112, 113, 114, 114, 115, 116, 117, 118, 119, 120, 121, 122, 123, 124, 125, 126, 127, 128, 129, 130, 131, 132, 133, 133, 134, 135, 136, 137, 138, 139, 140, 141, 142, 143, 144, 145, 146, 147, 148, 149, 150, 151, 152, 152, 153, 154, 155, 156, 157, 158, 159, 160, 161, 162, 163, 164, 165, 166, 167, 168, 169, 170, 171, 171, 172, 173, 174, 175, 176, 177, 178, 179, 180, 181, 182, 183, 184, 185, 186, 187, 188, 189, 190, 190, 191, 192, 194, 194, 195, 196, 197, 198, 199, 200, 201, 202, 202, 204, 205, 206, 207, 208, 209, 209, 210, 211, 212, 213, 215, 215, 216, 217, 218, 219, 220, 220, 222, 223, 224, 225, 226, 227, 227, 229, 229, 230, 231, 232, 234, 234, 235, 236, 237, 238, 239, 240, 241, 242, 243, 244, 245, 246, 247, 248, 248, 0, 0, 0, 0, 0, 0, 0};FIXME Range Coding of integers:------------------------- FIXME Neighboring Blocks:===================left and top are set to the respective blocks unless they are outside of the image in which case they are set to the Null block top-left is set to the top left block unless it is outside of the image in which case it is set to the left block if this block has no larger parent block or it is at the left side of its parent block and the top right block is not outside of the image then the top right block is used for top-right else the top-left block is used Null block y, cb, cr are 128 level, ref, mx and my are 0 Motion Vector Prediction:=========================1. the motion vectors of all the neighboring blocks are scaled to compensate for the difference of reference frames scaled_mv=(mv *(256 *(current_reference+1)/(mv.reference+1))+128)> the median of the scaled left
Definition: snow.txt:386
AV_PIX_FMT_UYVY422
@ AV_PIX_FMT_UYVY422
packed YUV 4:2:2, 16bpp, Cb Y0 Cr Y1
Definition: pixfmt.h:88
AV_RL32
uint64_t_TMPL AV_WL64 unsigned int_TMPL AV_RL32
Definition: bytestream.h:92
MODE_3G2
#define MODE_3G2
Definition: movenc.h:42
AVCodecParameters::avcodec_parameters_free
void avcodec_parameters_free(AVCodecParameters **par)
Free an AVCodecParameters instance and everything associated with it and write NULL to the supplied p...
Definition: codec_par.c:67
mov_flush_fragment
static int mov_flush_fragment(AVFormatContext *s, int force)
Definition: movenc.c:6655
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:3440
MOVTrack::par
AVCodecParameters * par
Definition: movenc.h:125
ff_isom_parse_apvc
int ff_isom_parse_apvc(APVDecoderConfigurationRecord *apvc, const AVPacket *pkt, void *logctx)
Definition: apv.c:252
AVStreamGroup
Definition: avformat.h:1117
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:281
AVStreamGroup::nb_streams
unsigned int nb_streams
Number of elements in AVStreamGroup.streams.
Definition: avformat.h:1172
channel_layout.h
ff_avc_write_annexb_extradata
int ff_avc_write_annexb_extradata(const uint8_t *in, uint8_t **buf, int *size)
Definition: avc.c:144
MOVMuxContext::flags
int flags
Definition: movenc.h:222
AV_PROFILE_AAC_HE_V2
#define AV_PROFILE_AAC_HE_V2
Definition: defs.h:73
AV_CODEC_ID_V410
@ AV_CODEC_ID_V410
Definition: codec_id.h:210
MOVTrack::last_stsd_index
int last_stsd_index
Definition: movenc.h:104
av_channel_layout_subset
uint64_t av_channel_layout_subset(const AVChannelLayout *channel_layout, uint64_t mask)
Find out what channels from a given set are present in a channel layout, without regard for their pos...
Definition: channel_layout.c:867
MOVMuxContext::reserved_moov_size
int reserved_moov_size
0 for disabled, -1 for automatic, size otherwise
Definition: movenc.h:240
ISOM_DVCC_DVVC_SIZE
#define ISOM_DVCC_DVVC_SIZE
Definition: dovi_isom.h:29
AVIO_SEEKABLE_NORMAL
#define AVIO_SEEKABLE_NORMAL
Seeking works like for a local file.
Definition: avio.h:41
is_cover_image
static int is_cover_image(const AVStream *st)
Definition: movenc.c:184
AVRational::den
int den
Denominator.
Definition: rational.h:60
rgb_to_yuv
static uint32_t rgb_to_yuv(uint32_t rgb)
Definition: movenc.c:7954
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:7697
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:4663
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:6173
mov_write_prft_tag
static int mov_write_prft_tag(AVIOContext *pb, MOVMuxContext *mov, int tracks)
Definition: movenc.c:6016
mov_write_fiel_tag
static int mov_write_fiel_tag(AVIOContext *pb, MOVTrack *track, int field_order)
Definition: movenc.c:2228
AV_OPT_TYPE_INT
@ AV_OPT_TYPE_INT
Underlying C type is int.
Definition: opt.h:259
av_channel_layout_uninit
void av_channel_layout_uninit(AVChannelLayout *channel_layout)
Free any allocated data in the channel layout and reset the channel count to 0.
Definition: channel_layout.c:443
MOVTrack::vc1_info
struct MOVTrack::@493 vc1_info
ff_codec_get_tag
unsigned int ff_codec_get_tag(const AVCodecTag *tags, enum AVCodecID id)
Definition: utils.c:133
AVIO_DATA_MARKER_HEADER
@ AVIO_DATA_MARKER_HEADER
Header data; this needs to be present for the stream to be decodeable.
Definition: avio.h:114
MOVTrack::is_unaligned_qt_rgb
int is_unaligned_qt_rgb
Definition: movenc.h:184
av_packet_make_writable
int av_packet_make_writable(AVPacket *pkt)
Create a writable reference for the data described by a given packet, avoiding data copy if possible.
Definition: packet.c:515
mov_write_identification
static int mov_write_identification(AVIOContext *pb, AVFormatContext *s)
Definition: movenc.c:6407
mov_write_sidx_tags
static int mov_write_sidx_tags(AVIOContext *pb, MOVMuxContext *mov, int tracks, int ref_size)
Definition: movenc.c:5978
eac3_info::bsid
uint8_t bsid
Definition: movenc.c:398
MOVMuxContext::tracks
MOVTrack * tracks
Definition: movenc.h:220
AV_RB8
uint64_t_TMPL AV_WL64 unsigned int_TMPL AV_WL32 unsigned int_TMPL AV_WL24 unsigned int_TMPL AV_WL16 uint64_t_TMPL AV_WB64 unsigned int_TMPL AV_WB32 unsigned int_TMPL AV_WB24 unsigned int_TMPL AV_WB16 unsigned int_TMPL AV_RB8
Definition: bytestream.h:99
ref
static int ref[MAX_W *MAX_W]
Definition: jpeg2000dwt.c:117
AVPixFmtDescriptor::comp
AVComponentDescriptor comp[4]
Parameters that describe how pixels are packed.
Definition: pixdesc.h:105
MOVTrack::multichannel_as_mono
int multichannel_as_mono
Definition: movenc.h:127
mov_write_ilst_tag
static int mov_write_ilst_tag(AVIOContext *pb, MOVMuxContext *mov, AVFormatContext *s)
Definition: movenc.c:4824
mov_flush_fragment_interleaving
static int mov_flush_fragment_interleaving(AVFormatContext *s, MOVTrack *track)
Definition: movenc.c:6536
eac3_info::complexity_index_type_a
uint8_t complexity_index_type_a
Definition: movenc.c:415
mov_write_btrt_tag
static int mov_write_btrt_tag(AVIOContext *pb, MOVTrack *track)
Definition: movenc.c:1275
mov_write_glbl_tag
static int mov_write_glbl_tag(AVIOContext *pb, MOVTrack *track)
Definition: movenc.c:1198
AVStreamGroupLCEVC::width
int width
Width of the final stream for presentation.
Definition: avformat.h:1082
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:3893
ff_codec_movsubtitle_tags
const AVCodecTag ff_codec_movsubtitle_tags[]
Definition: isom.c:75
AVPacket::stream_index
int stream_index
Definition: packet.h:597
mov_write_mdia_tag
static int mov_write_mdia_tag(AVFormatContext *s, AVIOContext *pb, MOVMuxContext *mov, MOVTrack *track)
Definition: movenc.c:3939
av_clip_uint8
#define av_clip_uint8
Definition: common.h:106
avio_skip
int64_t avio_skip(AVIOContext *s, int64_t offset)
Skip given number of bytes forward.
Definition: aviobuf.c:321
AV_PIX_FMT_RGB565BE
@ AV_PIX_FMT_RGB565BE
packed RGB 5:6:5, 16bpp, (msb) 5R 6G 5B(lsb), big-endian
Definition: pixfmt.h:112
avio_wb64
void avio_wb64(AVIOContext *s, uint64_t val)
Definition: aviobuf.c:434
MOV_TRACK_ENABLED
#define MOV_TRACK_ENABLED
Definition: movenc.h:115
av_realloc
#define av_realloc(p, s)
Definition: ops_asmgen.c:46
mov_write_ispe_tag
static int mov_write_ispe_tag(AVIOContext *pb, MOVMuxContext *mov, AVFormatContext *s, int stream_index)
Definition: movenc.c:3709
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:347
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:1144
param_write_hex
static void param_write_hex(AVIOContext *pb, const char *name, const uint8_t *value, int len)
Definition: movenc.c:5447
MOVTrack::timescale
unsigned timescale
Definition: movenc.h:97
ff_ismv_muxer
const FFOutputFormat ff_ismv_muxer
mov_write_av1c_tag
static int mov_write_av1c_tag(AVIOContext *pb, MOVTrack *track)
Definition: movenc.c:1568
AV_CODEC_ID_PCM_U8
@ AV_CODEC_ID_PCM_U8
Definition: codec_id.h:344
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:5119
AVPixFmtDescriptor
Descriptor that unambiguously describes how the bits of a pixel are stored in the up to 4 data planes...
Definition: pixdesc.h:69
avio_wb24
void avio_wb24(AVIOContext *s, unsigned int val)
Definition: aviobuf.c:458
map
const VDPAUPixFmtMap * map
Definition: hwcontext_vdpau.c:71
MOVMuxContext::avif_loop_count
int avif_loop_count
Definition: movenc.h:274
AV_CHANNEL_LAYOUT_MONO
#define AV_CHANNEL_LAYOUT_MONO
Definition: channel_layout.h:394
mpeg4_bit_rate_values::max_bit_rate
uint32_t max_bit_rate
Maximum rate in bits/second over any window of one second.
Definition: movenc.c:716
AV_CODEC_ID_PCM_F64LE
@ AV_CODEC_ID_PCM_F64LE
Definition: codec_id.h:362
mov_write_dvcc_dvvc_tag
static int mov_write_dvcc_dvvc_tag(AVFormatContext *s, AVIOContext *pb, AVDOVIDecoderConfigurationRecord *dovi)
Definition: movenc.c:2517
mov_preroll_write_stbl_atoms
static int mov_preroll_write_stbl_atoms(AVIOContext *pb, MOVTrack *track)
Definition: movenc.c:3289
AVStereo3D::view
enum AVStereo3DView view
Determines which views are packed.
Definition: stereo3d.h:217
MOVMuxContext::major_brand
char * major_brand
Definition: movenc.h:243
AV_PROFILE_AAC_HE
#define AV_PROFILE_AAC_HE
Definition: defs.h:72
av_free
#define av_free(p)
Definition: tableprint_vlc.h:34
mov_write_chan_tag
static int mov_write_chan_tag(AVFormatContext *s, AVIOContext *pb, MOVTrack *track)
Definition: movenc.c:998
AVDictionaryEntry
Definition: dict.h:90
mov_write_st3d_tag
static int mov_write_st3d_tag(AVFormatContext *s, AVIOContext *pb, AVStereo3D *stereo_3d)
Definition: movenc.c:2286
MOVTrack::cluster_capacity
unsigned cluster_capacity
Definition: movenc.h:131
MOVMuxContext::write_btrt
int write_btrt
Definition: movenc.h:265
MOVIentry::stsd_index
unsigned int stsd_index
Definition: movenc.h:53
language_code
static uint16_t language_code(const char *str)
Definition: movenc.c:4993
AVCodecParameters::codec_id
enum AVCodecID codec_id
Specific type of the encoded data (the codec used).
Definition: codec_par.h:57
mov_write_ipma_tag
static int mov_write_ipma_tag(AVIOContext *pb, MOVMuxContext *mov, AVFormatContext *s)
Definition: movenc.c:3754
get_samples_per_packet
static int get_samples_per_packet(MOVTrack *track)
Definition: movenc.c:1256
MOV_ENC_CENC_AES_CTR
@ MOV_ENC_CENC_AES_CTR
Definition: movenc.h:200
mov_write_smhd_tag
static int mov_write_smhd_tag(AVIOContext *pb)
Definition: movenc.c:3522
AVContentLightMetadata::MaxFALL
unsigned MaxFALL
Max average light level per frame (cd/m^2).
Definition: mastering_display_metadata.h:116
AVPacket
This structure stores compressed data.
Definition: packet.h:572
MOVTrack::extradata
uint8_t ** extradata
Definition: movenc.h:105
cr
static double cr(void *priv, double x, double y)
Definition: vf_geq.c:248
AV_OPT_TYPE_BOOL
@ AV_OPT_TYPE_BOOL
Underlying C type is int.
Definition: opt.h:327
PIX_FMT_LIST_MOV
@ PIX_FMT_LIST_MOV
Definition: raw.h:40
AV_CODEC_ID_ADPCM_IMA_WAV
@ AV_CODEC_ID_ADPCM_IMA_WAV
Definition: codec_id.h:379
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:3069
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:6457
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:520
AV_CHAN_AMBISONIC_BASE
@ AV_CHAN_AMBISONIC_BASE
Range of channels between AV_CHAN_AMBISONIC_BASE and AV_CHAN_AMBISONIC_END represent Ambisonic compon...
Definition: channel_layout.h:108
MOV_TRUN_SAMPLE_SIZE
#define MOV_TRUN_SAMPLE_SIZE
Definition: isom.h:419
ff_isom_init_apvc
int ff_isom_init_apvc(APVDecoderConfigurationRecord **papvc, void *logctx)
Definition: apv.c:352
AV_OPT_TYPE_FLAGS
@ AV_OPT_TYPE_FLAGS
Underlying C type is unsigned int.
Definition: opt.h:255
int32_t
int32_t
Definition: audioconvert.c:56
distance
static float distance(float x, float y, int band)
Definition: nellymoserenc.c:231
MOVTrack::eac3_priv
void * eac3_priv
Definition: movenc.h:177
mov_write_dops_tag
static int mov_write_dops_tag(AVFormatContext *s, AVIOContext *pb, MOVTrack *track)
Definition: movenc.c:877
mov_write_squashed_packet
static int mov_write_squashed_packet(AVFormatContext *s, MOVTrack *track)
Definition: movenc.c:6561
avio_wb16
void avio_wb16(AVIOContext *s, unsigned int val)
Definition: aviobuf.c:446
AV_CODEC_ID_VP8
@ AV_CODEC_ID_VP8
Definition: codec_id.h:192
mov_write_hmhd_tag
static int mov_write_hmhd_tag(AVIOContext *pb)
Definition: movenc.c:3788
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:360
param_write_string
static void param_write_string(AVIOContext *pb, const char *name, const char *value)
Definition: movenc.c:5442
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:2666
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:2374
ff_isom_write_lhvc
int ff_isom_write_lhvc(AVIOContext *pb, const uint8_t *data, int size, int ps_array_completeness, void *logctx)
Writes L-HEVC extradata (parameter sets with nuh_layer_id > 0, as a LHEVCDecoderConfigurationRecord) ...
Definition: hevc.c:1405
AVERROR_INVALIDDATA
#define AVERROR_INVALIDDATA
Invalid data found when processing input.
Definition: error.h:61
ff_mov_track_kind_table
const struct MP4TrackKindMapping ff_mov_track_kind_table[]
Definition: isom.c:451
MovTag::id
uint32_t * id
trackID of the referenced track
Definition: movenc.h:90
av_stereo3d_type_name
const char * av_stereo3d_type_name(unsigned int type)
Provide a human-readable name of a given stereo3d type.
Definition: stereo3d.c:92
MOVMuxContext::mdat_buf
AVIOContext * mdat_buf
Definition: movenc.h:235
mov_write_amr_tag
static int mov_write_amr_tag(AVIOContext *pb, MOVTrack *track)
Definition: movenc.c:369
mov_write_mdat_tag
static int mov_write_mdat_tag(AVIOContext *pb, MOVMuxContext *mov)
Definition: movenc.c:6162
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:5736
AV_CODEC_ID_VORBIS
@ AV_CODEC_ID_VORBIS
Definition: codec_id.h:466
MOVTrack::default_duration
int64_t default_duration
Definition: movenc.h:151
AVFMT_AVOID_NEG_TS_AUTO
#define AVFMT_AVOID_NEG_TS_AUTO
Enabled when required by target format.
Definition: avformat.h:1674
av_timecode_init_from_string
int av_timecode_init_from_string(AVTimecode *tc, AVRational rate, const char *str, void *log_ctx)
Parse timecode representation (hh:mm:ss[:;.
Definition: timecode.c:241
AVStereo3D
Stereo 3D type: this structure describes how two videos are packed within a single video surface,...
Definition: stereo3d.h:203
AVDictionaryEntry::value
char * value
Definition: dict.h:92
avstring.h
ff_mov_cenc_avc_parse_nal_units
int ff_mov_cenc_avc_parse_nal_units(MOVMuxCencContext *ctx, AVIOContext *pb, const uint8_t *buf_in, int size)
Parse AVC NAL units from annex B format, the nal size and type are written in the clear while the bod...
Definition: movenccenc.c:198
AV_OPT_TYPE_STRING
@ AV_OPT_TYPE_STRING
Underlying C type is a uint8_t* that is either NULL or points to a C string allocated with the av_mal...
Definition: opt.h:276
width
#define width
Definition: dsp.h:89
AVAmbientViewingEnvironment::ambient_light_y
AVRational ambient_light_y
Normalized y chromaticity coordinate of the environmental ambient light in the nominal viewing enviro...
Definition: ambient_viewing_environment.h:54
flac.h
MOVTrack::frag_info_capacity
unsigned frag_info_capacity
Definition: movenc.h:165
AVTimecode
Definition: timecode.h:41
AV_RB24
uint64_t_TMPL AV_WL64 unsigned int_TMPL AV_WL32 unsigned int_TMPL AV_WL24 unsigned int_TMPL AV_WL16 uint64_t_TMPL AV_WB64 unsigned int_TMPL AV_WB32 unsigned int_TMPL AV_RB24
Definition: bytestream.h:97
AV_PIX_FMT_VYU444
@ AV_PIX_FMT_VYU444
packed VYU 4:4:4, 24bpp (1 Cr & Cb sample per 1x1 Y), VYUVYU...
Definition: pixfmt.h:446
av_bswap16
#define av_bswap16
Definition: bswap.h:28
ff_is_ttml_stream_paragraph_based
static unsigned int ff_is_ttml_stream_paragraph_based(const AVCodecParameters *codecpar)
Definition: ttmlenc.h:28
MOVTrack::first_iamf_idx
int first_iamf_idx
Definition: movenc.h:191
AVCodecTag::tag
unsigned int tag
Definition: internal.h:44
avio_put_str
int avio_put_str(AVIOContext *s, const char *str)
Write a NULL-terminated string.
Definition: aviobuf.c:376
put_bits.h
AV_CODEC_ID_MPEG2VIDEO
@ AV_CODEC_ID_MPEG2VIDEO
preferred ID for MPEG-1/2 video decoding
Definition: codec_id.h:54
AC3HeaderInfo::sr_code
uint8_t sr_code
Definition: ac3_parser_internal.h:40
MOV_TRUN_SAMPLE_CTS
#define MOV_TRUN_SAMPLE_CTS
Definition: isom.h:421
AV_OPT_TYPE_CONST
@ AV_OPT_TYPE_CONST
Special option type for declaring named constants.
Definition: opt.h:299
MOV_ISMV_TTML_TAG
#define MOV_ISMV_TTML_TAG
Definition: isom.h:482
snprintf
#define snprintf
Definition: snprintf.h:34
mov_add_tref_id
static int mov_add_tref_id(MOVMuxContext *mov, MovTag *tag, uint32_t id)
Definition: movenc.c:5278
mov_write_tfrf_tags
static int mov_write_tfrf_tags(AVIOContext *pb, MOVMuxContext *mov, MOVTrack *track)
Definition: movenc.c:5771
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:352
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:2189
MOVTrack::src_track
int * src_track
the tracks that this hint (or tmcd) track describes
Definition: movenc.h:145
AVSphericalMapping
This structure describes how to handle spherical videos, outlining information about projection,...
Definition: spherical.h:100
MOVMuxContext::moov_written
int moov_written
Definition: movenc.h:229
av_dict_iterate
const AVDictionaryEntry * av_dict_iterate(const AVDictionary *m, const AVDictionaryEntry *prev)
Iterate over a dictionary.
Definition: dict.c:42
FLAC_METADATA_TYPE_STREAMINFO
@ FLAC_METADATA_TYPE_STREAMINFO
Definition: flac.h:46
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:5716
MOV_PARTIAL_SYNC_SAMPLE
#define MOV_PARTIAL_SYNC_SAMPLE
Definition: movenc.h:59
AVSphericalMapping::yaw
int32_t yaw
Rotation around the up vector [-180, 180].
Definition: spherical.h:144
MOVTrack::tref_tags
MovTag * tref_tags
Definition: movenc.h:135
AV_CODEC_ID_DNXHD
@ AV_CODEC_ID_DNXHD
Definition: codec_id.h:151
MOVTrack::default_size
uint32_t default_size
Definition: movenc.h:153
ff_f4v_muxer
const FFOutputFormat ff_f4v_muxer
mov_write_clli_tag
static int mov_write_clli_tag(AVIOContext *pb, MOVTrack *track)
Definition: movenc.c:2646
FF_API_V408_CODECID
#define FF_API_V408_CODECID
Definition: version_major.h:42
MOVMuxContext::gamma
float gamma
Definition: movenc.h:251
AVPacket::side_data_elems
int side_data_elems
Definition: packet.h:607
av_get_pix_fmt_name
const char * av_get_pix_fmt_name(enum AVPixelFormat pix_fmt)
Return the short name for a pixel format, NULL in case pix_fmt is unknown.
Definition: pixdesc.c:3376
ff_hevc_annexb2mp4
int ff_hevc_annexb2mp4(AVIOContext *pb, const uint8_t *buf_in, int size, int filter_ps, int *ps_count)
Writes Annex B formatted HEVC NAL units to the provided AVIOContext.
Definition: hevc.c:1201
AV_RB16
uint64_t_TMPL AV_WL64 unsigned int_TMPL AV_WL32 unsigned int_TMPL AV_WL24 unsigned int_TMPL AV_WL16 uint64_t_TMPL AV_WB64 unsigned int_TMPL AV_WB32 unsigned int_TMPL AV_WB24 unsigned int_TMPL AV_RB16
Definition: bytestream.h:98
MOVTrack::nb_frag_info
int nb_frag_info
Definition: movenc.h:163
iamf_writer.h
av_fourcc2str
#define av_fourcc2str(fourcc)
Definition: avutil.h:347
mov_write_dfla_tag
static int mov_write_dfla_tag(AVIOContext *pb, MOVTrack *track)
Definition: movenc.c:857
MP4TrackKindMapping
Definition: isom.h:492
ff_alloc_extradata
int ff_alloc_extradata(AVCodecParameters *par, int size)
Allocate extradata with additional AV_INPUT_BUFFER_PADDING_SIZE at end which is always set to 0.
Definition: utils.c:237
AVDOVIDecoderConfigurationRecord
Definition: dovi_meta.h:55
mov_write_sidx_tag
static int mov_write_sidx_tag(AVIOContext *pb, MOVTrack *track, int ref_size, int total_sidx_size)
Definition: movenc.c:5917
AVIO_DATA_MARKER_FLUSH_POINT
@ AVIO_DATA_MARKER_FLUSH_POINT
A point in the output bytestream where the underlying AVIOContext might flush the buffer depending on...
Definition: avio.h:145
mux.h
eac3_info::fscod
uint8_t fscod
Definition: movenc.c:396
MOVIentry::samples_in_chunk
unsigned int samples_in_chunk
Definition: movenc.h:54