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  //src_trk may have a different timescale than the tmcd track
5397  track->track_duration = av_rescale(mov->tracks[src_trk].track_duration,
5398  track->timescale,
5399  mov->tracks[src_trk].timescale);
5400  }
5401  }
5402  }
5403 
5404  mov_write_mvhd_tag(pb, mov);
5405  if (mov->mode != MODE_MOV && mov->mode != MODE_AVIF && !mov->iods_skip)
5406  mov_write_iods_tag(pb, mov);
5407  for (i = 0; i < mov->nb_tracks; i++) {
5408  if (mov->tracks[i].entry > 0 || mov->flags & FF_MOV_FLAG_FRAGMENT ||
5409  mov->mode == MODE_AVIF) {
5410  int ret = mov_write_trak_tag(s, pb, mov, &(mov->tracks[i]), i < mov->nb_streams ? mov->tracks[i].st : NULL);
5411  if (ret < 0)
5412  return ret;
5413  }
5414  }
5415  /* Don't write mvex for hybrid_fragmented during mov_write_trailer
5416  * (mov->moov_written != 0)
5417  */
5418  if (mov->flags & FF_MOV_FLAG_FRAGMENT &&
5420  mov_write_mvex_tag(pb, mov); /* QuickTime requires trak to precede this */
5421 
5422  if (mov->mode == MODE_PSP)
5424  else if (mov->mode != MODE_AVIF)
5425  mov_write_udta_tag(pb, mov, s);
5426  for (i = 0; i < mov->nb_streams; i++)
5427  mov_write_pssh_tag(pb, mov->tracks[i].st);
5428 
5429  return update_size(pb, pos);
5430 }
5431 
5432 static void param_write_int(AVIOContext *pb, const char *name, int value)
5433 {
5434  avio_printf(pb, "<param name=\"%s\" value=\"%d\" valuetype=\"data\"/>\n", name, value);
5435 }
5436 
5437 static void param_write_string(AVIOContext *pb, const char *name, const char *value)
5438 {
5439  avio_printf(pb, "<param name=\"%s\" value=\"%s\" valuetype=\"data\"/>\n", name, value);
5440 }
5441 
5442 static void param_write_hex(AVIOContext *pb, const char *name, const uint8_t *value, int len)
5443 {
5444  char buf[150];
5445  len = FFMIN(sizeof(buf) / 2 - 1, len);
5446  ff_data_to_hex(buf, value, len, 0);
5447  avio_printf(pb, "<param name=\"%s\" value=\"%s\" valuetype=\"data\"/>\n", name, buf);
5448 }
5449 
5451 {
5452  int64_t pos = avio_tell(pb);
5453  int i;
5454 
5455  static const AVUUID uuid = {
5456  0xa5, 0xd4, 0x0b, 0x30, 0xe8, 0x14, 0x11, 0xdd,
5457  0xba, 0x2f, 0x08, 0x00, 0x20, 0x0c, 0x9a, 0x66
5458  };
5459 
5460  avio_wb32(pb, 0);
5461  ffio_wfourcc(pb, "uuid");
5462  avio_write(pb, uuid, AV_UUID_LEN);
5463  avio_wb32(pb, 0);
5464 
5465  avio_printf(pb, "<?xml version=\"1.0\" encoding=\"utf-8\"?>\n");
5466  avio_printf(pb, "<smil xmlns=\"http://www.w3.org/2001/SMIL20/Language\">\n");
5467  avio_printf(pb, "<head>\n");
5468  if (!(mov->fc->flags & AVFMT_FLAG_BITEXACT))
5469  avio_printf(pb, "<meta name=\"creator\" content=\"%s\" />\n",
5471  avio_printf(pb, "</head>\n");
5472  avio_printf(pb, "<body>\n");
5473  avio_printf(pb, "<switch>\n");
5474 
5475  mov_setup_track_ids(mov, s);
5476 
5477  for (i = 0; i < mov->nb_tracks; i++) {
5478  MOVTrack *track = &mov->tracks[i];
5479  struct mpeg4_bit_rate_values bit_rates =
5481  const char *type;
5482  int track_id = track->track_id;
5483  char track_name_buf[32] = { 0 };
5484 
5485  AVStream *st = track->st;
5486  AVDictionaryEntry *lang = av_dict_get(st->metadata, "language", NULL,0);
5487 
5488  if (track->par->codec_type == AVMEDIA_TYPE_VIDEO && !is_cover_image(st)) {
5489  type = "video";
5490  } else if (track->par->codec_type == AVMEDIA_TYPE_AUDIO) {
5491  type = "audio";
5492  } else {
5493  continue;
5494  }
5495 
5496  avio_printf(pb, "<%s systemBitrate=\"%"PRIu32"\">\n", type,
5497  bit_rates.avg_bit_rate);
5498  param_write_int(pb, "systemBitrate", bit_rates.avg_bit_rate);
5499  param_write_int(pb, "trackID", track_id);
5500  param_write_string(pb, "systemLanguage", lang ? lang->value : "und");
5501 
5502  /* Build track name piece by piece: */
5503  /* 1. track type */
5504  av_strlcat(track_name_buf, type, sizeof(track_name_buf));
5505  /* 2. track language, if available */
5506  if (lang)
5507  av_strlcatf(track_name_buf, sizeof(track_name_buf),
5508  "_%s", lang->value);
5509  /* 3. special type suffix */
5510  /* "_cc" = closed captions, "_ad" = audio_description */
5512  av_strlcat(track_name_buf, "_cc", sizeof(track_name_buf));
5514  av_strlcat(track_name_buf, "_ad", sizeof(track_name_buf));
5515 
5516  param_write_string(pb, "trackName", track_name_buf);
5517 
5518  if (track->par->codec_type == AVMEDIA_TYPE_VIDEO) {
5519  if (track->par->codec_id == AV_CODEC_ID_H264) {
5520  uint8_t *ptr;
5521  int size = track->extradata_size[track->last_stsd_index];
5522  if (!ff_avc_write_annexb_extradata(track->extradata[track->last_stsd_index], &ptr,
5523  &size)) {
5524  param_write_hex(pb, "CodecPrivateData",
5525  ptr ? ptr : track->extradata[track->last_stsd_index],
5526  size);
5527  av_free(ptr);
5528  }
5529  param_write_string(pb, "FourCC", "H264");
5530  } else if (track->par->codec_id == AV_CODEC_ID_VC1) {
5531  param_write_string(pb, "FourCC", "WVC1");
5532  param_write_hex(pb, "CodecPrivateData", track->extradata[track->last_stsd_index],
5533  track->extradata_size[track->last_stsd_index]);
5534  }
5535  param_write_int(pb, "MaxWidth", track->par->width);
5536  param_write_int(pb, "MaxHeight", track->par->height);
5537  param_write_int(pb, "DisplayWidth", track->par->width);
5538  param_write_int(pb, "DisplayHeight", track->par->height);
5539  } else {
5540  if (track->par->codec_id == AV_CODEC_ID_AAC) {
5541  switch (track->par->profile) {
5542  case AV_PROFILE_AAC_HE_V2:
5543  param_write_string(pb, "FourCC", "AACP");
5544  break;
5545  case AV_PROFILE_AAC_HE:
5546  param_write_string(pb, "FourCC", "AACH");
5547  break;
5548  default:
5549  param_write_string(pb, "FourCC", "AACL");
5550  }
5551  } else if (track->par->codec_id == AV_CODEC_ID_WMAPRO) {
5552  param_write_string(pb, "FourCC", "WMAP");
5553  }
5554  param_write_hex(pb, "CodecPrivateData", track->extradata[track->last_stsd_index],
5555  track->extradata_size[track->last_stsd_index]);
5557  track->par->codec_id));
5558  param_write_int(pb, "Channels", track->par->ch_layout.nb_channels);
5559  param_write_int(pb, "SamplingRate", track->tag == MKTAG('i','a','m','f') ?
5560  0 : track->par->sample_rate);
5561  param_write_int(pb, "BitsPerSample", 16);
5562  param_write_int(pb, "PacketSize", track->par->block_align ?
5563  track->par->block_align : 4);
5564  }
5565  avio_printf(pb, "</%s>\n", type);
5566  }
5567  avio_printf(pb, "</switch>\n");
5568  avio_printf(pb, "</body>\n");
5569  avio_printf(pb, "</smil>\n");
5570 
5571  return update_size(pb, pos);
5572 }
5573 
5575 {
5576  avio_wb32(pb, 16);
5577  ffio_wfourcc(pb, "mfhd");
5578  avio_wb32(pb, 0);
5579  avio_wb32(pb, mov->fragments);
5580  return 0;
5581 }
5582 
5583 static uint32_t get_sample_flags(MOVTrack *track, MOVIentry *entry)
5584 {
5587 }
5588 
5590  MOVTrack *track, int64_t moof_offset)
5591 {
5592  int64_t pos = avio_tell(pb);
5595  if (!track->entry) {
5597  } else {
5599  }
5602  if (mov->flags & FF_MOV_FLAG_DEFAULT_BASE_MOOF) {
5605  }
5606  /* CMAF requires all values to be explicit in tfhd atoms */
5607  if (mov->flags & FF_MOV_FLAG_CMAF)
5609 
5610  /* Don't set a default sample size, the silverlight player refuses
5611  * to play files with that set. Don't set a default sample duration,
5612  * WMP freaks out if it is set. Don't set a base data offset, PIFF
5613  * file format says it MUST NOT be set. */
5614  if (track->mode == MODE_ISM)
5617 
5618  avio_wb32(pb, 0); /* size placeholder */
5619  ffio_wfourcc(pb, "tfhd");
5620  avio_w8(pb, 0); /* version */
5621  avio_wb24(pb, flags);
5622 
5623  avio_wb32(pb, track->track_id); /* track-id */
5625  avio_wb64(pb, moof_offset);
5626  if (flags & MOV_TFHD_STSD_ID) {
5627  avio_wb32(pb, 1);
5628  }
5630  track->default_duration = get_cluster_duration(track, 0);
5631  avio_wb32(pb, track->default_duration);
5632  }
5633  if (flags & MOV_TFHD_DEFAULT_SIZE) {
5634  track->default_size = track->entry ? track->cluster[0].size : 1;
5635  avio_wb32(pb, track->default_size);
5636  } else
5637  track->default_size = -1;
5638 
5639  if (flags & MOV_TFHD_DEFAULT_FLAGS) {
5640  /* Set the default flags based on the second sample, if available.
5641  * If the first sample is different, that can be signaled via a separate field. */
5642  if (track->entry > 1)
5643  track->default_sample_flags = get_sample_flags(track, &track->cluster[1]);
5644  else
5645  track->default_sample_flags =
5646  track->par->codec_type == AVMEDIA_TYPE_VIDEO ?
5649  avio_wb32(pb, track->default_sample_flags);
5650  }
5651 
5652  return update_size(pb, pos);
5653 }
5654 
5656  MOVTrack *track, int moof_size,
5657  int first, int end)
5658 {
5659  int64_t pos = avio_tell(pb);
5660  uint32_t flags = MOV_TRUN_DATA_OFFSET;
5661  int i;
5662 
5663  for (i = first; i < end; i++) {
5664  if (get_cluster_duration(track, i) != track->default_duration)
5666  if (track->cluster[i].size != track->default_size)
5668  if (i > first && get_sample_flags(track, &track->cluster[i]) != track->default_sample_flags)
5670  }
5671  if (!(flags & MOV_TRUN_SAMPLE_FLAGS) && track->entry > first &&
5672  get_sample_flags(track, &track->cluster[first]) != track->default_sample_flags)
5674  if (track->flags & MOV_TRACK_CTTS)
5676 
5677  avio_wb32(pb, 0); /* size placeholder */
5678  ffio_wfourcc(pb, "trun");
5680  avio_w8(pb, 1); /* version */
5681  else
5682  avio_w8(pb, 0); /* version */
5683  avio_wb24(pb, flags);
5684 
5685  avio_wb32(pb, end - first); /* sample count */
5686  if (mov->flags & FF_MOV_FLAG_OMIT_TFHD_OFFSET &&
5688  !mov->first_trun)
5689  avio_wb32(pb, 0); /* Later tracks follow immediately after the previous one */
5690  else
5691  avio_wb32(pb, moof_size + 8 + track->data_offset +
5692  track->cluster[first].pos); /* data offset */
5694  avio_wb32(pb, get_sample_flags(track, &track->cluster[first]));
5695 
5696  for (i = first; i < end; i++) {
5698  avio_wb32(pb, get_cluster_duration(track, i));
5700  avio_wb32(pb, track->cluster[i].size);
5702  avio_wb32(pb, get_sample_flags(track, &track->cluster[i]));
5703  if (flags & MOV_TRUN_SAMPLE_CTS)
5704  avio_wb32(pb, track->cluster[i].cts);
5705  }
5706 
5707  mov->first_trun = 0;
5708  return update_size(pb, pos);
5709 }
5710 
5711 static int mov_write_tfxd_tag(AVIOContext *pb, MOVTrack *track)
5712 {
5713  int64_t pos = avio_tell(pb);
5714  static const uint8_t uuid[] = {
5715  0x6d, 0x1d, 0x9b, 0x05, 0x42, 0xd5, 0x44, 0xe6,
5716  0x80, 0xe2, 0x14, 0x1d, 0xaf, 0xf7, 0x57, 0xb2
5717  };
5718 
5719  avio_wb32(pb, 0); /* size placeholder */
5720  ffio_wfourcc(pb, "uuid");
5721  avio_write(pb, uuid, AV_UUID_LEN);
5722  avio_w8(pb, 1);
5723  avio_wb24(pb, 0);
5724  avio_wb64(pb, track->cluster[0].dts + track->cluster[0].cts);
5725  avio_wb64(pb, track->end_pts -
5726  (track->cluster[0].dts + track->cluster[0].cts));
5727 
5728  return update_size(pb, pos);
5729 }
5730 
5732  MOVTrack *track, int entry)
5733 {
5734  int n = track->nb_frag_info - 1 - entry, i;
5735  int size = 8 + 16 + 4 + 1 + 16*n;
5736  static const uint8_t uuid[] = {
5737  0xd4, 0x80, 0x7e, 0xf2, 0xca, 0x39, 0x46, 0x95,
5738  0x8e, 0x54, 0x26, 0xcb, 0x9e, 0x46, 0xa7, 0x9f
5739  };
5740 
5741  if (entry < 0)
5742  return 0;
5743 
5744  avio_seek(pb, track->frag_info[entry].tfrf_offset, SEEK_SET);
5745  avio_wb32(pb, size);
5746  ffio_wfourcc(pb, "uuid");
5747  avio_write(pb, uuid, AV_UUID_LEN);
5748  avio_w8(pb, 1);
5749  avio_wb24(pb, 0);
5750  avio_w8(pb, n);
5751  for (i = 0; i < n; i++) {
5752  int index = entry + 1 + i;
5753  avio_wb64(pb, track->frag_info[index].time);
5754  avio_wb64(pb, track->frag_info[index].duration);
5755  }
5756  if (n < mov->ism_lookahead) {
5757  int free_size = 16 * (mov->ism_lookahead - n);
5758  avio_wb32(pb, free_size);
5759  ffio_wfourcc(pb, "free");
5760  ffio_fill(pb, 0, free_size - 8);
5761  }
5762 
5763  return 0;
5764 }
5765 
5767  MOVTrack *track)
5768 {
5769  int64_t pos = avio_tell(pb);
5770  int i;
5771  for (i = 0; i < mov->ism_lookahead; i++) {
5772  /* Update the tfrf tag for the last ism_lookahead fragments,
5773  * nb_frag_info - 1 is the next fragment to be written. */
5774  mov_write_tfrf_tag(pb, mov, track, track->nb_frag_info - 2 - i);
5775  }
5776  avio_seek(pb, pos, SEEK_SET);
5777  return 0;
5778 }
5779 
5780 static int mov_add_tfra_entries(AVIOContext *pb, MOVMuxContext *mov, int tracks,
5781  int size)
5782 {
5783  int i;
5784  for (i = 0; i < mov->nb_tracks; i++) {
5785  MOVTrack *track = &mov->tracks[i];
5787  if ((tracks >= 0 && i != tracks) || !track->entry)
5788  continue;
5789  track->nb_frag_info++;
5790  if (track->nb_frag_info >= track->frag_info_capacity) {
5791  unsigned new_capacity = track->nb_frag_info + MOV_FRAG_INFO_ALLOC_INCREMENT;
5792  if (av_reallocp_array(&track->frag_info,
5793  new_capacity,
5794  sizeof(*track->frag_info)))
5795  return AVERROR(ENOMEM);
5796  track->frag_info_capacity = new_capacity;
5797  }
5798  info = &track->frag_info[track->nb_frag_info - 1];
5799  info->offset = avio_tell(pb);
5800  info->size = size;
5801  // Try to recreate the original pts for the first packet
5802  // from the fields we have stored
5803  info->time = track->cluster[0].dts + track->cluster[0].cts;
5804  info->duration = track->end_pts -
5805  (track->cluster[0].dts + track->cluster[0].cts);
5806  // If the pts is less than zero, we will have trimmed
5807  // away parts of the media track using an edit list,
5808  // and the corresponding start presentation time is zero.
5809  if (info->time < 0) {
5810  info->duration += info->time;
5811  info->time = 0;
5812  }
5813  info->tfrf_offset = 0;
5814  mov_write_tfrf_tags(pb, mov, track);
5815  }
5816  return 0;
5817 }
5818 
5819 static void mov_prune_frag_info(MOVMuxContext *mov, int tracks, int max)
5820 {
5821  int i;
5822  for (i = 0; i < mov->nb_tracks; i++) {
5823  MOVTrack *track = &mov->tracks[i];
5824  if ((tracks >= 0 && i != tracks) || !track->entry)
5825  continue;
5826  if (track->nb_frag_info > max) {
5827  memmove(track->frag_info, track->frag_info + (track->nb_frag_info - max), max * sizeof(*track->frag_info));
5828  track->nb_frag_info = max;
5829  }
5830  }
5831 }
5832 
5833 static int mov_write_tfdt_tag(AVIOContext *pb, MOVTrack *track)
5834 {
5835  int64_t pos = avio_tell(pb);
5836 
5837  avio_wb32(pb, 0); /* size */
5838  ffio_wfourcc(pb, "tfdt");
5839  avio_w8(pb, 1); /* version */
5840  avio_wb24(pb, 0);
5841  avio_wb64(pb, track->cluster[0].dts - track->start_dts);
5842  return update_size(pb, pos);
5843 }
5844 
5846  MOVTrack *track, int64_t moof_offset,
5847  int moof_size)
5848 {
5849  int64_t pos = avio_tell(pb);
5850  int i, start = 0;
5851  avio_wb32(pb, 0); /* size placeholder */
5852  ffio_wfourcc(pb, "traf");
5853 
5854  mov_write_tfhd_tag(pb, mov, track, moof_offset);
5855  if (mov->mode != MODE_ISM)
5856  mov_write_tfdt_tag(pb, track);
5857  for (i = 1; i < track->entry; i++) {
5858  if (track->cluster[i].pos != track->cluster[i - 1].pos + track->cluster[i - 1].size) {
5859  mov_write_trun_tag(pb, mov, track, moof_size, start, i);
5860  start = i;
5861  }
5862  }
5863  mov_write_trun_tag(pb, mov, track, moof_size, start, track->entry);
5864  if (mov->mode == MODE_ISM) {
5865  mov_write_tfxd_tag(pb, track);
5866 
5867  if (mov->ism_lookahead) {
5868  int size = 16 + 4 + 1 + 16 * mov->ism_lookahead;
5869 
5870  if (track->nb_frag_info > 0) {
5871  MOVFragmentInfo *info = &track->frag_info[track->nb_frag_info - 1];
5872  if (!info->tfrf_offset)
5873  info->tfrf_offset = avio_tell(pb);
5874  }
5875  avio_wb32(pb, 8 + size);
5876  ffio_wfourcc(pb, "free");
5877  ffio_fill(pb, 0, size);
5878  }
5879  }
5880 
5881  if (track->cenc.aes_ctr && (mov->flags & FF_MOV_FLAG_FRAGMENT))
5882  ff_mov_cenc_write_stbl_atoms(&track->cenc, pb, moof_offset);
5883 
5884  return update_size(pb, pos);
5885 }
5886 
5888  int tracks, int moof_size)
5889 {
5890  int64_t pos = avio_tell(pb);
5891  int i;
5892 
5893  avio_wb32(pb, 0); /* size placeholder */
5894  ffio_wfourcc(pb, "moof");
5895  mov->first_trun = 1;
5896 
5897  mov_write_mfhd_tag(pb, mov);
5898  for (i = 0; i < mov->nb_tracks; i++) {
5899  MOVTrack *track = &mov->tracks[i];
5900  if (tracks >= 0 && i != tracks)
5901  continue;
5902  if (!track->entry)
5903  continue;
5904  if (track->cenc.aes_ctr && (mov->flags & FF_MOV_FLAG_FRAGMENT))
5905  mov_write_pssh_tag(pb, track->st);
5906  mov_write_traf_tag(pb, mov, track, pos, moof_size);
5907  }
5908 
5909  return update_size(pb, pos);
5910 }
5911 
5913  MOVTrack *track, int ref_size, int total_sidx_size)
5914 {
5915  int64_t pos = avio_tell(pb), offset_pos, end_pos;
5916  int64_t presentation_time, duration, offset;
5917  unsigned starts_with_SAP;
5918  int i, entries;
5919 
5920  if (track->entry) {
5921  entries = 1;
5922  presentation_time = track->cluster[0].dts + track->cluster[0].cts;
5923  duration = track->end_pts -
5924  (track->cluster[0].dts + track->cluster[0].cts);
5925  starts_with_SAP = track->cluster[0].flags & MOV_SYNC_SAMPLE;
5926 
5927  // pts<0 should be cut away using edts
5928  if (presentation_time < 0) {
5929  duration += presentation_time;
5930  presentation_time = 0;
5931  }
5932  } else {
5933  entries = track->nb_frag_info;
5934  if (entries <= 0)
5935  return 0;
5936  presentation_time = track->frag_info[0].time;
5937  }
5938 
5939  avio_wb32(pb, 0); /* size */
5940  ffio_wfourcc(pb, "sidx");
5941  avio_w8(pb, 1); /* version */
5942  avio_wb24(pb, 0);
5943  avio_wb32(pb, track->track_id); /* reference_ID */
5944  avio_wb32(pb, track->timescale); /* timescale */
5945  avio_wb64(pb, presentation_time); /* earliest_presentation_time */
5946  offset_pos = avio_tell(pb);
5947  avio_wb64(pb, 0); /* first_offset (offset to referenced moof) */
5948  avio_wb16(pb, 0); /* reserved */
5949 
5950  avio_wb16(pb, entries); /* reference_count */
5951  for (i = 0; i < entries; i++) {
5952  if (!track->entry) {
5953  if (i > 1 && track->frag_info[i].offset != track->frag_info[i - 1].offset + track->frag_info[i - 1].size) {
5954  av_log(NULL, AV_LOG_ERROR, "Non-consecutive fragments, writing incorrect sidx\n");
5955  }
5956  duration = track->frag_info[i].duration;
5957  ref_size = track->frag_info[i].size;
5958  starts_with_SAP = 1;
5959  }
5960  avio_wb32(pb, (0 << 31) | (ref_size & 0x7fffffff)); /* reference_type (0 = media) | referenced_size */
5961  avio_wb32(pb, duration); /* subsegment_duration */
5962  avio_wb32(pb, (starts_with_SAP << 31) | (0 << 28) | 0); /* starts_with_SAP | SAP_type | SAP_delta_time */
5963  }
5964 
5965  end_pos = avio_tell(pb);
5966  offset = pos + total_sidx_size - end_pos;
5967  avio_seek(pb, offset_pos, SEEK_SET);
5968  avio_wb64(pb, offset);
5969  avio_seek(pb, end_pos, SEEK_SET);
5970  return update_size(pb, pos);
5971 }
5972 
5974  int tracks, int ref_size)
5975 {
5976  int i, round, ret;
5977  AVIOContext *avio_buf;
5978  int total_size = 0;
5979  for (round = 0; round < 2; round++) {
5980  // First run one round to calculate the total size of all
5981  // sidx atoms.
5982  // This would be much simpler if we'd only write one sidx
5983  // atom, for the first track in the moof.
5984  if (round == 0) {
5985  if ((ret = ffio_open_null_buf(&avio_buf)) < 0)
5986  return ret;
5987  } else {
5988  avio_buf = pb;
5989  }
5990  for (i = 0; i < mov->nb_tracks; i++) {
5991  MOVTrack *track = &mov->tracks[i];
5992  if (tracks >= 0 && i != tracks)
5993  continue;
5994  // When writing a sidx for the full file, entry is 0, but
5995  // we want to include all tracks. ref_size is 0 in this case,
5996  // since we read it from frag_info instead.
5997  if (!track->entry && ref_size > 0)
5998  continue;
5999  total_size -= mov_write_sidx_tag(avio_buf, track, ref_size,
6000  total_size);
6001  }
6002  if (round == 0) {
6003  total_size = ffio_close_null_buf(avio_buf);
6004  if (total_size < 0)
6005  return total_size;
6006  }
6007  }
6008  return 0;
6009 }
6010 
6011 static int mov_write_prft_tag(AVIOContext *pb, MOVMuxContext *mov, int tracks)
6012 {
6013  int64_t pos = avio_tell(pb), pts_us, ntp_ts;
6014  MOVTrack *first_track;
6015  int flags = 24;
6016 
6017  /* PRFT should be associated with at most one track. So, choosing only the
6018  * first track. */
6019  if (tracks > 0)
6020  return 0;
6021  first_track = &(mov->tracks[0]);
6022 
6023  if (!first_track->entry) {
6024  av_log(mov->fc, AV_LOG_WARNING, "Unable to write PRFT, no entries in the track\n");
6025  return 0;
6026  }
6027 
6028  if (first_track->cluster[0].pts == AV_NOPTS_VALUE) {
6029  av_log(mov->fc, AV_LOG_WARNING, "Unable to write PRFT, first PTS is invalid\n");
6030  return 0;
6031  }
6032 
6033  if (mov->write_prft == MOV_PRFT_SRC_WALLCLOCK) {
6034  if (first_track->cluster[0].prft.wallclock) {
6035  /* Round the NTP time to whole milliseconds. */
6036  ntp_ts = ff_get_formatted_ntp_time((first_track->cluster[0].prft.wallclock / 1000) * 1000 +
6037  NTP_OFFSET_US);
6038  flags = first_track->cluster[0].prft.flags;
6039  } else
6041  } else if (mov->write_prft == MOV_PRFT_SRC_PTS) {
6042  pts_us = av_rescale_q(first_track->cluster[0].pts,
6043  first_track->st->time_base, AV_TIME_BASE_Q);
6044  ntp_ts = ff_get_formatted_ntp_time(pts_us + NTP_OFFSET_US);
6045  } else {
6046  av_log(mov->fc, AV_LOG_WARNING, "Unsupported PRFT box configuration: %d\n",
6047  mov->write_prft);
6048  return 0;
6049  }
6050 
6051  avio_wb32(pb, 0); // Size place holder
6052  ffio_wfourcc(pb, "prft"); // Type
6053  avio_w8(pb, 1); // Version
6054  avio_wb24(pb, flags); // Flags
6055  avio_wb32(pb, first_track->track_id); // reference track ID
6056  avio_wb64(pb, ntp_ts); // NTP time stamp
6057  avio_wb64(pb, first_track->cluster[0].pts); //media time
6058  return update_size(pb, pos);
6059 }
6060 
6061 static int mov_write_moof_tag(AVIOContext *pb, MOVMuxContext *mov, int tracks,
6062  int64_t mdat_size)
6063 {
6064  AVIOContext *avio_buf;
6065  int ret, moof_size;
6066 
6067  if ((ret = ffio_open_null_buf(&avio_buf)) < 0)
6068  return ret;
6069  mov_write_moof_tag_internal(avio_buf, mov, tracks, 0);
6070  moof_size = ffio_close_null_buf(avio_buf);
6071  if (moof_size < 0)
6072  return moof_size;
6073 
6074  if (mov->flags & FF_MOV_FLAG_DASH &&
6076  mov_write_sidx_tags(pb, mov, tracks, moof_size + 8 + mdat_size);
6077 
6078  if (mov->write_prft > MOV_PRFT_NONE && mov->write_prft < MOV_PRFT_NB)
6079  mov_write_prft_tag(pb, mov, tracks);
6080 
6081  if (mov->flags & FF_MOV_FLAG_GLOBAL_SIDX ||
6082  !(mov->flags & FF_MOV_FLAG_SKIP_TRAILER) ||
6083  mov->ism_lookahead) {
6084  if ((ret = mov_add_tfra_entries(pb, mov, tracks, moof_size + 8 + mdat_size)) < 0)
6085  return ret;
6086  if (!(mov->flags & FF_MOV_FLAG_GLOBAL_SIDX) &&
6088  mov_prune_frag_info(mov, tracks, mov->ism_lookahead + 1);
6089  }
6090  }
6091 
6092  return mov_write_moof_tag_internal(pb, mov, tracks, moof_size);
6093 }
6094 
6095 static int mov_write_tfra_tag(AVIOContext *pb, MOVTrack *track)
6096 {
6097  int64_t pos = avio_tell(pb);
6098  int i;
6099 
6100  avio_wb32(pb, 0); /* size placeholder */
6101  ffio_wfourcc(pb, "tfra");
6102  avio_w8(pb, 1); /* version */
6103  avio_wb24(pb, 0);
6104 
6105  avio_wb32(pb, track->track_id);
6106  avio_wb32(pb, 0); /* length of traf/trun/sample num */
6107  avio_wb32(pb, track->nb_frag_info);
6108  for (i = 0; i < track->nb_frag_info; i++) {
6109  avio_wb64(pb, track->frag_info[i].time);
6110  avio_wb64(pb, track->frag_info[i].offset + track->data_offset);
6111  avio_w8(pb, 1); /* traf number */
6112  avio_w8(pb, 1); /* trun number */
6113  avio_w8(pb, 1); /* sample number */
6114  }
6115 
6116  return update_size(pb, pos);
6117 }
6118 
6120 {
6121  AVIOContext *mfra_pb;
6122  int i, ret, sz;
6123  uint8_t *buf;
6124 
6125  ret = avio_open_dyn_buf(&mfra_pb);
6126  if (ret < 0)
6127  return ret;
6128 
6129  avio_wb32(mfra_pb, 0); /* size placeholder */
6130  ffio_wfourcc(mfra_pb, "mfra");
6131  /* An empty mfra atom is enough to indicate to the publishing point that
6132  * the stream has ended. */
6133  if (mov->flags & FF_MOV_FLAG_ISML)
6134  goto done_mfra;
6135 
6136  for (i = 0; i < mov->nb_tracks; i++) {
6137  MOVTrack *track = &mov->tracks[i];
6138  if (track->nb_frag_info)
6139  mov_write_tfra_tag(mfra_pb, track);
6140  }
6141 
6142  avio_wb32(mfra_pb, 16);
6143  ffio_wfourcc(mfra_pb, "mfro");
6144  avio_wb32(mfra_pb, 0); /* version + flags */
6145  avio_wb32(mfra_pb, avio_tell(mfra_pb) + 4);
6146 
6147 done_mfra:
6148 
6149  sz = update_size(mfra_pb, 0);
6150  ret = avio_get_dyn_buf(mfra_pb, &buf);
6151  avio_write(pb, buf, ret);
6152  ffio_free_dyn_buf(&mfra_pb);
6153 
6154  return sz;
6155 }
6156 
6158 {
6159  avio_wb32(pb, 8); // placeholder for extended size field (64 bit)
6160  ffio_wfourcc(pb, mov->mode == MODE_MOV ? "wide" : "free");
6161 
6162  mov->mdat_pos = avio_tell(pb);
6163  avio_wb32(pb, 0); /* size placeholder*/
6164  ffio_wfourcc(pb, "mdat");
6165  return 0;
6166 }
6167 
6169  int has_h264, int has_video, int write_minor)
6170 {
6171  MOVMuxContext *mov = s->priv_data;
6172  int minor = 0x200;
6173 
6174  if (mov->major_brand && strlen(mov->major_brand) >= 4)
6175  ffio_wfourcc(pb, mov->major_brand);
6176  else if (mov->mode == MODE_3GP) {
6177  ffio_wfourcc(pb, has_h264 ? "3gp6" : "3gp4");
6178  minor = has_h264 ? 0x100 : 0x200;
6179  } else if (mov->mode == MODE_AVIF) {
6180  ffio_wfourcc(pb, mov->is_animated_avif ? "avis" : "avif");
6181  minor = 0;
6182  } else if (mov->mode & MODE_3G2) {
6183  ffio_wfourcc(pb, has_h264 ? "3g2b" : "3g2a");
6184  minor = has_h264 ? 0x20000 : 0x10000;
6185  } else if (mov->mode == MODE_PSP)
6186  ffio_wfourcc(pb, "MSNV");
6187  else if (mov->mode == MODE_MP4 && mov->flags & FF_MOV_FLAG_FRAGMENT &&
6189  ffio_wfourcc(pb, "iso6"); // Required when using signed CTS offsets in trun boxes
6190  else if (mov->mode == MODE_MP4 && mov->flags & FF_MOV_FLAG_DEFAULT_BASE_MOOF)
6191  ffio_wfourcc(pb, "iso5"); // Required when using default-base-is-moof
6192  else if (mov->mode == MODE_MP4 && mov->flags & FF_MOV_FLAG_NEGATIVE_CTS_OFFSETS)
6193  ffio_wfourcc(pb, "iso4");
6194  else if (mov->mode == MODE_MP4)
6195  ffio_wfourcc(pb, "isom");
6196  else if (mov->mode == MODE_IPOD)
6197  ffio_wfourcc(pb, has_video ? "M4V ":"M4A ");
6198  else if (mov->mode == MODE_ISM)
6199  ffio_wfourcc(pb, "isml");
6200  else if (mov->mode == MODE_F4V)
6201  ffio_wfourcc(pb, "f4v ");
6202  else
6203  ffio_wfourcc(pb, "qt ");
6204 
6205  if (write_minor)
6206  avio_wb32(pb, minor);
6207 }
6208 
6210 {
6211  MOVMuxContext *mov = s->priv_data;
6212  int64_t pos = avio_tell(pb);
6213  int has_h264 = 0, has_av1 = 0, has_video = 0, has_dolby = 0, has_id3 = 0;
6214  int has_iamf = 0;
6215 
6216 #if CONFIG_IAMFENC
6217  for (int i = 0; i < s->nb_stream_groups; i++) {
6218  const AVStreamGroup *stg = s->stream_groups[i];
6219 
6222  has_iamf = 1;
6223  break;
6224  }
6225  }
6226 #endif
6227  for (int i = 0; i < mov->nb_streams; i++) {
6228  AVStream *st = mov->tracks[i].st;
6229  if (is_cover_image(st))
6230  continue;
6232  has_video = 1;
6233  if (st->codecpar->codec_id == AV_CODEC_ID_H264)
6234  has_h264 = 1;
6235  if (st->codecpar->codec_id == AV_CODEC_ID_AV1)
6236  has_av1 = 1;
6237  if (st->codecpar->codec_id == AV_CODEC_ID_AC3 ||
6243  has_dolby = 1;
6245  has_id3 = 1;
6246  }
6247 
6248  avio_wb32(pb, 0); /* size */
6249  ffio_wfourcc(pb, "ftyp");
6250 
6251  // Write major brand
6252  mov_write_ftyp_tag_internal(pb, s, has_h264, has_video, 1);
6253  // Write the major brand as the first compatible brand as well
6254  mov_write_ftyp_tag_internal(pb, s, has_h264, has_video, 0);
6255 
6256  // Write compatible brands, ensuring that we don't write the major brand as a
6257  // compatible brand a second time.
6258  if (mov->mode == MODE_ISM) {
6259  ffio_wfourcc(pb, "piff");
6260  } else if (mov->mode == MODE_AVIF) {
6261  const AVPixFmtDescriptor *pix_fmt_desc =
6262  av_pix_fmt_desc_get(s->streams[0]->codecpar->format);
6263  const int depth = pix_fmt_desc->comp[0].depth;
6264  if (mov->is_animated_avif) {
6265  // For animated AVIF, major brand is "avis". Add "avif" as a
6266  // compatible brand.
6267  ffio_wfourcc(pb, "avif");
6268  ffio_wfourcc(pb, "msf1");
6269  ffio_wfourcc(pb, "iso8");
6270  }
6271  ffio_wfourcc(pb, "mif1");
6272  ffio_wfourcc(pb, "miaf");
6273  if (depth == 8 || depth == 10) {
6274  // MA1B and MA1A brands are based on AV1 profile. Short hand for
6275  // computing that is based on chroma subsampling type. 420 chroma
6276  // subsampling is MA1B. 444 chroma subsampling is MA1A.
6277  if (!pix_fmt_desc->log2_chroma_w && !pix_fmt_desc->log2_chroma_h) {
6278  // 444 chroma subsampling.
6279  ffio_wfourcc(pb, "MA1A");
6280  } else {
6281  // 420 chroma subsampling.
6282  ffio_wfourcc(pb, "MA1B");
6283  }
6284  }
6285  } else if (mov->mode != MODE_MOV) {
6286  // We add tfdt atoms when fragmenting, signal this with the iso6 compatible
6287  // brand, if not already the major brand. This is compatible with users that
6288  // don't understand tfdt.
6289  if (mov->mode == MODE_MP4) {
6290  if (mov->flags & FF_MOV_FLAG_CMAF)
6291  ffio_wfourcc(pb, "cmfc");
6293  ffio_wfourcc(pb, "iso6");
6294  if (has_av1)
6295  ffio_wfourcc(pb, "av01");
6296  if (has_dolby)
6297  ffio_wfourcc(pb, "dby1");
6298  if (has_iamf)
6299  ffio_wfourcc(pb, "iamf");
6300  } else {
6301  if (mov->flags & FF_MOV_FLAG_FRAGMENT)
6302  ffio_wfourcc(pb, "iso6");
6304  ffio_wfourcc(pb, "iso5");
6305  else if (mov->flags & FF_MOV_FLAG_NEGATIVE_CTS_OFFSETS)
6306  ffio_wfourcc(pb, "iso4");
6307  }
6308  // Brands prior to iso5 can't be signaled when using default-base-is-moof
6309  if (!(mov->flags & FF_MOV_FLAG_DEFAULT_BASE_MOOF)) {
6310  // write isom for mp4 only if it it's not the major brand already.
6311  if (mov->mode != MODE_MP4 || mov->flags & FF_MOV_FLAG_NEGATIVE_CTS_OFFSETS)
6312  ffio_wfourcc(pb, "isom");
6313  ffio_wfourcc(pb, "iso2");
6314  if (has_h264)
6315  ffio_wfourcc(pb, "avc1");
6316  }
6317  }
6318 
6319  if (mov->mode == MODE_MP4)
6320  ffio_wfourcc(pb, "mp41");
6321 
6322  if (mov->flags & FF_MOV_FLAG_DASH && mov->flags & FF_MOV_FLAG_GLOBAL_SIDX)
6323  ffio_wfourcc(pb, "dash");
6324 
6325  if (has_id3)
6326  ffio_wfourcc(pb, "aid3");
6327 
6328  return update_size(pb, pos);
6329 }
6330 
6332 {
6333  AVStream *video_st = s->streams[0];
6334  AVCodecParameters *video_par = s->streams[0]->codecpar;
6335  AVCodecParameters *audio_par = s->streams[1]->codecpar;
6336  int audio_rate = audio_par->sample_rate;
6337  int64_t frame_rate = video_st->avg_frame_rate.den ?
6339  0;
6340  int audio_kbitrate = audio_par->bit_rate / 1000;
6341  int video_kbitrate = FFMIN(video_par->bit_rate / 1000, 800 - audio_kbitrate);
6342 
6343  if (frame_rate < 0 || frame_rate > INT32_MAX) {
6344  av_log(s, AV_LOG_ERROR, "Frame rate %f outside supported range\n", frame_rate / (double)0x10000);
6345  return AVERROR(EINVAL);
6346  }
6347 
6348  avio_wb32(pb, 0x94); /* size */
6349  ffio_wfourcc(pb, "uuid");
6350  ffio_wfourcc(pb, "PROF");
6351 
6352  avio_wb32(pb, 0x21d24fce); /* 96 bit UUID */
6353  avio_wb32(pb, 0xbb88695c);
6354  avio_wb32(pb, 0xfac9c740);
6355 
6356  avio_wb32(pb, 0x0); /* ? */
6357  avio_wb32(pb, 0x3); /* 3 sections ? */
6358 
6359  avio_wb32(pb, 0x14); /* size */
6360  ffio_wfourcc(pb, "FPRF");
6361  avio_wb32(pb, 0x0); /* ? */
6362  avio_wb32(pb, 0x0); /* ? */
6363  avio_wb32(pb, 0x0); /* ? */
6364 
6365  avio_wb32(pb, 0x2c); /* size */
6366  ffio_wfourcc(pb, "APRF"); /* audio */
6367  avio_wb32(pb, 0x0);
6368  avio_wb32(pb, 0x2); /* TrackID */
6369  ffio_wfourcc(pb, "mp4a");
6370  avio_wb32(pb, 0x20f);
6371  avio_wb32(pb, 0x0);
6372  avio_wb32(pb, audio_kbitrate);
6373  avio_wb32(pb, audio_kbitrate);
6374  avio_wb32(pb, audio_rate);
6375  avio_wb32(pb, audio_par->ch_layout.nb_channels);
6376 
6377  avio_wb32(pb, 0x34); /* size */
6378  ffio_wfourcc(pb, "VPRF"); /* video */
6379  avio_wb32(pb, 0x0);
6380  avio_wb32(pb, 0x1); /* TrackID */
6381  if (video_par->codec_id == AV_CODEC_ID_H264) {
6382  ffio_wfourcc(pb, "avc1");
6383  avio_wb16(pb, 0x014D);
6384  avio_wb16(pb, 0x0015);
6385  } else {
6386  ffio_wfourcc(pb, "mp4v");
6387  avio_wb16(pb, 0x0000);
6388  avio_wb16(pb, 0x0103);
6389  }
6390  avio_wb32(pb, 0x0);
6391  avio_wb32(pb, video_kbitrate);
6392  avio_wb32(pb, video_kbitrate);
6393  avio_wb32(pb, frame_rate);
6394  avio_wb32(pb, frame_rate);
6395  avio_wb16(pb, video_par->width);
6396  avio_wb16(pb, video_par->height);
6397  avio_wb32(pb, 0x010001); /* ? */
6398 
6399  return 0;
6400 }
6401 
6403 {
6404  MOVMuxContext *mov = s->priv_data;
6405  int i;
6406 
6407  mov_write_ftyp_tag(pb,s);
6408  if (mov->mode == MODE_PSP) {
6409  int video_streams_nb = 0, audio_streams_nb = 0, other_streams_nb = 0;
6410  for (i = 0; i < mov->nb_streams; i++) {
6411  AVStream *st = mov->tracks[i].st;
6412  if (is_cover_image(st))
6413  continue;
6415  video_streams_nb++;
6416  else if (st->codecpar->codec_type == AVMEDIA_TYPE_AUDIO)
6417  audio_streams_nb++;
6418  else
6419  other_streams_nb++;
6420  }
6421 
6422  if (video_streams_nb != 1 || audio_streams_nb != 1 || other_streams_nb) {
6423  av_log(s, AV_LOG_ERROR, "PSP mode need one video and one audio stream\n");
6424  return AVERROR(EINVAL);
6425  }
6426  return mov_write_uuidprof_tag(pb, s);
6427  }
6428  return 0;
6429 }
6430 
6431 static int mov_parse_mpeg2_frame(AVPacket *pkt, uint32_t *flags)
6432 {
6433  uint32_t c = -1;
6434  int i, closed_gop = 0;
6435 
6436  for (i = 0; i < pkt->size - 4; i++) {
6437  c = (c << 8) + pkt->data[i];
6438  if (c == 0x1b8) { // gop
6439  closed_gop = pkt->data[i + 4] >> 6 & 0x01;
6440  } else if (c == 0x100) { // pic
6441  int temp_ref = (pkt->data[i + 1] << 2) | (pkt->data[i + 2] >> 6);
6442  if (!temp_ref || closed_gop) // I picture is not reordered
6444  else
6446  break;
6447  }
6448  }
6449  return 0;
6450 }
6451 
6453 {
6454  const uint8_t *start, *next, *end = pkt->data + pkt->size;
6455  int seq = 0, entry = 0;
6456  int key = pkt->flags & AV_PKT_FLAG_KEY;
6457  start = find_next_marker(pkt->data, end);
6458  for (next = start; next < end; start = next) {
6459  next = find_next_marker(start + 4, end);
6460  switch (AV_RB32(start)) {
6461  case VC1_CODE_SEQHDR:
6462  seq = 1;
6463  break;
6464  case VC1_CODE_ENTRYPOINT:
6465  entry = 1;
6466  break;
6467  case VC1_CODE_SLICE:
6468  trk->vc1_info.slices = 1;
6469  break;
6470  }
6471  }
6472  if (!trk->entry && trk->vc1_info.first_packet_seen)
6473  trk->vc1_info.first_frag_written = 1;
6474  if (!trk->entry && !trk->vc1_info.first_frag_written) {
6475  /* First packet in first fragment */
6476  trk->vc1_info.first_packet_seq = seq;
6478  trk->vc1_info.first_packet_seen = 1;
6479  } else if ((seq && !trk->vc1_info.packet_seq) ||
6480  (entry && !trk->vc1_info.packet_entry)) {
6481  int i;
6482  for (i = 0; i < trk->entry; i++)
6483  trk->cluster[i].flags &= ~MOV_SYNC_SAMPLE;
6484  trk->has_keyframes = 0;
6485  if (seq)
6486  trk->vc1_info.packet_seq = 1;
6487  if (entry)
6488  trk->vc1_info.packet_entry = 1;
6489  if (!trk->vc1_info.first_frag_written) {
6490  /* First fragment */
6491  if ((!seq || trk->vc1_info.first_packet_seq) &&
6492  (!entry || trk->vc1_info.first_packet_entry)) {
6493  /* First packet had the same headers as this one, readd the
6494  * sync sample flag. */
6495  trk->cluster[0].flags |= MOV_SYNC_SAMPLE;
6496  trk->has_keyframes = 1;
6497  }
6498  }
6499  }
6500  if (trk->vc1_info.packet_seq && trk->vc1_info.packet_entry)
6501  key = seq && entry;
6502  else if (trk->vc1_info.packet_seq)
6503  key = seq;
6504  else if (trk->vc1_info.packet_entry)
6505  key = entry;
6506  if (key) {
6507  trk->cluster[trk->entry].flags |= MOV_SYNC_SAMPLE;
6508  trk->has_keyframes++;
6509  }
6510 }
6511 
6513 {
6514  int length;
6515 
6516  if (pkt->size < 8)
6517  return;
6518 
6519  length = (AV_RB16(pkt->data) & 0xFFF) * 2;
6520  if (length < 8 || length > pkt->size)
6521  return;
6522 
6523  if (AV_RB32(pkt->data + 4) == 0xF8726FBA) {
6524  trk->cluster[trk->entry].flags |= MOV_SYNC_SAMPLE;
6525  trk->has_keyframes++;
6526  }
6527 
6528  return;
6529 }
6530 
6532 {
6533  MOVMuxContext *mov = s->priv_data;
6534  int ret, buf_size;
6535  uint8_t *buf;
6536  int i, offset;
6537 
6538  if (!track->mdat_buf)
6539  return 0;
6540  if (!mov->mdat_buf) {
6541  if ((ret = avio_open_dyn_buf(&mov->mdat_buf)) < 0)
6542  return ret;
6543  }
6544  buf_size = avio_get_dyn_buf(track->mdat_buf, &buf);
6545 
6546  offset = avio_tell(mov->mdat_buf);
6547  avio_write(mov->mdat_buf, buf, buf_size);
6548  ffio_reset_dyn_buf(track->mdat_buf);
6549 
6550  for (i = track->entries_flushed; i < track->entry; i++)
6551  track->cluster[i].pos += offset;
6552  track->entries_flushed = track->entry;
6553  return 0;
6554 }
6555 
6557 {
6558  MOVMuxContext *mov = s->priv_data;
6559  AVPacket *squashed_packet = mov->pkt;
6560  int ret = AVERROR_BUG;
6561 
6562  switch (track->st->codecpar->codec_id) {
6563  case AV_CODEC_ID_TTML: {
6564  int had_packets = !!track->squashed_packet_queue.head;
6565 
6566  if ((ret = ff_mov_generate_squashed_ttml_packet(s, track, squashed_packet)) < 0) {
6567  goto finish_squash;
6568  }
6569 
6570  // We have generated a padding packet (no actual input packets in
6571  // queue) and its duration is zero. Skipping writing it.
6572  if (!had_packets && squashed_packet->duration == 0) {
6573  goto finish_squash;
6574  }
6575 
6576  track->end_reliable = 1;
6577  break;
6578  }
6579  default:
6580  ret = AVERROR(EINVAL);
6581  goto finish_squash;
6582  }
6583 
6584  squashed_packet->stream_index = track->st->index;
6585 
6586  ret = mov_write_single_packet(s, squashed_packet);
6587 
6588 finish_squash:
6589  av_packet_unref(squashed_packet);
6590 
6591  return ret;
6592 }
6593 
6595 {
6596  MOVMuxContext *mov = s->priv_data;
6597 
6598  for (int i = 0; i < mov->nb_streams; i++) {
6599  MOVTrack *track = &mov->tracks[i];
6600  int ret = AVERROR_BUG;
6601 
6602  if (track->squash_fragment_samples_to_one && !track->entry) {
6603  if ((ret = mov_write_squashed_packet(s, track)) < 0) {
6605  "Failed to write squashed packet for %s stream with "
6606  "index %d and track id %d. Error: %s\n",
6608  track->st->index, track->track_id,
6609  av_err2str(ret));
6610  return ret;
6611  }
6612  }
6613  }
6614 
6615  return 0;
6616 }
6617 
6619  int64_t ref_pos)
6620 {
6621  int i;
6622  if (!track->entry)
6623  return 0;
6624  if (mov->flags & FF_MOV_FLAG_HYBRID_FRAGMENTED) {
6625  for (i = 0; i < track->entry; i++)
6626  track->cluster[i].pos += ref_pos + track->data_offset;
6627  if (track->cluster_written == 0) {
6628  // First flush. Chunking for this fragment may already have been
6629  // done, either if we didn't use empty_moov, or if we did use
6630  // delay_moov. In either case, reset chunking here.
6631  for (i = 0; i < track->entry; i++) {
6632  track->cluster[i].chunkNum = 0;
6633  track->cluster[i].samples_in_chunk = track->cluster[i].entries;
6634  }
6635  }
6636  if (av_reallocp_array(&track->cluster_written,
6637  track->entry_written + track->entry,
6638  sizeof(*track->cluster)))
6639  return AVERROR(ENOMEM);
6640  memcpy(&track->cluster_written[track->entry_written],
6641  track->cluster, track->entry * sizeof(*track->cluster));
6642  track->entry_written += track->entry;
6643  }
6644  track->entry = 0;
6645  track->entries_flushed = 0;
6646  track->end_reliable = 0;
6647  return 0;
6648 }
6649 
6650 static int mov_flush_fragment(AVFormatContext *s, int force)
6651 {
6652  MOVMuxContext *mov = s->priv_data;
6653  int i, first_track = -1;
6654  int64_t mdat_size = 0, mdat_start = 0;
6655  int ret;
6656  int has_video = 0, starts_with_key = 0, first_video_track = 1;
6657 
6658  if (!(mov->flags & FF_MOV_FLAG_FRAGMENT))
6659  return 0;
6660 
6661  // Check if we have any tracks that require squashing.
6662  // In that case, we'll have to write the packet here.
6663  if ((ret = mov_write_squashed_packets(s)) < 0)
6664  return ret;
6665 
6666  // Try to fill in the duration of the last packet in each stream
6667  // from queued packets in the interleave queues. If the flushing
6668  // of fragments was triggered automatically by an AVPacket, we
6669  // already have reliable info for the end of that track, but other
6670  // tracks may need to be filled in.
6671  for (i = 0; i < mov->nb_streams; i++) {
6672  MOVTrack *track = &mov->tracks[i];
6673  if (!track->end_reliable) {
6674  const AVPacket *pkt = ff_interleaved_peek(s, i);
6675  if (pkt) {
6676  int64_t offset, dts, pts;
6678  pts = pkt->pts + offset;
6679  dts = pkt->dts + offset;
6680  if (track->dts_shift != AV_NOPTS_VALUE)
6681  dts += track->dts_shift;
6682  track->track_duration = dts - track->start_dts;
6683  if (pts != AV_NOPTS_VALUE)
6684  track->end_pts = pts;
6685  else
6686  track->end_pts = dts;
6687  if (!(pkt->flags & AV_PKT_FLAG_DISCARD))
6688  track->elst_end_pts = track->end_pts;
6689  }
6690  }
6691  }
6692 
6693  for (i = 0; i < mov->nb_tracks; i++) {
6694  MOVTrack *track = &mov->tracks[i];
6695  if (track->entry <= 1)
6696  continue;
6697  // Sample durations are calculated as the diff of dts values,
6698  // but for the last sample in a fragment, we don't know the dts
6699  // of the first sample in the next fragment, so we have to rely
6700  // on what was set as duration in the AVPacket. Not all callers
6701  // set this though, so we might want to replace it with an
6702  // estimate if it currently is zero.
6703  if (get_cluster_duration(track, track->entry - 1) != 0)
6704  continue;
6705  // Use the duration (i.e. dts diff) of the second last sample for
6706  // the last one. This is a wild guess (and fatal if it turns out
6707  // to be too long), but probably the best we can do - having a zero
6708  // duration is bad as well.
6709  track->track_duration += get_cluster_duration(track, track->entry - 2);
6710  track->end_pts += get_cluster_duration(track, track->entry - 2);
6711  if (!mov->missing_duration_warned) {
6713  "Estimating the duration of the last packet in a "
6714  "fragment, consider setting the duration field in "
6715  "AVPacket instead.\n");
6716  mov->missing_duration_warned = 1;
6717  }
6718  }
6719 
6720  if (!mov->moov_written) {
6721  int64_t pos = avio_tell(s->pb);
6722  uint8_t *buf;
6723  int buf_size, moov_size;
6724 
6725  for (i = 0; i < mov->nb_tracks; i++)
6726  if (!mov->tracks[i].entry && !is_cover_image(mov->tracks[i].st))
6727  break;
6728  /* Don't write the initial moov unless all tracks have data */
6729  if (i < mov->nb_tracks && !force)
6730  return 0;
6731 
6732  moov_size = get_moov_size(s);
6733  for (i = 0; i < mov->nb_tracks; i++)
6734  mov->tracks[i].data_offset = pos + moov_size + 8;
6735 
6737  if (mov->flags & FF_MOV_FLAG_DELAY_MOOV &&
6740  if ((ret = mov_write_moov_tag(s->pb, mov, s)) < 0)
6741  return ret;
6742 
6743  if (mov->flags & FF_MOV_FLAG_DELAY_MOOV) {
6744  if (mov->flags & FF_MOV_FLAG_GLOBAL_SIDX)
6745  mov->reserved_header_pos = avio_tell(s->pb);
6747  mov->moov_written = 1;
6748  return 0;
6749  }
6750 
6751  buf_size = avio_get_dyn_buf(mov->mdat_buf, &buf);
6752  avio_wb32(s->pb, buf_size + 8);
6753  ffio_wfourcc(s->pb, "mdat");
6754  avio_write(s->pb, buf, buf_size);
6756 
6757  if (mov->flags & FF_MOV_FLAG_GLOBAL_SIDX)
6758  mov->reserved_header_pos = avio_tell(s->pb);
6759 
6760  mov->moov_written = 1;
6761  mov->mdat_size = 0;
6762  for (i = 0; i < mov->nb_tracks; i++)
6763  mov_finish_fragment(mov, &mov->tracks[i], 0);
6765  return 0;
6766  }
6767 
6768  if (mov->frag_interleave) {
6769  for (i = 0; i < mov->nb_tracks; i++) {
6770  MOVTrack *track = &mov->tracks[i];
6771  int ret;
6772  if ((ret = mov_flush_fragment_interleaving(s, track)) < 0)
6773  return ret;
6774  }
6775 
6776  if (!mov->mdat_buf)
6777  return 0;
6778  mdat_size = avio_tell(mov->mdat_buf);
6779  }
6780 
6781  for (i = 0; i < mov->nb_tracks; i++) {
6782  MOVTrack *track = &mov->tracks[i];
6783  if (mov->flags & FF_MOV_FLAG_SEPARATE_MOOF || mov->frag_interleave)
6784  track->data_offset = 0;
6785  else
6786  track->data_offset = mdat_size;
6787  if (track->par->codec_type == AVMEDIA_TYPE_VIDEO) {
6788  has_video = 1;
6789  if (first_video_track) {
6790  if (track->entry)
6791  starts_with_key = track->cluster[0].flags & MOV_SYNC_SAMPLE;
6792  first_video_track = 0;
6793  }
6794  }
6795  if (!track->entry)
6796  continue;
6797  if (track->mdat_buf)
6798  mdat_size += avio_tell(track->mdat_buf);
6799  if (first_track < 0)
6800  first_track = i;
6801  }
6802 
6803  if (!mdat_size)
6804  return 0;
6805 
6806  avio_write_marker(s->pb,
6807  av_rescale(mov->tracks[first_track].cluster[0].dts, AV_TIME_BASE, mov->tracks[first_track].timescale),
6808  (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);
6809 
6810  for (i = first_track; i < mov->nb_tracks; i++) {
6811  MOVTrack *track = &mov->tracks[i];
6812  int buf_size, write_moof = 1, moof_tracks = -1;
6813  uint8_t *buf;
6814 
6815  if (!track->entry)
6816  continue;
6817  if (mov->flags & FF_MOV_FLAG_SEPARATE_MOOF) {
6818  mdat_size = avio_tell(track->mdat_buf);
6819  moof_tracks = i;
6820  } else {
6821  write_moof = i == first_track;
6822  }
6823 
6824  if (write_moof) {
6826 
6827  mov_write_moof_tag(s->pb, mov, moof_tracks, mdat_size);
6828  mov->fragments++;
6829 
6830  if (track->cenc.aes_ctr)
6831  ff_mov_cenc_flush(&track->cenc);
6832 
6833  avio_wb32(s->pb, mdat_size + 8);
6834  ffio_wfourcc(s->pb, "mdat");
6835  mdat_start = avio_tell(s->pb);
6836  }
6837 
6838  mov_finish_fragment(mov, &mov->tracks[i], mdat_start);
6839  if (!mov->frag_interleave) {
6840  if (!track->mdat_buf)
6841  continue;
6842  buf_size = avio_get_dyn_buf(track->mdat_buf, &buf);
6843  avio_write(s->pb, buf, buf_size);
6844  ffio_reset_dyn_buf(track->mdat_buf);
6845  } else {
6846  if (!mov->mdat_buf)
6847  continue;
6848  buf_size = avio_get_dyn_buf(mov->mdat_buf, &buf);
6849  avio_write(s->pb, buf, buf_size);
6851  }
6852  }
6853 
6854  mov->mdat_size = 0;
6855 
6857  return 0;
6858 }
6859 
6861 {
6862  MOVMuxContext *mov = s->priv_data;
6863  int had_moov = mov->moov_written;
6864  int ret = mov_flush_fragment(s, force);
6865  if (ret < 0)
6866  return ret;
6867  // If using delay_moov, the first flush only wrote the moov,
6868  // not the actual moof+mdat pair, thus flush once again.
6869  if (!had_moov && mov->flags & FF_MOV_FLAG_DELAY_MOOV)
6870  ret = mov_flush_fragment(s, force);
6871  return ret;
6872 }
6873 
6875 {
6876  int64_t ref;
6877  uint64_t duration;
6878 
6879  if (trk->entry) {
6880  ref = trk->cluster[trk->entry - 1].dts;
6881  } else if ( trk->start_dts != AV_NOPTS_VALUE
6882  && !trk->frag_discont) {
6883  ref = trk->start_dts + trk->track_duration;
6884  } else
6885  ref = pkt->dts; // Skip tests for the first packet
6886 
6887  if (trk->dts_shift != AV_NOPTS_VALUE) {
6888  /* With negative CTS offsets we have set an offset to the DTS,
6889  * reverse this for the check. */
6890  ref -= trk->dts_shift;
6891  }
6892 
6893  duration = pkt->dts - ref;
6894  if (pkt->dts < ref || duration >= INT_MAX) {
6895  av_log(s, AV_LOG_WARNING, "Packet duration: %"PRId64" / dts: %"PRId64" in stream %d is out of range\n",
6897 
6898  pkt->dts = ref + 1;
6899  pkt->pts = AV_NOPTS_VALUE;
6900  }
6901 
6902  if (pkt->duration < 0 || pkt->duration > INT_MAX) {
6903  av_log(s, AV_LOG_ERROR, "Application provided duration: %"PRId64" in stream %d is invalid\n", pkt->duration, pkt->stream_index);
6904  return AVERROR(EINVAL);
6905  }
6906  return 0;
6907 }
6908 
6910 {
6911  MOVMuxContext *mov = s->priv_data;
6912  AVIOContext *pb = s->pb;
6913  MOVTrack *trk;
6914  AVCodecParameters *par;
6916  unsigned int samples_in_chunk = 0;
6917  int size = pkt->size, ret = 0, offset = 0;
6918  size_t prft_size;
6919  uint8_t *reformatted_data = NULL;
6920 
6921  if (pkt->stream_index < s->nb_streams)
6922  trk = s->streams[pkt->stream_index]->priv_data;
6923  else // Timecode or chapter
6924  trk = &mov->tracks[pkt->stream_index];
6925  par = trk->par;
6926 
6927  ret = check_pkt(s, trk, pkt);
6928  if (ret < 0)
6929  return ret;
6930 
6931  if (pkt->pts != AV_NOPTS_VALUE &&
6932  (uint64_t)pkt->dts - pkt->pts != (int32_t)((uint64_t)pkt->dts - pkt->pts)) {
6933  av_log(s, AV_LOG_WARNING, "pts/dts pair unsupported\n");
6934  return AVERROR_PATCHWELCOME;
6935  }
6936 
6937  if (mov->flags & FF_MOV_FLAG_FRAGMENT || mov->mode == MODE_AVIF) {
6938  int ret;
6939  if (mov->moov_written || mov->flags & FF_MOV_FLAG_EMPTY_MOOV) {
6940  if (mov->frag_interleave && mov->fragments > 0) {
6941  if (trk->entry - trk->entries_flushed >= mov->frag_interleave) {
6942  if ((ret = mov_flush_fragment_interleaving(s, trk)) < 0)
6943  return ret;
6944  }
6945  }
6946 
6947  if (!trk->mdat_buf) {
6948  if ((ret = avio_open_dyn_buf(&trk->mdat_buf)) < 0)
6949  return ret;
6950  }
6951  pb = trk->mdat_buf;
6952  } else {
6953  if (!mov->mdat_buf) {
6954  if ((ret = avio_open_dyn_buf(&mov->mdat_buf)) < 0)
6955  return ret;
6956  }
6957  pb = mov->mdat_buf;
6958  }
6959  }
6960 
6961  if (par->codec_id == AV_CODEC_ID_AMR_NB) {
6962  /* We must find out how many AMR blocks there are in one packet */
6963  static const uint16_t packed_size[16] =
6964  {13, 14, 16, 18, 20, 21, 27, 32, 6, 0, 0, 0, 0, 0, 0, 1};
6965  int len = 0;
6966 
6967  while (len < size && samples_in_chunk < 100) {
6968  len += packed_size[(pkt->data[len] >> 3) & 0x0F];
6969  samples_in_chunk++;
6970  }
6971  if (samples_in_chunk > 1) {
6972  av_log(s, AV_LOG_ERROR, "fatal error, input is not a single packet, implement a AVParser for it\n");
6973  return -1;
6974  }
6975  } else if (par->codec_id == AV_CODEC_ID_ADPCM_MS ||
6977  samples_in_chunk = trk->par->frame_size;
6978  } else if (trk->sample_size)
6979  samples_in_chunk = size / trk->sample_size;
6980  else
6981  samples_in_chunk = 1;
6982 
6983  if (samples_in_chunk < 1) {
6984  av_log(s, AV_LOG_ERROR, "fatal error, input packet contains no samples\n");
6985  return AVERROR_PATCHWELCOME;
6986  }
6987 
6988  /* copy extradata if it exists */
6989  if (trk->extradata_size[0] == 0 && par->extradata_size > 0 &&
6990  !TAG_IS_AVCI(trk->tag) &&
6991  (par->codec_id != AV_CODEC_ID_DNXHD)) {
6992  trk->extradata[0] = av_memdup(par->extradata, par->extradata_size);
6993  if (!trk->extradata[0]) {
6994  ret = AVERROR(ENOMEM);
6995  goto err;
6996  }
6997  trk->extradata_size[0] = par->extradata_size;
6998  }
6999 
7000  if ((par->codec_id == AV_CODEC_ID_DNXHD ||
7001  par->codec_id == AV_CODEC_ID_H264 ||
7002  par->codec_id == AV_CODEC_ID_HEVC ||
7003  par->codec_id == AV_CODEC_ID_VVC ||
7004  par->codec_id == AV_CODEC_ID_VP9 ||
7005  par->codec_id == AV_CODEC_ID_EVC ||
7006  par->codec_id == AV_CODEC_ID_LCEVC ||
7007  par->codec_id == AV_CODEC_ID_TRUEHD) && !trk->extradata_size[0] &&
7008  !TAG_IS_AVCI(trk->tag)) {
7009  /* copy frame to create needed atoms */
7010  trk->extradata_size[0] = size;
7012  if (!trk->extradata[0]) {
7013  ret = AVERROR(ENOMEM);
7014  goto err;
7015  }
7016  memcpy(trk->extradata[0], pkt->data, size);
7017  memset(trk->extradata[0] + size, 0, AV_INPUT_BUFFER_PADDING_SIZE);
7018  }
7019 
7021  if (pkt->size && sd && sd->size > 0) {
7022  int i;
7023  for (i = 0; i < trk->stsd_count; i++) {
7024  if (trk->extradata_size[i] == sd->size && !memcmp(trk->extradata[i], sd->data, sd->size))
7025  break;
7026  }
7027 
7028  if (i < trk->stsd_count)
7029  trk->last_stsd_index = i;
7030  else if (trk->stsd_count <= INT_MAX - 1) {
7031  int new_count = trk->stsd_count + 1;
7032  uint8_t **extradata = av_realloc_array(trk->extradata, new_count, sizeof(*trk->extradata));
7033  if (!extradata)
7034  return AVERROR(ENOMEM);
7035  trk->extradata = extradata;
7036 
7037  int *extradata_size = av_realloc_array(trk->extradata_size, new_count, sizeof(*trk->extradata_size));
7038  if (!extradata_size)
7039  return AVERROR(ENOMEM);
7040  trk->extradata_size = extradata_size;
7041 
7042  trk->extradata[trk->stsd_count] = av_memdup(sd->data, sd->size);
7043  if (!trk->extradata[trk->stsd_count])
7044  return AVERROR(ENOMEM);
7045 
7046  trk->extradata_size[trk->stsd_count] = sd->size;
7047  trk->last_stsd_index = trk->stsd_count;
7048  trk->stsd_count = new_count;
7049  } else
7050  return AVERROR(ENOMEM);
7051  }
7052 
7053  if (par->codec_id == AV_CODEC_ID_AAC && pkt->size > 2 &&
7054  (AV_RB16(pkt->data) & 0xfff0) == 0xfff0) {
7055  if (!trk->st->nb_frames) {
7056  av_log(s, AV_LOG_ERROR, "Malformed AAC bitstream detected: "
7057  "use the audio bitstream filter 'aac_adtstoasc' to fix it "
7058  "('-bsf:a aac_adtstoasc' option with ffmpeg)\n");
7059  return -1;
7060  }
7061  av_log(s, AV_LOG_WARNING, "aac bitstream error\n");
7062  }
7063  if (par->codec_id == AV_CODEC_ID_H264 && trk->extradata_size[trk->last_stsd_index] > 0 &&
7064  *(uint8_t *)trk->extradata[trk->last_stsd_index] != 1 && !TAG_IS_AVCI(trk->tag)) {
7065  /* from x264 or from bytestream H.264 */
7066  /* NAL reformatting needed */
7067  if (trk->hint_track >= 0 && trk->hint_track < mov->nb_tracks) {
7068  ret = ff_nal_parse_units_buf(pkt->data, &reformatted_data,
7069  &size);
7070  if (ret < 0)
7071  return ret;
7072  avio_write(pb, reformatted_data, size);
7073  } else {
7074  if (trk->cenc.aes_ctr) {
7076  if (size < 0) {
7077  ret = size;
7078  goto err;
7079  }
7080  } else {
7081  size = ff_nal_parse_units(pb, pkt->data, pkt->size);
7082  }
7083  }
7084  } else if (par->codec_id == AV_CODEC_ID_HEVC && trk->extradata_size[trk->last_stsd_index] > 6 &&
7085  (AV_RB24(trk->extradata[trk->last_stsd_index]) == 1 || AV_RB32(trk->extradata[trk->last_stsd_index]) == 1)) {
7086  /* extradata is Annex B, assume the bitstream is too and convert it */
7087  int filter_ps = (trk->tag == MKTAG('h','v','c','1'));
7088  if (trk->hint_track >= 0 && trk->hint_track < mov->nb_tracks) {
7089  ret = ff_hevc_annexb2mp4_buf(pkt->data, &reformatted_data,
7090  &size, filter_ps, NULL);
7091  if (ret < 0)
7092  return ret;
7093  avio_write(pb, reformatted_data, size);
7094  } else {
7095  if (trk->cenc.aes_ctr) {
7097  if (size < 0) {
7098  ret = size;
7099  goto err;
7100  }
7101  } else {
7102  size = ff_hevc_annexb2mp4(pb, pkt->data, pkt->size, filter_ps, NULL);
7103  }
7104  }
7105  } else if (par->codec_id == AV_CODEC_ID_VVC && trk->extradata_size[trk->last_stsd_index] > 6 &&
7106  (AV_RB24(trk->extradata[trk->last_stsd_index]) == 1 || AV_RB32(trk->extradata[trk->last_stsd_index]) == 1)) {
7107  /* extradata is Annex B, assume the bitstream is too and convert it */
7108  if (trk->hint_track >= 0 && trk->hint_track < mov->nb_tracks) {
7109  ret = ff_vvc_annexb2mp4_buf(pkt->data, &reformatted_data,
7110  &size, 0, NULL);
7111  if (ret < 0)
7112  return ret;
7113  avio_write(pb, reformatted_data, size);
7114  } else {
7115  size = ff_vvc_annexb2mp4(pb, pkt->data, pkt->size, 0, NULL);
7116  }
7117  } else if (par->codec_id == AV_CODEC_ID_LCEVC && trk->extradata_size[trk->last_stsd_index] > 0 &&
7118  *(uint8_t *)trk->extradata[trk->last_stsd_index] != 1) {
7119  /* extradata is Annex B, assume the bitstream is too and convert it */
7120  if (trk->hint_track >= 0 && trk->hint_track < mov->nb_tracks) {
7121  ret = ff_nal_parse_units_buf(pkt->data, &reformatted_data, &size);
7122  if (ret < 0)
7123  return ret;
7124  avio_write(pb, reformatted_data, size);
7125  } else {
7126  if (trk->cenc.aes_ctr) {
7128  if (size < 0) {
7129  ret = size;
7130  goto err;
7131  }
7132  } else {
7133  size = ff_nal_parse_units(pb, pkt->data, pkt->size);
7134  }
7135  }
7136  } else if (par->codec_id == AV_CODEC_ID_AV1 && !trk->cenc.aes_ctr) {
7137  if (trk->hint_track >= 0 && trk->hint_track < mov->nb_tracks) {
7138  ret = ff_av1_filter_obus_buf(pkt->data, &reformatted_data,
7139  &size, &offset);
7140  if (ret < 0)
7141  return ret;
7142  avio_write(pb, reformatted_data, size);
7143  } else {
7144  size = ff_av1_filter_obus(pb, pkt->data, pkt->size);
7145  if (trk->mode == MODE_AVIF && !mov->avif_extent_length[pkt->stream_index]) {
7147  }
7148  }
7149 
7150  } else if (par->codec_id == AV_CODEC_ID_AC3 ||
7151  par->codec_id == AV_CODEC_ID_EAC3) {
7152  size = handle_eac3(mov, pkt, trk);
7153  if (size < 0)
7154  return size;
7155  else if (!size)
7156  goto end;
7157  avio_write(pb, pkt->data, size);
7158  } else if (par->codec_id == AV_CODEC_ID_EIA_608) {
7159  size = 8;
7160 
7161  for (int i = 0; i < pkt->size; i += 3) {
7162  if (pkt->data[i] == 0xFC) {
7163  size += 2;
7164  }
7165  }
7166  avio_wb32(pb, size);
7167  ffio_wfourcc(pb, "cdat");
7168  for (int i = 0; i < pkt->size; i += 3) {
7169  if (pkt->data[i] == 0xFC) {
7170  avio_w8(pb, pkt->data[i + 1]);
7171  avio_w8(pb, pkt->data[i + 2]);
7172  }
7173  }
7174  } else if (par->codec_id == AV_CODEC_ID_APV) {
7175  ff_isom_parse_apvc(trk->apv, pkt, s);
7176  avio_wb32(s->pb, pkt->size);
7177  size += 4;
7178 
7179  avio_write(s->pb, pkt->data, pkt->size);
7180  } else {
7181  if (trk->cenc.aes_ctr) {
7182  uint8_t *extradata = trk->extradata[trk->last_stsd_index];
7183  int extradata_size = trk->extradata_size[trk->last_stsd_index];
7184  if (par->codec_id == AV_CODEC_ID_H264 && extradata_size > 4) {
7185  int nal_size_length = (extradata[4] & 0x3) + 1;
7186  ret = ff_mov_cenc_avc_write_nal_units(s, &trk->cenc, nal_size_length, pb, pkt->data, size);
7187  } else if(par->codec_id == AV_CODEC_ID_HEVC && extradata_size > 21) {
7188  int nal_size_length = (extradata[21] & 0x3) + 1;
7189  ret = ff_mov_cenc_avc_write_nal_units(s, &trk->cenc, nal_size_length, pb, pkt->data, size);
7190  } else if(par->codec_id == AV_CODEC_ID_VVC) {
7192  } else if(par->codec_id == AV_CODEC_ID_AV1) {
7193  av_assert0(size == pkt->size);
7194  ret = ff_mov_cenc_av1_write_obus(s, &trk->cenc, pb, pkt);
7195  if (ret > 0) {
7196  size = ret;
7197  ret = 0;
7198  }
7199  } else {
7200  ret = ff_mov_cenc_write_packet(&trk->cenc, pb, pkt->data, size);
7201  }
7202 
7203  if (ret) {
7204  goto err;
7205  }
7206  } else {
7207  avio_write(pb, pkt->data, size);
7208  }
7209  }
7210 
7211  if (trk->entry >= trk->cluster_capacity) {
7212  unsigned new_capacity = trk->entry + MOV_INDEX_CLUSTER_SIZE;
7213  void *cluster = av_realloc_array(trk->cluster, new_capacity, sizeof(*trk->cluster));
7214  if (!cluster) {
7215  ret = AVERROR(ENOMEM);
7216  goto err;
7217  }
7218  trk->cluster = cluster;
7219  trk->cluster_capacity = new_capacity;
7220  }
7221 
7222  trk->cluster[trk->entry].pos = avio_tell(pb) - size;
7223  trk->cluster[trk->entry].stsd_index = trk->last_stsd_index;
7224  trk->cluster[trk->entry].samples_in_chunk = samples_in_chunk;
7225  trk->cluster[trk->entry].chunkNum = 0;
7226  trk->cluster[trk->entry].size = size;
7227  trk->cluster[trk->entry].entries = samples_in_chunk;
7228  trk->cluster[trk->entry].dts = pkt->dts;
7229  trk->cluster[trk->entry].pts = pkt->pts;
7230  if (!trk->squash_fragment_samples_to_one &&
7231  !trk->entry && trk->start_dts != AV_NOPTS_VALUE) {
7232  if (!trk->frag_discont) {
7233  /* First packet of a new fragment. We already wrote the duration
7234  * of the last packet of the previous fragment based on track_duration,
7235  * which might not exactly match our dts. Therefore adjust the dts
7236  * of this packet to be what the previous packets duration implies. */
7237  trk->cluster[trk->entry].dts = trk->start_dts + trk->track_duration;
7238  /* We also may have written the pts and the corresponding duration
7239  * in sidx/tfrf/tfxd tags; make sure the sidx pts and duration match up with
7240  * the next fragment. This means the cts of the first sample must
7241  * be the same in all fragments, unless end_pts was updated by
7242  * the packet causing the fragment to be written. */
7243  if ((mov->flags & FF_MOV_FLAG_DASH &&
7245  mov->mode == MODE_ISM)
7246  pkt->pts = pkt->dts + trk->end_pts - trk->cluster[trk->entry].dts;
7247  } else {
7248  /* New fragment, but discontinuous from previous fragments.
7249  * Pretend the duration sum of the earlier fragments is
7250  * pkt->dts - trk->start_dts. */
7251  trk->end_pts = trk->elst_end_pts = AV_NOPTS_VALUE;
7252  trk->frag_discont = 0;
7253  }
7254  }
7255 
7256  if (!trk->entry && trk->start_dts == AV_NOPTS_VALUE && !mov->use_editlist &&
7257  s->avoid_negative_ts == AVFMT_AVOID_NEG_TS_MAKE_ZERO) {
7258  /* Not using edit lists and shifting the first track to start from zero.
7259  * If the other streams start from a later timestamp, we won't be able
7260  * to signal the difference in starting time without an edit list.
7261  * Thus move the timestamp for this first sample to 0, increasing
7262  * its duration instead. */
7263  trk->cluster[trk->entry].dts = trk->start_dts = 0;
7264  }
7265  if (trk->start_dts == AV_NOPTS_VALUE) {
7266  trk->start_dts = pkt->dts;
7267  if (trk->frag_discont) {
7268  if (mov->use_editlist) {
7269  /* Pretend the whole stream started at pts=0, with earlier fragments
7270  * already written. If the stream started at pts=0, the duration sum
7271  * of earlier fragments would have been pkt->pts. */
7272  trk->start_dts = pkt->dts - pkt->pts;
7273  } else {
7274  /* Pretend the whole stream started at dts=0, with earlier fragments
7275  * already written, with a duration summing up to pkt->dts. */
7276  trk->start_dts = 0;
7277  }
7278  trk->frag_discont = 0;
7279  } else if (pkt->dts && mov->moov_written)
7281  "Track %d starts with a nonzero dts %"PRId64", while the moov "
7282  "already has been written. Set the delay_moov flag to handle "
7283  "this case.\n",
7284  pkt->stream_index, pkt->dts);
7285  }
7286  trk->track_duration = pkt->dts - trk->start_dts + pkt->duration;
7287  trk->last_sample_is_subtitle_end = 0;
7288 
7289  if (pkt->pts == AV_NOPTS_VALUE) {
7290  av_log(s, AV_LOG_WARNING, "pts has no value\n");
7291  pkt->pts = pkt->dts;
7292  }
7293  if (pkt->dts != pkt->pts)
7294  trk->flags |= MOV_TRACK_CTTS;
7295  trk->cluster[trk->entry].cts = pkt->pts - pkt->dts;
7296  trk->cluster[trk->entry].flags = 0;
7297  if (trk->start_cts == AV_NOPTS_VALUE || (pkt->dts <= 0 && trk->start_cts > pkt->pts - pkt->dts))
7298  trk->start_cts = pkt->pts - pkt->dts;
7299  if (trk->end_pts == AV_NOPTS_VALUE)
7300  trk->end_pts = trk->cluster[trk->entry].dts +
7301  trk->cluster[trk->entry].cts + pkt->duration;
7302  else
7303  trk->end_pts = FFMAX(trk->end_pts, trk->cluster[trk->entry].dts +
7304  trk->cluster[trk->entry].cts +
7305  pkt->duration);
7306  if (!(pkt->flags & AV_PKT_FLAG_DISCARD))
7307  trk->elst_end_pts = trk->end_pts;
7308 
7309  if (par->codec_id == AV_CODEC_ID_VC1) {
7310  mov_parse_vc1_frame(pkt, trk);
7311  } else if (par->codec_id == AV_CODEC_ID_TRUEHD) {
7313  } else if (pkt->flags & AV_PKT_FLAG_KEY) {
7314  if (mov->mode == MODE_MOV && par->codec_id == AV_CODEC_ID_MPEG2VIDEO &&
7315  trk->entry > 0) { // force sync sample for the first key frame
7317  if (trk->cluster[trk->entry].flags & MOV_PARTIAL_SYNC_SAMPLE)
7318  trk->flags |= MOV_TRACK_STPS;
7319  } else {
7320  trk->cluster[trk->entry].flags = MOV_SYNC_SAMPLE;
7321  }
7322  if (trk->cluster[trk->entry].flags & MOV_SYNC_SAMPLE)
7323  trk->has_keyframes++;
7324  }
7325  if (pkt->flags & AV_PKT_FLAG_DISPOSABLE) {
7326  trk->cluster[trk->entry].flags |= MOV_DISPOSABLE_SAMPLE;
7327  trk->has_disposable++;
7328  }
7329 
7331  if (prft && prft_size == sizeof(AVProducerReferenceTime))
7332  memcpy(&trk->cluster[trk->entry].prft, prft, prft_size);
7333  else
7334  memset(&trk->cluster[trk->entry].prft, 0, sizeof(AVProducerReferenceTime));
7335 
7336  trk->entry++;
7337  trk->sample_count += samples_in_chunk;
7338  mov->mdat_size += size;
7339 
7340  if (trk->hint_track >= 0 && trk->hint_track < mov->nb_tracks)
7342  reformatted_data ? reformatted_data + offset
7343  : NULL, size);
7344 
7345 end:
7346 err:
7347 
7348  if (pkt->data != reformatted_data)
7349  av_free(reformatted_data);
7350  return ret;
7351 }
7352 
7354 {
7355  MOVMuxContext *mov = s->priv_data;
7356  MOVTrack *trk = s->streams[pkt->stream_index]->priv_data;
7357  AVCodecParameters *par = trk->par;
7358  int64_t frag_duration = 0;
7359  int size = pkt->size;
7360 
7361  int ret = check_pkt(s, trk, pkt);
7362  if (ret < 0)
7363  return ret;
7364 
7365  if (mov->flags & FF_MOV_FLAG_FRAG_DISCONT) {
7366  for (int i = 0; i < mov->nb_streams; i++)
7367  mov->tracks[i].frag_discont = 1;
7369  }
7370 
7372  if (trk->dts_shift == AV_NOPTS_VALUE)
7373  trk->dts_shift = pkt->pts - pkt->dts;
7374  pkt->dts += trk->dts_shift;
7375  }
7376 
7377  if (trk->par->codec_id == AV_CODEC_ID_MP4ALS ||
7378  trk->par->codec_id == AV_CODEC_ID_AAC ||
7379  trk->par->codec_id == AV_CODEC_ID_AV1 ||
7380  trk->par->codec_id == AV_CODEC_ID_FLAC) {
7381  size_t side_size;
7382  uint8_t *side = av_packet_get_side_data(pkt, AV_PKT_DATA_NEW_EXTRADATA, &side_size);
7383  /* Overwrite extradata only on flush packets or when no extradata was available during init */
7384  if (side_size > 0 && (!pkt->size || !trk->extradata_size[trk->last_stsd_index])) {
7385  void *newextra = av_malloc(side_size + AV_INPUT_BUFFER_PADDING_SIZE);
7386  if (!newextra)
7387  return AVERROR(ENOMEM);
7388  memset((uint8_t*)newextra + side_size, 0, AV_INPUT_BUFFER_PADDING_SIZE);
7389  memcpy(newextra, side, side_size);
7390  av_free(trk->extradata[trk->last_stsd_index]);
7391  trk->extradata[trk->last_stsd_index] = newextra;
7392  trk->extradata_size[trk->last_stsd_index] = side_size;
7393  }
7394  }
7395 
7396  if (!pkt->size) {
7397  if (trk->start_dts == AV_NOPTS_VALUE && trk->frag_discont) {
7398  trk->start_dts = pkt->dts;
7399  if (pkt->pts != AV_NOPTS_VALUE)
7400  trk->start_cts = pkt->pts - pkt->dts;
7401  else
7402  trk->start_cts = 0;
7403  }
7404 
7405  return 0; /* Discard 0 sized packets */
7406  }
7407 
7408  if (trk->entry && pkt->stream_index < mov->nb_streams)
7409  frag_duration = av_rescale_q(pkt->dts - trk->cluster[0].dts,
7410  s->streams[pkt->stream_index]->time_base,
7411  AV_TIME_BASE_Q);
7412  if ((mov->max_fragment_duration &&
7413  frag_duration >= mov->max_fragment_duration) ||
7414  (mov->max_fragment_size && mov->mdat_size + size >= mov->max_fragment_size) ||
7415  (mov->flags & FF_MOV_FLAG_FRAG_KEYFRAME &&
7416  par->codec_type == AVMEDIA_TYPE_VIDEO &&
7417  trk->entry && pkt->flags & AV_PKT_FLAG_KEY) ||
7419  if (frag_duration >= mov->min_fragment_duration) {
7420  if (trk->entry) {
7421  // Set the duration of this track to line up with the next
7422  // sample in this track. This avoids relying on AVPacket
7423  // duration, but only helps for this particular track, not
7424  // for the other ones that are flushed at the same time.
7425  //
7426  // If we have trk->entry == 0, no fragment will be written
7427  // for this track, and we can't adjust the track end here.
7428  trk->track_duration = pkt->dts - trk->start_dts;
7429  if (pkt->pts != AV_NOPTS_VALUE)
7430  trk->end_pts = pkt->pts;
7431  else
7432  trk->end_pts = pkt->dts;
7433  if (!(pkt->flags & AV_PKT_FLAG_DISCARD))
7434  trk->elst_end_pts = trk->end_pts;
7435  trk->end_reliable = 1;
7436  }
7438  }
7439  }
7440 
7441  return ff_mov_write_packet(s, pkt);
7442 }
7443 
7445  int stream_index,
7446  int64_t dts) {
7447  MOVMuxContext *mov = s->priv_data;
7448  AVPacket *end = mov->pkt;
7449  uint8_t data[2] = {0};
7450  int ret;
7451 
7452  end->size = sizeof(data);
7453  end->data = data;
7454  end->pts = dts;
7455  end->dts = dts;
7456  end->duration = 0;
7457  end->stream_index = stream_index;
7458 
7459  ret = mov_write_single_packet(s, end);
7460  av_packet_unref(end);
7461 
7462  return ret;
7463 }
7464 
7465 #if CONFIG_IAMFENC
7466 static int mov_build_iamf_packet(AVFormatContext *s, MOVTrack *trk, AVPacket *pkt)
7467 {
7468  uint8_t *data;
7469  int ret;
7470 
7471  if (pkt->stream_index == trk->first_iamf_idx) {
7473  if (ret < 0)
7474  return ret;
7475  }
7476 
7478  s->streams[pkt->stream_index]->id, pkt);
7479  if (ret < 0)
7480  return ret;
7481 
7482  if (pkt->stream_index != trk->last_iamf_idx)
7483  return AVERROR(EAGAIN);
7484 
7485  ret = avio_close_dyn_buf(trk->iamf_buf, &data);
7486  trk->iamf_buf = NULL;
7487  if (!ret) {
7488  if (pkt->size) {
7489  // Either all or none of the packets for a single
7490  // IA Sample may be empty.
7491  av_log(s, AV_LOG_ERROR, "Unexpected packet from "
7492  "stream #%d\n", pkt->stream_index);
7494  }
7495  av_free(data);
7496  return ret;
7497  }
7498 
7499  av_buffer_unref(&pkt->buf);
7500  pkt->buf = av_buffer_create(data, ret, NULL, NULL, 0);
7501  if (!pkt->buf) {
7502  av_free(data);
7503  return AVERROR(ENOMEM);
7504  }
7505  pkt->data = data;
7506  pkt->size = ret;
7508 
7509  return avio_open_dyn_buf(&trk->iamf_buf);
7510 }
7511 #endif
7512 
7514 {
7515  int64_t pos = avio_tell(pb);
7516  const char *scheme_id_uri = "https://aomedia.org/emsg/ID3";
7517  const char *value = "";
7518 
7519  av_assert0(st->time_base.num == 1);
7520 
7521  avio_write_marker(pb,
7524 
7525  avio_wb32(pb, 0); /* size */
7526  ffio_wfourcc(pb, "emsg");
7527  avio_w8(pb, 1); /* version */
7528  avio_wb24(pb, 0);
7529  avio_wb32(pb, st->time_base.den); /* timescale */
7530  avio_wb64(pb, pkt->pts); /* presentation_time */
7531  avio_wb32(pb, 0xFFFFFFFFU); /* event_duration */
7532  avio_wb32(pb, 0); /* id */
7533  /* null terminated UTF8 strings */
7534  avio_write(pb, scheme_id_uri, strlen(scheme_id_uri) + 1);
7535  avio_write(pb, value, strlen(value) + 1);
7536  avio_write(pb, pkt->data, pkt->size);
7537 
7538  return update_size(pb, pos);
7539 }
7540 
7542 {
7543  MOVMuxContext *mov = s->priv_data;
7544  MOVTrack *trk;
7545 
7546  if (!pkt) {
7547  mov_flush_fragment(s, 1);
7548  return 1;
7549  }
7550 
7551  if (s->streams[pkt->stream_index]->codecpar->codec_id == AV_CODEC_ID_TIMED_ID3) {
7552  mov_write_emsg_tag(s->pb, s->streams[pkt->stream_index], pkt);
7553  return 0;
7554  }
7555 
7556  trk = s->streams[pkt->stream_index]->priv_data;
7557 
7558 #if CONFIG_IAMFENC
7559  if (trk->iamf) {
7560  int ret = mov_build_iamf_packet(s, trk, pkt);
7561  if (ret < 0) {
7562  if (ret == AVERROR(EAGAIN))
7563  return 0;
7564  av_log(s, AV_LOG_ERROR, "Error assembling an IAMF packet "
7565  "for stream #%d\n", trk->st->index);
7566  return ret;
7567  }
7568  }
7569 #endif
7570 
7571  if (is_cover_image(trk->st)) {
7572  int ret;
7573 
7574  if (trk->st->nb_frames >= 1) {
7575  if (trk->st->nb_frames == 1)
7576  av_log(s, AV_LOG_WARNING, "Got more than one picture in stream %d,"
7577  " ignoring.\n", pkt->stream_index);
7578  return 0;
7579  }
7580 
7581  if ((ret = av_packet_ref(trk->cover_image, pkt)) < 0)
7582  return ret;
7583 
7584  return 0;
7585  } else {
7586  int i;
7587 
7588  if (!pkt->size)
7589  return mov_write_single_packet(s, pkt); /* Passthrough. */
7590 
7591  /*
7592  * Subtitles require special handling.
7593  *
7594  * 1) For full compliance, every track must have a sample at
7595  * dts == 0, which is rarely true for subtitles. So, as soon
7596  * as we see any packet with dts > 0, write an empty subtitle
7597  * at dts == 0 for any subtitle track with no samples in it.
7598  *
7599  * 2) For each subtitle track, check if the current packet's
7600  * dts is past the duration of the last subtitle sample. If
7601  * so, we now need to write an end sample for that subtitle.
7602  *
7603  * This must be done conditionally to allow for subtitles that
7604  * immediately replace each other, in which case an end sample
7605  * is not needed, and is, in fact, actively harmful.
7606  *
7607  * 3) See mov_write_trailer for how the final end sample is
7608  * handled.
7609  */
7610  for (i = 0; i < mov->nb_tracks; i++) {
7611  MOVTrack *trk = &mov->tracks[i];
7612  int ret;
7613 
7614  if (trk->par->codec_id == AV_CODEC_ID_MOV_TEXT &&
7615  trk->track_duration < pkt->dts &&
7616  (trk->entry == 0 || !trk->last_sample_is_subtitle_end)) {
7618  if (ret < 0) return ret;
7619  trk->last_sample_is_subtitle_end = 1;
7620  }
7621  }
7622 
7623  if (trk->squash_fragment_samples_to_one) {
7624  /*
7625  * If the track has to have its samples squashed into one sample,
7626  * we just take it into the track's queue.
7627  * This will then be utilized as the samples get written in either
7628  * mov_flush_fragment or when the mux is finalized in
7629  * mov_write_trailer.
7630  */
7631  int ret = AVERROR_BUG;
7632 
7633  if (pkt->pts == AV_NOPTS_VALUE) {
7635  "Packets without a valid presentation timestamp are "
7636  "not supported with packet squashing!\n");
7637  return AVERROR(EINVAL);
7638  }
7639 
7640  /* The following will reset pkt and is only allowed to be used
7641  * because we return immediately. afterwards. */
7643  pkt, NULL, 0)) < 0) {
7644  return ret;
7645  }
7646 
7647  return 0;
7648  }
7649 
7650 
7651  if (trk->mode == MODE_MOV && trk->par->codec_type == AVMEDIA_TYPE_VIDEO) {
7652  AVPacket *opkt = pkt;
7653  int reshuffle_ret, ret;
7654  if (trk->is_unaligned_qt_rgb) {
7655  int64_t bpc = trk->par->bits_per_coded_sample != 15 ? trk->par->bits_per_coded_sample : 16;
7656  int expected_stride = ((trk->par->width * bpc + 15) >> 4)*2;
7657  reshuffle_ret = ff_reshuffle_raw_rgb(s, &pkt, trk->par, expected_stride);
7658  if (reshuffle_ret < 0)
7659  return reshuffle_ret;
7660  } else
7661  reshuffle_ret = 0;
7662  if (trk->par->format == AV_PIX_FMT_PAL8 && !trk->pal_done) {
7663  ret = ff_get_packet_palette(s, opkt, reshuffle_ret, trk->palette);
7664  if (ret < 0)
7665  goto fail;
7666  if (ret)
7667  trk->pal_done++;
7668  } else if (trk->par->codec_id == AV_CODEC_ID_RAWVIDEO &&
7669  (trk->par->format == AV_PIX_FMT_GRAY8 ||
7670  trk->par->format == AV_PIX_FMT_MONOBLACK)) {
7672  if (ret < 0)
7673  goto fail;
7674  for (i = 0; i < pkt->size; i++)
7675  pkt->data[i] = ~pkt->data[i];
7676  }
7677  if (reshuffle_ret) {
7679 fail:
7680  if (reshuffle_ret)
7681  av_packet_free(&pkt);
7682  return ret;
7683  }
7684  }
7685 
7686  return mov_write_single_packet(s, pkt);
7687  }
7688 }
7689 
7690 // QuickTime chapters involve an additional text track with the chapter names
7691 // as samples, and a tref pointing from the other tracks to the chapter one.
7692 static int mov_create_chapter_track(AVFormatContext *s, int tracknum)
7693 {
7694  static const uint8_t stub_header[] = {
7695  // TextSampleEntry
7696  0x00, 0x00, 0x00, 0x01, // displayFlags
7697  0x00, 0x00, // horizontal + vertical justification
7698  0x00, 0x00, 0x00, 0x00, // bgColourRed/Green/Blue/Alpha
7699  // BoxRecord
7700  0x00, 0x00, 0x00, 0x00, // defTextBoxTop/Left
7701  0x00, 0x00, 0x00, 0x00, // defTextBoxBottom/Right
7702  // StyleRecord
7703  0x00, 0x00, 0x00, 0x00, // startChar + endChar
7704  0x00, 0x01, // fontID
7705  0x00, 0x00, // fontStyleFlags + fontSize
7706  0x00, 0x00, 0x00, 0x00, // fgColourRed/Green/Blue/Alpha
7707  // FontTableBox
7708  0x00, 0x00, 0x00, 0x0D, // box size
7709  'f', 't', 'a', 'b', // box atom name
7710  0x00, 0x01, // entry count
7711  // FontRecord
7712  0x00, 0x01, // font ID
7713  0x00, // font name length
7714  };
7715  MOVMuxContext *mov = s->priv_data;
7716  MOVTrack *track = &mov->tracks[tracknum];
7717  AVPacket *pkt = mov->pkt;
7718  int i, len;
7719  int ret;
7720 
7721  track->mode = mov->mode;
7722  track->tag = MKTAG('t','e','x','t');
7723  track->timescale = mov->movie_timescale;
7724  track->par = avcodec_parameters_alloc();
7725  if (!track->par)
7726  return AVERROR(ENOMEM);
7728  ret = ff_alloc_extradata(track->par, sizeof(stub_header));
7729  if (ret < 0)
7730  return ret;
7731  memcpy(track->par->extradata, stub_header, sizeof(stub_header));
7732 
7733  if (track->extradata == NULL) {
7734  track->stsd_count = 1;
7735  track->extradata = av_calloc(1, sizeof(*track->extradata));
7736  track->extradata_size = av_calloc(1, sizeof(*track->extradata_size));
7737  if (!track->extradata || !track->extradata_size)
7738  return AVERROR(ENOMEM);
7739  }
7740 
7741  track->extradata[0] = av_memdup(stub_header, sizeof(stub_header));
7742  if (!track->extradata[0])
7743  return AVERROR(ENOMEM);
7744  track->extradata_size[0] = sizeof(stub_header);
7745 
7746  pkt->stream_index = tracknum;
7748 
7749  for (i = 0; i < s->nb_chapters; i++) {
7750  AVChapter *c = s->chapters[i];
7751  AVDictionaryEntry *t;
7752 
7753  int64_t end = av_rescale_q(c->end, c->time_base, (AVRational){1,mov->movie_timescale});
7754  pkt->pts = pkt->dts = av_rescale_q(c->start, c->time_base, (AVRational){1,mov->movie_timescale});
7755  pkt->duration = end - pkt->dts;
7756 
7757  if ((t = av_dict_get(c->metadata, "title", NULL, 0))) {
7758  static const char encd[12] = {
7759  0x00, 0x00, 0x00, 0x0C,
7760  'e', 'n', 'c', 'd',
7761  0x00, 0x00, 0x01, 0x00 };
7762  len = strlen(t->value);
7763  pkt->size = len + 2 + 12;
7764  pkt->data = av_malloc(pkt->size);
7765  if (!pkt->data) {
7767  return AVERROR(ENOMEM);
7768  }
7769  AV_WB16(pkt->data, len);
7770  memcpy(pkt->data + 2, t->value, len);
7771  memcpy(pkt->data + len + 2, encd, sizeof(encd));
7773  av_freep(&pkt->data);
7774  }
7775  }
7776 
7777  av_packet_unref(mov->pkt);
7778 
7779  return 0;
7780 }
7781 
7782 
7783 static int mov_check_timecode_track(AVFormatContext *s, AVTimecode *tc, AVStream *src_st, const char *tcstr)
7784 {
7785  int ret;
7786 
7787  /* compute the frame number */
7788  ret = av_timecode_init_from_string(tc, src_st->avg_frame_rate, tcstr, s);
7789  return ret;
7790 }
7791 
7792 static int mov_create_timecode_track(AVFormatContext *s, int index, int src_index, AVTimecode tc)
7793 {
7794  MOVMuxContext *mov = s->priv_data;
7795  MOVTrack *track = &mov->tracks[index];
7796  AVStream *src_st = mov->tracks[src_index].st;
7797  uint8_t data[4];
7798  AVPacket *pkt = mov->pkt;
7799  AVRational rate = src_st->avg_frame_rate;
7800  int ret;
7801 
7802  /* tmcd track based on video stream */
7803  track->mode = mov->mode;
7804  track->tag = MKTAG('t','m','c','d');
7805  track->src_track = av_malloc(sizeof(*track->src_track));
7806  if (!track->src_track)
7807  return AVERROR(ENOMEM);
7808  *track->src_track = src_index;
7809  track->nb_src_track = 1;
7810  track->timescale = mov->tracks[src_index].timescale;
7813 
7814  /* set st to src_st for metadata access*/
7815  track->st = src_st;
7816 
7817  /* encode context: tmcd data stream */
7818  track->par = avcodec_parameters_alloc();
7819  if (!track->par)
7820  return AVERROR(ENOMEM);
7821  track->par->codec_type = AVMEDIA_TYPE_DATA;
7822  track->par->codec_tag = track->tag;
7823  track->st->avg_frame_rate = rate;
7824 
7825  /* the tmcd track just contains one packet with the frame number */
7826  pkt->data = data;
7827  pkt->stream_index = index;
7829  pkt->pts = pkt->dts = av_rescale_q(tc.start, av_inv_q(rate), (AVRational){1,mov->movie_timescale});
7830  pkt->size = 4;
7831  AV_WB32(pkt->data, tc.start);
7834  return ret;
7835 }
7836 
7837 /*
7838  * st->disposition controls the "enabled" flag in the tkhd tag.
7839  * QuickTime will not play a track if it is not enabled. So make sure
7840  * that one track of each type (audio, video, subtitle) is enabled.
7841  *
7842  * Subtitles are special. For audio and video, setting "enabled" also
7843  * makes the track "default" (i.e. it is rendered when played). For
7844  * subtitles, an "enabled" subtitle is not rendered by default, but
7845  * if no subtitle is enabled, the subtitle menu in QuickTime will be
7846  * empty!
7847  */
7849 {
7850  MOVMuxContext *mov = s->priv_data;
7851  int i;
7852  int enabled[AVMEDIA_TYPE_NB];
7853  int first[AVMEDIA_TYPE_NB];
7854 
7855  for (i = 0; i < AVMEDIA_TYPE_NB; i++) {
7856  enabled[i] = 0;
7857  first[i] = -1;
7858  }
7859 
7860  for (i = 0; i < mov->nb_streams; i++) {
7861  AVStream *st = mov->tracks[i].st;
7862 
7865  is_cover_image(st))
7866  continue;
7867 
7868  if (first[st->codecpar->codec_type] < 0)
7869  first[st->codecpar->codec_type] = i;
7870  if (st->disposition & AV_DISPOSITION_DEFAULT) {
7871  mov->tracks[i].flags |= MOV_TRACK_ENABLED;
7872  enabled[st->codecpar->codec_type]++;
7873  }
7874  }
7875 
7876  for (i = 0; i < AVMEDIA_TYPE_NB; i++) {
7877  switch (i) {
7878  case AVMEDIA_TYPE_VIDEO:
7879  case AVMEDIA_TYPE_AUDIO:
7880  case AVMEDIA_TYPE_SUBTITLE:
7881  if (enabled[i] > 1)
7882  mov->per_stream_grouping = 1;
7883  if (!enabled[i] && first[i] >= 0)
7884  mov->tracks[first[i]].flags |= MOV_TRACK_ENABLED;
7885  break;
7886  }
7887  }
7888 }
7889 
7891 {
7892  MOVMuxContext *mov = s->priv_data;
7893 
7894  for (int i = 0; i < s->nb_streams; i++)
7895  s->streams[i]->priv_data = NULL;
7896 
7897  if (!mov->tracks)
7898  return;
7899 
7900  if (mov->chapter_track) {
7902  }
7903 
7904  for (int i = 0; i < mov->nb_tracks; i++) {
7905  MOVTrack *const track = &mov->tracks[i];
7906 
7907  if (track->tag == MKTAG('r','t','p',' '))
7908  ff_mov_close_hinting(track);
7909  else if (track->tag == MKTAG('t','m','c','d') && mov->nb_meta_tmcd)
7910  av_freep(&track->par);
7911  av_freep(&track->cluster);
7912  av_freep(&track->cluster_written);
7913  av_freep(&track->frag_info);
7914  av_packet_free(&track->cover_image);
7915 
7916  if (track->eac3_priv) {
7917  struct eac3_info *info = track->eac3_priv;
7918  av_packet_free(&info->pkt);
7919  av_freep(&track->eac3_priv);
7920  }
7921  for (int j = 0; j < track->stsd_count; j++)
7922  av_freep(&track->extradata[j]);
7923  av_freep(&track->extradata);
7924  av_freep(&track->extradata_size);
7925 
7926  for (int i = 0; i < track->nb_tref_tags; i++)
7927  av_freep(&track->tref_tags[i].id);
7928  av_freep(&track->tref_tags);
7929  av_freep(&track->src_track);
7930 
7931  ff_mov_cenc_free(&track->cenc);
7932  ffio_free_dyn_buf(&track->mdat_buf);
7933 
7934 #if CONFIG_IAMFENC
7935  ffio_free_dyn_buf(&track->iamf_buf);
7936  if (track->iamf)
7937  ff_iamf_uninit_context(track->iamf);
7938  av_freep(&track->iamf);
7939 #endif
7940  ff_isom_close_apvc(&track->apv);
7941 
7943  }
7944 
7945  av_freep(&mov->tracks);
7946  ffio_free_dyn_buf(&mov->mdat_buf);
7947 }
7948 
7949 static uint32_t rgb_to_yuv(uint32_t rgb)
7950 {
7951  uint8_t r, g, b;
7952  int y, cb, cr;
7953 
7954  r = (rgb >> 16) & 0xFF;
7955  g = (rgb >> 8) & 0xFF;
7956  b = (rgb ) & 0xFF;
7957 
7958  y = av_clip_uint8(( 16000 + 257 * r + 504 * g + 98 * b)/1000);
7959  cb = av_clip_uint8((128000 - 148 * r - 291 * g + 439 * b)/1000);
7960  cr = av_clip_uint8((128000 + 439 * r - 368 * g - 71 * b)/1000);
7961 
7962  return (y << 16) | (cr << 8) | cb;
7963 }
7964 
7966  AVStream *st)
7967 {
7968  int i, width = 720, height = 480;
7969  int have_palette = 0, have_size = 0;
7970  uint32_t palette[16];
7971  char *cur = st->codecpar->extradata;
7972 
7973  while (cur && *cur) {
7974  if (strncmp("palette:", cur, 8) == 0) {
7975  int i, count;
7976  count = sscanf(cur + 8,
7977  "%06"PRIx32", %06"PRIx32", %06"PRIx32", %06"PRIx32", "
7978  "%06"PRIx32", %06"PRIx32", %06"PRIx32", %06"PRIx32", "
7979  "%06"PRIx32", %06"PRIx32", %06"PRIx32", %06"PRIx32", "
7980  "%06"PRIx32", %06"PRIx32", %06"PRIx32", %06"PRIx32"",
7981  &palette[ 0], &palette[ 1], &palette[ 2], &palette[ 3],
7982  &palette[ 4], &palette[ 5], &palette[ 6], &palette[ 7],
7983  &palette[ 8], &palette[ 9], &palette[10], &palette[11],
7984  &palette[12], &palette[13], &palette[14], &palette[15]);
7985 
7986  for (i = 0; i < count; i++) {
7987  palette[i] = rgb_to_yuv(palette[i]);
7988  }
7989  have_palette = 1;
7990  } else if (!strncmp("size:", cur, 5)) {
7991  sscanf(cur + 5, "%dx%d", &width, &height);
7992  have_size = 1;
7993  }
7994  if (have_palette && have_size)
7995  break;
7996  cur += strcspn(cur, "\n\r");
7997  cur += strspn(cur, "\n\r");
7998  }
7999  if (have_palette) {
8001  if (!track->extradata[track->last_stsd_index])
8002  return AVERROR(ENOMEM);
8003  for (i = 0; i < 16; i++) {
8004  AV_WB32(track->extradata[track->last_stsd_index] + i * 4, palette[i]);
8005  }
8006  memset(track->extradata[track->last_stsd_index] + 16*4, 0, AV_INPUT_BUFFER_PADDING_SIZE);
8007  track->extradata_size[track->last_stsd_index] = 16 * 4;
8008  }
8009  st->codecpar->width = width;
8010  st->codecpar->height = track->height = height;
8011 
8012  return 0;
8013 }
8014 
8015 #if CONFIG_IAMFENC
8016 static int mov_init_iamf_track(AVFormatContext *s)
8017 {
8018  MOVMuxContext *mov = s->priv_data;
8019  MOVTrack *track;
8020  IAMFContext *iamf;
8021  int first_iamf_idx = INT_MAX, last_iamf_idx = 0;
8022  int nb_audio_elements = 0, nb_mix_presentations = 0;
8023  int ret;
8024 
8025  for (int i = 0; i < s->nb_stream_groups; i++) {
8026  const AVStreamGroup *stg = s->stream_groups[i];
8027 
8029  nb_audio_elements++;
8031  nb_mix_presentations++;
8032  }
8033 
8034  if (!nb_audio_elements && !nb_mix_presentations)
8035  return 0;
8036 
8037  if (nb_audio_elements < 1 || nb_audio_elements > 2 || nb_mix_presentations < 1) {
8038  av_log(s, AV_LOG_ERROR, "There must be >= 1 and <= 2 IAMF_AUDIO_ELEMENT and at least "
8039  "one IAMF_MIX_PRESENTATION stream groups to write a IMAF track\n");
8040  return AVERROR(EINVAL);
8041  }
8042 
8043  iamf = av_mallocz(sizeof(*iamf));
8044  if (!iamf)
8045  return AVERROR(ENOMEM);
8046 
8047 
8048  for (int i = 0; i < s->nb_stream_groups; i++) {
8049  const AVStreamGroup *stg = s->stream_groups[i];
8050  switch(stg->type) {
8052  for (int j = 0; j < stg->nb_streams; j++) {
8053  first_iamf_idx = FFMIN(stg->streams[j]->index, first_iamf_idx);
8054  last_iamf_idx = FFMAX(stg->streams[j]->index, last_iamf_idx);
8055  }
8056 
8057  ret = ff_iamf_add_audio_element(iamf, stg, s);
8058  break;
8060  ret = ff_iamf_add_mix_presentation(iamf, stg, s);
8061  break;
8062  default:
8063  av_assert0(0);
8064  }
8065  if (ret < 0) {
8066  ff_iamf_uninit_context(iamf);
8067  av_free(iamf);
8068  return ret;
8069  }
8070  }
8071 
8072  track = &mov->tracks[first_iamf_idx];
8073  track->iamf = iamf;
8074  track->first_iamf_idx = first_iamf_idx;
8075  track->last_iamf_idx = last_iamf_idx;
8076  track->tag = MKTAG('i','a','m','f');
8077 
8078  for (int i = 0; i < s->nb_stream_groups; i++) {
8079  AVStreamGroup *stg = s->stream_groups[i];
8081  continue;
8082  for (int j = 0; j < stg->nb_streams; j++)
8083  stg->streams[j]->priv_data = track;
8084  }
8085 
8086  ret = avio_open_dyn_buf(&track->iamf_buf);
8087  if (ret < 0)
8088  return ret;
8089 
8090  return 0;
8091 }
8092 #endif
8093 
8095 {
8096  MOVMuxContext *mov = s->priv_data;
8097  int has_iamf = 0;
8098  int i, ret;
8099 
8100  mov->fc = s;
8101  mov->pkt = ffformatcontext(s)->pkt;
8102 
8103  /* Default mode == MP4 */
8104  mov->mode = MODE_MP4;
8105 
8106 #define IS_MODE(muxer, config) (CONFIG_ ## config ## _MUXER && !strcmp(#muxer, s->oformat->name))
8107  if (IS_MODE(3gp, TGP)) mov->mode = MODE_3GP;
8108  else if (IS_MODE(3g2, TG2)) mov->mode = MODE_3GP|MODE_3G2;
8109  else if (IS_MODE(mov, MOV)) mov->mode = MODE_MOV;
8110  else if (IS_MODE(psp, PSP)) mov->mode = MODE_PSP;
8111  else if (IS_MODE(ipod, IPOD)) mov->mode = MODE_IPOD;
8112  else if (IS_MODE(ismv, ISMV)) mov->mode = MODE_ISM;
8113  else if (IS_MODE(f4v, F4V)) mov->mode = MODE_F4V;
8114  else if (IS_MODE(avif, AVIF)) mov->mode = MODE_AVIF;
8115 #undef IS_MODE
8116 
8117  if (mov->flags & FF_MOV_FLAG_DELAY_MOOV)
8118  mov->flags |= FF_MOV_FLAG_EMPTY_MOOV;
8119 
8120  if (mov->mode == MODE_AVIF)
8121  mov->flags |= FF_MOV_FLAG_DELAY_MOOV;
8122 
8123  /* Set the FRAGMENT flag if any of the fragmentation methods are
8124  * enabled. */
8125  if (mov->max_fragment_duration || mov->max_fragment_size ||
8126  mov->flags & (FF_MOV_FLAG_EMPTY_MOOV |
8130  mov->flags |= FF_MOV_FLAG_FRAGMENT;
8131 
8132  if (mov->flags & FF_MOV_FLAG_HYBRID_FRAGMENTED &&
8133  mov->flags & FF_MOV_FLAG_FASTSTART) {
8134  av_log(s, AV_LOG_ERROR, "Setting both hybrid_fragmented and faststart is not supported.\n");
8135  return AVERROR(EINVAL);
8136  }
8137 
8138  /* Set other implicit flags immediately */
8140  mov->flags |= FF_MOV_FLAG_FRAGMENT;
8141 
8142  if (mov->mode == MODE_ISM)
8145  if (mov->flags & FF_MOV_FLAG_DASH)
8148  if (mov->flags & FF_MOV_FLAG_CMAF)
8151 
8152  if (mov->flags & FF_MOV_FLAG_EMPTY_MOOV && s->flags & AVFMT_FLAG_AUTO_BSF) {
8153  av_log(s, AV_LOG_VERBOSE, "Empty MOOV enabled; disabling automatic bitstream filtering\n");
8154  s->flags &= ~AVFMT_FLAG_AUTO_BSF;
8155  }
8156 
8158  av_log(s, AV_LOG_WARNING, "Global SIDX enabled; Ignoring skip_sidx option\n");
8159  mov->flags &= ~FF_MOV_FLAG_SKIP_SIDX;
8160  }
8161 
8162  if (mov->flags & FF_MOV_FLAG_FASTSTART) {
8163  mov->reserved_moov_size = -1;
8164  }
8165 
8166  if (mov->use_editlist < 0) {
8167  mov->use_editlist = 1;
8168  if (mov->flags & FF_MOV_FLAG_FRAGMENT &&
8169  !(mov->flags & FF_MOV_FLAG_DELAY_MOOV)) {
8170  // If we can avoid needing an edit list by shifting the
8171  // tracks, prefer that over (trying to) write edit lists
8172  // in fragmented output.
8173  if (s->avoid_negative_ts == AVFMT_AVOID_NEG_TS_AUTO ||
8174  s->avoid_negative_ts == AVFMT_AVOID_NEG_TS_MAKE_ZERO)
8175  mov->use_editlist = 0;
8176  }
8177  }
8178  if (mov->flags & FF_MOV_FLAG_EMPTY_MOOV &&
8179  !(mov->flags & FF_MOV_FLAG_DELAY_MOOV) && mov->use_editlist)
8180  av_log(s, AV_LOG_WARNING, "No meaningful edit list will be written when using empty_moov without delay_moov\n");
8181 
8182  if (!mov->use_editlist && s->avoid_negative_ts == AVFMT_AVOID_NEG_TS_AUTO &&
8184  s->avoid_negative_ts = AVFMT_AVOID_NEG_TS_MAKE_ZERO;
8185 
8186  /* Clear the omit_tfhd_offset flag if default_base_moof is set;
8187  * if the latter is set that's enough and omit_tfhd_offset doesn't
8188  * add anything extra on top of that. */
8189  if (mov->flags & FF_MOV_FLAG_OMIT_TFHD_OFFSET &&
8192 
8193  if (mov->frag_interleave &&
8196  "Sample interleaving in fragments is mutually exclusive with "
8197  "omit_tfhd_offset and separate_moof\n");
8198  return AVERROR(EINVAL);
8199  }
8200 
8201  /* Non-seekable output is ok if using fragmentation. If ism_lookahead
8202  * is enabled, we don't support non-seekable output at all. */
8203  if (!(s->pb->seekable & AVIO_SEEKABLE_NORMAL) &&
8204  (!(mov->flags & FF_MOV_FLAG_FRAGMENT) || mov->ism_lookahead ||
8205  mov->mode == MODE_AVIF)) {
8206  av_log(s, AV_LOG_ERROR, "muxer does not support non seekable output\n");
8207  return AVERROR(EINVAL);
8208  }
8209 
8210  /* AVIF output must have at most two video streams (one for YUV and one for
8211  * alpha). */
8212  if (mov->mode == MODE_AVIF) {
8213  if (s->nb_streams > 2) {
8214  av_log(s, AV_LOG_ERROR, "AVIF output requires exactly one or two streams\n");
8215  return AVERROR(EINVAL);
8216  }
8217  if (s->streams[0]->codecpar->codec_type != AVMEDIA_TYPE_VIDEO &&
8218  (s->nb_streams > 1 && s->streams[1]->codecpar->codec_type != AVMEDIA_TYPE_VIDEO)) {
8219  av_log(s, AV_LOG_ERROR, "AVIF output supports only video streams\n");
8220  return AVERROR(EINVAL);
8221  }
8222  if (s->nb_streams > 1) {
8223  const AVPixFmtDescriptor *pixdesc =
8224  av_pix_fmt_desc_get(s->streams[1]->codecpar->format);
8225  if (pixdesc->nb_components != 1) {
8226  av_log(s, AV_LOG_ERROR, "Second stream for AVIF (alpha) output must have exactly one plane\n");
8227  return AVERROR(EINVAL);
8228  }
8229  }
8230  s->streams[0]->disposition |= AV_DISPOSITION_DEFAULT;
8231  }
8232 
8233  for (i = 0; i < s->nb_stream_groups; i++) {
8234  AVStreamGroup *stg = s->stream_groups[i];
8235 
8236  if (stg->type == AV_STREAM_GROUP_PARAMS_LCEVC) {
8237  if (stg->nb_streams != 2) {
8238  av_log(s, AV_LOG_ERROR, "Exactly two Streams are supported for Stream Groups of type LCEVC\n");
8239  return AVERROR(EINVAL);
8240  }
8241  AVStreamGroupLCEVC *lcevc = stg->params.lcevc;
8242  if (lcevc->lcevc_index > 1)
8243  return AVERROR(EINVAL);
8244  AVStream *st = stg->streams[lcevc->lcevc_index];
8245  if (st->codecpar->codec_id != AV_CODEC_ID_LCEVC) {
8246  av_log(s, AV_LOG_ERROR, "Stream #%u is not an LCEVC stream\n", lcevc->lcevc_index);
8247  return AVERROR(EINVAL);
8248  }
8249  }
8250 
8251 #if CONFIG_IAMFENC
8253  continue;
8254 
8255  for (int j = 0; j < stg->nb_streams; j++) {
8256  AVStream *st = stg->streams[j];
8257 
8258  if (st->priv_data) {
8259  av_log(s, AV_LOG_ERROR, "Stream %d is present in more than one Stream Group of type "
8260  "IAMF Audio Element\n", j);
8261  return AVERROR(EINVAL);
8262  }
8263  st->priv_data = st;
8264  }
8265  has_iamf = 1;
8266 
8267  if (!mov->nb_tracks) // We support one track for the entire IAMF structure
8268  mov->nb_tracks++;
8269 #endif
8270  }
8271 
8272  for (i = 0; i < s->nb_streams; i++) {
8273  AVStream *st = s->streams[i];
8274  if (st->priv_data)
8275  continue;
8276  // Don't produce a track in the output file for timed ID3 streams.
8277  if (st->codecpar->codec_id == AV_CODEC_ID_TIMED_ID3) {
8278  // Leave priv_data set to NULL for these AVStreams that don't
8279  // have a corresponding track.
8280  continue;
8281  }
8282  st->priv_data = st;
8283  mov->nb_tracks++;
8284  }
8285 
8286  mov->nb_streams = mov->nb_tracks;
8287 
8288  if (mov->mode & (MODE_MP4|MODE_MOV|MODE_IPOD) && s->nb_chapters)
8289  mov->chapter_track = mov->nb_tracks++;
8290 
8291  if (mov->flags & FF_MOV_FLAG_RTP_HINT) {
8292  for (i = 0; i < s->nb_streams; i++)
8293  if (rtp_hinting_needed(s->streams[i]))
8294  mov->nb_tracks++;
8295  }
8296 
8297  if (mov->write_btrt < 0) {
8298  mov->write_btrt = mov->mode == MODE_MP4;
8299  }
8300 
8301  if ( mov->write_tmcd == -1 && (mov->mode == MODE_MOV || mov->mode == MODE_MP4)
8302  || mov->write_tmcd == 1) {
8303  AVDictionaryEntry *global_tcr = av_dict_get(s->metadata, "timecode",
8304  NULL, 0);
8305 
8306  /* +1 tmcd track for each video stream with a timecode */
8307  for (i = 0; i < s->nb_streams; i++) {
8308  AVStream *st = s->streams[i];
8309  AVDictionaryEntry *t = global_tcr;
8310  if (st->codecpar->codec_type == AVMEDIA_TYPE_VIDEO &&
8311  (t || (t=av_dict_get(st->metadata, "timecode", NULL, 0)))) {
8312  AVTimecode tc;
8313  ret = mov_check_timecode_track(s, &tc, st, t->value);
8314  if (ret >= 0)
8315  mov->nb_meta_tmcd++;
8316  }
8317  }
8318 
8319  /* check if there is already a tmcd track to remux */
8320  if (mov->nb_meta_tmcd) {
8321  for (i = 0; i < s->nb_streams; i++) {
8322  AVStream *st = s->streams[i];
8323  if (st->codecpar->codec_tag == MKTAG('t','m','c','d')) {
8324  av_log(s, AV_LOG_WARNING, "You requested a copy of the original timecode track "
8325  "so timecode metadata are now ignored\n");
8326  mov->nb_meta_tmcd = 0;
8327  }
8328  }
8329  }
8330 
8331  mov->nb_tracks += mov->nb_meta_tmcd;
8332  }
8333 
8334  // Reserve an extra stream for chapters for the case where chapters
8335  // are written in the trailer
8336  mov->tracks = av_calloc(mov->nb_tracks + 1, sizeof(*mov->tracks));
8337  if (!mov->tracks)
8338  return AVERROR(ENOMEM);
8339 
8340  for (i = 0; i < mov->nb_tracks; i++) {
8341  MOVTrack *track = &mov->tracks[i];
8342 
8343  track->stsd_count = 1;
8344  track->extradata = av_calloc(track->stsd_count, sizeof(*track->extradata));
8345  track->extradata_size = av_calloc(track->stsd_count, sizeof(*track->extradata_size));
8346  if (!track->extradata || !track->extradata_size)
8347  return AVERROR(ENOMEM);
8348  }
8349 
8350  if (mov->encryption_scheme_str != NULL && strcmp(mov->encryption_scheme_str, "none") != 0) {
8351  if (strcmp(mov->encryption_scheme_str, "cenc-aes-ctr") == 0) {
8353 
8354  if (mov->encryption_key_len != AES_CTR_KEY_SIZE) {
8355  av_log(s, AV_LOG_ERROR, "Invalid encryption key len %d expected %d\n",
8357  return AVERROR(EINVAL);
8358  }
8359 
8360  if (mov->encryption_kid_len != CENC_KID_SIZE) {
8361  av_log(s, AV_LOG_ERROR, "Invalid encryption kid len %d expected %d\n",
8363  return AVERROR(EINVAL);
8364  }
8365  } else {
8366  av_log(s, AV_LOG_ERROR, "unsupported encryption scheme %s\n",
8367  mov->encryption_scheme_str);
8368  return AVERROR(EINVAL);
8369  }
8370  }
8371 
8372 #if CONFIG_IAMFENC
8373  ret = mov_init_iamf_track(s);
8374  if (ret < 0)
8375  return ret;
8376 #endif
8377 
8378  for (int j = 0, i = 0; j < s->nb_streams; j++) {
8379  AVStream *st = s->streams[j];
8380 
8381  if (st != st->priv_data) {
8382  if (has_iamf)
8383  i += has_iamf--;
8384  continue;
8385  }
8386  st->priv_data = &mov->tracks[i++];
8387  }
8388 
8389  for (i = 0; i < s->nb_streams; i++) {
8390  AVStream *st= s->streams[i];
8391  MOVTrack *track = st->priv_data;
8392  AVDictionaryEntry *lang = av_dict_get(st->metadata, "language", NULL,0);
8393 
8394  if (!track)
8395  continue;
8396 
8397  if (!track->st) {
8398  track->st = st;
8399  track->par = st->codecpar;
8400  }
8401  track->language = ff_mov_iso639_to_lang(lang?lang->value:"und", mov->mode!=MODE_MOV);
8402  if (track->language < 0)
8403  track->language = 32767; // Unspecified Macintosh language code
8404  track->mode = mov->mode;
8405  if (!track->tag)
8406  track->tag = mov_find_codec_tag(s, track);
8407  if (!track->tag) {
8408  av_log(s, AV_LOG_ERROR, "Could not find tag for codec %s in stream #%d, "
8409  "codec not currently supported in container\n",
8411  return AVERROR(EINVAL);
8412  }
8413  /* If hinting of this track is enabled by a later hint track,
8414  * this is updated. */
8415  track->hint_track = -1;
8416  track->start_dts = AV_NOPTS_VALUE;
8417  track->start_cts = AV_NOPTS_VALUE;
8418  track->end_pts = AV_NOPTS_VALUE;
8419  track->dts_shift = AV_NOPTS_VALUE;
8420  if (st->codecpar->codec_type == AVMEDIA_TYPE_VIDEO) {
8421  if (track->tag == MKTAG('m','x','3','p') || track->tag == MKTAG('m','x','3','n') ||
8422  track->tag == MKTAG('m','x','4','p') || track->tag == MKTAG('m','x','4','n') ||
8423  track->tag == MKTAG('m','x','5','p') || track->tag == MKTAG('m','x','5','n')) {
8424  if (st->codecpar->width != 720 || (st->codecpar->height != 608 && st->codecpar->height != 512)) {
8425  av_log(s, AV_LOG_ERROR, "D-10/IMX must use 720x608 or 720x512 video resolution\n");
8426  return AVERROR(EINVAL);
8427  }
8428  track->height = track->tag >> 24 == 'n' ? 486 : 576;
8429  }
8430  if (mov->video_track_timescale) {
8431  track->timescale = mov->video_track_timescale;
8432  if (mov->mode == MODE_ISM && mov->video_track_timescale != 10000000)
8433  av_log(s, AV_LOG_WARNING, "Warning: some tools, like mp4split, assume a timescale of 10000000 for ISMV.\n");
8434  } else {
8435  track->timescale = st->time_base.den;
8436  while(track->timescale < 10000)
8437  track->timescale *= 2;
8438  }
8439  if (st->codecpar->width > 65535 || st->codecpar->height > 65535) {
8440  av_log(s, AV_LOG_ERROR, "Resolution %dx%d too large for mov/mp4\n", st->codecpar->width, st->codecpar->height);
8441  return AVERROR(EINVAL);
8442  }
8443  if (track->mode == MODE_MOV && track->timescale > 100000)
8445  "WARNING codec timebase is very high. If duration is too long,\n"
8446  "file may not be playable by quicktime. Specify a shorter timebase\n"
8447  "or choose different container.\n");
8448  if (track->mode == MODE_MOV &&
8449  track->par->codec_id == AV_CODEC_ID_RAWVIDEO &&
8450  track->tag == MKTAG('r','a','w',' ')) {
8451  enum AVPixelFormat pix_fmt = track->par->format;
8452  if (pix_fmt == AV_PIX_FMT_NONE && track->par->bits_per_coded_sample == 1)
8454  track->is_unaligned_qt_rgb =
8457  pix_fmt == AV_PIX_FMT_PAL8 ||
8461  }
8462  if (track->par->codec_id == AV_CODEC_ID_VP9 && track->mode != MODE_MP4) {
8463  av_log(s, AV_LOG_ERROR, "%s only supported in MP4.\n", avcodec_get_name(track->par->codec_id));
8464  return AVERROR(EINVAL);
8465  } else if (track->par->codec_id == AV_CODEC_ID_AV1 &&
8466  track->mode != MODE_MP4 && track->mode != MODE_AVIF) {
8467  av_log(s, AV_LOG_ERROR, "%s only supported in MP4 and AVIF.\n", avcodec_get_name(track->par->codec_id));
8468  return AVERROR(EINVAL);
8469  } else if (track->par->codec_id == AV_CODEC_ID_VP8) {
8470  /* altref frames handling is not defined in the spec as of version v1.0,
8471  * so just forbid muxing VP8 streams altogether until a new version does */
8472  av_log(s, AV_LOG_ERROR, "VP8 muxing is currently not supported.\n");
8473  return AVERROR_PATCHWELCOME;
8474  } else if (track->par->codec_id == AV_CODEC_ID_APV) {
8475  ret = ff_isom_init_apvc(&track->apv, s);
8476  if (ret < 0)
8477  return ret;
8478  }
8479  if (is_cover_image(st)) {
8480  track->cover_image = av_packet_alloc();
8481  if (!track->cover_image)
8482  return AVERROR(ENOMEM);
8483  }
8484  } else if (st->codecpar->codec_type == AVMEDIA_TYPE_AUDIO) {
8485  track->timescale = st->codecpar->sample_rate;
8487  av_log(s, AV_LOG_WARNING, "track %d: codec frame size is not set\n", i);
8488  track->audio_vbr = 1;
8489  }else if (st->codecpar->codec_id == AV_CODEC_ID_ADPCM_MS ||
8492  if (!st->codecpar->block_align) {
8493  av_log(s, AV_LOG_ERROR, "track %d: codec block align is not set for adpcm\n", i);
8494  return AVERROR(EINVAL);
8495  }
8496  track->sample_size = st->codecpar->block_align;
8497  }else if (st->codecpar->frame_size > 1){ /* assume compressed audio */
8498  track->audio_vbr = 1;
8499  }else{
8500  track->sample_size = (av_get_bits_per_sample(st->codecpar->codec_id) >> 3) *
8502  }
8503  if (st->codecpar->codec_id == AV_CODEC_ID_ILBC ||
8505  track->audio_vbr = 1;
8506  }
8507  if (track->mode != MODE_MOV &&
8508  track->par->codec_id == AV_CODEC_ID_MP3 && track->timescale < 16000) {
8509  if (s->strict_std_compliance >= FF_COMPLIANCE_NORMAL) {
8510  av_log(s, AV_LOG_ERROR, "track %d: muxing mp3 at %dhz is not standard, to mux anyway set strict to -1\n",
8511  i, track->par->sample_rate);
8512  return AVERROR(EINVAL);
8513  } else {
8514  av_log(s, AV_LOG_WARNING, "track %d: muxing mp3 at %dhz is not standard in MP4\n",
8515  i, track->par->sample_rate);
8516  }
8517  }
8518  if (track->par->codec_id == AV_CODEC_ID_FLAC ||
8519  track->par->codec_id == AV_CODEC_ID_TRUEHD ||
8520  track->par->codec_id == AV_CODEC_ID_OPUS) {
8521  if (track->mode != MODE_MP4) {
8522  av_log(s, AV_LOG_ERROR, "%s only supported in MP4.\n", avcodec_get_name(track->par->codec_id));
8523  return AVERROR(EINVAL);
8524  }
8525  if (track->par->codec_id == AV_CODEC_ID_TRUEHD &&
8526  s->strict_std_compliance > FF_COMPLIANCE_EXPERIMENTAL) {
8528  "%s in MP4 support is experimental, add "
8529  "'-strict %d' if you want to use it.\n",
8531  return AVERROR_EXPERIMENTAL;
8532  }
8533  }
8534  } else if (st->codecpar->codec_type == AVMEDIA_TYPE_SUBTITLE) {
8535  track->timescale = st->time_base.den;
8536 
8537  if (track->par->codec_id == AV_CODEC_ID_TTML) {
8538  /* 14496-30 requires us to use a single sample per fragment
8539  for TTML, for which we define a per-track flag.
8540 
8541  We set the flag in case we are receiving TTML paragraphs
8542  from the input, in other words in case we are not doing
8543  stream copy. */
8546 
8547  if (track->mode != MODE_ISM &&
8548  track->par->codec_tag == MOV_ISMV_TTML_TAG &&
8549  s->strict_std_compliance > FF_COMPLIANCE_UNOFFICIAL) {
8551  "ISMV style TTML support with the 'dfxp' tag in "
8552  "non-ISMV formats is not officially supported. Add "
8553  "'-strict unofficial' if you want to use it.\n");
8554  return AVERROR_EXPERIMENTAL;
8555  }
8556  }
8557  } else if (st->codecpar->codec_type == AVMEDIA_TYPE_DATA) {
8558  track->timescale = st->time_base.den;
8559  } else {
8560  track->timescale = mov->movie_timescale;
8561  }
8562  if (!track->height)
8563  track->height = st->codecpar->height;
8564  /* The Protected Interoperable File Format (PIFF) standard, used by ISMV recommends but
8565  doesn't mandate a track timescale of 10,000,000. The muxer allows a custom timescale
8566  for video tracks, so if user-set, it isn't overwritten */
8567  if (mov->mode == MODE_ISM &&
8570  track->timescale = 10000000;
8571  }
8572 
8573  avpriv_set_pts_info(st, 64, 1, track->timescale);
8574 
8576  ret = ff_mov_cenc_init(&track->cenc, mov->encryption_key,
8577  (track->par->codec_id == AV_CODEC_ID_H264 || track->par->codec_id == AV_CODEC_ID_HEVC ||
8578  track->par->codec_id == AV_CODEC_ID_VVC || track->par->codec_id == AV_CODEC_ID_AV1),
8579  track->par->codec_id, s->flags & AVFMT_FLAG_BITEXACT);
8580  if (ret)
8581  return ret;
8582  }
8583  }
8584 
8585  for (i = 0; i < s->nb_stream_groups; i++) {
8586  AVStreamGroup *stg = s->stream_groups[i];
8587 
8588  switch (stg->type) {
8590  AVStreamGroupLCEVC *lcevc = stg->params.lcevc;
8591  AVStream *st = stg->streams[lcevc->lcevc_index];
8592  MOVTrack *track = st->priv_data;
8593 
8594  for (int j = 0; j < mov->nb_tracks; j++) {
8595  MOVTrack *trk = &mov->tracks[j];
8596 
8597  if (trk->st == stg->streams[!lcevc->lcevc_index]) {
8598  track->src_track = av_malloc(sizeof(*track->src_track));
8599  if (!track->src_track)
8600  return AVERROR(ENOMEM);
8601  *track->src_track = j;
8602  track->nb_src_track = 1;
8603  break;
8604  }
8605  }
8606 
8607  track->par->width = lcevc->width;
8608  track->par->height = track->height = lcevc->height;
8609  break;
8610  }
8612  const AVStreamGroupTREF *tref = stg->params.tref;
8613  MOVTrack *track;
8614 
8615  if (tref->metadata_index >= stg->nb_streams)
8616  return AVERROR(EINVAL);
8617 
8618  track = stg->streams[tref->metadata_index]->priv_data;
8619  for (int j = 0; j < stg->nb_streams; j++) {
8620  const AVStream *st2 = stg->streams[j];
8621  int index = -1;
8622 
8623  for (int k = 0; k < mov->nb_tracks; k++) {
8624  if (mov->tracks[k].st != st2)
8625  continue;
8626  index = k;
8627  break;
8628  }
8629  if (index < 0)
8630  return AVERROR(EINVAL);
8631 
8632  int *tmp = av_realloc(track->src_track,
8633  (track->nb_src_track + 1) * sizeof(*track->src_track));
8634  if (!tmp)
8635  return AVERROR(ENOMEM);
8636  track->src_track = tmp;
8637  track->src_track[track->nb_src_track++] = index;
8638  }
8639  break;
8640  }
8641  default:
8642  break;
8643  }
8644  }
8645 
8646  /* fill src_track for tmcd tracks not covered by stream groups or
8647  * created by this muxer, retaining the old behavior of src_track
8648  * being arbitrarily 0. */
8649  for (i = 0; i < s->nb_streams; i++) {
8650  AVStream *st = s->streams[i];
8651  MOVTrack *track = st->priv_data;
8652  if (st->codecpar->codec_tag != MKTAG('t','m','c','d') ||
8653  track->nb_src_track)
8654  continue;
8655 
8656  track->src_track = av_malloc(sizeof(*track->src_track));
8657  if (!track->src_track)
8658  return AVERROR(ENOMEM);
8659  *track->src_track = 0;
8660  track->nb_src_track = 1;
8661  }
8662 
8663  enable_tracks(s);
8664  return 0;
8665 }
8666 
8668 {
8669  AVIOContext *pb = s->pb;
8670  MOVMuxContext *mov = s->priv_data;
8671  int ret, hint_track = 0, tmcd_track = 0, nb_tracks = mov->nb_streams;
8672 
8673  if (mov->mode & (MODE_MP4|MODE_MOV|MODE_IPOD) && s->nb_chapters)
8674  nb_tracks++;
8675 
8676  if (mov->flags & FF_MOV_FLAG_RTP_HINT) {
8677  hint_track = nb_tracks;
8678  for (int i = 0; i < mov->nb_streams; i++) {
8679  if (rtp_hinting_needed(mov->tracks[i].st))
8680  nb_tracks++;
8681  }
8682  }
8683 
8684  if (mov->nb_meta_tmcd)
8685  tmcd_track = nb_tracks;
8686 
8687  for (int i = 0; i < mov->nb_streams; i++) {
8688  MOVTrack *track = &mov->tracks[i];
8689  AVStream *st = track->st;
8690 
8691  /* copy extradata if it exists */
8692  if (st->codecpar->extradata_size) {
8695  else if (!TAG_IS_AVCI(track->tag) && st->codecpar->codec_id != AV_CODEC_ID_DNXHD) {
8696  track->extradata_size[track->last_stsd_index] = st->codecpar->extradata_size;
8697  track->extradata[track->last_stsd_index] =
8699  if (!track->extradata[track->last_stsd_index]) {
8700  return AVERROR(ENOMEM);
8701  }
8702  memcpy(track->extradata[track->last_stsd_index],
8703  st->codecpar->extradata, track->extradata_size[track->last_stsd_index]);
8704  memset(track->extradata[track->last_stsd_index] + track->extradata_size[track->last_stsd_index],
8706  }
8707  }
8708 
8709  if (st->codecpar->codec_type != AVMEDIA_TYPE_AUDIO ||
8712  continue;
8713 
8714  for (int j = 0; j < mov->nb_streams; j++) {
8715  AVStream *stj= mov->tracks[j].st;
8716  MOVTrack *trackj= &mov->tracks[j];
8717  if (j == i)
8718  continue;
8719 
8720  if (stj->codecpar->codec_type == AVMEDIA_TYPE_AUDIO &&
8721  (trackj->par->ch_layout.nb_channels != 1 ||
8724  )
8725  track->mono_as_fc = -1;
8726 
8727  if (stj->codecpar->codec_type == AVMEDIA_TYPE_AUDIO &&
8730  trackj->par->ch_layout.nb_channels == 1 && track->mono_as_fc >= 0
8731  )
8732  track->mono_as_fc++;
8733 
8734  if (stj->codecpar->codec_type != AVMEDIA_TYPE_AUDIO ||
8737  trackj->language != track->language ||
8738  trackj->tag != track->tag
8739  )
8740  continue;
8741  track->multichannel_as_mono++;
8742  }
8743  }
8744 
8745  if (!(mov->flags & FF_MOV_FLAG_DELAY_MOOV) ||
8747  if ((ret = mov_write_identification(pb, s)) < 0)
8748  return ret;
8749  }
8750 
8751  if (mov->reserved_moov_size){
8752  mov->reserved_header_pos = avio_tell(pb);
8753  if (mov->reserved_moov_size > 0)
8754  avio_skip(pb, mov->reserved_moov_size);
8755  }
8756 
8757  if (mov->flags & FF_MOV_FLAG_FRAGMENT) {
8758  /* If no fragmentation options have been set, set a default. */
8759  if (!(mov->flags & (FF_MOV_FLAG_FRAG_KEYFRAME |
8764  if (mov->flags & FF_MOV_FLAG_HYBRID_FRAGMENTED) {
8765  avio_wb32(pb, 8); // placeholder for extended size field (64 bit)
8766  ffio_wfourcc(pb, mov->mode == MODE_MOV ? "wide" : "free");
8767  mov->mdat_pos = avio_tell(pb);
8768  // The free/wide header that later will be converted into an
8769  // mdat, covering the initial moov and all the fragments.
8770  avio_wb32(pb, 0);
8771  ffio_wfourcc(pb, mov->mode == MODE_MOV ? "wide" : "free");
8772  // Write an ftyp atom, hidden in a free/wide. This is neither
8773  // exposed while the file is written, as fragmented, nor when the
8774  // file is finalized into non-fragmented form. However, this allows
8775  // accessing a pristine, sequential ftyp+moov init segment, even
8776  // after the file is finalized. It also allows dumping the whole
8777  // contents of the mdat box, to get the fragmented form of the
8778  // file.
8779  if ((ret = mov_write_identification(pb, s)) < 0)
8780  return ret;
8781  update_size(pb, mov->mdat_pos);
8782  }
8783  } else if (mov->mode != MODE_AVIF) {
8784  if (mov->flags & FF_MOV_FLAG_FASTSTART)
8785  mov->reserved_header_pos = avio_tell(pb);
8786  mov_write_mdat_tag(pb, mov);
8787  }
8788 
8790  if (mov->time)
8791  mov->time += 0x7C25B080; // 1970 based -> 1904 based
8792 
8793  if (mov->chapter_track)
8794  if ((ret = mov_create_chapter_track(s, mov->chapter_track)) < 0)
8795  return ret;
8796 
8797  if (mov->flags & FF_MOV_FLAG_RTP_HINT) {
8798  for (int i = 0; i < mov->nb_streams; i++) {
8799  if (rtp_hinting_needed(mov->tracks[i].st)) {
8800  if ((ret = ff_mov_init_hinting(s, hint_track, i)) < 0)
8801  return ret;
8802  hint_track++;
8803  }
8804  }
8805  }
8806 
8807  if (mov->nb_meta_tmcd) {
8808  const AVDictionaryEntry *t, *global_tcr = av_dict_get(s->metadata,
8809  "timecode", NULL, 0);
8810  /* Initialize the tmcd tracks */
8811  for (int i = 0; i < mov->nb_streams; i++) {
8812  AVStream *st = mov->tracks[i].st;
8813  t = global_tcr;
8814 
8815  if (st->codecpar->codec_type == AVMEDIA_TYPE_VIDEO) {
8816  AVTimecode tc;
8817  if (!t)
8818  t = av_dict_get(st->metadata, "timecode", NULL, 0);
8819  if (!t)
8820  continue;
8821  if (mov_check_timecode_track(s, &tc, st, t->value) < 0)
8822  continue;
8823  if ((ret = mov_create_timecode_track(s, tmcd_track, i, tc)) < 0)
8824  return ret;
8825  tmcd_track++;
8826  }
8827  }
8828  }
8829 
8830  avio_flush(pb);
8831 
8832  if (mov->flags & FF_MOV_FLAG_ISML)
8833  mov_write_isml_manifest(pb, mov, s);
8834 
8835  if (mov->flags & FF_MOV_FLAG_EMPTY_MOOV &&
8836  !(mov->flags & FF_MOV_FLAG_DELAY_MOOV)) {
8837  if ((ret = mov_write_moov_tag(pb, mov, s)) < 0)
8838  return ret;
8839  mov->moov_written = 1;
8840  if (mov->flags & FF_MOV_FLAG_GLOBAL_SIDX)
8841  mov->reserved_header_pos = avio_tell(pb);
8842  }
8843 
8844  return 0;
8845 }
8846 
8848 {
8849  int ret;
8850  AVIOContext *moov_buf;
8851  MOVMuxContext *mov = s->priv_data;
8852 
8853  if ((ret = ffio_open_null_buf(&moov_buf)) < 0)
8854  return ret;
8855  if ((ret = mov_write_moov_tag(moov_buf, mov, s)) < 0)
8856  return ret;
8857  return ffio_close_null_buf(moov_buf);
8858 }
8859 
8861 {
8862  int ret;
8863  AVIOContext *buf;
8864  MOVMuxContext *mov = s->priv_data;
8865 
8866  if ((ret = ffio_open_null_buf(&buf)) < 0)
8867  return ret;
8868  mov_write_sidx_tags(buf, mov, -1, 0);
8869  return ffio_close_null_buf(buf);
8870 }
8871 
8872 /*
8873  * This function gets the moov size if moved to the top of the file: the chunk
8874  * offset table can switch between stco (32-bit entries) to co64 (64-bit
8875  * entries) when the moov is moved to the beginning, so the size of the moov
8876  * would change. It also updates the chunk offset tables.
8877  */
8879 {
8880  int i, moov_size, moov_size2;
8881  MOVMuxContext *mov = s->priv_data;
8882 
8883  moov_size = get_moov_size(s);
8884  if (moov_size < 0)
8885  return moov_size;
8886 
8887  for (i = 0; i < mov->nb_tracks; i++)
8888  mov->tracks[i].data_offset += moov_size;
8889 
8890  moov_size2 = get_moov_size(s);
8891  if (moov_size2 < 0)
8892  return moov_size2;
8893 
8894  /* if the size changed, we just switched from stco to co64 and need to
8895  * update the offsets */
8896  if (moov_size2 != moov_size)
8897  for (i = 0; i < mov->nb_tracks; i++)
8898  mov->tracks[i].data_offset += moov_size2 - moov_size;
8899 
8900  return moov_size2;
8901 }
8902 
8904 {
8905  int i, sidx_size;
8906  MOVMuxContext *mov = s->priv_data;
8907 
8908  sidx_size = get_sidx_size(s);
8909  if (sidx_size < 0)
8910  return sidx_size;
8911 
8912  for (i = 0; i < mov->nb_tracks; i++)
8913  mov->tracks[i].data_offset += sidx_size;
8914 
8915  return sidx_size;
8916 }
8917 
8919 {
8920  int moov_size;
8921  MOVMuxContext *mov = s->priv_data;
8922 
8923  if (mov->flags & FF_MOV_FLAG_FRAGMENT)
8924  moov_size = compute_sidx_size(s);
8925  else
8926  moov_size = compute_moov_size(s);
8927  if (moov_size < 0)
8928  return moov_size;
8929 
8930  return ff_format_shift_data(s, mov->reserved_header_pos, moov_size);
8931 }
8932 
8934 {
8935  MOVMuxContext *mov = s->priv_data;
8936  AVIOContext *pb = s->pb;
8937 
8938  /* Write size of mdat tag */
8939  if (mov->mdat_size + 8 <= UINT32_MAX) {
8940  avio_seek(pb, mov->mdat_pos, SEEK_SET);
8941  avio_wb32(pb, mov->mdat_size + 8);
8943  ffio_wfourcc(pb, "mdat"); // overwrite the original free/wide into a mdat
8944  } else {
8945  /* overwrite 'wide' placeholder atom */
8946  avio_seek(pb, mov->mdat_pos - 8, SEEK_SET);
8947  /* special value: real atom size will be 64 bit value after
8948  * tag field */
8949  avio_wb32(pb, 1);
8950  ffio_wfourcc(pb, "mdat");
8951  avio_wb64(pb, mov->mdat_size + 16);
8952  }
8953 }
8954 
8956 {
8957  MOVMuxContext *mov = s->priv_data;
8958  AVIOContext *pb = s->pb;
8959  int res = 0;
8960  int i;
8961  int64_t moov_pos;
8962 
8963  /*
8964  * Before actually writing the trailer, make sure that there are no
8965  * dangling subtitles, that need a terminating sample.
8966  */
8967  for (i = 0; i < mov->nb_tracks; i++) {
8968  MOVTrack *trk = &mov->tracks[i];
8969  if (trk->par->codec_id == AV_CODEC_ID_MOV_TEXT &&
8972  trk->last_sample_is_subtitle_end = 1;
8973  }
8974  }
8975 
8976  // Check if we have any tracks that require squashing.
8977  // In that case, we'll have to write the packet here.
8978  if ((res = mov_write_squashed_packets(s)) < 0)
8979  return res;
8980 
8981  // If there were no chapters when the header was written, but there
8982  // are chapters now, write them in the trailer. This only works
8983  // when we are not doing fragments.
8984  if (!mov->chapter_track && !(mov->flags & FF_MOV_FLAG_FRAGMENT)) {
8985  if (mov->mode & (MODE_MP4|MODE_MOV|MODE_IPOD) && s->nb_chapters) {
8986  mov->chapter_track = mov->nb_tracks++;
8987  if ((res = mov_create_chapter_track(s, mov->chapter_track)) < 0)
8988  return res;
8989  }
8990  }
8991 
8992  if (!(mov->flags & FF_MOV_FLAG_FRAGMENT) ||
8994  if (mov->flags & FF_MOV_FLAG_HYBRID_FRAGMENTED) {
8996  mov->mdat_size = avio_tell(pb) - mov->mdat_pos - 8;
8997  for (i = 0; i < mov->nb_tracks; i++) {
8998  MOVTrack *track = &mov->tracks[i];
8999  track->data_offset = 0;
9000  av_free(track->cluster);
9001  track->cluster = track->cluster_written;
9002  track->entry = track->entry_written;
9003  track->cluster_written = NULL;
9004  track->entry_written = 0;
9005  track->chunkCount = 0; // Force build_chunks to rebuild the list of chunks
9006  }
9007  // Clear the empty_moov flag, as we do want the moov to include
9008  // all the samples at this point.
9009  mov->flags &= ~FF_MOV_FLAG_EMPTY_MOOV;
9010  }
9011 
9012  moov_pos = avio_tell(pb);
9013 
9014  if (!(mov->flags & FF_MOV_FLAG_HYBRID_FRAGMENTED))
9016 
9017  avio_seek(pb, mov->reserved_moov_size > 0 ? mov->reserved_header_pos : moov_pos, SEEK_SET);
9018 
9019  if (mov->flags & FF_MOV_FLAG_FASTSTART) {
9020  av_log(s, AV_LOG_INFO, "Starting second pass: moving the moov atom to the beginning of the file\n");
9021  res = shift_data(s);
9022  if (res < 0)
9023  return res;
9024  avio_seek(pb, mov->reserved_header_pos, SEEK_SET);
9025  if ((res = mov_write_moov_tag(pb, mov, s)) < 0)
9026  return res;
9027  } else if (mov->reserved_moov_size > 0) {
9028  int64_t size;
9029  if ((res = mov_write_moov_tag(pb, mov, s)) < 0)
9030  return res;
9031  size = mov->reserved_moov_size - (avio_tell(pb) - mov->reserved_header_pos);
9032  if (size < 8){
9033  av_log(s, AV_LOG_ERROR, "reserved_moov_size is too small, needed %"PRId64" additional\n", 8-size);
9034  return AVERROR(EINVAL);
9035  }
9036  avio_wb32(pb, size);
9037  ffio_wfourcc(pb, "free");
9038  ffio_fill(pb, 0, size - 8);
9039  avio_seek(pb, moov_pos, SEEK_SET);
9040  } else {
9041  if ((res = mov_write_moov_tag(pb, mov, s)) < 0)
9042  return res;
9043  }
9044 
9045  if (mov->flags & FF_MOV_FLAG_HYBRID_FRAGMENTED) {
9046  // With hybrid fragmentation, only write the mdat size (hiding
9047  // the original moov and all the fragments within the mdat)
9048  // after we've successfully written the complete moov, to avoid
9049  // risk for an unreadable file if writing the final moov fails.
9051  }
9052 
9053  res = 0;
9054  } else {
9056  for (i = 0; i < mov->nb_tracks; i++)
9057  mov->tracks[i].data_offset = 0;
9058  if (mov->flags & FF_MOV_FLAG_GLOBAL_SIDX) {
9059  int64_t end;
9060  av_log(s, AV_LOG_INFO, "Starting second pass: inserting sidx atoms\n");
9061  res = shift_data(s);
9062  if (res < 0)
9063  return res;
9064  end = avio_tell(pb);
9065  avio_seek(pb, mov->reserved_header_pos, SEEK_SET);
9066  mov_write_sidx_tags(pb, mov, -1, 0);
9067  avio_seek(pb, end, SEEK_SET);
9068  }
9069  if (!(mov->flags & FF_MOV_FLAG_SKIP_TRAILER)) {
9071  res = mov_write_mfra_tag(pb, mov);
9072  if (res < 0)
9073  return res;
9074  }
9075  }
9076 
9077  return res;
9078 }
9079 
9081  const AVPacket *pkt)
9082 {
9083  int ret = 1;
9084 
9085  if (st->codecpar->codec_id == AV_CODEC_ID_AAC) {
9086  if (pkt->size > 2 && (AV_RB16(pkt->data) & 0xfff0) == 0xfff0)
9087  ret = ff_stream_add_bitstream_filter(st, "aac_adtstoasc", NULL);
9088  } else if (st->codecpar->codec_id == AV_CODEC_ID_VP9) {
9089  ret = ff_stream_add_bitstream_filter(st, "vp9_superframe", NULL);
9090  }
9091 
9092  return ret;
9093 }
9094 
9095 #if CONFIG_AVIF_MUXER
9096 static int avif_write_trailer(AVFormatContext *s)
9097 {
9098  AVIOContext *pb = s->pb;
9099  MOVMuxContext *mov = s->priv_data;
9100  int64_t pos_backup, extent_offsets[2];
9101  uint8_t *buf;
9102  int buf_size, moov_size;
9103 
9104  if (mov->moov_written) return 0;
9105 
9106  mov->is_animated_avif = s->streams[0]->nb_frames > 1;
9107  if (mov->is_animated_avif && mov->nb_streams > 1) {
9108  // For animated avif with alpha channel, we need to write a tref tag
9109  // with type "auxl".
9110  MovTag *tag = mov_add_tref_tag(mov, &mov->tracks[1], MKTAG('a', 'u', 'x', 'l'));
9111  if (!tag)
9112  return AVERROR(ENOMEM);
9113 
9114  int ret = mov_add_tref_id(mov, tag, 1);
9115  if (ret < 0)
9116  return ret;
9117  }
9119  mov_write_meta_tag(pb, mov, s);
9120 
9121  moov_size = get_moov_size(s);
9122  for (int i = 0; i < mov->nb_tracks; i++)
9123  mov->tracks[i].data_offset = avio_tell(pb) + moov_size + 8;
9124 
9125  if (mov->is_animated_avif) {
9126  int ret;
9127  if ((ret = mov_write_moov_tag(pb, mov, s)) < 0)
9128  return ret;
9129  }
9130 
9131  buf_size = avio_get_dyn_buf(mov->mdat_buf, &buf);
9132  avio_wb32(pb, buf_size + 8);
9133  ffio_wfourcc(pb, "mdat");
9134 
9135  // The offset for the YUV planes is the starting position of mdat.
9136  extent_offsets[0] = avio_tell(pb);
9137  // The offset for alpha plane is YUV offset + YUV size.
9138  extent_offsets[1] = extent_offsets[0] + mov->avif_extent_length[0];
9139 
9140  avio_write(pb, buf, buf_size);
9141 
9142  // write extent offsets.
9143  pos_backup = avio_tell(pb);
9144  for (int i = 0; i < mov->nb_streams; i++) {
9145  if (extent_offsets[i] != (uint32_t)extent_offsets[i]) {
9146  av_log(s, AV_LOG_ERROR, "extent offset does not fit in 32 bits\n");
9147  return AVERROR_INVALIDDATA;
9148  }
9149  avio_seek(pb, mov->avif_extent_pos[i], SEEK_SET);
9150  avio_wb32(pb, extent_offsets[i]); /* rewrite offset */
9151  }
9152  avio_seek(pb, pos_backup, SEEK_SET);
9153 
9154  return 0;
9155 }
9156 #endif
9157 
9158 #if CONFIG_TGP_MUXER || CONFIG_TG2_MUXER
9159 static const AVCodecTag codec_3gp_tags[] = {
9160  { AV_CODEC_ID_H263, MKTAG('s','2','6','3') },
9161  { AV_CODEC_ID_H264, MKTAG('a','v','c','1') },
9162  { AV_CODEC_ID_MPEG4, MKTAG('m','p','4','v') },
9163  { AV_CODEC_ID_AAC, MKTAG('m','p','4','a') },
9164  { AV_CODEC_ID_AMR_NB, MKTAG('s','a','m','r') },
9165  { AV_CODEC_ID_AMR_WB, MKTAG('s','a','w','b') },
9166  { AV_CODEC_ID_MOV_TEXT, MKTAG('t','x','3','g') },
9167  { AV_CODEC_ID_NONE, 0 },
9168 };
9169 static const AVCodecTag *const codec_3gp_tags_list[] = { codec_3gp_tags, NULL };
9170 #endif
9171 
9172 static const AVCodecTag codec_mp4_tags[] = {
9173  { AV_CODEC_ID_MPEG4, MKTAG('m', 'p', '4', 'v') },
9174  { AV_CODEC_ID_H264, MKTAG('a', 'v', 'c', '1') },
9175  { AV_CODEC_ID_H264, MKTAG('a', 'v', 'c', '3') },
9176  { AV_CODEC_ID_HEVC, MKTAG('h', 'e', 'v', '1') },
9177  { AV_CODEC_ID_HEVC, MKTAG('h', 'v', 'c', '1') },
9178  { AV_CODEC_ID_HEVC, MKTAG('d', 'v', 'h', '1') },
9179  { AV_CODEC_ID_VVC, MKTAG('v', 'v', 'c', '1') },
9180  { AV_CODEC_ID_VVC, MKTAG('v', 'v', 'i', '1') },
9181  { AV_CODEC_ID_EVC, MKTAG('e', 'v', 'c', '1') },
9182  { AV_CODEC_ID_LCEVC, MKTAG('l', 'v', 'c', '1') },
9183  { AV_CODEC_ID_APV, MKTAG('a', 'p', 'v', '1') },
9184  { AV_CODEC_ID_MPEG2VIDEO, MKTAG('m', 'p', '4', 'v') },
9185  { AV_CODEC_ID_MPEG1VIDEO, MKTAG('m', 'p', '4', 'v') },
9186  { AV_CODEC_ID_MJPEG, MKTAG('m', 'p', '4', 'v') },
9187  { AV_CODEC_ID_PNG, MKTAG('m', 'p', '4', 'v') },
9188  { AV_CODEC_ID_JPEG2000, MKTAG('m', 'p', '4', 'v') },
9189  { AV_CODEC_ID_VC1, MKTAG('v', 'c', '-', '1') },
9190  { AV_CODEC_ID_DIRAC, MKTAG('d', 'r', 'a', 'c') },
9191  { AV_CODEC_ID_TSCC2, MKTAG('m', 'p', '4', 'v') },
9192  { AV_CODEC_ID_VP9, MKTAG('v', 'p', '0', '9') },
9193  { AV_CODEC_ID_AV1, MKTAG('a', 'v', '0', '1') },
9194  { AV_CODEC_ID_AAC, MKTAG('m', 'p', '4', 'a') },
9195  { AV_CODEC_ID_ALAC, MKTAG('a', 'l', 'a', 'c') },
9196  { AV_CODEC_ID_MP4ALS, MKTAG('m', 'p', '4', 'a') },
9197  { AV_CODEC_ID_MP3, MKTAG('m', 'p', '4', 'a') },
9198  { AV_CODEC_ID_MP2, MKTAG('m', 'p', '4', 'a') },
9199  { AV_CODEC_ID_AC3, MKTAG('a', 'c', '-', '3') },
9200  { AV_CODEC_ID_EAC3, MKTAG('e', 'c', '-', '3') },
9201  { AV_CODEC_ID_DTS, MKTAG('m', 'p', '4', 'a') },
9202  { AV_CODEC_ID_TRUEHD, MKTAG('m', 'l', 'p', 'a') },
9203  { AV_CODEC_ID_FLAC, MKTAG('f', 'L', 'a', 'C') },
9204  { AV_CODEC_ID_OPUS, MKTAG('O', 'p', 'u', 's') },
9205  { AV_CODEC_ID_VORBIS, MKTAG('m', 'p', '4', 'a') },
9206  { AV_CODEC_ID_QCELP, MKTAG('m', 'p', '4', 'a') },
9207  { AV_CODEC_ID_EVRC, MKTAG('m', 'p', '4', 'a') },
9208  { AV_CODEC_ID_DVD_SUBTITLE, MKTAG('m', 'p', '4', 's') },
9209  { AV_CODEC_ID_MOV_TEXT, MKTAG('t', 'x', '3', 'g') },
9210  { AV_CODEC_ID_BIN_DATA, MKTAG('g', 'p', 'm', 'd') },
9211  { AV_CODEC_ID_MPEGH_3D_AUDIO, MKTAG('m', 'h', 'm', '1') },
9214  { AV_CODEC_ID_FFV1, MKTAG('F', 'F', 'V', '1') },
9215 
9216  /* ISO/IEC 23003-5 integer formats */
9223  /* ISO/IEC 23003-5 floating-point formats */
9228 
9229  { AV_CODEC_ID_AVS3, MKTAG('a', 'v', 's', '3') },
9230 
9231  { AV_CODEC_ID_NONE, 0 },
9232 };
9233 #if CONFIG_MP4_MUXER || CONFIG_PSP_MUXER
9234 static const AVCodecTag *const mp4_codec_tags_list[] = { codec_mp4_tags, NULL };
9235 #endif
9236 
9237 static const AVCodecTag codec_ism_tags[] = {
9238  { AV_CODEC_ID_WMAPRO , MKTAG('w', 'm', 'a', ' ') },
9240  { AV_CODEC_ID_NONE , 0 },
9241 };
9242 
9243 static const AVCodecTag codec_ipod_tags[] = {
9244  { AV_CODEC_ID_H264, MKTAG('a','v','c','1') },
9245  { AV_CODEC_ID_MPEG4, MKTAG('m','p','4','v') },
9246  { AV_CODEC_ID_AAC, MKTAG('m','p','4','a') },
9247  { AV_CODEC_ID_ALAC, MKTAG('a','l','a','c') },
9248  { AV_CODEC_ID_AC3, MKTAG('a','c','-','3') },
9249  { AV_CODEC_ID_MOV_TEXT, MKTAG('t','x','3','g') },
9250  { AV_CODEC_ID_MOV_TEXT, MKTAG('t','e','x','t') },
9251  { AV_CODEC_ID_NONE, 0 },
9252 };
9253 
9254 static const AVCodecTag codec_f4v_tags[] = {
9255  { AV_CODEC_ID_MP3, MKTAG('.','m','p','3') },
9256  { AV_CODEC_ID_AAC, MKTAG('m','p','4','a') },
9257  { AV_CODEC_ID_H264, MKTAG('a','v','c','1') },
9258  { AV_CODEC_ID_VP6A, MKTAG('V','P','6','A') },
9259  { AV_CODEC_ID_VP6F, MKTAG('V','P','6','F') },
9260  { AV_CODEC_ID_NONE, 0 },
9261 };
9262 
9263 #if CONFIG_AVIF_MUXER
9264 
9265 static const AVOption avif_options[] = {
9266  { "movie_timescale", "set movie timescale", offsetof(MOVMuxContext, movie_timescale), AV_OPT_TYPE_INT, {.i64 = MOV_TIMESCALE}, 1, INT_MAX, AV_OPT_FLAG_ENCODING_PARAM},
9267  { "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 },
9268  { NULL },
9269 };
9270 static const AVCodecTag codec_avif_tags[] = {
9271  { AV_CODEC_ID_AV1, MKTAG('a','v','0','1') },
9272  { AV_CODEC_ID_NONE, 0 },
9273 };
9274 static const AVCodecTag *const codec_avif_tags_list[] = { codec_avif_tags, NULL };
9275 
9276 static const AVClass mov_avif_muxer_class = {
9277  .class_name = "avif muxer",
9278  .item_name = av_default_item_name,
9279  .option = avif_options,
9280  .version = LIBAVUTIL_VERSION_INT,
9281 };
9282 #endif
9283 
9284 #if CONFIG_MOV_MUXER
9285 const FFOutputFormat ff_mov_muxer = {
9286  .p.name = "mov",
9287  .p.long_name = NULL_IF_CONFIG_SMALL("QuickTime / MOV"),
9288  .p.extensions = "mov",
9289  .priv_data_size = sizeof(MOVMuxContext),
9290  .p.audio_codec = AV_CODEC_ID_AAC,
9291  .p.video_codec = CONFIG_LIBX264_ENCODER ?
9293  .init = mov_init,
9294  .write_header = mov_write_header,
9295  .write_packet = mov_write_packet,
9296  .write_trailer = mov_write_trailer,
9297  .deinit = mov_free,
9299  .p.codec_tag = (const AVCodecTag* const []){
9301  },
9302  .check_bitstream = mov_check_bitstream,
9303  .p.priv_class = &mov_isobmff_muxer_class,
9304  .flags_internal = FF_OFMT_FLAG_ALLOW_FLUSH,
9305 };
9306 #endif
9307 #if CONFIG_TGP_MUXER
9308 const FFOutputFormat ff_tgp_muxer = {
9309  .p.name = "3gp",
9310  .p.long_name = NULL_IF_CONFIG_SMALL("3GP (3GPP file format)"),
9311  .p.extensions = "3gp",
9312  .priv_data_size = sizeof(MOVMuxContext),
9313  .p.audio_codec = AV_CODEC_ID_AMR_NB,
9314  .p.video_codec = AV_CODEC_ID_H263,
9315  .init = mov_init,
9316  .write_header = mov_write_header,
9317  .write_packet = mov_write_packet,
9318  .write_trailer = mov_write_trailer,
9319  .deinit = mov_free,
9321  .p.codec_tag = codec_3gp_tags_list,
9322  .check_bitstream = mov_check_bitstream,
9323  .p.priv_class = &mov_isobmff_muxer_class,
9324  .flags_internal = FF_OFMT_FLAG_ALLOW_FLUSH,
9325 };
9326 #endif
9327 #if CONFIG_MP4_MUXER
9328 const FFOutputFormat ff_mp4_muxer = {
9329  .p.name = "mp4",
9330  .p.long_name = NULL_IF_CONFIG_SMALL("MP4 (MPEG-4 Part 14)"),
9331  .p.mime_type = "video/mp4",
9332  .p.extensions = "mp4",
9333  .priv_data_size = sizeof(MOVMuxContext),
9334  .p.audio_codec = AV_CODEC_ID_AAC,
9335  .p.video_codec = CONFIG_LIBX264_ENCODER ?
9337  .init = mov_init,
9338  .write_header = mov_write_header,
9339  .write_packet = mov_write_packet,
9340  .write_trailer = mov_write_trailer,
9341  .deinit = mov_free,
9343  .p.codec_tag = mp4_codec_tags_list,
9344  .check_bitstream = mov_check_bitstream,
9345  .p.priv_class = &mov_isobmff_muxer_class,
9346  .flags_internal = FF_OFMT_FLAG_ALLOW_FLUSH,
9347 };
9348 #endif
9349 #if CONFIG_PSP_MUXER
9350 const FFOutputFormat ff_psp_muxer = {
9351  .p.name = "psp",
9352  .p.long_name = NULL_IF_CONFIG_SMALL("PSP MP4 (MPEG-4 Part 14)"),
9353  .p.extensions = "mp4,psp",
9354  .priv_data_size = sizeof(MOVMuxContext),
9355  .p.audio_codec = AV_CODEC_ID_AAC,
9356  .p.video_codec = CONFIG_LIBX264_ENCODER ?
9358  .init = mov_init,
9359  .write_header = mov_write_header,
9360  .write_packet = mov_write_packet,
9361  .write_trailer = mov_write_trailer,
9362  .deinit = mov_free,
9364  .p.codec_tag = mp4_codec_tags_list,
9365  .check_bitstream = mov_check_bitstream,
9366  .p.priv_class = &mov_isobmff_muxer_class,
9367  .flags_internal = FF_OFMT_FLAG_ALLOW_FLUSH,
9368 };
9369 #endif
9370 #if CONFIG_TG2_MUXER
9371 const FFOutputFormat ff_tg2_muxer = {
9372  .p.name = "3g2",
9373  .p.long_name = NULL_IF_CONFIG_SMALL("3GP2 (3GPP2 file format)"),
9374  .p.extensions = "3g2",
9375  .priv_data_size = sizeof(MOVMuxContext),
9376  .p.audio_codec = AV_CODEC_ID_AMR_NB,
9377  .p.video_codec = AV_CODEC_ID_H263,
9378  .init = mov_init,
9379  .write_header = mov_write_header,
9380  .write_packet = mov_write_packet,
9381  .write_trailer = mov_write_trailer,
9382  .deinit = mov_free,
9384  .p.codec_tag = codec_3gp_tags_list,
9385  .check_bitstream = mov_check_bitstream,
9386  .p.priv_class = &mov_isobmff_muxer_class,
9387  .flags_internal = FF_OFMT_FLAG_ALLOW_FLUSH,
9388 };
9389 #endif
9390 #if CONFIG_IPOD_MUXER
9391 const FFOutputFormat ff_ipod_muxer = {
9392  .p.name = "ipod",
9393  .p.long_name = NULL_IF_CONFIG_SMALL("iPod H.264 MP4 (MPEG-4 Part 14)"),
9394  .p.mime_type = "video/mp4",
9395  .p.extensions = "m4v,m4a,m4b",
9396  .priv_data_size = sizeof(MOVMuxContext),
9397  .p.audio_codec = AV_CODEC_ID_AAC,
9398  .p.video_codec = AV_CODEC_ID_H264,
9399  .init = mov_init,
9400  .write_header = mov_write_header,
9401  .write_packet = mov_write_packet,
9402  .write_trailer = mov_write_trailer,
9403  .deinit = mov_free,
9405  .p.codec_tag = (const AVCodecTag* const []){ codec_ipod_tags, 0 },
9406  .check_bitstream = mov_check_bitstream,
9407  .p.priv_class = &mov_isobmff_muxer_class,
9408  .flags_internal = FF_OFMT_FLAG_ALLOW_FLUSH,
9409 };
9410 #endif
9411 #if CONFIG_ISMV_MUXER
9412 const FFOutputFormat ff_ismv_muxer = {
9413  .p.name = "ismv",
9414  .p.long_name = NULL_IF_CONFIG_SMALL("ISMV/ISMA (Smooth Streaming)"),
9415  .p.mime_type = "video/mp4",
9416  .p.extensions = "ismv,isma",
9417  .priv_data_size = sizeof(MOVMuxContext),
9418  .p.audio_codec = AV_CODEC_ID_AAC,
9419  .p.video_codec = AV_CODEC_ID_H264,
9420  .init = mov_init,
9421  .write_header = mov_write_header,
9422  .write_packet = mov_write_packet,
9423  .write_trailer = mov_write_trailer,
9424  .deinit = mov_free,
9426  .p.codec_tag = (const AVCodecTag* const []){
9428  .check_bitstream = mov_check_bitstream,
9429  .p.priv_class = &mov_isobmff_muxer_class,
9430  .flags_internal = FF_OFMT_FLAG_ALLOW_FLUSH,
9431 };
9432 #endif
9433 #if CONFIG_F4V_MUXER
9434 const FFOutputFormat ff_f4v_muxer = {
9435  .p.name = "f4v",
9436  .p.long_name = NULL_IF_CONFIG_SMALL("F4V Adobe Flash Video"),
9437  .p.mime_type = "application/f4v",
9438  .p.extensions = "f4v",
9439  .priv_data_size = sizeof(MOVMuxContext),
9440  .p.audio_codec = AV_CODEC_ID_AAC,
9441  .p.video_codec = AV_CODEC_ID_H264,
9442  .init = mov_init,
9443  .write_header = mov_write_header,
9444  .write_packet = mov_write_packet,
9445  .write_trailer = mov_write_trailer,
9446  .deinit = mov_free,
9447  .p.flags = AVFMT_GLOBALHEADER,
9448  .p.codec_tag = (const AVCodecTag* const []){ codec_f4v_tags, 0 },
9449  .check_bitstream = mov_check_bitstream,
9450  .p.priv_class = &mov_isobmff_muxer_class,
9451  .flags_internal = FF_OFMT_FLAG_ALLOW_FLUSH,
9452 };
9453 #endif
9454 #if CONFIG_AVIF_MUXER
9455 const FFOutputFormat ff_avif_muxer = {
9456  .p.name = "avif",
9457  .p.long_name = NULL_IF_CONFIG_SMALL("AVIF"),
9458  .p.mime_type = "image/avif",
9459  .p.extensions = "avif",
9460  .priv_data_size = sizeof(MOVMuxContext),
9461  .p.video_codec = AV_CODEC_ID_AV1,
9462  .init = mov_init,
9463  .write_header = mov_write_header,
9464  .write_packet = mov_write_packet,
9465  .write_trailer = avif_write_trailer,
9466  .deinit = mov_free,
9467  .p.flags = AVFMT_GLOBALHEADER,
9468  .p.codec_tag = codec_avif_tags_list,
9469  .p.priv_class = &mov_avif_muxer_class,
9470  .flags_internal = FF_OFMT_FLAG_ALLOW_FLUSH,
9471 };
9472 #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:9237
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:5845
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:6119
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:5780
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:7353
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:5655
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:5583
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:6860
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:8094
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:7848
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:8667
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:8860
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:5833
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:6209
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:6618
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:5819
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:8955
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:7513
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:6095
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:6431
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:5574
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:8878
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:7783
codec_f4v_tags
static const AVCodecTag codec_f4v_tags[]
Definition: movenc.c:9254
mov_create_timecode_track
static int mov_create_timecode_track(AVFormatContext *s, int index, int src_index, AVTimecode tc)
Definition: movenc.c:7792
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:7541
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:8847
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:6874
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:6594
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:5887
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:5432
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:5450
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:7444
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:8903
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:9243
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:9172
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:7965
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:8918
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:7890
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:6331
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:6909
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:8933
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:6512
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:9080
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:5589
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:6061
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:6650
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:7949
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:7692
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:6168
mov_write_prft_tag
static int mov_write_prft_tag(AVIOContext *pb, MOVMuxContext *mov, int tracks)
Definition: movenc.c:6011
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:6402
mov_write_sidx_tags
static int mov_write_sidx_tags(AVIOContext *pb, MOVMuxContext *mov, int tracks, int ref_size)
Definition: movenc.c:5973
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:6531
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:5442
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:6452
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:6556
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:5437
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:6157
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:5731
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:5766
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:5711
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:5912
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