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