FFmpeg
movenc.c
Go to the documentation of this file.
1 /*
2  * MOV, 3GP, MP4 muxer
3  * Copyright (c) 2003 Thomas Raivio
4  * Copyright (c) 2004 Gildas Bazin <gbazin at videolan dot org>
5  * Copyright (c) 2009 Baptiste Coudurier <baptiste dot coudurier at gmail dot com>
6  *
7  * This file is part of FFmpeg.
8  *
9  * FFmpeg is free software; you can redistribute it and/or
10  * modify it under the terms of the GNU Lesser General Public
11  * License as published by the Free Software Foundation; either
12  * version 2.1 of the License, or (at your option) any later version.
13  *
14  * FFmpeg is distributed in the hope that it will be useful,
15  * but WITHOUT ANY WARRANTY; without even the implied warranty of
16  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
17  * Lesser General Public License for more details.
18  *
19  * You should have received a copy of the GNU Lesser General Public
20  * License along with FFmpeg; if not, write to the Free Software
21  * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
22  */
23 
24 #include "config_components.h"
25 
26 #include <stdint.h>
27 #include <inttypes.h>
28 
29 #include "movenc.h"
30 #include "avformat.h"
31 #include "avio_internal.h"
32 #include "dovi_isom.h"
33 #include "riff.h"
34 #include "avio.h"
35 #include "iamf_writer.h"
36 #include "isom.h"
37 #include "av1.h"
38 #include "avc.h"
39 #include "evc.h"
40 #include "apv.h"
41 #include "lcevc.h"
43 #include "libavcodec/dnxhddata.h"
44 #include "libavcodec/flac.h"
45 #include "libavcodec/get_bits.h"
46 
47 #include "libavcodec/internal.h"
48 #include "libavcodec/put_bits.h"
49 #include "libavcodec/vc1_common.h"
50 #include "libavcodec/raw.h"
51 #include "internal.h"
52 #include "libavutil/avstring.h"
54 #include "libavutil/csp.h"
55 #include "libavutil/intfloat.h"
56 #include "libavutil/mathematics.h"
57 #include "libavutil/libm.h"
58 #include "libavutil/mem.h"
59 #include "libavutil/opt.h"
60 #include "libavutil/dict.h"
61 #include "libavutil/pixdesc.h"
62 #include "libavutil/stereo3d.h"
63 #include "libavutil/timecode.h"
64 #include "libavutil/dovi_meta.h"
65 #include "libavutil/uuid.h"
66 #include "hevc.h"
67 #include "rtpenc.h"
68 #include "nal.h"
69 #include "mov_chan.h"
70 #include "movenc_ttml.h"
71 #include "mux.h"
72 #include "rawutils.h"
73 #include "ttmlenc.h"
74 #include "version.h"
75 #include "vpcc.h"
76 #include "vvc.h"
77 
78 static const AVOption options[] = {
79  { "brand", "Override major brand", offsetof(MOVMuxContext, major_brand), AV_OPT_TYPE_STRING, {.str = NULL}, .flags = AV_OPT_FLAG_ENCODING_PARAM },
80  { "empty_hdlr_name", "write zero-length name string in hdlr atoms within mdia and minf atoms", offsetof(MOVMuxContext, empty_hdlr_name), AV_OPT_TYPE_BOOL, {.i64 = 0}, 0, 1, AV_OPT_FLAG_ENCODING_PARAM},
81  { "encryption_key", "The media encryption key (hex)", offsetof(MOVMuxContext, encryption_key), AV_OPT_TYPE_BINARY, .flags = AV_OPT_FLAG_ENCODING_PARAM },
82  { "encryption_kid", "The media encryption key identifier (hex)", offsetof(MOVMuxContext, encryption_kid), AV_OPT_TYPE_BINARY, .flags = AV_OPT_FLAG_ENCODING_PARAM },
83  { "encryption_scheme", "Configures the encryption scheme, allowed values are none, cenc-aes-ctr", offsetof(MOVMuxContext, encryption_scheme_str), AV_OPT_TYPE_STRING, {.str = NULL}, .flags = AV_OPT_FLAG_ENCODING_PARAM },
84  { "frag_duration", "Maximum fragment duration", offsetof(MOVMuxContext, max_fragment_duration), AV_OPT_TYPE_INT, {.i64 = 0}, 0, INT_MAX, AV_OPT_FLAG_ENCODING_PARAM},
85  { "frag_interleave", "Interleave samples within fragments (max number of consecutive samples, lower is tighter interleaving, but with more overhead)", offsetof(MOVMuxContext, frag_interleave), AV_OPT_TYPE_INT, {.i64 = 0}, 0, INT_MAX, AV_OPT_FLAG_ENCODING_PARAM },
86  { "frag_size", "Maximum fragment size", offsetof(MOVMuxContext, max_fragment_size), AV_OPT_TYPE_INT, {.i64 = 0}, 0, INT_MAX, AV_OPT_FLAG_ENCODING_PARAM},
87  { "fragment_index", "Fragment number of the next fragment", offsetof(MOVMuxContext, fragments), AV_OPT_TYPE_INT, {.i64 = 1}, 1, INT_MAX, AV_OPT_FLAG_ENCODING_PARAM},
88  { "iods_audio_profile", "iods audio profile atom.", offsetof(MOVMuxContext, iods_audio_profile), AV_OPT_TYPE_INT, {.i64 = -1}, -1, 255, AV_OPT_FLAG_ENCODING_PARAM},
89  { "iods_video_profile", "iods video profile atom.", offsetof(MOVMuxContext, iods_video_profile), AV_OPT_TYPE_INT, {.i64 = -1}, -1, 255, AV_OPT_FLAG_ENCODING_PARAM},
90  { "ism_lookahead", "Number of lookahead entries for ISM files", offsetof(MOVMuxContext, ism_lookahead), AV_OPT_TYPE_INT, {.i64 = 0}, 0, 255, AV_OPT_FLAG_ENCODING_PARAM},
91  { "movflags", "MOV muxer flags", offsetof(MOVMuxContext, flags), AV_OPT_TYPE_FLAGS, {.i64 = 0}, INT_MIN, INT_MAX, AV_OPT_FLAG_ENCODING_PARAM, .unit = "movflags" },
92  { "cmaf", "Write CMAF compatible fragmented MP4", 0, AV_OPT_TYPE_CONST, {.i64 = FF_MOV_FLAG_CMAF}, INT_MIN, INT_MAX, AV_OPT_FLAG_ENCODING_PARAM, .unit = "movflags" },
93  { "dash", "Write DASH compatible fragmented MP4", 0, AV_OPT_TYPE_CONST, {.i64 = FF_MOV_FLAG_DASH}, INT_MIN, INT_MAX, AV_OPT_FLAG_ENCODING_PARAM, .unit = "movflags" },
94  { "default_base_moof", "Set the default-base-is-moof flag in tfhd atoms", 0, AV_OPT_TYPE_CONST, {.i64 = FF_MOV_FLAG_DEFAULT_BASE_MOOF}, INT_MIN, INT_MAX, AV_OPT_FLAG_ENCODING_PARAM, .unit = "movflags" },
95  { "delay_moov", "Delay writing the initial moov until the first fragment is cut, or until the first fragment flush", 0, AV_OPT_TYPE_CONST, {.i64 = FF_MOV_FLAG_DELAY_MOOV}, INT_MIN, INT_MAX, AV_OPT_FLAG_ENCODING_PARAM, .unit = "movflags" },
96  { "disable_chpl", "Disable Nero chapter atom", 0, AV_OPT_TYPE_CONST, {.i64 = FF_MOV_FLAG_DISABLE_CHPL}, INT_MIN, INT_MAX, AV_OPT_FLAG_ENCODING_PARAM, .unit = "movflags" },
97  { "empty_moov", "Make the initial moov atom empty", 0, AV_OPT_TYPE_CONST, {.i64 = FF_MOV_FLAG_EMPTY_MOOV}, INT_MIN, INT_MAX, AV_OPT_FLAG_ENCODING_PARAM, .unit = "movflags" },
98  { "faststart", "Run a second pass to put the index (moov atom) at the beginning of the file", 0, AV_OPT_TYPE_CONST, {.i64 = FF_MOV_FLAG_FASTSTART}, INT_MIN, INT_MAX, AV_OPT_FLAG_ENCODING_PARAM, .unit = "movflags" },
99  { "frag_custom", "Flush fragments on caller requests", 0, AV_OPT_TYPE_CONST, {.i64 = FF_MOV_FLAG_FRAG_CUSTOM}, INT_MIN, INT_MAX, AV_OPT_FLAG_ENCODING_PARAM, .unit = "movflags" },
100  { "frag_discont", "Signal that the next fragment is discontinuous from earlier ones", 0, AV_OPT_TYPE_CONST, {.i64 = FF_MOV_FLAG_FRAG_DISCONT}, INT_MIN, INT_MAX, AV_OPT_FLAG_ENCODING_PARAM, .unit = "movflags" },
101  { "frag_every_frame", "Fragment at every frame", 0, AV_OPT_TYPE_CONST, {.i64 = FF_MOV_FLAG_FRAG_EVERY_FRAME}, INT_MIN, INT_MAX, AV_OPT_FLAG_ENCODING_PARAM, .unit = "movflags" },
102  { "frag_keyframe", "Fragment at video keyframes", 0, AV_OPT_TYPE_CONST, {.i64 = FF_MOV_FLAG_FRAG_KEYFRAME}, INT_MIN, INT_MAX, AV_OPT_FLAG_ENCODING_PARAM, .unit = "movflags" },
103  { "global_sidx", "Write a global sidx index at the start of the file", 0, AV_OPT_TYPE_CONST, {.i64 = FF_MOV_FLAG_GLOBAL_SIDX}, INT_MIN, INT_MAX, AV_OPT_FLAG_ENCODING_PARAM, .unit = "movflags" },
104  { "isml", "Create a live smooth streaming feed (for pushing to a publishing point)", 0, AV_OPT_TYPE_CONST, {.i64 = FF_MOV_FLAG_ISML}, INT_MIN, INT_MAX, AV_OPT_FLAG_ENCODING_PARAM, .unit = "movflags" },
105  { "moov_size", "maximum moov size so it can be placed at the begin", offsetof(MOVMuxContext, reserved_moov_size), AV_OPT_TYPE_INT, {.i64 = 0}, 0, INT_MAX, AV_OPT_FLAG_ENCODING_PARAM, .unit = 0 },
106  { "negative_cts_offsets", "Use negative CTS offsets (reducing the need for edit lists)", 0, AV_OPT_TYPE_CONST, {.i64 = FF_MOV_FLAG_NEGATIVE_CTS_OFFSETS}, INT_MIN, INT_MAX, AV_OPT_FLAG_ENCODING_PARAM, .unit = "movflags" },
107  { "omit_tfhd_offset", "Omit the base data offset in tfhd atoms", 0, AV_OPT_TYPE_CONST, {.i64 = FF_MOV_FLAG_OMIT_TFHD_OFFSET}, INT_MIN, INT_MAX, AV_OPT_FLAG_ENCODING_PARAM, .unit = "movflags" },
108  { "prefer_icc", "If writing colr atom prioritise usage of ICC profile if it exists in stream packet side data", 0, AV_OPT_TYPE_CONST, {.i64 = FF_MOV_FLAG_PREFER_ICC}, INT_MIN, INT_MAX, AV_OPT_FLAG_ENCODING_PARAM, .unit = "movflags" },
109  { "rtphint", "Add RTP hint tracks", 0, AV_OPT_TYPE_CONST, {.i64 = FF_MOV_FLAG_RTP_HINT}, INT_MIN, INT_MAX, AV_OPT_FLAG_ENCODING_PARAM, .unit = "movflags" },
110  { "separate_moof", "Write separate moof/mdat atoms for each track", 0, AV_OPT_TYPE_CONST, {.i64 = FF_MOV_FLAG_SEPARATE_MOOF}, INT_MIN, INT_MAX, AV_OPT_FLAG_ENCODING_PARAM, .unit = "movflags" },
111  { "skip_sidx", "Skip writing of sidx atom", 0, AV_OPT_TYPE_CONST, {.i64 = FF_MOV_FLAG_SKIP_SIDX}, INT_MIN, INT_MAX, AV_OPT_FLAG_ENCODING_PARAM, .unit = "movflags" },
112  { "skip_trailer", "Skip writing the mfra/tfra/mfro trailer for fragmented files", 0, AV_OPT_TYPE_CONST, {.i64 = FF_MOV_FLAG_SKIP_TRAILER}, INT_MIN, INT_MAX, AV_OPT_FLAG_ENCODING_PARAM, .unit = "movflags" },
113  { "use_metadata_tags", "Use mdta atom for metadata.", 0, AV_OPT_TYPE_CONST, {.i64 = FF_MOV_FLAG_USE_MDTA}, INT_MIN, INT_MAX, AV_OPT_FLAG_ENCODING_PARAM, .unit = "movflags" },
114  { "write_colr", "Write colr atom even if the color info is unspecified (Experimental, may be renamed or changed, do not use from scripts)", 0, AV_OPT_TYPE_CONST, {.i64 = FF_MOV_FLAG_WRITE_COLR}, INT_MIN, INT_MAX, AV_OPT_FLAG_ENCODING_PARAM, .unit = "movflags" },
115  { "write_gama", "Write deprecated gama atom", 0, AV_OPT_TYPE_CONST, {.i64 = FF_MOV_FLAG_WRITE_GAMA}, INT_MIN, INT_MAX, AV_OPT_FLAG_ENCODING_PARAM, .unit = "movflags" },
116  { "hybrid_fragmented", "For recoverability, write a fragmented file that is converted to non-fragmented at the end.", 0, AV_OPT_TYPE_CONST, {.i64 = FF_MOV_FLAG_HYBRID_FRAGMENTED}, INT_MIN, INT_MAX, AV_OPT_FLAG_ENCODING_PARAM, .unit = "movflags" },
117  { "min_frag_duration", "Minimum fragment duration", offsetof(MOVMuxContext, min_fragment_duration), AV_OPT_TYPE_INT, {.i64 = 0}, 0, INT_MAX, AV_OPT_FLAG_ENCODING_PARAM},
118  { "mov_gamma", "gamma value for gama atom", offsetof(MOVMuxContext, gamma), AV_OPT_TYPE_FLOAT, {.dbl = 0.0 }, 0.0, 10, AV_OPT_FLAG_ENCODING_PARAM},
119  { "movie_timescale", "set movie timescale", offsetof(MOVMuxContext, movie_timescale), AV_OPT_TYPE_INT, {.i64 = 0}, 0, INT_MAX, AV_OPT_FLAG_ENCODING_PARAM},
120  FF_RTP_FLAG_OPTS(MOVMuxContext, rtp_flags),
121  { "skip_iods", "Skip writing iods atom.", offsetof(MOVMuxContext, iods_skip), AV_OPT_TYPE_BOOL, {.i64 = 1}, 0, 1, AV_OPT_FLAG_ENCODING_PARAM},
122  { "use_editlist", "use edit list", offsetof(MOVMuxContext, use_editlist), AV_OPT_TYPE_BOOL, {.i64 = -1}, -1, 1, AV_OPT_FLAG_ENCODING_PARAM},
123  { "use_stream_ids_as_track_ids", "use stream ids as track ids", offsetof(MOVMuxContext, use_stream_ids_as_track_ids), AV_OPT_TYPE_BOOL, {.i64 = 0}, 0, 1, AV_OPT_FLAG_ENCODING_PARAM},
124  { "video_track_timescale", "set timescale of all video tracks", offsetof(MOVMuxContext, video_track_timescale), AV_OPT_TYPE_INT, {.i64 = 0}, 0, INT_MAX, AV_OPT_FLAG_ENCODING_PARAM},
125  { "write_btrt", "force or disable writing btrt", offsetof(MOVMuxContext, write_btrt), AV_OPT_TYPE_BOOL, {.i64 = -1}, -1, 1, AV_OPT_FLAG_ENCODING_PARAM},
126  { "write_prft", "Write producer reference time box with specified time source", offsetof(MOVMuxContext, write_prft), AV_OPT_TYPE_INT, {.i64 = MOV_PRFT_NONE}, 0, MOV_PRFT_NB-1, AV_OPT_FLAG_ENCODING_PARAM, .unit = "prft"},
127  { "pts", NULL, 0, AV_OPT_TYPE_CONST, {.i64 = MOV_PRFT_SRC_PTS}, 0, 0, AV_OPT_FLAG_ENCODING_PARAM, .unit = "prft"},
128  { "wallclock", NULL, 0, AV_OPT_TYPE_CONST, {.i64 = MOV_PRFT_SRC_WALLCLOCK}, 0, 0, AV_OPT_FLAG_ENCODING_PARAM, .unit = "prft"},
129  { "write_tmcd", "force or disable writing tmcd", offsetof(MOVMuxContext, write_tmcd), AV_OPT_TYPE_BOOL, {.i64 = -1}, -1, 1, AV_OPT_FLAG_ENCODING_PARAM},
130  { NULL },
131 };
132 
134  .class_name = "mov/mp4/tgp/psp/tg2/ipod/ismv/f4v muxer",
135  .item_name = av_default_item_name,
136  .option = options,
137  .version = LIBAVUTIL_VERSION_INT,
138 };
139 
140 static int get_moov_size(AVFormatContext *s);
142 
143 static int utf8len(const uint8_t *b)
144 {
145  int len = 0;
146  int val;
147  while (*b) {
148  GET_UTF8(val, *b++, return -1;)
149  len++;
150  }
151  return len;
152 }
153 
154 //FIXME support 64 bit variant with wide placeholders
156 {
157  int64_t curpos = avio_tell(pb);
158  avio_seek(pb, pos, SEEK_SET);
159  avio_wb32(pb, curpos - pos); /* rewrite size */
160  avio_seek(pb, curpos, SEEK_SET);
161 
162  return curpos - pos;
163 }
164 
166 {
167  int64_t curpos = avio_tell(pb);
168  avio_seek(pb, pos, SEEK_SET);
169  avio_wb32(pb, curpos - pos); /* rewrite size */
170  avio_skip(pb, 4);
171  avio_w8(pb, version); /* rewrite version */
172  avio_seek(pb, curpos, SEEK_SET);
173 
174  return curpos - pos;
175 }
176 
177 static int co64_required(const MOVTrack *track)
178 {
179  if (track->entry > 0 && track->cluster[track->entry - 1].pos + track->data_offset > UINT32_MAX)
180  return 1;
181  return 0;
182 }
183 
184 static int is_cover_image(const AVStream *st)
185 {
186  /* Eg. AV_DISPOSITION_ATTACHED_PIC | AV_DISPOSITION_TIMED_THUMBNAILS
187  * is encoded as sparse video track */
188  return st && st->disposition == AV_DISPOSITION_ATTACHED_PIC;
189 }
190 
191 static int rtp_hinting_needed(const AVStream *st)
192 {
193  /* Add hint tracks for each real audio and video stream */
194  if (is_cover_image(st))
195  return 0;
196  return st->codecpar->codec_type == AVMEDIA_TYPE_VIDEO ||
198 }
199 
200 /* Chunk offset atom */
201 static int mov_write_stco_tag(AVIOContext *pb, MOVTrack *track)
202 {
203  int i;
204  int mode64 = co64_required(track); // use 32 bit size variant if possible
205  int64_t pos = avio_tell(pb);
206  avio_wb32(pb, 0); /* size */
207  if (mode64)
208  ffio_wfourcc(pb, "co64");
209  else
210  ffio_wfourcc(pb, "stco");
211  avio_wb32(pb, 0); /* version & flags */
212  avio_wb32(pb, track->chunkCount); /* entry count */
213  for (i = 0; i < track->entry; i++) {
214  if (!track->cluster[i].chunkNum)
215  continue;
216  if (mode64 == 1)
217  avio_wb64(pb, track->cluster[i].pos + track->data_offset);
218  else
219  avio_wb32(pb, track->cluster[i].pos + track->data_offset);
220  }
221  return update_size(pb, pos);
222 }
223 
224 /* Sample size atom */
225 static int mov_write_stsz_tag(AVIOContext *pb, MOVTrack *track)
226 {
227  int equalChunks = 1;
228  int i, j, entries = 0, tst = -1, oldtst = -1;
229 
230  int64_t pos = avio_tell(pb);
231  avio_wb32(pb, 0); /* size */
232  ffio_wfourcc(pb, "stsz");
233  avio_wb32(pb, 0); /* version & flags */
234 
235  for (i = 0; i < track->entry; i++) {
236  tst = track->cluster[i].size / track->cluster[i].entries;
237  if (oldtst != -1 && tst != oldtst)
238  equalChunks = 0;
239  oldtst = tst;
240  entries += track->cluster[i].entries;
241  }
242  if (equalChunks && track->entry) {
243  int sSize = track->entry ? track->cluster[0].size / track->cluster[0].entries : 0;
244  sSize = FFMAX(1, sSize); // adpcm mono case could make sSize == 0
245  avio_wb32(pb, sSize); // sample size
246  avio_wb32(pb, entries); // sample count
247  } else {
248  avio_wb32(pb, 0); // sample size
249  avio_wb32(pb, entries); // sample count
250  for (i = 0; i < track->entry; i++) {
251  for (j = 0; j < track->cluster[i].entries; j++) {
252  avio_wb32(pb, track->cluster[i].size /
253  track->cluster[i].entries);
254  }
255  }
256  }
257  return update_size(pb, pos);
258 }
259 
260 /* Sample to chunk atom */
261 static int mov_write_stsc_tag(AVIOContext *pb, MOVTrack *track)
262 {
263  int index = 0, oldidx = -1, oldval = -1, i;
264  int64_t entryPos, curpos;
265 
266  int64_t pos = avio_tell(pb);
267  avio_wb32(pb, 0); /* size */
268  ffio_wfourcc(pb, "stsc");
269  avio_wb32(pb, 0); // version & flags
270  entryPos = avio_tell(pb);
271  avio_wb32(pb, track->chunkCount); // entry count
272  for (i = 0; i < track->entry; i++) {
273  if ((oldval != track->cluster[i].samples_in_chunk ||
274  oldidx != track->cluster[i].stsd_index) && track->cluster[i].chunkNum) {
275  avio_wb32(pb, track->cluster[i].chunkNum); // first chunk
276  avio_wb32(pb, track->cluster[i].samples_in_chunk); // samples per chunk
277  avio_wb32(pb, track->cluster[i].stsd_index + 1); // sample description index
278  oldval = track->cluster[i].samples_in_chunk;
279  oldidx = track->cluster[i].stsd_index;
280  index++;
281  }
282  }
283  curpos = avio_tell(pb);
284  avio_seek(pb, entryPos, SEEK_SET);
285  avio_wb32(pb, index); // rewrite size
286  avio_seek(pb, curpos, SEEK_SET);
287 
288  return update_size(pb, pos);
289 }
290 
291 /* Sync sample atom */
292 static int mov_write_stss_tag(AVIOContext *pb, MOVTrack *track, uint32_t flag)
293 {
294  int64_t curpos, entryPos;
295  int i, index = 0;
296  int64_t pos = avio_tell(pb);
297  avio_wb32(pb, 0); // size
298  ffio_wfourcc(pb, flag == MOV_SYNC_SAMPLE ? "stss" : "stps");
299  avio_wb32(pb, 0); // version & flags
300  entryPos = avio_tell(pb);
301  avio_wb32(pb, track->entry); // entry count
302  for (i = 0; i < track->entry; i++) {
303  if (track->cluster[i].flags & flag) {
304  avio_wb32(pb, i + 1);
305  index++;
306  }
307  }
308  curpos = avio_tell(pb);
309  avio_seek(pb, entryPos, SEEK_SET);
310  avio_wb32(pb, index); // rewrite size
311  avio_seek(pb, curpos, SEEK_SET);
312  return update_size(pb, pos);
313 }
314 
315 /* Sample dependency atom */
316 static int mov_write_sdtp_tag(AVIOContext *pb, MOVTrack *track)
317 {
318  int i;
319  uint8_t leading, dependent, reference, redundancy;
320  int64_t pos = avio_tell(pb);
321  avio_wb32(pb, 0); // size
322  ffio_wfourcc(pb, "sdtp");
323  avio_wb32(pb, 0); // version & flags
324  for (i = 0; i < track->entry; i++) {
325  dependent = MOV_SAMPLE_DEPENDENCY_YES;
326  leading = reference = redundancy = MOV_SAMPLE_DEPENDENCY_UNKNOWN;
327  if (track->cluster[i].flags & MOV_DISPOSABLE_SAMPLE) {
328  reference = MOV_SAMPLE_DEPENDENCY_NO;
329  }
330  if (track->cluster[i].flags & MOV_SYNC_SAMPLE) {
331  dependent = MOV_SAMPLE_DEPENDENCY_NO;
332  }
333  avio_w8(pb, (leading << 6) | (dependent << 4) |
334  (reference << 2) | redundancy);
335  }
336  return update_size(pb, pos);
337 }
338 
339 #if CONFIG_IAMFENC
340 static int mov_write_iacb_tag(AVFormatContext *s, AVIOContext *pb, MOVTrack *track)
341 {
342  AVIOContext *dyn_bc;
343  int64_t pos = avio_tell(pb);
344  uint8_t *dyn_buf = NULL;
345  int dyn_size;
346  int ret = avio_open_dyn_buf(&dyn_bc);
347  if (ret < 0)
348  return ret;
349 
350  avio_wb32(pb, 0);
351  ffio_wfourcc(pb, "iacb");
352  avio_w8(pb, 1); // configurationVersion
353 
354  ret = ff_iamf_write_descriptors(track->iamf, dyn_bc, s);
355  if (ret < 0) {
356  ffio_free_dyn_buf(&dyn_bc);
357  return ret;
358  }
359 
360  dyn_size = avio_close_dyn_buf(dyn_bc, &dyn_buf);
361  ffio_write_leb(pb, dyn_size);
362  avio_write(pb, dyn_buf, dyn_size);
363  av_free(dyn_buf);
364 
365  return update_size(pb, pos);
366 }
367 #endif
368 
369 static int mov_write_amr_tag(AVIOContext *pb, MOVTrack *track)
370 {
371  avio_wb32(pb, 0x11); /* size */
372  if (track->mode == MODE_MOV) ffio_wfourcc(pb, "samr");
373  else ffio_wfourcc(pb, "damr");
374  ffio_wfourcc(pb, "FFMP");
375  avio_w8(pb, 0); /* decoder version */
376 
377  avio_wb16(pb, 0x81FF); /* Mode set (all modes for AMR_NB) */
378  avio_w8(pb, 0x00); /* Mode change period (no restriction) */
379  avio_w8(pb, 0x01); /* Frames per sample */
380  return 0x11;
381 }
382 
383 struct eac3_info {
385  uint8_t eof;
386  uint8_t ec3_done;
387  uint8_t num_blocks;
388 
389  /* Layout of the EC3SpecificBox */
390  /* maximum bitrate */
391  uint16_t data_rate;
393  /* number of independent substreams */
394  uint8_t num_ind_sub;
395  struct {
396  /* sample rate code (see ff_ac3_sample_rate_tab) 2 bits */
397  uint8_t fscod;
398  /* bit stream identification 5 bits */
399  uint8_t bsid;
400  /* one bit reserved */
401  /* audio service mixing (not supported yet) 1 bit */
402  /* bit stream mode 3 bits */
403  uint8_t bsmod;
404  /* audio coding mode 3 bits */
405  uint8_t acmod;
406  /* sub woofer on 1 bit */
407  uint8_t lfeon;
408  /* 3 bits reserved */
409  /* number of dependent substreams associated with this substream 4 bits */
410  uint8_t num_dep_sub;
411  /* channel locations of the dependent substream(s), if any, 9 bits */
412  uint16_t chan_loc;
413  /* if there is no dependent substream, then one bit reserved instead */
414  } substream[1]; /* TODO: support 8 independent substreams */
415  /* indicates the decoding complexity, 8 bits */
417 };
418 
420 {
421  struct eac3_info *info = track->eac3_priv;
422  PutBitContext pbc;
423  uint8_t buf[3];
424 
425  if (!info || !info->ec3_done) {
427  "Cannot write moov atom before AC3 packets."
428  " Set the delay_moov flag to fix this.\n");
429  return AVERROR(EINVAL);
430  }
431 
432  if (info->substream[0].bsid > 8) {
434  "RealAudio AC-3/DolbyNet with bsid %d is not defined by the "
435  "ISOBMFF specification in ETSI TS 102 366!\n",
436  info->substream[0].bsid);
437  return AVERROR(EINVAL);
438  }
439 
440  if (info->ac3_bit_rate_code < 0) {
442  "No valid AC3 bit rate code for data rate of %d!\n",
443  info->data_rate);
444  return AVERROR(EINVAL);
445  }
446 
447  avio_wb32(pb, 11);
448  ffio_wfourcc(pb, "dac3");
449 
450  init_put_bits(&pbc, buf, sizeof(buf));
451  put_bits(&pbc, 2, info->substream[0].fscod);
452  put_bits(&pbc, 5, info->substream[0].bsid);
453  put_bits(&pbc, 3, info->substream[0].bsmod);
454  put_bits(&pbc, 3, info->substream[0].acmod);
455  put_bits(&pbc, 1, info->substream[0].lfeon);
456  put_bits(&pbc, 5, info->ac3_bit_rate_code); // bit_rate_code
457  put_bits(&pbc, 5, 0); // reserved
458 
459  flush_put_bits(&pbc);
460  avio_write(pb, buf, sizeof(buf));
461 
462  return 11;
463 }
464 
465 static int handle_eac3(MOVMuxContext *mov, AVPacket *pkt, MOVTrack *track)
466 {
467  AC3HeaderInfo *hdr = NULL;
468  struct eac3_info *info;
469  int num_blocks, ret;
470 
471  if (!track->eac3_priv) {
472  if (!(track->eac3_priv = av_mallocz(sizeof(*info))))
473  return AVERROR(ENOMEM);
474 
475  ((struct eac3_info *)track->eac3_priv)->ac3_bit_rate_code = -1;
476  }
477  info = track->eac3_priv;
478 
479  if (!info->pkt && !(info->pkt = av_packet_alloc()))
480  return AVERROR(ENOMEM);
481 
482  if (info->eof) {
483  av_assert1(!info->pkt->size);
484  ret = pkt->size;
485  goto end;
486  }
487 
488  if ((ret = avpriv_ac3_parse_header(&hdr, pkt->data, pkt->size)) < 0) {
489  if (ret == AVERROR(ENOMEM))
490  goto end;
491 
492  /* drop the packets until we see a good one */
493  if (!track->entry) {
494  av_log(mov->fc, AV_LOG_WARNING, "Dropping invalid packet from start of the stream\n");
495  ret = 0;
496  } else
498  goto end;
499  }
500 
501  info->data_rate = FFMAX(info->data_rate, hdr->bit_rate / 1000);
502  info->ac3_bit_rate_code = FFMAX(info->ac3_bit_rate_code,
503  hdr->ac3_bit_rate_code);
504  info->complexity_index_type_a = hdr->complexity_index_type_a;
505 
506  num_blocks = hdr->num_blocks;
507 
508  if (!info->ec3_done) {
509  /* AC-3 substream must be the first one */
510  if (hdr->bitstream_id <= 10 && hdr->substreamid != 0) {
511  ret = AVERROR(EINVAL);
512  goto end;
513  }
514 
515  /* this should always be the case, given that our AC-3 parser
516  * concatenates dependent frames to their independent parent */
519  /* substream ids must be incremental */
520  if (hdr->substreamid > info->num_ind_sub + 1) {
521  ret = AVERROR(EINVAL);
522  goto end;
523  }
524 
525  if (hdr->substreamid == info->num_ind_sub + 1) {
526  //info->num_ind_sub++;
527  avpriv_request_sample(mov->fc, "Multiple independent substreams");
529  goto end;
530  } else if (hdr->substreamid < info->num_ind_sub ||
531  hdr->substreamid == 0 && info->substream[0].bsid) {
532  info->ec3_done = 1;
533  goto concatenate;
534  }
535  } else {
536  if (hdr->substreamid != 0) {
537  avpriv_request_sample(mov->fc, "Multiple non EAC3 independent substreams");
539  goto end;
540  }
541  }
542 
543  /* fill the info needed for the "dec3" atom */
544  info->substream[hdr->substreamid].fscod = hdr->sr_code;
545  info->substream[hdr->substreamid].bsid = hdr->bitstream_id;
546  info->substream[hdr->substreamid].bsmod = hdr->bitstream_mode;
547  info->substream[hdr->substreamid].acmod = hdr->channel_mode;
548  info->substream[hdr->substreamid].lfeon = hdr->lfe_on;
549 
550  if (track->par->codec_id == AV_CODEC_ID_AC3) {
551  // with AC-3 we only require the information of a single packet,
552  // so we can finish as soon as the basic values of the bit stream
553  // have been set to the track's informational structure.
554  info->ec3_done = 1;
555  goto concatenate;
556  }
557 
558  /* Parse dependent substream(s), if any */
559  if (pkt->size != hdr->frame_size) {
560  int cumul_size = hdr->frame_size;
561  int parent = hdr->substreamid;
562 
563  while (cumul_size != pkt->size) {
564  ret = avpriv_ac3_parse_header(&hdr, pkt->data + cumul_size, pkt->size - cumul_size);
565  if (ret < 0)
566  goto end;
568  ret = AVERROR(EINVAL);
569  goto end;
570  }
571  info->substream[parent].num_dep_sub++;
572  ret /= 8;
573 
574  /* get the dependent stream channel map, if exists */
575  if (hdr->channel_map_present)
576  info->substream[parent].chan_loc |= (hdr->channel_map >> 5) & 0x1f;
577  else
578  info->substream[parent].chan_loc |= hdr->channel_mode;
579  cumul_size += hdr->frame_size;
580  }
581  }
582  }
583 
584 concatenate:
585  if (!info->num_blocks && num_blocks == 6) {
586  ret = pkt->size;
587  goto end;
588  }
589  else if (info->num_blocks + num_blocks > 6) {
591  goto end;
592  }
593 
594  if (!info->num_blocks) {
595  ret = av_packet_ref(info->pkt, pkt);
596  if (!ret)
597  info->num_blocks = num_blocks;
598  goto end;
599  } else {
600  const AVPacketSideData *sd;
602  if ((ret = av_grow_packet(info->pkt, pkt->size)) < 0)
603  goto end;
605  if (sd && sd->size >= 10) {
606  uint8_t *buf = av_packet_new_side_data(info->pkt, AV_PKT_DATA_SKIP_SAMPLES, sd->size);
607  if (buf)
608  memcpy(buf, sd->data, sd->size);
609  if (track->par->frame_size)
610  duration = FFMAX(av_rescale_q(track->par->frame_size, (AVRational){ 1, track->par->sample_rate },
611  track->st->time_base), duration);
612  }
613  memcpy(info->pkt->data + info->pkt->size - pkt->size, pkt->data, pkt->size);
614  info->num_blocks += num_blocks;
615  info->pkt->duration += duration;
616  if (info->num_blocks != 6)
617  goto end;
619  av_packet_move_ref(pkt, info->pkt);
620  info->num_blocks = 0;
621  }
622  ret = pkt->size;
623 
624 end:
625  av_free(hdr);
626 
627  return ret;
628 }
629 
631 {
632  PutBitContext pbc;
633  uint8_t *buf;
634  struct eac3_info *info;
635  int size, i;
636 
637  if (!track->eac3_priv) {
639  "Cannot write moov atom before EAC3 packets parsed.\n");
640  return AVERROR(EINVAL);
641  }
642 
643  info = track->eac3_priv;
644  size = 2 + (4 * (info->num_ind_sub + 1)) + (2 * !!info->complexity_index_type_a);
645  buf = av_malloc(size);
646  if (!buf) {
647  return AVERROR(ENOMEM);
648  }
649 
650  init_put_bits(&pbc, buf, size);
651  put_bits(&pbc, 13, info->data_rate);
652  put_bits(&pbc, 3, info->num_ind_sub);
653  for (i = 0; i <= info->num_ind_sub; i++) {
654  put_bits(&pbc, 2, info->substream[i].fscod);
655  put_bits(&pbc, 5, info->substream[i].bsid);
656  put_bits(&pbc, 1, 0); /* reserved */
657  put_bits(&pbc, 1, 0); /* asvc */
658  put_bits(&pbc, 3, info->substream[i].bsmod);
659  put_bits(&pbc, 3, info->substream[i].acmod);
660  put_bits(&pbc, 1, info->substream[i].lfeon);
661  put_bits(&pbc, 3, 0); /* reserved */
662  put_bits(&pbc, 4, info->substream[i].num_dep_sub);
663  if (!info->substream[i].num_dep_sub) {
664  put_bits(&pbc, 1, 0); /* reserved */
665  } else {
666  put_bits(&pbc, 9, info->substream[i].chan_loc);
667  }
668  }
669  if (info->complexity_index_type_a) {
670  put_bits(&pbc, 7, 0); /* reserved */
671  put_bits(&pbc, 1, 1); // flag_eac3_extension_type_a
672  put_bits(&pbc, 8, info->complexity_index_type_a);
673  }
674  flush_put_bits(&pbc);
675  size = put_bytes_output(&pbc);
676 
677  avio_wb32(pb, size + 8);
678  ffio_wfourcc(pb, "dec3");
679  avio_write(pb, buf, size);
680 
681  av_free(buf);
682 
683  return size;
684 }
685 
686 /**
687  * This function writes extradata "as is".
688  * Extradata must be formatted like a valid atom (with size and tag).
689  */
691 {
692  avio_write(pb, track->extradata[track->last_stsd_index], track->extradata_size[track->last_stsd_index]);
693  return track->extradata_size[track->last_stsd_index];
694 }
695 
697 {
698  avio_wb32(pb, 10);
699  ffio_wfourcc(pb, "enda");
700  avio_wb16(pb, 1); /* little endian */
701  return 10;
702 }
703 
705 {
706  avio_wb32(pb, 10);
707  ffio_wfourcc(pb, "enda");
708  avio_wb16(pb, 0); /* big endian */
709  return 10;
710 }
711 
712 static void put_descr(AVIOContext *pb, int tag, unsigned int size)
713 {
714  int i = 3;
715  avio_w8(pb, tag);
716  for (; i > 0; i--)
717  avio_w8(pb, (size >> (7 * i)) | 0x80);
718  avio_w8(pb, size & 0x7F);
719 }
720 
721 static unsigned compute_avg_bitrate(MOVTrack *track)
722 {
723  uint64_t size = 0;
724  int i;
725  if (!track->track_duration)
726  return 0;
727  for (i = 0; i < track->entry; i++)
728  size += track->cluster[i].size;
729  return size * 8 * track->timescale / track->track_duration;
730 }
731 
733  uint32_t buffer_size; ///< Size of the decoding buffer for the elementary stream in bytes.
734  uint32_t max_bit_rate; ///< Maximum rate in bits/second over any window of one second.
735  uint32_t avg_bit_rate; ///< Average rate in bits/second over the entire presentation.
736 };
737 
739 {
740  const AVPacketSideData *sd = track->st ?
742  track->st->codecpar->nb_coded_side_data,
744  AVCPBProperties *props = sd ? (AVCPBProperties *)sd->data : NULL;
745  struct mpeg4_bit_rate_values bit_rates = { 0 };
746 
747  bit_rates.avg_bit_rate = compute_avg_bitrate(track);
748  if (!bit_rates.avg_bit_rate) {
749  // if the average bit rate cannot be calculated at this point, such as
750  // in the case of fragmented MP4, utilize the following values as
751  // fall-back in priority order:
752  //
753  // 1. average bit rate property
754  // 2. bit rate (usually average over the whole clip)
755  // 3. maximum bit rate property
756 
757  if (props && props->avg_bitrate) {
758  bit_rates.avg_bit_rate = props->avg_bitrate;
759  } else if (track->par->bit_rate) {
760  bit_rates.avg_bit_rate = track->par->bit_rate;
761  } else if (props && props->max_bitrate) {
762  bit_rates.avg_bit_rate = props->max_bitrate;
763  }
764  }
765 
766  // (FIXME should be max rate in any 1 sec window)
767  bit_rates.max_bit_rate = FFMAX(track->par->bit_rate,
768  bit_rates.avg_bit_rate);
769 
770  // utilize values from properties if we have them available
771  if (props) {
772  // no avg_bitrate signals that the track is VBR
773  if (!props->avg_bitrate)
774  bit_rates.avg_bit_rate = props->avg_bitrate;
775  bit_rates.max_bit_rate = FFMAX(bit_rates.max_bit_rate,
776  props->max_bitrate);
777  bit_rates.buffer_size = props->buffer_size / 8;
778  }
779 
780  return bit_rates;
781 }
782 
783 static int mov_write_esds_tag(AVIOContext *pb, MOVTrack *track) // Basic
784 {
785  struct mpeg4_bit_rate_values bit_rates = calculate_mpeg4_bit_rates(track);
786  int64_t pos = avio_tell(pb);
787  int decoder_specific_info_len = track->extradata_size[track->last_stsd_index] ?
788  5 + track->extradata_size[track->last_stsd_index] : 0;
789 
790  avio_wb32(pb, 0); // size
791  ffio_wfourcc(pb, "esds");
792  avio_wb32(pb, 0); // Version
793 
794  // ES descriptor
795  put_descr(pb, 0x03, 3 + 5+13 + decoder_specific_info_len + 5+1);
796  avio_wb16(pb, track->track_id);
797  avio_w8(pb, 0x00); // flags (= no flags)
798 
799  // DecoderConfig descriptor
800  put_descr(pb, 0x04, 13 + decoder_specific_info_len);
801 
802  // Object type indication
803  if ((track->par->codec_id == AV_CODEC_ID_MP2 ||
804  track->par->codec_id == AV_CODEC_ID_MP3) &&
805  track->par->sample_rate > 24000)
806  avio_w8(pb, 0x6B); // 11172-3
807  else
809 
810  // the following fields is made of 6 bits to identify the streamtype (4 for video, 5 for audio)
811  // plus 1 bit to indicate upstream and 1 bit set to 1 (reserved)
812  if (track->par->codec_id == AV_CODEC_ID_DVD_SUBTITLE)
813  avio_w8(pb, (0x38 << 2) | 1); // flags (= NeroSubpicStream)
814  else if (track->par->codec_type == AVMEDIA_TYPE_AUDIO)
815  avio_w8(pb, 0x15); // flags (= Audiostream)
816  else
817  avio_w8(pb, 0x11); // flags (= Visualstream)
818 
819  avio_wb24(pb, bit_rates.buffer_size); // Buffersize DB
820  avio_wb32(pb, bit_rates.max_bit_rate); // maxbitrate
821  avio_wb32(pb, bit_rates.avg_bit_rate);
822 
823  if (track->extradata_size[track->last_stsd_index]) {
824  // DecoderSpecific info descriptor
825  put_descr(pb, 0x05, track->extradata_size[track->last_stsd_index]);
826  avio_write(pb, track->extradata[track->last_stsd_index],
827  track->extradata_size[track->last_stsd_index]);
828  }
829 
830  // SL descriptor
831  put_descr(pb, 0x06, 1);
832  avio_w8(pb, 0x02);
833  return update_size(pb, pos);
834 }
835 
837 {
838  return codec_id == AV_CODEC_ID_PCM_S24LE ||
842 }
843 
845 {
846  return codec_id == AV_CODEC_ID_PCM_S24BE ||
850 }
851 
853 {
854  int ret;
855  int64_t pos = avio_tell(pb);
856  avio_wb32(pb, 0);
857  avio_wl32(pb, track->tag); // store it byteswapped
858  track->par->codec_tag = av_bswap16(track->tag >> 16);
859  if ((ret = ff_put_wav_header(s, pb, track->par, 0)) < 0)
860  return ret;
861  return update_size(pb, pos);
862 }
863 
865 {
866  int ret;
867  int64_t pos = avio_tell(pb);
868  avio_wb32(pb, 0);
869  ffio_wfourcc(pb, "wfex");
871  return ret;
872  return update_size(pb, pos);
873 }
874 
875 static int mov_write_dfla_tag(AVIOContext *pb, MOVTrack *track)
876 {
877  int64_t pos = avio_tell(pb);
878  avio_wb32(pb, 0);
879  ffio_wfourcc(pb, "dfLa");
880  avio_w8(pb, 0); /* version */
881  avio_wb24(pb, 0); /* flags */
882 
883  /* Expect the encoder to pass a METADATA_BLOCK_TYPE_STREAMINFO. */
885  return AVERROR_INVALIDDATA;
886 
887  /* TODO: Write other METADATA_BLOCK_TYPEs if the encoder makes them available. */
888  avio_w8(pb, 1 << 7 | FLAC_METADATA_TYPE_STREAMINFO); /* LastMetadataBlockFlag << 7 | BlockType */
889  avio_wb24(pb, track->extradata_size[track->last_stsd_index]); /* Length */
890  avio_write(pb, track->extradata[track->last_stsd_index], track->extradata_size[track->last_stsd_index]); /* BlockData[Length] */
891 
892  return update_size(pb, pos);
893 }
894 
896 {
897  int64_t pos = avio_tell(pb);
898  int channels, channel_map;
899  avio_wb32(pb, 0);
900  ffio_wfourcc(pb, "dOps");
901  avio_w8(pb, 0); /* Version */
902  if (track->extradata_size[track->last_stsd_index] < 19) {
903  av_log(s, AV_LOG_ERROR, "invalid extradata size\n");
904  return AVERROR_INVALIDDATA;
905  }
906  /* extradata contains an Ogg OpusHead, other than byte-ordering and
907  OpusHead's preceding magic/version, OpusSpecificBox is currently
908  identical. */
909  channels = AV_RB8(track->extradata[track->last_stsd_index] + 9);
910  channel_map = AV_RB8(track->extradata[track->last_stsd_index] + 18);
911 
912  avio_w8(pb, channels); /* OuputChannelCount */
913  avio_wb16(pb, AV_RL16(track->extradata[track->last_stsd_index] + 10)); /* PreSkip */
914  avio_wb32(pb, AV_RL32(track->extradata[track->last_stsd_index] + 12)); /* InputSampleRate */
915  avio_wb16(pb, AV_RL16(track->extradata[track->last_stsd_index] + 16)); /* OutputGain */
916  avio_w8(pb, channel_map); /* ChannelMappingFamily */
917  /* Write the rest of the header out without byte-swapping. */
918  if (channel_map) {
919  if (track->extradata_size[track->last_stsd_index] < 21 + channels) {
920  av_log(s, AV_LOG_ERROR, "invalid extradata size\n");
921  return AVERROR_INVALIDDATA;
922  }
923  avio_write(pb, track->extradata[track->last_stsd_index] + 19, 2 + channels); /* ChannelMappingTable */
924  }
925 
926  return update_size(pb, pos);
927 }
928 
930 {
931  int64_t pos = avio_tell(pb);
932  int length;
933  avio_wb32(pb, 0);
934  ffio_wfourcc(pb, "dmlp");
935 
936  if (track->extradata_size[track->last_stsd_index] < 20) {
938  "Cannot write moov atom before TrueHD packets."
939  " Set the delay_moov flag to fix this.\n");
940  return AVERROR(EINVAL);
941  }
942 
943  length = (AV_RB16(track->extradata[track->last_stsd_index]) & 0xFFF) * 2;
944  if (length < 20 || length > track->extradata_size[track->last_stsd_index])
945  return AVERROR_INVALIDDATA;
946 
947  // Only TrueHD is supported
948  if (AV_RB32(track->extradata[track->last_stsd_index] + 4) != 0xF8726FBA)
949  return AVERROR_INVALIDDATA;
950 
951  avio_wb32(pb, AV_RB32(track->extradata[track->last_stsd_index] + 8)); /* format_info */
952  avio_wb16(pb, AV_RB16(track->extradata[track->last_stsd_index] + 18) << 1); /* peak_data_rate */
953  avio_wb32(pb, 0); /* reserved */
954 
955  return update_size(pb, pos);
956 }
957 
959 {
960  const AVDictionaryEntry *str = av_dict_get(track->st->metadata, "SA3D", NULL, 0);
961  AVChannelLayout ch_layout = { 0 };
962  int64_t pos;
963  int ambisonic_order, ambi_channels, non_diegetic_channels;
964  int i, ret;
965 
966  if (!str)
967  return 0;
968 
969  ret = av_channel_layout_from_string(&ch_layout, str->value);
970  if (ret < 0) {
971  if (ret == AVERROR(EINVAL)) {
972 invalid:
973  av_log(s, AV_LOG_ERROR, "Invalid SA3D layout: \"%s\"\n", str->value);
974  ret = 0;
975  }
976  av_channel_layout_uninit(&ch_layout);
977  return ret;
978  }
979 
980  if (track->st->codecpar->ch_layout.nb_channels != ch_layout.nb_channels)
981  goto invalid;
982 
983  ambisonic_order = av_channel_layout_ambisonic_order(&ch_layout);
984  if (ambisonic_order < 0)
985  goto invalid;
986 
987  ambi_channels = (ambisonic_order + 1LL) * (ambisonic_order + 1LL);
988  non_diegetic_channels = ch_layout.nb_channels - ambi_channels;
989  if (non_diegetic_channels &&
990  (non_diegetic_channels != 2 ||
992  goto invalid;
993 
994  av_log(s, AV_LOG_VERBOSE, "Inserting SA3D box with layout: \"%s\"\n", str->value);
995 
996  pos = avio_tell(pb);
997 
998  avio_wb32(pb, 0); // Size
999  ffio_wfourcc(pb, "SA3D");
1000  avio_w8(pb, 0); // version
1001  avio_w8(pb, (!!non_diegetic_channels) << 7); // head_locked_stereo and ambisonic_type
1002  avio_wb32(pb, ambisonic_order); // ambisonic_order
1003  avio_w8(pb, 0); // ambisonic_channel_ordering
1004  avio_w8(pb, 0); // ambisonic_normalization
1005  avio_wb32(pb, ch_layout.nb_channels); // num_channels
1006  for (i = 0; i < ambi_channels; i++)
1008  for (; i < ch_layout.nb_channels; i++)
1009  avio_wb32(pb, av_channel_layout_channel_from_index(&ch_layout, i) + ambi_channels);
1010 
1011  av_channel_layout_uninit(&ch_layout);
1012 
1013  return update_size(pb, pos);
1014 }
1015 
1017 {
1018  uint32_t layout_tag, bitmap, *channel_desc;
1019  int64_t pos = avio_tell(pb);
1020  int num_desc, ret;
1021 
1022  if (track->multichannel_as_mono)
1023  return 0;
1024 
1025  ret = ff_mov_get_channel_layout_tag(track->par, &layout_tag,
1026  &bitmap, &channel_desc);
1027 
1028  if (ret < 0) {
1029  if (ret == AVERROR(ENOSYS)) {
1030  av_log(s, AV_LOG_WARNING, "not writing 'chan' tag due to "
1031  "lack of channel information\n");
1032  ret = 0;
1033  }
1034 
1035  return ret;
1036  }
1037 
1038  /* no predefined tag found + ch_layout in AV_CHANNEL_ORDER_NATIVE
1039  * but bitstream channels not actually in native order */
1040  if (layout_tag == MOV_CH_LAYOUT_UNKNOWN)
1041  return 0;
1042 
1043  if (layout_tag == MOV_CH_LAYOUT_MONO && track->mono_as_fc > 0) {
1044  av_assert0(!channel_desc);
1045  channel_desc = av_malloc(sizeof(*channel_desc));
1046  if (!channel_desc)
1047  return AVERROR(ENOMEM);
1048 
1049  layout_tag = 0;
1050  bitmap = 0;
1051  *channel_desc = 3; // channel label "Center"
1052  }
1053 
1054  num_desc = layout_tag ? 0 : track->par->ch_layout.nb_channels;
1055 
1056  avio_wb32(pb, 0); // Size
1057  ffio_wfourcc(pb, "chan"); // Type
1058  avio_w8(pb, 0); // Version
1059  avio_wb24(pb, 0); // Flags
1060  avio_wb32(pb, layout_tag); // mChannelLayoutTag
1061  avio_wb32(pb, bitmap); // mChannelBitmap
1062  avio_wb32(pb, num_desc); // mNumberChannelDescriptions
1063 
1064  for (int i = 0; i < num_desc; i++) {
1065  avio_wb32(pb, channel_desc[i]); // mChannelLabel
1066  avio_wb32(pb, 0); // mChannelFlags
1067  avio_wl32(pb, 0); // mCoordinates[0]
1068  avio_wl32(pb, 0); // mCoordinates[1]
1069  avio_wl32(pb, 0); // mCoordinates[2]
1070  }
1071 
1072  av_free(channel_desc);
1073 
1074  return update_size(pb, pos);
1075 }
1076 
1078 {
1079  int64_t pos = avio_tell(pb);
1080 
1081  avio_wb32(pb, 0); /* size */
1082  ffio_wfourcc(pb, "wave");
1083 
1084  if (track->par->codec_id != AV_CODEC_ID_QDM2) {
1085  avio_wb32(pb, 12); /* size */
1086  ffio_wfourcc(pb, "frma");
1087  avio_wl32(pb, track->tag);
1088  }
1089 
1090  if (track->par->codec_id == AV_CODEC_ID_AAC) {
1091  /* useless atom needed by mplayer, ipod, not needed by quicktime */
1092  avio_wb32(pb, 12); /* size */
1093  ffio_wfourcc(pb, "mp4a");
1094  avio_wb32(pb, 0);
1095  mov_write_esds_tag(pb, track);
1096  } else if (mov_pcm_le_gt16(track->par->codec_id)) {
1097  mov_write_enda_tag(pb);
1098  } else if (mov_pcm_be_gt16(track->par->codec_id)) {
1100  } else if (track->par->codec_id == AV_CODEC_ID_AMR_NB) {
1101  mov_write_amr_tag(pb, track);
1102  } else if (track->par->codec_id == AV_CODEC_ID_AC3) {
1103  mov_write_ac3_tag(s, pb, track);
1104  } else if (track->par->codec_id == AV_CODEC_ID_EAC3) {
1105  mov_write_eac3_tag(s, pb, track);
1106  } else if (track->par->codec_id == AV_CODEC_ID_ALAC ||
1107  track->par->codec_id == AV_CODEC_ID_QDM2) {
1108  mov_write_extradata_tag(pb, track);
1109  } else if (track->par->codec_id == AV_CODEC_ID_ADPCM_MS ||
1110  track->par->codec_id == AV_CODEC_ID_ADPCM_IMA_WAV) {
1111  mov_write_ms_tag(s, pb, track);
1112  }
1113 
1114  avio_wb32(pb, 8); /* size */
1115  avio_wb32(pb, 0); /* null tag */
1116 
1117  return update_size(pb, pos);
1118 }
1119 
1120 static int mov_write_dvc1_structs(MOVTrack *track, uint8_t *buf)
1121 {
1122  uint8_t *unescaped;
1123  const uint8_t *start, *next, *end = track->extradata[track->last_stsd_index] +
1124  track->extradata_size[track->last_stsd_index];
1125  int unescaped_size, seq_found = 0;
1126  int level = 0, interlace = 0;
1127  int packet_seq = track->vc1_info.packet_seq;
1128  int packet_entry = track->vc1_info.packet_entry;
1129  int slices = track->vc1_info.slices;
1130  PutBitContext pbc;
1131 
1132  if (track->start_dts == AV_NOPTS_VALUE) {
1133  /* No packets written yet, vc1_info isn't authoritative yet. */
1134  /* Assume inline sequence and entry headers. */
1135  packet_seq = packet_entry = 1;
1137  "moov atom written before any packets, unable to write correct "
1138  "dvc1 atom. Set the delay_moov flag to fix this.\n");
1139  }
1140 
1142  if (!unescaped)
1143  return AVERROR(ENOMEM);
1144  start = find_next_marker(track->extradata[track->last_stsd_index], end);
1145  for (next = start; next < end; start = next) {
1146  GetBitContext gb;
1147  int size;
1148  next = find_next_marker(start + 4, end);
1149  size = next - start - 4;
1150  if (size <= 0)
1151  continue;
1152  unescaped_size = vc1_unescape_buffer(start + 4, size, unescaped);
1153  init_get_bits(&gb, unescaped, 8 * unescaped_size);
1154  if (AV_RB32(start) == VC1_CODE_SEQHDR) {
1155  int profile = get_bits(&gb, 2);
1156  if (profile != PROFILE_ADVANCED) {
1157  av_free(unescaped);
1158  return AVERROR(ENOSYS);
1159  }
1160  seq_found = 1;
1161  level = get_bits(&gb, 3);
1162  /* chromaformat, frmrtq_postproc, bitrtq_postproc, postprocflag,
1163  * width, height */
1164  skip_bits_long(&gb, 2 + 3 + 5 + 1 + 2*12);
1165  skip_bits(&gb, 1); /* broadcast */
1166  interlace = get_bits1(&gb);
1167  skip_bits(&gb, 4); /* tfcntrflag, finterpflag, reserved, psf */
1168  }
1169  }
1170  if (!seq_found) {
1171  av_free(unescaped);
1172  return AVERROR(ENOSYS);
1173  }
1174 
1175  init_put_bits(&pbc, buf, 7);
1176  /* VC1DecSpecStruc */
1177  put_bits(&pbc, 4, 12); /* profile - advanced */
1178  put_bits(&pbc, 3, level);
1179  put_bits(&pbc, 1, 0); /* reserved */
1180  /* VC1AdvDecSpecStruc */
1181  put_bits(&pbc, 3, level);
1182  put_bits(&pbc, 1, 0); /* cbr */
1183  put_bits(&pbc, 6, 0); /* reserved */
1184  put_bits(&pbc, 1, !interlace); /* no interlace */
1185  put_bits(&pbc, 1, !packet_seq); /* no multiple seq */
1186  put_bits(&pbc, 1, !packet_entry); /* no multiple entry */
1187  put_bits(&pbc, 1, !slices); /* no slice code */
1188  put_bits(&pbc, 1, 0); /* no bframe */
1189  put_bits(&pbc, 1, 0); /* reserved */
1190 
1191  /* framerate */
1192  if (track->st->avg_frame_rate.num > 0 && track->st->avg_frame_rate.den > 0)
1193  put_bits32(&pbc, track->st->avg_frame_rate.num / track->st->avg_frame_rate.den);
1194  else
1195  put_bits32(&pbc, 0xffffffff);
1196 
1197  flush_put_bits(&pbc);
1198 
1199  av_free(unescaped);
1200 
1201  return 0;
1202 }
1203 
1204 static int mov_write_dvc1_tag(AVIOContext *pb, MOVTrack *track)
1205 {
1206  uint8_t buf[7] = { 0 };
1207  int ret;
1208 
1209  if ((ret = mov_write_dvc1_structs(track, buf)) < 0)
1210  return ret;
1211 
1212  avio_wb32(pb, track->extradata_size[track->last_stsd_index] + 8 + sizeof(buf));
1213  ffio_wfourcc(pb, "dvc1");
1214  avio_write(pb, buf, sizeof(buf));
1215  avio_write(pb, track->extradata[track->last_stsd_index],
1216  track->extradata_size[track->last_stsd_index]);
1217 
1218  return 0;
1219 }
1220 
1221 static int mov_write_glbl_tag(AVIOContext *pb, MOVTrack *track)
1222 {
1223  avio_wb32(pb, track->extradata_size[track->last_stsd_index] + 8);
1224  ffio_wfourcc(pb, "glbl");
1225  avio_write(pb, track->extradata[track->last_stsd_index],
1226  track->extradata_size[track->last_stsd_index]);
1227  return 8 + track->extradata_size[track->last_stsd_index];
1228 }
1229 
1230 /**
1231  * Compute flags for 'lpcm' tag.
1232  * See CoreAudioTypes and AudioStreamBasicDescription at Apple.
1233  */
1235 {
1236  switch (codec_id) {
1237  case AV_CODEC_ID_PCM_F32BE:
1238  case AV_CODEC_ID_PCM_F64BE:
1239  return 11;
1240  case AV_CODEC_ID_PCM_F32LE:
1241  case AV_CODEC_ID_PCM_F64LE:
1242  return 9;
1243  case AV_CODEC_ID_PCM_U8:
1244  return 10;
1245  case AV_CODEC_ID_PCM_S16BE:
1246  case AV_CODEC_ID_PCM_S24BE:
1247  case AV_CODEC_ID_PCM_S32BE:
1248  return 14;
1249  case AV_CODEC_ID_PCM_S8:
1250  case AV_CODEC_ID_PCM_S16LE:
1251  case AV_CODEC_ID_PCM_S24LE:
1252  case AV_CODEC_ID_PCM_S32LE:
1253  return 12;
1254  default:
1255  return 0;
1256  }
1257 }
1258 
1259 static int get_cluster_duration(MOVTrack *track, int cluster_idx)
1260 {
1261  int64_t next_dts;
1262 
1263  if (cluster_idx >= track->entry)
1264  return 0;
1265 
1266  if (cluster_idx + 1 == track->entry)
1267  next_dts = track->track_duration + track->start_dts;
1268  else
1269  next_dts = track->cluster[cluster_idx + 1].dts;
1270 
1271  next_dts -= track->cluster[cluster_idx].dts;
1272 
1273  av_assert0(next_dts >= 0);
1274  av_assert0(next_dts <= INT_MAX);
1275 
1276  return next_dts;
1277 }
1278 
1280 {
1281  int i, first_duration;
1282 
1283  /* use 1 for raw PCM */
1284  if (!track->audio_vbr)
1285  return 1;
1286 
1287  /* check to see if duration is constant for all clusters */
1288  if (!track->entry)
1289  return 0;
1290  first_duration = get_cluster_duration(track, 0);
1291  for (i = 1; i < track->entry; i++) {
1292  if (get_cluster_duration(track, i) != first_duration)
1293  return 0;
1294  }
1295  return first_duration;
1296 }
1297 
1298 static int mov_write_btrt_tag(AVIOContext *pb, MOVTrack *track)
1299 {
1300  int64_t pos = avio_tell(pb);
1301  struct mpeg4_bit_rate_values bit_rates = calculate_mpeg4_bit_rates(track);
1302  if (!bit_rates.max_bit_rate && !bit_rates.avg_bit_rate &&
1303  !bit_rates.buffer_size)
1304  // no useful data to be written, skip
1305  return 0;
1306 
1307  avio_wb32(pb, 0); /* size */
1308  ffio_wfourcc(pb, "btrt");
1309 
1310  avio_wb32(pb, bit_rates.buffer_size);
1311  avio_wb32(pb, bit_rates.max_bit_rate);
1312  avio_wb32(pb, bit_rates.avg_bit_rate);
1313 
1314  return update_size(pb, pos);
1315 }
1316 
1318 {
1319  int64_t pos = avio_tell(pb);
1320  int config = 0;
1321  int ret;
1322  uint8_t *speaker_pos = NULL;
1323  const AVChannelLayout *layout = &track->par->ch_layout;
1324 
1326  if (ret || !config) {
1327  config = 0;
1328  speaker_pos = av_malloc(layout->nb_channels);
1329  if (!speaker_pos)
1330  return AVERROR(ENOMEM);
1332  speaker_pos, layout->nb_channels);
1333  if (ret) {
1334  char buf[128] = {0};
1335 
1336  av_freep(&speaker_pos);
1337  av_channel_layout_describe(layout, buf, sizeof(buf));
1338  av_log(s, AV_LOG_ERROR, "unsupported channel layout %s\n", buf);
1339  return ret;
1340  }
1341  }
1342 
1343  avio_wb32(pb, 0); /* size */
1344  ffio_wfourcc(pb, "chnl");
1345  avio_wb32(pb, 0); /* version & flags */
1346 
1347  avio_w8(pb, 1); /* stream_structure */
1348  avio_w8(pb, config);
1349  if (config) {
1350  avio_wb64(pb, 0);
1351  } else {
1352  avio_write(pb, speaker_pos, layout->nb_channels);
1353  av_freep(&speaker_pos);
1354  }
1355 
1356  return update_size(pb, pos);
1357 }
1358 
1360 {
1361  int64_t pos = avio_tell(pb);
1362  int format_flags;
1363  int sample_size;
1364 
1365  avio_wb32(pb, 0); /* size */
1366  ffio_wfourcc(pb, "pcmC");
1367  avio_wb32(pb, 0); /* version & flags */
1368 
1369  /* 0x01: indicates little-endian format */
1370  format_flags = (track->par->codec_id == AV_CODEC_ID_PCM_F32LE ||
1371  track->par->codec_id == AV_CODEC_ID_PCM_F64LE ||
1372  track->par->codec_id == AV_CODEC_ID_PCM_S16LE ||
1373  track->par->codec_id == AV_CODEC_ID_PCM_S24LE ||
1374  track->par->codec_id == AV_CODEC_ID_PCM_S32LE);
1375  avio_w8(pb, format_flags);
1376  sample_size = track->par->bits_per_raw_sample;
1377  if (!sample_size)
1378  sample_size = av_get_exact_bits_per_sample(track->par->codec_id);
1379  av_assert0(sample_size);
1380  avio_w8(pb, sample_size);
1381 
1382  return update_size(pb, pos);
1383 }
1384 
1385 static int mov_write_srat_tag(AVIOContext *pb, MOVTrack *track)
1386 {
1387  int64_t pos = avio_tell(pb);
1388  avio_wb32(pb, 0); /* size */
1389  ffio_wfourcc(pb, "srat");
1390  avio_wb32(pb, 0); /* version & flags */
1391 
1392  avio_wb32(pb, track->par->sample_rate);
1393 
1394  return update_size(pb, pos);
1395 }
1396 
1398 {
1399  int64_t pos = avio_tell(pb);
1400  int version = 0;
1401  uint32_t tag = track->tag;
1402  int ret = 0;
1403 
1404  if (track->mode == MODE_MOV) {
1405  if (track->par->sample_rate > UINT16_MAX || !track->par->ch_layout.nb_channels ||
1406  track->par->codec_id == AV_CODEC_ID_EAC3 ||
1407  track->par->ch_layout.nb_channels > 2) {
1408  if (mov_get_lpcm_flags(track->par->codec_id))
1409  tag = AV_RL32("lpcm");
1410  version = 2;
1411  } else if (track->audio_vbr || mov_pcm_le_gt16(track->par->codec_id) ||
1412  mov_pcm_be_gt16(track->par->codec_id) ||
1413  track->par->codec_id == AV_CODEC_ID_ADPCM_MS ||
1414  track->par->codec_id == AV_CODEC_ID_ADPCM_IMA_WAV ||
1415  track->par->codec_id == AV_CODEC_ID_QDM2) {
1416  version = 1;
1417  }
1418  } else if (track->mode == MODE_MP4) {
1419  if (track->par->sample_rate > UINT16_MAX &&
1421  version = 1;
1422  }
1423 
1424  avio_wb32(pb, 0); /* size */
1425  if (mov->encryption_scheme != MOV_ENC_NONE) {
1426  ffio_wfourcc(pb, "enca");
1427  } else {
1428  avio_wl32(pb, tag); // store it byteswapped
1429  }
1430  avio_wb32(pb, 0); /* Reserved */
1431  avio_wb16(pb, 0); /* Reserved */
1432  avio_wb16(pb, 1); /* Data-reference index, XXX == 1 */
1433 
1434  /* SoundDescription */
1435  avio_wb16(pb, version); /* Version */
1436  avio_wb16(pb, 0); /* Revision level */
1437  avio_wb32(pb, 0); /* Reserved */
1438 
1439  if (version == 2) {
1440  avio_wb16(pb, 3);
1441  avio_wb16(pb, 16);
1442  avio_wb16(pb, 0xfffe);
1443  avio_wb16(pb, 0);
1444  avio_wb32(pb, 0x00010000);
1445  avio_wb32(pb, 72);
1446  avio_wb64(pb, av_double2int(track->par->sample_rate));
1447  avio_wb32(pb, track->par->ch_layout.nb_channels);
1448  avio_wb32(pb, 0x7F000000);
1450  avio_wb32(pb, mov_get_lpcm_flags(track->par->codec_id));
1451  avio_wb32(pb, track->sample_size);
1452  avio_wb32(pb, get_samples_per_packet(track));
1453  } else {
1454  unsigned sample_rate = track->par->sample_rate;
1455 
1456  if (track->mode == MODE_MOV) {
1457  avio_wb16(pb, track->par->ch_layout.nb_channels);
1458  if (track->par->codec_id == AV_CODEC_ID_PCM_U8 ||
1459  track->par->codec_id == AV_CODEC_ID_PCM_S8)
1460  avio_wb16(pb, 8); /* bits per sample */
1461  else if (track->par->codec_id == AV_CODEC_ID_ADPCM_G726)
1462  avio_wb16(pb, track->par->bits_per_coded_sample);
1463  else
1464  avio_wb16(pb, 16);
1465  avio_wb16(pb, track->audio_vbr ? -2 : 0); /* compression ID */
1466  } else { /* reserved for mp4/3gp */
1467  avio_wb16(pb, track->tag == MKTAG('i', 'a', 'm', 'f') ?
1468  0 : track->par->ch_layout.nb_channels);
1469  if (track->par->codec_id == AV_CODEC_ID_FLAC ||
1470  track->par->codec_id == AV_CODEC_ID_ALAC) {
1471  avio_wb16(pb, track->par->bits_per_raw_sample);
1472  } else {
1473  avio_wb16(pb, 16);
1474  }
1475  avio_wb16(pb, 0);
1476 
1477  while (sample_rate > UINT16_MAX)
1478  sample_rate >>= 1;
1479  }
1480 
1481  avio_wb16(pb, 0); /* packet size (= 0) */
1482  if (track->tag == MKTAG('i','a','m','f'))
1483  avio_wb16(pb, 0); /* samplerate must be 0 for IAMF */
1484  else if (track->par->codec_id == AV_CODEC_ID_OPUS)
1485  avio_wb16(pb, 48000);
1486  else if (track->par->codec_id == AV_CODEC_ID_TRUEHD)
1487  avio_wb32(pb, track->par->sample_rate);
1488  else
1489  avio_wb16(pb, sample_rate);
1490 
1491  if (track->par->codec_id != AV_CODEC_ID_TRUEHD)
1492  avio_wb16(pb, 0); /* Reserved */
1493  }
1494 
1495  if (track->mode == MODE_MOV && version == 1) { /* SoundDescription V1 extended info */
1496  if (mov_pcm_le_gt16(track->par->codec_id) ||
1497  mov_pcm_be_gt16(track->par->codec_id))
1498  avio_wb32(pb, 1); /* must be 1 for uncompressed formats */
1499  else
1500  avio_wb32(pb, track->par->frame_size); /* Samples per packet */
1501  avio_wb32(pb, track->sample_size / track->par->ch_layout.nb_channels); /* Bytes per packet */
1502  avio_wb32(pb, track->sample_size); /* Bytes per frame */
1503  avio_wb32(pb, 2); /* Bytes per sample */
1504  }
1505 
1506  if (track->mode == MODE_MOV &&
1507  (track->par->codec_id == AV_CODEC_ID_AAC ||
1508  track->par->codec_id == AV_CODEC_ID_AC3 ||
1509  track->par->codec_id == AV_CODEC_ID_EAC3 ||
1510  track->par->codec_id == AV_CODEC_ID_AMR_NB ||
1511  track->par->codec_id == AV_CODEC_ID_ALAC ||
1512  track->par->codec_id == AV_CODEC_ID_ADPCM_MS ||
1513  track->par->codec_id == AV_CODEC_ID_ADPCM_IMA_WAV ||
1514  track->par->codec_id == AV_CODEC_ID_QDM2 ||
1515  (mov_pcm_le_gt16(track->par->codec_id) && version==1) ||
1516  (mov_pcm_be_gt16(track->par->codec_id) && version==1)))
1517  ret = mov_write_wave_tag(s, pb, track);
1518  else if (track->tag == MKTAG('m','p','4','a'))
1519  ret = mov_write_esds_tag(pb, track);
1520 #if CONFIG_IAMFENC
1521  else if (track->tag == MKTAG('i','a','m','f'))
1522  ret = mov_write_iacb_tag(mov->fc, pb, track);
1523 #endif
1524  else if (track->par->codec_id == AV_CODEC_ID_AMR_NB)
1525  ret = mov_write_amr_tag(pb, track);
1526  else if (track->par->codec_id == AV_CODEC_ID_AC3)
1527  ret = mov_write_ac3_tag(s, pb, track);
1528  else if (track->par->codec_id == AV_CODEC_ID_EAC3)
1529  ret = mov_write_eac3_tag(s, pb, track);
1530  else if (track->par->codec_id == AV_CODEC_ID_ALAC)
1531  ret = mov_write_extradata_tag(pb, track);
1532  else if (track->par->codec_id == AV_CODEC_ID_WMAPRO)
1533  ret = mov_write_wfex_tag(s, pb, track);
1534  else if (track->par->codec_id == AV_CODEC_ID_FLAC)
1535  ret = mov_write_dfla_tag(pb, track);
1536  else if (track->par->codec_id == AV_CODEC_ID_OPUS)
1537  ret = mov_write_dops_tag(s, pb, track);
1538  else if (track->par->codec_id == AV_CODEC_ID_TRUEHD)
1539  ret = mov_write_dmlp_tag(s, pb, track);
1540  else if (tag == MOV_MP4_IPCM_TAG || tag == MOV_MP4_FPCM_TAG) {
1541  if (track->par->sample_rate > UINT16_MAX)
1542  mov_write_srat_tag(pb, track);
1543  if (track->par->ch_layout.nb_channels > 1)
1544  ret = mov_write_chnl_tag(s, pb, track);
1545  if (ret < 0)
1546  return ret;
1547  ret = mov_write_pcmc_tag(s, pb, track);
1548  } else if (track->extradata_size[track->last_stsd_index] > 0)
1549  ret = mov_write_glbl_tag(pb, track);
1550 
1551  if (ret < 0)
1552  return ret;
1553 
1554  if (track->mode == MODE_MP4 && track->par->codec_type == AVMEDIA_TYPE_AUDIO
1555  && ((ret = mov_write_SA3D_tag(s, pb, track)) < 0)) {
1556  return ret;
1557  }
1558 
1559  if (track->mode == MODE_MOV && track->par->codec_type == AVMEDIA_TYPE_AUDIO
1560  && ((ret = mov_write_chan_tag(s, pb, track)) < 0)) {
1561  return ret;
1562  }
1563 
1564  if (mov->encryption_scheme != MOV_ENC_NONE
1565  && ((ret = ff_mov_cenc_write_sinf_tag(track, pb, mov->encryption_kid)) < 0)) {
1566  return ret;
1567  }
1568 
1569  if (mov->write_btrt &&
1570  ((ret = mov_write_btrt_tag(pb, track)) < 0))
1571  return ret;
1572 
1573  if (track->mode == MODE_MP4)
1574  track->entry_version = version;
1575 
1576  ret = update_size(pb, pos);
1577  return ret;
1578 }
1579 
1581 {
1582  avio_wb32(pb, 0xf); /* size */
1583  ffio_wfourcc(pb, "d263");
1584  ffio_wfourcc(pb, "FFMP");
1585  avio_w8(pb, 0); /* decoder version */
1586  /* FIXME use AVCodecContext level/profile, when encoder will set values */
1587  avio_w8(pb, 0xa); /* level */
1588  avio_w8(pb, 0); /* profile */
1589  return 0xf;
1590 }
1591 
1592 static int mov_write_av1c_tag(AVIOContext *pb, MOVTrack *track)
1593 {
1594  int64_t pos = avio_tell(pb);
1595 
1596  avio_wb32(pb, 0);
1597  ffio_wfourcc(pb, "av1C");
1598  ff_isom_write_av1c(pb, track->extradata[track->last_stsd_index],
1599  track->extradata_size[track->last_stsd_index], track->mode != MODE_AVIF);
1600  return update_size(pb, pos);
1601 }
1602 
1603 static int mov_write_avcc_tag(AVIOContext *pb, MOVTrack *track)
1604 {
1605  int64_t pos = avio_tell(pb);
1606 
1607  avio_wb32(pb, 0);
1608  ffio_wfourcc(pb, "avcC");
1609  ff_isom_write_avcc(pb, track->extradata[track->last_stsd_index],
1610  track->extradata_size[track->last_stsd_index]);
1611  return update_size(pb, pos);
1612 }
1613 
1614 /* AVS3 Intelligent Media Coding
1615  * Information Technology - Intelligent Media Coding
1616  * Part 6: Intelligent Media Format
1617  */
1618 static int mov_write_av3c(AVIOContext *pb, const uint8_t *data, int len)
1619 {
1620  if (len < 4)
1621  return AVERROR_INVALIDDATA;
1622 
1623  if (data[0] == 1) {
1624  // In Avs3DecoderConfigurationRecord format
1625  avio_write(pb, data, len);
1626  return 0;
1627  }
1628 
1629  avio_w8(pb, 1); // version
1630  avio_wb16(pb, len); // sequence_header_length
1631  avio_write(pb, data, len); // sequence_header
1632  avio_w8(pb, 0xFC); // Only support library_dependency_idc = 0
1633 
1634  return 0;
1635 }
1636 
1637 static int mov_write_av3c_tag(AVIOContext *pb, MOVTrack *track)
1638 {
1639  int64_t pos = avio_tell(pb);
1640  avio_wb32(pb, 0);
1641  ffio_wfourcc(pb, "av3c");
1642  mov_write_av3c(pb, track->extradata[track->last_stsd_index],
1643  track->extradata_size[track->last_stsd_index]);
1644  return update_size(pb, pos);
1645 }
1646 
1648 {
1649  int64_t pos = avio_tell(pb);
1650 
1651  avio_wb32(pb, 0);
1652  ffio_wfourcc(pb, "vpcC");
1653  ff_isom_write_vpcc(s, pb, track->extradata[track->last_stsd_index],
1654  track->extradata_size[track->last_stsd_index], track->par);
1655  return update_size(pb, pos);
1656 }
1657 
1659 {
1660  int64_t pos = avio_tell(pb);
1661 
1662  avio_wb32(pb, 0);
1663  ffio_wfourcc(pb, "hvcC");
1664  if (track->tag == MKTAG('h','v','c','1'))
1665  ff_isom_write_hvcc(pb, track->extradata[track->last_stsd_index],
1666  track->extradata_size[track->last_stsd_index], 1, s);
1667  else
1668  ff_isom_write_hvcc(pb, track->extradata[track->last_stsd_index],
1669  track->extradata_size[track->last_stsd_index], 0, s);
1670  return update_size(pb, pos);
1671 }
1672 
1674 {
1675  int64_t pos = avio_tell(pb);
1676  int ret;
1677 
1678  avio_wb32(pb, 0);
1679  ffio_wfourcc(pb, "lhvC");
1680  if (track->tag == MKTAG('h','v','c','1'))
1681  ret = ff_isom_write_lhvc(pb, track->extradata[track->last_stsd_index],
1682  track->extradata_size[track->last_stsd_index], 1, s);
1683  else
1684  ret = ff_isom_write_lhvc(pb, track->extradata[track->last_stsd_index],
1685  track->extradata_size[track->last_stsd_index], 0, s);
1686 
1687  if (ret < 0) {
1688  avio_seek(pb, pos, SEEK_SET);
1689  return ret;
1690  }
1691 
1692  return update_size(pb, pos);
1693 }
1694 
1695 static int mov_write_evcc_tag(AVIOContext *pb, MOVTrack *track)
1696 {
1697  int64_t pos = avio_tell(pb);
1698 
1699  avio_wb32(pb, 0);
1700  ffio_wfourcc(pb, "evcC");
1701 
1702  if (track->tag == MKTAG('e','v','c','1'))
1703  ff_isom_write_evcc(pb, track->extradata[track->last_stsd_index],
1704  track->extradata_size[track->last_stsd_index], 1);
1705  else
1706  ff_isom_write_evcc(pb, track->extradata[track->last_stsd_index],
1707  track->extradata_size[track->last_stsd_index], 0);
1708 
1709  return update_size(pb, pos);
1710 }
1711 
1712 static int mov_write_lvcc_tag(AVIOContext *pb, MOVTrack *track)
1713 {
1714  int64_t pos = avio_tell(pb);
1715 
1716  avio_wb32(pb, 0);
1717  ffio_wfourcc(pb, "lvcC");
1718 
1719  ff_isom_write_lvcc(pb, track->extradata[track->last_stsd_index],
1720  track->extradata_size[track->last_stsd_index]);
1721 
1722  return update_size(pb, pos);
1723 }
1724 
1725 static int mov_write_vvcc_tag(AVIOContext *pb, MOVTrack *track)
1726 {
1727  int64_t pos = avio_tell(pb);
1728 
1729  avio_wb32(pb, 0);
1730  ffio_wfourcc(pb, "vvcC");
1731 
1732  avio_w8 (pb, 0); /* version */
1733  avio_wb24(pb, 0); /* flags */
1734 
1735  if (track->tag == MKTAG('v','v','c','1'))
1736  ff_isom_write_vvcc(pb, track->extradata[track->last_stsd_index],
1737  track->extradata_size[track->last_stsd_index], 1);
1738  else
1739  ff_isom_write_vvcc(pb, track->extradata[track->last_stsd_index],
1740  track->extradata_size[track->last_stsd_index], 0);
1741  return update_size(pb, pos);
1742 }
1743 
1745 {
1746  int64_t pos = avio_tell(pb);
1747 
1748  avio_wb32(pb, 0);
1749  ffio_wfourcc(pb, "apvC");
1750 
1751  avio_w8 (pb, 0); /* version */
1752  avio_wb24(pb, 0); /* flags */
1753 
1754  ff_isom_write_apvc(pb, track->apv, s);
1755 
1756  return update_size(pb, pos);
1757 }
1758 
1759 /* also used by all avid codecs (dv, imx, meridien) and their variants */
1760 /* https://community.avid.com/forums/t/136517.aspx */
1761 static int mov_write_avid_tag(AVIOContext *pb, MOVTrack *track)
1762 {
1763  int interlaced;
1764  int cid;
1765  int display_width = track->par->width;
1766  const uint8_t *extradata;
1767 
1768  if (track->extradata[track->last_stsd_index] && track->extradata_size[track->last_stsd_index] > 0x29) {
1769  if (ff_dnxhd_parse_header_prefix(track->extradata[track->last_stsd_index]) != 0) {
1770  /* looks like a DNxHD bit stream */
1771  extradata = track->extradata[track->last_stsd_index];
1772  } else {
1773  av_log(NULL, AV_LOG_WARNING, "Could not locate DNxHD bit stream in vos_data\n");
1774  return 0;
1775  }
1776  } else {
1777  av_log(NULL, AV_LOG_WARNING, "Could not locate DNxHD bit stream, vos_data too small\n");
1778  return 0;
1779  }
1780 
1781  cid = AV_RB32(extradata + 0x28);
1782 
1783  avio_wb32(pb, 24); /* size */
1784  ffio_wfourcc(pb, "ACLR");
1785  ffio_wfourcc(pb, "ACLR");
1786  ffio_wfourcc(pb, "0001");
1787  // 1: CCIR (supercolors will be dropped, 16 will be displayed as black)
1788  // 2: FullRange (0 will be displayed as black, 16 will be displayed as dark grey)
1789  if (track->par->color_range == AVCOL_RANGE_MPEG || /* Legal range (16-235) */
1791  avio_wb32(pb, 1);
1792  } else {
1793  avio_wb32(pb, 2);
1794  }
1795  avio_wb32(pb, 0); /* reserved */
1796 
1797  if (track->tag == MKTAG('A','V','d','h')) {
1798  int alp = extradata[0x07] & 1;
1799  int pma = (extradata[0x07] >> 2) & 1;
1800  int sbd = (extradata[0x21] >> 5) & 3;
1801  int ssc = (extradata[0x2C] >> 5) & 3;
1802  int clv = (extradata[0x2C] >> 1) & 3;
1803  int clf = extradata[0x2C] & 1;
1804 
1805  avio_wb32(pb, 32);
1806  ffio_wfourcc(pb, "ADHR");
1807  ffio_wfourcc(pb, "0001");
1808  avio_wb32(pb, cid); // Compression ID
1809  // 0: 4:2:2 Sub Sampling
1810  // 1: 4:2:0 Sub Sampling
1811  // 2: 4:4:4 Sub Sampling
1812  avio_wb32(pb, ssc); // Sub Sampling Control
1813  // 1: 8-bits per sample
1814  // 2: 10-bits per sample
1815  // 3: 12-bits per sample
1816  avio_wb32(pb, sbd); // Sample Bit Depth
1817  // 0: Bitstream is encoded using the YCBCR format rules and tables
1818  // 1: Bitstream is encoded using the RGB format rules and tables – only Compression IDs 1256, 1270
1819  avio_wb16(pb, clf); // Color Format
1820  // 0: ITU-R BT.709
1821  // 1: ITU-R BT.2020
1822  // 2: ITU-R BT.2020 C
1823  // 3: Out-of-band
1824  avio_wb16(pb, clv); // Color Volume
1825  // 0: Alpha channel not present
1826  // 1: Alpha channel present
1827  avio_wb16(pb, alp); // Alpha Present
1828  // 0: Alpha has not been applied to video channels
1829  // 1: Alpha has been applied to the video channels prior to encoding
1830  avio_wb16(pb, pma); // Pre-Multiplied Alpha
1831  return 0;
1832  }
1833 
1834  interlaced = extradata[5] & 2;
1835 
1836  avio_wb32(pb, 24); /* size */
1837  ffio_wfourcc(pb, "APRG");
1838  ffio_wfourcc(pb, "APRG");
1839  ffio_wfourcc(pb, "0001");
1840  // 1 for progressive or 2 for interlaced
1841  if (interlaced)
1842  avio_wb32(pb, 2);
1843  else
1844  avio_wb32(pb, 1);
1845  avio_wb32(pb, 0); /* reserved */
1846 
1847  avio_wb32(pb, 120); /* size */
1848  ffio_wfourcc(pb, "ARES");
1849  ffio_wfourcc(pb, "ARES");
1850  ffio_wfourcc(pb, "0001");
1851  avio_wb32(pb, cid); /* cid */
1852  if ( track->par->sample_aspect_ratio.num > 0
1853  && track->par->sample_aspect_ratio.den > 0)
1854  display_width = display_width * track->par->sample_aspect_ratio.num / track->par->sample_aspect_ratio.den;
1855  avio_wb32(pb, display_width); // field width
1856  if (interlaced) {
1857  avio_wb32(pb, track->par->height / 2); // field height
1858  avio_wb32(pb, 2); // num fields
1859  avio_wb32(pb, 0); // num black lines (must be 0)
1860  // 4: HD1080i
1861  // 5: HD1080P
1862  // 6: HD720P
1863  avio_wb32(pb, 4); // video format
1864  } else {
1865  avio_wb32(pb, track->par->height);
1866  avio_wb32(pb, 1); // num fields
1867  avio_wb32(pb, 0);
1868  if (track->par->height == 1080)
1869  avio_wb32(pb, 5);
1870  else
1871  avio_wb32(pb, 6);
1872  }
1873  /* padding */
1874  ffio_fill(pb, 0, 10 * 8);
1875 
1876  return 0;
1877 }
1878 
1879 static int mov_write_dpxe_tag(AVIOContext *pb, MOVTrack *track)
1880 {
1881  avio_wb32(pb, 12);
1882  ffio_wfourcc(pb, "DpxE");
1883  if (track->extradata_size[track->last_stsd_index] >= 12 &&
1884  !memcmp(&track->extradata[track->last_stsd_index][4], "DpxE", 4)) {
1885  avio_wb32(pb, track->extradata[track->last_stsd_index][11]);
1886  } else {
1887  avio_wb32(pb, 1);
1888  }
1889  return 0;
1890 }
1891 
1893 {
1894  int tag;
1895 
1896  if (track->par->width == 720) { /* SD */
1897  if (track->par->height == 480) { /* NTSC */
1898  if (track->par->format == AV_PIX_FMT_YUV422P) tag = MKTAG('d','v','5','n');
1899  else tag = MKTAG('d','v','c',' ');
1900  }else if (track->par->format == AV_PIX_FMT_YUV422P) tag = MKTAG('d','v','5','p');
1901  else if (track->par->format == AV_PIX_FMT_YUV420P) tag = MKTAG('d','v','c','p');
1902  else tag = MKTAG('d','v','p','p');
1903  } else if (track->par->height == 720) { /* HD 720 line */
1904  if (track->st->time_base.den == 50) tag = MKTAG('d','v','h','q');
1905  else tag = MKTAG('d','v','h','p');
1906  } else if (track->par->height == 1080) { /* HD 1080 line */
1907  if (track->st->time_base.den == 25) tag = MKTAG('d','v','h','5');
1908  else tag = MKTAG('d','v','h','6');
1909  } else {
1910  av_log(s, AV_LOG_ERROR, "unsupported height for dv codec\n");
1911  return 0;
1912  }
1913 
1914  return tag;
1915 }
1916 
1918 {
1919  AVRational rational_framerate = st->avg_frame_rate;
1920  int rate = 0;
1921  if (rational_framerate.den != 0)
1922  rate = av_q2d(rational_framerate);
1923  return rate;
1924 }
1925 
1927 {
1928  int tag = track->par->codec_tag;
1930  AVStream *st = track->st;
1931  int rate = defined_frame_rate(s, st);
1932 
1933  if (!tag)
1934  tag = MKTAG('m', '2', 'v', '1'); //fallback tag
1935 
1936  if (track->par->format == AV_PIX_FMT_YUV420P) {
1937  if (track->par->width == 1280 && track->par->height == 720) {
1938  if (!interlaced) {
1939  if (rate == 24) tag = MKTAG('x','d','v','4');
1940  else if (rate == 25) tag = MKTAG('x','d','v','5');
1941  else if (rate == 30) tag = MKTAG('x','d','v','1');
1942  else if (rate == 50) tag = MKTAG('x','d','v','a');
1943  else if (rate == 60) tag = MKTAG('x','d','v','9');
1944  }
1945  } else if (track->par->width == 1440 && track->par->height == 1080) {
1946  if (!interlaced) {
1947  if (rate == 24) tag = MKTAG('x','d','v','6');
1948  else if (rate == 25) tag = MKTAG('x','d','v','7');
1949  else if (rate == 30) tag = MKTAG('x','d','v','8');
1950  } else {
1951  if (rate == 25) tag = MKTAG('x','d','v','3');
1952  else if (rate == 30) tag = MKTAG('x','d','v','2');
1953  }
1954  } else if (track->par->width == 1920 && track->par->height == 1080) {
1955  if (!interlaced) {
1956  if (rate == 24) tag = MKTAG('x','d','v','d');
1957  else if (rate == 25) tag = MKTAG('x','d','v','e');
1958  else if (rate == 30) tag = MKTAG('x','d','v','f');
1959  } else {
1960  if (rate == 25) tag = MKTAG('x','d','v','c');
1961  else if (rate == 30) tag = MKTAG('x','d','v','b');
1962  }
1963  }
1964  } else if (track->par->format == AV_PIX_FMT_YUV422P) {
1965  if (track->par->width == 1280 && track->par->height == 720) {
1966  if (!interlaced) {
1967  if (rate == 24) tag = MKTAG('x','d','5','4');
1968  else if (rate == 25) tag = MKTAG('x','d','5','5');
1969  else if (rate == 30) tag = MKTAG('x','d','5','1');
1970  else if (rate == 50) tag = MKTAG('x','d','5','a');
1971  else if (rate == 60) tag = MKTAG('x','d','5','9');
1972  }
1973  } else if (track->par->width == 1920 && track->par->height == 1080) {
1974  if (!interlaced) {
1975  if (rate == 24) tag = MKTAG('x','d','5','d');
1976  else if (rate == 25) tag = MKTAG('x','d','5','e');
1977  else if (rate == 30) tag = MKTAG('x','d','5','f');
1978  } else {
1979  if (rate == 25) tag = MKTAG('x','d','5','c');
1980  else if (rate == 30) tag = MKTAG('x','d','5','b');
1981  }
1982  }
1983  }
1984 
1985  return tag;
1986 }
1987 
1989 {
1990  int tag = track->par->codec_tag;
1992  AVStream *st = track->st;
1993  int rate = defined_frame_rate(s, st);
1994 
1995  if (!tag)
1996  tag = MKTAG('a', 'v', 'c', 'i'); //fallback tag
1997 
1998  if (track->par->profile == AV_PROFILE_UNKNOWN ||
1999  !(track->par->profile & AV_PROFILE_H264_INTRA))
2000  return tag;
2001 
2002  if (track->par->format == AV_PIX_FMT_YUV420P10) {
2003  if (track->par->width == 960 && track->par->height == 720) {
2004  if (!interlaced) {
2005  if (rate == 24) tag = MKTAG('a','i','5','p');
2006  else if (rate == 25) tag = MKTAG('a','i','5','q');
2007  else if (rate == 30) tag = MKTAG('a','i','5','p');
2008  else if (rate == 50) tag = MKTAG('a','i','5','q');
2009  else if (rate == 60) tag = MKTAG('a','i','5','p');
2010  }
2011  } else if (track->par->width == 1440 && track->par->height == 1080) {
2012  if (!interlaced) {
2013  if (rate == 24) tag = MKTAG('a','i','5','3');
2014  else if (rate == 25) tag = MKTAG('a','i','5','2');
2015  else if (rate == 30) tag = MKTAG('a','i','5','3');
2016  } else {
2017  if (rate == 50) tag = MKTAG('a','i','5','5');
2018  else if (rate == 60) tag = MKTAG('a','i','5','6');
2019  }
2020  }
2021  } else if (track->par->format == AV_PIX_FMT_YUV422P10) {
2022  if (track->par->width == 1280 && track->par->height == 720) {
2023  if (!interlaced) {
2024  if (rate == 24) tag = MKTAG('a','i','1','p');
2025  else if (rate == 25) tag = MKTAG('a','i','1','q');
2026  else if (rate == 30) tag = MKTAG('a','i','1','p');
2027  else if (rate == 50) tag = MKTAG('a','i','1','q');
2028  else if (rate == 60) tag = MKTAG('a','i','1','p');
2029  }
2030  } else if (track->par->width == 1920 && track->par->height == 1080) {
2031  if (!interlaced) {
2032  if (rate == 24) tag = MKTAG('a','i','1','3');
2033  else if (rate == 25) tag = MKTAG('a','i','1','2');
2034  else if (rate == 30) tag = MKTAG('a','i','1','3');
2035  } else {
2036  if (rate == 25) tag = MKTAG('a','i','1','5');
2037  else if (rate == 50) tag = MKTAG('a','i','1','5');
2038  else if (rate == 60) tag = MKTAG('a','i','1','6');
2039  }
2040  } else if ( track->par->width == 4096 && track->par->height == 2160
2041  || track->par->width == 3840 && track->par->height == 2160
2042  || track->par->width == 2048 && track->par->height == 1080) {
2043  tag = MKTAG('a','i','v','x');
2044  }
2045  }
2046 
2047  return tag;
2048 }
2049 
2051 {
2052  int tag = track->par->codec_tag;
2053 
2054  if (!tag)
2055  tag = MKTAG('e', 'v', 'c', '1');
2056 
2057  return tag;
2058 }
2059 
2061 {
2062  int tag = track->par->codec_tag;
2063 
2064  if (!tag)
2065  tag = MKTAG('a', 'p', 'v', '1');
2066 
2067  return tag;
2068 }
2069 
2070 
2071 static const struct {
2073  uint32_t tag;
2074  unsigned bps;
2075 } mov_pix_fmt_tags[] = {
2076  { AV_PIX_FMT_YUYV422, MKTAG('y','u','v','2'), 0 },
2077  { AV_PIX_FMT_YUYV422, MKTAG('y','u','v','s'), 0 },
2078  { AV_PIX_FMT_UYVY422, MKTAG('2','v','u','y'), 0 },
2079  { AV_PIX_FMT_VYU444, MKTAG('v','3','0','8'), 0 },
2080  { AV_PIX_FMT_UYVA, MKTAG('v','4','0','8'), 0 },
2081  { AV_PIX_FMT_V30XLE, MKTAG('v','4','1','0'), 0 },
2082  { AV_PIX_FMT_RGB555BE,MKTAG('r','a','w',' '), 16 },
2083  { AV_PIX_FMT_RGB555LE,MKTAG('L','5','5','5'), 16 },
2084  { AV_PIX_FMT_RGB565LE,MKTAG('L','5','6','5'), 16 },
2085  { AV_PIX_FMT_RGB565BE,MKTAG('B','5','6','5'), 16 },
2086  { AV_PIX_FMT_GRAY16BE,MKTAG('b','1','6','g'), 16 },
2087  { AV_PIX_FMT_RGB24, MKTAG('r','a','w',' '), 24 },
2088  { AV_PIX_FMT_BGR24, MKTAG('2','4','B','G'), 24 },
2089  { AV_PIX_FMT_ARGB, MKTAG('r','a','w',' '), 32 },
2090  { AV_PIX_FMT_BGRA, MKTAG('B','G','R','A'), 32 },
2091  { AV_PIX_FMT_RGBA, MKTAG('R','G','B','A'), 32 },
2092  { AV_PIX_FMT_ABGR, MKTAG('A','B','G','R'), 32 },
2093  { AV_PIX_FMT_RGB48BE, MKTAG('b','4','8','r'), 48 },
2094 };
2095 
2097 {
2098  int tag = MKTAG('A','V','d','n');
2099  if (track->par->profile != AV_PROFILE_UNKNOWN &&
2100  track->par->profile != AV_PROFILE_DNXHD)
2101  tag = MKTAG('A','V','d','h');
2102  return tag;
2103 }
2104 
2106 {
2107  int tag = track->par->codec_tag;
2108  int i;
2109  enum AVPixelFormat pix_fmt;
2110 
2111  for (i = 0; i < FF_ARRAY_ELEMS(mov_pix_fmt_tags); i++) {
2112  if (track->par->format == mov_pix_fmt_tags[i].pix_fmt) {
2113  tag = mov_pix_fmt_tags[i].tag;
2115  if (track->par->codec_tag == mov_pix_fmt_tags[i].tag)
2116  break;
2117  }
2118  }
2119 
2121  track->par->bits_per_coded_sample);
2122  if (tag == MKTAG('r','a','w',' ') &&
2123  track->par->format != pix_fmt &&
2124  track->par->format != AV_PIX_FMT_GRAY8 &&
2125  track->par->format != AV_PIX_FMT_NONE)
2126  av_log(s, AV_LOG_ERROR, "%s rawvideo cannot be written to mov, output file will be unreadable\n",
2127  av_get_pix_fmt_name(track->par->format));
2128  return tag;
2129 }
2130 
2131 static unsigned int mov_get_codec_tag(AVFormatContext *s, MOVTrack *track)
2132 {
2133  unsigned int tag = track->par->codec_tag;
2134 
2135  // "rtp " is used to distinguish internally created RTP-hint tracks
2136  // (with rtp_ctx) from other tracks.
2137  if (tag == MKTAG('r','t','p',' '))
2138  tag = 0;
2139  if (!tag || (s->strict_std_compliance >= FF_COMPLIANCE_NORMAL &&
2140  (track->par->codec_id == AV_CODEC_ID_DVVIDEO ||
2141  track->par->codec_id == AV_CODEC_ID_RAWVIDEO ||
2142  track->par->codec_id == AV_CODEC_ID_H263 ||
2143  track->par->codec_id == AV_CODEC_ID_H264 ||
2144  track->par->codec_id == AV_CODEC_ID_DNXHD ||
2145  track->par->codec_id == AV_CODEC_ID_MPEG2VIDEO ||
2146  av_get_bits_per_sample(track->par->codec_id)))) { // pcm audio
2147  if (track->par->codec_id == AV_CODEC_ID_DVVIDEO)
2148  tag = mov_get_dv_codec_tag(s, track);
2149  else if (track->par->codec_id == AV_CODEC_ID_RAWVIDEO)
2150  tag = mov_get_rawvideo_codec_tag(s, track);
2151  else if (track->par->codec_id == AV_CODEC_ID_MPEG2VIDEO)
2153  else if (track->par->codec_id == AV_CODEC_ID_H264)
2154  tag = mov_get_h264_codec_tag(s, track);
2155  else if (track->par->codec_id == AV_CODEC_ID_EVC)
2156  tag = mov_get_evc_codec_tag(s, track);
2157  else if (track->par->codec_id == AV_CODEC_ID_APV)
2158  tag = mov_get_apv_codec_tag(s, track);
2159  else if (track->par->codec_id == AV_CODEC_ID_DNXHD)
2160  tag = mov_get_dnxhd_codec_tag(s, track);
2161  else if (track->par->codec_type == AVMEDIA_TYPE_VIDEO) {
2163  if (!tag) { // if no mac fcc found, try with Microsoft tags
2165  if (tag)
2166  av_log(s, AV_LOG_WARNING, "Using MS style video codec tag, "
2167  "the file may be unplayable!\n");
2168  }
2169  } else if (track->par->codec_type == AVMEDIA_TYPE_AUDIO) {
2171  if (!tag) { // if no mac fcc found, try with Microsoft tags
2172  int ms_tag = ff_codec_get_tag(ff_codec_wav_tags, track->par->codec_id);
2173  if (ms_tag) {
2174  tag = MKTAG('m', 's', ((ms_tag >> 8) & 0xff), (ms_tag & 0xff));
2175  av_log(s, AV_LOG_WARNING, "Using MS style audio codec tag, "
2176  "the file may be unplayable!\n");
2177  }
2178  }
2179  } else if (track->par->codec_type == AVMEDIA_TYPE_SUBTITLE)
2181  }
2182 
2183  return tag;
2184 }
2185 
2187  { AV_CODEC_ID_MJPEG, 0xD },
2188  { AV_CODEC_ID_PNG, 0xE },
2189  { AV_CODEC_ID_BMP, 0x1B },
2190  { AV_CODEC_ID_NONE, 0 },
2191 };
2192 
2193 static unsigned int validate_codec_tag(const AVCodecTag *const *tags,
2194  unsigned int tag, int codec_id)
2195 {
2196  int i;
2197 
2198  /**
2199  * Check that tag + id is in the table
2200  */
2201  for (i = 0; tags && tags[i]; i++) {
2202  const AVCodecTag *codec_tags = tags[i];
2203  while (codec_tags->id != AV_CODEC_ID_NONE) {
2204  if (ff_toupper4(codec_tags->tag) == ff_toupper4(tag) &&
2205  codec_tags->id == codec_id)
2206  return codec_tags->tag;
2207  codec_tags++;
2208  }
2209  }
2210  return 0;
2211 }
2212 
2213 static unsigned int mov_find_codec_tag(AVFormatContext *s, MOVTrack *track)
2214 {
2215  if (is_cover_image(track->st))
2217 
2218  if (track->mode == MODE_IPOD)
2219  if (!av_match_ext(s->url, "m4a") &&
2220  !av_match_ext(s->url, "m4v") &&
2221  !av_match_ext(s->url, "m4b"))
2222  av_log(s, AV_LOG_WARNING, "Warning, extension is not .m4a nor .m4v "
2223  "Quicktime/Ipod might not play the file\n");
2224 
2225  if (track->mode == MODE_MOV) {
2226  return mov_get_codec_tag(s, track);
2227  } else
2228  return validate_codec_tag(s->oformat->codec_tag, track->par->codec_tag,
2229  track->par->codec_id);
2230 }
2231 
2232 /** Write uuid atom.
2233  * Needed to make file play in iPods running newest firmware
2234  * goes after avcC atom in moov.trak.mdia.minf.stbl.stsd.avc1
2235  */
2237 {
2238  avio_wb32(pb, 28);
2239  ffio_wfourcc(pb, "uuid");
2240  avio_wb32(pb, 0x6b6840f2);
2241  avio_wb32(pb, 0x5f244fc5);
2242  avio_wb32(pb, 0xba39a51b);
2243  avio_wb32(pb, 0xcf0323f3);
2244  avio_wb32(pb, 0x0);
2245  return 28;
2246 }
2247 
2248 static const uint16_t fiel_data[] = {
2249  0x0000, 0x0100, 0x0201, 0x0206, 0x0209, 0x020e
2250 };
2251 
2252 static int mov_write_fiel_tag(AVIOContext *pb, MOVTrack *track, int field_order)
2253 {
2254  unsigned mov_field_order = 0;
2255  if (field_order < FF_ARRAY_ELEMS(fiel_data))
2256  mov_field_order = fiel_data[field_order];
2257  else
2258  return 0;
2259  avio_wb32(pb, 10);
2260  ffio_wfourcc(pb, "fiel");
2261  avio_wb16(pb, mov_field_order);
2262  return 10;
2263 }
2264 
2266 {
2267  MOVMuxContext *mov = s->priv_data;
2268  int ret = AVERROR_BUG;
2269  int64_t pos = avio_tell(pb);
2270  avio_wb32(pb, 0); /* size */
2271  avio_wl32(pb, track->tag); // store it byteswapped
2272  avio_wb32(pb, 0); /* Reserved */
2273  avio_wb16(pb, 0); /* Reserved */
2274  avio_wb16(pb, 1); /* Data-reference index */
2275 
2276  if (track->par->codec_id == AV_CODEC_ID_DVD_SUBTITLE)
2277  mov_write_esds_tag(pb, track);
2278  else if (track->par->codec_id == AV_CODEC_ID_TTML) {
2279  switch (track->par->codec_tag) {
2280  case MOV_ISMV_TTML_TAG:
2281  // ISMV dfxp requires no extradata.
2282  break;
2283  case MOV_MP4_TTML_TAG:
2284  // As specified in 14496-30, XMLSubtitleSampleEntry
2285  // Namespace
2286  avio_put_str(pb, "http://www.w3.org/ns/ttml");
2287  // Empty schema_location
2288  avio_w8(pb, 0);
2289  // Empty auxiliary_mime_types
2290  avio_w8(pb, 0);
2291  break;
2292  default:
2294  "Unknown codec tag '%s' utilized for TTML stream with "
2295  "index %d (track id %d)!\n",
2296  av_fourcc2str(track->par->codec_tag), track->st->index,
2297  track->track_id);
2298  return AVERROR(EINVAL);
2299  }
2300  } else if (track->extradata_size[track->last_stsd_index])
2301  avio_write(pb, track->extradata[track->last_stsd_index], track->extradata_size[track->last_stsd_index]);
2302 
2303  if (mov->write_btrt &&
2304  ((ret = mov_write_btrt_tag(pb, track)) < 0))
2305  return ret;
2306 
2307  return update_size(pb, pos);
2308 }
2309 
2311 {
2312  int8_t stereo_mode;
2313 
2314  if (stereo_3d->flags != 0) {
2315  av_log(s, AV_LOG_WARNING, "Unsupported stereo_3d flags %x. st3d not written.\n", stereo_3d->flags);
2316  return 0;
2317  }
2318 
2319  switch (stereo_3d->type) {
2320  case AV_STEREO3D_2D:
2321  stereo_mode = 0;
2322  break;
2323  case AV_STEREO3D_TOPBOTTOM:
2324  stereo_mode = 1;
2325  break;
2327  stereo_mode = 2;
2328  break;
2329  default:
2330  av_log(s, AV_LOG_WARNING, "Unsupported stereo_3d type %s. st3d not written.\n", av_stereo3d_type_name(stereo_3d->type));
2331  return 0;
2332  }
2333  avio_wb32(pb, 13); /* size */
2334  ffio_wfourcc(pb, "st3d");
2335  avio_wb32(pb, 0); /* version = 0 & flags = 0 */
2336  avio_w8(pb, stereo_mode);
2337  return 13;
2338 }
2339 
2341 {
2342  int64_t sv3d_pos, svhd_pos, proj_pos;
2343  const char* metadata_source = s->flags & AVFMT_FLAG_BITEXACT ? "Lavf" : LIBAVFORMAT_IDENT;
2344 
2345  if (spherical_mapping->projection != AV_SPHERICAL_EQUIRECTANGULAR &&
2346  spherical_mapping->projection != AV_SPHERICAL_EQUIRECTANGULAR_TILE &&
2347  spherical_mapping->projection != AV_SPHERICAL_CUBEMAP) {
2348  av_log(s, AV_LOG_WARNING, "Unsupported projection %d. sv3d not written.\n", spherical_mapping->projection);
2349  return 0;
2350  }
2351 
2352  sv3d_pos = avio_tell(pb);
2353  avio_wb32(pb, 0); /* size */
2354  ffio_wfourcc(pb, "sv3d");
2355 
2356  svhd_pos = avio_tell(pb);
2357  avio_wb32(pb, 0); /* size */
2358  ffio_wfourcc(pb, "svhd");
2359  avio_wb32(pb, 0); /* version = 0 & flags = 0 */
2360  avio_put_str(pb, metadata_source);
2361  update_size(pb, svhd_pos);
2362 
2363  proj_pos = avio_tell(pb);
2364  avio_wb32(pb, 0); /* size */
2365  ffio_wfourcc(pb, "proj");
2366 
2367  avio_wb32(pb, 24); /* size */
2368  ffio_wfourcc(pb, "prhd");
2369  avio_wb32(pb, 0); /* version = 0 & flags = 0 */
2370  avio_wb32(pb, spherical_mapping->yaw);
2371  avio_wb32(pb, spherical_mapping->pitch);
2372  avio_wb32(pb, spherical_mapping->roll);
2373 
2374  switch (spherical_mapping->projection) {
2377  avio_wb32(pb, 28); /* size */
2378  ffio_wfourcc(pb, "equi");
2379  avio_wb32(pb, 0); /* version = 0 & flags = 0 */
2380  avio_wb32(pb, spherical_mapping->bound_top);
2381  avio_wb32(pb, spherical_mapping->bound_bottom);
2382  avio_wb32(pb, spherical_mapping->bound_left);
2383  avio_wb32(pb, spherical_mapping->bound_right);
2384  break;
2385  case AV_SPHERICAL_CUBEMAP:
2386  avio_wb32(pb, 20); /* size */
2387  ffio_wfourcc(pb, "cbmp");
2388  avio_wb32(pb, 0); /* version = 0 & flags = 0 */
2389  avio_wb32(pb, 0); /* layout */
2390  avio_wb32(pb, spherical_mapping->padding); /* padding */
2391  break;
2392  }
2393  update_size(pb, proj_pos);
2394 
2395  return update_size(pb, sv3d_pos);
2396 }
2397 
2398 static inline int64_t rescale_rational(AVRational q, int b)
2399 {
2400  return av_rescale(q.num, b, q.den);
2401 }
2402 
2404  const AVStereo3D *stereo3d)
2405 {
2406  if (!stereo3d->horizontal_field_of_view.num)
2407  return;
2408 
2409  avio_wb32(pb, 12); /* size */
2410  ffio_wfourcc(pb, "hfov");
2411  avio_wb32(pb, rescale_rational(stereo3d->horizontal_field_of_view, 1000));
2412 }
2413 
2415  const AVSphericalMapping *spherical_mapping)
2416 {
2417  avio_wb32(pb, 24); /* size */
2418  ffio_wfourcc(pb, "proj");
2419  avio_wb32(pb, 16); /* size */
2420  ffio_wfourcc(pb, "prji");
2421  avio_wb32(pb, 0); /* version + flags */
2422 
2423  switch (spherical_mapping->projection) {
2425  ffio_wfourcc(pb, "rect");
2426  break;
2428  ffio_wfourcc(pb, "equi");
2429  break;
2431  ffio_wfourcc(pb, "hequ");
2432  break;
2433  case AV_SPHERICAL_FISHEYE:
2434  ffio_wfourcc(pb, "fish");
2435  break;
2436  default:
2437  av_assert0(0);
2438  }
2439 }
2440 
2442  const AVStereo3D *stereo3d)
2443 {
2444  int64_t pos = avio_tell(pb);
2445  int view = 0;
2446 
2447  avio_wb32(pb, 0); /* size */
2448  ffio_wfourcc(pb, "eyes");
2449 
2450  // stri is mandatory
2451  avio_wb32(pb, 13); /* size */
2452  ffio_wfourcc(pb, "stri");
2453  avio_wb32(pb, 0); /* version + flags */
2454  switch (stereo3d->view) {
2455  case AV_STEREO3D_VIEW_LEFT:
2456  view |= 1 << 0;
2457  break;
2459  view |= 1 << 1;
2460  break;
2462  view |= (1 << 0) | (1 << 1);
2463  break;
2464  }
2465  view |= !!(stereo3d->flags & AV_STEREO3D_FLAG_INVERT) << 3;
2466  avio_w8(pb, view);
2467 
2468  // hero is optional
2469  if (stereo3d->primary_eye != AV_PRIMARY_EYE_NONE) {
2470  avio_wb32(pb, 13); /* size */
2471  ffio_wfourcc(pb, "hero");
2472  avio_wb32(pb, 0); /* version + flags */
2473  avio_w8(pb, stereo3d->primary_eye);
2474  }
2475 
2476  // it's not clear if cams is mandatory or optional
2477  if (stereo3d->baseline) {
2478  avio_wb32(pb, 24); /* size */
2479  ffio_wfourcc(pb, "cams");
2480  avio_wb32(pb, 16); /* size */
2481  ffio_wfourcc(pb, "blin");
2482  avio_wb32(pb, 0); /* version + flags */
2483  avio_wb32(pb, stereo3d->baseline);
2484  }
2485 
2486  // it's not clear if cmfy is mandatory or optional
2487  if (stereo3d->horizontal_disparity_adjustment.num) {
2488  avio_wb32(pb, 24); /* size */
2489  ffio_wfourcc(pb, "cmfy");
2490  avio_wb32(pb, 16); /* size */
2491  ffio_wfourcc(pb, "dadj");
2492  avio_wb32(pb, 0); /* version + flags */
2494  }
2495 
2496  return update_size(pb, pos);
2497 }
2498 
2500  const AVStereo3D *stereo3d,
2501  const AVSphericalMapping *spherical_mapping)
2502 {
2503  int64_t pos;
2504 
2505  if (spherical_mapping &&
2506  spherical_mapping->projection != AV_SPHERICAL_RECTILINEAR &&
2507  spherical_mapping->projection != AV_SPHERICAL_EQUIRECTANGULAR &&
2508  spherical_mapping->projection != AV_SPHERICAL_HALF_EQUIRECTANGULAR &&
2509  spherical_mapping->projection != AV_SPHERICAL_FISHEYE) {
2510  av_log(s, AV_LOG_WARNING, "Unsupported projection %d. proj not written.\n",
2511  spherical_mapping->projection);
2512  spherical_mapping = NULL;
2513  }
2514 
2515  if (stereo3d && (stereo3d->type == AV_STEREO3D_2D ||
2516  (!(stereo3d->flags & AV_STEREO3D_FLAG_INVERT) &&
2517  stereo3d->view == AV_STEREO3D_VIEW_UNSPEC &&
2518  stereo3d->primary_eye == AV_PRIMARY_EYE_NONE &&
2519  !stereo3d->baseline &&
2520  !stereo3d->horizontal_disparity_adjustment.num))) {
2521  av_log(s, AV_LOG_WARNING, "Unsupported stereo 3d metadata. eyes not written.\n");
2522  stereo3d = NULL;
2523  }
2524 
2525  if (!spherical_mapping && !stereo3d)
2526  return 0;
2527 
2528  pos = avio_tell(pb);
2529  avio_wb32(pb, 0); /* size */
2530  ffio_wfourcc(pb, "vexu");
2531 
2532  if (spherical_mapping)
2533  mov_write_vexu_proj_tag(s, pb, spherical_mapping);
2534 
2535  if (stereo3d)
2536  mov_write_eyes_tag(s, pb, stereo3d);
2537 
2538  return update_size(pb, pos);
2539 }
2540 
2542 {
2543  uint8_t buf[ISOM_DVCC_DVVC_SIZE];
2544 
2545  avio_wb32(pb, 32); /* size = 8 + 24 */
2546  if (dovi->dv_profile > 10)
2547  ffio_wfourcc(pb, "dvwC");
2548  else if (dovi->dv_profile > 7)
2549  ffio_wfourcc(pb, "dvvC");
2550  else
2551  ffio_wfourcc(pb, "dvcC");
2552 
2553  ff_isom_put_dvcc_dvvc(s, buf, dovi);
2554  avio_write(pb, buf, sizeof(buf));
2555 
2556  return 32; /* 8 + 24 */
2557 }
2558 
2560 {
2561  avio_wb32(pb, 8 + sd->size);
2562  ffio_wfourcc(pb, "hvcE");
2563  avio_write(pb, sd->data, sd->size);
2564  return 8 + sd->size;
2565 }
2566 
2567 static int mov_write_clap_tag(AVIOContext *pb, MOVTrack *track,
2568  uint32_t top, uint32_t bottom,
2569  uint32_t left, uint32_t right)
2570 {
2571  uint32_t cropped_width = track->par->width - left - right;
2572  uint32_t cropped_height = track->height - top - bottom;
2573  AVRational horizOff =
2574  av_sub_q((AVRational) { track->par->width - cropped_width, 2 },
2575  (AVRational) { left, 1 });
2576  AVRational vertOff =
2577  av_sub_q((AVRational) { track->height - cropped_height, 2 },
2578  (AVRational) { top, 1 });
2579 
2580  avio_wb32(pb, 40);
2581  ffio_wfourcc(pb, "clap");
2582  avio_wb32(pb, cropped_width); /* apertureWidthN */
2583  avio_wb32(pb, 1); /* apertureWidthD */
2584  avio_wb32(pb, cropped_height); /* apertureHeightN */
2585  avio_wb32(pb, 1); /* apertureHeightD */
2586 
2587  avio_wb32(pb, -horizOff.num);
2588  avio_wb32(pb, horizOff.den);
2589  avio_wb32(pb, -vertOff.num);
2590  avio_wb32(pb, vertOff.den);
2591 
2592  return 40;
2593 }
2594 
2595 static int mov_write_pasp_tag(AVIOContext *pb, MOVTrack *track)
2596 {
2597  AVRational sar;
2598  av_reduce(&sar.num, &sar.den, track->par->sample_aspect_ratio.num,
2599  track->par->sample_aspect_ratio.den, INT_MAX);
2600 
2601  avio_wb32(pb, 16);
2602  ffio_wfourcc(pb, "pasp");
2603  avio_wb32(pb, sar.num);
2604  avio_wb32(pb, sar.den);
2605  return 16;
2606 }
2607 
2608 static int mov_write_gama_tag(AVFormatContext *s, AVIOContext *pb, MOVTrack *track, double gamma)
2609 {
2610  uint32_t gama = 0;
2611  if (gamma <= 0.0)
2612  gamma = av_csp_approximate_eotf_gamma(track->par->color_trc);
2613  av_log(s, AV_LOG_DEBUG, "gamma value %g\n", gamma);
2614 
2615  if (gamma > 1e-6) {
2616  gama = (uint32_t)lrint((double)(1<<16) * gamma);
2617  av_log(s, AV_LOG_DEBUG, "writing gama value %"PRId32"\n", gama);
2618 
2619  av_assert0(track->mode == MODE_MOV);
2620  avio_wb32(pb, 12);
2621  ffio_wfourcc(pb, "gama");
2622  avio_wb32(pb, gama);
2623  return 12;
2624  } else {
2625  av_log(s, AV_LOG_WARNING, "gamma value unknown, unable to write gama atom\n");
2626  }
2627  return 0;
2628 }
2629 
2630 static int mov_write_colr_tag(AVIOContext *pb, MOVTrack *track, int prefer_icc)
2631 {
2632  int64_t pos = avio_tell(pb);
2633 
2634  // Ref (MOV): https://developer.apple.com/library/mac/technotes/tn2162/_index.html#//apple_ref/doc/uid/DTS40013070-CH1-TNTAG9
2635  // Ref (MP4): ISO/IEC 14496-12:2012
2636 
2637  if (prefer_icc) {
2639  track->st->codecpar->nb_coded_side_data,
2641 
2642  if (sd) {
2643  avio_wb32(pb, 12 + sd->size);
2644  ffio_wfourcc(pb, "colr");
2645  ffio_wfourcc(pb, "prof");
2646  avio_write(pb, sd->data, sd->size);
2647  return 12 + sd->size;
2648  }
2649  else {
2650  av_log(NULL, AV_LOG_INFO, "no ICC profile found, will write nclx/nclc colour info instead\n");
2651  }
2652  }
2653 
2654  /* We should only ever be called for MOV, MP4 and AVIF. */
2655  av_assert0(track->mode == MODE_MOV || track->mode == MODE_MP4 ||
2656  track->mode == MODE_AVIF);
2657 
2658  avio_wb32(pb, 0); /* size */
2659  ffio_wfourcc(pb, "colr");
2660  if (track->mode == MODE_MP4 || track->mode == MODE_AVIF)
2661  ffio_wfourcc(pb, "nclx");
2662  else
2663  ffio_wfourcc(pb, "nclc");
2664  // Do not try to guess the color info if it is AVCOL_PRI_UNSPECIFIED.
2665  // e.g., Dolby Vision for Apple devices should be set to AVCOL_PRI_UNSPECIFIED. See
2666  // https://developer.apple.com/av-foundation/High-Dynamic-Range-Metadata-for-Apple-Devices.pdf
2667  avio_wb16(pb, track->par->color_primaries);
2668  avio_wb16(pb, track->par->color_trc);
2669  avio_wb16(pb, track->par->color_space);
2670  if (track->mode == MODE_MP4 || track->mode == MODE_AVIF) {
2671  int full_range = track->par->color_range == AVCOL_RANGE_JPEG;
2672  avio_w8(pb, full_range << 7);
2673  }
2674 
2675  return update_size(pb, pos);
2676 }
2677 
2678 static int mov_write_clli_tag(AVIOContext *pb, MOVTrack *track)
2679 {
2680  const AVPacketSideData *side_data;
2681  const AVContentLightMetadata *content_light_metadata;
2682 
2683  side_data = av_packet_side_data_get(track->st->codecpar->coded_side_data,
2684  track->st->codecpar->nb_coded_side_data,
2686  if (!side_data) {
2687  return 0;
2688  }
2689  content_light_metadata = (const AVContentLightMetadata*)side_data->data;
2690 
2691  avio_wb32(pb, 12); // size
2692  ffio_wfourcc(pb, "clli");
2693  avio_wb16(pb, content_light_metadata->MaxCLL);
2694  avio_wb16(pb, content_light_metadata->MaxFALL);
2695  return 12;
2696 }
2697 
2698 static int mov_write_mdcv_tag(AVIOContext *pb, MOVTrack *track)
2699 {
2700  const int chroma_den = 50000;
2701  const int luma_den = 10000;
2702  const AVPacketSideData *side_data;
2704 
2705  side_data = av_packet_side_data_get(track->st->codecpar->coded_side_data,
2706  track->st->codecpar->nb_coded_side_data,
2708  if (side_data)
2709  metadata = (const AVMasteringDisplayMetadata*)side_data->data;
2710  if (!metadata || !metadata->has_primaries || !metadata->has_luminance) {
2711  return 0;
2712  }
2713 
2714  avio_wb32(pb, 32); // size
2715  ffio_wfourcc(pb, "mdcv");
2716  avio_wb16(pb, rescale_rational(metadata->display_primaries[1][0], chroma_den));
2717  avio_wb16(pb, rescale_rational(metadata->display_primaries[1][1], chroma_den));
2718  avio_wb16(pb, rescale_rational(metadata->display_primaries[2][0], chroma_den));
2719  avio_wb16(pb, rescale_rational(metadata->display_primaries[2][1], chroma_den));
2720  avio_wb16(pb, rescale_rational(metadata->display_primaries[0][0], chroma_den));
2721  avio_wb16(pb, rescale_rational(metadata->display_primaries[0][1], chroma_den));
2722  avio_wb16(pb, rescale_rational(metadata->white_point[0], chroma_den));
2723  avio_wb16(pb, rescale_rational(metadata->white_point[1], chroma_den));
2724  avio_wb32(pb, rescale_rational(metadata->max_luminance, luma_den));
2725  avio_wb32(pb, rescale_rational(metadata->min_luminance, luma_den));
2726  return 32;
2727 }
2728 
2729 static int mov_write_amve_tag(AVIOContext *pb, MOVTrack *track)
2730 {
2731  const int illuminance_den = 10000;
2732  const int ambient_den = 50000;
2733  const AVPacketSideData *side_data;
2734  const AVAmbientViewingEnvironment *ambient;
2735 
2736 
2737  side_data = av_packet_side_data_get(track->st->codecpar->coded_side_data,
2738  track->st->codecpar->nb_coded_side_data,
2740 
2741  if (!side_data)
2742  return 0;
2743 
2744  ambient = (const AVAmbientViewingEnvironment*)side_data->data;
2745  if (!ambient || !ambient->ambient_illuminance.num)
2746  return 0;
2747 
2748  avio_wb32(pb, 16); // size
2749  ffio_wfourcc(pb, "amve");
2750  avio_wb32(pb, rescale_rational(ambient->ambient_illuminance, illuminance_den));
2751  avio_wb16(pb, rescale_rational(ambient->ambient_light_x, ambient_den));
2752  avio_wb16(pb, rescale_rational(ambient->ambient_light_y, ambient_den));
2753  return 16;
2754 }
2755 
2756 static void find_compressor(char * compressor_name, int len, MOVTrack *track)
2757 {
2758  AVDictionaryEntry *encoder;
2759  int xdcam_res = (track->par->width == 1280 && track->par->height == 720)
2760  || (track->par->width == 1440 && track->par->height == 1080)
2761  || (track->par->width == 1920 && track->par->height == 1080);
2762 
2763  if ((track->mode == MODE_AVIF ||
2764  track->mode == MODE_MOV ||
2765  track->mode == MODE_MP4) &&
2766  (encoder = av_dict_get(track->st->metadata, "encoder", NULL, 0))) {
2767  av_strlcpy(compressor_name, encoder->value, 32);
2768  } else if (track->par->codec_id == AV_CODEC_ID_MPEG2VIDEO && xdcam_res) {
2770  AVStream *st = track->st;
2771  int rate = defined_frame_rate(NULL, st);
2772  av_strlcatf(compressor_name, len, "XDCAM");
2773  if (track->par->format == AV_PIX_FMT_YUV422P) {
2774  av_strlcatf(compressor_name, len, " HD422");
2775  } else if(track->par->width == 1440) {
2776  av_strlcatf(compressor_name, len, " HD");
2777  } else
2778  av_strlcatf(compressor_name, len, " EX");
2779 
2780  av_strlcatf(compressor_name, len, " %d%c", track->par->height, interlaced ? 'i' : 'p');
2781 
2782  av_strlcatf(compressor_name, len, "%d", rate * (interlaced + 1));
2783  }
2784 }
2785 
2787 {
2788  int64_t pos = avio_tell(pb);
2789  // Write sane defaults:
2790  // all_ref_pics_intra = 0 : all samples can use any type of reference.
2791  // intra_pred_used = 1 : intra prediction may or may not be used.
2792  // max_ref_per_pic = 15 : reserved value to indicate that any number of
2793  // reference images can be used.
2794  uint8_t ccstValue = (0 << 7) | /* all_ref_pics_intra */
2795  (1 << 6) | /* intra_pred_used */
2796  (15 << 2); /* max_ref_per_pic */
2797  avio_wb32(pb, 0); /* size */
2798  ffio_wfourcc(pb, "ccst");
2799  avio_wb32(pb, 0); /* Version & flags */
2800  avio_w8(pb, ccstValue);
2801  avio_wb24(pb, 0); /* reserved */
2802  return update_size(pb, pos);
2803 }
2804 
2805 static int mov_write_aux_tag(AVIOContext *pb, const char *aux_type)
2806 {
2807  int64_t pos = avio_tell(pb);
2808  avio_wb32(pb, 0); /* size */
2809  ffio_wfourcc(pb, aux_type);
2810  avio_wb32(pb, 0); /* Version & flags */
2811  avio_write(pb, "urn:mpeg:mpegB:cicp:systems:auxiliary:alpha\0", 44);
2812  return update_size(pb, pos);
2813 }
2814 
2816 {
2817  int ret = AVERROR_BUG;
2818  int64_t pos = avio_tell(pb);
2819  const AVPacketSideData *sd;
2820  char compressor_name[32] = { 0 };
2821  int avid = 0;
2822 
2823  int uncompressed_ycbcr = ((track->par->codec_id == AV_CODEC_ID_RAWVIDEO && track->par->format == AV_PIX_FMT_UYVY422)
2824  || (track->par->codec_id == AV_CODEC_ID_RAWVIDEO && track->par->format == AV_PIX_FMT_YUYV422)
2825  || (track->par->codec_id == AV_CODEC_ID_RAWVIDEO && track->par->format == AV_PIX_FMT_VYU444)
2826  || (track->par->codec_id == AV_CODEC_ID_RAWVIDEO && track->par->format == AV_PIX_FMT_UYVA)
2827  || (track->par->codec_id == AV_CODEC_ID_RAWVIDEO && track->par->format == AV_PIX_FMT_V30XLE)
2828  || track->par->codec_id == AV_CODEC_ID_V210);
2829 
2830  avio_wb32(pb, 0); /* size */
2831  if (mov->encryption_scheme != MOV_ENC_NONE) {
2832  ffio_wfourcc(pb, "encv");
2833  } else {
2834  avio_wl32(pb, track->tag); // store it byteswapped
2835  }
2836  avio_wb32(pb, 0); /* Reserved */
2837  avio_wb16(pb, 0); /* Reserved */
2838  avio_wb16(pb, 1); /* Data-reference index */
2839 
2840  if (uncompressed_ycbcr) {
2841  avio_wb16(pb, 2); /* Codec stream version */
2842  } else {
2843  avio_wb16(pb, 0); /* Codec stream version */
2844  }
2845  avio_wb16(pb, 0); /* Codec stream revision (=0) */
2846  if (track->mode == MODE_MOV) {
2847  ffio_wfourcc(pb, "FFMP"); /* Vendor */
2848  if (track->par->codec_id == AV_CODEC_ID_RAWVIDEO || uncompressed_ycbcr) {
2849  avio_wb32(pb, 0); /* Temporal Quality */
2850  avio_wb32(pb, 0x400); /* Spatial Quality = lossless*/
2851  } else {
2852  avio_wb32(pb, 0x200); /* Temporal Quality = normal */
2853  avio_wb32(pb, 0x200); /* Spatial Quality = normal */
2854  }
2855  } else {
2856  ffio_fill(pb, 0, 3 * 4); /* Reserved */
2857  }
2858  avio_wb16(pb, track->par->width); /* Video width */
2859  avio_wb16(pb, track->height); /* Video height */
2860  avio_wb32(pb, 0x00480000); /* Horizontal resolution 72dpi */
2861  avio_wb32(pb, 0x00480000); /* Vertical resolution 72dpi */
2862  avio_wb32(pb, 0); /* Data size (= 0) */
2863  avio_wb16(pb, 1); /* Frame count (= 1) */
2864 
2865  find_compressor(compressor_name, 32, track);
2866  avio_w8(pb, strlen(compressor_name));
2867  avio_write(pb, compressor_name, 31);
2868 
2869  if (track->mode == MODE_MOV && track->par->codec_id == AV_CODEC_ID_V210)
2870  avio_wb16(pb, 0x18);
2871  else if (track->mode == MODE_MOV && track->par->bits_per_coded_sample)
2872  avio_wb16(pb, track->par->bits_per_coded_sample |
2873  (track->par->format == AV_PIX_FMT_GRAY8 ? 0x20 : 0));
2874  else
2875  avio_wb16(pb, 0x18); /* Reserved */
2876 
2877  if (track->mode == MODE_MOV && track->par->format == AV_PIX_FMT_PAL8) {
2878  int pal_size, i;
2879  avio_wb16(pb, 0); /* Color table ID */
2880  avio_wb32(pb, 0); /* Color table seed */
2881  avio_wb16(pb, 0x8000); /* Color table flags */
2882  if (track->par->bits_per_coded_sample < 0 || track->par->bits_per_coded_sample > 8)
2883  return AVERROR(EINVAL);
2884  pal_size = 1 << track->par->bits_per_coded_sample;
2885  avio_wb16(pb, pal_size - 1); /* Color table size (zero-relative) */
2886  for (i = 0; i < pal_size; i++) {
2887  uint32_t rgb = track->palette[i];
2888  uint16_t r = (rgb >> 16) & 0xff;
2889  uint16_t g = (rgb >> 8) & 0xff;
2890  uint16_t b = rgb & 0xff;
2891  avio_wb16(pb, 0);
2892  avio_wb16(pb, (r << 8) | r);
2893  avio_wb16(pb, (g << 8) | g);
2894  avio_wb16(pb, (b << 8) | b);
2895  }
2896  } else
2897  avio_wb16(pb, 0xffff); /* Reserved */
2898 
2899  if (track->tag == MKTAG('m','p','4','v'))
2900  mov_write_esds_tag(pb, track);
2901  else if (track->par->codec_id == AV_CODEC_ID_H263)
2902  mov_write_d263_tag(pb);
2903  else if (track->par->codec_id == AV_CODEC_ID_AVUI ||
2904  track->par->codec_id == AV_CODEC_ID_SVQ3) {
2905  mov_write_extradata_tag(pb, track);
2906  avio_wb32(pb, 0);
2907  } else if (track->par->codec_id == AV_CODEC_ID_DNXHD) {
2908  mov_write_avid_tag(pb, track);
2909  avid = 1;
2910  } else if (track->par->codec_id == AV_CODEC_ID_HEVC) {
2911  mov_write_hvcc_tag(mov->fc, pb, track);
2912  if (track->st->disposition & AV_DISPOSITION_MULTILAYER) {
2913  ret = mov_write_lhvc_tag(mov->fc, pb, track);
2914  if (ret < 0)
2915  av_log(mov->fc, AV_LOG_WARNING, "Not writing 'lhvC' atom for multilayer stream.\n");
2916  }
2917  } else if (track->par->codec_id == AV_CODEC_ID_VVC)
2918  mov_write_vvcc_tag(pb, track);
2919  else if (track->par->codec_id == AV_CODEC_ID_H264 && !TAG_IS_AVCI(track->tag)) {
2920  mov_write_avcc_tag(pb, track);
2921  if (track->mode == MODE_IPOD)
2923  }
2924  else if (track->par->codec_id ==AV_CODEC_ID_EVC) {
2925  mov_write_evcc_tag(pb, track);
2926  } else if (track->par->codec_id == AV_CODEC_ID_LCEVC) {
2927  mov_write_lvcc_tag(pb, track);
2928  } else if (track->par->codec_id ==AV_CODEC_ID_APV) {
2929  mov_write_apvc_tag(mov->fc, pb, track);
2930  } else if (track->par->codec_id == AV_CODEC_ID_VP9) {
2931  mov_write_vpcc_tag(mov->fc, pb, track);
2932  } else if (track->par->codec_id == AV_CODEC_ID_AV1) {
2933  mov_write_av1c_tag(pb, track);
2934  } else if (track->par->codec_id == AV_CODEC_ID_VC1 && track->extradata_size[track->last_stsd_index] > 0)
2935  mov_write_dvc1_tag(pb, track);
2936  else if (track->par->codec_id == AV_CODEC_ID_VP6F ||
2937  track->par->codec_id == AV_CODEC_ID_VP6A) {
2938  /* Don't write any potential extradata here - the cropping
2939  * is signalled via the normal width/height fields. */
2940  } else if (track->par->codec_id == AV_CODEC_ID_R10K) {
2941  if (track->par->codec_tag == MKTAG('R','1','0','k'))
2942  mov_write_dpxe_tag(pb, track);
2943  } else if (track->par->codec_id == AV_CODEC_ID_AVS3) {
2944  mov_write_av3c_tag(pb, track);
2945  } else if (track->extradata_size[track->last_stsd_index] > 0)
2946  mov_write_glbl_tag(pb, track);
2947 
2948  if (track->par->codec_id != AV_CODEC_ID_H264 &&
2949  track->par->codec_id != AV_CODEC_ID_MPEG4 &&
2950  track->par->codec_id != AV_CODEC_ID_DNXHD) {
2951  int field_order = track->par->field_order;
2952 
2953  if (field_order != AV_FIELD_UNKNOWN)
2954  mov_write_fiel_tag(pb, track, field_order);
2955  }
2956 
2957  if (mov->flags & FF_MOV_FLAG_WRITE_GAMA) {
2958  if (track->mode == MODE_MOV)
2959  mov_write_gama_tag(s, pb, track, mov->gamma);
2960  else
2961  av_log(mov->fc, AV_LOG_WARNING, "Not writing 'gama' atom. Format is not MOV.\n");
2962  }
2963  if (track->mode == MODE_MOV || track->mode == MODE_MP4 || track->mode == MODE_AVIF) {
2964  int has_color_info = track->par->color_primaries != AVCOL_PRI_UNSPECIFIED &&
2965  track->par->color_trc != AVCOL_TRC_UNSPECIFIED &&
2967  if (has_color_info || mov->flags & FF_MOV_FLAG_WRITE_COLR ||
2970  int prefer_icc = mov->flags & FF_MOV_FLAG_PREFER_ICC || !has_color_info;
2971  mov_write_colr_tag(pb, track, prefer_icc);
2972  }
2973  } else if (mov->flags & FF_MOV_FLAG_WRITE_COLR) {
2974  av_log(mov->fc, AV_LOG_WARNING, "Not writing 'colr' atom. Format is not MOV or MP4 or AVIF.\n");
2975  }
2976 
2977  if (track->mode == MODE_MOV || track->mode == MODE_MP4) {
2978  mov_write_clli_tag(pb, track);
2979  mov_write_mdcv_tag(pb, track);
2980  mov_write_amve_tag(pb, track);
2981  }
2982 
2983  if (track->mode == MODE_MP4 && mov->fc->strict_std_compliance <= FF_COMPLIANCE_UNOFFICIAL) {
2985  track->st->codecpar->nb_coded_side_data,
2987  const AVPacketSideData *spherical_mapping = av_packet_side_data_get(track->st->codecpar->coded_side_data,
2988  track->st->codecpar->nb_coded_side_data,
2990  if (stereo_3d)
2991  mov_write_st3d_tag(s, pb, (AVStereo3D*)stereo_3d->data);
2992  if (spherical_mapping)
2993  mov_write_sv3d_tag(mov->fc, pb, (AVSphericalMapping*)spherical_mapping->data);
2994  }
2995 
2996  if (track->mode == MODE_MOV || (track->mode == MODE_MP4 &&
2998  const AVStereo3D *stereo3d = NULL;
2999  const AVSphericalMapping *spherical_mapping = NULL;
3000 
3002  track->st->codecpar->nb_coded_side_data,
3004  if (sd)
3005  stereo3d = (AVStereo3D *)sd->data;
3006 
3008  track->st->codecpar->nb_coded_side_data,
3010  if (sd)
3011  spherical_mapping = (AVSphericalMapping *)sd->data;
3012 
3013  if (stereo3d || spherical_mapping)
3014  mov_write_vexu_tag(s, pb, stereo3d, spherical_mapping);
3015  if (stereo3d)
3016  mov_write_hfov_tag(s, pb, stereo3d);
3017  }
3018 
3019  if (track->mode == MODE_MP4) {
3021  track->st->codecpar->nb_coded_side_data,
3023  if (dovi && mov->fc->strict_std_compliance <= FF_COMPLIANCE_UNOFFICIAL) {
3025  } else if (dovi) {
3026  av_log(mov->fc, AV_LOG_WARNING, "Not writing 'dvcC'/'dvvC' box. Requires -strict unofficial.\n");
3027  }
3028 
3030  track->st->codecpar->nb_coded_side_data,
3032  if (hvce && mov->fc->strict_std_compliance <= FF_COMPLIANCE_UNOFFICIAL) {
3033  mov_write_hvce_tag(pb, hvce);
3034  } else if (hvce) {
3035  av_log(mov->fc, AV_LOG_WARNING, "Not writing 'hvcE' box. Requires -strict unofficial.\n");
3036  }
3037  }
3038 
3039  if (track->par->sample_aspect_ratio.den && track->par->sample_aspect_ratio.num) {
3040  mov_write_pasp_tag(pb, track);
3041  }
3042 
3044  track->st->codecpar->nb_coded_side_data,
3046  if (sd && sd->size >= sizeof(uint32_t) * 4) {
3047  uint64_t top = AV_RL32(sd->data + 0);
3048  uint64_t bottom = AV_RL32(sd->data + 4);
3049  uint64_t left = AV_RL32(sd->data + 8);
3050  uint64_t right = AV_RL32(sd->data + 12);
3051 
3052  if ((left + right) >= track->par->width ||
3053  (top + bottom) >= track->height) {
3054  av_log(s, AV_LOG_ERROR, "Invalid cropping dimensions in stream side data\n");
3055  return AVERROR(EINVAL);
3056  }
3057  if (top || bottom || left || right)
3058  mov_write_clap_tag(pb, track, top, bottom, left, right);
3059  } else if (uncompressed_ycbcr)
3060  mov_write_clap_tag(pb, track, 0, 0, 0, 0);
3061 
3062  if (mov->encryption_scheme != MOV_ENC_NONE) {
3063  ff_mov_cenc_write_sinf_tag(track, pb, mov->encryption_kid);
3064  }
3065 
3066  if (mov->write_btrt &&
3067  ((ret = mov_write_btrt_tag(pb, track)) < 0))
3068  return ret;
3069 
3070  /* extra padding for avid stsd */
3071  /* https://developer.apple.com/library/mac/documentation/QuickTime/QTFF/QTFFChap2/qtff2.html#//apple_ref/doc/uid/TP40000939-CH204-61112 */
3072  if (avid)
3073  avio_wb32(pb, 0);
3074 
3075  if (track->mode == MODE_AVIF) {
3076  mov_write_ccst_tag(pb);
3077  if (mov->nb_streams > 0 && track == &mov->tracks[1])
3078  mov_write_aux_tag(pb, "auxi");
3079  }
3080 
3081  return update_size(pb, pos);
3082 }
3083 
3084 static int mov_write_rtp_tag(AVIOContext *pb, MOVTrack *track)
3085 {
3086  int64_t pos = avio_tell(pb);
3087  avio_wb32(pb, 0); /* size */
3088  ffio_wfourcc(pb, "rtp ");
3089  avio_wb32(pb, 0); /* Reserved */
3090  avio_wb16(pb, 0); /* Reserved */
3091  avio_wb16(pb, 1); /* Data-reference index */
3092 
3093  avio_wb16(pb, 1); /* Hint track version */
3094  avio_wb16(pb, 1); /* Highest compatible version */
3095  avio_wb32(pb, track->max_packet_size); /* Max packet size */
3096 
3097  avio_wb32(pb, 12); /* size */
3098  ffio_wfourcc(pb, "tims");
3099  avio_wb32(pb, track->timescale);
3100 
3101  return update_size(pb, pos);
3102 }
3103 
3104 static int mov_write_source_reference_tag(AVIOContext *pb, MOVTrack *track, const char *reel_name)
3105 {
3106  uint64_t str_size =strlen(reel_name);
3107  int64_t pos = avio_tell(pb);
3108 
3109  if (str_size >= UINT16_MAX){
3110  av_log(NULL, AV_LOG_ERROR, "reel_name length %"PRIu64" is too large\n", str_size);
3111  avio_wb16(pb, 0);
3112  return AVERROR(EINVAL);
3113  }
3114 
3115  avio_wb32(pb, 0); /* size */
3116  ffio_wfourcc(pb, "name"); /* Data format */
3117  avio_wb16(pb, str_size); /* string size */
3118  avio_wb16(pb, track->language); /* langcode */
3119  avio_write(pb, reel_name, str_size); /* reel name */
3120  return update_size(pb,pos);
3121 }
3122 
3123 static int mov_write_tmcd_tag(AVIOContext *pb, MOVTrack *track)
3124 {
3125  int64_t pos = avio_tell(pb);
3126 #if 1
3127  int frame_duration;
3128  int nb_frames;
3129  AVDictionaryEntry *t = NULL;
3130 
3131  if (!track->st->avg_frame_rate.num || !track->st->avg_frame_rate.den) {
3132  av_log(NULL, AV_LOG_ERROR, "avg_frame_rate not set for tmcd track.\n");
3133  return AVERROR(EINVAL);
3134  } else {
3135  frame_duration = av_rescale(track->timescale, track->st->avg_frame_rate.den, track->st->avg_frame_rate.num);
3136  nb_frames = ROUNDED_DIV(track->st->avg_frame_rate.num, track->st->avg_frame_rate.den);
3137  }
3138 
3139  if (nb_frames > 255) {
3140  av_log(NULL, AV_LOG_ERROR, "fps %d is too large\n", nb_frames);
3141  return AVERROR(EINVAL);
3142  }
3143 
3144  avio_wb32(pb, 0); /* size */
3145  ffio_wfourcc(pb, "tmcd"); /* Data format */
3146  avio_wb32(pb, 0); /* Reserved */
3147  avio_wb32(pb, 1); /* Data reference index */
3148  avio_wb32(pb, 0); /* Flags */
3149  avio_wb32(pb, track->timecode_flags); /* Flags (timecode) */
3150  avio_wb32(pb, track->timescale); /* Timescale */
3151  avio_wb32(pb, frame_duration); /* Frame duration */
3152  avio_w8(pb, nb_frames); /* Number of frames */
3153  avio_w8(pb, 0); /* Reserved */
3154 
3155  t = av_dict_get(track->st->metadata, "reel_name", NULL, 0);
3156  if (t && utf8len(t->value) && track->mode != MODE_MP4)
3157  mov_write_source_reference_tag(pb, track, t->value);
3158  else
3159  avio_wb16(pb, 0); /* zero size */
3160 #else
3161 
3162  avio_wb32(pb, 0); /* size */
3163  ffio_wfourcc(pb, "tmcd"); /* Data format */
3164  avio_wb32(pb, 0); /* Reserved */
3165  avio_wb32(pb, 1); /* Data reference index */
3166  if (track->par->extradata_size)
3167  avio_write(pb, track->par->extradata, track->par->extradata_size);
3168 #endif
3169  return update_size(pb, pos);
3170 }
3171 
3172 static int mov_write_gpmd_tag(AVIOContext *pb, const MOVTrack *track)
3173 {
3174  int64_t pos = avio_tell(pb);
3175  avio_wb32(pb, 0); /* size */
3176  ffio_wfourcc(pb, "gpmd");
3177  avio_wb32(pb, 0); /* Reserved */
3178  avio_wb16(pb, 0); /* Reserved */
3179  avio_wb16(pb, 1); /* Data-reference index */
3180  avio_wb32(pb, 0); /* Reserved */
3181  return update_size(pb, pos);
3182 }
3183 
3185 {
3186  int64_t pos = avio_tell(pb);
3187  int ret = 0;
3188  avio_wb32(pb, 0); /* size */
3189  ffio_wfourcc(pb, "stsd");
3190  avio_wb32(pb, 0); /* version & flags */
3191  avio_wb32(pb, track->stsd_count);
3192 
3193  int stsd_index_back = track->last_stsd_index;
3194  for (track->last_stsd_index = 0;
3195  track->last_stsd_index < track->stsd_count;
3196  track->last_stsd_index++) {
3197  if (track->par->codec_type == AVMEDIA_TYPE_VIDEO)
3198  ret = mov_write_video_tag(s, pb, mov, track);
3199  else if (track->par->codec_type == AVMEDIA_TYPE_AUDIO)
3200  ret = mov_write_audio_tag(s, pb, mov, track);
3201  else if (track->par->codec_type == AVMEDIA_TYPE_SUBTITLE)
3202  ret = mov_write_subtitle_tag(s, pb, track);
3203  else if (track->par->codec_tag == MKTAG('r','t','p',' '))
3204  ret = mov_write_rtp_tag(pb, track);
3205  else if (track->par->codec_tag == MKTAG('t','m','c','d'))
3206  ret = mov_write_tmcd_tag(pb, track);
3207  else if (track->par->codec_tag == MKTAG('g','p','m','d'))
3208  ret = mov_write_gpmd_tag(pb, track);
3209 
3210  if (ret < 0)
3211  return ret;
3212  }
3213 
3214  track->last_stsd_index = stsd_index_back;
3215 
3216  return update_size_and_version(pb, pos, track->entry_version);
3217 }
3218 
3220 {
3221  MOVMuxContext *mov = s->priv_data;
3222  MOVCtts *ctts_entries;
3223  uint32_t entries = 0;
3224  uint32_t atom_size;
3225  int i;
3226 
3227  ctts_entries = av_malloc_array((track->entry + 1), sizeof(*ctts_entries)); /* worst case */
3228  if (!ctts_entries)
3229  return AVERROR(ENOMEM);
3230  ctts_entries[0].count = 1;
3231  ctts_entries[0].offset = track->cluster[0].cts;
3232  for (i = 1; i < track->entry; i++) {
3233  if (track->cluster[i].cts == ctts_entries[entries].offset) {
3234  ctts_entries[entries].count++; /* compress */
3235  } else {
3236  entries++;
3237  ctts_entries[entries].offset = track->cluster[i].cts;
3238  ctts_entries[entries].count = 1;
3239  }
3240  }
3241  entries++; /* last one */
3242  atom_size = 16 + (entries * 8);
3243  avio_wb32(pb, atom_size); /* size */
3244  ffio_wfourcc(pb, "ctts");
3246  avio_w8(pb, 1); /* version */
3247  else
3248  avio_w8(pb, 0); /* version */
3249  avio_wb24(pb, 0); /* flags */
3250  avio_wb32(pb, entries); /* entry count */
3251  for (i = 0; i < entries; i++) {
3252  avio_wb32(pb, ctts_entries[i].count);
3253  avio_wb32(pb, ctts_entries[i].offset);
3254  }
3255  av_free(ctts_entries);
3256  return atom_size;
3257 }
3258 
3259 /* Time to sample atom */
3260 static int mov_write_stts_tag(AVIOContext *pb, MOVTrack *track)
3261 {
3262  MOVStts *stts_entries = NULL;
3263  uint32_t entries = -1;
3264  uint32_t atom_size;
3265  int i;
3266 
3267  if (track->par->codec_type == AVMEDIA_TYPE_AUDIO && !track->audio_vbr) {
3268  stts_entries = av_malloc(sizeof(*stts_entries)); /* one entry */
3269  if (!stts_entries)
3270  return AVERROR(ENOMEM);
3271  stts_entries[0].count = track->sample_count;
3272  stts_entries[0].duration = 1;
3273  entries = 1;
3274  } else {
3275  if (track->entry) {
3276  stts_entries = av_malloc_array(track->entry, sizeof(*stts_entries)); /* worst case */
3277  if (!stts_entries)
3278  return AVERROR(ENOMEM);
3279  }
3280  for (i = 0; i < track->entry; i++) {
3281  int duration = get_cluster_duration(track, i);
3282 #if CONFIG_IAMFENC
3283  if (track->iamf && track->par->codec_id == AV_CODEC_ID_OPUS)
3284  duration = av_rescale(duration, 48000, track->par->sample_rate);
3285 #endif
3286  if (i && duration == stts_entries[entries].duration) {
3287  stts_entries[entries].count++; /* compress */
3288  } else {
3289  entries++;
3290  stts_entries[entries].duration = duration;
3291  stts_entries[entries].count = 1;
3292  }
3293  }
3294  entries++; /* last one */
3295  }
3296  atom_size = 16 + (entries * 8);
3297  avio_wb32(pb, atom_size); /* size */
3298  ffio_wfourcc(pb, "stts");
3299  avio_wb32(pb, 0); /* version & flags */
3300  avio_wb32(pb, entries); /* entry count */
3301  for (i = 0; i < entries; i++) {
3302  avio_wb32(pb, stts_entries[i].count);
3303  avio_wb32(pb, stts_entries[i].duration);
3304  }
3305  av_free(stts_entries);
3306  return atom_size;
3307 }
3308 
3310 {
3311  avio_wb32(pb, 28); /* size */
3312  ffio_wfourcc(pb, "dref");
3313  avio_wb32(pb, 0); /* version & flags */
3314  avio_wb32(pb, 1); /* entry count */
3315 
3316  avio_wb32(pb, 0xc); /* size */
3317  //FIXME add the alis and rsrc atom
3318  ffio_wfourcc(pb, "url ");
3319  avio_wb32(pb, 1); /* version & flags */
3320 
3321  return 28;
3322 }
3323 
3325 {
3326  struct sgpd_entry {
3327  int count;
3328  int16_t roll_distance;
3329  int group_description_index;
3330  };
3331 
3332  struct sgpd_entry *sgpd_entries = NULL;
3333  int entries = -1;
3334  int group = 0;
3335  int i, j;
3336 
3337  const int OPUS_SEEK_PREROLL_MS = 80;
3338  int roll_samples = av_rescale_q(OPUS_SEEK_PREROLL_MS,
3339  (AVRational){1, 1000},
3340  (AVRational){1, 48000});
3341 
3342  if (!track->entry)
3343  return 0;
3344 
3345  sgpd_entries = av_malloc_array(track->entry, sizeof(*sgpd_entries));
3346  if (!sgpd_entries)
3347  return AVERROR(ENOMEM);
3348 
3350 
3351  if (track->par->codec_id == AV_CODEC_ID_OPUS) {
3352  for (i = 0; i < track->entry; i++) {
3353  int roll_samples_remaining = roll_samples;
3354  int distance = 0;
3355  for (j = i - 1; j >= 0; j--) {
3356  roll_samples_remaining -= get_cluster_duration(track, j);
3357  distance++;
3358  if (roll_samples_remaining <= 0)
3359  break;
3360  }
3361  /* We don't have enough preceding samples to compute a valid
3362  roll_distance here, so this sample can't be independently
3363  decoded. */
3364  if (roll_samples_remaining > 0)
3365  distance = 0;
3366  /* Verify distance is a maximum of 32 (2.5ms) packets. */
3367  if (distance > 32) {
3368  av_freep(&sgpd_entries);
3369  return AVERROR_INVALIDDATA;
3370  }
3371  if (i && distance == sgpd_entries[entries].roll_distance) {
3372  sgpd_entries[entries].count++;
3373  } else {
3374  entries++;
3375  sgpd_entries[entries].count = 1;
3376  sgpd_entries[entries].roll_distance = distance;
3377  sgpd_entries[entries].group_description_index = distance ? ++group : 0;
3378  }
3379  }
3380  } else {
3381  entries++;
3382  sgpd_entries[entries].count = track->sample_count;
3383  sgpd_entries[entries].roll_distance = 1;
3384  sgpd_entries[entries].group_description_index = ++group;
3385  }
3386  entries++;
3387 
3388  if (!group) {
3389  av_free(sgpd_entries);
3390  return 0;
3391  }
3392 
3393  /* Write sgpd tag */
3394  avio_wb32(pb, 24 + (group * 2)); /* size */
3395  ffio_wfourcc(pb, "sgpd");
3396  avio_wb32(pb, 1 << 24); /* fullbox */
3397  ffio_wfourcc(pb, "roll");
3398  avio_wb32(pb, 2); /* default_length */
3399  avio_wb32(pb, group); /* entry_count */
3400  for (i = 0; i < entries; i++) {
3401  if (sgpd_entries[i].group_description_index) {
3402  avio_wb16(pb, -sgpd_entries[i].roll_distance); /* roll_distance */
3403  }
3404  }
3405 
3406  /* Write sbgp tag */
3407  avio_wb32(pb, 20 + (entries * 8)); /* size */
3408  ffio_wfourcc(pb, "sbgp");
3409  avio_wb32(pb, 0); /* fullbox */
3410  ffio_wfourcc(pb, "roll");
3411  avio_wb32(pb, entries); /* entry_count */
3412  for (i = 0; i < entries; i++) {
3413  avio_wb32(pb, sgpd_entries[i].count); /* sample_count */
3414  avio_wb32(pb, sgpd_entries[i].group_description_index); /* group_description_index */
3415  }
3416 
3417  av_free(sgpd_entries);
3418  return 0;
3419 }
3420 
3422 {
3423  int64_t pos = avio_tell(pb);
3424  int ret = 0;
3425 
3426  avio_wb32(pb, 0); /* size */
3427  ffio_wfourcc(pb, "stbl");
3428  if ((ret = mov_write_stsd_tag(s, pb, mov, track)) < 0)
3429  return ret;
3430  mov_write_stts_tag(pb, track);
3431  if ((track->par->codec_type == AVMEDIA_TYPE_VIDEO ||
3432  track->par->codec_id == AV_CODEC_ID_TRUEHD ||
3434  (track->par->codec_id == AV_CODEC_ID_AAC && track->par->profile == AV_PROFILE_AAC_USAC) ||
3435  track->par->codec_tag == MKTAG('r','t','p',' ')) &&
3436  track->has_keyframes && track->has_keyframes < track->entry)
3437  mov_write_stss_tag(pb, track, MOV_SYNC_SAMPLE);
3438  if (track->par->codec_type == AVMEDIA_TYPE_VIDEO && track->has_disposable && track->entry)
3439  mov_write_sdtp_tag(pb, track);
3440  if (track->mode == MODE_MOV && track->flags & MOV_TRACK_STPS)
3442  if (track->par->codec_type == AVMEDIA_TYPE_VIDEO &&
3443  track->flags & MOV_TRACK_CTTS && track->entry) {
3444 
3445  if ((ret = mov_write_ctts_tag(s, pb, track)) < 0)
3446  return ret;
3447  }
3448  mov_write_stsc_tag(pb, track);
3449  mov_write_stsz_tag(pb, track);
3450  mov_write_stco_tag(pb, track);
3451  if (track->cenc.aes_ctr && !(mov->flags & FF_MOV_FLAG_FRAGMENT)) {
3452  ff_mov_cenc_write_stbl_atoms(&track->cenc, pb, 0);
3453  }
3454  if (track->par->codec_id == AV_CODEC_ID_OPUS || track->par->codec_id == AV_CODEC_ID_AAC) {
3455  mov_preroll_write_stbl_atoms(pb, track);
3456  }
3457  return update_size(pb, pos);
3458 }
3459 
3461 {
3462  int64_t pos = avio_tell(pb);
3463  avio_wb32(pb, 0); /* size */
3464  ffio_wfourcc(pb, "dinf");
3465  mov_write_dref_tag(pb);
3466  return update_size(pb, pos);
3467 }
3468 
3470 {
3471  avio_wb32(pb, 12);
3472  ffio_wfourcc(pb, "nmhd");
3473  avio_wb32(pb, 0);
3474  return 12;
3475 }
3476 
3478 {
3479  avio_wb32(pb, 12);
3480  ffio_wfourcc(pb, "sthd");
3481  avio_wb32(pb, 0);
3482  return 12;
3483 }
3484 
3485 static int mov_write_tcmi_tag(AVIOContext *pb, MOVTrack *track)
3486 {
3487  int64_t pos = avio_tell(pb);
3488  const char *font = "Lucida Grande";
3489  avio_wb32(pb, 0); /* size */
3490  ffio_wfourcc(pb, "tcmi"); /* timecode media information atom */
3491  avio_wb32(pb, 0); /* version & flags */
3492  avio_wb16(pb, 0); /* text font */
3493  avio_wb16(pb, 0); /* text face */
3494  avio_wb16(pb, 12); /* text size */
3495  avio_wb16(pb, 0); /* (unknown, not in the QT specs...) */
3496  avio_wb16(pb, 0x0000); /* text color (red) */
3497  avio_wb16(pb, 0x0000); /* text color (green) */
3498  avio_wb16(pb, 0x0000); /* text color (blue) */
3499  avio_wb16(pb, 0xffff); /* background color (red) */
3500  avio_wb16(pb, 0xffff); /* background color (green) */
3501  avio_wb16(pb, 0xffff); /* background color (blue) */
3502  avio_w8(pb, strlen(font)); /* font len (part of the pascal string) */
3503  avio_write(pb, font, strlen(font)); /* font name */
3504  return update_size(pb, pos);
3505 }
3506 
3507 static int mov_write_gmhd_tag(AVIOContext *pb, MOVTrack *track)
3508 {
3509  int64_t pos = avio_tell(pb);
3510  avio_wb32(pb, 0); /* size */
3511  ffio_wfourcc(pb, "gmhd");
3512  avio_wb32(pb, 0x18); /* gmin size */
3513  ffio_wfourcc(pb, "gmin");/* generic media info */
3514  avio_wb32(pb, 0); /* version & flags */
3515  avio_wb16(pb, 0x40); /* graphics mode = */
3516  avio_wb16(pb, 0x8000); /* opColor (r?) */
3517  avio_wb16(pb, 0x8000); /* opColor (g?) */
3518  avio_wb16(pb, 0x8000); /* opColor (b?) */
3519  avio_wb16(pb, 0); /* balance */
3520  avio_wb16(pb, 0); /* reserved */
3521 
3522  /*
3523  * This special text atom is required for
3524  * Apple Quicktime chapters. The contents
3525  * don't appear to be documented, so the
3526  * bytes are copied verbatim.
3527  */
3528  if (track->tag != MKTAG('c','6','0','8')) {
3529  avio_wb32(pb, 0x2C); /* size */
3530  ffio_wfourcc(pb, "text");
3531  avio_wb16(pb, 0x01);
3532  avio_wb32(pb, 0x00);
3533  avio_wb32(pb, 0x00);
3534  avio_wb32(pb, 0x00);
3535  avio_wb32(pb, 0x01);
3536  avio_wb32(pb, 0x00);
3537  avio_wb32(pb, 0x00);
3538  avio_wb32(pb, 0x00);
3539  avio_wb32(pb, 0x00004000);
3540  avio_wb16(pb, 0x0000);
3541  }
3542 
3543  if (track->par->codec_tag == MKTAG('t','m','c','d')) {
3544  int64_t tmcd_pos = avio_tell(pb);
3545  avio_wb32(pb, 0); /* size */
3546  ffio_wfourcc(pb, "tmcd");
3547  mov_write_tcmi_tag(pb, track);
3548  update_size(pb, tmcd_pos);
3549  } else if (track->par->codec_tag == MKTAG('g','p','m','d')) {
3550  int64_t gpmd_pos = avio_tell(pb);
3551  avio_wb32(pb, 0); /* size */
3552  ffio_wfourcc(pb, "gpmd");
3553  avio_wb32(pb, 0); /* version */
3554  update_size(pb, gpmd_pos);
3555  }
3556  return update_size(pb, pos);
3557 }
3558 
3560 {
3561  avio_wb32(pb, 16); /* size */
3562  ffio_wfourcc(pb, "smhd");
3563  avio_wb32(pb, 0); /* version & flags */
3564  avio_wb16(pb, 0); /* reserved (balance, normally = 0) */
3565  avio_wb16(pb, 0); /* reserved */
3566  return 16;
3567 }
3568 
3570 {
3571  avio_wb32(pb, 0x14); /* size (always 0x14) */
3572  ffio_wfourcc(pb, "vmhd");
3573  avio_wb32(pb, 0x01); /* version & flags */
3574  avio_wb64(pb, 0); /* reserved (graphics mode = copy) */
3575  return 0x14;
3576 }
3577 
3578 static int is_clcp_track(MOVTrack *track)
3579 {
3580  return track->tag == MKTAG('c','7','0','8') ||
3581  track->tag == MKTAG('c','6','0','8');
3582 }
3583 
3585 {
3586  MOVMuxContext *mov = s->priv_data;
3587  const char *hdlr, *descr = NULL, *hdlr_type = NULL;
3588  int64_t pos = avio_tell(pb);
3589  size_t descr_len;
3590 
3591  hdlr = "dhlr";
3592  hdlr_type = "url ";
3593  descr = "DataHandler";
3594 
3595  if (track) {
3596  hdlr = (track->mode == MODE_MOV) ? "mhlr" : "\0\0\0\0";
3597  if (track->par->codec_type == AVMEDIA_TYPE_VIDEO) {
3598  if (track->mode == MODE_AVIF) {
3599  hdlr_type = (track == &mov->tracks[0]) ? "pict" : "auxv";
3600  descr = "PictureHandler";
3601  } else {
3602  hdlr_type = "vide";
3603  descr = "VideoHandler";
3604  }
3605  } else if (track->par->codec_type == AVMEDIA_TYPE_AUDIO) {
3606  hdlr_type = "soun";
3607  descr = "SoundHandler";
3608  } else if (track->par->codec_type == AVMEDIA_TYPE_SUBTITLE) {
3609  if (is_clcp_track(track)) {
3610  hdlr_type = "clcp";
3611  descr = "ClosedCaptionHandler";
3612  } else {
3613  if (track->tag == MKTAG('t','x','3','g')) {
3614  hdlr_type = "sbtl";
3615  } else if (track->tag == MKTAG('m','p','4','s')) {
3616  hdlr_type = "subp";
3617  } else if (track->tag == MOV_MP4_TTML_TAG) {
3618  hdlr_type = "subt";
3619  } else {
3620  hdlr_type = "text";
3621  }
3622  descr = "SubtitleHandler";
3623  }
3624  } else if (track->par->codec_tag == MKTAG('r','t','p',' ')) {
3625  hdlr_type = "hint";
3626  descr = "HintHandler";
3627  } else if (track->par->codec_tag == MKTAG('t','m','c','d')) {
3628  hdlr_type = "tmcd";
3629  descr = "TimeCodeHandler";
3630  } else if (track->par->codec_tag == MKTAG('g','p','m','d')) {
3631  hdlr_type = "meta";
3632  descr = "GoPro MET"; // GoPro Metadata
3633  } else {
3635  "Unknown hdlr_type for %s, writing dummy values\n",
3636  av_fourcc2str(track->par->codec_tag));
3637  }
3638  if (track->st) {
3639  // hdlr.name is used by some players to identify the content title
3640  // of the track. So if an alternate handler description is
3641  // specified, use it.
3642  AVDictionaryEntry *t;
3643  t = av_dict_get(track->st->metadata, "handler_name", NULL, 0);
3644  if (t && utf8len(t->value))
3645  descr = t->value;
3646  }
3647  }
3648 
3649  if (mov->empty_hdlr_name) /* expressly allowed by QTFF and not prohibited in ISO 14496-12 8.4.3.3 */
3650  descr = "";
3651 
3652  avio_wb32(pb, 0); /* size */
3653  ffio_wfourcc(pb, "hdlr");
3654  avio_wb32(pb, 0); /* Version & flags */
3655  avio_write(pb, hdlr, 4); /* handler */
3656  ffio_wfourcc(pb, hdlr_type); /* handler type */
3657  avio_wb32(pb, 0); /* reserved */
3658  avio_wb32(pb, 0); /* reserved */
3659  avio_wb32(pb, 0); /* reserved */
3660  descr_len = strlen(descr);
3661  if (!track || track->mode == MODE_MOV)
3662  avio_w8(pb, descr_len); /* pascal string */
3663  avio_write(pb, descr, descr_len); /* handler description */
3664  if (track && track->mode != MODE_MOV)
3665  avio_w8(pb, 0); /* c string */
3666  return update_size(pb, pos);
3667 }
3668 
3669 static int mov_write_pitm_tag(AVIOContext *pb, int item_id)
3670 {
3671  int64_t pos = avio_tell(pb);
3672  avio_wb32(pb, 0); /* size */
3673  ffio_wfourcc(pb, "pitm");
3674  avio_wb32(pb, 0); /* Version & flags */
3675  avio_wb16(pb, item_id); /* item_id */
3676  return update_size(pb, pos);
3677 }
3678 
3680 {
3681  int64_t pos = avio_tell(pb);
3682  avio_wb32(pb, 0); /* size */
3683  ffio_wfourcc(pb, "iloc");
3684  avio_wb32(pb, 0); /* Version & flags */
3685  avio_w8(pb, (4 << 4) + 4); /* offset_size(4) and length_size(4) */
3686  avio_w8(pb, 0); /* base_offset_size(4) and reserved(4) */
3687  avio_wb16(pb, mov->nb_streams); /* item_count */
3688 
3689  for (int i = 0; i < mov->nb_streams; i++) {
3690  avio_wb16(pb, i + 1); /* item_id */
3691  avio_wb16(pb, 0); /* data_reference_index */
3692  avio_wb16(pb, 1); /* extent_count */
3693  mov->avif_extent_pos[i] = avio_tell(pb);
3694  avio_wb32(pb, 0); /* extent_offset (written later) */
3695  // For animated AVIF, we simply write the first packet's size.
3696  avio_wb32(pb, mov->avif_extent_length[i]); /* extent_length */
3697  }
3698 
3699  return update_size(pb, pos);
3700 }
3701 
3703 {
3704  int64_t iinf_pos = avio_tell(pb);
3705  avio_wb32(pb, 0); /* size */
3706  ffio_wfourcc(pb, "iinf");
3707  avio_wb32(pb, 0); /* Version & flags */
3708  avio_wb16(pb, mov->nb_streams); /* entry_count */
3709 
3710  for (int i = 0; i < mov->nb_streams; i++) {
3711  int64_t infe_pos = avio_tell(pb);
3712  avio_wb32(pb, 0); /* size */
3713  ffio_wfourcc(pb, "infe");
3714  avio_w8(pb, 0x2); /* Version */
3715  avio_wb24(pb, 0); /* flags */
3716  avio_wb16(pb, i + 1); /* item_id */
3717  avio_wb16(pb, 0); /* item_protection_index */
3718  avio_write(pb, "av01", 4); /* item_type */
3719  avio_write(pb, !i ? "Color\0" : "Alpha\0", 6); /* item_name */
3720  update_size(pb, infe_pos);
3721  }
3722 
3723  return update_size(pb, iinf_pos);
3724 }
3725 
3726 
3728 {
3729  int64_t auxl_pos;
3730  int64_t iref_pos = avio_tell(pb);
3731  avio_wb32(pb, 0); /* size */
3732  ffio_wfourcc(pb, "iref");
3733  avio_wb32(pb, 0); /* Version & flags */
3734 
3735  auxl_pos = avio_tell(pb);
3736  avio_wb32(pb, 0); /* size */
3737  ffio_wfourcc(pb, "auxl");
3738  avio_wb16(pb, 2); /* from_item_ID */
3739  avio_wb16(pb, 1); /* reference_count */
3740  avio_wb16(pb, 1); /* to_item_ID */
3741  update_size(pb, auxl_pos);
3742 
3743  return update_size(pb, iref_pos);
3744 }
3745 
3747  int stream_index)
3748 {
3749  int64_t pos = avio_tell(pb);
3750  avio_wb32(pb, 0); /* size */
3751  ffio_wfourcc(pb, "ispe");
3752  avio_wb32(pb, 0); /* Version & flags */
3753  avio_wb32(pb, s->streams[stream_index]->codecpar->width); /* image_width */
3754  avio_wb32(pb, s->streams[stream_index]->codecpar->height); /* image_height */
3755  return update_size(pb, pos);
3756 }
3757 
3759  int stream_index)
3760 {
3761  int64_t pos = avio_tell(pb);
3762  const AVPixFmtDescriptor *pixdesc =
3763  av_pix_fmt_desc_get(s->streams[stream_index]->codecpar->format);
3764  avio_wb32(pb, 0); /* size */
3765  ffio_wfourcc(pb, "pixi");
3766  avio_wb32(pb, 0); /* Version & flags */
3767  avio_w8(pb, pixdesc->nb_components); /* num_channels */
3768  for (int i = 0; i < pixdesc->nb_components; ++i) {
3769  avio_w8(pb, pixdesc->comp[i].depth); /* bits_per_channel */
3770  }
3771  return update_size(pb, pos);
3772 }
3773 
3775 {
3776  int64_t pos = avio_tell(pb);
3777  avio_wb32(pb, 0); /* size */
3778  ffio_wfourcc(pb, "ipco");
3779  for (int i = 0; i < mov->nb_streams; i++) {
3780  mov_write_ispe_tag(pb, mov, s, i);
3781  mov_write_pixi_tag(pb, mov, s, i);
3782  mov_write_av1c_tag(pb, &mov->tracks[i]);
3783  if (!i)
3784  mov_write_colr_tag(pb, &mov->tracks[0], 0);
3785  else
3786  mov_write_aux_tag(pb, "auxC");
3787  }
3788  return update_size(pb, pos);
3789 }
3790 
3792 {
3793  int64_t pos = avio_tell(pb);
3794  avio_wb32(pb, 0); /* size */
3795  ffio_wfourcc(pb, "ipma");
3796  avio_wb32(pb, 0); /* Version & flags */
3797  avio_wb32(pb, mov->nb_streams); /* entry_count */
3798 
3799  for (int i = 0, index = 1; i < mov->nb_streams; i++) {
3800  avio_wb16(pb, i + 1); /* item_ID */
3801  avio_w8(pb, 4); /* association_count */
3802 
3803  // ispe association.
3804  avio_w8(pb, index++); /* essential and property_index */
3805  // pixi association.
3806  avio_w8(pb, index++); /* essential and property_index */
3807  // av1C association.
3808  avio_w8(pb, 0x80 | index++); /* essential and property_index */
3809  // colr/auxC association.
3810  avio_w8(pb, index++); /* essential and property_index */
3811  }
3812  return update_size(pb, pos);
3813 }
3814 
3816 {
3817  int64_t pos = avio_tell(pb);
3818  avio_wb32(pb, 0); /* size */
3819  ffio_wfourcc(pb, "iprp");
3820  mov_write_ipco_tag(pb, mov, s);
3821  mov_write_ipma_tag(pb, mov, s);
3822  return update_size(pb, pos);
3823 }
3824 
3826 {
3827  /* This atom must be present, but leaving the values at zero
3828  * seems harmless. */
3829  avio_wb32(pb, 28); /* size */
3830  ffio_wfourcc(pb, "hmhd");
3831  avio_wb32(pb, 0); /* version, flags */
3832  avio_wb16(pb, 0); /* maxPDUsize */
3833  avio_wb16(pb, 0); /* avgPDUsize */
3834  avio_wb32(pb, 0); /* maxbitrate */
3835  avio_wb32(pb, 0); /* avgbitrate */
3836  avio_wb32(pb, 0); /* reserved */
3837  return 28;
3838 }
3839 
3841 {
3842  int64_t pos = avio_tell(pb);
3843  int ret;
3844 
3845  avio_wb32(pb, 0); /* size */
3846  ffio_wfourcc(pb, "minf");
3847  if (track->par->codec_type == AVMEDIA_TYPE_VIDEO)
3848  mov_write_vmhd_tag(pb);
3849  else if (track->par->codec_type == AVMEDIA_TYPE_AUDIO)
3850  mov_write_smhd_tag(pb);
3851  else if (track->par->codec_type == AVMEDIA_TYPE_SUBTITLE) {
3852  if (track->tag == MKTAG('t','e','x','t') || is_clcp_track(track)) {
3853  mov_write_gmhd_tag(pb, track);
3854  } else if (track->tag == MOV_MP4_TTML_TAG) {
3855  mov_write_sthd_tag(pb);
3856  } else {
3857  mov_write_nmhd_tag(pb);
3858  }
3859  } else if (track->tag == MKTAG('r','t','p',' ')) {
3860  mov_write_hmhd_tag(pb);
3861  } else if (track->tag == MKTAG('t','m','c','d')) {
3862  if (track->mode != MODE_MOV)
3863  mov_write_nmhd_tag(pb);
3864  else
3865  mov_write_gmhd_tag(pb, track);
3866  } else if (track->tag == MKTAG('g','p','m','d')) {
3867  mov_write_gmhd_tag(pb, track);
3868  }
3869  if (track->mode == MODE_MOV) /* ISO 14496-12 8.4.3.1 specifies hdlr only within mdia or meta boxes */
3870  mov_write_hdlr_tag(s, pb, NULL);
3871  mov_write_dinf_tag(pb);
3872  if ((ret = mov_write_stbl_tag(s, pb, mov, track)) < 0)
3873  return ret;
3874  return update_size(pb, pos);
3875 }
3876 
3877 static void get_pts_range(MOVMuxContext *mov, MOVTrack *track,
3878  int64_t *start, int64_t *end, int elst, int mdhd)
3879 {
3880  if (track->tag == MKTAG('t','m','c','d') && mov->nb_meta_tmcd && track->nb_src_track) {
3881  // tmcd tracks gets track_duration set in mov_write_moov_tag from
3882  // another track's duration, while the end_pts may be left at zero.
3883  // Calculate the pts duration for that track instead.
3884  get_pts_range(mov, &mov->tracks[*track->src_track], start, end, elst, mdhd);
3885  *start = av_rescale(*start, track->timescale,
3886  mov->tracks[*track->src_track].timescale);
3887  *end = av_rescale(*end, track->timescale,
3888  mov->tracks[*track->src_track].timescale);
3889  return;
3890  }
3891  if (!mdhd && track->end_pts != AV_NOPTS_VALUE &&
3892  track->start_dts != AV_NOPTS_VALUE &&
3893  track->start_cts != AV_NOPTS_VALUE) {
3894  *start = track->start_dts + track->start_cts;
3895  *end = elst ? track->elst_end_pts : track->end_pts;
3896  return;
3897  }
3898  *start = 0;
3899  *end = track->track_duration;
3900 }
3901 
3903 {
3904  int64_t start, end;
3905  get_pts_range(mov, track, &start, &end, 0, 1);
3906  return end - start;
3907 }
3908 
3909 // Calculate the actual duration of the track, after edits.
3910 // If it starts with a pts < 0, that is removed by the edit list.
3911 // If it starts with a pts > 0, the edit list adds a delay before that.
3912 // Thus, with edit lists enabled, the post-edit output of the file is
3913 // starting with pts=0.
3915 {
3916  int64_t start, end;
3917  get_pts_range(mov, track, &start, &end, 0, 0);
3918  if (mov->use_editlist != 0)
3919  start = 0;
3920  return end - start;
3921 }
3922 
3924 {
3925  int64_t start, end;
3926  get_pts_range(mov, track, &start, &end, 1, 0);
3927  return end - start;
3928 }
3929 
3931 {
3932  if (track && track->mode == MODE_ISM)
3933  return 1;
3934  if (duration < INT32_MAX)
3935  return 0;
3936  return 1;
3937 }
3938 
3940  MOVTrack *track)
3941 {
3943  int version = mov_mdhd_mvhd_tkhd_version(mov, track, duration);
3944 
3945  (version == 1) ? avio_wb32(pb, 44) : avio_wb32(pb, 32); /* size */
3946  ffio_wfourcc(pb, "mdhd");
3947  avio_w8(pb, version);
3948  avio_wb24(pb, 0); /* flags */
3949  if (version == 1) {
3950  avio_wb64(pb, track->time);
3951  avio_wb64(pb, track->time);
3952  } else {
3953  avio_wb32(pb, track->time); /* creation time */
3954  avio_wb32(pb, track->time); /* modification time */
3955  }
3956  avio_wb32(pb, track->timescale); /* time scale (sample rate for audio) */
3957  if (!track->entry && mov->mode == MODE_ISM)
3958  (version == 1) ? avio_wb64(pb, UINT64_C(0xffffffffffffffff)) : avio_wb32(pb, 0xffffffff);
3959  else if (!track->entry)
3960  (version == 1) ? avio_wb64(pb, 0) : avio_wb32(pb, 0);
3961  else
3962  (version == 1) ? avio_wb64(pb, duration) : avio_wb32(pb, duration); /* duration */
3963  avio_wb16(pb, track->language); /* language */
3964  avio_wb16(pb, 0); /* reserved (quality) */
3965 
3966  if (version != 0 && track->mode == MODE_MOV) {
3968  "FATAL error, file duration too long for timebase, this file will not be\n"
3969  "playable with QuickTime. Choose a different timebase with "
3970  "-video_track_timescale or a different container format\n");
3971  }
3972 
3973  return 32;
3974 }
3975 
3977  MOVMuxContext *mov, MOVTrack *track)
3978 {
3979  int64_t pos = avio_tell(pb);
3980  int ret;
3981 
3982  avio_wb32(pb, 0); /* size */
3983  ffio_wfourcc(pb, "mdia");
3984  mov_write_mdhd_tag(pb, mov, track);
3985  mov_write_hdlr_tag(s, pb, track);
3986  if ((ret = mov_write_minf_tag(s, pb, mov, track)) < 0)
3987  return ret;
3988  return update_size(pb, pos);
3989 }
3990 
3991 /* transformation matrix
3992  |a b u|
3993  |c d v|
3994  |tx ty w| */
3995 static void write_matrix(AVIOContext *pb, int16_t a, int16_t b, int16_t c,
3996  int16_t d, int16_t tx, int16_t ty)
3997 {
3998  avio_wb32(pb, a << 16); /* 16.16 format */
3999  avio_wb32(pb, b << 16); /* 16.16 format */
4000  avio_wb32(pb, 0); /* u in 2.30 format */
4001  avio_wb32(pb, c << 16); /* 16.16 format */
4002  avio_wb32(pb, d << 16); /* 16.16 format */
4003  avio_wb32(pb, 0); /* v in 2.30 format */
4004  avio_wb32(pb, tx << 16); /* 16.16 format */
4005  avio_wb32(pb, ty << 16); /* 16.16 format */
4006  avio_wb32(pb, 1 << 30); /* w in 2.30 format */
4007 }
4008 
4010  MOVTrack *track, AVStream *st)
4011 {
4013  mov->movie_timescale, track->timescale,
4014  AV_ROUND_UP);
4015  int version;
4017  int group = 0;
4018 
4019  uint32_t *display_matrix = NULL;
4020  int i;
4021 
4022  if (mov->mode == MODE_AVIF)
4023  if (!mov->avif_loop_count)
4024  duration = INT64_MAX;
4025  else
4026  duration *= mov->avif_loop_count;
4027 
4028  if (st) {
4029  const AVPacketSideData *sd;
4030  if (mov->per_stream_grouping)
4031  group = st->index;
4032  else
4033  group = st->codecpar->codec_type;
4034 
4038  if (sd && sd->size == 9 * sizeof(*display_matrix))
4039  display_matrix = (uint32_t *)sd->data;
4040  }
4041 
4042  if (track->flags & MOV_TRACK_ENABLED)
4044 
4046 
4047  (version == 1) ? avio_wb32(pb, 104) : avio_wb32(pb, 92); /* size */
4048  ffio_wfourcc(pb, "tkhd");
4049  avio_w8(pb, version);
4050  avio_wb24(pb, flags);
4051  if (version == 1) {
4052  avio_wb64(pb, track->time);
4053  avio_wb64(pb, track->time);
4054  } else {
4055  avio_wb32(pb, track->time); /* creation time */
4056  avio_wb32(pb, track->time); /* modification time */
4057  }
4058  avio_wb32(pb, track->track_id); /* track-id */
4059  avio_wb32(pb, 0); /* reserved */
4060  if (!track->entry && mov->mode == MODE_ISM)
4061  (version == 1) ? avio_wb64(pb, UINT64_C(0xffffffffffffffff)) : avio_wb32(pb, 0xffffffff);
4062  else if (!track->entry)
4063  (version == 1) ? avio_wb64(pb, 0) : avio_wb32(pb, 0);
4064  else
4065  (version == 1) ? avio_wb64(pb, duration) : avio_wb32(pb, duration);
4066 
4067  avio_wb32(pb, 0); /* reserved */
4068  avio_wb32(pb, 0); /* reserved */
4069  avio_wb16(pb, 0); /* layer */
4070  avio_wb16(pb, group); /* alternate group) */
4071  /* Volume, only for audio */
4072  if (track->par->codec_type == AVMEDIA_TYPE_AUDIO)
4073  avio_wb16(pb, 0x0100);
4074  else
4075  avio_wb16(pb, 0);
4076  avio_wb16(pb, 0); /* reserved */
4077 
4078  /* Matrix structure */
4079  if (display_matrix) {
4080  for (i = 0; i < 9; i++)
4081  avio_wb32(pb, display_matrix[i]);
4082  } else {
4083  write_matrix(pb, 1, 0, 0, 1, 0, 0);
4084  }
4085  /* Track width and height, for visual only */
4086  if (st && (track->par->codec_type == AVMEDIA_TYPE_VIDEO ||
4087  track->par->codec_type == AVMEDIA_TYPE_SUBTITLE)) {
4088  int64_t track_width_1616;
4089  if (track->mode == MODE_MOV || track->mode == MODE_AVIF) {
4090  track_width_1616 = track->par->width * 0x10000ULL;
4091  } else {
4092  track_width_1616 = av_rescale(st->sample_aspect_ratio.num,
4093  track->par->width * 0x10000LL,
4094  st->sample_aspect_ratio.den);
4095  if (!track_width_1616 ||
4096  track->height != track->par->height ||
4097  track_width_1616 > UINT32_MAX)
4098  track_width_1616 = track->par->width * 0x10000ULL;
4099  }
4100  if (track_width_1616 > UINT32_MAX) {
4101  av_log(mov->fc, AV_LOG_WARNING, "track width is too large\n");
4102  track_width_1616 = 0;
4103  }
4104  avio_wb32(pb, track_width_1616);
4105  if (track->height > 0xFFFF) {
4106  av_log(mov->fc, AV_LOG_WARNING, "track height is too large\n");
4107  avio_wb32(pb, 0);
4108  } else
4109  avio_wb32(pb, track->height * 0x10000U);
4110  } else {
4111  avio_wb32(pb, 0);
4112  avio_wb32(pb, 0);
4113  }
4114  return 0x5c;
4115 }
4116 
4117 static int mov_write_tapt_tag(AVIOContext *pb, MOVTrack *track)
4118 {
4120  track->par->sample_aspect_ratio.den);
4121 
4122  int64_t pos = avio_tell(pb);
4123 
4124  avio_wb32(pb, 0); /* size */
4125  ffio_wfourcc(pb, "tapt");
4126 
4127  avio_wb32(pb, 20);
4128  ffio_wfourcc(pb, "clef");
4129  avio_wb32(pb, 0);
4130  avio_wb32(pb, width << 16);
4131  avio_wb32(pb, track->par->height << 16);
4132 
4133  avio_wb32(pb, 20);
4134  ffio_wfourcc(pb, "prof");
4135  avio_wb32(pb, 0);
4136  avio_wb32(pb, width << 16);
4137  avio_wb32(pb, track->par->height << 16);
4138 
4139  avio_wb32(pb, 20);
4140  ffio_wfourcc(pb, "enof");
4141  avio_wb32(pb, 0);
4142  avio_wb32(pb, track->par->width << 16);
4143  avio_wb32(pb, track->par->height << 16);
4144 
4145  return update_size(pb, pos);
4146 }
4147 
4148 // This box is written in the following cases:
4149 // * Seems important for the psp playback. Without it the movie seems to hang.
4150 // * Used for specifying the looping behavior of animated AVIF (as specified
4151 // in Section 9.6 of the HEIF specification ISO/IEC 23008-12).
4153  MOVTrack *track)
4154 {
4156  mov->movie_timescale, track->timescale,
4157  AV_ROUND_UP);
4158  int version = duration < INT32_MAX ? 0 : 1;
4159  int entry_size, entry_count, size;
4160  int64_t delay, start_ct = track->start_cts;
4161  int64_t start_dts = track->start_dts;
4162  int flags = 0;
4163 
4164  if (track->entry) {
4165  if (start_dts != track->cluster[0].dts || (start_ct != track->cluster[0].cts && track->cluster[0].dts >= 0)) {
4166 
4167  av_log(mov->fc, AV_LOG_DEBUG,
4168  "EDTS using dts:%"PRId64" cts:%d instead of dts:%"PRId64" cts:%"PRId64" tid:%d\n",
4169  track->cluster[0].dts, track->cluster[0].cts,
4170  start_dts, start_ct, track->track_id);
4171  start_dts = track->cluster[0].dts;
4172  start_ct = track->cluster[0].cts;
4173  }
4174  }
4175 
4176  delay = av_rescale_rnd(start_dts + start_ct, mov->movie_timescale,
4177  track->timescale, AV_ROUND_DOWN);
4178 
4179  if (mov->mode == MODE_AVIF) {
4180  delay = 0;
4181  // Section 9.6.3 of ISO/IEC 23008-12: flags specifies repetition of the
4182  // edit list as follows: (flags & 1) equal to 0 specifies that the edit
4183  // list is not repeated, while (flags & 1) equal to 1 specifies that the
4184  // edit list is repeated.
4185  flags = mov->avif_loop_count != 1;
4186  start_ct = 0;
4187  }
4188 
4189  version |= delay < INT32_MAX ? 0 : 1;
4190 
4191  entry_size = (version == 1) ? 20 : 12;
4192  entry_count = 1 + (delay > 0);
4193  size = 24 + entry_count * entry_size;
4194 
4195  /* write the atom data */
4196  avio_wb32(pb, size);
4197  ffio_wfourcc(pb, "edts");
4198  avio_wb32(pb, size - 8);
4199  ffio_wfourcc(pb, "elst");
4200  avio_w8(pb, version);
4201  avio_wb24(pb, flags); /* flags */
4202 
4203  avio_wb32(pb, entry_count);
4204  if (delay > 0) { /* add an empty edit to delay presentation */
4205  /* In the positive delay case, the delay includes the cts
4206  * offset, and the second edit list entry below trims out
4207  * the same amount from the actual content. This makes sure
4208  * that the offset last sample is included in the edit
4209  * list duration as well. */
4210  if (version == 1) {
4211  avio_wb64(pb, delay);
4212  avio_wb64(pb, -1);
4213  } else {
4214  avio_wb32(pb, delay);
4215  avio_wb32(pb, -1);
4216  }
4217  avio_wb32(pb, 0x00010000);
4218  } else if (mov->mode != MODE_AVIF) {
4219  /* Avoid accidentally ending up with start_ct = -1 which has got a
4220  * special meaning. Normally start_ct should end up positive or zero
4221  * here, but use FFMIN in case dts is a small positive integer
4222  * rounded to 0 when represented in movie timescale units. */
4223  av_assert0(av_rescale_rnd(start_dts, mov->movie_timescale, track->timescale, AV_ROUND_DOWN) <= 0);
4224  start_ct = -FFMIN(start_dts, 0);
4225 
4226 #if CONFIG_IAMFENC
4227  if (track->iamf && track->par->codec_id == AV_CODEC_ID_OPUS)
4228  start_ct = av_rescale(start_ct, 48000, track->par->sample_rate);
4229 #endif
4230  /* Note, this delay is calculated from the pts of the first sample,
4231  * ensuring that we don't reduce the duration for cases with
4232  * dts<0 pts=0. */
4233  duration += delay;
4234  }
4235 
4236  /* For fragmented files, we don't know the full length yet. Setting
4237  * duration to 0 allows us to only specify the offset, including
4238  * the rest of the content (from all future fragments) without specifying
4239  * an explicit duration.
4240  *
4241  * For hybrid_fragmented during mov_write_trailer (mov->moov_written != 0),
4242  * don't reset duration to zero.
4243  */
4244  if (mov->flags & FF_MOV_FLAG_FRAGMENT &&
4246  duration = 0;
4247 
4248  /* duration */
4249  if (version == 1) {
4250  avio_wb64(pb, duration);
4251  avio_wb64(pb, start_ct);
4252  } else {
4253  avio_wb32(pb, duration);
4254  avio_wb32(pb, start_ct);
4255  }
4256  avio_wb32(pb, 0x00010000);
4257  return size;
4258 }
4259 
4260 static int mov_write_tref_tag(AVIOContext *pb, MOVTrack *track)
4261 {
4262  int64_t pos = avio_tell(pb);
4263  avio_wb32(pb, 0); // size placeholder
4264  ffio_wfourcc(pb, "tref");
4265 
4266  for (int i = 0; i < track->nb_tref_tags; i++) {
4267  MovTag *tag = &track->tref_tags[i];
4268  avio_wb32(pb, 8 + tag->nb_id * sizeof(*tag->id)); // size (subatom)
4269  avio_wl32(pb, tag->name);
4270  for (int j = 0; j < tag->nb_id; j++)
4271  avio_wb32(pb, tag->id[j]);
4272  }
4273  return update_size(pb, pos);
4274 }
4275 
4276 // goes at the end of each track! ... Critical for PSP playback ("Incompatible data" without it)
4278 {
4279  avio_wb32(pb, 0x34); /* size ... reports as 28 in mp4box! */
4280  ffio_wfourcc(pb, "uuid");
4281  ffio_wfourcc(pb, "USMT");
4282  avio_wb32(pb, 0x21d24fce);
4283  avio_wb32(pb, 0xbb88695c);
4284  avio_wb32(pb, 0xfac9c740);
4285  avio_wb32(pb, 0x1c); // another size here!
4286  ffio_wfourcc(pb, "MTDT");
4287  avio_wb32(pb, 0x00010012);
4288  avio_wb32(pb, 0x0a);
4289  avio_wb32(pb, 0x55c40000);
4290  avio_wb32(pb, 0x1);
4291  avio_wb32(pb, 0x0);
4292  return 0x34;
4293 }
4294 
4295 static int mov_write_udta_sdp(AVIOContext *pb, MOVTrack *track)
4296 {
4297  AVFormatContext *ctx = track->rtp_ctx;
4298  char buf[1000] = "";
4299  int len;
4300 
4301  av_assert0(track->nb_src_track);
4302  ff_sdp_write_media(buf, sizeof(buf), ctx->streams[0], *track->src_track,
4303  NULL, NULL, 0, 0, ctx);
4304  av_strlcatf(buf, sizeof(buf), "a=control:streamid=%d\r\n", track->track_id);
4305  len = strlen(buf);
4306 
4307  avio_wb32(pb, len + 24);
4308  ffio_wfourcc(pb, "udta");
4309  avio_wb32(pb, len + 16);
4310  ffio_wfourcc(pb, "hnti");
4311  avio_wb32(pb, len + 8);
4312  ffio_wfourcc(pb, "sdp ");
4313  avio_write(pb, buf, len);
4314  return len + 24;
4315 }
4316 
4318  const char *tag, const char *str)
4319 {
4320  int64_t pos = avio_tell(pb);
4321  AVDictionaryEntry *t = av_dict_get(st->metadata, str, NULL, 0);
4322  if (!t || !utf8len(t->value))
4323  return 0;
4324 
4325  avio_wb32(pb, 0); /* size */
4326  ffio_wfourcc(pb, tag); /* type */
4327  avio_write(pb, t->value, strlen(t->value)); /* UTF8 string value */
4328  return update_size(pb, pos);
4329 }
4330 
4331 static int mov_write_track_kind(AVIOContext *pb, const char *scheme_uri,
4332  const char *value)
4333 {
4334  int64_t pos = avio_tell(pb);
4335 
4336  /* Box|FullBox basics */
4337  avio_wb32(pb, 0); /* size placeholder */
4338  ffio_wfourcc(pb, (const unsigned char *)"kind");
4339  avio_w8(pb, 0); /* version = 0 */
4340  avio_wb24(pb, 0); /* flags = 0 */
4341 
4342  /* Required null-terminated scheme URI */
4343  avio_write(pb, (const unsigned char *)scheme_uri,
4344  strlen(scheme_uri));
4345  avio_w8(pb, 0);
4346 
4347  /* Optional value string */
4348  if (value && value[0])
4349  avio_write(pb, (const unsigned char *)value,
4350  strlen(value));
4351 
4352  avio_w8(pb, 0);
4353 
4354  return update_size(pb, pos);
4355 }
4356 
4358 {
4359  int ret = AVERROR_BUG;
4360 
4361  for (int i = 0; ff_mov_track_kind_table[i].scheme_uri; i++) {
4363 
4364  for (int j = 0; map.value_maps[j].disposition; j++) {
4365  const struct MP4TrackKindValueMapping value_map = map.value_maps[j];
4366  if (!(st->disposition & value_map.disposition))
4367  continue;
4368 
4369  if ((ret = mov_write_track_kind(pb, map.scheme_uri, value_map.value)) < 0)
4370  return ret;
4371  }
4372  }
4373 
4374  return 0;
4375 }
4376 
4378  AVStream *st)
4379 {
4380  AVIOContext *pb_buf;
4381  int ret, size;
4382  uint8_t *buf;
4383 
4384  if (!st)
4385  return 0;
4386 
4387  ret = avio_open_dyn_buf(&pb_buf);
4388  if (ret < 0)
4389  return ret;
4390 
4391  if (mov->mode & (MODE_MP4|MODE_MOV))
4392  mov_write_track_metadata(pb_buf, st, "name", "title");
4393 
4394  if (mov->mode & MODE_MP4) {
4395  if ((ret = mov_write_track_kinds(pb_buf, st)) < 0)
4396  goto end;
4397  }
4398 
4399  if ((size = avio_get_dyn_buf(pb_buf, &buf)) > 0) {
4400  avio_wb32(pb, size + 8);
4401  ffio_wfourcc(pb, "udta");
4402  avio_write(pb, buf, size);
4403  }
4404 end:
4405  ffio_free_dyn_buf(&pb_buf);
4406 
4407  return ret;
4408 }
4409 
4411  MOVTrack *track, AVStream *st)
4412 {
4413  int64_t pos = avio_tell(pb);
4414  int entry_backup = track->entry;
4415  int chunk_backup = track->chunkCount;
4416  int ret;
4417 
4418  /* If we want to have an empty moov, but some samples already have been
4419  * buffered (delay_moov), pretend that no samples have been written yet. */
4420  if (mov->flags & FF_MOV_FLAG_EMPTY_MOOV)
4421  track->chunkCount = track->entry = 0;
4422 
4423  avio_wb32(pb, 0); /* size */
4424  ffio_wfourcc(pb, "trak");
4425  mov_write_tkhd_tag(pb, mov, track, st);
4426 
4427  av_assert2(mov->use_editlist >= 0);
4428 
4429  if (track->start_dts != AV_NOPTS_VALUE) {
4430  if (mov->use_editlist)
4431  mov_write_edts_tag(pb, mov, track); // PSP Movies and several other cases require edts box
4432  else if ((track->entry && track->cluster[0].dts) || track->mode == MODE_PSP || is_clcp_track(track))
4433  av_log(mov->fc, AV_LOG_WARNING,
4434  "Not writing any edit list even though one would have been required\n");
4435  }
4436 
4437  if (mov->is_animated_avif)
4438  mov_write_edts_tag(pb, mov, track);
4439 
4440  if (track->nb_tref_tags)
4441  mov_write_tref_tag(pb, track);
4442 
4443  if ((ret = mov_write_mdia_tag(s, pb, mov, track)) < 0)
4444  return ret;
4445  if (track->mode == MODE_PSP)
4446  mov_write_uuid_tag_psp(pb, track); // PSP Movies require this uuid box
4447  if (track->tag == MKTAG('r','t','p',' '))
4448  mov_write_udta_sdp(pb, track);
4449  if (track->mode == MODE_MOV) {
4450  if (track->par->codec_type == AVMEDIA_TYPE_VIDEO) {
4451  double sample_aspect_ratio = av_q2d(st->sample_aspect_ratio);
4452  if (st->sample_aspect_ratio.num && 1.0 != sample_aspect_ratio) {
4453  mov_write_tapt_tag(pb, track);
4454  }
4455  }
4456  if (is_clcp_track(track) && st->sample_aspect_ratio.num) {
4457  mov_write_tapt_tag(pb, track);
4458  }
4459  }
4460  mov_write_track_udta_tag(pb, mov, st);
4461  track->entry = entry_backup;
4462  track->chunkCount = chunk_backup;
4463  return update_size(pb, pos);
4464 }
4465 
4467 {
4468  int i, has_audio = 0, has_video = 0;
4469  int64_t pos = avio_tell(pb);
4470  int audio_profile = mov->iods_audio_profile;
4471  int video_profile = mov->iods_video_profile;
4472  for (i = 0; i < mov->nb_tracks; i++) {
4473  if (mov->tracks[i].entry > 0 || mov->flags & FF_MOV_FLAG_EMPTY_MOOV) {
4474  has_audio |= mov->tracks[i].par->codec_type == AVMEDIA_TYPE_AUDIO;
4475  has_video |= mov->tracks[i].par->codec_type == AVMEDIA_TYPE_VIDEO;
4476  }
4477  }
4478  if (audio_profile < 0)
4479  audio_profile = 0xFF - has_audio;
4480  if (video_profile < 0)
4481  video_profile = 0xFF - has_video;
4482  avio_wb32(pb, 0x0); /* size */
4483  ffio_wfourcc(pb, "iods");
4484  avio_wb32(pb, 0); /* version & flags */
4485  put_descr(pb, 0x10, 7);
4486  avio_wb16(pb, 0x004f);
4487  avio_w8(pb, 0xff);
4488  avio_w8(pb, 0xff);
4489  avio_w8(pb, audio_profile);
4490  avio_w8(pb, video_profile);
4491  avio_w8(pb, 0xff);
4492  return update_size(pb, pos);
4493 }
4494 
4495 static int mov_write_trex_tag(AVIOContext *pb, MOVTrack *track)
4496 {
4497  avio_wb32(pb, 0x20); /* size */
4498  ffio_wfourcc(pb, "trex");
4499  avio_wb32(pb, 0); /* version & flags */
4500  avio_wb32(pb, track->track_id); /* track ID */
4501  avio_wb32(pb, 1); /* default sample description index */
4502  avio_wb32(pb, 0); /* default sample duration */
4503  avio_wb32(pb, 0); /* default sample size */
4504  avio_wb32(pb, 0); /* default sample flags */
4505  return 0;
4506 }
4507 
4509 {
4510  int64_t pos = avio_tell(pb);
4511  int i;
4512  avio_wb32(pb, 0x0); /* size */
4513  ffio_wfourcc(pb, "mvex");
4514  for (i = 0; i < mov->nb_tracks; i++)
4515  mov_write_trex_tag(pb, &mov->tracks[i]);
4516  return update_size(pb, pos);
4517 }
4518 
4520 {
4521  int max_track_id = 1, i;
4522  int64_t max_track_len = 0;
4523  int version;
4524  int timescale;
4525 
4526  for (i = 0; i < mov->nb_tracks; i++) {
4527  if (mov->tracks[i].entry > 0 && mov->tracks[i].timescale) {
4528  int64_t max_track_len_temp = av_rescale_rnd(
4529  calc_pts_duration(mov, &mov->tracks[i]),
4530  mov->movie_timescale,
4531  mov->tracks[i].timescale,
4532  AV_ROUND_UP);
4533  if (max_track_len < max_track_len_temp)
4534  max_track_len = max_track_len_temp;
4535  if (max_track_id < mov->tracks[i].track_id)
4536  max_track_id = mov->tracks[i].track_id;
4537  }
4538  }
4539  /* If using delay_moov, make sure the output is the same as if no
4540  * samples had been written yet. */
4541  if (mov->flags & FF_MOV_FLAG_EMPTY_MOOV) {
4542  max_track_len = 0;
4543  max_track_id = 1;
4544  }
4545 
4546  version = mov_mdhd_mvhd_tkhd_version(mov, NULL, max_track_len);
4547  avio_wb32(pb, version == 1 ? 120 : 108); /* size */
4548 
4549  ffio_wfourcc(pb, "mvhd");
4550  avio_w8(pb, version);
4551  avio_wb24(pb, 0); /* flags */
4552  if (version == 1) {
4553  avio_wb64(pb, mov->time);
4554  avio_wb64(pb, mov->time);
4555  } else {
4556  avio_wb32(pb, mov->time); /* creation time */
4557  avio_wb32(pb, mov->time); /* modification time */
4558  }
4559 
4560  timescale = mov->movie_timescale;
4561  if (mov->mode == MODE_AVIF && !timescale)
4562  timescale = mov->tracks[0].timescale;
4563 
4564  avio_wb32(pb, timescale);
4565  (version == 1) ? avio_wb64(pb, max_track_len) : avio_wb32(pb, max_track_len); /* duration of longest track */
4566 
4567  avio_wb32(pb, 0x00010000); /* reserved (preferred rate) 1.0 = normal */
4568  avio_wb16(pb, 0x0100); /* reserved (preferred volume) 1.0 = normal */
4569  ffio_fill(pb, 0, 2 + 2 * 4); /* reserved */
4570 
4571  /* Matrix structure */
4572  write_matrix(pb, 1, 0, 0, 1, 0, 0);
4573 
4574  avio_wb32(pb, 0); /* reserved (preview time) */
4575  avio_wb32(pb, 0); /* reserved (preview duration) */
4576  avio_wb32(pb, 0); /* reserved (poster time) */
4577  avio_wb32(pb, 0); /* reserved (selection time) */
4578  avio_wb32(pb, 0); /* reserved (selection duration) */
4579  avio_wb32(pb, 0); /* reserved (current time) */
4580  avio_wb32(pb, max_track_id + 1); /* Next track id */
4581  return 0x6c;
4582 }
4583 
4585  AVFormatContext *s)
4586 {
4587  avio_wb32(pb, 33); /* size */
4588  ffio_wfourcc(pb, "hdlr");
4589  avio_wb32(pb, 0);
4590  avio_wb32(pb, 0);
4591  ffio_wfourcc(pb, "mdir");
4592  ffio_wfourcc(pb, "appl");
4593  avio_wb32(pb, 0);
4594  avio_wb32(pb, 0);
4595  avio_w8(pb, 0);
4596  return 33;
4597 }
4598 
4599 /* helper function to write a data tag with the specified string as data */
4600 static int mov_write_string_data_tag(AVIOContext *pb, const char *data, int lang, int long_style)
4601 {
4602  size_t data_len = strlen(data);
4603  if (long_style) {
4604  int size = 16 + data_len;
4605  avio_wb32(pb, size); /* size */
4606  ffio_wfourcc(pb, "data");
4607  avio_wb32(pb, 1);
4608  avio_wb32(pb, 0);
4609  avio_write(pb, data, data_len);
4610  return size;
4611  } else {
4612  avio_wb16(pb, data_len); /* string length */
4613  if (!lang)
4614  lang = ff_mov_iso639_to_lang("und", 1);
4615  avio_wb16(pb, lang);
4616  avio_write(pb, data, data_len);
4617  return data_len + 4;
4618  }
4619 }
4620 
4621 static int mov_write_string_tag(AVIOContext *pb, const char *name,
4622  const char *value, int lang, int long_style)
4623 {
4624  int size = 0;
4625  if (value && value[0]) {
4626  int64_t pos = avio_tell(pb);
4627  avio_wb32(pb, 0); /* size */
4628  ffio_wfourcc(pb, name);
4629  mov_write_string_data_tag(pb, value, lang, long_style);
4630  size = update_size(pb, pos);
4631  }
4632  return size;
4633 }
4634 
4635 static int mov_write_freeform_tag(AVIOContext *pb, const char *mean,
4636  const char *name, const char *data)
4637 {
4638  if (!data || !data[0])
4639  return 0;
4640 
4641  static const char stub_flags[4] = {0, 0, 0, 0};
4642 
4643  int64_t entry_pos = avio_tell(pb);
4644  avio_wb32(pb, 0); /* size */
4645  ffio_wfourcc(pb, "----"); /* freeform */
4646 
4647  size_t mean_len = strlen(mean);
4648  avio_wb32(pb, 12 + mean_len);
4649  ffio_wfourcc(pb, "mean");
4650  avio_write(pb, &stub_flags[0], sizeof(stub_flags));
4651  avio_write(pb, mean, mean_len);
4652 
4653  size_t name_len = strlen(name);
4654  avio_wb32(pb, 12 + name_len);
4655  ffio_wfourcc(pb, "name");
4656  avio_write(pb, &stub_flags[0], sizeof(stub_flags));
4657  avio_write(pb, name, name_len);
4658 
4659  mov_write_string_data_tag(pb, data, 0, 1);
4660 
4661  return update_size(pb, entry_pos);
4662 }
4663 
4665  const char *tag, int *lang)
4666 {
4667  int l, len, len2;
4668  AVDictionaryEntry *t, *t2 = NULL;
4669  char tag2[16];
4670 
4671  *lang = 0;
4672 
4673  if (!(t = av_dict_get(s->metadata, tag, NULL, 0)))
4674  return NULL;
4675 
4676  len = strlen(t->key);
4677  snprintf(tag2, sizeof(tag2), "%s-", tag);
4678  while ((t2 = av_dict_get(s->metadata, tag2, t2, AV_DICT_IGNORE_SUFFIX))) {
4679  len2 = strlen(t2->key);
4680  if (len2 == len + 4 && !strcmp(t->value, t2->value)
4681  && (l = ff_mov_iso639_to_lang(&t2->key[len2 - 3], 1)) >= 0) {
4682  *lang = l;
4683  return t;
4684  }
4685  }
4686  return t;
4687 }
4688 
4690  const char *name, const char *tag,
4691  int long_style)
4692 {
4693  int lang;
4694  AVDictionaryEntry *t = get_metadata_lang(s, tag, &lang);
4695  if (!t)
4696  return 0;
4697  return mov_write_string_tag(pb, name, t->value, lang, long_style);
4698 }
4699 
4701  const char *mean, const char *name,
4702  const char *tag)
4703 {
4704  AVDictionaryEntry *t = av_dict_get(s->metadata, tag, NULL, 0);
4705  if (!t)
4706  return 0;
4707  return mov_write_freeform_tag(pb, mean, name, t->value);
4708 }
4709 
4710 /* iTunes bpm number */
4712 {
4713  AVDictionaryEntry *t = av_dict_get(s->metadata, "tmpo", NULL, 0);
4714  int size = 0, tmpo = t ? atoi(t->value) : 0;
4715  if (tmpo) {
4716  size = 26;
4717  avio_wb32(pb, size);
4718  ffio_wfourcc(pb, "tmpo");
4719  avio_wb32(pb, size-8); /* size */
4720  ffio_wfourcc(pb, "data");
4721  avio_wb32(pb, 0x15); //type specifier
4722  avio_wb32(pb, 0);
4723  avio_wb16(pb, tmpo); // data
4724  }
4725  return size;
4726 }
4727 
4728 /* 3GPP TS 26.244 */
4730 {
4731  int lang;
4732  int64_t pos = avio_tell(pb);
4733  double latitude, longitude, altitude;
4734  int32_t latitude_fix, longitude_fix, altitude_fix;
4735  AVDictionaryEntry *t = get_metadata_lang(s, "location", &lang);
4736  const char *ptr, *place = "";
4737  char *end;
4738  static const char *astronomical_body = "earth";
4739  if (!t)
4740  return 0;
4741 
4742  ptr = t->value;
4743  latitude = strtod(ptr, &end);
4744  if (end == ptr) {
4745  av_log(s, AV_LOG_WARNING, "malformed location metadata\n");
4746  return 0;
4747  }
4748  ptr = end;
4749  longitude = strtod(ptr, &end);
4750  if (end == ptr) {
4751  av_log(s, AV_LOG_WARNING, "malformed location metadata\n");
4752  return 0;
4753  }
4754  ptr = end;
4755  altitude = strtod(ptr, &end);
4756  /* If no altitude was present, the default 0 should be fine */
4757  if (*end == '/')
4758  place = end + 1;
4759 
4760  latitude_fix = (int32_t) ((1 << 16) * latitude);
4761  longitude_fix = (int32_t) ((1 << 16) * longitude);
4762  altitude_fix = (int32_t) ((1 << 16) * altitude);
4763 
4764  avio_wb32(pb, 0); /* size */
4765  ffio_wfourcc(pb, "loci"); /* type */
4766  avio_wb32(pb, 0); /* version + flags */
4767  avio_wb16(pb, lang);
4768  avio_write(pb, place, strlen(place) + 1);
4769  avio_w8(pb, 0); /* role of place (0 == shooting location, 1 == real location, 2 == fictional location) */
4770  avio_wb32(pb, longitude_fix);
4771  avio_wb32(pb, latitude_fix);
4772  avio_wb32(pb, altitude_fix);
4773  avio_write(pb, astronomical_body, strlen(astronomical_body) + 1);
4774  avio_w8(pb, 0); /* additional notes, null terminated string */
4775 
4776  return update_size(pb, pos);
4777 }
4778 
4779 /* iTunes track or disc number */
4781  AVFormatContext *s, int disc)
4782 {
4783  AVDictionaryEntry *t = av_dict_get(s->metadata,
4784  disc ? "disc" : "track",
4785  NULL, 0);
4786  int size = 0, track = t ? atoi(t->value) : 0;
4787  if (track) {
4788  int tracks = 0;
4789  char *slash = strchr(t->value, '/');
4790  if (slash)
4791  tracks = atoi(slash + 1);
4792  avio_wb32(pb, 32); /* size */
4793  ffio_wfourcc(pb, disc ? "disk" : "trkn");
4794  avio_wb32(pb, 24); /* size */
4795  ffio_wfourcc(pb, "data");
4796  avio_wb32(pb, 0); // 8 bytes empty
4797  avio_wb32(pb, 0);
4798  avio_wb16(pb, 0); // empty
4799  avio_wb16(pb, track); // track / disc number
4800  avio_wb16(pb, tracks); // total track / disc number
4801  avio_wb16(pb, 0); // empty
4802  size = 32;
4803  }
4804  return size;
4805 }
4806 
4808  const char *name, const char *tag,
4809  int len)
4810 {
4811  AVDictionaryEntry *t = NULL;
4812  uint8_t num;
4813  int size = 24 + len;
4814 
4815  if (len != 1 && len != 4)
4816  return -1;
4817 
4818  if (!(t = av_dict_get(s->metadata, tag, NULL, 0)))
4819  return 0;
4820  num = atoi(t->value);
4821 
4822  avio_wb32(pb, size);
4823  ffio_wfourcc(pb, name);
4824  avio_wb32(pb, size - 8);
4825  ffio_wfourcc(pb, "data");
4826  avio_wb32(pb, 0x15);
4827  avio_wb32(pb, 0);
4828  if (len==4) avio_wb32(pb, num);
4829  else avio_w8 (pb, num);
4830 
4831  return size;
4832 }
4833 
4835 {
4836  MOVMuxContext *mov = s->priv_data;
4837  int64_t pos = 0;
4838 
4839  for (int i = 0; i < mov->nb_streams; i++) {
4840  MOVTrack *trk = &mov->tracks[i];
4841 
4842  if (!is_cover_image(trk->st) || trk->cover_image->size <= 0)
4843  continue;
4844 
4845  if (!pos) {
4846  pos = avio_tell(pb);
4847  avio_wb32(pb, 0);
4848  ffio_wfourcc(pb, "covr");
4849  }
4850  avio_wb32(pb, 16 + trk->cover_image->size);
4851  ffio_wfourcc(pb, "data");
4852  avio_wb32(pb, trk->tag);
4853  avio_wb32(pb , 0);
4854  avio_write(pb, trk->cover_image->data, trk->cover_image->size);
4855  }
4856 
4857  return pos ? update_size(pb, pos) : 0;
4858 }
4859 
4860 /* iTunes meta data list */
4862  AVFormatContext *s)
4863 {
4864  int64_t pos = avio_tell(pb);
4865  avio_wb32(pb, 0); /* size */
4866  ffio_wfourcc(pb, "ilst");
4867  mov_write_string_metadata(s, pb, "\251nam", "title" , 1);
4868  mov_write_string_metadata(s, pb, "\251ART", "artist" , 1);
4869  mov_write_string_metadata(s, pb, "aART", "album_artist", 1);
4870  mov_write_string_metadata(s, pb, "\251wrt", "composer" , 1);
4871  mov_write_string_metadata(s, pb, "\251alb", "album" , 1);
4872  mov_write_string_metadata(s, pb, "\251day", "date" , 1);
4873  if (!mov_write_string_metadata(s, pb, "\251too", "encoding_tool", 1)) {
4874  if (!(s->flags & AVFMT_FLAG_BITEXACT))
4875  mov_write_string_tag(pb, "\251too", LIBAVFORMAT_IDENT, 0, 1);
4876  }
4877  mov_write_string_metadata(s, pb, "\251cmt", "comment" , 1);
4878  mov_write_string_metadata(s, pb, "\251gen", "genre" , 1);
4879  mov_write_string_metadata(s, pb, "cprt", "copyright", 1);
4880  mov_write_string_metadata(s, pb, "\251grp", "grouping" , 1);
4881  mov_write_string_metadata(s, pb, "\251lyr", "lyrics" , 1);
4882  mov_write_string_metadata(s, pb, "desc", "description",1);
4883  mov_write_string_metadata(s, pb, "ldes", "synopsis" , 1);
4884  mov_write_string_metadata(s, pb, "tvsh", "show" , 1);
4885  mov_write_string_metadata(s, pb, "tven", "episode_id",1);
4886  mov_write_string_metadata(s, pb, "tvnn", "network" , 1);
4887  mov_write_string_metadata(s, pb, "keyw", "keywords" , 1);
4888  mov_write_int8_metadata (s, pb, "tves", "episode_sort",4);
4889  mov_write_int8_metadata (s, pb, "tvsn", "season_number",4);
4890  mov_write_int8_metadata (s, pb, "stik", "media_type",1);
4891  mov_write_int8_metadata (s, pb, "hdvd", "hd_video", 1);
4892  mov_write_int8_metadata (s, pb, "pgap", "gapless_playback",1);
4893  mov_write_int8_metadata (s, pb, "cpil", "compilation", 1);
4894  mov_write_covr(pb, s);
4895  mov_write_trkn_tag(pb, mov, s, 0); // track number
4896  mov_write_trkn_tag(pb, mov, s, 1); // disc number
4897  mov_write_tmpo_tag(pb, s);
4898  mov_write_custom_metadata(s, pb, "com.apple.iTunes", "DISCSUBTITLE", "disc_subtitle");
4899  return update_size(pb, pos);
4900 }
4901 
4903  AVFormatContext *s)
4904 {
4905  avio_wb32(pb, 33); /* size */
4906  ffio_wfourcc(pb, "hdlr");
4907  avio_wb32(pb, 0);
4908  avio_wb32(pb, 0);
4909  ffio_wfourcc(pb, "mdta");
4910  avio_wb32(pb, 0);
4911  avio_wb32(pb, 0);
4912  avio_wb32(pb, 0);
4913  avio_w8(pb, 0);
4914  return 33;
4915 }
4916 
4918  AVFormatContext *s)
4919 {
4920  const AVDictionaryEntry *t = NULL;
4921  int64_t pos = avio_tell(pb);
4922  int64_t curpos, entry_pos;
4923  int count = 0;
4924 
4925  avio_wb32(pb, 0); /* size */
4926  ffio_wfourcc(pb, "keys");
4927  avio_wb32(pb, 0);
4928  entry_pos = avio_tell(pb);
4929  avio_wb32(pb, 0); /* entry count */
4930 
4931  while (t = av_dict_iterate(s->metadata, t)) {
4932  size_t key_len = strlen(t->key);
4933  avio_wb32(pb, key_len + 8);
4934  ffio_wfourcc(pb, "mdta");
4935  avio_write(pb, t->key, key_len);
4936  count += 1;
4937  }
4938  curpos = avio_tell(pb);
4939  avio_seek(pb, entry_pos, SEEK_SET);
4940  avio_wb32(pb, count); // rewrite entry count
4941  avio_seek(pb, curpos, SEEK_SET);
4942 
4943  return update_size(pb, pos);
4944 }
4945 
4947  AVFormatContext *s)
4948 {
4949  const AVDictionaryEntry *t = NULL;
4950  int64_t pos = avio_tell(pb);
4951  int count = 1; /* keys are 1-index based */
4952 
4953  avio_wb32(pb, 0); /* size */
4954  ffio_wfourcc(pb, "ilst");
4955 
4956  while (t = av_dict_iterate(s->metadata, t)) {
4957  int64_t entry_pos = avio_tell(pb);
4958  avio_wb32(pb, 0); /* size */
4959  avio_wb32(pb, count); /* key */
4960  mov_write_string_data_tag(pb, t->value, 0, 1);
4961  update_size(pb, entry_pos);
4962  count += 1;
4963  }
4964  return update_size(pb, pos);
4965 }
4966 
4967 /* meta data tags */
4969  AVFormatContext *s)
4970 {
4971  int size = 0;
4972  int64_t pos = avio_tell(pb);
4973  avio_wb32(pb, 0); /* size */
4974  ffio_wfourcc(pb, "meta");
4975  avio_wb32(pb, 0);
4976  if (mov->flags & FF_MOV_FLAG_USE_MDTA) {
4977  mov_write_mdta_hdlr_tag(pb, mov, s);
4978  mov_write_mdta_keys_tag(pb, mov, s);
4979  mov_write_mdta_ilst_tag(pb, mov, s);
4980  } else if (mov->mode == MODE_AVIF) {
4981  mov_write_hdlr_tag(s, pb, &mov->tracks[0]);
4982  // We always write the primary item id as 1 since only one track is
4983  // supported for AVIF.
4984  mov_write_pitm_tag(pb, 1);
4985  mov_write_iloc_tag(pb, mov, s);
4986  mov_write_iinf_tag(pb, mov, s);
4987  if (mov->nb_streams > 1)
4988  mov_write_iref_tag(pb, mov, s);
4989  mov_write_iprp_tag(pb, mov, s);
4990  } else {
4991  /* iTunes metadata tag */
4992  mov_write_itunes_hdlr_tag(pb, mov, s);
4993  mov_write_ilst_tag(pb, mov, s);
4994  }
4995  size = update_size(pb, pos);
4996  return size;
4997 }
4998 
5000  const char *name, const char *key)
5001 {
5002  int len;
5003  AVDictionaryEntry *t;
5004 
5005  if (!(t = av_dict_get(s->metadata, key, NULL, 0)))
5006  return 0;
5007 
5008  len = strlen(t->value);
5009  if (len > 0) {
5010  int size = len + 8;
5011  avio_wb32(pb, size);
5012  ffio_wfourcc(pb, name);
5013  avio_write(pb, t->value, len);
5014  return size;
5015  }
5016  return 0;
5017 }
5018 
5019 static int ascii_to_wc(AVIOContext *pb, const uint8_t *b)
5020 {
5021  int val;
5022  while (*b) {
5023  GET_UTF8(val, *b++, return -1;)
5024  avio_wb16(pb, val);
5025  }
5026  avio_wb16(pb, 0x00);
5027  return 0;
5028 }
5029 
5030 static uint16_t language_code(const char *str)
5031 {
5032  return (((str[0] - 0x60) & 0x1F) << 10) +
5033  (((str[1] - 0x60) & 0x1F) << 5) +
5034  (( str[2] - 0x60) & 0x1F);
5035 }
5036 
5038  const char *tag, const char *str)
5039 {
5040  int64_t pos = avio_tell(pb);
5041  AVDictionaryEntry *t = av_dict_get(s->metadata, str, NULL, 0);
5042  if (!t || !utf8len(t->value))
5043  return 0;
5044  avio_wb32(pb, 0); /* size */
5045  ffio_wfourcc(pb, tag); /* type */
5046  avio_wb32(pb, 0); /* version + flags */
5047  if (!strcmp(tag, "yrrc"))
5048  avio_wb16(pb, atoi(t->value));
5049  else {
5050  avio_wb16(pb, language_code("eng")); /* language */
5051  avio_write(pb, t->value, strlen(t->value) + 1); /* UTF8 string value */
5052  if (!strcmp(tag, "albm") &&
5053  (t = av_dict_get(s->metadata, "track", NULL, 0)))
5054  avio_w8(pb, atoi(t->value));
5055  }
5056  return update_size(pb, pos);
5057 }
5058 
5060 {
5061  int64_t pos = avio_tell(pb);
5062  int i, nb_chapters = FFMIN(s->nb_chapters, 255);
5063 
5064  avio_wb32(pb, 0); // size
5065  ffio_wfourcc(pb, "chpl");
5066  avio_wb32(pb, 0x01000000); // version + flags
5067  avio_wb32(pb, 0); // unknown
5068  avio_w8(pb, nb_chapters);
5069 
5070  for (i = 0; i < nb_chapters; i++) {
5071  AVChapter *c = s->chapters[i];
5072  AVDictionaryEntry *t;
5073  avio_wb64(pb, av_rescale_q(c->start, c->time_base, (AVRational){1,10000000}));
5074 
5075  if ((t = av_dict_get(c->metadata, "title", NULL, 0))) {
5076  int len = FFMIN(strlen(t->value), 255);
5077  avio_w8(pb, len);
5078  avio_write(pb, t->value, len);
5079  } else
5080  avio_w8(pb, 0);
5081  }
5082  return update_size(pb, pos);
5083 }
5084 
5086  AVFormatContext *s)
5087 {
5088  AVIOContext *pb_buf;
5089  int ret, size;
5090  uint8_t *buf;
5091 
5092  ret = avio_open_dyn_buf(&pb_buf);
5093  if (ret < 0)
5094  return ret;
5095 
5096  if (mov->mode & MODE_3GP) {
5097  mov_write_3gp_udta_tag(pb_buf, s, "perf", "artist");
5098  mov_write_3gp_udta_tag(pb_buf, s, "titl", "title");
5099  mov_write_3gp_udta_tag(pb_buf, s, "auth", "author");
5100  mov_write_3gp_udta_tag(pb_buf, s, "gnre", "genre");
5101  mov_write_3gp_udta_tag(pb_buf, s, "dscp", "comment");
5102  mov_write_3gp_udta_tag(pb_buf, s, "albm", "album");
5103  mov_write_3gp_udta_tag(pb_buf, s, "cprt", "copyright");
5104  mov_write_3gp_udta_tag(pb_buf, s, "yrrc", "date");
5105  mov_write_loci_tag(s, pb_buf);
5106  } 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
5107  mov_write_string_metadata(s, pb_buf, "\251ART", "artist", 0);
5108  mov_write_string_metadata(s, pb_buf, "\251nam", "title", 0);
5109  mov_write_string_metadata(s, pb_buf, "\251aut", "author", 0);
5110  mov_write_string_metadata(s, pb_buf, "\251alb", "album", 0);
5111  mov_write_string_metadata(s, pb_buf, "\251day", "date", 0);
5112  mov_write_string_metadata(s, pb_buf, "\251swr", "encoder", 0);
5113  // currently ignored by mov.c
5114  mov_write_string_metadata(s, pb_buf, "\251des", "comment", 0);
5115  // add support for libquicktime, this atom is also actually read by mov.c
5116  mov_write_string_metadata(s, pb_buf, "\251cmt", "comment", 0);
5117  mov_write_string_metadata(s, pb_buf, "\251gen", "genre", 0);
5118  mov_write_string_metadata(s, pb_buf, "\251cpy", "copyright", 0);
5119  mov_write_string_metadata(s, pb_buf, "\251mak", "make", 0);
5120  mov_write_string_metadata(s, pb_buf, "\251mod", "model", 0);
5121  mov_write_string_metadata(s, pb_buf, "\251xyz", "location", 0);
5122  mov_write_string_metadata(s, pb_buf, "\251key", "keywords", 0);
5123  mov_write_raw_metadata_tag(s, pb_buf, "XMP_", "xmp");
5124  } else {
5125  /* iTunes meta data */
5126  mov_write_meta_tag(pb_buf, mov, s);
5127  mov_write_loci_tag(s, pb_buf);
5128  }
5129 
5130  if (s->nb_chapters && !(mov->flags & FF_MOV_FLAG_DISABLE_CHPL))
5131  mov_write_chpl_tag(pb_buf, s);
5132 
5133  if ((size = avio_get_dyn_buf(pb_buf, &buf)) > 0) {
5134  avio_wb32(pb, size + 8);
5135  ffio_wfourcc(pb, "udta");
5136  avio_write(pb, buf, size);
5137  }
5138  ffio_free_dyn_buf(&pb_buf);
5139 
5140  return 0;
5141 }
5142 
5144  const char *str, const char *lang, int type)
5145 {
5146  int len = utf8len(str) + 1;
5147  if (len <= 0)
5148  return;
5149  avio_wb16(pb, len * 2 + 10); /* size */
5150  avio_wb32(pb, type); /* type */
5151  avio_wb16(pb, language_code(lang)); /* language */
5152  avio_wb16(pb, 0x01); /* ? */
5153  ascii_to_wc(pb, str);
5154 }
5155 
5157 {
5158  AVDictionaryEntry *title = av_dict_get(s->metadata, "title", NULL, 0);
5159  int64_t pos, pos2;
5160 
5161  if (title) {
5162  pos = avio_tell(pb);
5163  avio_wb32(pb, 0); /* size placeholder*/
5164  ffio_wfourcc(pb, "uuid");
5165  ffio_wfourcc(pb, "USMT");
5166  avio_wb32(pb, 0x21d24fce); /* 96 bit UUID */
5167  avio_wb32(pb, 0xbb88695c);
5168  avio_wb32(pb, 0xfac9c740);
5169 
5170  pos2 = avio_tell(pb);
5171  avio_wb32(pb, 0); /* size placeholder*/
5172  ffio_wfourcc(pb, "MTDT");
5173  avio_wb16(pb, 4);
5174 
5175  // ?
5176  avio_wb16(pb, 0x0C); /* size */
5177  avio_wb32(pb, 0x0B); /* type */
5178  avio_wb16(pb, language_code("und")); /* language */
5179  avio_wb16(pb, 0x0); /* ? */
5180  avio_wb16(pb, 0x021C); /* data */
5181 
5182  if (!(s->flags & AVFMT_FLAG_BITEXACT))
5183  mov_write_psp_udta_tag(pb, LIBAVFORMAT_IDENT, "eng", 0x04);
5184  mov_write_psp_udta_tag(pb, title->value, "eng", 0x01);
5185  mov_write_psp_udta_tag(pb, "2006/04/01 11:11:11", "und", 0x03);
5186 
5187  update_size(pb, pos2);
5188  return update_size(pb, pos);
5189  }
5190 
5191  return 0;
5192 }
5193 
5195 {
5200  if (!sd)
5201  return 0;
5202 
5204  for (AVEncryptionInitInfo *copy = info; copy; copy = copy->next) {
5205  int64_t pos;
5206 
5207  if (!copy->data_size && !copy->num_key_ids)
5208  continue;
5209 
5210  pos = avio_tell(pb);
5211  avio_wb32(pb, 0); /* size placeholder */
5212  ffio_wfourcc(pb, "pssh");
5213  avio_w8(pb, 1); /* version */
5214  avio_wb24(pb, 0);
5215  for (int i = 0; i < copy->system_id_size; i++)
5216  avio_w8(pb, copy->system_id[i]);
5217  avio_wb32(pb, copy->num_key_ids);
5218  for (int i = 0; i < copy->num_key_ids; i++)
5219  for (int j = 0; j < copy->key_id_size; j++)
5220  avio_w8(pb, copy->key_ids[i][j]);
5221  avio_wb32(pb, copy->data_size);
5222  avio_write(pb, copy->data, copy->data_size);
5223  update_size(pb, pos);
5224  }
5225 
5227 
5228  return 0;
5229 }
5230 
5231 static void build_chunks(MOVTrack *trk)
5232 {
5233  int i;
5234  MOVIentry *chunk = &trk->cluster[0];
5235  uint64_t chunkSize = chunk->size;
5236  chunk->chunkNum = 1;
5237  if (trk->chunkCount)
5238  return;
5239  trk->chunkCount = 1;
5240  for (i = 1; i<trk->entry; i++){
5241  if (chunk->pos + chunkSize == trk->cluster[i].pos &&
5242  chunk->stsd_index == trk->cluster[i].stsd_index &&
5243  chunkSize + trk->cluster[i].size < (1<<20)){
5244  chunkSize += trk->cluster[i].size;
5245  chunk->samples_in_chunk += trk->cluster[i].entries;
5246  } else {
5247  trk->cluster[i].chunkNum = chunk->chunkNum+1;
5248  chunk=&trk->cluster[i];
5249  chunkSize = chunk->size;
5250  trk->chunkCount++;
5251  }
5252  }
5253 }
5254 
5255 /**
5256  * Assign track ids. If option "use_stream_ids_as_track_ids" is set,
5257  * the stream ids are used as track ids.
5258  *
5259  * This assumes mov->tracks and s->streams are in the same order and
5260  * there are no gaps in either of them (so mov->tracks[n] refers to
5261  * s->streams[n]).
5262  *
5263  * As an exception, there can be more entries in
5264  * s->streams than in mov->tracks, in which case new track ids are
5265  * generated (starting after the largest found stream id).
5266  */
5268 {
5269  int i;
5270 
5271  if (mov->track_ids_ok)
5272  return 0;
5273 
5274  if (mov->use_stream_ids_as_track_ids) {
5275  int next_generated_track_id = 0;
5276  for (i = 0; i < mov->nb_streams; i++) {
5277  AVStream *st = mov->tracks[i].st;
5278  if (st->id > next_generated_track_id)
5279  next_generated_track_id = st->id;
5280  }
5281 
5282  for (i = 0; i < mov->nb_tracks; i++) {
5283  if (mov->tracks[i].entry <= 0 && !(mov->flags & FF_MOV_FLAG_FRAGMENT))
5284  continue;
5285 
5286  mov->tracks[i].track_id = i >= mov->nb_streams ? ++next_generated_track_id : mov->tracks[i].st->id;
5287  }
5288  } else {
5289  int last_track_id = 0;
5290  for (i = 0; i < mov->nb_tracks; i++) {
5291  if (mov->tracks[i].entry <= 0 && !(mov->flags & FF_MOV_FLAG_FRAGMENT))
5292  continue;
5293 
5294  last_track_id =
5295  mov->tracks[i].track_id = (mov->tracks[i].st
5296  ? FFMAX(mov->tracks[i].st->index, last_track_id)
5297  : FFMAX(i, last_track_id)) + 1;
5298  }
5299  }
5300 
5301  mov->track_ids_ok = 1;
5302 
5303  return 0;
5304 }
5305 
5306 static int mov_find_tref_id(MOVMuxContext *mov, const MovTag *tag, uint32_t id)
5307 {
5308  for (int i = 0; i < tag->nb_id; i++) {
5309  if (tag->id[i] == id)
5310  return 1;
5311  }
5312  return 0;
5313 }
5314 
5315 static int mov_add_tref_id(MOVMuxContext *mov, MovTag *tag, uint32_t id)
5316 {
5317  int ret = mov_find_tref_id(mov, tag, id);
5318 
5319  if (!ret) {
5320  uint32_t *tmp = av_realloc_array(tag->id, tag->nb_id + 1, sizeof(*tag->id));
5321  if (!tmp)
5322  return AVERROR(ENOMEM);
5323  tag->id = tmp;
5324  tag->id[tag->nb_id++] = id;
5325  }
5326 
5327  return 0;
5328 }
5329 
5330 static MovTag *mov_find_tref_tag(MOVMuxContext *mov, const MOVTrack *trk, uint32_t name)
5331 {
5332  for (int i = 0; i < trk->nb_tref_tags; i++) {
5333  MovTag *entry = &trk->tref_tags[i];
5334 
5335  if (entry->name == name)
5336  return entry;
5337  }
5338  return NULL;
5339 }
5340 
5341 static MovTag *mov_add_tref_tag(MOVMuxContext *mov, MOVTrack *trk, uint32_t name)
5342 {
5343  MovTag *tag = mov_find_tref_tag(mov, trk, name);
5344 
5345  if (!tag) {
5346  MovTag *tmp = av_realloc_array(trk->tref_tags, trk->nb_tref_tags + 1,
5347  sizeof(*trk->tref_tags));
5348  if (!tmp)
5349  return NULL;
5350  trk->tref_tags = tmp;
5351  tag = &trk->tref_tags[trk->nb_tref_tags++];
5352  *tag = (MovTag){ .name = name };
5353  }
5354 
5355  return tag;
5356 }
5357 
5359  AVFormatContext *s)
5360 {
5361  int i;
5362  int64_t pos = avio_tell(pb);
5363  avio_wb32(pb, 0); /* size placeholder*/
5364  ffio_wfourcc(pb, "moov");
5365 
5366  mov_setup_track_ids(mov, s);
5367 
5368  for (i = 0; i < mov->nb_tracks; i++) {
5369  if (mov->tracks[i].entry <= 0 && !(mov->flags & FF_MOV_FLAG_FRAGMENT))
5370  continue;
5371 
5372  mov->tracks[i].time = mov->time;
5373 
5374  if (mov->tracks[i].entry)
5375  build_chunks(&mov->tracks[i]);
5376  }
5377 
5378  if (mov->chapter_track)
5379  for (i = 0; i < mov->nb_streams; i++) {
5380  MovTag *tag = mov_add_tref_tag(mov, &mov->tracks[i], MKTAG('c','h','a','p'));
5381  if (!tag)
5382  return AVERROR(ENOMEM);
5383 
5384  int ret = mov_add_tref_id(mov, tag, mov->tracks[mov->chapter_track].track_id);
5385  if (ret < 0)
5386  return ret;
5387  }
5388  for (i = 0; i < mov->nb_tracks; i++) {
5389  MOVTrack *track = &mov->tracks[i];
5390  if (track->tag == MKTAG('r','t','p',' ')) {
5391  MovTag *tag = mov_add_tref_tag(mov, track, MKTAG('h','i','n','t'));
5392  if (!tag)
5393  return AVERROR(ENOMEM);
5394 
5395  av_assert0(track->nb_src_track);
5396  int ret = mov_add_tref_id(mov, tag, mov->tracks[*track->src_track].track_id);
5397  if (ret < 0)
5398  return ret;
5399  } else if (track->tag == MKTAG('l','v','c','1') && track->nb_src_track) {
5400  MovTag *tag = mov_add_tref_tag(mov, track, MKTAG('s','b','a','s'));
5401  if (!tag)
5402  return AVERROR(ENOMEM);
5403 
5404  int ret = mov_add_tref_id(mov, tag, mov->tracks[*track->src_track].track_id);
5405  if (ret < 0)
5406  return ret;
5407  } else {
5408  if (track->par->codec_type == AVMEDIA_TYPE_AUDIO) {
5410  track->st->codecpar->nb_coded_side_data,
5412  if (sd && sd->size == sizeof(int)) {
5413  int *fallback = (int *)sd->data;
5414  if (*fallback >= 0 && *fallback < mov->nb_tracks) {
5415  MovTag *tag = mov_add_tref_tag(mov, track, MKTAG('f','a','l','l'));
5416  if (!tag)
5417  return AVERROR(ENOMEM);
5418 
5419  int ret = mov_add_tref_id(mov, tag, mov->tracks[*fallback].track_id);
5420  if (ret < 0)
5421  return ret;
5422  }
5423  }
5424  }
5425  for (int j = 0; j < track->nb_src_track; j++) {
5426  int src_trk = track->src_track[j];
5427  MovTag *tag = mov_add_tref_tag(mov, &mov->tracks[src_trk], track->tag);
5428  if (!tag)
5429  return AVERROR(ENOMEM);
5430  int ret = mov_add_tref_id(mov, tag, track->track_id);
5431  if (ret < 0)
5432  return ret;
5433  }
5434  if (mov->nb_meta_tmcd && track->nb_src_track) {
5435  /* Derive the duration from the first source track, matching
5436  * the convention used by get_pts_range() and the rtp/lvc1
5437  * branches above. The source may use a different timescale. */
5438  int src_trk = track->src_track[0];
5439  track->track_duration = av_rescale(mov->tracks[src_trk].track_duration,
5440  track->timescale,
5441  mov->tracks[src_trk].timescale);
5442  }
5443  }
5444  }
5445 
5446  mov_write_mvhd_tag(pb, mov);
5447  if (mov->mode != MODE_MOV && mov->mode != MODE_AVIF && !mov->iods_skip)
5448  mov_write_iods_tag(pb, mov);
5449  for (i = 0; i < mov->nb_tracks; i++) {
5450  if (mov->tracks[i].entry > 0 || mov->flags & FF_MOV_FLAG_FRAGMENT ||
5451  mov->mode == MODE_AVIF) {
5452  int ret = mov_write_trak_tag(s, pb, mov, &(mov->tracks[i]), i < mov->nb_streams ? mov->tracks[i].st : NULL);
5453  if (ret < 0)
5454  return ret;
5455  }
5456  }
5457  /* Don't write mvex for hybrid_fragmented during mov_write_trailer
5458  * (mov->moov_written != 0)
5459  */
5460  if (mov->flags & FF_MOV_FLAG_FRAGMENT &&
5462  mov_write_mvex_tag(pb, mov); /* QuickTime requires trak to precede this */
5463 
5464  if (mov->mode == MODE_PSP)
5466  else if (mov->mode != MODE_AVIF)
5467  mov_write_udta_tag(pb, mov, s);
5468  for (i = 0; i < mov->nb_streams; i++)
5469  mov_write_pssh_tag(pb, mov->tracks[i].st);
5470 
5471  return update_size(pb, pos);
5472 }
5473 
5474 static void param_write_int(AVIOContext *pb, const char *name, int value)
5475 {
5476  avio_printf(pb, "<param name=\"%s\" value=\"%d\" valuetype=\"data\"/>\n", name, value);
5477 }
5478 
5479 static void param_write_string(AVIOContext *pb, const char *name, const char *value)
5480 {
5481  avio_printf(pb, "<param name=\"%s\" value=\"%s\" valuetype=\"data\"/>\n", name, value);
5482 }
5483 
5484 static void param_write_hex(AVIOContext *pb, const char *name, const uint8_t *value, int len)
5485 {
5486  char buf[150];
5487  len = FFMIN(sizeof(buf) / 2 - 1, len);
5488  ff_data_to_hex(buf, value, len, 0);
5489  avio_printf(pb, "<param name=\"%s\" value=\"%s\" valuetype=\"data\"/>\n", name, buf);
5490 }
5491 
5493 {
5494  int64_t pos = avio_tell(pb);
5495  int i;
5496 
5497  static const AVUUID uuid = {
5498  0xa5, 0xd4, 0x0b, 0x30, 0xe8, 0x14, 0x11, 0xdd,
5499  0xba, 0x2f, 0x08, 0x00, 0x20, 0x0c, 0x9a, 0x66
5500  };
5501 
5502  avio_wb32(pb, 0);
5503  ffio_wfourcc(pb, "uuid");
5504  avio_write(pb, uuid, AV_UUID_LEN);
5505  avio_wb32(pb, 0);
5506 
5507  avio_printf(pb, "<?xml version=\"1.0\" encoding=\"utf-8\"?>\n");
5508  avio_printf(pb, "<smil xmlns=\"http://www.w3.org/2001/SMIL20/Language\">\n");
5509  avio_printf(pb, "<head>\n");
5510  if (!(mov->fc->flags & AVFMT_FLAG_BITEXACT))
5511  avio_printf(pb, "<meta name=\"creator\" content=\"%s\" />\n",
5513  avio_printf(pb, "</head>\n");
5514  avio_printf(pb, "<body>\n");
5515  avio_printf(pb, "<switch>\n");
5516 
5517  mov_setup_track_ids(mov, s);
5518 
5519  for (i = 0; i < mov->nb_tracks; i++) {
5520  MOVTrack *track = &mov->tracks[i];
5521  struct mpeg4_bit_rate_values bit_rates =
5523  const char *type;
5524  int track_id = track->track_id;
5525  char track_name_buf[32] = { 0 };
5526 
5527  AVStream *st = track->st;
5528  AVDictionaryEntry *lang = av_dict_get(st->metadata, "language", NULL,0);
5529 
5530  if (track->par->codec_type == AVMEDIA_TYPE_VIDEO && !is_cover_image(st)) {
5531  type = "video";
5532  } else if (track->par->codec_type == AVMEDIA_TYPE_AUDIO) {
5533  type = "audio";
5534  } else {
5535  continue;
5536  }
5537 
5538  avio_printf(pb, "<%s systemBitrate=\"%"PRIu32"\">\n", type,
5539  bit_rates.avg_bit_rate);
5540  param_write_int(pb, "systemBitrate", bit_rates.avg_bit_rate);
5541  param_write_int(pb, "trackID", track_id);
5542  param_write_string(pb, "systemLanguage", lang ? lang->value : "und");
5543 
5544  /* Build track name piece by piece: */
5545  /* 1. track type */
5546  av_strlcat(track_name_buf, type, sizeof(track_name_buf));
5547  /* 2. track language, if available */
5548  if (lang)
5549  av_strlcatf(track_name_buf, sizeof(track_name_buf),
5550  "_%s", lang->value);
5551  /* 3. special type suffix */
5552  /* "_cc" = closed captions, "_ad" = audio_description */
5554  av_strlcat(track_name_buf, "_cc", sizeof(track_name_buf));
5556  av_strlcat(track_name_buf, "_ad", sizeof(track_name_buf));
5557 
5558  param_write_string(pb, "trackName", track_name_buf);
5559 
5560  if (track->par->codec_type == AVMEDIA_TYPE_VIDEO) {
5561  if (track->par->codec_id == AV_CODEC_ID_H264) {
5562  uint8_t *ptr;
5563  int size = track->extradata_size[track->last_stsd_index];
5564  if (!ff_avc_write_annexb_extradata(track->extradata[track->last_stsd_index], &ptr,
5565  &size)) {
5566  param_write_hex(pb, "CodecPrivateData",
5567  ptr ? ptr : track->extradata[track->last_stsd_index],
5568  size);
5569  av_free(ptr);
5570  }
5571  param_write_string(pb, "FourCC", "H264");
5572  } else if (track->par->codec_id == AV_CODEC_ID_VC1) {
5573  param_write_string(pb, "FourCC", "WVC1");
5574  param_write_hex(pb, "CodecPrivateData", track->extradata[track->last_stsd_index],
5575  track->extradata_size[track->last_stsd_index]);
5576  }
5577  param_write_int(pb, "MaxWidth", track->par->width);
5578  param_write_int(pb, "MaxHeight", track->par->height);
5579  param_write_int(pb, "DisplayWidth", track->par->width);
5580  param_write_int(pb, "DisplayHeight", track->par->height);
5581  } else {
5582  if (track->par->codec_id == AV_CODEC_ID_AAC) {
5583  switch (track->par->profile) {
5584  case AV_PROFILE_AAC_HE_V2:
5585  param_write_string(pb, "FourCC", "AACP");
5586  break;
5587  case AV_PROFILE_AAC_HE:
5588  param_write_string(pb, "FourCC", "AACH");
5589  break;
5590  default:
5591  param_write_string(pb, "FourCC", "AACL");
5592  }
5593  } else if (track->par->codec_id == AV_CODEC_ID_WMAPRO) {
5594  param_write_string(pb, "FourCC", "WMAP");
5595  }
5596  param_write_hex(pb, "CodecPrivateData", track->extradata[track->last_stsd_index],
5597  track->extradata_size[track->last_stsd_index]);
5599  track->par->codec_id));
5600  param_write_int(pb, "Channels", track->par->ch_layout.nb_channels);
5601  param_write_int(pb, "SamplingRate", track->tag == MKTAG('i','a','m','f') ?
5602  0 : track->par->sample_rate);
5603  param_write_int(pb, "BitsPerSample", 16);
5604  param_write_int(pb, "PacketSize", track->par->block_align ?
5605  track->par->block_align : 4);
5606  }
5607  avio_printf(pb, "</%s>\n", type);
5608  }
5609  avio_printf(pb, "</switch>\n");
5610  avio_printf(pb, "</body>\n");
5611  avio_printf(pb, "</smil>\n");
5612 
5613  return update_size(pb, pos);
5614 }
5615 
5617 {
5618  avio_wb32(pb, 16);
5619  ffio_wfourcc(pb, "mfhd");
5620  avio_wb32(pb, 0);
5621  avio_wb32(pb, mov->fragments);
5622  return 0;
5623 }
5624 
5625 static uint32_t get_sample_flags(MOVTrack *track, MOVIentry *entry)
5626 {
5629 }
5630 
5632  MOVTrack *track, int64_t moof_offset)
5633 {
5634  int64_t pos = avio_tell(pb);
5637  if (!track->entry) {
5639  } else {
5641  }
5644  if (mov->flags & FF_MOV_FLAG_DEFAULT_BASE_MOOF) {
5647  }
5648  /* CMAF requires all values to be explicit in tfhd atoms */
5649  if (mov->flags & FF_MOV_FLAG_CMAF)
5651 
5652  /* Don't set a default sample size, the silverlight player refuses
5653  * to play files with that set. Don't set a default sample duration,
5654  * WMP freaks out if it is set. Don't set a base data offset, PIFF
5655  * file format says it MUST NOT be set. */
5656  if (track->mode == MODE_ISM)
5659 
5660  avio_wb32(pb, 0); /* size placeholder */
5661  ffio_wfourcc(pb, "tfhd");
5662  avio_w8(pb, 0); /* version */
5663  avio_wb24(pb, flags);
5664 
5665  avio_wb32(pb, track->track_id); /* track-id */
5667  avio_wb64(pb, moof_offset);
5668  if (flags & MOV_TFHD_STSD_ID) {
5669  avio_wb32(pb, 1);
5670  }
5672  track->default_duration = get_cluster_duration(track, 0);
5673  avio_wb32(pb, track->default_duration);
5674  }
5675  if (flags & MOV_TFHD_DEFAULT_SIZE) {
5676  track->default_size = track->entry ? track->cluster[0].size : 1;
5677  avio_wb32(pb, track->default_size);
5678  } else
5679  track->default_size = -1;
5680 
5681  if (flags & MOV_TFHD_DEFAULT_FLAGS) {
5682  /* Set the default flags based on the second sample, if available.
5683  * If the first sample is different, that can be signaled via a separate field. */
5684  if (track->entry > 1)
5685  track->default_sample_flags = get_sample_flags(track, &track->cluster[1]);
5686  else
5687  track->default_sample_flags =
5688  track->par->codec_type == AVMEDIA_TYPE_VIDEO ?
5691  avio_wb32(pb, track->default_sample_flags);
5692  }
5693 
5694  return update_size(pb, pos);
5695 }
5696 
5698  MOVTrack *track, int moof_size,
5699  int first, int end)
5700 {
5701  int64_t pos = avio_tell(pb);
5702  uint32_t flags = MOV_TRUN_DATA_OFFSET;
5703  int i;
5704 
5705  for (i = first; i < end; i++) {
5706  if (get_cluster_duration(track, i) != track->default_duration)
5708  if (track->cluster[i].size != track->default_size)
5710  if (i > first && get_sample_flags(track, &track->cluster[i]) != track->default_sample_flags)
5712  }
5713  if (!(flags & MOV_TRUN_SAMPLE_FLAGS) && track->entry > first &&
5714  get_sample_flags(track, &track->cluster[first]) != track->default_sample_flags)
5716  if (track->flags & MOV_TRACK_CTTS)
5718 
5719  avio_wb32(pb, 0); /* size placeholder */
5720  ffio_wfourcc(pb, "trun");
5722  avio_w8(pb, 1); /* version */
5723  else
5724  avio_w8(pb, 0); /* version */
5725  avio_wb24(pb, flags);
5726 
5727  avio_wb32(pb, end - first); /* sample count */
5728  if (mov->flags & FF_MOV_FLAG_OMIT_TFHD_OFFSET &&
5730  !mov->first_trun)
5731  avio_wb32(pb, 0); /* Later tracks follow immediately after the previous one */
5732  else
5733  avio_wb32(pb, moof_size + 8 + track->data_offset +
5734  track->cluster[first].pos); /* data offset */
5736  avio_wb32(pb, get_sample_flags(track, &track->cluster[first]));
5737 
5738  for (i = first; i < end; i++) {
5740  avio_wb32(pb, get_cluster_duration(track, i));
5742  avio_wb32(pb, track->cluster[i].size);
5744  avio_wb32(pb, get_sample_flags(track, &track->cluster[i]));
5745  if (flags & MOV_TRUN_SAMPLE_CTS)
5746  avio_wb32(pb, track->cluster[i].cts);
5747  }
5748 
5749  mov->first_trun = 0;
5750  return update_size(pb, pos);
5751 }
5752 
5753 static int mov_write_tfxd_tag(AVIOContext *pb, MOVTrack *track)
5754 {
5755  int64_t pos = avio_tell(pb);
5756  static const uint8_t uuid[] = {
5757  0x6d, 0x1d, 0x9b, 0x05, 0x42, 0xd5, 0x44, 0xe6,
5758  0x80, 0xe2, 0x14, 0x1d, 0xaf, 0xf7, 0x57, 0xb2
5759  };
5760 
5761  avio_wb32(pb, 0); /* size placeholder */
5762  ffio_wfourcc(pb, "uuid");
5763  avio_write(pb, uuid, AV_UUID_LEN);
5764  avio_w8(pb, 1);
5765  avio_wb24(pb, 0);
5766  avio_wb64(pb, track->cluster[0].dts + track->cluster[0].cts);
5767  avio_wb64(pb, track->end_pts -
5768  (track->cluster[0].dts + track->cluster[0].cts));
5769 
5770  return update_size(pb, pos);
5771 }
5772 
5774  MOVTrack *track, int entry)
5775 {
5776  int n = track->nb_frag_info - 1 - entry, i;
5777  int size = 8 + 16 + 4 + 1 + 16*n;
5778  static const uint8_t uuid[] = {
5779  0xd4, 0x80, 0x7e, 0xf2, 0xca, 0x39, 0x46, 0x95,
5780  0x8e, 0x54, 0x26, 0xcb, 0x9e, 0x46, 0xa7, 0x9f
5781  };
5782 
5783  if (entry < 0)
5784  return 0;
5785 
5786  avio_seek(pb, track->frag_info[entry].tfrf_offset, SEEK_SET);
5787  avio_wb32(pb, size);
5788  ffio_wfourcc(pb, "uuid");
5789  avio_write(pb, uuid, AV_UUID_LEN);
5790  avio_w8(pb, 1);
5791  avio_wb24(pb, 0);
5792  avio_w8(pb, n);
5793  for (i = 0; i < n; i++) {
5794  int index = entry + 1 + i;
5795  avio_wb64(pb, track->frag_info[index].time);
5796  avio_wb64(pb, track->frag_info[index].duration);
5797  }
5798  if (n < mov->ism_lookahead) {
5799  int free_size = 16 * (mov->ism_lookahead - n);
5800  avio_wb32(pb, free_size);
5801  ffio_wfourcc(pb, "free");
5802  ffio_fill(pb, 0, free_size - 8);
5803  }
5804 
5805  return 0;
5806 }
5807 
5809  MOVTrack *track)
5810 {
5811  int64_t pos = avio_tell(pb);
5812  int i;
5813  for (i = 0; i < mov->ism_lookahead; i++) {
5814  /* Update the tfrf tag for the last ism_lookahead fragments,
5815  * nb_frag_info - 1 is the next fragment to be written. */
5816  mov_write_tfrf_tag(pb, mov, track, track->nb_frag_info - 2 - i);
5817  }
5818  avio_seek(pb, pos, SEEK_SET);
5819  return 0;
5820 }
5821 
5822 static int mov_add_tfra_entries(AVIOContext *pb, MOVMuxContext *mov, int tracks,
5823  int size)
5824 {
5825  int i;
5826  for (i = 0; i < mov->nb_tracks; i++) {
5827  MOVTrack *track = &mov->tracks[i];
5829  if ((tracks >= 0 && i != tracks) || !track->entry)
5830  continue;
5831  track->nb_frag_info++;
5832  if (track->nb_frag_info >= track->frag_info_capacity) {
5833  unsigned new_capacity = track->nb_frag_info + MOV_FRAG_INFO_ALLOC_INCREMENT;
5834  if (av_reallocp_array(&track->frag_info,
5835  new_capacity,
5836  sizeof(*track->frag_info)))
5837  return AVERROR(ENOMEM);
5838  track->frag_info_capacity = new_capacity;
5839  }
5840  info = &track->frag_info[track->nb_frag_info - 1];
5841  info->offset = avio_tell(pb);
5842  info->size = size;
5843  // Try to recreate the original pts for the first packet
5844  // from the fields we have stored
5845  info->time = track->cluster[0].dts + track->cluster[0].cts;
5846  info->duration = track->end_pts -
5847  (track->cluster[0].dts + track->cluster[0].cts);
5848  // If the pts is less than zero, we will have trimmed
5849  // away parts of the media track using an edit list,
5850  // and the corresponding start presentation time is zero.
5851  if (info->time < 0) {
5852  info->duration += info->time;
5853  info->time = 0;
5854  }
5855  info->tfrf_offset = 0;
5856  mov_write_tfrf_tags(pb, mov, track);
5857  }
5858  return 0;
5859 }
5860 
5861 static void mov_prune_frag_info(MOVMuxContext *mov, int tracks, int max)
5862 {
5863  int i;
5864  for (i = 0; i < mov->nb_tracks; i++) {
5865  MOVTrack *track = &mov->tracks[i];
5866  if ((tracks >= 0 && i != tracks) || !track->entry)
5867  continue;
5868  if (track->nb_frag_info > max) {
5869  memmove(track->frag_info, track->frag_info + (track->nb_frag_info - max), max * sizeof(*track->frag_info));
5870  track->nb_frag_info = max;
5871  }
5872  }
5873 }
5874 
5875 static int mov_write_tfdt_tag(AVIOContext *pb, MOVTrack *track)
5876 {
5877  int64_t pos = avio_tell(pb);
5878 
5879  avio_wb32(pb, 0); /* size */
5880  ffio_wfourcc(pb, "tfdt");
5881  avio_w8(pb, 1); /* version */
5882  avio_wb24(pb, 0);
5883  avio_wb64(pb, track->cluster[0].dts - track->start_dts);
5884  return update_size(pb, pos);
5885 }
5886 
5888  MOVTrack *track, int64_t moof_offset,
5889  int moof_size)
5890 {
5891  int64_t pos = avio_tell(pb);
5892  int i, start = 0;
5893  avio_wb32(pb, 0); /* size placeholder */
5894  ffio_wfourcc(pb, "traf");
5895 
5896  mov_write_tfhd_tag(pb, mov, track, moof_offset);
5897  if (mov->mode != MODE_ISM)
5898  mov_write_tfdt_tag(pb, track);
5899  for (i = 1; i < track->entry; i++) {
5900  if (track->cluster[i].pos != track->cluster[i - 1].pos + track->cluster[i - 1].size) {
5901  mov_write_trun_tag(pb, mov, track, moof_size, start, i);
5902  start = i;
5903  }
5904  }
5905  mov_write_trun_tag(pb, mov, track, moof_size, start, track->entry);
5906  if (mov->mode == MODE_ISM) {
5907  mov_write_tfxd_tag(pb, track);
5908 
5909  if (mov->ism_lookahead) {
5910  int size = 16 + 4 + 1 + 16 * mov->ism_lookahead;
5911 
5912  if (track->nb_frag_info > 0) {
5913  MOVFragmentInfo *info = &track->frag_info[track->nb_frag_info - 1];
5914  if (!info->tfrf_offset)
5915  info->tfrf_offset = avio_tell(pb);
5916  }
5917  avio_wb32(pb, 8 + size);
5918  ffio_wfourcc(pb, "free");
5919  ffio_fill(pb, 0, size);
5920  }
5921  }
5922 
5923  if (track->cenc.aes_ctr && (mov->flags & FF_MOV_FLAG_FRAGMENT))
5924  ff_mov_cenc_write_stbl_atoms(&track->cenc, pb, moof_offset);
5925 
5926  return update_size(pb, pos);
5927 }
5928 
5930  int tracks, int moof_size)
5931 {
5932  int64_t pos = avio_tell(pb);
5933  int i;
5934 
5935  avio_wb32(pb, 0); /* size placeholder */
5936  ffio_wfourcc(pb, "moof");
5937  mov->first_trun = 1;
5938 
5939  mov_write_mfhd_tag(pb, mov);
5940  for (i = 0; i < mov->nb_tracks; i++) {
5941  MOVTrack *track = &mov->tracks[i];
5942  if (tracks >= 0 && i != tracks)
5943  continue;
5944  if (!track->entry)
5945  continue;
5946  if (track->cenc.aes_ctr && (mov->flags & FF_MOV_FLAG_FRAGMENT))
5947  mov_write_pssh_tag(pb, track->st);
5948  mov_write_traf_tag(pb, mov, track, pos, moof_size);
5949  }
5950 
5951  return update_size(pb, pos);
5952 }
5953 
5955  MOVTrack *track, int ref_size, int total_sidx_size)
5956 {
5957  int64_t pos = avio_tell(pb), offset_pos, end_pos;
5958  int64_t presentation_time, duration, offset;
5959  unsigned starts_with_SAP;
5960  int i, entries;
5961 
5962  if (track->entry) {
5963  entries = 1;
5964  presentation_time = track->cluster[0].dts + track->cluster[0].cts;
5965  duration = track->end_pts -
5966  (track->cluster[0].dts + track->cluster[0].cts);
5967  starts_with_SAP = track->cluster[0].flags & MOV_SYNC_SAMPLE;
5968 
5969  // pts<0 should be cut away using edts
5970  if (presentation_time < 0) {
5971  duration += presentation_time;
5972  presentation_time = 0;
5973  }
5974  } else {
5975  entries = track->nb_frag_info;
5976  if (entries <= 0)
5977  return 0;
5978  presentation_time = track->frag_info[0].time;
5979  }
5980 
5981  avio_wb32(pb, 0); /* size */
5982  ffio_wfourcc(pb, "sidx");
5983  avio_w8(pb, 1); /* version */
5984  avio_wb24(pb, 0);
5985  avio_wb32(pb, track->track_id); /* reference_ID */
5986  avio_wb32(pb, track->timescale); /* timescale */
5987  avio_wb64(pb, presentation_time); /* earliest_presentation_time */
5988  offset_pos = avio_tell(pb);
5989  avio_wb64(pb, 0); /* first_offset (offset to referenced moof) */
5990  avio_wb16(pb, 0); /* reserved */
5991 
5992  avio_wb16(pb, entries); /* reference_count */
5993  for (i = 0; i < entries; i++) {
5994  if (!track->entry) {
5995  if (i > 1 && track->frag_info[i].offset != track->frag_info[i - 1].offset + track->frag_info[i - 1].size) {
5996  av_log(NULL, AV_LOG_ERROR, "Non-consecutive fragments, writing incorrect sidx\n");
5997  }
5998  duration = track->frag_info[i].duration;
5999  ref_size = track->frag_info[i].size;
6000  starts_with_SAP = 1;
6001  }
6002  avio_wb32(pb, (0 << 31) | (ref_size & 0x7fffffff)); /* reference_type (0 = media) | referenced_size */
6003  avio_wb32(pb, duration); /* subsegment_duration */
6004  avio_wb32(pb, (starts_with_SAP << 31) | (0 << 28) | 0); /* starts_with_SAP | SAP_type | SAP_delta_time */
6005  }
6006 
6007  end_pos = avio_tell(pb);
6008  offset = pos + total_sidx_size - end_pos;
6009  avio_seek(pb, offset_pos, SEEK_SET);
6010  avio_wb64(pb, offset);
6011  avio_seek(pb, end_pos, SEEK_SET);
6012  return update_size(pb, pos);
6013 }
6014 
6016  int tracks, int ref_size)
6017 {
6018  int i, round, ret;
6019  AVIOContext *avio_buf;
6020  int total_size = 0;
6021  for (round = 0; round < 2; round++) {
6022  // First run one round to calculate the total size of all
6023  // sidx atoms.
6024  // This would be much simpler if we'd only write one sidx
6025  // atom, for the first track in the moof.
6026  if (round == 0) {
6027  if ((ret = ffio_open_null_buf(&avio_buf)) < 0)
6028  return ret;
6029  } else {
6030  avio_buf = pb;
6031  }
6032  for (i = 0; i < mov->nb_tracks; i++) {
6033  MOVTrack *track = &mov->tracks[i];
6034  if (tracks >= 0 && i != tracks)
6035  continue;
6036  // When writing a sidx for the full file, entry is 0, but
6037  // we want to include all tracks. ref_size is 0 in this case,
6038  // since we read it from frag_info instead.
6039  if (!track->entry && ref_size > 0)
6040  continue;
6041  total_size -= mov_write_sidx_tag(avio_buf, track, ref_size,
6042  total_size);
6043  }
6044  if (round == 0) {
6045  total_size = ffio_close_null_buf(avio_buf);
6046  if (total_size < 0)
6047  return total_size;
6048  }
6049  }
6050  return 0;
6051 }
6052 
6053 static int mov_write_prft_tag(AVIOContext *pb, MOVMuxContext *mov, int tracks)
6054 {
6055  int64_t pos = avio_tell(pb), pts_us, ntp_ts;
6056  MOVTrack *first_track;
6057  int flags = 24;
6058 
6059  /* PRFT should be associated with at most one track. So, choosing only the
6060  * first track. */
6061  if (tracks > 0)
6062  return 0;
6063  first_track = &(mov->tracks[0]);
6064 
6065  if (!first_track->entry) {
6066  av_log(mov->fc, AV_LOG_WARNING, "Unable to write PRFT, no entries in the track\n");
6067  return 0;
6068  }
6069 
6070  if (first_track->cluster[0].pts == AV_NOPTS_VALUE) {
6071  av_log(mov->fc, AV_LOG_WARNING, "Unable to write PRFT, first PTS is invalid\n");
6072  return 0;
6073  }
6074 
6075  if (mov->write_prft == MOV_PRFT_SRC_WALLCLOCK) {
6076  if (first_track->cluster[0].prft.wallclock) {
6077  /* Round the NTP time to whole milliseconds. */
6078  ntp_ts = ff_get_formatted_ntp_time((first_track->cluster[0].prft.wallclock / 1000) * 1000 +
6079  NTP_OFFSET_US);
6080  flags = first_track->cluster[0].prft.flags;
6081  } else
6083  } else if (mov->write_prft == MOV_PRFT_SRC_PTS) {
6084  pts_us = av_rescale_q(first_track->cluster[0].pts,
6085  first_track->st->time_base, AV_TIME_BASE_Q);
6086  ntp_ts = ff_get_formatted_ntp_time(pts_us + NTP_OFFSET_US);
6087  } else {
6088  av_log(mov->fc, AV_LOG_WARNING, "Unsupported PRFT box configuration: %d\n",
6089  mov->write_prft);
6090  return 0;
6091  }
6092 
6093  avio_wb32(pb, 0); // Size place holder
6094  ffio_wfourcc(pb, "prft"); // Type
6095  avio_w8(pb, 1); // Version
6096  avio_wb24(pb, flags); // Flags
6097  avio_wb32(pb, first_track->track_id); // reference track ID
6098  avio_wb64(pb, ntp_ts); // NTP time stamp
6099  avio_wb64(pb, first_track->cluster[0].pts); //media time
6100  return update_size(pb, pos);
6101 }
6102 
6103 static int mov_write_moof_tag(AVIOContext *pb, MOVMuxContext *mov, int tracks,
6104  int64_t mdat_size)
6105 {
6106  AVIOContext *avio_buf;
6107  int ret, moof_size;
6108 
6109  if ((ret = ffio_open_null_buf(&avio_buf)) < 0)
6110  return ret;
6111  mov_write_moof_tag_internal(avio_buf, mov, tracks, 0);
6112  moof_size = ffio_close_null_buf(avio_buf);
6113  if (moof_size < 0)
6114  return moof_size;
6115 
6116  if (mov->flags & FF_MOV_FLAG_DASH &&
6118  mov_write_sidx_tags(pb, mov, tracks, moof_size + 8 + mdat_size);
6119 
6120  if (mov->write_prft > MOV_PRFT_NONE && mov->write_prft < MOV_PRFT_NB)
6121  mov_write_prft_tag(pb, mov, tracks);
6122 
6123  if (mov->flags & FF_MOV_FLAG_GLOBAL_SIDX ||
6124  !(mov->flags & FF_MOV_FLAG_SKIP_TRAILER) ||
6125  mov->ism_lookahead) {
6126  if ((ret = mov_add_tfra_entries(pb, mov, tracks, moof_size + 8 + mdat_size)) < 0)
6127  return ret;
6128  if (!(mov->flags & FF_MOV_FLAG_GLOBAL_SIDX) &&
6130  mov_prune_frag_info(mov, tracks, mov->ism_lookahead + 1);
6131  }
6132  }
6133 
6134  return mov_write_moof_tag_internal(pb, mov, tracks, moof_size);
6135 }
6136 
6137 static int mov_write_tfra_tag(AVIOContext *pb, MOVTrack *track)
6138 {
6139  int64_t pos = avio_tell(pb);
6140  int i;
6141 
6142  avio_wb32(pb, 0); /* size placeholder */
6143  ffio_wfourcc(pb, "tfra");
6144  avio_w8(pb, 1); /* version */
6145  avio_wb24(pb, 0);
6146 
6147  avio_wb32(pb, track->track_id);
6148  avio_wb32(pb, 0); /* length of traf/trun/sample num */
6149  avio_wb32(pb, track->nb_frag_info);
6150  for (i = 0; i < track->nb_frag_info; i++) {
6151  avio_wb64(pb, track->frag_info[i].time);
6152  avio_wb64(pb, track->frag_info[i].offset + track->data_offset);
6153  avio_w8(pb, 1); /* traf number */
6154  avio_w8(pb, 1); /* trun number */
6155  avio_w8(pb, 1); /* sample number */
6156  }
6157 
6158  return update_size(pb, pos);
6159 }
6160 
6162 {
6163  AVIOContext *mfra_pb;
6164  int i, ret, sz;
6165  uint8_t *buf;
6166 
6167  ret = avio_open_dyn_buf(&mfra_pb);
6168  if (ret < 0)
6169  return ret;
6170 
6171  avio_wb32(mfra_pb, 0); /* size placeholder */
6172  ffio_wfourcc(mfra_pb, "mfra");
6173  /* An empty mfra atom is enough to indicate to the publishing point that
6174  * the stream has ended. */
6175  if (mov->flags & FF_MOV_FLAG_ISML)
6176  goto done_mfra;
6177 
6178  for (i = 0; i < mov->nb_tracks; i++) {
6179  MOVTrack *track = &mov->tracks[i];
6180  if (track->nb_frag_info)
6181  mov_write_tfra_tag(mfra_pb, track);
6182  }
6183 
6184  avio_wb32(mfra_pb, 16);
6185  ffio_wfourcc(mfra_pb, "mfro");
6186  avio_wb32(mfra_pb, 0); /* version + flags */
6187  avio_wb32(mfra_pb, avio_tell(mfra_pb) + 4);
6188 
6189 done_mfra:
6190 
6191  sz = update_size(mfra_pb, 0);
6192  ret = avio_get_dyn_buf(mfra_pb, &buf);
6193  avio_write(pb, buf, ret);
6194  ffio_free_dyn_buf(&mfra_pb);
6195 
6196  return sz;
6197 }
6198 
6200 {
6201  avio_wb32(pb, 8); // placeholder for extended size field (64 bit)
6202  ffio_wfourcc(pb, mov->mode == MODE_MOV ? "wide" : "free");
6203 
6204  mov->mdat_pos = avio_tell(pb);
6205  avio_wb32(pb, 0); /* size placeholder*/
6206  ffio_wfourcc(pb, "mdat");
6207  return 0;
6208 }
6209 
6211  int has_h264, int has_video, int write_minor)
6212 {
6213  MOVMuxContext *mov = s->priv_data;
6214  int minor = 0x200;
6215 
6216  if (mov->major_brand && strlen(mov->major_brand) >= 4)
6217  ffio_wfourcc(pb, mov->major_brand);
6218  else if (mov->mode == MODE_3GP) {
6219  ffio_wfourcc(pb, has_h264 ? "3gp6" : "3gp4");
6220  minor = has_h264 ? 0x100 : 0x200;
6221  } else if (mov->mode == MODE_AVIF) {
6222  ffio_wfourcc(pb, mov->is_animated_avif ? "avis" : "avif");
6223  minor = 0;
6224  } else if (mov->mode & MODE_3G2) {
6225  ffio_wfourcc(pb, has_h264 ? "3g2b" : "3g2a");
6226  minor = has_h264 ? 0x20000 : 0x10000;
6227  } else if (mov->mode == MODE_PSP)
6228  ffio_wfourcc(pb, "MSNV");
6229  else if (mov->mode == MODE_MP4 && mov->flags & FF_MOV_FLAG_FRAGMENT &&
6231  ffio_wfourcc(pb, "iso6"); // Required when using signed CTS offsets in trun boxes
6232  else if (mov->mode == MODE_MP4 && mov->flags & FF_MOV_FLAG_DEFAULT_BASE_MOOF)
6233  ffio_wfourcc(pb, "iso5"); // Required when using default-base-is-moof
6234  else if (mov->mode == MODE_MP4 && mov->flags & FF_MOV_FLAG_NEGATIVE_CTS_OFFSETS)
6235  ffio_wfourcc(pb, "iso4");
6236  else if (mov->mode == MODE_MP4)
6237  ffio_wfourcc(pb, "isom");
6238  else if (mov->mode == MODE_IPOD)
6239  ffio_wfourcc(pb, has_video ? "M4V ":"M4A ");
6240  else if (mov->mode == MODE_ISM)
6241  ffio_wfourcc(pb, "isml");
6242  else if (mov->mode == MODE_F4V)
6243  ffio_wfourcc(pb, "f4v ");
6244  else
6245  ffio_wfourcc(pb, "qt ");
6246 
6247  if (write_minor)
6248  avio_wb32(pb, minor);
6249 }
6250 
6252 {
6253  MOVMuxContext *mov = s->priv_data;
6254  int64_t pos = avio_tell(pb);
6255  int has_h264 = 0, has_av1 = 0, has_video = 0, has_dolby = 0, has_id3 = 0;
6256  int has_iamf = 0;
6257 
6258 #if CONFIG_IAMFENC
6259  for (int i = 0; i < s->nb_stream_groups; i++) {
6260  const AVStreamGroup *stg = s->stream_groups[i];
6261 
6264  has_iamf = 1;
6265  break;
6266  }
6267  }
6268 #endif
6269  for (int i = 0; i < mov->nb_streams; i++) {
6270  AVStream *st = mov->tracks[i].st;
6271  if (is_cover_image(st))
6272  continue;
6274  has_video = 1;
6275  if (st->codecpar->codec_id == AV_CODEC_ID_H264)
6276  has_h264 = 1;
6277  if (st->codecpar->codec_id == AV_CODEC_ID_AV1)
6278  has_av1 = 1;
6279  if (st->codecpar->codec_id == AV_CODEC_ID_AC3 ||
6285  has_dolby = 1;
6287  has_id3 = 1;
6288  }
6289 
6290  avio_wb32(pb, 0); /* size */
6291  ffio_wfourcc(pb, "ftyp");
6292 
6293  // Write major brand
6294  mov_write_ftyp_tag_internal(pb, s, has_h264, has_video, 1);
6295  // Write the major brand as the first compatible brand as well
6296  mov_write_ftyp_tag_internal(pb, s, has_h264, has_video, 0);
6297 
6298  // Write compatible brands, ensuring that we don't write the major brand as a
6299  // compatible brand a second time.
6300  if (mov->mode == MODE_ISM) {
6301  ffio_wfourcc(pb, "piff");
6302  } else if (mov->mode == MODE_AVIF) {
6303  const AVPixFmtDescriptor *pix_fmt_desc =
6304  av_pix_fmt_desc_get(s->streams[0]->codecpar->format);
6305  const int depth = pix_fmt_desc->comp[0].depth;
6306  if (mov->is_animated_avif) {
6307  // For animated AVIF, major brand is "avis". Add "avif" as a
6308  // compatible brand.
6309  ffio_wfourcc(pb, "avif");
6310  ffio_wfourcc(pb, "msf1");
6311  ffio_wfourcc(pb, "iso8");
6312  }
6313  ffio_wfourcc(pb, "mif1");
6314  ffio_wfourcc(pb, "miaf");
6315  if (depth == 8 || depth == 10) {
6316  // MA1B and MA1A brands are based on AV1 profile. Short hand for
6317  // computing that is based on chroma subsampling type. 420 chroma
6318  // subsampling is MA1B. 444 chroma subsampling is MA1A.
6319  if (!pix_fmt_desc->log2_chroma_w && !pix_fmt_desc->log2_chroma_h) {
6320  // 444 chroma subsampling.
6321  ffio_wfourcc(pb, "MA1A");
6322  } else {
6323  // 420 chroma subsampling.
6324  ffio_wfourcc(pb, "MA1B");
6325  }
6326  }
6327  } else if (mov->mode != MODE_MOV) {
6328  // We add tfdt atoms when fragmenting, signal this with the iso6 compatible
6329  // brand, if not already the major brand. This is compatible with users that
6330  // don't understand tfdt.
6331  if (mov->mode == MODE_MP4) {
6332  if (mov->flags & FF_MOV_FLAG_CMAF)
6333  ffio_wfourcc(pb, "cmfc");
6335  ffio_wfourcc(pb, "iso6");
6336  if (has_av1)
6337  ffio_wfourcc(pb, "av01");
6338  if (has_dolby)
6339  ffio_wfourcc(pb, "dby1");
6340  if (has_iamf)
6341  ffio_wfourcc(pb, "iamf");
6342  } else {
6343  if (mov->flags & FF_MOV_FLAG_FRAGMENT)
6344  ffio_wfourcc(pb, "iso6");
6346  ffio_wfourcc(pb, "iso5");
6347  else if (mov->flags & FF_MOV_FLAG_NEGATIVE_CTS_OFFSETS)
6348  ffio_wfourcc(pb, "iso4");
6349  }
6350  // Brands prior to iso5 can't be signaled when using default-base-is-moof
6351  if (!(mov->flags & FF_MOV_FLAG_DEFAULT_BASE_MOOF)) {
6352  // write isom for mp4 only if it it's not the major brand already.
6353  if (mov->mode != MODE_MP4 || mov->flags & FF_MOV_FLAG_NEGATIVE_CTS_OFFSETS)
6354  ffio_wfourcc(pb, "isom");
6355  ffio_wfourcc(pb, "iso2");
6356  if (has_h264)
6357  ffio_wfourcc(pb, "avc1");
6358  }
6359  }
6360 
6361  if (mov->mode == MODE_MP4)
6362  ffio_wfourcc(pb, "mp41");
6363 
6364  if (mov->flags & FF_MOV_FLAG_DASH && mov->flags & FF_MOV_FLAG_GLOBAL_SIDX)
6365  ffio_wfourcc(pb, "dash");
6366 
6367  if (has_id3)
6368  ffio_wfourcc(pb, "aid3");
6369 
6370  return update_size(pb, pos);
6371 }
6372 
6374 {
6375  AVStream *video_st = s->streams[0];
6376  AVCodecParameters *video_par = s->streams[0]->codecpar;
6377  AVCodecParameters *audio_par = s->streams[1]->codecpar;
6378  int audio_rate = audio_par->sample_rate;
6379  int64_t frame_rate = video_st->avg_frame_rate.den ?
6381  0;
6382  int audio_kbitrate = audio_par->bit_rate / 1000;
6383  int video_kbitrate = FFMIN(video_par->bit_rate / 1000, 800 - audio_kbitrate);
6384 
6385  if (frame_rate < 0 || frame_rate > INT32_MAX) {
6386  av_log(s, AV_LOG_ERROR, "Frame rate %f outside supported range\n", frame_rate / (double)0x10000);
6387  return AVERROR(EINVAL);
6388  }
6389 
6390  avio_wb32(pb, 0x94); /* size */
6391  ffio_wfourcc(pb, "uuid");
6392  ffio_wfourcc(pb, "PROF");
6393 
6394  avio_wb32(pb, 0x21d24fce); /* 96 bit UUID */
6395  avio_wb32(pb, 0xbb88695c);
6396  avio_wb32(pb, 0xfac9c740);
6397 
6398  avio_wb32(pb, 0x0); /* ? */
6399  avio_wb32(pb, 0x3); /* 3 sections ? */
6400 
6401  avio_wb32(pb, 0x14); /* size */
6402  ffio_wfourcc(pb, "FPRF");
6403  avio_wb32(pb, 0x0); /* ? */
6404  avio_wb32(pb, 0x0); /* ? */
6405  avio_wb32(pb, 0x0); /* ? */
6406 
6407  avio_wb32(pb, 0x2c); /* size */
6408  ffio_wfourcc(pb, "APRF"); /* audio */
6409  avio_wb32(pb, 0x0);
6410  avio_wb32(pb, 0x2); /* TrackID */
6411  ffio_wfourcc(pb, "mp4a");
6412  avio_wb32(pb, 0x20f);
6413  avio_wb32(pb, 0x0);
6414  avio_wb32(pb, audio_kbitrate);
6415  avio_wb32(pb, audio_kbitrate);
6416  avio_wb32(pb, audio_rate);
6417  avio_wb32(pb, audio_par->ch_layout.nb_channels);
6418 
6419  avio_wb32(pb, 0x34); /* size */
6420  ffio_wfourcc(pb, "VPRF"); /* video */
6421  avio_wb32(pb, 0x0);
6422  avio_wb32(pb, 0x1); /* TrackID */
6423  if (video_par->codec_id == AV_CODEC_ID_H264) {
6424  ffio_wfourcc(pb, "avc1");
6425  avio_wb16(pb, 0x014D);
6426  avio_wb16(pb, 0x0015);
6427  } else {
6428  ffio_wfourcc(pb, "mp4v");
6429  avio_wb16(pb, 0x0000);
6430  avio_wb16(pb, 0x0103);
6431  }
6432  avio_wb32(pb, 0x0);
6433  avio_wb32(pb, video_kbitrate);
6434  avio_wb32(pb, video_kbitrate);
6435  avio_wb32(pb, frame_rate);
6436  avio_wb32(pb, frame_rate);
6437  avio_wb16(pb, video_par->width);
6438  avio_wb16(pb, video_par->height);
6439  avio_wb32(pb, 0x010001); /* ? */
6440 
6441  return 0;
6442 }
6443 
6445 {
6446  MOVMuxContext *mov = s->priv_data;
6447  int i;
6448 
6449  mov_write_ftyp_tag(pb,s);
6450  if (mov->mode == MODE_PSP) {
6451  int video_streams_nb = 0, audio_streams_nb = 0, other_streams_nb = 0;
6452  for (i = 0; i < mov->nb_streams; i++) {
6453  AVStream *st = mov->tracks[i].st;
6454  if (is_cover_image(st))
6455  continue;
6457  video_streams_nb++;
6458  else if (st->codecpar->codec_type == AVMEDIA_TYPE_AUDIO)
6459  audio_streams_nb++;
6460  else
6461  other_streams_nb++;
6462  }
6463 
6464  if (video_streams_nb != 1 || audio_streams_nb != 1 || other_streams_nb) {
6465  av_log(s, AV_LOG_ERROR, "PSP mode need one video and one audio stream\n");
6466  return AVERROR(EINVAL);
6467  }
6468  return mov_write_uuidprof_tag(pb, s);
6469  }
6470  return 0;
6471 }
6472 
6473 static int mov_parse_mpeg2_frame(AVPacket *pkt, uint32_t *flags)
6474 {
6475  uint32_t c = -1;
6476  int i, closed_gop = 0;
6477 
6478  for (i = 0; i < pkt->size - 4; i++) {
6479  c = (c << 8) + pkt->data[i];
6480  if (c == 0x1b8) { // gop
6481  closed_gop = pkt->data[i + 4] >> 6 & 0x01;
6482  } else if (c == 0x100) { // pic
6483  int temp_ref = (pkt->data[i + 1] << 2) | (pkt->data[i + 2] >> 6);
6484  if (!temp_ref || closed_gop) // I picture is not reordered
6486  else
6488  break;
6489  }
6490  }
6491  return 0;
6492 }
6493 
6495 {
6496  const uint8_t *start, *next, *end = pkt->data + pkt->size;
6497  int seq = 0, entry = 0;
6498  int key = pkt->flags & AV_PKT_FLAG_KEY;
6499  start = find_next_marker(pkt->data, end);
6500  for (next = start; next < end; start = next) {
6501  next = find_next_marker(start + 4, end);
6502  switch (AV_RB32(start)) {
6503  case VC1_CODE_SEQHDR:
6504  seq = 1;
6505  break;
6506  case VC1_CODE_ENTRYPOINT:
6507  entry = 1;
6508  break;
6509  case VC1_CODE_SLICE:
6510  trk->vc1_info.slices = 1;
6511  break;
6512  }
6513  }
6514  if (!trk->entry && trk->vc1_info.first_packet_seen)
6515  trk->vc1_info.first_frag_written = 1;
6516  if (!trk->entry && !trk->vc1_info.first_frag_written) {
6517  /* First packet in first fragment */
6518  trk->vc1_info.first_packet_seq = seq;
6520  trk->vc1_info.first_packet_seen = 1;
6521  } else if ((seq && !trk->vc1_info.packet_seq) ||
6522  (entry && !trk->vc1_info.packet_entry)) {
6523  int i;
6524  for (i = 0; i < trk->entry; i++)
6525  trk->cluster[i].flags &= ~MOV_SYNC_SAMPLE;
6526  trk->has_keyframes = 0;
6527  if (seq)
6528  trk->vc1_info.packet_seq = 1;
6529  if (entry)
6530  trk->vc1_info.packet_entry = 1;
6531  if (!trk->vc1_info.first_frag_written) {
6532  /* First fragment */
6533  if ((!seq || trk->vc1_info.first_packet_seq) &&
6534  (!entry || trk->vc1_info.first_packet_entry)) {
6535  /* First packet had the same headers as this one, readd the
6536  * sync sample flag. */
6537  trk->cluster[0].flags |= MOV_SYNC_SAMPLE;
6538  trk->has_keyframes = 1;
6539  }
6540  }
6541  }
6542  if (trk->vc1_info.packet_seq && trk->vc1_info.packet_entry)
6543  key = seq && entry;
6544  else if (trk->vc1_info.packet_seq)
6545  key = seq;
6546  else if (trk->vc1_info.packet_entry)
6547  key = entry;
6548  if (key) {
6549  trk->cluster[trk->entry].flags |= MOV_SYNC_SAMPLE;
6550  trk->has_keyframes++;
6551  }
6552 }
6553 
6555 {
6556  int length;
6557 
6558  if (pkt->size < 8)
6559  return;
6560 
6561  length = (AV_RB16(pkt->data) & 0xFFF) * 2;
6562  if (length < 8 || length > pkt->size)
6563  return;
6564 
6565  if (AV_RB32(pkt->data + 4) == 0xF8726FBA) {
6566  trk->cluster[trk->entry].flags |= MOV_SYNC_SAMPLE;
6567  trk->has_keyframes++;
6568  }
6569 
6570  return;
6571 }
6572 
6574 {
6575  MOVMuxContext *mov = s->priv_data;
6576  int ret, buf_size;
6577  uint8_t *buf;
6578  int i, offset;
6579 
6580  if (!track->mdat_buf)
6581  return 0;
6582  if (!mov->mdat_buf) {
6583  if ((ret = avio_open_dyn_buf(&mov->mdat_buf)) < 0)
6584  return ret;
6585  }
6586  buf_size = avio_get_dyn_buf(track->mdat_buf, &buf);
6587 
6588  offset = avio_tell(mov->mdat_buf);
6589  avio_write(mov->mdat_buf, buf, buf_size);
6590  ffio_reset_dyn_buf(track->mdat_buf);
6591 
6592  for (i = track->entries_flushed; i < track->entry; i++)
6593  track->cluster[i].pos += offset;
6594  track->entries_flushed = track->entry;
6595  return 0;
6596 }
6597 
6599 {
6600  MOVMuxContext *mov = s->priv_data;
6601  AVPacket *squashed_packet = mov->pkt;
6602  int ret = AVERROR_BUG;
6603 
6604  switch (track->st->codecpar->codec_id) {
6605  case AV_CODEC_ID_TTML: {
6606  int had_packets = !!track->squashed_packet_queue.head;
6607 
6608  if ((ret = ff_mov_generate_squashed_ttml_packet(s, track, squashed_packet)) < 0) {
6609  goto finish_squash;
6610  }
6611 
6612  // We have generated a padding packet (no actual input packets in
6613  // queue) and its duration is zero. Skipping writing it.
6614  if (!had_packets && squashed_packet->duration == 0) {
6615  goto finish_squash;
6616  }
6617 
6618  track->end_reliable = 1;
6619  break;
6620  }
6621  default:
6622  ret = AVERROR(EINVAL);
6623  goto finish_squash;
6624  }
6625 
6626  squashed_packet->stream_index = track->st->index;
6627 
6628  ret = mov_write_single_packet(s, squashed_packet);
6629 
6630 finish_squash:
6631  av_packet_unref(squashed_packet);
6632 
6633  return ret;
6634 }
6635 
6637 {
6638  MOVMuxContext *mov = s->priv_data;
6639 
6640  for (int i = 0; i < mov->nb_streams; i++) {
6641  MOVTrack *track = &mov->tracks[i];
6642  int ret = AVERROR_BUG;
6643 
6644  if (track->squash_fragment_samples_to_one && !track->entry) {
6645  if ((ret = mov_write_squashed_packet(s, track)) < 0) {
6647  "Failed to write squashed packet for %s stream with "
6648  "index %d and track id %d. Error: %s\n",
6650  track->st->index, track->track_id,
6651  av_err2str(ret));
6652  return ret;
6653  }
6654  }
6655  }
6656 
6657  return 0;
6658 }
6659 
6661  int64_t ref_pos)
6662 {
6663  int i;
6664  if (!track->entry)
6665  return 0;
6666  if (mov->flags & FF_MOV_FLAG_HYBRID_FRAGMENTED) {
6667  for (i = 0; i < track->entry; i++)
6668  track->cluster[i].pos += ref_pos + track->data_offset;
6669  if (track->cluster_written == 0) {
6670  // First flush. Chunking for this fragment may already have been
6671  // done, either if we didn't use empty_moov, or if we did use
6672  // delay_moov. In either case, reset chunking here.
6673  for (i = 0; i < track->entry; i++) {
6674  track->cluster[i].chunkNum = 0;
6675  track->cluster[i].samples_in_chunk = track->cluster[i].entries;
6676  }
6677  }
6678  if (av_reallocp_array(&track->cluster_written,
6679  track->entry_written + track->entry,
6680  sizeof(*track->cluster)))
6681  return AVERROR(ENOMEM);
6682  memcpy(&track->cluster_written[track->entry_written],
6683  track->cluster, track->entry * sizeof(*track->cluster));
6684  track->entry_written += track->entry;
6685  }
6686  track->entry = 0;
6687  track->entries_flushed = 0;
6688  track->end_reliable = 0;
6689  return 0;
6690 }
6691 
6692 static int mov_flush_fragment(AVFormatContext *s, int force)
6693 {
6694  MOVMuxContext *mov = s->priv_data;
6695  int i, first_track = -1;
6696  int64_t mdat_size = 0, mdat_start = 0;
6697  int ret;
6698  int has_video = 0, starts_with_key = 0, first_video_track = 1;
6699 
6700  if (!(mov->flags & FF_MOV_FLAG_FRAGMENT))
6701  return 0;
6702 
6703  // Check if we have any tracks that require squashing.
6704  // In that case, we'll have to write the packet here.
6705  if ((ret = mov_write_squashed_packets(s)) < 0)
6706  return ret;
6707 
6708  // Try to fill in the duration of the last packet in each stream
6709  // from queued packets in the interleave queues. If the flushing
6710  // of fragments was triggered automatically by an AVPacket, we
6711  // already have reliable info for the end of that track, but other
6712  // tracks may need to be filled in.
6713  for (i = 0; i < mov->nb_streams; i++) {
6714  MOVTrack *track = &mov->tracks[i];
6715  if (!track->end_reliable) {
6716  const AVPacket *pkt = ff_interleaved_peek(s, i);
6717  if (pkt) {
6718  int64_t offset, dts, pts;
6720  pts = pkt->pts + offset;
6721  dts = pkt->dts + offset;
6722  if (track->dts_shift != AV_NOPTS_VALUE)
6723  dts += track->dts_shift;
6724  track->track_duration = dts - track->start_dts;
6725  if (pts != AV_NOPTS_VALUE)
6726  track->end_pts = pts;
6727  else
6728  track->end_pts = dts;
6729  if (!(pkt->flags & AV_PKT_FLAG_DISCARD))
6730  track->elst_end_pts = track->end_pts;
6731  }
6732  }
6733  }
6734 
6735  for (i = 0; i < mov->nb_tracks; i++) {
6736  MOVTrack *track = &mov->tracks[i];
6737  if (track->entry <= 1)
6738  continue;
6739  // Sample durations are calculated as the diff of dts values,
6740  // but for the last sample in a fragment, we don't know the dts
6741  // of the first sample in the next fragment, so we have to rely
6742  // on what was set as duration in the AVPacket. Not all callers
6743  // set this though, so we might want to replace it with an
6744  // estimate if it currently is zero.
6745  if (get_cluster_duration(track, track->entry - 1) != 0)
6746  continue;
6747  // Use the duration (i.e. dts diff) of the second last sample for
6748  // the last one. This is a wild guess (and fatal if it turns out
6749  // to be too long), but probably the best we can do - having a zero
6750  // duration is bad as well.
6751  track->track_duration += get_cluster_duration(track, track->entry - 2);
6752  track->end_pts += get_cluster_duration(track, track->entry - 2);
6753  if (!mov->missing_duration_warned) {
6755  "Estimating the duration of the last packet in a "
6756  "fragment, consider setting the duration field in "
6757  "AVPacket instead.\n");
6758  mov->missing_duration_warned = 1;
6759  }
6760  }
6761 
6762  if (!mov->moov_written) {
6763  int64_t pos = avio_tell(s->pb);
6764  uint8_t *buf;
6765  int buf_size, moov_size;
6766 
6767  for (i = 0; i < mov->nb_tracks; i++)
6768  if (!mov->tracks[i].entry && !is_cover_image(mov->tracks[i].st))
6769  break;
6770  /* Don't write the initial moov unless all tracks have data */
6771  if (i < mov->nb_tracks && !force)
6772  return 0;
6773 
6774  moov_size = get_moov_size(s);
6775  for (i = 0; i < mov->nb_tracks; i++)
6776  mov->tracks[i].data_offset = pos + moov_size + 8;
6777 
6779  if (mov->flags & FF_MOV_FLAG_DELAY_MOOV &&
6782  if ((ret = mov_write_moov_tag(s->pb, mov, s)) < 0)
6783  return ret;
6784 
6785  if (mov->flags & FF_MOV_FLAG_DELAY_MOOV) {
6786  if (mov->flags & FF_MOV_FLAG_GLOBAL_SIDX)
6787  mov->reserved_header_pos = avio_tell(s->pb);
6789  mov->moov_written = 1;
6790  return 0;
6791  }
6792 
6793  buf_size = avio_get_dyn_buf(mov->mdat_buf, &buf);
6794  avio_wb32(s->pb, buf_size + 8);
6795  ffio_wfourcc(s->pb, "mdat");
6796  avio_write(s->pb, buf, buf_size);
6798 
6799  if (mov->flags & FF_MOV_FLAG_GLOBAL_SIDX)
6800  mov->reserved_header_pos = avio_tell(s->pb);
6801 
6802  mov->moov_written = 1;
6803  mov->mdat_size = 0;
6804  for (i = 0; i < mov->nb_tracks; i++)
6805  mov_finish_fragment(mov, &mov->tracks[i], 0);
6807  return 0;
6808  }
6809 
6810  if (mov->frag_interleave) {
6811  for (i = 0; i < mov->nb_tracks; i++) {
6812  MOVTrack *track = &mov->tracks[i];
6813  int ret;
6814  if ((ret = mov_flush_fragment_interleaving(s, track)) < 0)
6815  return ret;
6816  }
6817 
6818  if (!mov->mdat_buf)
6819  return 0;
6820  mdat_size = avio_tell(mov->mdat_buf);
6821  }
6822 
6823  for (i = 0; i < mov->nb_tracks; i++) {
6824  MOVTrack *track = &mov->tracks[i];
6825  if (mov->flags & FF_MOV_FLAG_SEPARATE_MOOF || mov->frag_interleave)
6826  track->data_offset = 0;
6827  else
6828  track->data_offset = mdat_size;
6829  if (track->par->codec_type == AVMEDIA_TYPE_VIDEO) {
6830  has_video = 1;
6831  if (first_video_track) {
6832  if (track->entry)
6833  starts_with_key = track->cluster[0].flags & MOV_SYNC_SAMPLE;
6834  first_video_track = 0;
6835  }
6836  }
6837  if (!track->entry)
6838  continue;
6839  if (track->mdat_buf)
6840  mdat_size += avio_tell(track->mdat_buf);
6841  if (first_track < 0)
6842  first_track = i;
6843  }
6844 
6845  if (!mdat_size)
6846  return 0;
6847 
6848  avio_write_marker(s->pb,
6849  av_rescale(mov->tracks[first_track].cluster[0].dts, AV_TIME_BASE, mov->tracks[first_track].timescale),
6850  (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);
6851 
6852  for (i = first_track; i < mov->nb_tracks; i++) {
6853  MOVTrack *track = &mov->tracks[i];
6854  int buf_size, write_moof = 1, moof_tracks = -1;
6855  uint8_t *buf;
6856 
6857  if (!track->entry)
6858  continue;
6859  if (mov->flags & FF_MOV_FLAG_SEPARATE_MOOF) {
6860  mdat_size = avio_tell(track->mdat_buf);
6861  moof_tracks = i;
6862  } else {
6863  write_moof = i == first_track;
6864  }
6865 
6866  if (write_moof) {
6868 
6869  mov_write_moof_tag(s->pb, mov, moof_tracks, mdat_size);
6870  mov->fragments++;
6871 
6872  if (track->cenc.aes_ctr)
6873  ff_mov_cenc_flush(&track->cenc);
6874 
6875  avio_wb32(s->pb, mdat_size + 8);
6876  ffio_wfourcc(s->pb, "mdat");
6877  mdat_start = avio_tell(s->pb);
6878  }
6879 
6880  mov_finish_fragment(mov, &mov->tracks[i], mdat_start);
6881  if (!mov->frag_interleave) {
6882  if (!track->mdat_buf)
6883  continue;
6884  buf_size = avio_get_dyn_buf(track->mdat_buf, &buf);
6885  avio_write(s->pb, buf, buf_size);
6886  ffio_reset_dyn_buf(track->mdat_buf);
6887  } else {
6888  if (!mov->mdat_buf)
6889  continue;
6890  buf_size = avio_get_dyn_buf(mov->mdat_buf, &buf);
6891  avio_write(s->pb, buf, buf_size);
6893  }
6894  }
6895 
6896  mov->mdat_size = 0;
6897 
6899  return 0;
6900 }
6901 
6903 {
6904  MOVMuxContext *mov = s->priv_data;
6905  int had_moov = mov->moov_written;
6906  int ret = mov_flush_fragment(s, force);
6907  if (ret < 0)
6908  return ret;
6909  // If using delay_moov, the first flush only wrote the moov,
6910  // not the actual moof+mdat pair, thus flush once again.
6911  if (!had_moov && mov->flags & FF_MOV_FLAG_DELAY_MOOV)
6912  ret = mov_flush_fragment(s, force);
6913  return ret;
6914 }
6915 
6917 {
6918  int64_t ref;
6919  uint64_t duration;
6920 
6921  if (trk->entry) {
6922  ref = trk->cluster[trk->entry - 1].dts;
6923  } else if ( trk->start_dts != AV_NOPTS_VALUE
6924  && !trk->frag_discont) {
6925  ref = trk->start_dts + trk->track_duration;
6926  } else
6927  ref = pkt->dts; // Skip tests for the first packet
6928 
6929  if (trk->dts_shift != AV_NOPTS_VALUE) {
6930  /* With negative CTS offsets we have set an offset to the DTS,
6931  * reverse this for the check. */
6932  ref -= trk->dts_shift;
6933  }
6934 
6935  duration = pkt->dts - ref;
6936  if (pkt->dts < ref || duration >= INT_MAX) {
6937  av_log(s, AV_LOG_WARNING, "Packet duration: %"PRId64" / dts: %"PRId64" in stream %d is out of range\n",
6939 
6940  pkt->dts = ref + 1;
6941  pkt->pts = AV_NOPTS_VALUE;
6942  }
6943 
6944  if (pkt->duration < 0 || pkt->duration > INT_MAX) {
6945  av_log(s, AV_LOG_ERROR, "Application provided duration: %"PRId64" in stream %d is invalid\n", pkt->duration, pkt->stream_index);
6946  return AVERROR(EINVAL);
6947  }
6948  return 0;
6949 }
6950 
6952 {
6953  MOVMuxContext *mov = s->priv_data;
6954  AVIOContext *pb = s->pb;
6955  MOVTrack *trk;
6956  AVCodecParameters *par;
6958  unsigned int samples_in_chunk = 0;
6959  int64_t duration;
6960  int size = pkt->size, ret = 0, offset = 0;
6961  size_t prft_size;
6962  uint8_t *reformatted_data = NULL;
6963 
6964  if (pkt->stream_index < s->nb_streams)
6965  trk = s->streams[pkt->stream_index]->priv_data;
6966  else // Timecode or chapter
6967  trk = &mov->tracks[pkt->stream_index];
6968  par = trk->par;
6969 
6970  ret = check_pkt(s, trk, pkt);
6971  if (ret < 0)
6972  return ret;
6973 
6974  if (pkt->pts != AV_NOPTS_VALUE &&
6975  (uint64_t)pkt->dts - pkt->pts != (int32_t)((uint64_t)pkt->dts - pkt->pts)) {
6976  av_log(s, AV_LOG_WARNING, "pts/dts pair unsupported\n");
6977  return AVERROR_PATCHWELCOME;
6978  }
6979 
6980  if (mov->flags & FF_MOV_FLAG_FRAGMENT || mov->mode == MODE_AVIF) {
6981  int ret;
6982  if (mov->moov_written || mov->flags & FF_MOV_FLAG_EMPTY_MOOV) {
6983  if (mov->frag_interleave && mov->fragments > 0) {
6984  if (trk->entry - trk->entries_flushed >= mov->frag_interleave) {
6985  if ((ret = mov_flush_fragment_interleaving(s, trk)) < 0)
6986  return ret;
6987  }
6988  }
6989 
6990  if (!trk->mdat_buf) {
6991  if ((ret = avio_open_dyn_buf(&trk->mdat_buf)) < 0)
6992  return ret;
6993  }
6994  pb = trk->mdat_buf;
6995  } else {
6996  if (!mov->mdat_buf) {
6997  if ((ret = avio_open_dyn_buf(&mov->mdat_buf)) < 0)
6998  return ret;
6999  }
7000  pb = mov->mdat_buf;
7001  }
7002  }
7003 
7004  if (par->codec_id == AV_CODEC_ID_AMR_NB) {
7005  /* We must find out how many AMR blocks there are in one packet */
7006  static const uint16_t packed_size[16] =
7007  {13, 14, 16, 18, 20, 21, 27, 32, 6, 0, 0, 0, 0, 0, 0, 1};
7008  int len = 0;
7009 
7010  while (len < size && samples_in_chunk < 100) {
7011  len += packed_size[(pkt->data[len] >> 3) & 0x0F];
7012  samples_in_chunk++;
7013  }
7014  if (samples_in_chunk > 1) {
7015  av_log(s, AV_LOG_ERROR, "fatal error, input is not a single packet, implement a AVParser for it\n");
7016  return -1;
7017  }
7018  } else if (par->codec_id == AV_CODEC_ID_ADPCM_MS ||
7020  samples_in_chunk = trk->par->frame_size;
7021  } else if (trk->sample_size)
7022  samples_in_chunk = size / trk->sample_size;
7023  else
7024  samples_in_chunk = 1;
7025 
7026  if (samples_in_chunk < 1) {
7027  av_log(s, AV_LOG_ERROR, "fatal error, input packet contains no samples\n");
7028  return AVERROR_PATCHWELCOME;
7029  }
7030 
7031  /* copy extradata if it exists */
7032  if (trk->extradata_size[0] == 0 && par->extradata_size > 0 &&
7033  !TAG_IS_AVCI(trk->tag) &&
7034  (par->codec_id != AV_CODEC_ID_DNXHD)) {
7035  trk->extradata[0] = av_memdup(par->extradata, par->extradata_size);
7036  if (!trk->extradata[0]) {
7037  ret = AVERROR(ENOMEM);
7038  goto err;
7039  }
7040  trk->extradata_size[0] = par->extradata_size;
7041  }
7042 
7043  if ((par->codec_id == AV_CODEC_ID_DNXHD ||
7044  par->codec_id == AV_CODEC_ID_H264 ||
7045  par->codec_id == AV_CODEC_ID_HEVC ||
7046  par->codec_id == AV_CODEC_ID_VVC ||
7047  par->codec_id == AV_CODEC_ID_VP9 ||
7048  par->codec_id == AV_CODEC_ID_EVC ||
7049  par->codec_id == AV_CODEC_ID_LCEVC ||
7050  par->codec_id == AV_CODEC_ID_TRUEHD) && !trk->extradata_size[0] &&
7051  !TAG_IS_AVCI(trk->tag)) {
7052  /* copy frame to create needed atoms */
7053  trk->extradata_size[0] = size;
7055  if (!trk->extradata[0]) {
7056  ret = AVERROR(ENOMEM);
7057  goto err;
7058  }
7059  memcpy(trk->extradata[0], pkt->data, size);
7060  memset(trk->extradata[0] + size, 0, AV_INPUT_BUFFER_PADDING_SIZE);
7061  }
7062 
7064  if (pkt->size && sd && sd->size > 0) {
7065  int i;
7066  for (i = 0; i < trk->stsd_count; i++) {
7067  if (trk->extradata_size[i] == sd->size && !memcmp(trk->extradata[i], sd->data, sd->size))
7068  break;
7069  }
7070 
7071  if (i < trk->stsd_count)
7072  trk->last_stsd_index = i;
7073  else if (trk->stsd_count <= INT_MAX - 1) {
7074  int new_count = trk->stsd_count + 1;
7075  uint8_t **extradata = av_realloc_array(trk->extradata, new_count, sizeof(*trk->extradata));
7076  if (!extradata)
7077  return AVERROR(ENOMEM);
7078  trk->extradata = extradata;
7079 
7080  int *extradata_size = av_realloc_array(trk->extradata_size, new_count, sizeof(*trk->extradata_size));
7081  if (!extradata_size)
7082  return AVERROR(ENOMEM);
7083  trk->extradata_size = extradata_size;
7084 
7085  trk->extradata[trk->stsd_count] = av_memdup(sd->data, sd->size);
7086  if (!trk->extradata[trk->stsd_count])
7087  return AVERROR(ENOMEM);
7088 
7089  trk->extradata_size[trk->stsd_count] = sd->size;
7090  trk->last_stsd_index = trk->stsd_count;
7091  trk->stsd_count = new_count;
7092  } else
7093  return AVERROR(ENOMEM);
7094  }
7095 
7096  if (par->codec_id == AV_CODEC_ID_AAC && pkt->size > 2 &&
7097  (AV_RB16(pkt->data) & 0xfff0) == 0xfff0) {
7098  if (!trk->st->nb_frames) {
7099  av_log(s, AV_LOG_ERROR, "Malformed AAC bitstream detected: "
7100  "use the audio bitstream filter 'aac_adtstoasc' to fix it "
7101  "('-bsf:a aac_adtstoasc' option with ffmpeg)\n");
7102  return -1;
7103  }
7104  av_log(s, AV_LOG_WARNING, "aac bitstream error\n");
7105  }
7106  if (par->codec_id == AV_CODEC_ID_H264 && trk->extradata_size[trk->last_stsd_index] > 0 &&
7107  *(uint8_t *)trk->extradata[trk->last_stsd_index] != 1 && !TAG_IS_AVCI(trk->tag)) {
7108  /* from x264 or from bytestream H.264 */
7109  /* NAL reformatting needed */
7110  if (trk->hint_track >= 0 && trk->hint_track < mov->nb_tracks) {
7111  ret = ff_nal_parse_units_buf(pkt->data, &reformatted_data,
7112  &size);
7113  if (ret < 0)
7114  return ret;
7115  avio_write(pb, reformatted_data, size);
7116  } else {
7117  if (trk->cenc.aes_ctr) {
7119  if (size < 0) {
7120  ret = size;
7121  goto err;
7122  }
7123  } else {
7124  size = ff_nal_parse_units(pb, pkt->data, pkt->size);
7125  }
7126  }
7127  } else if (par->codec_id == AV_CODEC_ID_HEVC && trk->extradata_size[trk->last_stsd_index] > 6 &&
7128  (AV_RB24(trk->extradata[trk->last_stsd_index]) == 1 || AV_RB32(trk->extradata[trk->last_stsd_index]) == 1)) {
7129  /* extradata is Annex B, assume the bitstream is too and convert it */
7130  int filter_ps = (trk->tag == MKTAG('h','v','c','1'));
7131  if (trk->hint_track >= 0 && trk->hint_track < mov->nb_tracks) {
7132  ret = ff_hevc_annexb2mp4_buf(pkt->data, &reformatted_data,
7133  &size, filter_ps, NULL);
7134  if (ret < 0)
7135  return ret;
7136  avio_write(pb, reformatted_data, size);
7137  } else {
7138  if (trk->cenc.aes_ctr) {
7140  if (size < 0) {
7141  ret = size;
7142  goto err;
7143  }
7144  } else {
7145  size = ff_hevc_annexb2mp4(pb, pkt->data, pkt->size, filter_ps, NULL);
7146  }
7147  }
7148  } else if (par->codec_id == AV_CODEC_ID_VVC && trk->extradata_size[trk->last_stsd_index] > 6 &&
7149  (AV_RB24(trk->extradata[trk->last_stsd_index]) == 1 || AV_RB32(trk->extradata[trk->last_stsd_index]) == 1)) {
7150  /* extradata is Annex B, assume the bitstream is too and convert it */
7151  if (trk->hint_track >= 0 && trk->hint_track < mov->nb_tracks) {
7152  ret = ff_vvc_annexb2mp4_buf(pkt->data, &reformatted_data,
7153  &size, 0, NULL);
7154  if (ret < 0)
7155  return ret;
7156  avio_write(pb, reformatted_data, size);
7157  } else {
7158  size = ff_vvc_annexb2mp4(pb, pkt->data, pkt->size, 0, NULL);
7159  }
7160  } else if (par->codec_id == AV_CODEC_ID_LCEVC && trk->extradata_size[trk->last_stsd_index] > 0 &&
7161  *(uint8_t *)trk->extradata[trk->last_stsd_index] != 1) {
7162  /* extradata is Annex B, assume the bitstream is too and convert it */
7163  if (trk->hint_track >= 0 && trk->hint_track < mov->nb_tracks) {
7164  ret = ff_nal_parse_units_buf(pkt->data, &reformatted_data, &size);
7165  if (ret < 0)
7166  return ret;
7167  avio_write(pb, reformatted_data, size);
7168  } else {
7169  if (trk->cenc.aes_ctr) {
7171  if (size < 0) {
7172  ret = size;
7173  goto err;
7174  }
7175  } else {
7176  size = ff_nal_parse_units(pb, pkt->data, pkt->size);
7177  }
7178  }
7179  } else if (par->codec_id == AV_CODEC_ID_AV1 && !trk->cenc.aes_ctr) {
7180  if (trk->hint_track >= 0 && trk->hint_track < mov->nb_tracks) {
7181  ret = ff_av1_filter_obus_buf(pkt->data, &reformatted_data,
7182  &size, &offset);
7183  if (ret < 0)
7184  return ret;
7185  avio_write(pb, reformatted_data, size);
7186  } else {
7187  size = ff_av1_filter_obus(pb, pkt->data, pkt->size);
7188  if (trk->mode == MODE_AVIF && !mov->avif_extent_length[pkt->stream_index]) {
7190  }
7191  }
7192 
7193  } else if (par->codec_id == AV_CODEC_ID_AC3 ||
7194  par->codec_id == AV_CODEC_ID_EAC3) {
7195  size = handle_eac3(mov, pkt, trk);
7196  if (size < 0)
7197  return size;
7198  else if (!size)
7199  goto end;
7200  avio_write(pb, pkt->data, size);
7201  } else if (par->codec_id == AV_CODEC_ID_EIA_608) {
7202  size = 8;
7203 
7204  for (int i = 0; i < pkt->size; i += 3) {
7205  if (pkt->data[i] == 0xFC) {
7206  size += 2;
7207  }
7208  }
7209  avio_wb32(pb, size);
7210  ffio_wfourcc(pb, "cdat");
7211  for (int i = 0; i < pkt->size; i += 3) {
7212  if (pkt->data[i] == 0xFC) {
7213  avio_w8(pb, pkt->data[i + 1]);
7214  avio_w8(pb, pkt->data[i + 2]);
7215  }
7216  }
7217  } else if (par->codec_id == AV_CODEC_ID_APV) {
7218  ff_isom_parse_apvc(trk->apv, pkt, s);
7219  avio_wb32(s->pb, pkt->size);
7220  size += 4;
7221 
7222  avio_write(s->pb, pkt->data, pkt->size);
7223  } else {
7224  if (trk->cenc.aes_ctr) {
7225  uint8_t *extradata = trk->extradata[trk->last_stsd_index];
7226  int extradata_size = trk->extradata_size[trk->last_stsd_index];
7227  if (par->codec_id == AV_CODEC_ID_H264 && extradata_size > 4) {
7228  int nal_size_length = (extradata[4] & 0x3) + 1;
7229  ret = ff_mov_cenc_avc_write_nal_units(s, &trk->cenc, nal_size_length, pb, pkt->data, size);
7230  } else if(par->codec_id == AV_CODEC_ID_HEVC && extradata_size > 21) {
7231  int nal_size_length = (extradata[21] & 0x3) + 1;
7232  ret = ff_mov_cenc_avc_write_nal_units(s, &trk->cenc, nal_size_length, pb, pkt->data, size);
7233  } else if(par->codec_id == AV_CODEC_ID_VVC) {
7235  } else if(par->codec_id == AV_CODEC_ID_AV1) {
7236  av_assert0(size == pkt->size);
7237  ret = ff_mov_cenc_av1_write_obus(s, &trk->cenc, pb, pkt);
7238  if (ret > 0) {
7239  size = ret;
7240  ret = 0;
7241  }
7242  } else {
7243  ret = ff_mov_cenc_write_packet(&trk->cenc, pb, pkt->data, size);
7244  }
7245 
7246  if (ret) {
7247  goto err;
7248  }
7249  } else {
7250  avio_write(pb, pkt->data, size);
7251  }
7252  }
7253 
7254  if (trk->entry >= trk->cluster_capacity) {
7255  unsigned new_capacity = trk->entry + MOV_INDEX_CLUSTER_SIZE;
7256  void *cluster = av_realloc_array(trk->cluster, new_capacity, sizeof(*trk->cluster));
7257  if (!cluster) {
7258  ret = AVERROR(ENOMEM);
7259  goto err;
7260  }
7261  trk->cluster = cluster;
7262  trk->cluster_capacity = new_capacity;
7263  }
7264 
7265  trk->cluster[trk->entry].pos = avio_tell(pb) - size;
7266  trk->cluster[trk->entry].stsd_index = trk->last_stsd_index;
7267  trk->cluster[trk->entry].samples_in_chunk = samples_in_chunk;
7268  trk->cluster[trk->entry].chunkNum = 0;
7269  trk->cluster[trk->entry].size = size;
7270  trk->cluster[trk->entry].entries = samples_in_chunk;
7271  trk->cluster[trk->entry].dts = pkt->dts;
7272  trk->cluster[trk->entry].pts = pkt->pts;
7273  if (!trk->squash_fragment_samples_to_one &&
7274  !trk->entry && trk->start_dts != AV_NOPTS_VALUE) {
7275  if (!trk->frag_discont) {
7276  /* First packet of a new fragment. We already wrote the duration
7277  * of the last packet of the previous fragment based on track_duration,
7278  * which might not exactly match our dts. Therefore adjust the dts
7279  * of this packet to be what the previous packets duration implies. */
7280  trk->cluster[trk->entry].dts = trk->start_dts + trk->track_duration;
7281  /* We also may have written the pts and the corresponding duration
7282  * in sidx/tfrf/tfxd tags; make sure the sidx pts and duration match up with
7283  * the next fragment. This means the cts of the first sample must
7284  * be the same in all fragments, unless end_pts was updated by
7285  * the packet causing the fragment to be written. */
7286  if ((mov->flags & FF_MOV_FLAG_DASH &&
7288  mov->mode == MODE_ISM)
7289  pkt->pts = pkt->dts + trk->end_pts - trk->cluster[trk->entry].dts;
7290  } else {
7291  /* New fragment, but discontinuous from previous fragments.
7292  * Pretend the duration sum of the earlier fragments is
7293  * pkt->dts - trk->start_dts. */
7294  trk->end_pts = trk->elst_end_pts = AV_NOPTS_VALUE;
7295  trk->frag_discont = 0;
7296  }
7297  }
7298 
7299  if (!trk->entry && trk->start_dts == AV_NOPTS_VALUE && !mov->use_editlist &&
7300  s->avoid_negative_ts == AVFMT_AVOID_NEG_TS_MAKE_ZERO) {
7301  /* Not using edit lists and shifting the first track to start from zero.
7302  * If the other streams start from a later timestamp, we won't be able
7303  * to signal the difference in starting time without an edit list.
7304  * Thus move the timestamp for this first sample to 0, increasing
7305  * its duration instead. */
7306  trk->cluster[trk->entry].dts = trk->start_dts = 0;
7307  }
7308  if (trk->start_dts == AV_NOPTS_VALUE) {
7309  trk->start_dts = pkt->dts;
7310  if (trk->frag_discont) {
7311  if (mov->use_editlist) {
7312  /* Pretend the whole stream started at pts=0, with earlier fragments
7313  * already written. If the stream started at pts=0, the duration sum
7314  * of earlier fragments would have been pkt->pts. */
7315  trk->start_dts = pkt->dts - pkt->pts;
7316  } else {
7317  /* Pretend the whole stream started at dts=0, with earlier fragments
7318  * already written, with a duration summing up to pkt->dts. */
7319  trk->start_dts = 0;
7320  }
7321  trk->frag_discont = 0;
7322  } else if (pkt->dts && mov->moov_written)
7324  "Track %d starts with a nonzero dts %"PRId64", while the moov "
7325  "already has been written. Set the delay_moov flag to handle "
7326  "this case.\n",
7327  pkt->stream_index, pkt->dts);
7328  }
7329 
7331  if (sd && sd->size >= 10 && trk->par->frame_size) {
7332  duration = FFMAX(av_rescale_q(trk->par->frame_size, (AVRational){ 1, trk->par->sample_rate },
7333  trk->st->time_base), pkt->duration);
7334  if (mov->use_editlist)
7335  pkt->duration = duration;
7336  duration -= av_rescale_q(AV_RL32(sd->data + 4), (AVRational){ 1, trk->par->sample_rate },
7337  trk->st->time_base);
7338  if (duration < 0)
7339  return AVERROR_INVALIDDATA;
7340  } else
7341  duration = pkt->duration;
7342 
7343  trk->track_duration = pkt->dts - trk->start_dts + pkt->duration;
7344  trk->last_sample_is_subtitle_end = 0;
7345 
7346  if (pkt->pts == AV_NOPTS_VALUE) {
7347  av_log(s, AV_LOG_WARNING, "pts has no value\n");
7348  pkt->pts = pkt->dts;
7349  }
7350  if (pkt->dts != pkt->pts)
7351  trk->flags |= MOV_TRACK_CTTS;
7352  trk->cluster[trk->entry].cts = pkt->pts - pkt->dts;
7353  trk->cluster[trk->entry].flags = 0;
7354  if (trk->start_cts == AV_NOPTS_VALUE || (pkt->dts <= 0 && trk->start_cts > pkt->pts - pkt->dts))
7355  trk->start_cts = pkt->pts - pkt->dts;
7356  if (trk->end_pts == AV_NOPTS_VALUE)
7357  trk->end_pts = trk->cluster[trk->entry].dts +
7358  trk->cluster[trk->entry].cts + duration;
7359  else
7360  trk->end_pts = FFMAX(trk->end_pts, trk->cluster[trk->entry].dts +
7361  trk->cluster[trk->entry].cts +
7362  duration);
7363  if (!(pkt->flags & AV_PKT_FLAG_DISCARD))
7364  trk->elst_end_pts = trk->end_pts;
7365 
7366  if (par->codec_id == AV_CODEC_ID_VC1) {
7367  mov_parse_vc1_frame(pkt, trk);
7368  } else if (par->codec_id == AV_CODEC_ID_TRUEHD) {
7370  } else if (pkt->flags & AV_PKT_FLAG_KEY) {
7371  if (mov->mode == MODE_MOV && par->codec_id == AV_CODEC_ID_MPEG2VIDEO &&
7372  trk->entry > 0) { // force sync sample for the first key frame
7374  if (trk->cluster[trk->entry].flags & MOV_PARTIAL_SYNC_SAMPLE)
7375  trk->flags |= MOV_TRACK_STPS;
7376  } else {
7377  trk->cluster[trk->entry].flags = MOV_SYNC_SAMPLE;
7378  }
7379  if (trk->cluster[trk->entry].flags & MOV_SYNC_SAMPLE)
7380  trk->has_keyframes++;
7381  }
7382  if (pkt->flags & AV_PKT_FLAG_DISPOSABLE) {
7383  trk->cluster[trk->entry].flags |= MOV_DISPOSABLE_SAMPLE;
7384  trk->has_disposable++;
7385  }
7386 
7388  if (prft && prft_size == sizeof(AVProducerReferenceTime))
7389  memcpy(&trk->cluster[trk->entry].prft, prft, prft_size);
7390  else
7391  memset(&trk->cluster[trk->entry].prft, 0, sizeof(AVProducerReferenceTime));
7392 
7393  trk->entry++;
7394  trk->sample_count += samples_in_chunk;
7395  mov->mdat_size += size;
7396 
7397  if (trk->hint_track >= 0 && trk->hint_track < mov->nb_tracks)
7399  reformatted_data ? reformatted_data + offset
7400  : NULL, size);
7401 
7402 end:
7403 err:
7404 
7405  if (pkt->data != reformatted_data)
7406  av_free(reformatted_data);
7407  return ret;
7408 }
7409 
7411 {
7412  MOVMuxContext *mov = s->priv_data;
7413  MOVTrack *trk = s->streams[pkt->stream_index]->priv_data;
7414  AVCodecParameters *par = trk->par;
7415  int64_t frag_duration = 0;
7416  int size = pkt->size;
7417 
7418  int ret = check_pkt(s, trk, pkt);
7419  if (ret < 0)
7420  return ret;
7421 
7422  if (mov->flags & FF_MOV_FLAG_FRAG_DISCONT) {
7423  for (int i = 0; i < mov->nb_streams; i++)
7424  mov->tracks[i].frag_discont = 1;
7426  }
7427 
7429  if (trk->dts_shift == AV_NOPTS_VALUE)
7430  trk->dts_shift = pkt->pts - pkt->dts;
7431  pkt->dts += trk->dts_shift;
7432  }
7433 
7434  if (trk->par->codec_id == AV_CODEC_ID_MP4ALS ||
7435  trk->par->codec_id == AV_CODEC_ID_AAC ||
7436  trk->par->codec_id == AV_CODEC_ID_AV1 ||
7437  trk->par->codec_id == AV_CODEC_ID_FLAC) {
7438  size_t side_size;
7439  uint8_t *side = av_packet_get_side_data(pkt, AV_PKT_DATA_NEW_EXTRADATA, &side_size);
7440  /* Overwrite extradata only on flush packets or when no extradata was available during init */
7441  if (side_size > 0 && (!pkt->size || !trk->extradata_size[trk->last_stsd_index])) {
7442  void *newextra = av_malloc(side_size + AV_INPUT_BUFFER_PADDING_SIZE);
7443  if (!newextra)
7444  return AVERROR(ENOMEM);
7445  memset((uint8_t*)newextra + side_size, 0, AV_INPUT_BUFFER_PADDING_SIZE);
7446  memcpy(newextra, side, side_size);
7447  av_free(trk->extradata[trk->last_stsd_index]);
7448  trk->extradata[trk->last_stsd_index] = newextra;
7449  trk->extradata_size[trk->last_stsd_index] = side_size;
7450  }
7451  }
7452 
7453  if (!pkt->size) {
7454  if (trk->start_dts == AV_NOPTS_VALUE && trk->frag_discont) {
7455  trk->start_dts = pkt->dts;
7456  if (pkt->pts != AV_NOPTS_VALUE)
7457  trk->start_cts = pkt->pts - pkt->dts;
7458  else
7459  trk->start_cts = 0;
7460  }
7461 
7462  return 0; /* Discard 0 sized packets */
7463  }
7464 
7465  if (trk->entry && pkt->stream_index < mov->nb_streams)
7466  frag_duration = av_rescale_q(pkt->dts - trk->cluster[0].dts,
7467  s->streams[pkt->stream_index]->time_base,
7468  AV_TIME_BASE_Q);
7469  if ((mov->max_fragment_duration &&
7470  frag_duration >= mov->max_fragment_duration) ||
7471  (mov->max_fragment_size && mov->mdat_size + size >= mov->max_fragment_size) ||
7472  (mov->flags & FF_MOV_FLAG_FRAG_KEYFRAME &&
7473  par->codec_type == AVMEDIA_TYPE_VIDEO &&
7474  trk->entry && pkt->flags & AV_PKT_FLAG_KEY) ||
7476  if (frag_duration >= mov->min_fragment_duration) {
7477  if (trk->entry) {
7478  // Set the duration of this track to line up with the next
7479  // sample in this track. This avoids relying on AVPacket
7480  // duration, but only helps for this particular track, not
7481  // for the other ones that are flushed at the same time.
7482  //
7483  // If we have trk->entry == 0, no fragment will be written
7484  // for this track, and we can't adjust the track end here.
7485  trk->track_duration = pkt->dts - trk->start_dts;
7486  if (pkt->pts != AV_NOPTS_VALUE)
7487  trk->end_pts = pkt->pts;
7488  else
7489  trk->end_pts = pkt->dts;
7490  if (!(pkt->flags & AV_PKT_FLAG_DISCARD))
7491  trk->elst_end_pts = trk->end_pts;
7492  trk->end_reliable = 1;
7493  }
7495  }
7496  }
7497 
7498  return ff_mov_write_packet(s, pkt);
7499 }
7500 
7502  int stream_index,
7503  int64_t dts) {
7504  MOVMuxContext *mov = s->priv_data;
7505  AVPacket *end = mov->pkt;
7506  uint8_t data[2] = {0};
7507  int ret;
7508 
7509  end->size = sizeof(data);
7510  end->data = data;
7511  end->pts = dts;
7512  end->dts = dts;
7513  end->duration = 0;
7514  end->stream_index = stream_index;
7515 
7516  ret = mov_write_single_packet(s, end);
7517  av_packet_unref(end);
7518 
7519  return ret;
7520 }
7521 
7522 #if CONFIG_IAMFENC
7523 static int mov_build_iamf_packet(AVFormatContext *s, MOVTrack *trk, AVPacket *pkt)
7524 {
7525  uint8_t *data;
7526  int ret;
7527 
7528  if (pkt->stream_index == trk->first_iamf_idx) {
7530  if (ret < 0)
7531  return ret;
7532  }
7533 
7535  s->streams[pkt->stream_index]->id, pkt);
7536  if (ret < 0)
7537  return ret;
7538 
7539  if (pkt->stream_index != trk->last_iamf_idx)
7540  return AVERROR(EAGAIN);
7541 
7542  ret = avio_close_dyn_buf(trk->iamf_buf, &data);
7543  trk->iamf_buf = NULL;
7544  if (!ret) {
7545  if (pkt->size) {
7546  // Either all or none of the packets for a single
7547  // IA Sample may be empty.
7548  av_log(s, AV_LOG_ERROR, "Unexpected packet from "
7549  "stream #%d\n", pkt->stream_index);
7551  }
7552  av_free(data);
7553  return ret;
7554  }
7555 
7556  av_buffer_unref(&pkt->buf);
7557  pkt->buf = av_buffer_create(data, ret, NULL, NULL, 0);
7558  if (!pkt->buf) {
7559  av_free(data);
7560  return AVERROR(ENOMEM);
7561  }
7562  pkt->data = data;
7563  pkt->size = ret;
7565 
7566  return avio_open_dyn_buf(&trk->iamf_buf);
7567 }
7568 #endif
7569 
7571 {
7572  int64_t pos = avio_tell(pb);
7573  const char *scheme_id_uri = "https://aomedia.org/emsg/ID3";
7574  const char *value = "";
7575 
7576  av_assert0(st->time_base.num == 1);
7577 
7578  avio_write_marker(pb,
7581 
7582  avio_wb32(pb, 0); /* size */
7583  ffio_wfourcc(pb, "emsg");
7584  avio_w8(pb, 1); /* version */
7585  avio_wb24(pb, 0);
7586  avio_wb32(pb, st->time_base.den); /* timescale */
7587  avio_wb64(pb, pkt->pts); /* presentation_time */
7588  avio_wb32(pb, 0xFFFFFFFFU); /* event_duration */
7589  avio_wb32(pb, 0); /* id */
7590  /* null terminated UTF8 strings */
7591  avio_write(pb, scheme_id_uri, strlen(scheme_id_uri) + 1);
7592  avio_write(pb, value, strlen(value) + 1);
7593  avio_write(pb, pkt->data, pkt->size);
7594 
7595  return update_size(pb, pos);
7596 }
7597 
7599 {
7600  MOVMuxContext *mov = s->priv_data;
7601  MOVTrack *trk;
7602 
7603  if (!pkt) {
7604  mov_flush_fragment(s, 1);
7605  return 1;
7606  }
7607 
7608  if (s->streams[pkt->stream_index]->codecpar->codec_id == AV_CODEC_ID_TIMED_ID3) {
7609  mov_write_emsg_tag(s->pb, s->streams[pkt->stream_index], pkt);
7610  return 0;
7611  }
7612 
7613  trk = s->streams[pkt->stream_index]->priv_data;
7614 
7615 #if CONFIG_IAMFENC
7616  if (trk->iamf) {
7617  int ret = mov_build_iamf_packet(s, trk, pkt);
7618  if (ret < 0) {
7619  if (ret == AVERROR(EAGAIN))
7620  return 0;
7621  av_log(s, AV_LOG_ERROR, "Error assembling an IAMF packet "
7622  "for stream #%d\n", trk->st->index);
7623  return ret;
7624  }
7625  }
7626 #endif
7627 
7628  if (is_cover_image(trk->st)) {
7629  int ret;
7630 
7631  if (trk->st->nb_frames >= 1) {
7632  if (trk->st->nb_frames == 1)
7633  av_log(s, AV_LOG_WARNING, "Got more than one picture in stream %d,"
7634  " ignoring.\n", pkt->stream_index);
7635  return 0;
7636  }
7637 
7638  if ((ret = av_packet_ref(trk->cover_image, pkt)) < 0)
7639  return ret;
7640 
7641  return 0;
7642  } else {
7643  int i;
7644 
7645  if (!pkt->size)
7646  return mov_write_single_packet(s, pkt); /* Passthrough. */
7647 
7648  /*
7649  * Subtitles require special handling.
7650  *
7651  * 1) For full compliance, every track must have a sample at
7652  * dts == 0, which is rarely true for subtitles. So, as soon
7653  * as we see any packet with dts > 0, write an empty subtitle
7654  * at dts == 0 for any subtitle track with no samples in it.
7655  *
7656  * 2) For each subtitle track, check if the current packet's
7657  * dts is past the duration of the last subtitle sample. If
7658  * so, we now need to write an end sample for that subtitle.
7659  *
7660  * This must be done conditionally to allow for subtitles that
7661  * immediately replace each other, in which case an end sample
7662  * is not needed, and is, in fact, actively harmful.
7663  *
7664  * 3) See mov_write_trailer for how the final end sample is
7665  * handled.
7666  */
7667  for (i = 0; i < mov->nb_tracks; i++) {
7668  MOVTrack *trk = &mov->tracks[i];
7669  int ret;
7670 
7671  if (trk->par->codec_id == AV_CODEC_ID_MOV_TEXT &&
7672  trk->track_duration < pkt->dts &&
7673  (trk->entry == 0 || !trk->last_sample_is_subtitle_end)) {
7675  if (ret < 0) return ret;
7676  trk->last_sample_is_subtitle_end = 1;
7677  }
7678  }
7679 
7680  if (trk->squash_fragment_samples_to_one) {
7681  /*
7682  * If the track has to have its samples squashed into one sample,
7683  * we just take it into the track's queue.
7684  * This will then be utilized as the samples get written in either
7685  * mov_flush_fragment or when the mux is finalized in
7686  * mov_write_trailer.
7687  */
7688  int ret = AVERROR_BUG;
7689 
7690  if (pkt->pts == AV_NOPTS_VALUE) {
7692  "Packets without a valid presentation timestamp are "
7693  "not supported with packet squashing!\n");
7694  return AVERROR(EINVAL);
7695  }
7696 
7697  /* The following will reset pkt and is only allowed to be used
7698  * because we return immediately. afterwards. */
7700  pkt, NULL, 0)) < 0) {
7701  return ret;
7702  }
7703 
7704  return 0;
7705  }
7706 
7707 
7708  if (trk->mode == MODE_MOV && trk->par->codec_type == AVMEDIA_TYPE_VIDEO) {
7709  AVPacket *opkt = pkt;
7710  int reshuffle_ret, ret;
7711  if (trk->is_unaligned_qt_rgb) {
7712  int64_t bpc = trk->par->bits_per_coded_sample != 15 ? trk->par->bits_per_coded_sample : 16;
7713  int expected_stride = ((trk->par->width * bpc + 15) >> 4)*2;
7714  reshuffle_ret = ff_reshuffle_raw_rgb(s, &pkt, trk->par, expected_stride);
7715  if (reshuffle_ret < 0)
7716  return reshuffle_ret;
7717  } else
7718  reshuffle_ret = 0;
7719  if (trk->par->format == AV_PIX_FMT_PAL8 && !trk->pal_done) {
7720  ret = ff_get_packet_palette(s, opkt, reshuffle_ret, trk->palette);
7721  if (ret < 0)
7722  goto fail;
7723  if (ret)
7724  trk->pal_done++;
7725  } else if (trk->par->codec_id == AV_CODEC_ID_RAWVIDEO &&
7726  (trk->par->format == AV_PIX_FMT_GRAY8 ||
7727  trk->par->format == AV_PIX_FMT_MONOBLACK)) {
7729  if (ret < 0)
7730  goto fail;
7731  for (i = 0; i < pkt->size; i++)
7732  pkt->data[i] = ~pkt->data[i];
7733  }
7734  if (reshuffle_ret) {
7736 fail:
7737  if (reshuffle_ret)
7738  av_packet_free(&pkt);
7739  return ret;
7740  }
7741  }
7742 
7743  return mov_write_single_packet(s, pkt);
7744  }
7745 }
7746 
7747 // QuickTime chapters involve an additional text track with the chapter names
7748 // as samples, and a tref pointing from the other tracks to the chapter one.
7749 static int mov_create_chapter_track(AVFormatContext *s, int tracknum)
7750 {
7751  static const uint8_t stub_header[] = {
7752  // TextSampleEntry
7753  0x00, 0x00, 0x00, 0x01, // displayFlags
7754  0x00, 0x00, // horizontal + vertical justification
7755  0x00, 0x00, 0x00, 0x00, // bgColourRed/Green/Blue/Alpha
7756  // BoxRecord
7757  0x00, 0x00, 0x00, 0x00, // defTextBoxTop/Left
7758  0x00, 0x00, 0x00, 0x00, // defTextBoxBottom/Right
7759  // StyleRecord
7760  0x00, 0x00, 0x00, 0x00, // startChar + endChar
7761  0x00, 0x01, // fontID
7762  0x00, 0x00, // fontStyleFlags + fontSize
7763  0x00, 0x00, 0x00, 0x00, // fgColourRed/Green/Blue/Alpha
7764  // FontTableBox
7765  0x00, 0x00, 0x00, 0x0D, // box size
7766  'f', 't', 'a', 'b', // box atom name
7767  0x00, 0x01, // entry count
7768  // FontRecord
7769  0x00, 0x01, // font ID
7770  0x00, // font name length
7771  };
7772  MOVMuxContext *mov = s->priv_data;
7773  MOVTrack *track = &mov->tracks[tracknum];
7774  AVPacket *pkt = mov->pkt;
7775  int i, len;
7776  int ret;
7777 
7778  track->mode = mov->mode;
7779  track->tag = MKTAG('t','e','x','t');
7780  track->timescale = mov->movie_timescale;
7781  track->par = avcodec_parameters_alloc();
7782  if (!track->par)
7783  return AVERROR(ENOMEM);
7785  ret = ff_alloc_extradata(track->par, sizeof(stub_header));
7786  if (ret < 0)
7787  return ret;
7788  memcpy(track->par->extradata, stub_header, sizeof(stub_header));
7789 
7790  if (track->extradata == NULL) {
7791  track->stsd_count = 1;
7792  track->extradata = av_calloc(1, sizeof(*track->extradata));
7793  track->extradata_size = av_calloc(1, sizeof(*track->extradata_size));
7794  if (!track->extradata || !track->extradata_size)
7795  return AVERROR(ENOMEM);
7796  }
7797 
7798  track->extradata[0] = av_memdup(stub_header, sizeof(stub_header));
7799  if (!track->extradata[0])
7800  return AVERROR(ENOMEM);
7801  track->extradata_size[0] = sizeof(stub_header);
7802 
7803  pkt->stream_index = tracknum;
7805 
7806  for (i = 0; i < s->nb_chapters; i++) {
7807  AVChapter *c = s->chapters[i];
7808  AVDictionaryEntry *t;
7809 
7810  int64_t end = av_rescale_q(c->end, c->time_base, (AVRational){1,mov->movie_timescale});
7811  pkt->pts = pkt->dts = av_rescale_q(c->start, c->time_base, (AVRational){1,mov->movie_timescale});
7812  pkt->duration = end - pkt->dts;
7813 
7814  if ((t = av_dict_get(c->metadata, "title", NULL, 0))) {
7815  static const char encd[12] = {
7816  0x00, 0x00, 0x00, 0x0C,
7817  'e', 'n', 'c', 'd',
7818  0x00, 0x00, 0x01, 0x00 };
7819  len = strlen(t->value);
7820  pkt->size = len + 2 + 12;
7821  pkt->data = av_malloc(pkt->size);
7822  if (!pkt->data) {
7824  return AVERROR(ENOMEM);
7825  }
7826  AV_WB16(pkt->data, len);
7827  memcpy(pkt->data + 2, t->value, len);
7828  memcpy(pkt->data + len + 2, encd, sizeof(encd));
7830  av_freep(&pkt->data);
7831  }
7832  }
7833 
7834  av_packet_unref(mov->pkt);
7835 
7836  return 0;
7837 }
7838 
7839 
7840 static int mov_check_timecode_track(AVFormatContext *s, AVTimecode *tc, AVStream *src_st, const char *tcstr)
7841 {
7842  int ret;
7843 
7844  /* compute the frame number */
7845  ret = av_timecode_init_from_string(tc, src_st->avg_frame_rate, tcstr, s);
7846  return ret;
7847 }
7848 
7849 static int mov_create_timecode_track(AVFormatContext *s, int index, int src_index, AVTimecode tc)
7850 {
7851  MOVMuxContext *mov = s->priv_data;
7852  MOVTrack *track = &mov->tracks[index];
7853  AVStream *src_st = mov->tracks[src_index].st;
7854  uint8_t data[4];
7855  AVPacket *pkt = mov->pkt;
7856  AVRational rate = src_st->avg_frame_rate;
7857  int ret;
7858 
7859  /* tmcd track based on video stream */
7860  track->mode = mov->mode;
7861  track->tag = MKTAG('t','m','c','d');
7862  track->src_track = av_malloc(sizeof(*track->src_track));
7863  if (!track->src_track)
7864  return AVERROR(ENOMEM);
7865  *track->src_track = src_index;
7866  track->nb_src_track = 1;
7867  track->timescale = mov->tracks[src_index].timescale;
7870 
7871  /* set st to src_st for metadata access*/
7872  track->st = src_st;
7873 
7874  /* encode context: tmcd data stream */
7875  track->par = avcodec_parameters_alloc();
7876  if (!track->par)
7877  return AVERROR(ENOMEM);
7878  track->par->codec_type = AVMEDIA_TYPE_DATA;
7879  track->par->codec_tag = track->tag;
7880  track->st->avg_frame_rate = rate;
7881 
7882  /* the tmcd track just contains one packet with the frame number */
7883  pkt->data = data;
7884  pkt->stream_index = index;
7886  pkt->pts = pkt->dts = av_rescale_q(tc.start, av_inv_q(rate), (AVRational){ 1, track->timescale });
7887  pkt->size = 4;
7888  AV_WB32(pkt->data, tc.start);
7891  return ret;
7892 }
7893 
7894 /*
7895  * st->disposition controls the "enabled" flag in the tkhd tag.
7896  * QuickTime will not play a track if it is not enabled. So make sure
7897  * that one track of each type (audio, video, subtitle) is enabled.
7898  *
7899  * Subtitles are special. For audio and video, setting "enabled" also
7900  * makes the track "default" (i.e. it is rendered when played). For
7901  * subtitles, an "enabled" subtitle is not rendered by default, but
7902  * if no subtitle is enabled, the subtitle menu in QuickTime will be
7903  * empty!
7904  */
7906 {
7907  MOVMuxContext *mov = s->priv_data;
7908  int i;
7909  int enabled[AVMEDIA_TYPE_NB];
7910  int first[AVMEDIA_TYPE_NB];
7911 
7912  for (i = 0; i < AVMEDIA_TYPE_NB; i++) {
7913  enabled[i] = 0;
7914  first[i] = -1;
7915  }
7916 
7917  for (i = 0; i < mov->nb_streams; i++) {
7918  AVStream *st = mov->tracks[i].st;
7919 
7922  is_cover_image(st))
7923  continue;
7924 
7925  if (first[st->codecpar->codec_type] < 0)
7926  first[st->codecpar->codec_type] = i;
7927  if (st->disposition & AV_DISPOSITION_DEFAULT) {
7928  mov->tracks[i].flags |= MOV_TRACK_ENABLED;
7929  enabled[st->codecpar->codec_type]++;
7930  }
7931  }
7932 
7933  for (i = 0; i < AVMEDIA_TYPE_NB; i++) {
7934  switch (i) {
7935  case AVMEDIA_TYPE_VIDEO:
7936  case AVMEDIA_TYPE_AUDIO:
7937  case AVMEDIA_TYPE_SUBTITLE:
7938  if (enabled[i] > 1)
7939  mov->per_stream_grouping = 1;
7940  if (!enabled[i] && first[i] >= 0)
7941  mov->tracks[first[i]].flags |= MOV_TRACK_ENABLED;
7942  break;
7943  }
7944  }
7945 }
7946 
7948 {
7949  MOVMuxContext *mov = s->priv_data;
7950 
7951  for (int i = 0; i < s->nb_streams; i++)
7952  s->streams[i]->priv_data = NULL;
7953 
7954  if (!mov->tracks)
7955  return;
7956 
7957  if (mov->chapter_track) {
7959  }
7960 
7961  for (int i = 0; i < mov->nb_tracks; i++) {
7962  MOVTrack *const track = &mov->tracks[i];
7963 
7964  if (track->tag == MKTAG('r','t','p',' '))
7965  ff_mov_close_hinting(track);
7966  else if (track->tag == MKTAG('t','m','c','d') && mov->nb_meta_tmcd)
7967  av_freep(&track->par);
7968  av_freep(&track->cluster);
7969  av_freep(&track->cluster_written);
7970  av_freep(&track->frag_info);
7971  av_packet_free(&track->cover_image);
7972 
7973  if (track->eac3_priv) {
7974  struct eac3_info *info = track->eac3_priv;
7975  av_packet_free(&info->pkt);
7976  av_freep(&track->eac3_priv);
7977  }
7978  for (int j = 0; j < track->stsd_count; j++)
7979  av_freep(&track->extradata[j]);
7980  av_freep(&track->extradata);
7981  av_freep(&track->extradata_size);
7982 
7983  for (int i = 0; i < track->nb_tref_tags; i++)
7984  av_freep(&track->tref_tags[i].id);
7985  av_freep(&track->tref_tags);
7986  av_freep(&track->src_track);
7987 
7988  ff_mov_cenc_free(&track->cenc);
7989  ffio_free_dyn_buf(&track->mdat_buf);
7990 
7991 #if CONFIG_IAMFENC
7992  ffio_free_dyn_buf(&track->iamf_buf);
7993  if (track->iamf)
7994  ff_iamf_uninit_context(track->iamf);
7995  av_freep(&track->iamf);
7996 #endif
7997  ff_isom_close_apvc(&track->apv);
7998 
8000  }
8001 
8002  av_freep(&mov->tracks);
8003  ffio_free_dyn_buf(&mov->mdat_buf);
8004 }
8005 
8006 static uint32_t rgb_to_yuv(uint32_t rgb)
8007 {
8008  uint8_t r, g, b;
8009  int y, cb, cr;
8010 
8011  r = (rgb >> 16) & 0xFF;
8012  g = (rgb >> 8) & 0xFF;
8013  b = (rgb ) & 0xFF;
8014 
8015  y = av_clip_uint8(( 16000 + 257 * r + 504 * g + 98 * b)/1000);
8016  cb = av_clip_uint8((128000 - 148 * r - 291 * g + 439 * b)/1000);
8017  cr = av_clip_uint8((128000 + 439 * r - 368 * g - 71 * b)/1000);
8018 
8019  return (y << 16) | (cr << 8) | cb;
8020 }
8021 
8023  AVStream *st)
8024 {
8025  int i, width = 720, height = 480;
8026  int have_palette = 0, have_size = 0;
8027  uint32_t palette[16];
8028  char *cur = st->codecpar->extradata;
8029 
8030  while (cur && *cur) {
8031  if (strncmp("palette:", cur, 8) == 0) {
8032  int i, count;
8033  count = sscanf(cur + 8,
8034  "%06"PRIx32", %06"PRIx32", %06"PRIx32", %06"PRIx32", "
8035  "%06"PRIx32", %06"PRIx32", %06"PRIx32", %06"PRIx32", "
8036  "%06"PRIx32", %06"PRIx32", %06"PRIx32", %06"PRIx32", "
8037  "%06"PRIx32", %06"PRIx32", %06"PRIx32", %06"PRIx32"",
8038  &palette[ 0], &palette[ 1], &palette[ 2], &palette[ 3],
8039  &palette[ 4], &palette[ 5], &palette[ 6], &palette[ 7],
8040  &palette[ 8], &palette[ 9], &palette[10], &palette[11],
8041  &palette[12], &palette[13], &palette[14], &palette[15]);
8042 
8043  for (i = 0; i < count; i++) {
8044  palette[i] = rgb_to_yuv(palette[i]);
8045  }
8046  have_palette = 1;
8047  } else if (!strncmp("size:", cur, 5)) {
8048  sscanf(cur + 5, "%dx%d", &width, &height);
8049  have_size = 1;
8050  }
8051  if (have_palette && have_size)
8052  break;
8053  cur += strcspn(cur, "\n\r");
8054  cur += strspn(cur, "\n\r");
8055  }
8056  if (have_palette) {
8058  if (!track->extradata[track->last_stsd_index])
8059  return AVERROR(ENOMEM);
8060  for (i = 0; i < 16; i++) {
8061  AV_WB32(track->extradata[track->last_stsd_index] + i * 4, palette[i]);
8062  }
8063  memset(track->extradata[track->last_stsd_index] + 16*4, 0, AV_INPUT_BUFFER_PADDING_SIZE);
8064  track->extradata_size[track->last_stsd_index] = 16 * 4;
8065  }
8066  st->codecpar->width = width;
8067  st->codecpar->height = track->height = height;
8068 
8069  return 0;
8070 }
8071 
8072 #if CONFIG_IAMFENC
8073 static int mov_init_iamf_track(AVFormatContext *s)
8074 {
8075  MOVMuxContext *mov = s->priv_data;
8076  MOVTrack *track;
8077  IAMFContext *iamf;
8078  int first_iamf_idx = INT_MAX, last_iamf_idx = 0;
8079  int nb_audio_elements = 0, nb_mix_presentations = 0;
8080  int ret;
8081 
8082  for (int i = 0; i < s->nb_stream_groups; i++) {
8083  const AVStreamGroup *stg = s->stream_groups[i];
8084 
8086  nb_audio_elements++;
8088  nb_mix_presentations++;
8089  }
8090 
8091  if (!nb_audio_elements && !nb_mix_presentations)
8092  return 0;
8093 
8094  if (nb_audio_elements < 1 || nb_audio_elements > 2 || nb_mix_presentations < 1) {
8095  av_log(s, AV_LOG_ERROR, "There must be >= 1 and <= 2 IAMF_AUDIO_ELEMENT and at least "
8096  "one IAMF_MIX_PRESENTATION stream groups to write a IMAF track\n");
8097  return AVERROR(EINVAL);
8098  }
8099 
8100  iamf = av_mallocz(sizeof(*iamf));
8101  if (!iamf)
8102  return AVERROR(ENOMEM);
8103 
8104 
8105  for (int i = 0; i < s->nb_stream_groups; i++) {
8106  const AVStreamGroup *stg = s->stream_groups[i];
8107  switch(stg->type) {
8109  for (int j = 0; j < stg->nb_streams; j++) {
8110  first_iamf_idx = FFMIN(stg->streams[j]->index, first_iamf_idx);
8111  last_iamf_idx = FFMAX(stg->streams[j]->index, last_iamf_idx);
8112  }
8113 
8114  ret = ff_iamf_add_audio_element(iamf, stg, s);
8115  break;
8117  ret = ff_iamf_add_mix_presentation(iamf, stg, s);
8118  break;
8119  default:
8120  av_assert0(0);
8121  }
8122  if (ret < 0) {
8123  ff_iamf_uninit_context(iamf);
8124  av_free(iamf);
8125  return ret;
8126  }
8127  }
8128 
8129  track = &mov->tracks[first_iamf_idx];
8130  track->iamf = iamf;
8131  track->first_iamf_idx = first_iamf_idx;
8132  track->last_iamf_idx = last_iamf_idx;
8133  track->tag = MKTAG('i','a','m','f');
8134 
8135  for (int i = 0; i < s->nb_stream_groups; i++) {
8136  AVStreamGroup *stg = s->stream_groups[i];
8138  continue;
8139  for (int j = 0; j < stg->nb_streams; j++)
8140  stg->streams[j]->priv_data = track;
8141  }
8142 
8143  ret = avio_open_dyn_buf(&track->iamf_buf);
8144  if (ret < 0)
8145  return ret;
8146 
8147  return 0;
8148 }
8149 #endif
8150 
8152 {
8153  MOVMuxContext *mov = s->priv_data;
8154  int has_iamf = 0;
8155  int i, ret;
8156 
8157  mov->fc = s;
8158  mov->pkt = ffformatcontext(s)->pkt;
8159 
8160  /* Default mode == MP4 */
8161  mov->mode = MODE_MP4;
8162 
8163 #define IS_MODE(muxer, config) (CONFIG_ ## config ## _MUXER && !strcmp(#muxer, s->oformat->name))
8164  if (IS_MODE(3gp, TGP)) mov->mode = MODE_3GP;
8165  else if (IS_MODE(3g2, TG2)) mov->mode = MODE_3GP|MODE_3G2;
8166  else if (IS_MODE(mov, MOV)) mov->mode = MODE_MOV;
8167  else if (IS_MODE(psp, PSP)) mov->mode = MODE_PSP;
8168  else if (IS_MODE(ipod, IPOD)) mov->mode = MODE_IPOD;
8169  else if (IS_MODE(ismv, ISMV)) mov->mode = MODE_ISM;
8170  else if (IS_MODE(f4v, F4V)) mov->mode = MODE_F4V;
8171  else if (IS_MODE(avif, AVIF)) mov->mode = MODE_AVIF;
8172 #undef IS_MODE
8173 
8174  if (mov->flags & FF_MOV_FLAG_DELAY_MOOV)
8175  mov->flags |= FF_MOV_FLAG_EMPTY_MOOV;
8176 
8177  if (mov->mode == MODE_AVIF)
8178  mov->flags |= FF_MOV_FLAG_DELAY_MOOV;
8179 
8180  /* Set the FRAGMENT flag if any of the fragmentation methods are
8181  * enabled. */
8182  if (mov->max_fragment_duration || mov->max_fragment_size ||
8183  mov->flags & (FF_MOV_FLAG_EMPTY_MOOV |
8187  mov->flags |= FF_MOV_FLAG_FRAGMENT;
8188 
8189  if (mov->flags & FF_MOV_FLAG_HYBRID_FRAGMENTED &&
8190  mov->flags & FF_MOV_FLAG_FASTSTART) {
8191  av_log(s, AV_LOG_ERROR, "Setting both hybrid_fragmented and faststart is not supported.\n");
8192  return AVERROR(EINVAL);
8193  }
8194 
8195  /* Set other implicit flags immediately */
8197  mov->flags |= FF_MOV_FLAG_FRAGMENT;
8198 
8199  if (mov->mode == MODE_ISM)
8202  if (mov->flags & FF_MOV_FLAG_DASH)
8205  if (mov->flags & FF_MOV_FLAG_CMAF)
8208 
8209  if (mov->flags & FF_MOV_FLAG_EMPTY_MOOV && s->flags & AVFMT_FLAG_AUTO_BSF) {
8210  av_log(s, AV_LOG_VERBOSE, "Empty MOOV enabled; disabling automatic bitstream filtering\n");
8211  s->flags &= ~AVFMT_FLAG_AUTO_BSF;
8212  }
8213 
8215  av_log(s, AV_LOG_WARNING, "Global SIDX enabled; Ignoring skip_sidx option\n");
8216  mov->flags &= ~FF_MOV_FLAG_SKIP_SIDX;
8217  }
8218 
8219  if (mov->flags & FF_MOV_FLAG_FASTSTART) {
8220  mov->reserved_moov_size = -1;
8221  }
8222 
8223  if (mov->use_editlist < 0) {
8224  mov->use_editlist = 1;
8225  if (mov->flags & FF_MOV_FLAG_FRAGMENT &&
8226  !(mov->flags & FF_MOV_FLAG_DELAY_MOOV)) {
8227  // If we can avoid needing an edit list by shifting the
8228  // tracks, prefer that over (trying to) write edit lists
8229  // in fragmented output.
8230  if (s->avoid_negative_ts == AVFMT_AVOID_NEG_TS_AUTO ||
8231  s->avoid_negative_ts == AVFMT_AVOID_NEG_TS_MAKE_ZERO)
8232  mov->use_editlist = 0;
8233  }
8234  }
8235  if (mov->flags & FF_MOV_FLAG_EMPTY_MOOV &&
8236  !(mov->flags & FF_MOV_FLAG_DELAY_MOOV) && mov->use_editlist)
8237  av_log(s, AV_LOG_WARNING, "No meaningful edit list will be written when using empty_moov without delay_moov\n");
8238 
8239  if (mov->flags & FF_MOV_FLAG_CMAF && mov->use_editlist)
8241 
8242  if (!mov->use_editlist && s->avoid_negative_ts == AVFMT_AVOID_NEG_TS_AUTO &&
8244  s->avoid_negative_ts = AVFMT_AVOID_NEG_TS_MAKE_ZERO;
8245 
8246  /* Clear the omit_tfhd_offset flag if default_base_moof is set;
8247  * if the latter is set that's enough and omit_tfhd_offset doesn't
8248  * add anything extra on top of that. */
8249  if (mov->flags & FF_MOV_FLAG_OMIT_TFHD_OFFSET &&
8252 
8253  if (mov->frag_interleave &&
8256  "Sample interleaving in fragments is mutually exclusive with "
8257  "omit_tfhd_offset and separate_moof\n");
8258  return AVERROR(EINVAL);
8259  }
8260 
8261  /* Non-seekable output is ok if using fragmentation. If ism_lookahead
8262  * is enabled, we don't support non-seekable output at all. */
8263  if (!(s->pb->seekable & AVIO_SEEKABLE_NORMAL) &&
8264  (!(mov->flags & FF_MOV_FLAG_FRAGMENT) || mov->ism_lookahead ||
8265  mov->mode == MODE_AVIF)) {
8266  av_log(s, AV_LOG_ERROR, "muxer does not support non seekable output\n");
8267  return AVERROR(EINVAL);
8268  }
8269 
8270  /* AVIF output must have at most two video streams (one for YUV and one for
8271  * alpha). */
8272  if (mov->mode == MODE_AVIF) {
8273  if (s->nb_streams > 2) {
8274  av_log(s, AV_LOG_ERROR, "AVIF output requires exactly one or two streams\n");
8275  return AVERROR(EINVAL);
8276  }
8277  if (s->streams[0]->codecpar->codec_type != AVMEDIA_TYPE_VIDEO &&
8278  (s->nb_streams > 1 && s->streams[1]->codecpar->codec_type != AVMEDIA_TYPE_VIDEO)) {
8279  av_log(s, AV_LOG_ERROR, "AVIF output supports only video streams\n");
8280  return AVERROR(EINVAL);
8281  }
8282  if (s->nb_streams > 1) {
8283  const AVPixFmtDescriptor *pixdesc =
8284  av_pix_fmt_desc_get(s->streams[1]->codecpar->format);
8285  if (pixdesc->nb_components != 1) {
8286  av_log(s, AV_LOG_ERROR, "Second stream for AVIF (alpha) output must have exactly one plane\n");
8287  return AVERROR(EINVAL);
8288  }
8289  }
8290  s->streams[0]->disposition |= AV_DISPOSITION_DEFAULT;
8291  }
8292 
8293  for (i = 0; i < s->nb_stream_groups; i++) {
8294  AVStreamGroup *stg = s->stream_groups[i];
8295 
8296  if (stg->type == AV_STREAM_GROUP_PARAMS_LCEVC) {
8297  if (stg->nb_streams != 2) {
8298  av_log(s, AV_LOG_ERROR, "Exactly two Streams are supported for Stream Groups of type LCEVC\n");
8299  return AVERROR(EINVAL);
8300  }
8302  if (lcevc->el_index > 1)
8303  return AVERROR(EINVAL);
8304  AVStream *st = stg->streams[lcevc->el_index];
8305  if (st->codecpar->codec_id != AV_CODEC_ID_LCEVC) {
8306  av_log(s, AV_LOG_ERROR, "Stream #%u is not an LCEVC stream\n", lcevc->el_index);
8307  return AVERROR(EINVAL);
8308  }
8309  }
8310 
8311 #if CONFIG_IAMFENC
8313  continue;
8314 
8315  for (int j = 0; j < stg->nb_streams; j++) {
8316  AVStream *st = stg->streams[j];
8317 
8318  if (st->priv_data) {
8319  av_log(s, AV_LOG_ERROR, "Stream %d is present in more than one Stream Group of type "
8320  "IAMF Audio Element\n", j);
8321  return AVERROR(EINVAL);
8322  }
8323  st->priv_data = st;
8324  }
8325  has_iamf = 1;
8326 
8327  if (!mov->nb_tracks) // We support one track for the entire IAMF structure
8328  mov->nb_tracks++;
8329 #endif
8330  }
8331 
8332  for (i = 0; i < s->nb_streams; i++) {
8333  AVStream *st = s->streams[i];
8334  if (st->priv_data)
8335  continue;
8336  // Don't produce a track in the output file for timed ID3 streams.
8337  if (st->codecpar->codec_id == AV_CODEC_ID_TIMED_ID3) {
8338  // Leave priv_data set to NULL for these AVStreams that don't
8339  // have a corresponding track.
8340  continue;
8341  }
8342  st->priv_data = st;
8343  mov->nb_tracks++;
8344  }
8345 
8346  mov->nb_streams = mov->nb_tracks;
8347 
8348  if (mov->mode & (MODE_MP4|MODE_MOV|MODE_IPOD) && s->nb_chapters)
8349  mov->chapter_track = mov->nb_tracks++;
8350 
8351  if (mov->flags & FF_MOV_FLAG_RTP_HINT) {
8352  for (i = 0; i < s->nb_streams; i++)
8353  if (rtp_hinting_needed(s->streams[i]))
8354  mov->nb_tracks++;
8355  }
8356 
8357  if (mov->write_btrt < 0) {
8358  mov->write_btrt = mov->mode == MODE_MP4;
8359  }
8360 
8361  if ( mov->write_tmcd == -1 && (mov->mode == MODE_MOV || mov->mode == MODE_MP4)
8362  || mov->write_tmcd == 1) {
8363  AVDictionaryEntry *global_tcr = av_dict_get(s->metadata, "timecode",
8364  NULL, 0);
8365 
8366  /* +1 tmcd track for each video stream with a timecode */
8367  for (i = 0; i < s->nb_streams; i++) {
8368  AVStream *st = s->streams[i];
8369  AVDictionaryEntry *t = global_tcr;
8370  if (st->codecpar->codec_type == AVMEDIA_TYPE_VIDEO &&
8371  (t || (t=av_dict_get(st->metadata, "timecode", NULL, 0)))) {
8372  AVTimecode tc;
8373  ret = mov_check_timecode_track(s, &tc, st, t->value);
8374  if (ret >= 0)
8375  mov->nb_meta_tmcd++;
8376  }
8377  }
8378 
8379  /* check if there is already a tmcd track to remux */
8380  if (mov->nb_meta_tmcd) {
8381  for (i = 0; i < s->nb_streams; i++) {
8382  AVStream *st = s->streams[i];
8383  if (st->codecpar->codec_tag == MKTAG('t','m','c','d')) {
8384  av_log(s, AV_LOG_WARNING, "You requested a copy of the original timecode track "
8385  "so timecode metadata are now ignored\n");
8386  mov->nb_meta_tmcd = 0;
8387  }
8388  }
8389  }
8390 
8391  mov->nb_tracks += mov->nb_meta_tmcd;
8392  }
8393 
8394  // Reserve an extra stream for chapters for the case where chapters
8395  // are written in the trailer
8396  mov->tracks = av_calloc(mov->nb_tracks + 1, sizeof(*mov->tracks));
8397  if (!mov->tracks)
8398  return AVERROR(ENOMEM);
8399 
8400  for (i = 0; i < mov->nb_tracks; i++) {
8401  MOVTrack *track = &mov->tracks[i];
8402 
8403  track->stsd_count = 1;
8404  track->extradata = av_calloc(track->stsd_count, sizeof(*track->extradata));
8405  track->extradata_size = av_calloc(track->stsd_count, sizeof(*track->extradata_size));
8406  if (!track->extradata || !track->extradata_size)
8407  return AVERROR(ENOMEM);
8408  }
8409 
8410  if (mov->encryption_scheme_str != NULL && strcmp(mov->encryption_scheme_str, "none") != 0) {
8411  if (strcmp(mov->encryption_scheme_str, "cenc-aes-ctr") == 0) {
8413 
8414  if (mov->encryption_key_len != AES_CTR_KEY_SIZE) {
8415  av_log(s, AV_LOG_ERROR, "Invalid encryption key len %d expected %d\n",
8417  return AVERROR(EINVAL);
8418  }
8419 
8420  if (mov->encryption_kid_len != CENC_KID_SIZE) {
8421  av_log(s, AV_LOG_ERROR, "Invalid encryption kid len %d expected %d\n",
8423  return AVERROR(EINVAL);
8424  }
8425  } else {
8426  av_log(s, AV_LOG_ERROR, "unsupported encryption scheme %s\n",
8427  mov->encryption_scheme_str);
8428  return AVERROR(EINVAL);
8429  }
8430  }
8431 
8432 #if CONFIG_IAMFENC
8433  ret = mov_init_iamf_track(s);
8434  if (ret < 0)
8435  return ret;
8436 #endif
8437 
8438  for (int j = 0, i = 0; j < s->nb_streams; j++) {
8439  AVStream *st = s->streams[j];
8440 
8441  if (st != st->priv_data) {
8442  if (has_iamf)
8443  i += has_iamf--;
8444  continue;
8445  }
8446  st->priv_data = &mov->tracks[i++];
8447  }
8448 
8449  AVRational movie_timescale = (AVRational) { 0, 1 };
8450  for (i = 0; i < s->nb_streams; i++) {
8451  AVStream *st= s->streams[i];
8452  MOVTrack *track = st->priv_data;
8453 
8454  if (!track)
8455  continue;
8456 
8457  if (!track->st) {
8458  track->st = st;
8459  track->par = st->codecpar;
8460  }
8461 
8462  movie_timescale = av_gcd_q(movie_timescale, st->time_base, INT_MAX, (AVRational){1,0});
8463  }
8464  if (!movie_timescale.den)
8465  movie_timescale = MOV_TIMESCALE_Q;
8466 
8467  if (!mov->movie_timescale)
8468  mov->movie_timescale = FFMAX(movie_timescale.den, MOV_TIMESCALE);
8469 
8470  for (i = 0; i < s->nb_streams; i++) {
8471  AVStream *st= s->streams[i];
8472  MOVTrack *track = st->priv_data;
8473  AVDictionaryEntry *lang = av_dict_get(st->metadata, "language", NULL,0);
8474 
8475  if (!track)
8476  continue;
8477 
8478  track->language = ff_mov_iso639_to_lang(lang?lang->value:"und", mov->mode!=MODE_MOV);
8479  if (track->language < 0)
8480  track->language = 32767; // Unspecified Macintosh language code
8481  track->mode = mov->mode;
8482  if (!track->tag)
8483  track->tag = mov_find_codec_tag(s, track);
8484  if (!track->tag) {
8485  av_log(s, AV_LOG_ERROR, "Could not find tag for codec %s in stream #%d, "
8486  "codec not currently supported in container\n",
8488  return AVERROR(EINVAL);
8489  }
8490  /* If hinting of this track is enabled by a later hint track,
8491  * this is updated. */
8492  track->hint_track = -1;
8493  track->start_dts = AV_NOPTS_VALUE;
8494  track->start_cts = AV_NOPTS_VALUE;
8495  track->end_pts = AV_NOPTS_VALUE;
8496  track->dts_shift = AV_NOPTS_VALUE;
8497  if (st->codecpar->codec_type == AVMEDIA_TYPE_VIDEO) {
8498  if (track->tag == MKTAG('m','x','3','p') || track->tag == MKTAG('m','x','3','n') ||
8499  track->tag == MKTAG('m','x','4','p') || track->tag == MKTAG('m','x','4','n') ||
8500  track->tag == MKTAG('m','x','5','p') || track->tag == MKTAG('m','x','5','n')) {
8501  if (st->codecpar->width != 720 || (st->codecpar->height != 608 && st->codecpar->height != 512)) {
8502  av_log(s, AV_LOG_ERROR, "D-10/IMX must use 720x608 or 720x512 video resolution\n");
8503  return AVERROR(EINVAL);
8504  }
8505  track->height = track->tag >> 24 == 'n' ? 486 : 576;
8506  }
8507  if (mov->video_track_timescale) {
8508  track->timescale = mov->video_track_timescale;
8509  if (mov->mode == MODE_ISM && mov->video_track_timescale != 10000000)
8510  av_log(s, AV_LOG_WARNING, "Warning: some tools, like mp4split, assume a timescale of 10000000 for ISMV.\n");
8511  } else {
8512  track->timescale = st->time_base.den;
8513  while(track->timescale < 10000)
8514  track->timescale *= 2;
8515  }
8516  if (st->codecpar->width > 65535 || st->codecpar->height > 65535) {
8517  av_log(s, AV_LOG_ERROR, "Resolution %dx%d too large for mov/mp4\n", st->codecpar->width, st->codecpar->height);
8518  return AVERROR(EINVAL);
8519  }
8520  if (track->mode == MODE_MOV && track->timescale > 100000)
8522  "WARNING codec timebase is very high. If duration is too long,\n"
8523  "file may not be playable by quicktime. Specify a shorter timebase\n"
8524  "or choose different container.\n");
8525  if (track->mode == MODE_MOV &&
8526  track->par->codec_id == AV_CODEC_ID_RAWVIDEO &&
8527  track->tag == MKTAG('r','a','w',' ')) {
8528  enum AVPixelFormat pix_fmt = track->par->format;
8529  if (pix_fmt == AV_PIX_FMT_NONE && track->par->bits_per_coded_sample == 1)
8531  track->is_unaligned_qt_rgb =
8534  pix_fmt == AV_PIX_FMT_PAL8 ||
8538  }
8539  if (track->par->codec_id == AV_CODEC_ID_VP9 && track->mode != MODE_MP4) {
8540  av_log(s, AV_LOG_ERROR, "%s only supported in MP4.\n", avcodec_get_name(track->par->codec_id));
8541  return AVERROR(EINVAL);
8542  } else if (track->par->codec_id == AV_CODEC_ID_AV1 &&
8543  track->mode != MODE_MP4 && track->mode != MODE_AVIF) {
8544  av_log(s, AV_LOG_ERROR, "%s only supported in MP4 and AVIF.\n", avcodec_get_name(track->par->codec_id));
8545  return AVERROR(EINVAL);
8546  } else if (track->par->codec_id == AV_CODEC_ID_VP8) {
8547  /* altref frames handling is not defined in the spec as of version v1.0,
8548  * so just forbid muxing VP8 streams altogether until a new version does */
8549  av_log(s, AV_LOG_ERROR, "VP8 muxing is currently not supported.\n");
8550  return AVERROR_PATCHWELCOME;
8551  } else if (track->par->codec_id == AV_CODEC_ID_APV) {
8552  ret = ff_isom_init_apvc(&track->apv, s);
8553  if (ret < 0)
8554  return ret;
8555  }
8556  if (is_cover_image(st)) {
8557  track->cover_image = av_packet_alloc();
8558  if (!track->cover_image)
8559  return AVERROR(ENOMEM);
8560  }
8561  } else if (st->codecpar->codec_type == AVMEDIA_TYPE_AUDIO) {
8562  track->timescale = st->codecpar->sample_rate;
8564  av_log(s, AV_LOG_WARNING, "track %d: codec frame size is not set\n", i);
8565  track->audio_vbr = 1;
8566  }else if (st->codecpar->codec_id == AV_CODEC_ID_ADPCM_MS ||
8569  if (!st->codecpar->block_align) {
8570  av_log(s, AV_LOG_ERROR, "track %d: codec block align is not set for adpcm\n", i);
8571  return AVERROR(EINVAL);
8572  }
8573  track->sample_size = st->codecpar->block_align;
8574  }else if (st->codecpar->frame_size > 1){ /* assume compressed audio */
8575  track->audio_vbr = 1;
8576  }else{
8577  track->sample_size = (av_get_bits_per_sample(st->codecpar->codec_id) >> 3) *
8579  }
8580  if (st->codecpar->codec_id == AV_CODEC_ID_ILBC ||
8582  track->audio_vbr = 1;
8583  }
8584  if (track->mode != MODE_MOV &&
8585  track->par->codec_id == AV_CODEC_ID_MP3 && track->timescale < 16000) {
8586  if (s->strict_std_compliance >= FF_COMPLIANCE_NORMAL) {
8587  av_log(s, AV_LOG_ERROR, "track %d: muxing mp3 at %dhz is not standard, to mux anyway set strict to -1\n",
8588  i, track->par->sample_rate);
8589  return AVERROR(EINVAL);
8590  } else {
8591  av_log(s, AV_LOG_WARNING, "track %d: muxing mp3 at %dhz is not standard in MP4\n",
8592  i, track->par->sample_rate);
8593  }
8594  }
8595  if (track->par->codec_id == AV_CODEC_ID_FLAC ||
8596  track->par->codec_id == AV_CODEC_ID_TRUEHD ||
8597  track->par->codec_id == AV_CODEC_ID_OPUS) {
8598  if (track->mode != MODE_MP4) {
8599  av_log(s, AV_LOG_ERROR, "%s only supported in MP4.\n", avcodec_get_name(track->par->codec_id));
8600  return AVERROR(EINVAL);
8601  }
8602  if (track->par->codec_id == AV_CODEC_ID_TRUEHD &&
8603  s->strict_std_compliance > FF_COMPLIANCE_EXPERIMENTAL) {
8605  "%s in MP4 support is experimental, add "
8606  "'-strict %d' if you want to use it.\n",
8608  return AVERROR_EXPERIMENTAL;
8609  }
8610  }
8611  } else if (st->codecpar->codec_type == AVMEDIA_TYPE_SUBTITLE) {
8612  track->timescale = st->time_base.den;
8613 
8614  if (track->par->codec_id == AV_CODEC_ID_TTML) {
8615  /* 14496-30 requires us to use a single sample per fragment
8616  for TTML, for which we define a per-track flag.
8617 
8618  We set the flag in case we are receiving TTML paragraphs
8619  from the input, in other words in case we are not doing
8620  stream copy. */
8623 
8624  if (track->mode != MODE_ISM &&
8625  track->par->codec_tag == MOV_ISMV_TTML_TAG &&
8626  s->strict_std_compliance > FF_COMPLIANCE_UNOFFICIAL) {
8628  "ISMV style TTML support with the 'dfxp' tag in "
8629  "non-ISMV formats is not officially supported. Add "
8630  "'-strict unofficial' if you want to use it.\n");
8631  return AVERROR_EXPERIMENTAL;
8632  }
8633  }
8634  } else if (st->codecpar->codec_type == AVMEDIA_TYPE_DATA) {
8635  track->timescale = st->time_base.den;
8636  } else {
8637  track->timescale = mov->movie_timescale;
8638  }
8639  if (!track->height)
8640  track->height = st->codecpar->height;
8641  /* The Protected Interoperable File Format (PIFF) standard, used by ISMV recommends but
8642  doesn't mandate a track timescale of 10,000,000. The muxer allows a custom timescale
8643  for video tracks, so if user-set, it isn't overwritten */
8644  if (mov->mode == MODE_ISM &&
8647  track->timescale = 10000000;
8648  }
8649 
8650  avpriv_set_pts_info(st, 64, 1, track->timescale);
8651 
8653  ret = ff_mov_cenc_init(&track->cenc, mov->encryption_key,
8654  (track->par->codec_id == AV_CODEC_ID_H264 || track->par->codec_id == AV_CODEC_ID_HEVC ||
8655  track->par->codec_id == AV_CODEC_ID_VVC || track->par->codec_id == AV_CODEC_ID_AV1),
8656  track->par->codec_id, s->flags & AVFMT_FLAG_BITEXACT);
8657  if (ret)
8658  return ret;
8659  }
8660  }
8661 
8662  for (i = 0; i < s->nb_stream_groups; i++) {
8663  AVStreamGroup *stg = s->stream_groups[i];
8664 
8665  switch (stg->type) {
8668  AVStream *st = stg->streams[lcevc->el_index];
8669  MOVTrack *track = st->priv_data;
8670 
8671  for (int j = 0; j < mov->nb_tracks; j++) {
8672  MOVTrack *trk = &mov->tracks[j];
8673 
8674  if (trk->st == stg->streams[!lcevc->el_index]) {
8675  track->src_track = av_malloc(sizeof(*track->src_track));
8676  if (!track->src_track)
8677  return AVERROR(ENOMEM);
8678  *track->src_track = j;
8679  track->nb_src_track = 1;
8680  break;
8681  }
8682  }
8683 
8684  track->par->width = lcevc->width;
8685  track->par->height = track->height = lcevc->height;
8686  break;
8687  }
8689  const AVStreamGroupTREF *tref = stg->params.tref;
8690  MOVTrack *track;
8691 
8692  if (tref->metadata_index >= stg->nb_streams)
8693  return AVERROR(EINVAL);
8694 
8695  track = stg->streams[tref->metadata_index]->priv_data;
8696  for (int j = 0; j < stg->nb_streams; j++) {
8697  const AVStream *st2 = stg->streams[j];
8698  int index = -1;
8699 
8700  if (j == tref->metadata_index)
8701  continue;
8702 
8703  for (int k = 0; k < mov->nb_tracks; k++) {
8704  if (mov->tracks[k].st != st2)
8705  continue;
8706  index = k;
8707  break;
8708  }
8709  if (index < 0)
8710  return AVERROR(EINVAL);
8711 
8712  int *tmp = av_realloc(track->src_track,
8713  (track->nb_src_track + 1) * sizeof(*track->src_track));
8714  if (!tmp)
8715  return AVERROR(ENOMEM);
8716  track->src_track = tmp;
8717  track->src_track[track->nb_src_track++] = index;
8718  }
8719  break;
8720  }
8721  default:
8722  break;
8723  }
8724  }
8725 
8726  /* fill src_track for tmcd tracks not covered by stream groups or
8727  * created by this muxer, retaining the old behavior of src_track
8728  * being arbitrarily 0. */
8729  for (i = 0; i < s->nb_streams; i++) {
8730  AVStream *st = s->streams[i];
8731  MOVTrack *track = st->priv_data;
8732  if (st->codecpar->codec_tag != MKTAG('t','m','c','d') ||
8733  track->nb_src_track)
8734  continue;
8735 
8736  track->src_track = av_malloc(sizeof(*track->src_track));
8737  if (!track->src_track)
8738  return AVERROR(ENOMEM);
8739  *track->src_track = 0;
8740  track->nb_src_track = 1;
8741  }
8742 
8743  enable_tracks(s);
8744  return 0;
8745 }
8746 
8748 {
8749  AVIOContext *pb = s->pb;
8750  MOVMuxContext *mov = s->priv_data;
8751  int ret, hint_track = 0, tmcd_track = 0, nb_tracks = mov->nb_streams;
8752 
8753  if (mov->mode & (MODE_MP4|MODE_MOV|MODE_IPOD) && s->nb_chapters)
8754  nb_tracks++;
8755 
8756  if (mov->flags & FF_MOV_FLAG_RTP_HINT) {
8757  hint_track = nb_tracks;
8758  for (int i = 0; i < mov->nb_streams; i++) {
8759  if (rtp_hinting_needed(mov->tracks[i].st))
8760  nb_tracks++;
8761  }
8762  }
8763 
8764  if (mov->nb_meta_tmcd)
8765  tmcd_track = nb_tracks;
8766 
8767  for (int i = 0; i < mov->nb_streams; i++) {
8768  MOVTrack *track = &mov->tracks[i];
8769  AVStream *st = track->st;
8770 
8771  /* copy extradata if it exists */
8772  if (st->codecpar->extradata_size) {
8775  else if (!TAG_IS_AVCI(track->tag) && st->codecpar->codec_id != AV_CODEC_ID_DNXHD) {
8776  track->extradata_size[track->last_stsd_index] = st->codecpar->extradata_size;
8777  track->extradata[track->last_stsd_index] =
8779  if (!track->extradata[track->last_stsd_index]) {
8780  return AVERROR(ENOMEM);
8781  }
8782  memcpy(track->extradata[track->last_stsd_index],
8783  st->codecpar->extradata, track->extradata_size[track->last_stsd_index]);
8784  memset(track->extradata[track->last_stsd_index] + track->extradata_size[track->last_stsd_index],
8786  }
8787  }
8788 
8789  if (st->codecpar->codec_type != AVMEDIA_TYPE_AUDIO ||
8792  continue;
8793 
8794  for (int j = 0; j < mov->nb_streams; j++) {
8795  AVStream *stj= mov->tracks[j].st;
8796  MOVTrack *trackj= &mov->tracks[j];
8797  if (j == i)
8798  continue;
8799 
8800  if (stj->codecpar->codec_type == AVMEDIA_TYPE_AUDIO &&
8801  (trackj->par->ch_layout.nb_channels != 1 ||
8804  )
8805  track->mono_as_fc = -1;
8806 
8807  if (stj->codecpar->codec_type == AVMEDIA_TYPE_AUDIO &&
8810  trackj->par->ch_layout.nb_channels == 1 && track->mono_as_fc >= 0
8811  )
8812  track->mono_as_fc++;
8813 
8814  if (stj->codecpar->codec_type != AVMEDIA_TYPE_AUDIO ||
8817  trackj->language != track->language ||
8818  trackj->tag != track->tag
8819  )
8820  continue;
8821  track->multichannel_as_mono++;
8822  }
8823  }
8824 
8825  if (!(mov->flags & FF_MOV_FLAG_DELAY_MOOV) ||
8827  if ((ret = mov_write_identification(pb, s)) < 0)
8828  return ret;
8829  }
8830 
8831  if (mov->reserved_moov_size){
8832  mov->reserved_header_pos = avio_tell(pb);
8833  if (mov->reserved_moov_size > 0)
8834  avio_skip(pb, mov->reserved_moov_size);
8835  }
8836 
8837  if (mov->flags & FF_MOV_FLAG_FRAGMENT) {
8838  /* If no fragmentation options have been set, set a default. */
8839  if (!(mov->flags & (FF_MOV_FLAG_FRAG_KEYFRAME |
8844  if (mov->flags & FF_MOV_FLAG_HYBRID_FRAGMENTED) {
8845  avio_wb32(pb, 8); // placeholder for extended size field (64 bit)
8846  ffio_wfourcc(pb, mov->mode == MODE_MOV ? "wide" : "free");
8847  mov->mdat_pos = avio_tell(pb);
8848  // The free/wide header that later will be converted into an
8849  // mdat, covering the initial moov and all the fragments.
8850  avio_wb32(pb, 0);
8851  ffio_wfourcc(pb, mov->mode == MODE_MOV ? "wide" : "free");
8852  // Write an ftyp atom, hidden in a free/wide. This is neither
8853  // exposed while the file is written, as fragmented, nor when the
8854  // file is finalized into non-fragmented form. However, this allows
8855  // accessing a pristine, sequential ftyp+moov init segment, even
8856  // after the file is finalized. It also allows dumping the whole
8857  // contents of the mdat box, to get the fragmented form of the
8858  // file.
8859  if ((ret = mov_write_identification(pb, s)) < 0)
8860  return ret;
8861  update_size(pb, mov->mdat_pos);
8862  }
8863  } else if (mov->mode != MODE_AVIF) {
8864  if (mov->flags & FF_MOV_FLAG_FASTSTART)
8865  mov->reserved_header_pos = avio_tell(pb);
8866  mov_write_mdat_tag(pb, mov);
8867  }
8868 
8870  if (mov->time)
8871  mov->time += 0x7C25B080; // 1970 based -> 1904 based
8872 
8873  if (mov->chapter_track)
8874  if ((ret = mov_create_chapter_track(s, mov->chapter_track)) < 0)
8875  return ret;
8876 
8877  if (mov->flags & FF_MOV_FLAG_RTP_HINT) {
8878  for (int i = 0; i < mov->nb_streams; i++) {
8879  if (rtp_hinting_needed(mov->tracks[i].st)) {
8880  if ((ret = ff_mov_init_hinting(s, hint_track, i)) < 0)
8881  return ret;
8882  hint_track++;
8883  }
8884  }
8885  }
8886 
8887  if (mov->nb_meta_tmcd) {
8888  const AVDictionaryEntry *t, *global_tcr = av_dict_get(s->metadata,
8889  "timecode", NULL, 0);
8890  /* Initialize the tmcd tracks */
8891  for (int i = 0; i < mov->nb_streams; i++) {
8892  AVStream *st = mov->tracks[i].st;
8893  t = global_tcr;
8894 
8895  if (st->codecpar->codec_type == AVMEDIA_TYPE_VIDEO) {
8896  AVTimecode tc;
8897  if (!t)
8898  t = av_dict_get(st->metadata, "timecode", NULL, 0);
8899  if (!t)
8900  continue;
8901  if (mov_check_timecode_track(s, &tc, st, t->value) < 0)
8902  continue;
8903  if ((ret = mov_create_timecode_track(s, tmcd_track, i, tc)) < 0)
8904  return ret;
8905  tmcd_track++;
8906  }
8907  }
8908  }
8909 
8910  avio_flush(pb);
8911 
8912  if (mov->flags & FF_MOV_FLAG_ISML)
8913  mov_write_isml_manifest(pb, mov, s);
8914 
8915  if (mov->flags & FF_MOV_FLAG_EMPTY_MOOV &&
8916  !(mov->flags & FF_MOV_FLAG_DELAY_MOOV)) {
8917  if ((ret = mov_write_moov_tag(pb, mov, s)) < 0)
8918  return ret;
8919  mov->moov_written = 1;
8920  if (mov->flags & FF_MOV_FLAG_GLOBAL_SIDX)
8921  mov->reserved_header_pos = avio_tell(pb);
8922  }
8923 
8924  return 0;
8925 }
8926 
8928 {
8929  int ret;
8930  AVIOContext *moov_buf;
8931  MOVMuxContext *mov = s->priv_data;
8932 
8933  if ((ret = ffio_open_null_buf(&moov_buf)) < 0)
8934  return ret;
8935  if ((ret = mov_write_moov_tag(moov_buf, mov, s)) < 0)
8936  return ret;
8937  return ffio_close_null_buf(moov_buf);
8938 }
8939 
8941 {
8942  int ret;
8943  AVIOContext *buf;
8944  MOVMuxContext *mov = s->priv_data;
8945 
8946  if ((ret = ffio_open_null_buf(&buf)) < 0)
8947  return ret;
8948  mov_write_sidx_tags(buf, mov, -1, 0);
8949  return ffio_close_null_buf(buf);
8950 }
8951 
8952 /*
8953  * This function gets the moov size if moved to the top of the file: the chunk
8954  * offset table can switch between stco (32-bit entries) to co64 (64-bit
8955  * entries) when the moov is moved to the beginning, so the size of the moov
8956  * would change. It also updates the chunk offset tables.
8957  */
8959 {
8960  int i, moov_size, moov_size2;
8961  MOVMuxContext *mov = s->priv_data;
8962 
8963  moov_size = get_moov_size(s);
8964  if (moov_size < 0)
8965  return moov_size;
8966 
8967  for (i = 0; i < mov->nb_tracks; i++)
8968  mov->tracks[i].data_offset += moov_size;
8969 
8970  moov_size2 = get_moov_size(s);
8971  if (moov_size2 < 0)
8972  return moov_size2;
8973 
8974  /* if the size changed, we just switched from stco to co64 and need to
8975  * update the offsets */
8976  if (moov_size2 != moov_size)
8977  for (i = 0; i < mov->nb_tracks; i++)
8978  mov->tracks[i].data_offset += moov_size2 - moov_size;
8979 
8980  return moov_size2;
8981 }
8982 
8984 {
8985  int i, sidx_size;
8986  MOVMuxContext *mov = s->priv_data;
8987 
8988  sidx_size = get_sidx_size(s);
8989  if (sidx_size < 0)
8990  return sidx_size;
8991 
8992  for (i = 0; i < mov->nb_tracks; i++)
8993  mov->tracks[i].data_offset += sidx_size;
8994 
8995  return sidx_size;
8996 }
8997 
8999 {
9000  int moov_size;
9001  MOVMuxContext *mov = s->priv_data;
9002 
9003  if (mov->flags & FF_MOV_FLAG_FRAGMENT)
9004  moov_size = compute_sidx_size(s);
9005  else
9006  moov_size = compute_moov_size(s);
9007  if (moov_size < 0)
9008  return moov_size;
9009 
9010  return ff_format_shift_data(s, mov->reserved_header_pos, moov_size);
9011 }
9012 
9014 {
9015  MOVMuxContext *mov = s->priv_data;
9016  AVIOContext *pb = s->pb;
9017 
9018  /* Write size of mdat tag */
9019  if (mov->mdat_size + 8 <= UINT32_MAX) {
9020  avio_seek(pb, mov->mdat_pos, SEEK_SET);
9021  avio_wb32(pb, mov->mdat_size + 8);
9023  ffio_wfourcc(pb, "mdat"); // overwrite the original free/wide into a mdat
9024  } else {
9025  /* overwrite 'wide' placeholder atom */
9026  avio_seek(pb, mov->mdat_pos - 8, SEEK_SET);
9027  /* special value: real atom size will be 64 bit value after
9028  * tag field */
9029  avio_wb32(pb, 1);
9030  ffio_wfourcc(pb, "mdat");
9031  avio_wb64(pb, mov->mdat_size + 16);
9032  }
9033 }
9034 
9036 {
9037  MOVMuxContext *mov = s->priv_data;
9038  AVIOContext *pb = s->pb;
9039  int res = 0;
9040  int i;
9041  int64_t moov_pos;
9042 
9043  /*
9044  * Before actually writing the trailer, make sure that there are no
9045  * dangling subtitles, that need a terminating sample.
9046  */
9047  for (i = 0; i < mov->nb_tracks; i++) {
9048  MOVTrack *trk = &mov->tracks[i];
9049  if (trk->par->codec_id == AV_CODEC_ID_MOV_TEXT &&
9052  trk->last_sample_is_subtitle_end = 1;
9053  }
9054  }
9055 
9056  //Also check for a buffered EAC3 packet
9057  for (i = 0; i < mov->nb_tracks; i++) {
9058  MOVTrack *trk = &mov->tracks[i];
9059  if (trk->par->codec_id != AV_CODEC_ID_EAC3)
9060  continue;
9061  struct eac3_info *info = trk->eac3_priv;
9062  if (!info || !info->pkt || !info->pkt->size)
9063  continue;
9064 
9065  av_packet_move_ref(mov->pkt, info->pkt);
9066  info->eof = 1;
9067  res = mov_write_single_packet(s, mov->pkt);
9068  if (res < 0)
9069  return res;
9070 
9071  av_packet_unref(mov->pkt);
9072  }
9073 
9074  // Check if we have any tracks that require squashing.
9075  // In that case, we'll have to write the packet here.
9076  if ((res = mov_write_squashed_packets(s)) < 0)
9077  return res;
9078 
9079  // If there were no chapters when the header was written, but there
9080  // are chapters now, write them in the trailer. This only works
9081  // when we are not doing fragments.
9082  if (!mov->chapter_track && !(mov->flags & FF_MOV_FLAG_FRAGMENT)) {
9083  if (mov->mode & (MODE_MP4|MODE_MOV|MODE_IPOD) && s->nb_chapters) {
9084  mov->chapter_track = mov->nb_tracks++;
9085  if ((res = mov_create_chapter_track(s, mov->chapter_track)) < 0)
9086  return res;
9087  }
9088  }
9089 
9090  if (!(mov->flags & FF_MOV_FLAG_FRAGMENT) ||
9092  if (mov->flags & FF_MOV_FLAG_HYBRID_FRAGMENTED) {
9094  mov->mdat_size = avio_tell(pb) - mov->mdat_pos - 8;
9095  for (i = 0; i < mov->nb_tracks; i++) {
9096  MOVTrack *track = &mov->tracks[i];
9097  track->data_offset = 0;
9098  av_free(track->cluster);
9099  track->cluster = track->cluster_written;
9100  track->entry = track->entry_written;
9101  track->cluster_written = NULL;
9102  track->entry_written = 0;
9103  track->chunkCount = 0; // Force build_chunks to rebuild the list of chunks
9104  }
9105  // Clear the empty_moov flag, as we do want the moov to include
9106  // all the samples at this point.
9107  mov->flags &= ~FF_MOV_FLAG_EMPTY_MOOV;
9108  }
9109 
9110  moov_pos = avio_tell(pb);
9111 
9112  if (!(mov->flags & FF_MOV_FLAG_HYBRID_FRAGMENTED))
9114 
9115  avio_seek(pb, mov->reserved_moov_size > 0 ? mov->reserved_header_pos : moov_pos, SEEK_SET);
9116 
9117  if (mov->flags & FF_MOV_FLAG_FASTSTART) {
9118  av_log(s, AV_LOG_INFO, "Starting second pass: moving the moov atom to the beginning of the file\n");
9119  res = shift_data(s);
9120  if (res < 0)
9121  return res;
9122  avio_seek(pb, mov->reserved_header_pos, SEEK_SET);
9123  if ((res = mov_write_moov_tag(pb, mov, s)) < 0)
9124  return res;
9125  } else if (mov->reserved_moov_size > 0) {
9126  int64_t size;
9127  if ((res = mov_write_moov_tag(pb, mov, s)) < 0)
9128  return res;
9129  size = mov->reserved_moov_size - (avio_tell(pb) - mov->reserved_header_pos);
9130  if (size < 8){
9131  av_log(s, AV_LOG_ERROR, "reserved_moov_size is too small, needed %"PRId64" additional\n", 8-size);
9132  return AVERROR(EINVAL);
9133  }
9134  avio_wb32(pb, size);
9135  ffio_wfourcc(pb, "free");
9136  ffio_fill(pb, 0, size - 8);
9137  avio_seek(pb, moov_pos, SEEK_SET);
9138  } else {
9139  if ((res = mov_write_moov_tag(pb, mov, s)) < 0)
9140  return res;
9141  }
9142 
9143  if (mov->flags & FF_MOV_FLAG_HYBRID_FRAGMENTED) {
9144  // With hybrid fragmentation, only write the mdat size (hiding
9145  // the original moov and all the fragments within the mdat)
9146  // after we've successfully written the complete moov, to avoid
9147  // risk for an unreadable file if writing the final moov fails.
9149  }
9150 
9151  res = 0;
9152  } else {
9154  for (i = 0; i < mov->nb_tracks; i++)
9155  mov->tracks[i].data_offset = 0;
9156  if (mov->flags & FF_MOV_FLAG_GLOBAL_SIDX) {
9157  int64_t end;
9158  av_log(s, AV_LOG_INFO, "Starting second pass: inserting sidx atoms\n");
9159  res = shift_data(s);
9160  if (res < 0)
9161  return res;
9162  end = avio_tell(pb);
9163  avio_seek(pb, mov->reserved_header_pos, SEEK_SET);
9164  mov_write_sidx_tags(pb, mov, -1, 0);
9165  avio_seek(pb, end, SEEK_SET);
9166  }
9167  if (!(mov->flags & FF_MOV_FLAG_SKIP_TRAILER)) {
9169  res = mov_write_mfra_tag(pb, mov);
9170  if (res < 0)
9171  return res;
9172  }
9173  }
9174 
9175  return res;
9176 }
9177 
9179  const AVPacket *pkt)
9180 {
9181  int ret = 1;
9182 
9183  if (st->codecpar->codec_id == AV_CODEC_ID_AAC) {
9184  if (pkt->size > 2 && (AV_RB16(pkt->data) & 0xfff0) == 0xfff0)
9185  ret = ff_stream_add_bitstream_filter(st, "aac_adtstoasc", NULL);
9186  } else if (st->codecpar->codec_id == AV_CODEC_ID_VP9) {
9187  ret = ff_stream_add_bitstream_filter(st, "vp9_superframe", NULL);
9188  }
9189 
9190  return ret;
9191 }
9192 
9193 #if CONFIG_AVIF_MUXER
9194 static int avif_write_trailer(AVFormatContext *s)
9195 {
9196  AVIOContext *pb = s->pb;
9197  MOVMuxContext *mov = s->priv_data;
9198  int64_t pos_backup, extent_offsets[2];
9199  uint8_t *buf;
9200  int buf_size, moov_size;
9201 
9202  if (mov->moov_written) return 0;
9203 
9204  mov->is_animated_avif = s->streams[0]->nb_frames > 1;
9205  if (mov->is_animated_avif && mov->nb_streams > 1) {
9206  // For animated avif with alpha channel, we need to write a tref tag
9207  // with type "auxl".
9208  MovTag *tag = mov_add_tref_tag(mov, &mov->tracks[1], MKTAG('a', 'u', 'x', 'l'));
9209  if (!tag)
9210  return AVERROR(ENOMEM);
9211 
9212  int ret = mov_add_tref_id(mov, tag, 1);
9213  if (ret < 0)
9214  return ret;
9215  }
9217  mov_write_meta_tag(pb, mov, s);
9218 
9219  moov_size = get_moov_size(s);
9220  for (int i = 0; i < mov->nb_tracks; i++)
9221  mov->tracks[i].data_offset = avio_tell(pb) + moov_size + 8;
9222 
9223  if (mov->is_animated_avif) {
9224  int ret;
9225  if ((ret = mov_write_moov_tag(pb, mov, s)) < 0)
9226  return ret;
9227  }
9228 
9229  buf_size = avio_get_dyn_buf(mov->mdat_buf, &buf);
9230  avio_wb32(pb, buf_size + 8);
9231  ffio_wfourcc(pb, "mdat");
9232 
9233  // The offset for the YUV planes is the starting position of mdat.
9234  extent_offsets[0] = avio_tell(pb);
9235  // The offset for alpha plane is YUV offset + YUV size.
9236  extent_offsets[1] = extent_offsets[0] + mov->avif_extent_length[0];
9237 
9238  avio_write(pb, buf, buf_size);
9239 
9240  // write extent offsets.
9241  pos_backup = avio_tell(pb);
9242  for (int i = 0; i < mov->nb_streams; i++) {
9243  if (extent_offsets[i] != (uint32_t)extent_offsets[i]) {
9244  av_log(s, AV_LOG_ERROR, "extent offset does not fit in 32 bits\n");
9245  return AVERROR_INVALIDDATA;
9246  }
9247  avio_seek(pb, mov->avif_extent_pos[i], SEEK_SET);
9248  avio_wb32(pb, extent_offsets[i]); /* rewrite offset */
9249  }
9250  avio_seek(pb, pos_backup, SEEK_SET);
9251 
9252  return 0;
9253 }
9254 #endif
9255 
9256 #if CONFIG_TGP_MUXER || CONFIG_TG2_MUXER
9257 static const AVCodecTag codec_3gp_tags[] = {
9258  { AV_CODEC_ID_H263, MKTAG('s','2','6','3') },
9259  { AV_CODEC_ID_H264, MKTAG('a','v','c','1') },
9260  { AV_CODEC_ID_MPEG4, MKTAG('m','p','4','v') },
9261  { AV_CODEC_ID_AAC, MKTAG('m','p','4','a') },
9262  { AV_CODEC_ID_AMR_NB, MKTAG('s','a','m','r') },
9263  { AV_CODEC_ID_AMR_WB, MKTAG('s','a','w','b') },
9264  { AV_CODEC_ID_MOV_TEXT, MKTAG('t','x','3','g') },
9265  { AV_CODEC_ID_NONE, 0 },
9266 };
9267 static const AVCodecTag *const codec_3gp_tags_list[] = { codec_3gp_tags, NULL };
9268 #endif
9269 
9270 static const AVCodecTag codec_mp4_tags[] = {
9271  { AV_CODEC_ID_MPEG4, MKTAG('m', 'p', '4', 'v') },
9272  { AV_CODEC_ID_H264, MKTAG('a', 'v', 'c', '1') },
9273  { AV_CODEC_ID_H264, MKTAG('a', 'v', 'c', '3') },
9274  { AV_CODEC_ID_HEVC, MKTAG('h', 'e', 'v', '1') },
9275  { AV_CODEC_ID_HEVC, MKTAG('h', 'v', 'c', '1') },
9276  { AV_CODEC_ID_HEVC, MKTAG('d', 'v', 'h', '1') },
9277  { AV_CODEC_ID_VVC, MKTAG('v', 'v', 'c', '1') },
9278  { AV_CODEC_ID_VVC, MKTAG('v', 'v', 'i', '1') },
9279  { AV_CODEC_ID_EVC, MKTAG('e', 'v', 'c', '1') },
9280  { AV_CODEC_ID_LCEVC, MKTAG('l', 'v', 'c', '1') },
9281  { AV_CODEC_ID_APV, MKTAG('a', 'p', 'v', '1') },
9282  { AV_CODEC_ID_MPEG2VIDEO, MKTAG('m', 'p', '4', 'v') },
9283  { AV_CODEC_ID_MPEG1VIDEO, MKTAG('m', 'p', '4', 'v') },
9284  { AV_CODEC_ID_MJPEG, MKTAG('m', 'p', '4', 'v') },
9285  { AV_CODEC_ID_PNG, MKTAG('m', 'p', '4', 'v') },
9286  { AV_CODEC_ID_JPEG2000, MKTAG('m', 'p', '4', 'v') },
9287  { AV_CODEC_ID_VC1, MKTAG('v', 'c', '-', '1') },
9288  { AV_CODEC_ID_DIRAC, MKTAG('d', 'r', 'a', 'c') },
9289  { AV_CODEC_ID_TSCC2, MKTAG('m', 'p', '4', 'v') },
9290  { AV_CODEC_ID_VP9, MKTAG('v', 'p', '0', '9') },
9291  { AV_CODEC_ID_AV1, MKTAG('a', 'v', '0', '1') },
9292  { AV_CODEC_ID_AAC, MKTAG('m', 'p', '4', 'a') },
9293  { AV_CODEC_ID_ALAC, MKTAG('a', 'l', 'a', 'c') },
9294  { AV_CODEC_ID_MP4ALS, MKTAG('m', 'p', '4', 'a') },
9295  { AV_CODEC_ID_MP3, MKTAG('m', 'p', '4', 'a') },
9296  { AV_CODEC_ID_MP2, MKTAG('m', 'p', '4', 'a') },
9297  { AV_CODEC_ID_AC3, MKTAG('a', 'c', '-', '3') },
9298  { AV_CODEC_ID_EAC3, MKTAG('e', 'c', '-', '3') },
9299  { AV_CODEC_ID_DTS, MKTAG('m', 'p', '4', 'a') },
9300  { AV_CODEC_ID_TRUEHD, MKTAG('m', 'l', 'p', 'a') },
9301  { AV_CODEC_ID_FLAC, MKTAG('f', 'L', 'a', 'C') },
9302  { AV_CODEC_ID_OPUS, MKTAG('O', 'p', 'u', 's') },
9303  { AV_CODEC_ID_VORBIS, MKTAG('m', 'p', '4', 'a') },
9304  { AV_CODEC_ID_QCELP, MKTAG('m', 'p', '4', 'a') },
9305  { AV_CODEC_ID_EVRC, MKTAG('m', 'p', '4', 'a') },
9306  { AV_CODEC_ID_DVD_SUBTITLE, MKTAG('m', 'p', '4', 's') },
9307  { AV_CODEC_ID_MOV_TEXT, MKTAG('t', 'x', '3', 'g') },
9308  { AV_CODEC_ID_BIN_DATA, MKTAG('g', 'p', 'm', 'd') },
9309  { AV_CODEC_ID_MPEGH_3D_AUDIO, MKTAG('m', 'h', 'm', '1') },
9312  { AV_CODEC_ID_FFV1, MKTAG('F', 'F', 'V', '1') },
9313 
9314  /* ISO/IEC 23003-5 integer formats */
9321  /* ISO/IEC 23003-5 floating-point formats */
9326 
9327  { AV_CODEC_ID_AVS3, MKTAG('a', 'v', 's', '3') },
9328 
9329  { AV_CODEC_ID_NONE, 0 },
9330 };
9331 #if CONFIG_MP4_MUXER || CONFIG_PSP_MUXER
9332 static const AVCodecTag *const mp4_codec_tags_list[] = { codec_mp4_tags, NULL };
9333 #endif
9334 
9335 static const AVCodecTag codec_ism_tags[] = {
9336  { AV_CODEC_ID_WMAPRO , MKTAG('w', 'm', 'a', ' ') },
9338  { AV_CODEC_ID_NONE , 0 },
9339 };
9340 
9341 static const AVCodecTag codec_ipod_tags[] = {
9342  { AV_CODEC_ID_H264, MKTAG('a','v','c','1') },
9343  { AV_CODEC_ID_MPEG4, MKTAG('m','p','4','v') },
9344  { AV_CODEC_ID_AAC, MKTAG('m','p','4','a') },
9345  { AV_CODEC_ID_ALAC, MKTAG('a','l','a','c') },
9346  { AV_CODEC_ID_AC3, MKTAG('a','c','-','3') },
9347  { AV_CODEC_ID_MOV_TEXT, MKTAG('t','x','3','g') },
9348  { AV_CODEC_ID_MOV_TEXT, MKTAG('t','e','x','t') },
9349  { AV_CODEC_ID_NONE, 0 },
9350 };
9351 
9352 static const AVCodecTag codec_f4v_tags[] = {
9353  { AV_CODEC_ID_MP3, MKTAG('.','m','p','3') },
9354  { AV_CODEC_ID_AAC, MKTAG('m','p','4','a') },
9355  { AV_CODEC_ID_H264, MKTAG('a','v','c','1') },
9356  { AV_CODEC_ID_VP6A, MKTAG('V','P','6','A') },
9357  { AV_CODEC_ID_VP6F, MKTAG('V','P','6','F') },
9358  { AV_CODEC_ID_NONE, 0 },
9359 };
9360 
9361 #if CONFIG_AVIF_MUXER
9362 
9363 static const AVOption avif_options[] = {
9364  { "movie_timescale", "set movie timescale", offsetof(MOVMuxContext, movie_timescale), AV_OPT_TYPE_INT, {.i64 = MOV_TIMESCALE}, 1, INT_MAX, AV_OPT_FLAG_ENCODING_PARAM},
9365  { "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 },
9366  { NULL },
9367 };
9368 static const AVCodecTag codec_avif_tags[] = {
9369  { AV_CODEC_ID_AV1, MKTAG('a','v','0','1') },
9370  { AV_CODEC_ID_NONE, 0 },
9371 };
9372 static const AVCodecTag *const codec_avif_tags_list[] = { codec_avif_tags, NULL };
9373 
9374 static const AVClass mov_avif_muxer_class = {
9375  .class_name = "avif muxer",
9376  .item_name = av_default_item_name,
9377  .option = avif_options,
9378  .version = LIBAVUTIL_VERSION_INT,
9379 };
9380 #endif
9381 
9382 #if CONFIG_MOV_MUXER
9383 const FFOutputFormat ff_mov_muxer = {
9384  .p.name = "mov",
9385  .p.long_name = NULL_IF_CONFIG_SMALL("QuickTime / MOV"),
9386  .p.extensions = "mov",
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 = (const AVCodecTag* const []){
9399  },
9400  .check_bitstream = mov_check_bitstream,
9401  .p.priv_class = &mov_isobmff_muxer_class,
9402  .flags_internal = FF_OFMT_FLAG_ALLOW_FLUSH,
9403 };
9404 #endif
9405 #if CONFIG_TGP_MUXER
9406 const FFOutputFormat ff_tgp_muxer = {
9407  .p.name = "3gp",
9408  .p.long_name = NULL_IF_CONFIG_SMALL("3GP (3GPP file format)"),
9409  .p.extensions = "3gp",
9410  .priv_data_size = sizeof(MOVMuxContext),
9411  .p.audio_codec = AV_CODEC_ID_AMR_NB,
9412  .p.video_codec = AV_CODEC_ID_H263,
9413  .init = mov_init,
9414  .write_header = mov_write_header,
9415  .write_packet = mov_write_packet,
9416  .write_trailer = mov_write_trailer,
9417  .deinit = mov_free,
9419  .p.codec_tag = codec_3gp_tags_list,
9420  .check_bitstream = mov_check_bitstream,
9421  .p.priv_class = &mov_isobmff_muxer_class,
9422  .flags_internal = FF_OFMT_FLAG_ALLOW_FLUSH,
9423 };
9424 #endif
9425 #if CONFIG_MP4_MUXER
9426 const FFOutputFormat ff_mp4_muxer = {
9427  .p.name = "mp4",
9428  .p.long_name = NULL_IF_CONFIG_SMALL("MP4 (MPEG-4 Part 14)"),
9429  .p.mime_type = "video/mp4",
9430  .p.extensions = "mp4",
9431  .priv_data_size = sizeof(MOVMuxContext),
9432  .p.audio_codec = AV_CODEC_ID_AAC,
9433  .p.video_codec = CONFIG_LIBX264_ENCODER ?
9435  .init = mov_init,
9436  .write_header = mov_write_header,
9437  .write_packet = mov_write_packet,
9438  .write_trailer = mov_write_trailer,
9439  .deinit = mov_free,
9441  .p.codec_tag = mp4_codec_tags_list,
9442  .check_bitstream = mov_check_bitstream,
9443  .p.priv_class = &mov_isobmff_muxer_class,
9444  .flags_internal = FF_OFMT_FLAG_ALLOW_FLUSH,
9445 };
9446 #endif
9447 #if CONFIG_PSP_MUXER
9448 const FFOutputFormat ff_psp_muxer = {
9449  .p.name = "psp",
9450  .p.long_name = NULL_IF_CONFIG_SMALL("PSP MP4 (MPEG-4 Part 14)"),
9451  .p.extensions = "mp4,psp",
9452  .priv_data_size = sizeof(MOVMuxContext),
9453  .p.audio_codec = AV_CODEC_ID_AAC,
9454  .p.video_codec = CONFIG_LIBX264_ENCODER ?
9456  .init = mov_init,
9457  .write_header = mov_write_header,
9458  .write_packet = mov_write_packet,
9459  .write_trailer = mov_write_trailer,
9460  .deinit = mov_free,
9462  .p.codec_tag = mp4_codec_tags_list,
9463  .check_bitstream = mov_check_bitstream,
9464  .p.priv_class = &mov_isobmff_muxer_class,
9465  .flags_internal = FF_OFMT_FLAG_ALLOW_FLUSH,
9466 };
9467 #endif
9468 #if CONFIG_TG2_MUXER
9469 const FFOutputFormat ff_tg2_muxer = {
9470  .p.name = "3g2",
9471  .p.long_name = NULL_IF_CONFIG_SMALL("3GP2 (3GPP2 file format)"),
9472  .p.extensions = "3g2",
9473  .priv_data_size = sizeof(MOVMuxContext),
9474  .p.audio_codec = AV_CODEC_ID_AMR_NB,
9475  .p.video_codec = AV_CODEC_ID_H263,
9476  .init = mov_init,
9477  .write_header = mov_write_header,
9478  .write_packet = mov_write_packet,
9479  .write_trailer = mov_write_trailer,
9480  .deinit = mov_free,
9482  .p.codec_tag = codec_3gp_tags_list,
9483  .check_bitstream = mov_check_bitstream,
9484  .p.priv_class = &mov_isobmff_muxer_class,
9485  .flags_internal = FF_OFMT_FLAG_ALLOW_FLUSH,
9486 };
9487 #endif
9488 #if CONFIG_IPOD_MUXER
9489 const FFOutputFormat ff_ipod_muxer = {
9490  .p.name = "ipod",
9491  .p.long_name = NULL_IF_CONFIG_SMALL("iPod H.264 MP4 (MPEG-4 Part 14)"),
9492  .p.mime_type = "video/mp4",
9493  .p.extensions = "m4v,m4a,m4b",
9494  .priv_data_size = sizeof(MOVMuxContext),
9495  .p.audio_codec = AV_CODEC_ID_AAC,
9496  .p.video_codec = AV_CODEC_ID_H264,
9497  .init = mov_init,
9498  .write_header = mov_write_header,
9499  .write_packet = mov_write_packet,
9500  .write_trailer = mov_write_trailer,
9501  .deinit = mov_free,
9503  .p.codec_tag = (const AVCodecTag* const []){ codec_ipod_tags, 0 },
9504  .check_bitstream = mov_check_bitstream,
9505  .p.priv_class = &mov_isobmff_muxer_class,
9506  .flags_internal = FF_OFMT_FLAG_ALLOW_FLUSH,
9507 };
9508 #endif
9509 #if CONFIG_ISMV_MUXER
9510 const FFOutputFormat ff_ismv_muxer = {
9511  .p.name = "ismv",
9512  .p.long_name = NULL_IF_CONFIG_SMALL("ISMV/ISMA (Smooth Streaming)"),
9513  .p.mime_type = "video/mp4",
9514  .p.extensions = "ismv,isma",
9515  .priv_data_size = sizeof(MOVMuxContext),
9516  .p.audio_codec = AV_CODEC_ID_AAC,
9517  .p.video_codec = AV_CODEC_ID_H264,
9518  .init = mov_init,
9519  .write_header = mov_write_header,
9520  .write_packet = mov_write_packet,
9521  .write_trailer = mov_write_trailer,
9522  .deinit = mov_free,
9524  .p.codec_tag = (const AVCodecTag* const []){
9526  .check_bitstream = mov_check_bitstream,
9527  .p.priv_class = &mov_isobmff_muxer_class,
9528  .flags_internal = FF_OFMT_FLAG_ALLOW_FLUSH,
9529 };
9530 #endif
9531 #if CONFIG_F4V_MUXER
9532 const FFOutputFormat ff_f4v_muxer = {
9533  .p.name = "f4v",
9534  .p.long_name = NULL_IF_CONFIG_SMALL("F4V Adobe Flash Video"),
9535  .p.mime_type = "application/f4v",
9536  .p.extensions = "f4v",
9537  .priv_data_size = sizeof(MOVMuxContext),
9538  .p.audio_codec = AV_CODEC_ID_AAC,
9539  .p.video_codec = AV_CODEC_ID_H264,
9540  .init = mov_init,
9541  .write_header = mov_write_header,
9542  .write_packet = mov_write_packet,
9543  .write_trailer = mov_write_trailer,
9544  .deinit = mov_free,
9545  .p.flags = AVFMT_GLOBALHEADER,
9546  .p.codec_tag = (const AVCodecTag* const []){ codec_f4v_tags, 0 },
9547  .check_bitstream = mov_check_bitstream,
9548  .p.priv_class = &mov_isobmff_muxer_class,
9549  .flags_internal = FF_OFMT_FLAG_ALLOW_FLUSH,
9550 };
9551 #endif
9552 #if CONFIG_AVIF_MUXER
9553 const FFOutputFormat ff_avif_muxer = {
9554  .p.name = "avif",
9555  .p.long_name = NULL_IF_CONFIG_SMALL("AVIF"),
9556  .p.mime_type = "image/avif",
9557  .p.extensions = "avif",
9558  .priv_data_size = sizeof(MOVMuxContext),
9559  .p.video_codec = AV_CODEC_ID_AV1,
9560  .init = mov_init,
9561  .write_header = mov_write_header,
9562  .write_packet = mov_write_packet,
9563  .write_trailer = avif_write_trailer,
9564  .deinit = mov_free,
9565  .p.flags = AVFMT_GLOBALHEADER,
9566  .p.codec_tag = codec_avif_tags_list,
9567  .p.priv_class = &mov_avif_muxer_class,
9568  .flags_internal = FF_OFMT_FLAG_ALLOW_FLUSH,
9569 };
9570 #endif
AV_CODEC_ID_PCM_S16LE
@ AV_CODEC_ID_PCM_S16LE
Definition: codec_id.h:330
flags
const SwsFlags flags[]
Definition: swscale.c:85
codec_ism_tags
static const AVCodecTag codec_ism_tags[]
Definition: movenc.c:9335
ff_isom_write_vpcc
int ff_isom_write_vpcc(void *logctx, AVIOContext *pb, const uint8_t *data, int len, const AVCodecParameters *par)
Writes VP codec configuration to the provided AVIOContext.
Definition: vpcc.c:204
MOVTrack::height
int height
active picture (w/o VBI) height for D-10/IMX
Definition: movenc.h:134
MOVMuxContext::mdat_pos
int64_t mdat_pos
Definition: movenc.h:219
MOVTrack::elst_end_pts
int64_t elst_end_pts
Definition: movenc.h:140
mov_write_traf_tag
static int mov_write_traf_tag(AVIOContext *pb, MOVMuxContext *mov, MOVTrack *track, int64_t moof_offset, int moof_size)
Definition: movenc.c:5887
AV_CODEC_ID_EIA_608
@ AV_CODEC_ID_EIA_608
Definition: codec_id.h:575
AV_PKT_DATA_DISPLAYMATRIX
@ AV_PKT_DATA_DISPLAYMATRIX
This side data contains a 3x3 transformation matrix describing an affine transformation that needs to...
Definition: packet.h:105
AV_ROUND_UP
@ AV_ROUND_UP
Round toward +infinity.
Definition: mathematics.h:134
av_packet_unref
void av_packet_unref(AVPacket *pkt)
Wipe the packet.
Definition: packet.c:434
eac3_info
Definition: movenc.c:383
MOVMuxContext::nb_tracks
int nb_tracks
Definition: movenc.h:216
MOVMuxContext::fc
AVFormatContext * fc
Definition: movenc.h:247
MOVTrack::end_pts
int64_t end_pts
Definition: movenc.h:139
MOVMuxContext::iods_audio_profile
int iods_audio_profile
Definition: movenc.h:228
MODE_PSP
#define MODE_PSP
Definition: movenc.h:41
mov_write_udta_sdp
static int mov_write_udta_sdp(AVIOContext *pb, MOVTrack *track)
Definition: movenc.c:4295
AVMEDIA_TYPE_SUBTITLE
@ AVMEDIA_TYPE_SUBTITLE
Definition: avutil.h:203
AV_CODEC_ID_VP6F
@ AV_CODEC_ID_VP6F
Definition: codec_id.h:142
FF_MOV_FLAG_GLOBAL_SIDX
#define FF_MOV_FLAG_GLOBAL_SIDX
Definition: movenc.h:292
skip_bits_long
static void skip_bits_long(GetBitContext *s, int n)
Skips the specified number of bits.
Definition: get_bits.h:280
AV_LOG_WARNING
#define AV_LOG_WARNING
Something somehow does not look correct.
Definition: log.h:216
MOV_TFHD_DEFAULT_FLAGS
#define MOV_TFHD_DEFAULT_FLAGS
Definition: isom.h:412
MODE_IPOD
#define MODE_IPOD
Definition: movenc.h:44
MODE_MP4
#define MODE_MP4
Definition: movenc.h:38
AV_CODEC_ID_PCM_F32BE
@ AV_CODEC_ID_PCM_F32BE
Definition: codec_id.h:350
AVCodecParameters::extradata
uint8_t * extradata
Extra binary data needed for initializing the decoder, codec-dependent.
Definition: codec_par.h:71
AV_CODEC_ID_ADPCM_MS
@ AV_CODEC_ID_ADPCM_MS
Definition: codec_id.h:375
AVPixelFormat
AVPixelFormat
Pixel format.
Definition: pixfmt.h:71
mov_get_dnxhd_codec_tag
static int mov_get_dnxhd_codec_tag(AVFormatContext *s, MOVTrack *track)
Definition: movenc.c:2096
calc_elst_duration
static int64_t calc_elst_duration(MOVMuxContext *mov, MOVTrack *track)
Definition: movenc.c:3923
name
it s the only field you need to keep assuming you have a context There is some magic you don t need to care about around this just let it vf default minimum maximum flags name is the option name
Definition: writing_filters.txt:88
LIBAVFORMAT_IDENT
#define LIBAVFORMAT_IDENT
Definition: version.h:45
PacketList::head
PacketListEntry * head
Definition: packet_internal.h:30
AV_CODEC_ID_ADPCM_IMA_QT
@ AV_CODEC_ID_ADPCM_IMA_QT
Definition: codec_id.h:369
AVERROR_EXPERIMENTAL
#define AVERROR_EXPERIMENTAL
Requested feature is flagged experimental. Set strict_std_compliance if you really want to use it.
Definition: error.h:74
movenc_ttml.h
entry
#define entry
Definition: aom_film_grain_template.c:66
eac3_info::num_dep_sub
uint8_t num_dep_sub
Definition: movenc.c:410
MOVTrack::chunkCount
long chunkCount
Definition: movenc.h:111
MOVTrack::cluster_written
MOVIentry * cluster_written
Definition: movenc.h:131
level
uint8_t level
Definition: svq3.c:208
AV_CODEC_ID_AC3
@ AV_CODEC_ID_AC3
Definition: codec_id.h:455
AV_STEREO3D_VIEW_LEFT
@ AV_STEREO3D_VIEW_LEFT
Frame contains only the left view.
Definition: stereo3d.h:158
AVIO_DATA_MARKER_BOUNDARY_POINT
@ AVIO_DATA_MARKER_BOUNDARY_POINT
A point in the output bytestream where a demuxer can start parsing (for non self synchronizing bytest...
Definition: avio.h:127
AC3HeaderInfo::frame_type
uint8_t frame_type
Definition: ac3_parser_internal.h:45
mov_write_moov_tag
static int mov_write_moov_tag(AVIOContext *pb, MOVMuxContext *mov, AVFormatContext *s)
Definition: movenc.c:5358
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:2441
MOV_TRUN_SAMPLE_FLAGS
#define MOV_TRUN_SAMPLE_FLAGS
Definition: isom.h:420
mov_write_vmhd_tag
static int mov_write_vmhd_tag(AVIOContext *pb)
Definition: movenc.c:3569
MOVFragmentInfo::tfrf_offset
int64_t tfrf_offset
Definition: movenc.h:84
mov_write_freeform_tag
static int mov_write_freeform_tag(AVIOContext *pb, const char *mean, const char *name, const char *data)
Definition: movenc.c:4635
AV_PKT_DATA_AMBIENT_VIEWING_ENVIRONMENT
@ AV_PKT_DATA_AMBIENT_VIEWING_ENVIRONMENT
Ambient viewing environment metadata, as defined by H.274.
Definition: packet.h:327
AVStreamGroupLayeredVideo
AVStreamGroupLayeredVideo is meant to define the relation between a base layer video stream and a sep...
Definition: avformat.h:1074
AVOutputFormat::name
const char * name
Definition: avformat.h:508
r
const char * r
Definition: vf_curves.c:127
AVERROR
Filter the word “frame” indicates either a video frame or a group of audio as stored in an AVFrame structure Format for each input and each output the list of supported formats For video that means pixel format For audio that means channel sample they are references to shared objects When the negotiation mechanism computes the intersection of the formats supported at each end of a all references to both lists are replaced with a reference to the intersection And when a single format is eventually chosen for a link amongst the remaining all references to the list are updated That means that if a filter requires that its input and output have the same format amongst a supported all it has to do is use a reference to the same list of formats query_formats can leave some formats unset and return AVERROR(EAGAIN) to cause the negotiation mechanism toagain later. That can be used by filters with complex requirements to use the format negotiated on one link to set the formats supported on another. Frame references ownership and permissions
opt.h
mov_write_track_kinds
static int mov_write_track_kinds(AVIOContext *pb, AVStream *st)
Definition: movenc.c:4357
MOVTrack::squash_fragment_samples_to_one
unsigned int squash_fragment_samples_to_one
Definition: movenc.h:187
flag
int flag
Definition: cpu.c:40
MOVMuxContext::mode
int mode
Definition: movenc.h:213
AV_PROFILE_H264_INTRA
#define AV_PROFILE_H264_INTRA
Definition: defs.h:108
FF_MOV_FLAG_FRAG_KEYFRAME
#define FF_MOV_FLAG_FRAG_KEYFRAME
Definition: movenc.h:281
mov_write_wfex_tag
static int mov_write_wfex_tag(AVFormatContext *s, AVIOContext *pb, MOVTrack *track)
Definition: movenc.c:864
MOV_TKHD_FLAG_ENABLED
#define MOV_TKHD_FLAG_ENABLED
Definition: isom.h:433
mov_write_mfra_tag
static int mov_write_mfra_tag(AVIOContext *pb, MOVMuxContext *mov)
Definition: movenc.c:6161
AVStreamGroup::params
union AVStreamGroup::@455 params
Group type-specific parameters.
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:5085
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:5822
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:5037
ffio_wfourcc
static av_always_inline void ffio_wfourcc(AVIOContext *pb, const uint8_t *s)
Definition: avio_internal.h:124
AVUUID
uint8_t AVUUID[AV_UUID_LEN]
Definition: uuid.h:60
put_bytes_output
static int put_bytes_output(const PutBitContext *s)
Definition: put_bits.h:99
FF_MOV_FLAG_HYBRID_FRAGMENTED
#define FF_MOV_FLAG_HYBRID_FRAGMENTED
Definition: movenc.h:302
cb
static double cb(void *priv, double x, double y)
Definition: vf_geq.c:247
mpeg4_bit_rate_values::buffer_size
uint32_t buffer_size
Size of the decoding buffer for the elementary stream in bytes.
Definition: movenc.c:733
ff_mp4_obj_type
const AVCodecTag ff_mp4_obj_type[]
Definition: isom.c:34
MOVMuxContext::encryption_scheme
MOVEncryptionScheme encryption_scheme
Definition: movenc.h:258
FF_MOV_FLAG_WRITE_COLR
#define FF_MOV_FLAG_WRITE_COLR
Definition: movenc.h:293
AV_PKT_DATA_FRAME_CROPPING
@ AV_PKT_DATA_FRAME_CROPPING
The number of pixels to discard from the top/bottom/left/right border of the decoded frame to obtain ...
Definition: packet.h:340
mov_write_single_packet
static int mov_write_single_packet(AVFormatContext *s, AVPacket *pkt)
Definition: movenc.c:7410
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:5697
MOVTrack::mode
int mode
Definition: movenc.h:95
mov_write_mvhd_tag
static int mov_write_mvhd_tag(AVIOContext *pb, MOVMuxContext *mov)
Definition: movenc.c:4519
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:5625
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:4377
MOVIentry
Definition: movenc.h:49
AVStream::priv_data
void * priv_data
Definition: avformat.h:772
av_pix_fmt_desc_get
const AVPixFmtDescriptor * av_pix_fmt_desc_get(enum AVPixelFormat pix_fmt)
Definition: pixdesc.c:3456
AVFMT_VARIABLE_FPS
#define AVFMT_VARIABLE_FPS
Format allows variable fps.
Definition: avformat.h:482
get_pts_range
static void get_pts_range(MOVMuxContext *mov, MOVTrack *track, int64_t *start, int64_t *end, int elst, int mdhd)
Definition: movenc.c:3877
FF_MOV_FLAG_SKIP_TRAILER
#define FF_MOV_FLAG_SKIP_TRAILER
Definition: movenc.h:296
mov_write_gama_tag
static int mov_write_gama_tag(AVFormatContext *s, AVIOContext *pb, MOVTrack *track, double gamma)
Definition: movenc.c:2608
AV_DISPOSITION_ATTACHED_PIC
#define AV_DISPOSITION_ATTACHED_PIC
The stream is stored in the file as an attached picture/"cover art" (e.g.
Definition: avformat.h:673
AV_FIELD_PROGRESSIVE
@ AV_FIELD_PROGRESSIVE
Definition: defs.h:213
ff_packet_list_free
void ff_packet_list_free(PacketList *list)
Wipe the list and unref all the packets in it.
Definition: packet_list.c:103
AV_PKT_DATA_MASTERING_DISPLAY_METADATA
@ AV_PKT_DATA_MASTERING_DISPLAY_METADATA
Mastering display metadata (based on SMPTE-2086:2014).
Definition: packet.h:219
MOVFragmentInfo::size
int size
Definition: movenc.h:85
AV_PKT_FLAG_DISCARD
#define AV_PKT_FLAG_DISCARD
Flag is used to discard packets which are required to maintain valid decoder state but are not requir...
Definition: packet.h:657
IS_MODE
#define IS_MODE(muxer, config)
MOVFragmentInfo
Definition: movenc.h:80
MOVTrack::last_iamf_idx
int last_iamf_idx
Definition: movenc.h:193
AV_TIME_BASE_Q
#define AV_TIME_BASE_Q
Internal time base represented as fractional value.
Definition: avutil.h:263
AV_CODEC_ID_DIRAC
@ AV_CODEC_ID_DIRAC
Definition: codec_id.h:166
AVCodecTag::id
enum AVCodecID id
Definition: internal.h:43
eac3_info::num_blocks
uint8_t num_blocks
Definition: movenc.c:387
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:852
init_put_bits
static void init_put_bits(PutBitContext *s, uint8_t *buffer, int buffer_size)
Initialize the PutBitContext s.
Definition: put_bits.h:62
MOVTrack::iamf_buf
AVIOContext * iamf_buf
Definition: movenc.h:194
mov_auto_flush_fragment
static int mov_auto_flush_fragment(AVFormatContext *s, int force)
Definition: movenc.c:6902
AV_CODEC_ID_RAWVIDEO
@ AV_CODEC_ID_RAWVIDEO
Definition: codec_id.h:63
mov_pcm_le_gt16
static int mov_pcm_le_gt16(enum AVCodecID codec_id)
Definition: movenc.c:836
vvc.h
ff_vvc_annexb2mp4
int ff_vvc_annexb2mp4(AVIOContext *pb, const uint8_t *buf_in, int size, int filter_ps, int *ps_count)
Writes Annex B formatted H.266/VVC NAL units to the provided AVIOContext.
Definition: vvc.c:810
ff_get_formatted_ntp_time
uint64_t ff_get_formatted_ntp_time(uint64_t ntp_time_us)
Get the NTP time stamp formatted as per the RFC-5905.
Definition: utils.c:262
AV_DISPOSITION_DEFAULT
#define AV_DISPOSITION_DEFAULT
The stream should be chosen by default among other streams of the same type, unless the user has expl...
Definition: avformat.h:620
MOVMuxContext::min_fragment_duration
int min_fragment_duration
Definition: movenc.h:233
AV_CODEC_ID_MPEG4
@ AV_CODEC_ID_MPEG4
Definition: codec_id.h:62
MOVMuxContext::avif_extent_length
int avif_extent_length[2]
Definition: movenc.h:273
AVContentLightMetadata::MaxCLL
unsigned MaxCLL
Max content light level (cd/m^2).
Definition: mastering_display_metadata.h:111
ff_isom_write_vvcc
int ff_isom_write_vvcc(AVIOContext *pb, const uint8_t *data, int size, int ps_array_completeness)
Writes H.266/VVC extradata (parameter sets, declarative SEI NAL units) to the provided AVIOContext.
Definition: vvc.c:879
MODE_MOV
#define MODE_MOV
Definition: movenc.h:39
MOVMuxContext::encryption_scheme_str
char * encryption_scheme_str
Definition: movenc.h:257
FF_MOV_FLAG_FRAG_CUSTOM
#define FF_MOV_FLAG_FRAG_CUSTOM
Definition: movenc.h:283
av_encryption_init_info_free
void av_encryption_init_info_free(AVEncryptionInitInfo *info)
Frees the given encryption init info object.
Definition: encryption_info.c:216
mov_write_enda_tag
static int mov_write_enda_tag(AVIOContext *pb)
Definition: movenc.c:696
mov_write_apvc_tag
static int mov_write_apvc_tag(AVFormatContext *s, AVIOContext *pb, MOVTrack *track)
Definition: movenc.c:1744
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:4466
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:4009
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:8151
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:7905
mov_write_ccst_tag
static int mov_write_ccst_tag(AVIOContext *pb)
Definition: movenc.c:2786
AVOption
AVOption.
Definition: opt.h:428
MOVFragmentInfo::duration
int64_t duration
Definition: movenc.h:83
b
#define b
Definition: input.c:43
AVCOL_TRC_UNSPECIFIED
@ AVCOL_TRC_UNSPECIFIED
Definition: pixfmt.h:669
mov_write_mdta_hdlr_tag
static int mov_write_mdta_hdlr_tag(AVIOContext *pb, MOVMuxContext *mov, AVFormatContext *s)
Definition: movenc.c:4902
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:4999
AVStream::avg_frame_rate
AVRational avg_frame_rate
Average framerate.
Definition: avformat.h:836
MOVTrack::flags
uint32_t flags
Definition: movenc.h:117
data
const char data[16]
Definition: mxf.c:149
AV_PIX_FMT_MONOWHITE
@ AV_PIX_FMT_MONOWHITE
Y , 1bpp, 0 is white, 1 is black, in each byte pixels are ordered from the msb to the lsb.
Definition: pixfmt.h:82
AVTimecode::flags
uint32_t flags
flags such as drop frame, +24 hours support, ...
Definition: timecode.h:43
AV_CODEC_ID_ALAC
@ AV_CODEC_ID_ALAC
Definition: codec_id.h:468
MOVTrack::tag
int tag
stsd fourcc
Definition: movenc.h:124
MOVTrack::pal_done
int pal_done
Definition: movenc.h:183
AV_PIX_FMT_YUV420P10
#define AV_PIX_FMT_YUV420P10
Definition: pixfmt.h:539
AV_DICT_IGNORE_SUFFIX
#define AV_DICT_IGNORE_SUFFIX
Return first entry in a dictionary whose first part corresponds to the search key,...
Definition: dict.h:75
AV_CODEC_ID_AMR_NB
@ AV_CODEC_ID_AMR_NB
Definition: codec_id.h:433
AVStreamGroupTREF::metadata_index
unsigned int metadata_index
Index of the metadata stream in the AVStreamGroup.
Definition: avformat.h:1124
MOVIentry::dts
int64_t dts
Definition: movenc.h:51
ff_isom_write_lvcc
int ff_isom_write_lvcc(AVIOContext *pb, const uint8_t *data, int len)
Definition: lcevc.c:251
MOV_TIMESCALE
#define MOV_TIMESCALE
Definition: movenc.h:33
co64_required
static int co64_required(const MOVTrack *track)
Definition: movenc.c:177
mov_write_aux_tag
static int mov_write_aux_tag(AVIOContext *pb, const char *aux_type)
Definition: movenc.c:2805
MOVMuxContext::encryption_key
uint8_t * encryption_key
Definition: movenc.h:259
ff_toupper4
unsigned int ff_toupper4(unsigned int x)
Definition: to_upper4.h:29
ff_parse_creation_time_metadata
int ff_parse_creation_time_metadata(AVFormatContext *s, int64_t *timestamp, int return_seconds)
Parse creation_time in AVFormatContext metadata if exists and warn if the parsing fails.
Definition: mux_utils.c:137
AV_LOG_VERBOSE
#define AV_LOG_VERBOSE
Detailed information.
Definition: log.h:226
ff_codec_wav_tags
const AVCodecTag ff_codec_wav_tags[]
Definition: riff.c:525
MOVIentry::flags
uint32_t flags
Definition: movenc.h:62
mov_write_itunes_hdlr_tag
static int mov_write_itunes_hdlr_tag(AVIOContext *pb, MOVMuxContext *mov, AVFormatContext *s)
Definition: movenc.c:4584
mov_write_header
static int mov_write_header(AVFormatContext *s)
Definition: movenc.c:8747
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:2340
put_bits32
static av_unused void put_bits32(PutBitContext *s, uint32_t value)
Write exactly 32 bits into a bitstream.
Definition: put_bits.h:301
MP4TrackKindMapping::scheme_uri
const char * scheme_uri
Definition: isom.h:493
AV_PIX_FMT_BGR24
@ AV_PIX_FMT_BGR24
packed RGB 8:8:8, 24bpp, BGRBGR...
Definition: pixfmt.h:76
AV_PIX_FMT_BGRA
@ AV_PIX_FMT_BGRA
packed BGRA 8:8:8:8, 32bpp, BGRABGRA...
Definition: pixfmt.h:102
mov_write_loci_tag
static int mov_write_loci_tag(AVFormatContext *s, AVIOContext *pb)
Definition: movenc.c:4729
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:8940
AVStreamGroup::tref
struct AVStreamGroupTREF * tref
Definition: avformat.h:1184
AVCodecParameters::codec_tag
uint32_t codec_tag
Additional information about the codec (corresponds to the AVI FOURCC).
Definition: codec_par.h:61
AV_SPHERICAL_EQUIRECTANGULAR_TILE
@ AV_SPHERICAL_EQUIRECTANGULAR_TILE
Video represents a portion of a sphere mapped on a flat surface using equirectangular projection.
Definition: spherical.h:68
AVStereo3D::baseline
uint32_t baseline
The distance between the centres of the lenses of the camera system, in micrometers.
Definition: stereo3d.h:228
max
#define max(a, b)
Definition: cuda_runtime.h:33
FF_MOV_FLAG_WRITE_GAMA
#define FF_MOV_FLAG_WRITE_GAMA
Definition: movenc.h:294
mathematics.h
FF_COMPLIANCE_EXPERIMENTAL
#define FF_COMPLIANCE_EXPERIMENTAL
Allow nonstandardized experimental things.
Definition: defs.h:62
mov_write_d263_tag
static int mov_write_d263_tag(AVIOContext *pb)
Definition: movenc.c:1580
MOVTrack::track_id
int track_id
Definition: movenc.h:123
AV_CODEC_ID_FLAC
@ AV_CODEC_ID_FLAC
Definition: codec_id.h:464
AV_PKT_FLAG_DISPOSABLE
#define AV_PKT_FLAG_DISPOSABLE
Flag is used to indicate packets that contain frames that can be discarded by the decoder.
Definition: packet.h:669
FFMAX
#define FFMAX(a, b)
Definition: macros.h:47
fiel_data
static const uint16_t fiel_data[]
Definition: movenc.c:2248
av_sub_q
AVRational av_sub_q(AVRational b, AVRational c)
Subtract one rational from another.
Definition: rational.c:101
ff_mov_init_hinting
int ff_mov_init_hinting(AVFormatContext *s, int index, int src_index)
Definition: movenchint.c:30
ff_isom_write_apvc
void ff_isom_write_apvc(AVIOContext *pb, const APVDecoderConfigurationRecord *apvc, void *logctx)
Definition: apv.c:80
ff_mov_get_channel_layout_tag
int ff_mov_get_channel_layout_tag(const AVCodecParameters *par, uint32_t *layout, uint32_t *bitmap, uint32_t **pchannel_desc)
Get the channel layout tag for the specified codec id and channel layout.
Definition: mov_chan.c:476
AVChannelLayout::nb_channels
int nb_channels
Number of channels in this layout.
Definition: channel_layout.h:329
mov_write_srat_tag
static int mov_write_srat_tag(AVIOContext *pb, MOVTrack *track)
Definition: movenc.c:1385
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:3084
MOVTrack::track_duration
int64_t track_duration
Definition: movenc.h:100
MOV_SAMPLE_DEPENDENCY_UNKNOWN
#define MOV_SAMPLE_DEPENDENCY_UNKNOWN
Definition: isom.h:438
is_clcp_track
static int is_clcp_track(MOVTrack *track)
Definition: movenc.c:3578
AV_CODEC_ID_R10K
@ AV_CODEC_ID_R10K
Definition: codec_id.h:195
codec_cover_image_tags
static const AVCodecTag codec_cover_image_tags[]
Definition: movenc.c:2186
av_encryption_init_info_get_side_data
AVEncryptionInitInfo * av_encryption_init_info_get_side_data(const uint8_t *side_data, size_t side_data_size)
Creates a copy of the AVEncryptionInitInfo that is contained in the given side data.
Definition: encryption_info.c:231
AV_STEREO3D_VIEW_RIGHT
@ AV_STEREO3D_VIEW_RIGHT
Frame contains only the right view.
Definition: stereo3d.h:163
av_strlcatf
size_t av_strlcatf(char *dst, size_t size, const char *fmt,...)
Definition: avstring.c:103
AV_CODEC_ID_TRUEHD
@ AV_CODEC_ID_TRUEHD
Definition: codec_id.h:496
AV_STEREO3D_VIEW_UNSPEC
@ AV_STEREO3D_VIEW_UNSPEC
Content is unspecified.
Definition: stereo3d.h:168
avio_get_dyn_buf
int avio_get_dyn_buf(AVIOContext *s, uint8_t **pbuffer)
Return the written size and a pointer to the buffer.
Definition: aviobuf.c:1377
tf_sess_config.config
config
Definition: tf_sess_config.py:33
AV_PKT_FLAG_KEY
#define AV_PKT_FLAG_KEY
The packet contains a keyframe.
Definition: packet.h:650
MOVTrack::dts_shift
int64_t dts_shift
Definition: movenc.h:142
init_get_bits
static int init_get_bits(GetBitContext *s, const uint8_t *buffer, int bit_size)
Initialize GetBitContext.
Definition: get_bits.h:517
ff_get_muxer_ts_offset
int ff_get_muxer_ts_offset(AVFormatContext *s, int stream_index, int64_t *offset)
Definition: mux.c:1027
av_packet_free
void av_packet_free(AVPacket **pkt)
Free the packet, if the packet is reference counted, it will be unreferenced first.
Definition: packet.c:74
MOVIentry::entries
unsigned int entries
Definition: movenc.h:57
AV_PIX_FMT_RGB555BE
@ AV_PIX_FMT_RGB555BE
packed RGB 5:5:5, 16bpp, (msb)1X 5R 5G 5B(lsb), big-endian , X=unused/undefined
Definition: pixfmt.h:114
MOVMuxContext::write_prft
MOVPrftBox write_prft
Definition: movenc.h:268
MOVTrack::first_frag_written
int first_frag_written
Definition: movenc.h:172
ascii_to_wc
static int ascii_to_wc(AVIOContext *pb, const uint8_t *b)
Definition: movenc.c:5019
FFOutputFormat::p
AVOutputFormat p
The public AVOutputFormat.
Definition: mux.h:65
FF_RTP_FLAG_OPTS
#define FF_RTP_FLAG_OPTS(ctx, fieldname)
Definition: rtpenc.h:74
AV_CODEC_ID_AMR_WB
@ AV_CODEC_ID_AMR_WB
Definition: codec_id.h:434
AV_CODEC_ID_BIN_DATA
@ AV_CODEC_ID_BIN_DATA
Definition: codec_id.h:606
MOVMuxContext::mdat_size
uint64_t mdat_size
Definition: movenc.h:220
mov_write_chnl_tag
static int mov_write_chnl_tag(AVFormatContext *s, AVIOContext *pb, MOVTrack *track)
Definition: movenc.c:1317
MOVMuxContext::write_tmcd
int write_tmcd
Definition: movenc.h:267
OPUS_SEEK_PREROLL_MS
#define OPUS_SEEK_PREROLL_MS
Definition: oggparseopus.c:36
FF_MOV_FLAG_CMAF
#define FF_MOV_FLAG_CMAF
Definition: movenc.h:300
mov_write_tfdt_tag
static int mov_write_tfdt_tag(AVIOContext *pb, MOVTrack *track)
Definition: movenc.c:5875
MOVTrack::frag_info
MOVFragmentInfo * frag_info
Definition: movenc.h:165
mov_write_wave_tag
static int mov_write_wave_tag(AVFormatContext *s, AVIOContext *pb, MOVTrack *track)
Definition: movenc.c:1077
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:5306
AV_CODEC_ID_MPEGH_3D_AUDIO
@ AV_CODEC_ID_MPEGH_3D_AUDIO
Definition: codec_id.h:543
MOV_PRFT_SRC_PTS
@ MOV_PRFT_SRC_PTS
Definition: movenc.h:207
MOVTrack
Definition: movenc.h:94
av_memdup
void * av_memdup(const void *p, size_t size)
Duplicate a buffer with av_malloc().
Definition: mem.c:304
AVContentLightMetadata
Content light level needed by to transmit HDR over HDMI (CTA-861.3).
Definition: mastering_display_metadata.h:107
AV_PKT_DATA_DOVI_CONF
@ AV_PKT_DATA_DOVI_CONF
DOVI configuration ref: dolby-vision-bitstreams-within-the-iso-base-media-file-format-v2....
Definition: packet.h:280
MOVFragmentInfo::offset
int64_t offset
Definition: movenc.h:81
AVStereo3D::horizontal_field_of_view
AVRational horizontal_field_of_view
Horizontal field of view, in degrees.
Definition: stereo3d.h:239
skip_bits
static void skip_bits(GetBitContext *s, int n)
Definition: get_bits.h:383
AVCodecParameters::color_primaries
enum AVColorPrimaries color_primaries
Definition: codec_par.h:190
avio_write_marker
void avio_write_marker(AVIOContext *s, int64_t time, enum AVIODataMarkerType type)
Mark the written bytestream as a specific type.
Definition: aviobuf.c:464
AV_PIX_FMT_GRAY16BE
@ AV_PIX_FMT_GRAY16BE
Y , 16bpp, big-endian.
Definition: pixfmt.h:104
AV_STEREO3D_SIDEBYSIDE
@ AV_STEREO3D_SIDEBYSIDE
Views are next to each other.
Definition: stereo3d.h:64
AVPacketSideData::size
size_t size
Definition: packet.h:426
mov_write_trex_tag
static int mov_write_trex_tag(AVIOContext *pb, MOVTrack *track)
Definition: movenc.c:4495
get_bits
static unsigned int get_bits(GetBitContext *s, int n)
Read 1-25 bits.
Definition: get_bits.h:337
FF_MOV_FLAG_FRAG_EVERY_FRAME
#define FF_MOV_FLAG_FRAG_EVERY_FRAME
Definition: movenc.h:298
mov_write_dvc1_tag
static int mov_write_dvc1_tag(AVIOContext *pb, MOVTrack *track)
Definition: movenc.c:1204
rgb
Definition: rpzaenc.c:60
MOVTrack::entry_version
int entry_version
Definition: movenc.h:96
put_descr
static void put_descr(AVIOContext *pb, int tag, unsigned int size)
Definition: movenc.c:712
eac3_info::ac3_bit_rate_code
int8_t ac3_bit_rate_code
Definition: movenc.c:392
mov_write_vexu_proj_tag
static void mov_write_vexu_proj_tag(AVFormatContext *s, AVIOContext *pb, const AVSphericalMapping *spherical_mapping)
Definition: movenc.c:2414
MOV_ENC_NONE
@ MOV_ENC_NONE
Definition: movenc.h:200
MODE_ISM
#define MODE_ISM
Definition: movenc.h:45
mov_write_pcmc_tag
static int mov_write_pcmc_tag(AVFormatContext *s, AVIOContext *pb, MOVTrack *track)
Definition: movenc.c:1359
AV_STEREO3D_VIEW_PACKED
@ AV_STEREO3D_VIEW_PACKED
Frame contains two packed views.
Definition: stereo3d.h:153
avpriv_set_pts_info
void avpriv_set_pts_info(AVStream *st, int pts_wrap_bits, unsigned int pts_num, unsigned int pts_den)
Set the time base and wrapping info for a given stream.
Definition: avformat.c:830
AV_OPT_TYPE_BINARY
@ AV_OPT_TYPE_BINARY
Underlying C type is a uint8_t* that is either NULL or points to an array allocated with the av_mallo...
Definition: opt.h:285
calc_samples_pts_duration
static int64_t calc_samples_pts_duration(MOVMuxContext *mov, MOVTrack *track)
Definition: movenc.c:3902
AC3HeaderInfo::complexity_index_type_a
uint8_t complexity_index_type_a
Definition: ac3_parser_internal.h:81
FF_MOV_FLAG_DEFAULT_BASE_MOOF
#define FF_MOV_FLAG_DEFAULT_BASE_MOOF
Definition: movenc.h:288
mov_write_audio_tag
static int mov_write_audio_tag(AVFormatContext *s, AVIOContext *pb, MOVMuxContext *mov, MOVTrack *track)
Definition: movenc.c:1397
eac3_info::acmod
uint8_t acmod
Definition: movenc.c:405
MOV_TRACK_CTTS
#define MOV_TRACK_CTTS
Definition: movenc.h:114
AV_CODEC_ID_PCM_S16BE
@ AV_CODEC_ID_PCM_S16BE
Definition: codec_id.h:331
defined_frame_rate
static int defined_frame_rate(AVFormatContext *s, AVStream *st)
Definition: movenc.c:1917
MOV_FRAG_SAMPLE_FLAG_IS_NON_SYNC
#define MOV_FRAG_SAMPLE_FLAG_IS_NON_SYNC
Definition: isom.h:424
mov_write_gpmd_tag
static int mov_write_gpmd_tag(AVIOContext *pb, const MOVTrack *track)
Definition: movenc.c:3172
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:4689
ffio_open_null_buf
int ffio_open_null_buf(AVIOContext **s)
Open a write-only fake memory stream.
Definition: aviobuf.c:1462
AV_STEREO3D_2D
@ AV_STEREO3D_2D
Video is not stereoscopic (and metadata has to be there).
Definition: stereo3d.h:52
AVFMT_FLAG_AUTO_BSF
#define AVFMT_FLAG_AUTO_BSF
Add bitstream filters as requested by the muxer.
Definition: avformat.h:1485
MOVMuxContext::use_editlist
int use_editlist
Definition: movenc.h:251
mov_write_mvex_tag
static int mov_write_mvex_tag(AVIOContext *pb, MOVMuxContext *mov)
Definition: movenc.c:4508
timecode.h
MOV_TRACK_STPS
#define MOV_TRACK_STPS
Definition: movenc.h:115
eac3_info::chan_loc
uint16_t chan_loc
Definition: movenc.c:412
mov_write_dref_tag
static int mov_write_dref_tag(AVIOContext *pb)
Definition: movenc.c:3309
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:3939
mov_write_video_tag
static int mov_write_video_tag(AVFormatContext *s, AVIOContext *pb, MOVMuxContext *mov, MOVTrack *track)
Definition: movenc.c:2815
AC3HeaderInfo
Definition: ac3_parser_internal.h:34
mov_write_evcc_tag
static int mov_write_evcc_tag(AVIOContext *pb, MOVTrack *track)
Definition: movenc.c:1695
MOVTrack::frag_discont
int frag_discont
Definition: movenc.h:161
mov_get_rawvideo_codec_tag
static int mov_get_rawvideo_codec_tag(AVFormatContext *s, MOVTrack *track)
Definition: movenc.c:2105
mov_write_esds_tag
static int mov_write_esds_tag(AVIOContext *pb, MOVTrack *track)
Definition: movenc.c:783
AC3HeaderInfo::frame_size
uint16_t frame_size
Definition: ac3_parser_internal.h:62
avio_tell
static av_always_inline int64_t avio_tell(AVIOContext *s)
ftell() equivalent for AVIOContext.
Definition: avio.h:494
MOVTrack::first_packet_entry
int first_packet_entry
Definition: movenc.h:170
mov_write_ftyp_tag
static int mov_write_ftyp_tag(AVIOContext *pb, AVFormatContext *s)
Definition: movenc.c:6251
EAC3_FRAME_TYPE_DEPENDENT
@ EAC3_FRAME_TYPE_DEPENDENT
Definition: ac3defs.h:112
AVChapter
Definition: avformat.h:1273
MOV_TRUN_SAMPLE_DURATION
#define MOV_TRUN_SAMPLE_DURATION
Definition: isom.h:418
val
static double val(void *priv, double ch)
Definition: aeval.c:77
compute_avg_bitrate
static unsigned compute_avg_bitrate(MOVTrack *track)
Definition: movenc.c:721
MOVTrack::apv
struct APVDecoderConfigurationRecord * apv
Definition: movenc.h:196
MOVIentry::size
unsigned int size
Definition: movenc.h:53
validate_codec_tag
static unsigned int validate_codec_tag(const AVCodecTag *const *tags, unsigned int tag, int codec_id)
Definition: movenc.c:2193
MOVTrack::mdat_buf
AVIOContext * mdat_buf
Definition: movenc.h:159
MOVTrack::cluster
MOVIentry * cluster
Definition: movenc.h:130
AVFMT_AVOID_NEG_TS_MAKE_ZERO
#define AVFMT_AVOID_NEG_TS_MAKE_ZERO
Shift timestamps so that they start at 0.
Definition: avformat.h:1707
AC3HeaderInfo::channel_mode
uint8_t channel_mode
Definition: ac3_parser_internal.h:43
type
it s the only field you need to keep assuming you have a context There is some magic you don t need to care about around this just let it vf type
Definition: writing_filters.txt:86
mov_write_lvcc_tag
static int mov_write_lvcc_tag(AVIOContext *pb, MOVTrack *track)
Definition: movenc.c:1712
mov_setup_track_ids
static int mov_setup_track_ids(MOVMuxContext *mov, AVFormatContext *s)
Assign track ids.
Definition: movenc.c:5267
pts
static int64_t pts
Definition: transcode_aac.c:649
MOV_SYNC_SAMPLE
#define MOV_SYNC_SAMPLE
Definition: movenc.h:59
FF_MOV_FLAG_USE_MDTA
#define FF_MOV_FLAG_USE_MDTA
Definition: movenc.h:295
AV_CODEC_ID_MP3
@ AV_CODEC_ID_MP3
preferred ID for decoding MPEG audio layer 1, 2 or 3
Definition: codec_id.h:453
mov_finish_fragment
static int mov_finish_fragment(MOVMuxContext *mov, MOVTrack *track, int64_t ref_pos)
Definition: movenc.c:6660
mov_write_iref_tag
static int mov_write_iref_tag(AVIOContext *pb, MOVMuxContext *mov, AVFormatContext *s)
Definition: movenc.c:3727
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:5194
MOVMuxContext::iods_video_profile
int iods_video_profile
Definition: movenc.h:227
av_reduce
int av_reduce(int *dst_num, int *dst_den, int64_t num, int64_t den, int64_t max)
Reduce a fraction.
Definition: rational.c:35
MOV_PRFT_NB
@ MOV_PRFT_NB
Definition: movenc.h:208
ff_data_to_hex
char * ff_data_to_hex(char *buf, const uint8_t *src, int size, int lowercase)
Write hexadecimal string corresponding to given binary data.
Definition: utils.c:458
AVRational::num
int num
Numerator.
Definition: rational.h:59
AV_CH_LAYOUT_STEREO
#define AV_CH_LAYOUT_STEREO
Definition: channel_layout.h:218
vpcc.h
MOV_CH_LAYOUT_MONO
@ MOV_CH_LAYOUT_MONO
Definition: mov_chan.h:56
mov_get_dv_codec_tag
static int mov_get_dv_codec_tag(AVFormatContext *s, MOVTrack *track)
Definition: movenc.c:1892
MOVIentry::prft
AVProducerReferenceTime prft
Definition: movenc.h:63
MOV_FRAG_SAMPLE_FLAG_DEPENDS_YES
#define MOV_FRAG_SAMPLE_FLAG_DEPENDS_YES
Definition: isom.h:431
MovTag
Definition: movenc.h:88
MOV_TRUN_DATA_OFFSET
#define MOV_TRUN_DATA_OFFSET
Definition: isom.h:416
eac3_info::lfeon
uint8_t lfeon
Definition: movenc.c:407
handle_eac3
static int handle_eac3(MOVMuxContext *mov, AVPacket *pkt, MOVTrack *track)
Definition: movenc.c:465
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:5861
av_get_bits_per_sample
int av_get_bits_per_sample(enum AVCodecID codec_id)
Return codec bits per sample.
Definition: utils.c:556
GET_UTF8
#define GET_UTF8(val, GET_BYTE, ERROR)
Convert a UTF-8 character (up to 4 bytes) to its 32-bit UCS-4 encoded form.
Definition: common.h:477
AVCodecParameters::color_trc
enum AVColorTransferCharacteristic color_trc
Definition: codec_par.h:191
MOVTrack::st
AVStream * st
Definition: movenc.h:125
avio_close_dyn_buf
int avio_close_dyn_buf(AVIOContext *s, uint8_t **pbuffer)
Return the written size and a pointer to the buffer.
Definition: aviobuf.c:1410
mov_write_tmpo_tag
static int mov_write_tmpo_tag(AVIOContext *pb, AVFormatContext *s)
Definition: movenc.c:4711
ff_mp4_muxer
const FFOutputFormat ff_mp4_muxer
MOVTrack::nb_tref_tags
int nb_tref_tags
Definition: movenc.h:135
mov_write_trak_tag
static int mov_write_trak_tag(AVFormatContext *s, AVIOContext *pb, MOVMuxContext *mov, MOVTrack *track, AVStream *st)
Definition: movenc.c:4410
AV_CODEC_ID_PCM_S8
@ AV_CODEC_ID_PCM_S8
Definition: codec_id.h:334
first
trying all byte sequences megabyte in length and selecting the best looking sequence will yield cases to try But first
Definition: rate_distortion.txt:12
MODE_AVIF
#define MODE_AVIF
Definition: movenc.h:47
pix_fmt
enum AVPixelFormat pix_fmt
Definition: movenc.c:2072
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:403
MOVTrack::palette
uint32_t palette[AVPALETTE_COUNT]
Definition: movenc.h:182
pkt
static AVPacket * pkt
Definition: movenc.c:60
AV_LOG_ERROR
#define AV_LOG_ERROR
Something went wrong and cannot losslessly be recovered.
Definition: log.h:210
FF_MOV_FLAG_FRAG_DISCONT
#define FF_MOV_FLAG_FRAG_DISCONT
Definition: movenc.h:290
mov_write_trailer
static int mov_write_trailer(AVFormatContext *s)
Definition: movenc.c:9035
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:7570
MOVTrack::squashed_packet_queue
PacketList squashed_packet_queue
Definition: movenc.h:189
MOVTrack::mono_as_fc
int mono_as_fc
Definition: movenc.h:127
MOVMuxContext::encryption_kid_len
int encryption_kid_len
Definition: movenc.h:262
MOVMuxContext::pkt
AVPacket * pkt
Definition: movenc.h:249
duration
static int64_t duration
Definition: movenc.c:65
AV_FIELD_UNKNOWN
@ AV_FIELD_UNKNOWN
Definition: defs.h:212
AVCodecParameters::frame_size
int frame_size
Audio frame size, if known.
Definition: codec_par.h:227
av_dict_get
AVDictionaryEntry * av_dict_get(const AVDictionary *m, const char *key, const AVDictionaryEntry *prev, int flags)
Get a dictionary entry with matching key.
Definition: dict.c:60
avio_open_dyn_buf
int avio_open_dyn_buf(AVIOContext **s)
Open a write only memory stream.
Definition: aviobuf.c:1365
av_channel_layout_describe
int av_channel_layout_describe(const AVChannelLayout *channel_layout, char *buf, size_t buf_size)
Get a human-readable string describing the channel layout properties.
Definition: channel_layout.c:654
AES_CTR_KEY_SIZE
#define AES_CTR_KEY_SIZE
Definition: aes_ctr.h:35
AV_STREAM_GROUP_PARAMS_IAMF_MIX_PRESENTATION
@ AV_STREAM_GROUP_PARAMS_IAMF_MIX_PRESENTATION
Definition: avformat.h:1130
MOVMuxContext::chapter_track
int chapter_track
qt chapter track number
Definition: movenc.h:218
FF_MOV_FLAG_FRAGMENT
#define FF_MOV_FLAG_FRAGMENT
Definition: movenc.h:279
full_range
bool full_range
Definition: hwcontext_videotoolbox.c:47
AV_CODEC_ID_ADPCM_G726
@ AV_CODEC_ID_ADPCM_G726
Definition: codec_id.h:380
VC1_CODE_SLICE
@ VC1_CODE_SLICE
Definition: vc1_common.h:36
ff_iamf_add_audio_element
int ff_iamf_add_audio_element(IAMFContext *iamf, const AVStreamGroup *stg, void *log_ctx)
Definition: iamf_writer.c:223
stereo3d.h
MOV_TIMESCALE_Q
#define MOV_TIMESCALE_Q
Definition: movenc.h:34
MOV_TFHD_DEFAULT_BASE_IS_MOOF
#define MOV_TFHD_DEFAULT_BASE_IS_MOOF
Definition: isom.h:414
AV_CODEC_ID_BMP
@ AV_CODEC_ID_BMP
Definition: codec_id.h:128
mov_write_chpl_tag
static int mov_write_chpl_tag(AVIOContext *pb, AVFormatContext *s)
Definition: movenc.c:5059
AV_CODEC_ID_EVC
@ AV_CODEC_ID_EVC
Definition: codec_id.h:316
AV_CODEC_ID_WMAPRO
@ AV_CODEC_ID_WMAPRO
Definition: codec_id.h:489
MOV_TFHD_DEFAULT_DURATION
#define MOV_TFHD_DEFAULT_DURATION
Definition: isom.h:410
MOVMuxContext::movie_timescale
int movie_timescale
Definition: movenc.h:270
MOVCtts::count
unsigned int count
Definition: isom.h:69
av_realloc_array
void * av_realloc_array(void *ptr, size_t nmemb, size_t size)
Definition: mem.c:217
AVFormatContext::flags
int flags
Flags modifying the (de)muxer behaviour.
Definition: avformat.h:1465
AVCodecParameters::sample_aspect_ratio
AVRational sample_aspect_ratio
The aspect ratio (width/height) which a single pixel should have when displayed.
Definition: codec_par.h:161
FF_MOV_FLAG_DELAY_MOOV
#define FF_MOV_FLAG_DELAY_MOOV
Definition: movenc.h:291
mov_write_av3c
static int mov_write_av3c(AVIOContext *pb, const uint8_t *data, int len)
Definition: movenc.c:1618
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:419
MOVMuxContext::per_stream_grouping
int per_stream_grouping
Definition: movenc.h:246
AVDictionaryEntry::key
char * key
Definition: dict.h:91
AVSphericalMapping::bound_top
uint32_t bound_top
Distance from the top edge.
Definition: spherical.h:186
AVMEDIA_TYPE_AUDIO
@ AVMEDIA_TYPE_AUDIO
Definition: avutil.h:201
AV_CODEC_ID_VP9
@ AV_CODEC_ID_VP9
Definition: codec_id.h:217
AVCodecParameters::width
int width
The width of the video frame in pixels.
Definition: codec_par.h:143
AV_CODEC_ID_MP2
@ AV_CODEC_ID_MP2
Definition: codec_id.h:452
ff_av1_filter_obus_buf
int ff_av1_filter_obus_buf(const uint8_t *in, uint8_t **out, int *size, int *offset)
Filter out AV1 OBUs not meant to be present in ISOBMFF sample data and return the result in a data bu...
Definition: av1.c:88
MOV_TRUN_FIRST_SAMPLE_FLAGS
#define MOV_TRUN_FIRST_SAMPLE_FLAGS
Definition: isom.h:417
MOVTrack::stsd_count
int stsd_count
Definition: movenc.h:104
av_q2d
static double av_q2d(AVRational a)
Convert an AVRational to a double.
Definition: rational.h:104
MOVMuxContext::nb_meta_tmcd
int nb_meta_tmcd
number of new created tmcd track based on metadata (aka not data copy)
Definition: movenc.h:217
utf8len
static int utf8len(const uint8_t *b)
Definition: movenc.c:143
info
MIPS optimizations info
Definition: mips.txt:2
mov_write_tfra_tag
static int mov_write_tfra_tag(AVIOContext *pb, MOVTrack *track)
Definition: movenc.c:6137
MOVStts::duration
unsigned int duration
Definition: isom.h:65
av_match_ext
int av_match_ext(const char *filename, const char *extensions)
Return a positive value if the given filename has one of the given extensions, 0 otherwise.
Definition: format.c:41
MOVTrack::timecode_flags
uint32_t timecode_flags
Definition: movenc.h:121
MOVIentry::pts
int64_t pts
Definition: movenc.h:52
MOVTrack::has_disposable
int has_disposable
Definition: movenc.h:113
FF_MOV_FLAG_NEGATIVE_CTS_OFFSETS
#define FF_MOV_FLAG_NEGATIVE_CTS_OFFSETS
Definition: movenc.h:297
av_assert0
#define av_assert0(cond)
assert() equivalent, that is always enabled.
Definition: avassert.h:42
MODE_F4V
#define MODE_F4V
Definition: movenc.h:46
AVMEDIA_TYPE_NB
@ AVMEDIA_TYPE_NB
Definition: avutil.h:205
EAC3_FRAME_TYPE_INDEPENDENT
@ EAC3_FRAME_TYPE_INDEPENDENT
Definition: ac3defs.h:111
mov_write_trkn_tag
static int mov_write_trkn_tag(AVIOContext *pb, MOVMuxContext *mov, AVFormatContext *s, int disc)
Definition: movenc.c:4780
MOVTrack::entry_written
int entry_written
Definition: movenc.h:97
ff_isom_put_dvcc_dvvc
void ff_isom_put_dvcc_dvvc(void *logctx, uint8_t out[ISOM_DVCC_DVVC_SIZE], const AVDOVIDecoderConfigurationRecord *dovi)
Definition: dovi_isom.c:89
FF_MOV_FLAG_PREFER_ICC
#define FF_MOV_FLAG_PREFER_ICC
Definition: movenc.h:301
PROFILE_ADVANCED
@ PROFILE_ADVANCED
Definition: vc1_common.h:52
ff_nal_parse_units
int ff_nal_parse_units(AVIOContext *pb, const uint8_t *buf_in, int size)
Definition: nal.c:113
MOVMuxContext::encryption_kid
uint8_t * encryption_kid
Definition: movenc.h:261
AV_LOG_DEBUG
#define AV_LOG_DEBUG
Stuff which is only useful for libav* developers.
Definition: log.h:231
AVPacketSideData::data
uint8_t * data
Definition: packet.h:425
AVDOVIDecoderConfigurationRecord::dv_profile
uint8_t dv_profile
Definition: dovi_meta.h:58
ctx
static AVFormatContext * ctx
Definition: movenc.c:49
channels
channels
Definition: aptx.h:31
mov_write_ipco_tag
static int mov_write_ipco_tag(AVIOContext *pb, MOVMuxContext *mov, AVFormatContext *s)
Definition: movenc.c:3774
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:3679
AV_RL16
uint64_t_TMPL AV_WL64 unsigned int_TMPL AV_WL32 unsigned int_TMPL AV_WL24 unsigned int_TMPL AV_RL16
Definition: bytestream.h:94
AV_PKT_DATA_STEREO3D
@ AV_PKT_DATA_STEREO3D
This side data should be associated with a video stream and contains Stereoscopic 3D information in f...
Definition: packet.h:111
MOVMuxContext::frag_interleave
int frag_interleave
Definition: movenc.h:254
ffio_write_leb
void ffio_write_leb(AVIOContext *s, unsigned val)
Definition: aviobuf.c:947
av_rescale_q
int64_t av_rescale_q(int64_t a, AVRational bq, AVRational cq)
Rescale a 64-bit integer by 2 rational numbers.
Definition: mathematics.c:142
channel_map
static const uint8_t channel_map[8][8]
Definition: atrac3plusdec.c:52
AVPixFmtDescriptor::log2_chroma_w
uint8_t log2_chroma_w
Amount to shift the luma width right to find the chroma width.
Definition: pixdesc.h:80
MOVTrack::max_packet_size
uint32_t max_packet_size
Definition: movenc.h:150
MOVTrack::sample_size
long sample_size
Definition: movenc.h:110
codec_id
enum AVCodecID codec_id
Definition: vaapi_decode.c:410
AV_PIX_FMT_YUV420P
@ AV_PIX_FMT_YUV420P
planar YUV 4:2:0, 12bpp, (1 Cr & Cb sample per 2x2 Y samples)
Definition: pixfmt.h:73
AV_CODEC_ID_SVQ3
@ AV_CODEC_ID_SVQ3
Definition: codec_id.h:73
key
const char * key
Definition: hwcontext_opencl.c:189
AVCodecParameters::nb_coded_side_data
int nb_coded_side_data
Amount of entries in coded_side_data.
Definition: codec_par.h:88
AVMEDIA_TYPE_DATA
@ AVMEDIA_TYPE_DATA
Opaque data information usually continuous.
Definition: avutil.h:202
av_mallocz
#define av_mallocz(s)
Definition: tableprint_vlc.h:31
MOVIentry::pos
uint64_t pos
Definition: movenc.h:50
mov_parse_mpeg2_frame
static int mov_parse_mpeg2_frame(AVPacket *pkt, uint32_t *flags)
Definition: movenc.c:6473
mov_write_tcmi_tag
static int mov_write_tcmi_tag(AVIOContext *pb, MOVTrack *track)
Definition: movenc.c:3485
build_chunks
static void build_chunks(MOVTrack *trk)
Definition: movenc.c:5231
MOV_PRFT_NONE
@ MOV_PRFT_NONE
Definition: movenc.h:205
AVCOL_PRI_UNSPECIFIED
@ AVCOL_PRI_UNSPECIFIED
Definition: pixfmt.h:639
mov_write_edts_tag
static int mov_write_edts_tag(AVIOContext *pb, MOVMuxContext *mov, MOVTrack *track)
Definition: movenc.c:4152
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:2630
AV_CODEC_ID_H264
@ AV_CODEC_ID_H264
Definition: codec_id.h:77
PutBitContext
Definition: put_bits.h:50
AVStreamGroup::layered_video
struct AVStreamGroupLayeredVideo * layered_video
Definition: avformat.h:1176
mov_write_hdlr_tag
static int mov_write_hdlr_tag(AVFormatContext *s, AVIOContext *pb, MOVTrack *track)
Definition: movenc.c:3584
MOVMuxContext::time
int64_t time
Definition: movenc.h:214
tmp
static uint8_t tmp[40]
Definition: aes_ctr.c:52
MOVTrack::packet_entry
int packet_entry
Definition: movenc.h:174
AV_PIX_FMT_RGBA
@ AV_PIX_FMT_RGBA
packed RGBA 8:8:8:8, 32bpp, RGBARGBA...
Definition: pixfmt.h:100
AVStereo3D::flags
int flags
Additional information about the frame packing.
Definition: stereo3d.h:212
AV_CODEC_ID_PNG
@ AV_CODEC_ID_PNG
Definition: codec_id.h:111
AV_CODEC_ID_AVUI
@ AV_CODEC_ID_AVUI
Definition: codec_id.h:252
FF_MOV_FLAG_RTP_HINT
#define FF_MOV_FLAG_RTP_HINT
Definition: movenc.h:278
if
if(ret)
Definition: filter_design.txt:179
mov_write_mfhd_tag
static int mov_write_mfhd_tag(AVIOContext *pb, MOVMuxContext *mov)
Definition: movenc.c:5616
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:5143
mov_write_vpcc_tag
static int mov_write_vpcc_tag(AVFormatContext *s, AVIOContext *pb, MOVTrack *track)
Definition: movenc.c:1647
avio_flush
void avio_flush(AVIOContext *s)
Force flushing of buffered data.
Definition: aviobuf.c:228
MOVMuxContext::use_stream_ids_as_track_ids
int use_stream_ids_as_track_ids
Definition: movenc.h:264
MOVTrack::sample_count
long sample_count
Definition: movenc.h:109
MOVTrack::start_dts
int64_t start_dts
Definition: movenc.h:137
AV_CODEC_ID_AVS3
@ AV_CODEC_ID_AVS3
Definition: codec_id.h:245
AVFormatContext
Format I/O context.
Definition: avformat.h:1314
fail
#define fail
Definition: test.h:478
MOVMuxContext::iods_skip
int iods_skip
Definition: movenc.h:226
mov_isobmff_muxer_class
static const AVClass mov_isobmff_muxer_class
Definition: movenc.c:133
calculate_mpeg4_bit_rates
static struct mpeg4_bit_rate_values calculate_mpeg4_bit_rates(MOVTrack *track)
Definition: movenc.c:738
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:8958
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:3669
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:844
AV_CODEC_ID_AV1
@ AV_CODEC_ID_AV1
Definition: codec_id.h:275
AVPixFmtDescriptor::nb_components
uint8_t nb_components
The number of components each pixel has, (1-4)
Definition: pixdesc.h:71
AVEncryptionInitInfo
This describes info used to initialize an encryption key system.
Definition: encryption_info.h:88
isom.h
eac3_info::eof
uint8_t eof
Definition: movenc.c:385
AV_CODEC_ID_TIMED_ID3
@ AV_CODEC_ID_TIMED_ID3
Definition: codec_id.h:605
mov_check_timecode_track
static int mov_check_timecode_track(AVFormatContext *s, AVTimecode *tc, AVStream *src_st, const char *tcstr)
Definition: movenc.c:7840
codec_f4v_tags
static const AVCodecTag codec_f4v_tags[]
Definition: movenc.c:9352
mov_create_timecode_track
static int mov_create_timecode_track(AVFormatContext *s, int index, int src_index, AVTimecode tc)
Definition: movenc.c:7849
mov_write_extradata_tag
static int mov_write_extradata_tag(AVIOContext *pb, MOVTrack *track)
This function writes extradata "as is".
Definition: movenc.c:690
mov_write_packet
static int mov_write_packet(AVFormatContext *s, AVPacket *pkt)
Definition: movenc.c:7598
MP4TrackKindValueMapping::disposition
int disposition
Definition: isom.h:488
mov_write_stsc_tag
static int mov_write_stsc_tag(AVIOContext *pb, MOVTrack *track)
Definition: movenc.c:261
AV_WB16
#define AV_WB16(p, v)
Definition: intreadwrite.h:401
AVIO_DATA_MARKER_TRAILER
@ AVIO_DATA_MARKER_TRAILER
Trailer data, which doesn't contain actual content, but only for finalizing the output file.
Definition: avio.h:139
AV_PIX_FMT_YUYV422
@ AV_PIX_FMT_YUYV422
packed YUV 4:2:2, 16bpp, Y0 Cb Y1 Cr
Definition: pixfmt.h:74
get_moov_size
static int get_moov_size(AVFormatContext *s)
Definition: movenc.c:8927
vc1_unescape_buffer
static av_always_inline int vc1_unescape_buffer(const uint8_t *src, int size, uint8_t *dst)
Definition: vc1_common.h:70
MOVMuxContext::encryption_key_len
int encryption_key_len
Definition: movenc.h:260
AV_CODEC_ID_MOV_TEXT
@ AV_CODEC_ID_MOV_TEXT
Definition: codec_id.h:570
ff_mov_cenc_avc_write_nal_units
int ff_mov_cenc_avc_write_nal_units(AVFormatContext *s, MOVMuxCencContext *ctx, int nal_length_size, AVIOContext *pb, const uint8_t *buf_in, int size)
Write AVC NAL units that are in MP4 format, the nal size and type are written in the clear while the ...
Definition: movenccenc.c:238
AVRational
Rational number (pair of numerator and denominator).
Definition: rational.h:58
ff_hevc_annexb2mp4_buf
int ff_hevc_annexb2mp4_buf(const uint8_t *buf_in, uint8_t **buf_out, int *size, int filter_ps, int *ps_count)
Writes Annex B formatted HEVC NAL units to a data buffer.
Definition: hevc.c:1249
rtp_hinting_needed
static int rtp_hinting_needed(const AVStream *st)
Definition: movenc.c:191
mov_get_apv_codec_tag
static int mov_get_apv_codec_tag(AVFormatContext *s, MOVTrack *track)
Definition: movenc.c:2060
check_pkt
static int check_pkt(AVFormatContext *s, MOVTrack *trk, AVPacket *pkt)
Definition: movenc.c:6916
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:6636
MOVMuxContext::max_fragment_size
int max_fragment_size
Definition: movenc.h:234
ROUNDED_DIV
#define ROUNDED_DIV(a, b)
Definition: common.h:58
MOV_CH_LAYOUT_UNKNOWN
#define MOV_CH_LAYOUT_UNKNOWN
Definition: mov_chan.h:52
AV_CODEC_ID_DVD_SUBTITLE
@ AV_CODEC_ID_DVD_SUBTITLE
Definition: codec_id.h:565
av_default_item_name
const char * av_default_item_name(void *ptr)
Return the context name.
Definition: log.c:242
AVStereo3D::horizontal_disparity_adjustment
AVRational horizontal_disparity_adjustment
Relative shift of the left and right images, which changes the zero parallax plane.
Definition: stereo3d.h:234
get_bits1
static unsigned int get_bits1(GetBitContext *s)
Definition: get_bits.h:391
mov_write_moof_tag_internal
static int mov_write_moof_tag_internal(AVIOContext *pb, MOVMuxContext *mov, int tracks, int moof_size)
Definition: movenc.c:5929
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:2567
avc.h
MOVTrack::cenc
MOVMuxCencContext cenc
Definition: movenc.h:180
AVStreamGroupTREF
AVStreamGroupTREF is meant to define the relation between video, audio, or subtitle streams,...
Definition: avformat.h:1118
options
Definition: swscale.c:50
TAG_IS_AVCI
#define TAG_IS_AVCI(tag)
Definition: isom.h:442
AC3HeaderInfo::substreamid
int substreamid
substream identification
Definition: ac3_parser_internal.h:46
MOVTrack::last_sample_is_subtitle_end
int last_sample_is_subtitle_end
Definition: movenc.h:101
VC1_CODE_ENTRYPOINT
@ VC1_CODE_ENTRYPOINT
Definition: vc1_common.h:39
AVStream::metadata
AVDictionary * metadata
Definition: avformat.h:827
get_cluster_duration
static int get_cluster_duration(MOVTrack *track, int cluster_idx)
Definition: movenc.c:1259
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:2595
MOV_SAMPLE_DEPENDENCY_NO
#define MOV_SAMPLE_DEPENDENCY_NO
Definition: isom.h:440
MOVMuxContext
Definition: movenc.h:211
mov_add_tref_tag
static MovTag * mov_add_tref_tag(MOVMuxContext *mov, MOVTrack *trk, uint32_t name)
Definition: movenc.c:5341
ff_iamf_add_mix_presentation
int ff_iamf_add_mix_presentation(IAMFContext *iamf, const AVStreamGroup *stg, void *log_ctx)
Definition: iamf_writer.c:433
MOVMuxContext::missing_duration_warned
int missing_duration_warned
Definition: movenc.h:255
MOVTrack::data_offset
int64_t data_offset
Definition: movenc.h:160
mov_write_track_metadata
static int mov_write_track_metadata(AVIOContext *pb, AVStream *st, const char *tag, const char *str)
Definition: movenc.c:4317
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:2729
ff_mov_get_channel_positions_from_layout
int ff_mov_get_channel_positions_from_layout(const AVChannelLayout *layout, uint8_t *position, int position_num)
Get ISO/IEC 23001-8 OutputChannelPosition from AVChannelLayout.
Definition: mov_chan.c:741
ff_codec_movvideo_tags
const AVCodecTag ff_codec_movvideo_tags[]
Definition: isom_tags.c:29
AV_PIX_FMT_YUV422P10
#define AV_PIX_FMT_YUV422P10
Definition: pixfmt.h:540
mov_get_lpcm_flags
static int mov_get_lpcm_flags(enum AVCodecID codec_id)
Compute flags for 'lpcm' tag.
Definition: movenc.c:1234
ffio_fill
void ffio_fill(AVIOContext *s, int b, int64_t count)
Definition: aviobuf.c:192
MOVIentry::cts
int cts
Definition: movenc.h:58
AV_DISPOSITION_MULTILAYER
#define AV_DISPOSITION_MULTILAYER
The video stream contains multiple layers, e.g.
Definition: avformat.h:717
AV_CODEC_ID_QDM2
@ AV_CODEC_ID_QDM2
Definition: codec_id.h:471
AV_PIX_FMT_GRAY8
@ AV_PIX_FMT_GRAY8
Y , 8bpp.
Definition: pixfmt.h:81
mov_write_nmhd_tag
static int mov_write_nmhd_tag(AVIOContext *pb)
Definition: movenc.c:3469
AVProducerReferenceTime
This structure supplies correlation between a packet timestamp and a wall clock production time.
Definition: defs.h:331
av_packet_ref
int av_packet_ref(AVPacket *dst, const AVPacket *src)
Setup a new reference to the data described by a given packet.
Definition: packet.c:442
MOVTrack::nb_src_track
int nb_src_track
Definition: movenc.h:145
AVCodecParameters::ch_layout
AVChannelLayout ch_layout
The channel layout and number of channels.
Definition: codec_par.h:207
mov_get_codec_tag
static unsigned int mov_get_codec_tag(AVFormatContext *s, MOVTrack *track)
Definition: movenc.c:2131
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:3840
mov_write_SA3D_tag
static int mov_write_SA3D_tag(AVFormatContext *s, AVIOContext *pb, MOVTrack *track)
Definition: movenc.c:958
AV_CODEC_ID_VP6A
@ AV_CODEC_ID_VP6A
Definition: codec_id.h:156
MOVTrack::packet_seq
int packet_seq
Definition: movenc.h:173
param_write_int
static void param_write_int(AVIOContext *pb, const char *name, int value)
Definition: movenc.c:5474
FF_MOV_FLAG_DISABLE_CHPL
#define FF_MOV_FLAG_DISABLE_CHPL
Definition: movenc.h:287
FLAC_METADATA_TYPE_STREAMINFO
@ FLAC_METADATA_TYPE_STREAMINFO
Definition: flac.h:46
mov_write_ctts_tag
static int mov_write_ctts_tag(AVFormatContext *s, AVIOContext *pb, MOVTrack *track)
Definition: movenc.c:3219
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:4600
AVProducerReferenceTime::flags
int flags
Definition: defs.h:336
MOV_MP4_TTML_TAG
#define MOV_MP4_TTML_TAG
Definition: isom.h:483
AV_PKT_DATA_CONTENT_LIGHT_LEVEL
@ AV_PKT_DATA_CONTENT_LIGHT_LEVEL
Content light level (based on CTA-861.3).
Definition: packet.h:232
MOV_TFHD_BASE_DATA_OFFSET
#define MOV_TFHD_BASE_DATA_OFFSET
Definition: isom.h:408
AV_PIX_FMT_ABGR
@ AV_PIX_FMT_ABGR
packed ABGR 8:8:8:8, 32bpp, ABGRABGR...
Definition: pixfmt.h:101
AV_CODEC_ID_MP4ALS
@ AV_CODEC_ID_MP4ALS
Definition: codec_id.h:497
AVCOL_RANGE_UNSPECIFIED
@ AVCOL_RANGE_UNSPECIFIED
Definition: pixfmt.h:743
mov_write_isml_manifest
static int mov_write_isml_manifest(AVIOContext *pb, MOVMuxContext *mov, AVFormatContext *s)
Definition: movenc.c:5492
MOVMuxContext::empty_hdlr_name
int empty_hdlr_name
Definition: movenc.h:269
ff_codec_movaudio_tags
const AVCodecTag ff_codec_movaudio_tags[]
Definition: isom_tags.c:306
AV_OPT_FLAG_ENCODING_PARAM
#define AV_OPT_FLAG_ENCODING_PARAM
A generic parameter which can be set by the user for muxing or encoding.
Definition: opt.h:351
index
int index
Definition: gxfenc.c:90
c
Undefined Behavior In the C some operations are like signed integer dereferencing freed accessing outside allocated Undefined Behavior must not occur in a C it is not safe even if the output of undefined operations is unused The unsafety may seem nit picking but Optimizing compilers have in fact optimized code on the assumption that no undefined Behavior occurs Optimizing code based on wrong assumptions can and has in some cases lead to effects beyond the output of computations The signed integer overflow problem in speed critical code Code which is highly optimized and works with signed integers sometimes has the problem that often the output of the computation does not c
Definition: undefined.txt:32
mov_write_subtitle_end_packet
static int mov_write_subtitle_end_packet(AVFormatContext *s, int stream_index, int64_t dts)
Definition: movenc.c:7501
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:3421
cid
uint16_t cid
Definition: mxfenc.c:2335
compute_sidx_size
static int compute_sidx_size(AVFormatContext *s)
Definition: movenc.c:8983
MOVStts
Definition: isom.h:63
AC3HeaderInfo::num_blocks
int num_blocks
number of audio blocks
Definition: ac3_parser_internal.h:51
AV_CODEC_ID_MPEG1VIDEO
@ AV_CODEC_ID_MPEG1VIDEO
Definition: codec_id.h:51
av_buffer_create
AVBufferRef * av_buffer_create(uint8_t *data, size_t size, void(*free)(void *opaque, uint8_t *data), void *opaque, int flags)
Create an AVBuffer from an existing array.
Definition: buffer.c:55
ff_ipod_muxer
const FFOutputFormat ff_ipod_muxer
find_compressor
static void find_compressor(char *compressor_name, int len, MOVTrack *track)
Definition: movenc.c:2756
AVStream::nb_frames
int64_t nb_frames
number of frames in this stream if known or 0
Definition: avformat.h:808
movenc.h
AVCodecID
AVCodecID
Identify the syntax and semantics of the bitstream.
Definition: codec_id.h:47
av_packet_side_data_get
const AVPacketSideData * av_packet_side_data_get(const AVPacketSideData *sd, int nb_sd, enum AVPacketSideDataType type)
Get side information from a side data array.
Definition: packet.c:570
AV_CODEC_ID_EAC3
@ AV_CODEC_ID_EAC3
Definition: codec_id.h:492
AV_PKT_DATA_SPHERICAL
@ AV_PKT_DATA_SPHERICAL
This side data should be associated with a video stream and corresponds to the AVSphericalMapping str...
Definition: packet.h:225
AVCodecParameters::extradata_size
int extradata_size
Size of the extradata content in bytes.
Definition: codec_par.h:75
AV_WB32
#define AV_WB32(p, v)
Definition: intreadwrite.h:415
MOV_FRAG_SAMPLE_FLAG_DEPENDS_NO
#define MOV_FRAG_SAMPLE_FLAG_DEPENDS_NO
Definition: isom.h:430
EAC3_FRAME_TYPE_AC3_CONVERT
@ EAC3_FRAME_TYPE_AC3_CONVERT
Definition: ac3defs.h:113
AV_CODEC_ID_AAC
@ AV_CODEC_ID_AAC
Definition: codec_id.h:454
ff_mov_get_channel_config_from_layout
int ff_mov_get_channel_config_from_layout(const AVChannelLayout *layout, int *config)
Get ISO/IEC 23001-8 ChannelConfiguration from AVChannelLayout.
Definition: mov_chan.c:705
AVStereo3D::primary_eye
enum AVStereo3DPrimaryEye primary_eye
Which eye is the primary eye when rendering in 2D.
Definition: stereo3d.h:222
AV_ROUND_DOWN
@ AV_ROUND_DOWN
Round toward -infinity.
Definition: mathematics.h:133
AV_UUID_LEN
#define AV_UUID_LEN
Definition: uuid.h:57
av_rescale_rnd
int64_t av_rescale_rnd(int64_t a, int64_t b, int64_t c, enum AVRounding rnd)
Rescale a 64-bit integer with specified rounding.
Definition: mathematics.c:58
AV_CODEC_ID_QCELP
@ AV_CODEC_ID_QCELP
Definition: codec_id.h:476
AV_SPHERICAL_HALF_EQUIRECTANGULAR
@ AV_SPHERICAL_HALF_EQUIRECTANGULAR
Video frame displays as a 180 degree equirectangular projection.
Definition: spherical.h:73
av_get_exact_bits_per_sample
int av_get_exact_bits_per_sample(enum AVCodecID codec_id)
Return codec bits per sample.
Definition: utils.c:461
ff_mov_generate_squashed_ttml_packet
int ff_mov_generate_squashed_ttml_packet(AVFormatContext *s, MOVTrack *track, AVPacket *pkt)
Definition: movenc_ttml.c:236
AV_CODEC_ID_FFV1
@ AV_CODEC_ID_FFV1
Definition: codec_id.h:83
AVIOContext
Bytestream IO Context.
Definition: avio.h:160
AV_CODEC_ID_PCM_S24LE
@ AV_CODEC_ID_PCM_S24LE
Definition: codec_id.h:342
AV_PIX_FMT_RGB24
@ AV_PIX_FMT_RGB24
packed RGB 8:8:8, 24bpp, RGBRGB...
Definition: pixfmt.h:75
AV_SPHERICAL_CUBEMAP
@ AV_SPHERICAL_CUBEMAP
Video frame is split into 6 faces of a cube, and arranged on a 3x2 layout.
Definition: spherical.h:61
ffio_reset_dyn_buf
void ffio_reset_dyn_buf(AVIOContext *s)
Reset a dynamic buffer.
Definition: aviobuf.c:1399
ff_mov_cenc_av1_write_obus
int ff_mov_cenc_av1_write_obus(AVFormatContext *s, MOVMuxCencContext *ctx, AVIOContext *pb, const AVPacket *pkt)
Definition: movenccenc.c:387
ac3_parser_internal.h
AVPacket::size
int size
Definition: packet.h:604
NULL_IF_CONFIG_SMALL
#define NULL_IF_CONFIG_SMALL(x)
Return NULL if CONFIG_SMALL is true, otherwise the argument without modification.
Definition: internal.h:88
avpriv_pix_fmt_find
enum AVPixelFormat avpriv_pix_fmt_find(enum PixelFormatTagLists list, unsigned fourcc)
Definition: raw.c:78
AV_STREAM_GROUP_PARAMS_TREF
@ AV_STREAM_GROUP_PARAMS_TREF
Definition: avformat.h:1133
codec_ipod_tags
static const AVCodecTag codec_ipod_tags[]
Definition: movenc.c:9341
copy
static void copy(const float *p1, float *p2, const int length)
Definition: vf_vaguedenoiser.c:186
FF_OFMT_FLAG_ALLOW_FLUSH
#define FF_OFMT_FLAG_ALLOW_FLUSH
This flag indicates that the muxer stores data internally and supports flushing it.
Definition: mux.h:38
ff_isom_write_avcc
int ff_isom_write_avcc(AVIOContext *pb, const uint8_t *data, int len)
Definition: avc.c:32
height
#define height
Definition: dsp.h:89
AC3HeaderInfo::channel_map_present
uint8_t channel_map_present
Definition: ac3_parser_internal.h:49
MOVTrack::cover_image
AVPacket * cover_image
Definition: movenc.h:157
MOVTrack::vc1_info
struct MOVTrack::@500 vc1_info
AVChannelLayout
An AVChannelLayout holds information about the channel layout of audio data.
Definition: channel_layout.h:319
MOVFragmentInfo::time
int64_t time
Definition: movenc.h:82
AVSphericalMapping::bound_right
uint32_t bound_right
Distance from the right edge.
Definition: spherical.h:187
mov_write_dpxe_tag
static int mov_write_dpxe_tag(AVIOContext *pb, MOVTrack *track)
Definition: movenc.c:1879
mov_write_vvcc_tag
static int mov_write_vvcc_tag(AVIOContext *pb, MOVTrack *track)
Definition: movenc.c:1725
FF_MOV_FLAG_FASTSTART
#define FF_MOV_FLAG_FASTSTART
Definition: movenc.h:285
mpeg4_bit_rate_values::avg_bit_rate
uint32_t avg_bit_rate
Average rate in bits/second over the entire presentation.
Definition: movenc.c:735
MOVTrack::language
int language
Definition: movenc.h:122
i
#define i(width, name, range_min, range_max)
Definition: cbs_h264.c:63
av_err2str
#define av_err2str(errnum)
Convenience macro, the return value should be used only directly in function arguments but never stan...
Definition: error.h:122
MOVMuxContext::first_trun
int first_trun
Definition: movenc.h:237
MOVMuxContext::ism_lookahead
int ism_lookahead
Definition: movenc.h:235
ff_vvc_annexb2mp4_buf
int ff_vvc_annexb2mp4_buf(const uint8_t *buf_in, uint8_t **buf_out, int *size, int filter_ps, int *ps_count)
Writes Annex B formatted H.266/VVC NAL units to a data buffer.
Definition: vvc.c:858
mov_write_eac3_tag
static int mov_write_eac3_tag(AVFormatContext *s, AVIOContext *pb, MOVTrack *track)
Definition: movenc.c:630
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:2403
ff_mov_cenc_write_stbl_atoms
void ff_mov_cenc_write_stbl_atoms(MOVMuxCencContext *ctx, AVIOContext *pb, int64_t moof_offset)
Write the cenc atoms that should reside inside stbl.
Definition: movenccenc.c:542
AV_CODEC_ID_DTS
@ AV_CODEC_ID_DTS
Definition: codec_id.h:456
bps
unsigned bps
Definition: movenc.c:2074
MOVTrack::default_sample_flags
uint32_t default_sample_flags
Definition: movenc.h:153
ff_nal_parse_units_buf
int ff_nal_parse_units_buf(const uint8_t *buf_in, uint8_t **buf, int *size)
Definition: nal.c:133
mov_write_vexu_tag
static int mov_write_vexu_tag(AVFormatContext *s, AVIOContext *pb, const AVStereo3D *stereo3d, const AVSphericalMapping *spherical_mapping)
Definition: movenc.c:2499
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:732
AV_CODEC_ID_H263
@ AV_CODEC_ID_H263
Definition: codec_id.h:54
MOV_TFHD_STSD_ID
#define MOV_TFHD_STSD_ID
Definition: isom.h:409
ff_iamf_uninit_context
void ff_iamf_uninit_context(IAMFContext *c)
Definition: iamf.c:172
size
int size
Definition: twinvq_data.h:10344
MOVMuxContext::avif_extent_pos
int64_t avif_extent_pos[2]
Definition: movenc.h:272
mov_write_mdta_keys_tag
static int mov_write_mdta_keys_tag(AVIOContext *pb, MOVMuxContext *mov, AVFormatContext *s)
Definition: movenc.c:4917
avio.h
mov_write_uuid_tag_psp
static int mov_write_uuid_tag_psp(AVIOContext *pb, MOVTrack *mov)
Definition: movenc.c:4277
video_st
static AVStream * video_st
Definition: movenc.c:61
AV_NOPTS_VALUE
#define AV_NOPTS_VALUE
Undefined timestamp value.
Definition: avutil.h:247
NTP_OFFSET_US
#define NTP_OFFSET_US
Definition: internal.h:415
codec_mp4_tags
static const AVCodecTag codec_mp4_tags[]
Definition: movenc.c:9270
ff_iamf_write_parameter_blocks
int ff_iamf_write_parameter_blocks(const IAMFContext *iamf, AVIOContext *pb, const AVPacket *pkt, void *log_ctx)
Definition: iamf_writer.c:1172
AV_RB32
uint64_t_TMPL AV_WL64 unsigned int_TMPL AV_WL32 unsigned int_TMPL AV_WL24 unsigned int_TMPL AV_WL16 uint64_t_TMPL AV_WB64 unsigned int_TMPL AV_RB32
Definition: bytestream.h:96
AV_CODEC_ID_V210
@ AV_CODEC_ID_V210
Definition: codec_id.h:177
mov_write_lhvc_tag
static int mov_write_lhvc_tag(AVFormatContext *s, AVIOContext *pb, MOVTrack *track)
Definition: movenc.c:1673
get_metadata_lang
static AVDictionaryEntry * get_metadata_lang(AVFormatContext *s, const char *tag, int *lang)
Definition: movenc.c:4664
FF_MOV_FLAG_ISML
#define FF_MOV_FLAG_ISML
Definition: movenc.h:284
FF_PUT_WAV_HEADER_FORCE_WAVEFORMATEX
#define FF_PUT_WAV_HEADER_FORCE_WAVEFORMATEX
Tell ff_put_wav_header() to use WAVEFORMATEX even for PCM codecs.
Definition: riff.h:53
AVCodecParameters::profile
int profile
Codec-specific bitstream restrictions that the stream conforms to.
Definition: codec_par.h:135
write_matrix
static void write_matrix(AVIOContext *pb, int16_t a, int16_t b, int16_t c, int16_t d, int16_t tx, int16_t ty)
Definition: movenc.c:3995
mov_create_dvd_sub_decoder_specific_info
static int mov_create_dvd_sub_decoder_specific_info(MOVTrack *track, AVStream *st)
Definition: movenc.c:8022
AV_CODEC_ID_OPUS
@ AV_CODEC_ID_OPUS
Definition: codec_id.h:512
MOVMuxContext::reserved_header_pos
int64_t reserved_header_pos
Definition: movenc.h:242
MOVTrack::audio_vbr
int audio_vbr
Definition: movenc.h:133
mov_write_gmhd_tag
static int mov_write_gmhd_tag(AVIOContext *pb, MOVTrack *track)
Definition: movenc.c:3507
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:3184
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:3123
mov_write_dmlp_tag
static int mov_write_dmlp_tag(AVFormatContext *s, AVIOContext *pb, MOVTrack *track)
Definition: movenc.c:929
AVIO_DATA_MARKER_SYNC_POINT
@ AVIO_DATA_MARKER_SYNC_POINT
A point in the output bytestream where a decoder can start decoding (i.e.
Definition: avio.h:121
MOVTrack::end_reliable
int end_reliable
Definition: movenc.h:141
ff_mov_iso639_to_lang
int ff_mov_iso639_to_lang(const char lang[4], int mp4)
Definition: isom.c:233
calc_pts_duration
static int64_t calc_pts_duration(MOVMuxContext *mov, MOVTrack *track)
Definition: movenc.c:3914
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:2559
ff_isom_write_av1c
int ff_isom_write_av1c(AVIOContext *pb, const uint8_t *buf, int size, int write_seq_header)
Writes AV1 extradata (Sequence Header and Metadata OBUs) to the provided AVIOContext.
Definition: av1.c:399
AVPacket::dts
int64_t dts
Decompression timestamp in AVStream->time_base units; the time at which the packet is decompressed.
Definition: packet.h:602
avio_write
void avio_write(AVIOContext *s, const unsigned char *buf, int size)
Definition: aviobuf.c:206
avio_wb32
void avio_wb32(AVIOContext *s, unsigned int val)
Definition: aviobuf.c:368
FF_COMPLIANCE_NORMAL
#define FF_COMPLIANCE_NORMAL
Definition: defs.h:60
AVSphericalMapping::padding
uint32_t padding
Number of pixels to pad from the edge of each cube face.
Definition: spherical.h:200
a
The reader does not expect b to be semantically here and if the code is changed by maybe adding a a division or other the signedness will almost certainly be mistaken To avoid this confusion a new type was SUINT is the C unsigned type but it holds a signed int to use the same example SUINT a
Definition: undefined.txt:41
MOVTrack::slices
int slices
Definition: movenc.h:175
av_reallocp_array
int av_reallocp_array(void *ptr, size_t nmemb, size_t size)
Allocate, reallocate an array through a pointer to a pointer.
Definition: mem.c:225
mov_get_evc_codec_tag
static int mov_get_evc_codec_tag(AVFormatContext *s, MOVTrack *track)
Definition: movenc.c:2050
AV_PRIMARY_EYE_NONE
@ AV_PRIMARY_EYE_NONE
Neither eye.
Definition: stereo3d.h:178
MOV_MP4_FPCM_TAG
#define MOV_MP4_FPCM_TAG
Definition: isom.h:484
avio_wl32
void avio_wl32(AVIOContext *s, unsigned int val)
Definition: aviobuf.c:360
csp.h
AV_CODEC_ID_VVC
@ AV_CODEC_ID_VVC
Definition: codec_id.h:247
MOVTrack::first_packet_seen
int first_packet_seen
Definition: movenc.h:171
mov_write_subtitle_tag
static int mov_write_subtitle_tag(AVFormatContext *s, AVIOContext *pb, MOVTrack *track)
Definition: movenc.c:2265
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:4331
offset
it s the only field you need to keep assuming you have a context There is some magic you don t need to care about around this just let it vf offset
Definition: writing_filters.txt:86
AV_CODEC_ID_LCEVC
@ AV_CODEC_ID_LCEVC
Definition: codec_id.h:608
AC3HeaderInfo::bitstream_mode
uint8_t bitstream_mode
Definition: ac3_parser_internal.h:42
AVPacket::flags
int flags
A combination of AV_PKT_FLAG values.
Definition: packet.h:609
av_packet_alloc
AVPacket * av_packet_alloc(void)
Allocate an AVPacket and set its fields to default values.
Definition: packet.c:63
xf
#define xf(width, name, var, range_min, range_max, subs,...)
Definition: cbs_av1.c:622
FF_COMPLIANCE_UNOFFICIAL
#define FF_COMPLIANCE_UNOFFICIAL
Allow unofficial extensions.
Definition: defs.h:61
MOVTrack::start_cts
int64_t start_cts
Definition: movenc.h:138
AVCodecParameters::avcodec_parameters_alloc
AVCodecParameters * avcodec_parameters_alloc(void)
Allocate a new AVCodecParameters and set its fields to default values (unknown/invalid/0).
Definition: codec_par.c:57
version
version
Definition: libkvazaar.c:313
AV_STREAM_GROUP_PARAMS_IAMF_AUDIO_ELEMENT
@ AV_STREAM_GROUP_PARAMS_IAMF_AUDIO_ELEMENT
Definition: avformat.h:1129
mov_write_avid_tag
static int mov_write_avid_tag(AVIOContext *pb, MOVTrack *track)
Definition: movenc.c:1761
mov_write_mdta_ilst_tag
static int mov_write_mdta_ilst_tag(AVIOContext *pb, MOVMuxContext *mov, AVFormatContext *s)
Definition: movenc.c:4946
AV_STEREO3D_FLAG_INVERT
#define AV_STEREO3D_FLAG_INVERT
Inverted views, Right/Bottom represents the left view.
Definition: stereo3d.h:194
MOVIentry::chunkNum
unsigned int chunkNum
Chunk number if the current entry is a chunk start otherwise 0.
Definition: movenc.h:56
AVStreamGroup::streams
AVStream ** streams
A list of streams in the group.
Definition: avformat.h:1215
vc1_common.h
mov_write_meta_tag
static int mov_write_meta_tag(AVIOContext *pb, MOVMuxContext *mov, AVFormatContext *s)
Definition: movenc.c:4968
FF_MOV_FLAG_OMIT_TFHD_OFFSET
#define FF_MOV_FLAG_OMIT_TFHD_OFFSET
Definition: movenc.h:286
MOV_MP4_IPCM_TAG
#define MOV_MP4_IPCM_TAG
Definition: isom.h:485
MOV_DISPOSABLE_SAMPLE
#define MOV_DISPOSABLE_SAMPLE
Definition: movenc.h:61
shift_data
static int shift_data(AVFormatContext *s)
Definition: movenc.c:8998
mov_write_dvc1_structs
static int mov_write_dvc1_structs(MOVTrack *track, uint8_t *buf)
Definition: movenc.c:1120
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:3702
AC3HeaderInfo::ac3_bit_rate_code
int8_t ac3_bit_rate_code
Definition: ac3_parser_internal.h:64
AV_CODEC_ID_TSCC2
@ AV_CODEC_ID_TSCC2
Definition: codec_id.h:213
AV_LOG_INFO
#define AV_LOG_INFO
Standard information.
Definition: log.h:221
mov_free
static void mov_free(AVFormatContext *s)
Definition: movenc.c:7947
MODE_3GP
#define MODE_3GP
Definition: movenc.h:40
MOVTrack::time
uint64_t time
Definition: movenc.h:99
FF_MOV_FLAG_SKIP_SIDX
#define FF_MOV_FLAG_SKIP_SIDX
Definition: movenc.h:299
AV_PIX_FMT_ARGB
@ AV_PIX_FMT_ARGB
packed ARGB 8:8:8:8, 32bpp, ARGBARGB...
Definition: pixfmt.h:99
AV_OPT_TYPE_FLOAT
@ AV_OPT_TYPE_FLOAT
Underlying C type is float.
Definition: opt.h:270
apv.h
ff_mov_add_hinted_packet
int ff_mov_add_hinted_packet(AVFormatContext *s, AVPacket *pkt, int track_index, int sample, uint8_t *sample_data, int sample_size)
Definition: movenchint.c:405
AV_SPHERICAL_RECTILINEAR
@ AV_SPHERICAL_RECTILINEAR
Video frame displays on a flat, rectangular 2D surface.
Definition: spherical.h:78
layout
Filter the word “frame” indicates either a video frame or a group of audio as stored in an AVFrame structure Format for each input and each output the list of supported formats For video that means pixel format For audio that means channel layout
Definition: filter_design.txt:18
mov_write_covr
static int mov_write_covr(AVIOContext *pb, AVFormatContext *s)
Definition: movenc.c:4834
avcodec_get_name
const char * avcodec_get_name(enum AVCodecID id)
Get the name of a codec.
Definition: utils.c:421
AV_CODEC_ID_MJPEG
@ AV_CODEC_ID_MJPEG
Definition: codec_id.h:57
MOVTrack::hint_track
int hint_track
the track that hints this track, -1 if no hint track is set
Definition: movenc.h:144
MOVTrack::has_keyframes
int has_keyframes
Definition: movenc.h:112
AV_PIX_FMT_UYVA
@ AV_PIX_FMT_UYVA
packed UYVA 4:4:4:4, 32bpp (1 Cr & Cb sample per 1x1 Y & A samples), UYVAUYVA...
Definition: pixfmt.h:444
av_double2int
static av_always_inline uint64_t av_double2int(double f)
Reinterpret a double as a 64-bit integer.
Definition: intfloat.h:70
mov_write_iprp_tag
static int mov_write_iprp_tag(AVIOContext *pb, MOVMuxContext *mov, AVFormatContext *s)
Definition: movenc.c:3815
interlaced
uint8_t interlaced
Definition: mxfenc.c:2336
MOVTrack::entry
int entry
Definition: movenc.h:97
av_assert2
#define av_assert2(cond)
assert() equivalent, that does lie in speed critical code.
Definition: avassert.h:68
mov_write_uuidprof_tag
static int mov_write_uuidprof_tag(AVIOContext *pb, AVFormatContext *s)
Definition: movenc.c:6373
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:3460
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:1637
ff_interleaved_peek
const AVPacket * ff_interleaved_peek(AVFormatContext *s, int stream)
Find the next packet in the interleaving queue for the given stream.
Definition: mux.c:1043
AVFMT_GLOBALHEADER
#define AVFMT_GLOBALHEADER
Format wants global header.
Definition: avformat.h:478
av_malloc
#define av_malloc(s)
Definition: ops_asmgen.c:44
FF_MOV_FLAG_EMPTY_MOOV
#define FF_MOV_FLAG_EMPTY_MOOV
Definition: movenc.h:280
AV_CODEC_ID_NONE
@ AV_CODEC_ID_NONE
Definition: codec_id.h:48
AVPacket::pts
int64_t pts
Presentation timestamp in AVStream->time_base units; the time at which the decompressed packet will b...
Definition: packet.h:596
avio_internal.h
ff_mov_write_packet
int ff_mov_write_packet(AVFormatContext *s, AVPacket *pkt)
Definition: movenc.c:6951
MOVCtts::offset
int offset
Definition: isom.h:70
round
static av_always_inline av_const double round(double x)
Definition: libm.h:446
MOVMuxContext::nb_streams
int nb_streams
Definition: movenc.h:215
av_packet_get_side_data
uint8_t * av_packet_get_side_data(const AVPacket *pkt, enum AVPacketSideDataType type, size_t *size)
Get side information from packet.
Definition: packet.c:252
av_gcd_q
AVRational av_gcd_q(AVRational a, AVRational b, int max_den, AVRational def)
Return the best rational so that a and b are multiple of it.
Definition: rational.c:188
AV_SPHERICAL_FISHEYE
@ AV_SPHERICAL_FISHEYE
Fisheye projection (Apple).
Definition: spherical.h:84
AV_CODEC_ID_EVRC
@ AV_CODEC_ID_EVRC
Definition: codec_id.h:523
AVCodecParameters::height
int height
The height of the video frame in pixels.
Definition: codec_par.h:150
mov_write_avcc_tag
static int mov_write_avcc_tag(AVIOContext *pb, MOVTrack *track)
Definition: movenc.c:1603
AV_TIME_BASE
#define AV_TIME_BASE
Internal time base represented as integer.
Definition: avutil.h:253
MOVMuxContext::fragments
int fragments
Definition: movenc.h:231
AVCodecParameters::block_align
int block_align
The number of bytes per coded audio frame, required by some formats.
Definition: codec_par.h:221
AV_CODEC_ID_TTML
@ AV_CODEC_ID_TTML
Definition: codec_id.h:589
av_malloc_array
#define av_malloc_array(a, b)
Definition: tableprint_vlc.h:32
mov_get_mpeg2_xdcam_codec_tag
static int mov_get_mpeg2_xdcam_codec_tag(AVFormatContext *s, MOVTrack *track)
Definition: movenc.c:1926
MOV_PRFT_SRC_WALLCLOCK
@ MOV_PRFT_SRC_WALLCLOCK
Definition: movenc.h:206
AV_PKT_DATA_ICC_PROFILE
@ AV_PKT_DATA_ICC_PROFILE
ICC profile data consisting of an opaque octet buffer following the format described by ISO 15076-1.
Definition: packet.h:271
AV_STEREO3D_TOPBOTTOM
@ AV_STEREO3D_TOPBOTTOM
Views are on top of each other.
Definition: stereo3d.h:76
ff_mov_cenc_flush
void ff_mov_cenc_flush(MOVMuxCencContext *ctx)
Clear subsample data.
Definition: movenccenc.c:633
av_assert1
#define av_assert1(cond)
assert() equivalent, that does not lie in speed critical code.
Definition: avassert.h:58
MOVTrack::extradata_size
int * extradata_size
Definition: movenc.h:107
mov_write_string_tag
static int mov_write_string_tag(AVIOContext *pb, const char *name, const char *value, int lang, int long_style)
Definition: movenc.c:4621
MOVTrack::first_packet_seq
int first_packet_seq
Definition: movenc.h:169
s
uint8_t s
Definition: llvidencdsp.c:39
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:391
avpriv_ac3_parse_header
int avpriv_ac3_parse_header(AC3HeaderInfo **phdr, const uint8_t *buf, size_t size)
Definition: ac3_parser.c:491
AV_CODEC_ID_PCM_F64BE
@ AV_CODEC_ID_PCM_F64BE
Definition: codec_id.h:352
mov_write_mdat_size
static void mov_write_mdat_size(AVFormatContext *s)
Definition: movenc.c:9013
AVStreamGroupLayeredVideo::width
int width
Width of the final stream for presentation.
Definition: avformat.h:1095
AV_CODEC_ID_HEVC
@ AV_CODEC_ID_HEVC
Definition: codec_id.h:223
value
it s the only field you need to keep assuming you have a context There is some magic you don t need to care about around this just let it vf default value
Definition: writing_filters.txt:86
MOVMuxContext::video_track_timescale
int video_track_timescale
Definition: movenc.h:239
mov_write_stss_tag
static int mov_write_stss_tag(AVIOContext *pb, MOVTrack *track, uint32_t flag)
Definition: movenc.c:292
MOV_TIMECODE_FLAG_DROPFRAME
#define MOV_TIMECODE_FLAG_DROPFRAME
Definition: movenc.h:118
FFMIN
#define FFMIN(a, b)
Definition: macros.h:49
mov_parse_truehd_frame
static void mov_parse_truehd_frame(AVPacket *pkt, MOVTrack *trk)
Definition: movenc.c:6554
AV_CODEC_ID_DVVIDEO
@ AV_CODEC_ID_DVVIDEO
Definition: codec_id.h:74
AV_CODEC_ID_PCM_S32BE
@ AV_CODEC_ID_PCM_S32BE
Definition: codec_id.h:339
AC3HeaderInfo::channel_map
uint16_t channel_map
Definition: ac3_parser_internal.h:50
MOVMuxContext::max_fragment_duration
int max_fragment_duration
Definition: movenc.h:232
ff_mov_cenc_init
int ff_mov_cenc_init(MOVMuxCencContext *ctx, uint8_t *encryption_key, int use_subsamples, enum AVCodecID codec_id, int bitexact)
Initialize a CENC context.
Definition: movenccenc.c:600
MOVTrack::rtp_ctx
AVFormatContext * rtp_ctx
the format context for the hinting rtp muxer
Definition: movenc.h:147
av_inv_q
static av_always_inline AVRational av_inv_q(AVRational q)
Invert a rational.
Definition: rational.h:159
AV_CODEC_ID_VC1
@ AV_CODEC_ID_VC1
Definition: codec_id.h:120
mov_find_tref_tag
static MovTag * mov_find_tref_tag(MOVMuxContext *mov, const MOVTrack *trk, uint32_t name)
Definition: movenc.c:5330
AVCodecParameters::color_range
enum AVColorRange color_range
Additional colorspace characteristics.
Definition: codec_par.h:189
AVMasteringDisplayMetadata
Mastering display metadata capable of representing the color volume of the display used to master the...
Definition: mastering_display_metadata.h:38
len
int len
Definition: vorbis_enc_data.h:426
AV_CODEC_ID_JPEG2000
@ AV_CODEC_ID_JPEG2000
Definition: codec_id.h:138
MOV_TFHD_DEFAULT_SIZE
#define MOV_TFHD_DEFAULT_SIZE
Definition: isom.h:411
mov_write_tapt_tag
static int mov_write_tapt_tag(AVIOContext *pb, MOVTrack *track)
Definition: movenc.c:4117
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:9178
MOV_SAMPLE_DEPENDENCY_YES
#define MOV_SAMPLE_DEPENDENCY_YES
Definition: isom.h:439
av_rescale
int64_t av_rescale(int64_t a, int64_t b, int64_t c)
Rescale a 64-bit integer with rounding to nearest.
Definition: mathematics.c:129
AVCodecParameters::coded_side_data
AVPacketSideData * coded_side_data
Additional data associated with the entire stream.
Definition: codec_par.h:83
nal.h
AVCOL_RANGE_MPEG
@ AVCOL_RANGE_MPEG
Narrow or limited range content.
Definition: pixfmt.h:760
av_calloc
void * av_calloc(size_t nmemb, size_t size)
Definition: mem.c:264
MOVTrack::iamf
struct IAMFContext * iamf
Definition: movenc.h:191
AVCodecParameters::field_order
enum AVFieldOrder field_order
The order of the fields in interlaced video.
Definition: codec_par.h:182
ff_packet_list_put
int ff_packet_list_put(PacketList *list, AVPacket *pkt, int(*copy)(AVPacket *dst, const AVPacket *src), int flags)
Append an AVPacket to the list.
Definition: packet_list.c:40
update_size
static int64_t update_size(AVIOContext *pb, int64_t pos)
Definition: movenc.c:155
MP4TrackKindValueMapping
Definition: isom.h:487
ff_tgp_muxer
const FFOutputFormat ff_tgp_muxer
AVFMT_TS_NEGATIVE
#define AVFMT_TS_NEGATIVE
Format allows muxing negative timestamps.
Definition: avformat.h:491
ff_sdp_write_media
int ff_sdp_write_media(char *buff, int size, const AVStream *st, int idx, const char *dest_addr, const char *dest_type, int port, int ttl, AVFormatContext *fmt)
Append the media-specific SDP fragment for the media stream c to the buffer buff.
Definition: sdp.c:955
ff_iamf_write_audio_frame
int ff_iamf_write_audio_frame(const IAMFContext *iamf, AVIOContext *pb, unsigned audio_substream_id, const AVPacket *pkt)
Definition: iamf_writer.c:1222
ff_iamf_write_descriptors
int ff_iamf_write_descriptors(const IAMFContext *iamf, AVIOContext *pb, void *log_ctx)
Definition: iamf_writer.c:1014
version.h
AV_TIMECODE_FLAG_DROPFRAME
@ AV_TIMECODE_FLAG_DROPFRAME
timecode is drop frame
Definition: timecode.h:36
mov_write_tfhd_tag
static int mov_write_tfhd_tag(AVIOContext *pb, MOVMuxContext *mov, MOVTrack *track, int64_t moof_offset)
Definition: movenc.c:5631
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:3260
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:6103
AV_PROFILE_DNXHD
#define AV_PROFILE_DNXHD
Definition: defs.h:80
tag
uint32_t tag
Definition: movenc.c:2073
ffio_free_dyn_buf
void ffio_free_dyn_buf(AVIOContext **s)
Free a dynamic buffer.
Definition: aviobuf.c:1438
AVStream::id
int id
Format-specific stream ID.
Definition: avformat.h:759
AVFMT_FLAG_BITEXACT
#define AVFMT_FLAG_BITEXACT
When muxing, try to avoid writing any random/volatile data to the output.
Definition: avformat.h:1482
ret
ret
Definition: filter_design.txt:187
AVStream
Stream structure.
Definition: avformat.h:747
AV_CODEC_ID_APV
@ AV_CODEC_ID_APV
Definition: codec_id.h:323
mov_get_h264_codec_tag
static int mov_get_h264_codec_tag(AVFormatContext *s, MOVTrack *track)
Definition: movenc.c:1988
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:4807
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:3758
ff_dnxhd_parse_header_prefix
static av_always_inline uint64_t ff_dnxhd_parse_header_prefix(const uint8_t *buf)
Definition: dnxhddata.h:85
ff_mov_cenc_write_sinf_tag
int ff_mov_cenc_write_sinf_tag(MOVTrack *track, AVIOContext *pb, uint8_t *kid)
Write the sinf atom, contained inside stsd.
Definition: movenccenc.c:568
av_strlcat
size_t av_strlcat(char *dst, const char *src, size_t size)
Append the string src to the string dst, but to a total length of no more than size - 1 bytes,...
Definition: avstring.c:95
MOVMuxContext::track_ids_ok
int track_ids_ok
Definition: movenc.h:265
AVSphericalMapping::pitch
int32_t pitch
Rotation around the right vector [-90, 90].
Definition: spherical.h:145
mov_write_hvcc_tag
static int mov_write_hvcc_tag(AVFormatContext *s, AVIOContext *pb, MOVTrack *track)
Definition: movenc.c:1658
ff_av1_filter_obus
int ff_av1_filter_obus(AVIOContext *pb, const uint8_t *buf, int size)
Filter out AV1 OBUs not meant to be present in ISOBMFF sample data and write the resulting bitstream ...
Definition: av1.c:83
rawutils.h
ff_isom_close_apvc
void ff_isom_close_apvc(APVDecoderConfigurationRecord **papvc)
Definition: apv.c:375
MOVTrack::entries_flushed
int entries_flushed
Definition: movenc.h:162
MOV_TKHD_FLAG_IN_MOVIE
#define MOV_TKHD_FLAG_IN_MOVIE
Definition: isom.h:434
AVStereo3D::type
enum AVStereo3DType type
How views are packed within the video.
Definition: stereo3d.h:207
FF_MOV_FLAG_DASH
#define FF_MOV_FLAG_DASH
Definition: movenc.h:289
mov_write_tref_tag
static int mov_write_tref_tag(AVIOContext *pb, MOVTrack *track)
Definition: movenc.c:4260
mov_write_uuid_tag_ipod
static int mov_write_uuid_tag_ipod(AVIOContext *pb)
Write uuid atom.
Definition: movenc.c:2236
pos
unsigned int pos
Definition: spdifenc.c:414
MOVMuxCencContext::aes_ctr
struct AVAESCTR * aes_ctr
Definition: movenccenc.h:41
avformat.h
dovi_meta.h
dict.h
AVPacket::side_data
AVPacketSideData * side_data
Additional packet data that can be provided by the container.
Definition: packet.h:614
MOVMuxContext::is_animated_avif
int is_animated_avif
Definition: movenc.h:274
AV_INPUT_BUFFER_PADDING_SIZE
#define AV_INPUT_BUFFER_PADDING_SIZE
Definition: defs.h:40
id
enum AVCodecID id
Definition: dts2pts.c:578
left
Tag MUST be and< 10hcoeff half pel interpolation filter coefficients, hcoeff[0] are the 2 middle coefficients[1] are the next outer ones and so on, resulting in a filter like:...eff[2], hcoeff[1], hcoeff[0], hcoeff[0], hcoeff[1], hcoeff[2] ... the sign of the coefficients is not explicitly stored but alternates after each coeff and coeff[0] is positive, so ...,+,-,+,-,+,+,-,+,-,+,... hcoeff[0] is not explicitly stored but found by subtracting the sum of all stored coefficients with signs from 32 hcoeff[0]=32 - hcoeff[1] - hcoeff[2] - ... a good choice for hcoeff and htaps is htaps=6 hcoeff={40,-10, 2} an alternative which requires more computations at both encoder and decoder side and may or may not be better is htaps=8 hcoeff={42,-14, 6,-2}ref_frames minimum of the number of available reference frames and max_ref_frames for example the first frame after a key frame always has ref_frames=1spatial_decomposition_type wavelet type 0 is a 9/7 symmetric compact integer wavelet 1 is a 5/3 symmetric compact integer wavelet others are reserved stored as delta from last, last is reset to 0 if always_reset||keyframeqlog quality(logarithmic quantizer scale) stored as delta from last, last is reset to 0 if always_reset||keyframemv_scale stored as delta from last, last is reset to 0 if always_reset||keyframe FIXME check that everything works fine if this changes between framesqbias dequantization bias stored as delta from last, last is reset to 0 if always_reset||keyframeblock_max_depth maximum depth of the block tree stored as delta from last, last is reset to 0 if always_reset||keyframequant_table quantization tableHighlevel bitstream structure:==============================--------------------------------------------|Header|--------------------------------------------|------------------------------------|||Block0||||split?||||yes no||||......... intra?||||:Block01 :yes no||||:Block02 :....... ..........||||:Block03 ::y DC ::ref index:||||:Block04 ::cb DC ::motion x :||||......... :cr DC ::motion y :||||....... ..........|||------------------------------------||------------------------------------|||Block1|||...|--------------------------------------------|------------ ------------ ------------|||Y subbands||Cb subbands||Cr subbands||||--- ---||--- ---||--- ---|||||LL0||HL0||||LL0||HL0||||LL0||HL0|||||--- ---||--- ---||--- ---||||--- ---||--- ---||--- ---|||||LH0||HH0||||LH0||HH0||||LH0||HH0|||||--- ---||--- ---||--- ---||||--- ---||--- ---||--- ---|||||HL1||LH1||||HL1||LH1||||HL1||LH1|||||--- ---||--- ---||--- ---||||--- ---||--- ---||--- ---|||||HH1||HL2||||HH1||HL2||||HH1||HL2|||||...||...||...|||------------ ------------ ------------|--------------------------------------------Decoding process:=================------------|||Subbands|------------||||------------|Intra DC||||LL0 subband prediction ------------|\ Dequantization ------------------- \||Reference frames|\ IDWT|------- -------|Motion \|||Frame 0||Frame 1||Compensation . OBMC v -------|------- -------|--------------. \------> Frame n output Frame Frame<----------------------------------/|...|------------------- Range Coder:============Binary Range Coder:------------------- The implemented range coder is an adapted version based upon "Range encoding: an algorithm for removing redundancy from a digitised message." by G. N. N. Martin. The symbols encoded by the Snow range coder are bits(0|1). The associated probabilities are not fix but change depending on the symbol mix seen so far. bit seen|new state ---------+----------------------------------------------- 0|256 - state_transition_table[256 - old_state];1|state_transition_table[old_state];state_transition_table={ 0, 0, 0, 0, 0, 0, 0, 0, 20, 21, 22, 23, 24, 25, 26, 27, 28, 29, 30, 31, 32, 33, 34, 35, 36, 37, 37, 38, 39, 40, 41, 42, 43, 44, 45, 46, 47, 48, 49, 50, 51, 52, 53, 54, 55, 56, 56, 57, 58, 59, 60, 61, 62, 63, 64, 65, 66, 67, 68, 69, 70, 71, 72, 73, 74, 75, 75, 76, 77, 78, 79, 80, 81, 82, 83, 84, 85, 86, 87, 88, 89, 90, 91, 92, 93, 94, 94, 95, 96, 97, 98, 99, 100, 101, 102, 103, 104, 105, 106, 107, 108, 109, 110, 111, 112, 113, 114, 114, 115, 116, 117, 118, 119, 120, 121, 122, 123, 124, 125, 126, 127, 128, 129, 130, 131, 132, 133, 133, 134, 135, 136, 137, 138, 139, 140, 141, 142, 143, 144, 145, 146, 147, 148, 149, 150, 151, 152, 152, 153, 154, 155, 156, 157, 158, 159, 160, 161, 162, 163, 164, 165, 166, 167, 168, 169, 170, 171, 171, 172, 173, 174, 175, 176, 177, 178, 179, 180, 181, 182, 183, 184, 185, 186, 187, 188, 189, 190, 190, 191, 192, 194, 194, 195, 196, 197, 198, 199, 200, 201, 202, 202, 204, 205, 206, 207, 208, 209, 209, 210, 211, 212, 213, 215, 215, 216, 217, 218, 219, 220, 220, 222, 223, 224, 225, 226, 227, 227, 229, 229, 230, 231, 232, 234, 234, 235, 236, 237, 238, 239, 240, 241, 242, 243, 244, 245, 246, 247, 248, 248, 0, 0, 0, 0, 0, 0, 0};FIXME Range Coding of integers:------------------------- FIXME Neighboring Blocks:===================left and top are set to the respective blocks unless they are outside of the image in which case they are set to the Null block top-left is set to the top left block unless it is outside of the image in which case it is set to the left block if this block has no larger parent block or it is at the left side of its parent block and the top right block is not outside of the image then the top right block is used for top-right else the top-left block is used Null block y, cb, cr are 128 level, ref, mx and my are 0 Motion Vector Prediction:=========================1. the motion vectors of all the neighboring blocks are scaled to compensate for the difference of reference frames scaled_mv=(mv *(256 *(current_reference+1)/(mv.reference+1))+128)> the median of the scaled left
Definition: snow.txt:386
AV_PIX_FMT_UYVY422
@ AV_PIX_FMT_UYVY422
packed YUV 4:2:2, 16bpp, Cb Y0 Cr Y1
Definition: pixfmt.h:88
AV_RL32
uint64_t_TMPL AV_WL64 unsigned int_TMPL AV_RL32
Definition: bytestream.h:92
MODE_3G2
#define MODE_3G2
Definition: movenc.h:43
AVCodecParameters::avcodec_parameters_free
void avcodec_parameters_free(AVCodecParameters **par)
Free an AVCodecParameters instance and everything associated with it and write NULL to the supplied p...
Definition: codec_par.c:67
mov_flush_fragment
static int mov_flush_fragment(AVFormatContext *s, int force)
Definition: movenc.c:6692
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:3477
MOVTrack::par
AVCodecParameters * par
Definition: movenc.h:126
ff_isom_parse_apvc
int ff_isom_parse_apvc(APVDecoderConfigurationRecord *apvc, const AVPacket *pkt, void *logctx)
Definition: apv.c:252
AVStreamGroup
Definition: avformat.h:1140
AVStream::index
int index
stream index in AVFormatContext
Definition: avformat.h:753
eac3_info::num_ind_sub
uint8_t num_ind_sub
Definition: movenc.c:394
MOV_INDEX_CLUSTER_SIZE
#define MOV_INDEX_CLUSTER_SIZE
Definition: movenc.h:32
ff_codec_bmp_tags
const AVCodecTag ff_codec_bmp_tags[]
Definition: riff.c:36
FF_MOV_FLAG_SEPARATE_MOOF
#define FF_MOV_FLAG_SEPARATE_MOOF
Definition: movenc.h:282
AVStreamGroup::nb_streams
unsigned int nb_streams
Number of elements in AVStreamGroup.streams.
Definition: avformat.h:1202
channel_layout.h
ff_avc_write_annexb_extradata
int ff_avc_write_annexb_extradata(const uint8_t *in, uint8_t **buf, int *size)
Definition: avc.c:145
MOVMuxContext::flags
int flags
Definition: movenc.h:223
AV_PROFILE_AAC_HE_V2
#define AV_PROFILE_AAC_HE_V2
Definition: defs.h:73
MOVTrack::last_stsd_index
int last_stsd_index
Definition: movenc.h:105
av_channel_layout_subset
uint64_t av_channel_layout_subset(const AVChannelLayout *channel_layout, uint64_t mask)
Find out what channels from a given set are present in a channel layout, without regard for their pos...
Definition: channel_layout.c:867
MOVMuxContext::reserved_moov_size
int reserved_moov_size
0 for disabled, -1 for automatic, size otherwise
Definition: movenc.h:241
ISOM_DVCC_DVVC_SIZE
#define ISOM_DVCC_DVVC_SIZE
Definition: dovi_isom.h:29
AVIO_SEEKABLE_NORMAL
#define AVIO_SEEKABLE_NORMAL
Seeking works like for a local file.
Definition: avio.h:41
is_cover_image
static int is_cover_image(const AVStream *st)
Definition: movenc.c:184
av_packet_new_side_data
uint8_t * av_packet_new_side_data(AVPacket *pkt, enum AVPacketSideDataType type, size_t size)
Allocate new information of a packet.
Definition: packet.c:231
AVRational::den
int den
Denominator.
Definition: rational.h:60
rgb_to_yuv
static uint32_t rgb_to_yuv(uint32_t rgb)
Definition: movenc.c:8006
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:7749
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:4700
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:6210
mov_write_prft_tag
static int mov_write_prft_tag(AVIOContext *pb, MOVMuxContext *mov, int tracks)
Definition: movenc.c:6053
mov_write_fiel_tag
static int mov_write_fiel_tag(AVIOContext *pb, MOVTrack *track, int field_order)
Definition: movenc.c:2252
AV_OPT_TYPE_INT
@ AV_OPT_TYPE_INT
Underlying C type is int.
Definition: opt.h:258
av_channel_layout_uninit
void av_channel_layout_uninit(AVChannelLayout *channel_layout)
Free any allocated data in the channel layout and reset the channel count to 0.
Definition: channel_layout.c:443
ff_codec_get_tag
unsigned int ff_codec_get_tag(const AVCodecTag *tags, enum AVCodecID id)
Definition: utils.c:133
AVIO_DATA_MARKER_HEADER
@ AVIO_DATA_MARKER_HEADER
Header data; this needs to be present for the stream to be decodeable.
Definition: avio.h:114
MOVTrack::is_unaligned_qt_rgb
int is_unaligned_qt_rgb
Definition: movenc.h:185
av_packet_make_writable
int av_packet_make_writable(AVPacket *pkt)
Create a writable reference for the data described by a given packet, avoiding data copy if possible.
Definition: packet.c:516
mov_write_identification
static int mov_write_identification(AVIOContext *pb, AVFormatContext *s)
Definition: movenc.c:6444
mov_write_sidx_tags
static int mov_write_sidx_tags(AVIOContext *pb, MOVMuxContext *mov, int tracks, int ref_size)
Definition: movenc.c:6015
eac3_info::bsid
uint8_t bsid
Definition: movenc.c:399
MOVMuxContext::tracks
MOVTrack * tracks
Definition: movenc.h:221
AV_RB8
uint64_t_TMPL AV_WL64 unsigned int_TMPL AV_WL32 unsigned int_TMPL AV_WL24 unsigned int_TMPL AV_WL16 uint64_t_TMPL AV_WB64 unsigned int_TMPL AV_WB32 unsigned int_TMPL AV_WB24 unsigned int_TMPL AV_WB16 unsigned int_TMPL AV_RB8
Definition: bytestream.h:99
ref
static int ref[MAX_W *MAX_W]
Definition: jpeg2000dwt.c:117
AVPixFmtDescriptor::comp
AVComponentDescriptor comp[4]
Parameters that describe how pixels are packed.
Definition: pixdesc.h:105
MOVTrack::multichannel_as_mono
int multichannel_as_mono
Definition: movenc.h:128
mov_write_ilst_tag
static int mov_write_ilst_tag(AVIOContext *pb, MOVMuxContext *mov, AVFormatContext *s)
Definition: movenc.c:4861
mov_flush_fragment_interleaving
static int mov_flush_fragment_interleaving(AVFormatContext *s, MOVTrack *track)
Definition: movenc.c:6573
AV_PKT_DATA_SKIP_SAMPLES
@ AV_PKT_DATA_SKIP_SAMPLES
Recommends skipping the specified number of samples.
Definition: packet.h:153
eac3_info::complexity_index_type_a
uint8_t complexity_index_type_a
Definition: movenc.c:416
mov_write_btrt_tag
static int mov_write_btrt_tag(AVIOContext *pb, MOVTrack *track)
Definition: movenc.c:1298
mov_write_glbl_tag
static int mov_write_glbl_tag(AVIOContext *pb, MOVTrack *track)
Definition: movenc.c:1221
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:386
mov_mdhd_mvhd_tkhd_version
static int mov_mdhd_mvhd_tkhd_version(MOVMuxContext *mov, MOVTrack *track, int64_t duration)
Definition: movenc.c:3930
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:3976
av_clip_uint8
#define av_clip_uint8
Definition: common.h:106
avio_skip
int64_t avio_skip(AVIOContext *s, int64_t offset)
Skip given number of bytes forward.
Definition: aviobuf.c:321
AV_PIX_FMT_RGB565BE
@ AV_PIX_FMT_RGB565BE
packed RGB 5:6:5, 16bpp, (msb) 5R 6G 5B(lsb), big-endian
Definition: pixfmt.h:112
avio_wb64
void avio_wb64(AVIOContext *s, uint64_t val)
Definition: aviobuf.c:434
MOV_TRACK_ENABLED
#define MOV_TRACK_ENABLED
Definition: movenc.h:116
av_realloc
#define av_realloc(p, s)
Definition: ops_asmgen.c:46
mov_write_ispe_tag
static int mov_write_ispe_tag(AVIOContext *pb, MOVMuxContext *mov, AVFormatContext *s, int stream_index)
Definition: movenc.c:3746
AC3HeaderInfo::bitstream_id
uint8_t bitstream_id
Definition: ac3_parser_internal.h:41
AVMEDIA_TYPE_VIDEO
@ AVMEDIA_TYPE_VIDEO
Definition: avutil.h:200
ff_reshuffle_raw_rgb
int ff_reshuffle_raw_rgb(AVFormatContext *s, AVPacket **ppkt, AVCodecParameters *par, int expected_stride)
Reshuffles the lines to use the user specified stride.
Definition: rawutils.c:27
AV_CODEC_ID_PCM_S32LE
@ AV_CODEC_ID_PCM_S32LE
Definition: codec_id.h:338
AVCodecParameters::bits_per_coded_sample
int bits_per_coded_sample
The number of bits per sample in the codedwords.
Definition: codec_par.h:113
AV_PIX_FMT_V30XLE
@ AV_PIX_FMT_V30XLE
packed VYUX 4:4:4 like XV30, 32bpp, (msb)10V 10Y 10U 2X(lsb), little-endian
Definition: pixfmt.h:449
AV_PIX_FMT_YUV422P
@ AV_PIX_FMT_YUV422P
planar YUV 4:2:2, 16bpp, (1 Cr & Cb sample per 2x1 Y samples)
Definition: pixfmt.h:77
mov_write_sdtp_tag
static int mov_write_sdtp_tag(AVIOContext *pb, MOVTrack *track)
Definition: movenc.c:316
mem.h
AVStreamGroup::type
enum AVStreamGroupParamsType type
Group type.
Definition: avformat.h:1167
param_write_hex
static void param_write_hex(AVIOContext *pb, const char *name, const uint8_t *value, int len)
Definition: movenc.c:5484
MOVTrack::timescale
unsigned timescale
Definition: movenc.h:98
ff_ismv_muxer
const FFOutputFormat ff_ismv_muxer
mov_write_av1c_tag
static int mov_write_av1c_tag(AVIOContext *pb, MOVTrack *track)
Definition: movenc.c:1592
AV_CODEC_ID_PCM_U8
@ AV_CODEC_ID_PCM_U8
Definition: codec_id.h:335
AVSphericalMapping::bound_left
uint32_t bound_left
Distance from the left edge.
Definition: spherical.h:185
FFFormatContext::pkt
AVPacket * pkt
Used to hold temporary packets for the generic demuxing code.
Definition: internal.h:111
avpriv_request_sample
#define avpriv_request_sample(...)
Definition: tableprint_vlc.h:37
AVCodecParameters::format
int format
Definition: codec_par.h:94
flush_put_bits
static void flush_put_bits(PutBitContext *s)
Pad the end of the output stream with zeros.
Definition: put_bits.h:153
mov_write_uuidusmt_tag
static int mov_write_uuidusmt_tag(AVIOContext *pb, AVFormatContext *s)
Definition: movenc.c:5156
AVPixFmtDescriptor
Descriptor that unambiguously describes how the bits of a pixel are stored in the up to 4 data planes...
Definition: pixdesc.h:69
avio_wb24
void avio_wb24(AVIOContext *s, unsigned int val)
Definition: aviobuf.c:458
map
const VDPAUPixFmtMap * map
Definition: hwcontext_vdpau.c:71
MOVMuxContext::avif_loop_count
int avif_loop_count
Definition: movenc.h:275
AV_CHANNEL_LAYOUT_MONO
#define AV_CHANNEL_LAYOUT_MONO
Definition: channel_layout.h:394
mpeg4_bit_rate_values::max_bit_rate
uint32_t max_bit_rate
Maximum rate in bits/second over any window of one second.
Definition: movenc.c:734
AV_CODEC_ID_PCM_F64LE
@ AV_CODEC_ID_PCM_F64LE
Definition: codec_id.h:353
mov_write_dvcc_dvvc_tag
static int mov_write_dvcc_dvvc_tag(AVFormatContext *s, AVIOContext *pb, AVDOVIDecoderConfigurationRecord *dovi)
Definition: movenc.c:2541
mov_preroll_write_stbl_atoms
static int mov_preroll_write_stbl_atoms(AVIOContext *pb, MOVTrack *track)
Definition: movenc.c:3324
AVStereo3D::view
enum AVStereo3DView view
Determines which views are packed.
Definition: stereo3d.h:217
MOVMuxContext::major_brand
char * major_brand
Definition: movenc.h:244
AV_PROFILE_AAC_HE
#define AV_PROFILE_AAC_HE
Definition: defs.h:72
av_free
#define av_free(p)
Definition: tableprint_vlc.h:34
mov_write_chan_tag
static int mov_write_chan_tag(AVFormatContext *s, AVIOContext *pb, MOVTrack *track)
Definition: movenc.c:1016
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:2310
MOVTrack::cluster_capacity
unsigned cluster_capacity
Definition: movenc.h:132
MOVMuxContext::write_btrt
int write_btrt
Definition: movenc.h:266
MOVIentry::stsd_index
unsigned int stsd_index
Definition: movenc.h:54
language_code
static uint16_t language_code(const char *str)
Definition: movenc.c:5030
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:3791
get_samples_per_packet
static int get_samples_per_packet(MOVTrack *track)
Definition: movenc.c:1279
MOV_ENC_CENC_AES_CTR
@ MOV_ENC_CENC_AES_CTR
Definition: movenc.h:201
mov_write_smhd_tag
static int mov_write_smhd_tag(AVIOContext *pb)
Definition: movenc.c:3559
AVContentLightMetadata::MaxFALL
unsigned MaxFALL
Max average light level per frame (cd/m^2).
Definition: mastering_display_metadata.h:116
AVPacket
This structure stores compressed data.
Definition: packet.h:580
MOVTrack::extradata
uint8_t ** extradata
Definition: movenc.h:106
cr
static double cr(void *priv, double x, double y)
Definition: vf_geq.c:248
AV_OPT_TYPE_BOOL
@ AV_OPT_TYPE_BOOL
Underlying C type is int.
Definition: opt.h:326
PIX_FMT_LIST_MOV
@ PIX_FMT_LIST_MOV
Definition: raw.h:40
AV_CODEC_ID_ADPCM_IMA_WAV
@ AV_CODEC_ID_ADPCM_IMA_WAV
Definition: codec_id.h:370
av_freep
#define av_freep(p)
Definition: tableprint_vlc.h:35
mov_write_source_reference_tag
static int mov_write_source_reference_tag(AVIOContext *pb, MOVTrack *track, const char *reel_name)
Definition: movenc.c:3104
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:6494
riff.h
MOV_TFHD_DURATION_IS_EMPTY
#define MOV_TFHD_DURATION_IS_EMPTY
Definition: isom.h:413
AV_CODEC_ID_ILBC
@ AV_CODEC_ID_ILBC
Definition: codec_id.h:511
AV_CHAN_AMBISONIC_BASE
@ AV_CHAN_AMBISONIC_BASE
Range of channels between AV_CHAN_AMBISONIC_BASE and AV_CHAN_AMBISONIC_END represent Ambisonic compon...
Definition: channel_layout.h:108
MOV_TRUN_SAMPLE_SIZE
#define MOV_TRUN_SAMPLE_SIZE
Definition: isom.h:419
ff_isom_init_apvc
int ff_isom_init_apvc(APVDecoderConfigurationRecord **papvc, void *logctx)
Definition: apv.c:352
AV_OPT_TYPE_FLAGS
@ AV_OPT_TYPE_FLAGS
Underlying C type is unsigned int.
Definition: opt.h:254
int32_t
int32_t
Definition: audioconvert.c:56
distance
static float distance(float x, float y, int band)
Definition: nellymoserenc.c:231
MOVTrack::eac3_priv
void * eac3_priv
Definition: movenc.h:178
mov_write_dops_tag
static int mov_write_dops_tag(AVFormatContext *s, AVIOContext *pb, MOVTrack *track)
Definition: movenc.c:895
mov_write_squashed_packet
static int mov_write_squashed_packet(AVFormatContext *s, MOVTrack *track)
Definition: movenc.c:6598
avio_wb16
void avio_wb16(AVIOContext *s, unsigned int val)
Definition: aviobuf.c:446
AV_CODEC_ID_VP8
@ AV_CODEC_ID_VP8
Definition: codec_id.h:190
mov_write_hmhd_tag
static int mov_write_hmhd_tag(AVIOContext *pb)
Definition: movenc.c:3825
AVERROR_BUG
#define AVERROR_BUG
Internal bug, also see AVERROR_BUG2.
Definition: error.h:52
rgb
static const SheerTable rgb[2]
Definition: sheervideodata.h:32
MP4TrackKindValueMapping::value
const char * value
Definition: isom.h:489
av_strlcpy
size_t av_strlcpy(char *dst, const char *src, size_t size)
Copy the string src to dst, but no more than size - 1 bytes, and null-terminate dst.
Definition: avstring.c:85
AV_CODEC_ID_PCM_F32LE
@ AV_CODEC_ID_PCM_F32LE
Definition: codec_id.h:351
param_write_string
static void param_write_string(AVIOContext *pb, const char *name, const char *value)
Definition: movenc.c:5479
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:2698
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:704
rescale_rational
static int64_t rescale_rational(AVRational q, int b)
Definition: movenc.c:2398
ff_isom_write_lhvc
int ff_isom_write_lhvc(AVIOContext *pb, const uint8_t *data, int size, int ps_array_completeness, void *logctx)
Writes L-HEVC extradata (parameter sets with nuh_layer_id > 0, as a LHEVCDecoderConfigurationRecord) ...
Definition: hevc.c:1405
AVERROR_INVALIDDATA
#define AVERROR_INVALIDDATA
Invalid data found when processing input.
Definition: error.h:61
ff_mov_track_kind_table
const struct MP4TrackKindMapping ff_mov_track_kind_table[]
Definition: isom.c:464
MovTag::id
uint32_t * id
trackID of the referenced track
Definition: movenc.h:91
av_stereo3d_type_name
const char * av_stereo3d_type_name(unsigned int type)
Provide a human-readable name of a given stereo3d type.
Definition: stereo3d.c:93
MOVMuxContext::mdat_buf
AVIOContext * mdat_buf
Definition: movenc.h:236
mov_write_amr_tag
static int mov_write_amr_tag(AVIOContext *pb, MOVTrack *track)
Definition: movenc.c:369
mov_write_mdat_tag
static int mov_write_mdat_tag(AVIOContext *pb, MOVMuxContext *mov)
Definition: movenc.c:6199
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:5773
AV_CODEC_ID_VORBIS
@ AV_CODEC_ID_VORBIS
Definition: codec_id.h:457
MOVTrack::default_duration
int64_t default_duration
Definition: movenc.h:152
AVFMT_AVOID_NEG_TS_AUTO
#define AVFMT_AVOID_NEG_TS_AUTO
Enabled when required by target format.
Definition: avformat.h:1704
av_timecode_init_from_string
int av_timecode_init_from_string(AVTimecode *tc, AVRational rate, const char *str, void *log_ctx)
Parse timecode representation (hh:mm:ss[:;.
Definition: timecode.c:241
AVStereo3D
Stereo 3D type: this structure describes how two videos are packed within a single video surface,...
Definition: stereo3d.h:203
AVDictionaryEntry::value
char * value
Definition: dict.h:92
avstring.h
ff_mov_cenc_avc_parse_nal_units
int ff_mov_cenc_avc_parse_nal_units(MOVMuxCencContext *ctx, AVIOContext *pb, const uint8_t *buf_in, int size)
Parse AVC NAL units from annex B format, the nal size and type are written in the clear while the bod...
Definition: movenccenc.c:198
AV_OPT_TYPE_STRING
@ AV_OPT_TYPE_STRING
Underlying C type is a uint8_t* that is either NULL or points to a C string allocated with the av_mal...
Definition: opt.h:275
width
#define width
Definition: dsp.h:89
AVAmbientViewingEnvironment::ambient_light_y
AVRational ambient_light_y
Normalized y chromaticity coordinate of the environmental ambient light in the nominal viewing enviro...
Definition: ambient_viewing_environment.h:54
eac3_info::substream
struct eac3_info::@499 substream[1]
flac.h
MOVTrack::frag_info_capacity
unsigned frag_info_capacity
Definition: movenc.h:166
AVTimecode
Definition: timecode.h:41
AV_RB24
uint64_t_TMPL AV_WL64 unsigned int_TMPL AV_WL32 unsigned int_TMPL AV_WL24 unsigned int_TMPL AV_WL16 uint64_t_TMPL AV_WB64 unsigned int_TMPL AV_WB32 unsigned int_TMPL AV_RB24
Definition: bytestream.h:97
AV_PIX_FMT_VYU444
@ AV_PIX_FMT_VYU444
packed VYU 4:4:4, 24bpp (1 Cr & Cb sample per 1x1 Y), VYUVYU...
Definition: pixfmt.h:446
av_bswap16
#define av_bswap16
Definition: bswap.h:28
ff_is_ttml_stream_paragraph_based
static unsigned int ff_is_ttml_stream_paragraph_based(const AVCodecParameters *codecpar)
Definition: ttmlenc.h:28
MOVTrack::first_iamf_idx
int first_iamf_idx
Definition: movenc.h:192
AVCodecTag::tag
unsigned int tag
Definition: internal.h:44
avio_put_str
int avio_put_str(AVIOContext *s, const char *str)
Write a NULL-terminated string.
Definition: aviobuf.c:376
put_bits.h
mov_pix_fmt_tags
static const struct @498 mov_pix_fmt_tags[]
AV_CODEC_ID_MPEG2VIDEO
@ AV_CODEC_ID_MPEG2VIDEO
preferred ID for MPEG-1/2 video decoding
Definition: codec_id.h:52
AVStreamGroupLayeredVideo::el_index
unsigned int el_index
Index of the enhancement layer stream in AVStreamGroup.
Definition: avformat.h:1083
AC3HeaderInfo::sr_code
uint8_t sr_code
Definition: ac3_parser_internal.h:40
MOV_TRUN_SAMPLE_CTS
#define MOV_TRUN_SAMPLE_CTS
Definition: isom.h:421
AV_OPT_TYPE_CONST
@ AV_OPT_TYPE_CONST
Special option type for declaring named constants.
Definition: opt.h:298
MOV_ISMV_TTML_TAG
#define MOV_ISMV_TTML_TAG
Definition: isom.h:482
snprintf
#define snprintf
Definition: snprintf.h:34
mov_add_tref_id
static int mov_add_tref_id(MOVMuxContext *mov, MovTag *tag, uint32_t id)
Definition: movenc.c:5315
mov_write_tfrf_tags
static int mov_write_tfrf_tags(AVIOContext *pb, MOVMuxContext *mov, MOVTrack *track)
Definition: movenc.c:5808
ff_stream_add_bitstream_filter
int ff_stream_add_bitstream_filter(AVStream *st, const char *name, const char *args)
Add a bitstream filter to a stream.
Definition: mux.c:1294
AV_PROFILE_AAC_USAC
#define AV_PROFILE_AAC_USAC
Definition: defs.h:76
AV_CODEC_ID_PCM_S24BE
@ AV_CODEC_ID_PCM_S24BE
Definition: codec_id.h:343
AC3HeaderInfo::bit_rate
uint32_t bit_rate
Definition: ac3_parser_internal.h:60
mov_find_codec_tag
static unsigned int mov_find_codec_tag(AVFormatContext *s, MOVTrack *track)
Definition: movenc.c:2213
MOVTrack::src_track
int * src_track
the tracks that this hint (or tmcd) track describes
Definition: movenc.h:146
AVSphericalMapping
This structure describes how to handle spherical videos, outlining information about projection,...
Definition: spherical.h:100
MOVMuxContext::moov_written
int moov_written
Definition: movenc.h:230
av_dict_iterate
const AVDictionaryEntry * av_dict_iterate(const AVDictionary *m, const AVDictionaryEntry *prev)
Iterate over a dictionary.
Definition: dict.c:42
AVPixFmtDescriptor::log2_chroma_h
uint8_t log2_chroma_h
Amount to shift the luma height right to find the chroma height.
Definition: pixdesc.h:89
mov_write_tfxd_tag
static int mov_write_tfxd_tag(AVIOContext *pb, MOVTrack *track)
Definition: movenc.c:5753
MOV_PARTIAL_SYNC_SAMPLE
#define MOV_PARTIAL_SYNC_SAMPLE
Definition: movenc.h:60
AVSphericalMapping::yaw
int32_t yaw
Rotation around the up vector [-180, 180].
Definition: spherical.h:144
MOVTrack::tref_tags
MovTag * tref_tags
Definition: movenc.h:136
AV_CODEC_ID_DNXHD
@ AV_CODEC_ID_DNXHD
Definition: codec_id.h:149
MOVTrack::default_size
uint32_t default_size
Definition: movenc.h:154
ff_f4v_muxer
const FFOutputFormat ff_f4v_muxer
mov_write_clli_tag
static int mov_write_clli_tag(AVIOContext *pb, MOVTrack *track)
Definition: movenc.c:2678
MOVMuxContext::gamma
float gamma
Definition: movenc.h:252
AVPacket::side_data_elems
int side_data_elems
Definition: packet.h:615
av_get_pix_fmt_name
const char * av_get_pix_fmt_name(enum AVPixelFormat pix_fmt)
Return the short name for a pixel format, NULL in case pix_fmt is unknown.
Definition: pixdesc.c:3376
ff_hevc_annexb2mp4
int ff_hevc_annexb2mp4(AVIOContext *pb, const uint8_t *buf_in, int size, int filter_ps, int *ps_count)
Writes Annex B formatted HEVC NAL units to the provided AVIOContext.
Definition: hevc.c:1201
AV_RB16
uint64_t_TMPL AV_WL64 unsigned int_TMPL AV_WL32 unsigned int_TMPL AV_WL24 unsigned int_TMPL AV_WL16 uint64_t_TMPL AV_WB64 unsigned int_TMPL AV_WB32 unsigned int_TMPL AV_WB24 unsigned int_TMPL AV_RB16
Definition: bytestream.h:98
MOVTrack::nb_frag_info
int nb_frag_info
Definition: movenc.h:164
iamf_writer.h
av_fourcc2str
#define av_fourcc2str(fourcc)
Definition: avutil.h:323
mov_write_dfla_tag
static int mov_write_dfla_tag(AVIOContext *pb, MOVTrack *track)
Definition: movenc.c:875
MP4TrackKindMapping
Definition: isom.h:492
ff_alloc_extradata
int ff_alloc_extradata(AVCodecParameters *par, int size)
Allocate extradata with additional AV_INPUT_BUFFER_PADDING_SIZE at end which is always set to 0.
Definition: utils.c:237
AVDOVIDecoderConfigurationRecord
Definition: dovi_meta.h:55
mov_write_sidx_tag
static int mov_write_sidx_tag(AVIOContext *pb, MOVTrack *track, int ref_size, int total_sidx_size)
Definition: movenc.c:5954
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:397
MOVIentry::samples_in_chunk
unsigned int samples_in_chunk
Definition: movenc.h:55