FFmpeg
movenc.c
Go to the documentation of this file.
1 /*
2  * MOV, 3GP, MP4 muxer
3  * Copyright (c) 2003 Thomas Raivio
4  * Copyright (c) 2004 Gildas Bazin <gbazin at videolan dot org>
5  * Copyright (c) 2009 Baptiste Coudurier <baptiste dot coudurier at gmail dot com>
6  *
7  * This file is part of FFmpeg.
8  *
9  * FFmpeg is free software; you can redistribute it and/or
10  * modify it under the terms of the GNU Lesser General Public
11  * License as published by the Free Software Foundation; either
12  * version 2.1 of the License, or (at your option) any later version.
13  *
14  * FFmpeg is distributed in the hope that it will be useful,
15  * but WITHOUT ANY WARRANTY; without even the implied warranty of
16  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
17  * Lesser General Public License for more details.
18  *
19  * You should have received a copy of the GNU Lesser General Public
20  * License along with FFmpeg; if not, write to the Free Software
21  * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
22  */
23 
24 #include "config_components.h"
25 
26 #include <stdint.h>
27 #include <inttypes.h>
28 
29 #include "movenc.h"
30 #include "avformat.h"
31 #include "avio_internal.h"
32 #include "dovi_isom.h"
33 #include "riff.h"
34 #include "avio.h"
35 #include "iamf_writer.h"
36 #include "isom.h"
37 #include "av1.h"
38 #include "avc.h"
39 #include "evc.h"
40 #include "apv.h"
41 #include "lcevc.h"
43 #include "libavcodec/dnxhddata.h"
44 #include "libavcodec/flac.h"
45 #include "libavcodec/get_bits.h"
46 
47 #include "libavcodec/internal.h"
48 #include "libavcodec/put_bits.h"
49 #include "libavcodec/vc1_common.h"
50 #include "libavcodec/raw.h"
51 #include "internal.h"
52 #include "libavutil/avstring.h"
54 #include "libavutil/csp.h"
55 #include "libavutil/intfloat.h"
56 #include "libavutil/mathematics.h"
57 #include "libavutil/libm.h"
58 #include "libavutil/mem.h"
59 #include "libavutil/opt.h"
60 #include "libavutil/dict.h"
61 #include "libavutil/pixdesc.h"
62 #include "libavutil/stereo3d.h"
63 #include "libavutil/timecode.h"
64 #include "libavutil/dovi_meta.h"
65 #include "libavutil/uuid.h"
66 #include "hevc.h"
67 #include "rtpenc.h"
68 #include "nal.h"
69 #include "mov_chan.h"
70 #include "movenc_ttml.h"
71 #include "mux.h"
72 #include "rawutils.h"
73 #include "ttmlenc.h"
74 #include "version.h"
75 #include "vpcc.h"
76 #include "vvc.h"
77 
78 static const AVOption options[] = {
79  { "brand", "Override major brand", offsetof(MOVMuxContext, major_brand), AV_OPT_TYPE_STRING, {.str = NULL}, .flags = AV_OPT_FLAG_ENCODING_PARAM },
80  { "empty_hdlr_name", "write zero-length name string in hdlr atoms within mdia and minf atoms", offsetof(MOVMuxContext, empty_hdlr_name), AV_OPT_TYPE_BOOL, {.i64 = 0}, 0, 1, AV_OPT_FLAG_ENCODING_PARAM},
81  { "encryption_key", "The media encryption key (hex)", offsetof(MOVMuxContext, encryption_key), AV_OPT_TYPE_BINARY, .flags = AV_OPT_FLAG_ENCODING_PARAM },
82  { "encryption_kid", "The media encryption key identifier (hex)", offsetof(MOVMuxContext, encryption_kid), AV_OPT_TYPE_BINARY, .flags = AV_OPT_FLAG_ENCODING_PARAM },
83  { "encryption_scheme", "Configures the encryption scheme, allowed values are none, cenc-aes-ctr", offsetof(MOVMuxContext, encryption_scheme_str), AV_OPT_TYPE_STRING, {.str = NULL}, .flags = AV_OPT_FLAG_ENCODING_PARAM },
84  { "frag_duration", "Maximum fragment duration", offsetof(MOVMuxContext, max_fragment_duration), AV_OPT_TYPE_INT, {.i64 = 0}, 0, INT_MAX, AV_OPT_FLAG_ENCODING_PARAM},
85  { "frag_interleave", "Interleave samples within fragments (max number of consecutive samples, lower is tighter interleaving, but with more overhead)", offsetof(MOVMuxContext, frag_interleave), AV_OPT_TYPE_INT, {.i64 = 0}, 0, INT_MAX, AV_OPT_FLAG_ENCODING_PARAM },
86  { "frag_size", "Maximum fragment size", offsetof(MOVMuxContext, max_fragment_size), AV_OPT_TYPE_INT, {.i64 = 0}, 0, INT_MAX, AV_OPT_FLAG_ENCODING_PARAM},
87  { "fragment_index", "Fragment number of the next fragment", offsetof(MOVMuxContext, fragments), AV_OPT_TYPE_INT, {.i64 = 1}, 1, INT_MAX, AV_OPT_FLAG_ENCODING_PARAM},
88  { "iods_audio_profile", "iods audio profile atom.", offsetof(MOVMuxContext, iods_audio_profile), AV_OPT_TYPE_INT, {.i64 = -1}, -1, 255, AV_OPT_FLAG_ENCODING_PARAM},
89  { "iods_video_profile", "iods video profile atom.", offsetof(MOVMuxContext, iods_video_profile), AV_OPT_TYPE_INT, {.i64 = -1}, -1, 255, AV_OPT_FLAG_ENCODING_PARAM},
90  { "ism_lookahead", "Number of lookahead entries for ISM files", offsetof(MOVMuxContext, ism_lookahead), AV_OPT_TYPE_INT, {.i64 = 0}, 0, 255, AV_OPT_FLAG_ENCODING_PARAM},
91  { "movflags", "MOV muxer flags", offsetof(MOVMuxContext, flags), AV_OPT_TYPE_FLAGS, {.i64 = 0}, INT_MIN, INT_MAX, AV_OPT_FLAG_ENCODING_PARAM, .unit = "movflags" },
92  { "cmaf", "Write CMAF compatible fragmented MP4", 0, AV_OPT_TYPE_CONST, {.i64 = FF_MOV_FLAG_CMAF}, INT_MIN, INT_MAX, AV_OPT_FLAG_ENCODING_PARAM, .unit = "movflags" },
93  { "dash", "Write DASH compatible fragmented MP4", 0, AV_OPT_TYPE_CONST, {.i64 = FF_MOV_FLAG_DASH}, INT_MIN, INT_MAX, AV_OPT_FLAG_ENCODING_PARAM, .unit = "movflags" },
94  { "default_base_moof", "Set the default-base-is-moof flag in tfhd atoms", 0, AV_OPT_TYPE_CONST, {.i64 = FF_MOV_FLAG_DEFAULT_BASE_MOOF}, INT_MIN, INT_MAX, AV_OPT_FLAG_ENCODING_PARAM, .unit = "movflags" },
95  { "delay_moov", "Delay writing the initial moov until the first fragment is cut, or until the first fragment flush", 0, AV_OPT_TYPE_CONST, {.i64 = FF_MOV_FLAG_DELAY_MOOV}, INT_MIN, INT_MAX, AV_OPT_FLAG_ENCODING_PARAM, .unit = "movflags" },
96  { "disable_chpl", "Disable Nero chapter atom", 0, AV_OPT_TYPE_CONST, {.i64 = FF_MOV_FLAG_DISABLE_CHPL}, INT_MIN, INT_MAX, AV_OPT_FLAG_ENCODING_PARAM, .unit = "movflags" },
97  { "empty_moov", "Make the initial moov atom empty", 0, AV_OPT_TYPE_CONST, {.i64 = FF_MOV_FLAG_EMPTY_MOOV}, INT_MIN, INT_MAX, AV_OPT_FLAG_ENCODING_PARAM, .unit = "movflags" },
98  { "faststart", "Run a second pass to put the index (moov atom) at the beginning of the file", 0, AV_OPT_TYPE_CONST, {.i64 = FF_MOV_FLAG_FASTSTART}, INT_MIN, INT_MAX, AV_OPT_FLAG_ENCODING_PARAM, .unit = "movflags" },
99  { "frag_custom", "Flush fragments on caller requests", 0, AV_OPT_TYPE_CONST, {.i64 = FF_MOV_FLAG_FRAG_CUSTOM}, INT_MIN, INT_MAX, AV_OPT_FLAG_ENCODING_PARAM, .unit = "movflags" },
100  { "frag_discont", "Signal that the next fragment is discontinuous from earlier ones", 0, AV_OPT_TYPE_CONST, {.i64 = FF_MOV_FLAG_FRAG_DISCONT}, INT_MIN, INT_MAX, AV_OPT_FLAG_ENCODING_PARAM, .unit = "movflags" },
101  { "frag_every_frame", "Fragment at every frame", 0, AV_OPT_TYPE_CONST, {.i64 = FF_MOV_FLAG_FRAG_EVERY_FRAME}, INT_MIN, INT_MAX, AV_OPT_FLAG_ENCODING_PARAM, .unit = "movflags" },
102  { "frag_keyframe", "Fragment at video keyframes", 0, AV_OPT_TYPE_CONST, {.i64 = FF_MOV_FLAG_FRAG_KEYFRAME}, INT_MIN, INT_MAX, AV_OPT_FLAG_ENCODING_PARAM, .unit = "movflags" },
103  { "global_sidx", "Write a global sidx index at the start of the file", 0, AV_OPT_TYPE_CONST, {.i64 = FF_MOV_FLAG_GLOBAL_SIDX}, INT_MIN, INT_MAX, AV_OPT_FLAG_ENCODING_PARAM, .unit = "movflags" },
104  { "isml", "Create a live smooth streaming feed (for pushing to a publishing point)", 0, AV_OPT_TYPE_CONST, {.i64 = FF_MOV_FLAG_ISML}, INT_MIN, INT_MAX, AV_OPT_FLAG_ENCODING_PARAM, .unit = "movflags" },
105  { "moov_size", "maximum moov size so it can be placed at the begin", offsetof(MOVMuxContext, reserved_moov_size), AV_OPT_TYPE_INT, {.i64 = 0}, 0, INT_MAX, AV_OPT_FLAG_ENCODING_PARAM, .unit = 0 },
106  { "negative_cts_offsets", "Use negative CTS offsets (reducing the need for edit lists)", 0, AV_OPT_TYPE_CONST, {.i64 = FF_MOV_FLAG_NEGATIVE_CTS_OFFSETS}, INT_MIN, INT_MAX, AV_OPT_FLAG_ENCODING_PARAM, .unit = "movflags" },
107  { "omit_tfhd_offset", "Omit the base data offset in tfhd atoms", 0, AV_OPT_TYPE_CONST, {.i64 = FF_MOV_FLAG_OMIT_TFHD_OFFSET}, INT_MIN, INT_MAX, AV_OPT_FLAG_ENCODING_PARAM, .unit = "movflags" },
108  { "prefer_icc", "If writing colr atom prioritise usage of ICC profile if it exists in stream packet side data", 0, AV_OPT_TYPE_CONST, {.i64 = FF_MOV_FLAG_PREFER_ICC}, INT_MIN, INT_MAX, AV_OPT_FLAG_ENCODING_PARAM, .unit = "movflags" },
109  { "rtphint", "Add RTP hint tracks", 0, AV_OPT_TYPE_CONST, {.i64 = FF_MOV_FLAG_RTP_HINT}, INT_MIN, INT_MAX, AV_OPT_FLAG_ENCODING_PARAM, .unit = "movflags" },
110  { "separate_moof", "Write separate moof/mdat atoms for each track", 0, AV_OPT_TYPE_CONST, {.i64 = FF_MOV_FLAG_SEPARATE_MOOF}, INT_MIN, INT_MAX, AV_OPT_FLAG_ENCODING_PARAM, .unit = "movflags" },
111  { "skip_sidx", "Skip writing of sidx atom", 0, AV_OPT_TYPE_CONST, {.i64 = FF_MOV_FLAG_SKIP_SIDX}, INT_MIN, INT_MAX, AV_OPT_FLAG_ENCODING_PARAM, .unit = "movflags" },
112  { "skip_trailer", "Skip writing the mfra/tfra/mfro trailer for fragmented files", 0, AV_OPT_TYPE_CONST, {.i64 = FF_MOV_FLAG_SKIP_TRAILER}, INT_MIN, INT_MAX, AV_OPT_FLAG_ENCODING_PARAM, .unit = "movflags" },
113  { "use_metadata_tags", "Use mdta atom for metadata.", 0, AV_OPT_TYPE_CONST, {.i64 = FF_MOV_FLAG_USE_MDTA}, INT_MIN, INT_MAX, AV_OPT_FLAG_ENCODING_PARAM, .unit = "movflags" },
114  { "write_colr", "Write colr atom even if the color info is unspecified (Experimental, may be renamed or changed, do not use from scripts)", 0, AV_OPT_TYPE_CONST, {.i64 = FF_MOV_FLAG_WRITE_COLR}, INT_MIN, INT_MAX, AV_OPT_FLAG_ENCODING_PARAM, .unit = "movflags" },
115  { "write_gama", "Write deprecated gama atom", 0, AV_OPT_TYPE_CONST, {.i64 = FF_MOV_FLAG_WRITE_GAMA}, INT_MIN, INT_MAX, AV_OPT_FLAG_ENCODING_PARAM, .unit = "movflags" },
116  { "hybrid_fragmented", "For recoverability, write a fragmented file that is converted to non-fragmented at the end.", 0, AV_OPT_TYPE_CONST, {.i64 = FF_MOV_FLAG_HYBRID_FRAGMENTED}, INT_MIN, INT_MAX, AV_OPT_FLAG_ENCODING_PARAM, .unit = "movflags" },
117  { "min_frag_duration", "Minimum fragment duration", offsetof(MOVMuxContext, min_fragment_duration), AV_OPT_TYPE_INT, {.i64 = 0}, 0, INT_MAX, AV_OPT_FLAG_ENCODING_PARAM},
118  { "mov_gamma", "gamma value for gama atom", offsetof(MOVMuxContext, gamma), AV_OPT_TYPE_FLOAT, {.dbl = 0.0 }, 0.0, 10, AV_OPT_FLAG_ENCODING_PARAM},
119  { "movie_timescale", "set movie timescale", offsetof(MOVMuxContext, movie_timescale), AV_OPT_TYPE_INT, {.i64 = MOV_TIMESCALE}, 1, INT_MAX, AV_OPT_FLAG_ENCODING_PARAM},
120  FF_RTP_FLAG_OPTS(MOVMuxContext, rtp_flags),
121  { "skip_iods", "Skip writing iods atom.", offsetof(MOVMuxContext, iods_skip), AV_OPT_TYPE_BOOL, {.i64 = 1}, 0, 1, AV_OPT_FLAG_ENCODING_PARAM},
122  { "use_editlist", "use edit list", offsetof(MOVMuxContext, use_editlist), AV_OPT_TYPE_BOOL, {.i64 = -1}, -1, 1, AV_OPT_FLAG_ENCODING_PARAM},
123  { "use_stream_ids_as_track_ids", "use stream ids as track ids", offsetof(MOVMuxContext, use_stream_ids_as_track_ids), AV_OPT_TYPE_BOOL, {.i64 = 0}, 0, 1, AV_OPT_FLAG_ENCODING_PARAM},
124  { "video_track_timescale", "set timescale of all video tracks", offsetof(MOVMuxContext, video_track_timescale), AV_OPT_TYPE_INT, {.i64 = 0}, 0, INT_MAX, AV_OPT_FLAG_ENCODING_PARAM},
125  { "write_btrt", "force or disable writing btrt", offsetof(MOVMuxContext, write_btrt), AV_OPT_TYPE_BOOL, {.i64 = -1}, -1, 1, AV_OPT_FLAG_ENCODING_PARAM},
126  { "write_prft", "Write producer reference time box with specified time source", offsetof(MOVMuxContext, write_prft), AV_OPT_TYPE_INT, {.i64 = MOV_PRFT_NONE}, 0, MOV_PRFT_NB-1, AV_OPT_FLAG_ENCODING_PARAM, .unit = "prft"},
127  { "pts", NULL, 0, AV_OPT_TYPE_CONST, {.i64 = MOV_PRFT_SRC_PTS}, 0, 0, AV_OPT_FLAG_ENCODING_PARAM, .unit = "prft"},
128  { "wallclock", NULL, 0, AV_OPT_TYPE_CONST, {.i64 = MOV_PRFT_SRC_WALLCLOCK}, 0, 0, AV_OPT_FLAG_ENCODING_PARAM, .unit = "prft"},
129  { "write_tmcd", "force or disable writing tmcd", offsetof(MOVMuxContext, write_tmcd), AV_OPT_TYPE_BOOL, {.i64 = -1}, -1, 1, AV_OPT_FLAG_ENCODING_PARAM},
130  { NULL },
131 };
132 
134  .class_name = "mov/mp4/tgp/psp/tg2/ipod/ismv/f4v muxer",
135  .item_name = av_default_item_name,
136  .option = options,
137  .version = LIBAVUTIL_VERSION_INT,
138 };
139 
140 static int get_moov_size(AVFormatContext *s);
142 
143 static int utf8len(const uint8_t *b)
144 {
145  int len = 0;
146  int val;
147  while (*b) {
148  GET_UTF8(val, *b++, return -1;)
149  len++;
150  }
151  return len;
152 }
153 
154 //FIXME support 64 bit variant with wide placeholders
156 {
157  int64_t curpos = avio_tell(pb);
158  avio_seek(pb, pos, SEEK_SET);
159  avio_wb32(pb, curpos - pos); /* rewrite size */
160  avio_seek(pb, curpos, SEEK_SET);
161 
162  return curpos - pos;
163 }
164 
166 {
167  int64_t curpos = avio_tell(pb);
168  avio_seek(pb, pos, SEEK_SET);
169  avio_wb32(pb, curpos - pos); /* rewrite size */
170  avio_skip(pb, 4);
171  avio_w8(pb, version); /* rewrite version */
172  avio_seek(pb, curpos, SEEK_SET);
173 
174  return curpos - pos;
175 }
176 
177 static int co64_required(const MOVTrack *track)
178 {
179  if (track->entry > 0 && track->cluster[track->entry - 1].pos + track->data_offset > UINT32_MAX)
180  return 1;
181  return 0;
182 }
183 
184 static int is_cover_image(const AVStream *st)
185 {
186  /* Eg. AV_DISPOSITION_ATTACHED_PIC | AV_DISPOSITION_TIMED_THUMBNAILS
187  * is encoded as sparse video track */
188  return st && st->disposition == AV_DISPOSITION_ATTACHED_PIC;
189 }
190 
191 static int rtp_hinting_needed(const AVStream *st)
192 {
193  /* Add hint tracks for each real audio and video stream */
194  if (is_cover_image(st))
195  return 0;
196  return st->codecpar->codec_type == AVMEDIA_TYPE_VIDEO ||
198 }
199 
200 /* Chunk offset atom */
201 static int mov_write_stco_tag(AVIOContext *pb, MOVTrack *track)
202 {
203  int i;
204  int mode64 = co64_required(track); // use 32 bit size variant if possible
205  int64_t pos = avio_tell(pb);
206  avio_wb32(pb, 0); /* size */
207  if (mode64)
208  ffio_wfourcc(pb, "co64");
209  else
210  ffio_wfourcc(pb, "stco");
211  avio_wb32(pb, 0); /* version & flags */
212  avio_wb32(pb, track->chunkCount); /* entry count */
213  for (i = 0; i < track->entry; i++) {
214  if (!track->cluster[i].chunkNum)
215  continue;
216  if (mode64 == 1)
217  avio_wb64(pb, track->cluster[i].pos + track->data_offset);
218  else
219  avio_wb32(pb, track->cluster[i].pos + track->data_offset);
220  }
221  return update_size(pb, pos);
222 }
223 
224 /* Sample size atom */
225 static int mov_write_stsz_tag(AVIOContext *pb, MOVTrack *track)
226 {
227  int equalChunks = 1;
228  int i, j, entries = 0, tst = -1, oldtst = -1;
229 
230  int64_t pos = avio_tell(pb);
231  avio_wb32(pb, 0); /* size */
232  ffio_wfourcc(pb, "stsz");
233  avio_wb32(pb, 0); /* version & flags */
234 
235  for (i = 0; i < track->entry; i++) {
236  tst = track->cluster[i].size / track->cluster[i].entries;
237  if (oldtst != -1 && tst != oldtst)
238  equalChunks = 0;
239  oldtst = tst;
240  entries += track->cluster[i].entries;
241  }
242  if (equalChunks && track->entry) {
243  int sSize = track->entry ? track->cluster[0].size / track->cluster[0].entries : 0;
244  sSize = FFMAX(1, sSize); // adpcm mono case could make sSize == 0
245  avio_wb32(pb, sSize); // sample size
246  avio_wb32(pb, entries); // sample count
247  } else {
248  avio_wb32(pb, 0); // sample size
249  avio_wb32(pb, entries); // sample count
250  for (i = 0; i < track->entry; i++) {
251  for (j = 0; j < track->cluster[i].entries; j++) {
252  avio_wb32(pb, track->cluster[i].size /
253  track->cluster[i].entries);
254  }
255  }
256  }
257  return update_size(pb, pos);
258 }
259 
260 /* Sample to chunk atom */
261 static int mov_write_stsc_tag(AVIOContext *pb, MOVTrack *track)
262 {
263  int index = 0, oldidx = -1, oldval = -1, i;
264  int64_t entryPos, curpos;
265 
266  int64_t pos = avio_tell(pb);
267  avio_wb32(pb, 0); /* size */
268  ffio_wfourcc(pb, "stsc");
269  avio_wb32(pb, 0); // version & flags
270  entryPos = avio_tell(pb);
271  avio_wb32(pb, track->chunkCount); // entry count
272  for (i = 0; i < track->entry; i++) {
273  if ((oldval != track->cluster[i].samples_in_chunk ||
274  oldidx != track->cluster[i].stsd_index) && track->cluster[i].chunkNum) {
275  avio_wb32(pb, track->cluster[i].chunkNum); // first chunk
276  avio_wb32(pb, track->cluster[i].samples_in_chunk); // samples per chunk
277  avio_wb32(pb, track->cluster[i].stsd_index + 1); // sample description index
278  oldval = track->cluster[i].samples_in_chunk;
279  oldidx = track->cluster[i].stsd_index;
280  index++;
281  }
282  }
283  curpos = avio_tell(pb);
284  avio_seek(pb, entryPos, SEEK_SET);
285  avio_wb32(pb, index); // rewrite size
286  avio_seek(pb, curpos, SEEK_SET);
287 
288  return update_size(pb, pos);
289 }
290 
291 /* Sync sample atom */
292 static int mov_write_stss_tag(AVIOContext *pb, MOVTrack *track, uint32_t flag)
293 {
294  int64_t curpos, entryPos;
295  int i, index = 0;
296  int64_t pos = avio_tell(pb);
297  avio_wb32(pb, 0); // size
298  ffio_wfourcc(pb, flag == MOV_SYNC_SAMPLE ? "stss" : "stps");
299  avio_wb32(pb, 0); // version & flags
300  entryPos = avio_tell(pb);
301  avio_wb32(pb, track->entry); // entry count
302  for (i = 0; i < track->entry; i++) {
303  if (track->cluster[i].flags & flag) {
304  avio_wb32(pb, i + 1);
305  index++;
306  }
307  }
308  curpos = avio_tell(pb);
309  avio_seek(pb, entryPos, SEEK_SET);
310  avio_wb32(pb, index); // rewrite size
311  avio_seek(pb, curpos, SEEK_SET);
312  return update_size(pb, pos);
313 }
314 
315 /* Sample dependency atom */
316 static int mov_write_sdtp_tag(AVIOContext *pb, MOVTrack *track)
317 {
318  int i;
319  uint8_t leading, dependent, reference, redundancy;
320  int64_t pos = avio_tell(pb);
321  avio_wb32(pb, 0); // size
322  ffio_wfourcc(pb, "sdtp");
323  avio_wb32(pb, 0); // version & flags
324  for (i = 0; i < track->entry; i++) {
325  dependent = MOV_SAMPLE_DEPENDENCY_YES;
326  leading = reference = redundancy = MOV_SAMPLE_DEPENDENCY_UNKNOWN;
327  if (track->cluster[i].flags & MOV_DISPOSABLE_SAMPLE) {
328  reference = MOV_SAMPLE_DEPENDENCY_NO;
329  }
330  if (track->cluster[i].flags & MOV_SYNC_SAMPLE) {
331  dependent = MOV_SAMPLE_DEPENDENCY_NO;
332  }
333  avio_w8(pb, (leading << 6) | (dependent << 4) |
334  (reference << 2) | redundancy);
335  }
336  return update_size(pb, pos);
337 }
338 
339 #if CONFIG_IAMFENC
340 static int mov_write_iacb_tag(AVFormatContext *s, AVIOContext *pb, MOVTrack *track)
341 {
342  AVIOContext *dyn_bc;
343  int64_t pos = avio_tell(pb);
344  uint8_t *dyn_buf = NULL;
345  int dyn_size;
346  int ret = avio_open_dyn_buf(&dyn_bc);
347  if (ret < 0)
348  return ret;
349 
350  avio_wb32(pb, 0);
351  ffio_wfourcc(pb, "iacb");
352  avio_w8(pb, 1); // configurationVersion
353 
354  ret = ff_iamf_write_descriptors(track->iamf, dyn_bc, s);
355  if (ret < 0)
356  return ret;
357 
358  dyn_size = avio_close_dyn_buf(dyn_bc, &dyn_buf);
359  ffio_write_leb(pb, dyn_size);
360  avio_write(pb, dyn_buf, dyn_size);
361  av_free(dyn_buf);
362 
363  return update_size(pb, pos);
364 }
365 #endif
366 
367 static int mov_write_amr_tag(AVIOContext *pb, MOVTrack *track)
368 {
369  avio_wb32(pb, 0x11); /* size */
370  if (track->mode == MODE_MOV) ffio_wfourcc(pb, "samr");
371  else ffio_wfourcc(pb, "damr");
372  ffio_wfourcc(pb, "FFMP");
373  avio_w8(pb, 0); /* decoder version */
374 
375  avio_wb16(pb, 0x81FF); /* Mode set (all modes for AMR_NB) */
376  avio_w8(pb, 0x00); /* Mode change period (no restriction) */
377  avio_w8(pb, 0x01); /* Frames per sample */
378  return 0x11;
379 }
380 
381 struct eac3_info {
383  uint8_t ec3_done;
384  uint8_t num_blocks;
385 
386  /* Layout of the EC3SpecificBox */
387  /* maximum bitrate */
388  uint16_t data_rate;
390  /* number of independent substreams */
391  uint8_t num_ind_sub;
392  struct {
393  /* sample rate code (see ff_ac3_sample_rate_tab) 2 bits */
394  uint8_t fscod;
395  /* bit stream identification 5 bits */
396  uint8_t bsid;
397  /* one bit reserved */
398  /* audio service mixing (not supported yet) 1 bit */
399  /* bit stream mode 3 bits */
400  uint8_t bsmod;
401  /* audio coding mode 3 bits */
402  uint8_t acmod;
403  /* sub woofer on 1 bit */
404  uint8_t lfeon;
405  /* 3 bits reserved */
406  /* number of dependent substreams associated with this substream 4 bits */
407  uint8_t num_dep_sub;
408  /* channel locations of the dependent substream(s), if any, 9 bits */
409  uint16_t chan_loc;
410  /* if there is no dependent substream, then one bit reserved instead */
411  } substream[1]; /* TODO: support 8 independent substreams */
412  /* indicates the decoding complexity, 8 bits */
414 };
415 
417 {
418  struct eac3_info *info = track->eac3_priv;
419  PutBitContext pbc;
420  uint8_t buf[3];
421 
422  if (!info || !info->ec3_done) {
424  "Cannot write moov atom before AC3 packets."
425  " Set the delay_moov flag to fix this.\n");
426  return AVERROR(EINVAL);
427  }
428 
429  if (info->substream[0].bsid > 8) {
431  "RealAudio AC-3/DolbyNet with bsid %d is not defined by the "
432  "ISOBMFF specification in ETSI TS 102 366!\n",
433  info->substream[0].bsid);
434  return AVERROR(EINVAL);
435  }
436 
437  if (info->ac3_bit_rate_code < 0) {
439  "No valid AC3 bit rate code for data rate of %d!\n",
440  info->data_rate);
441  return AVERROR(EINVAL);
442  }
443 
444  avio_wb32(pb, 11);
445  ffio_wfourcc(pb, "dac3");
446 
447  init_put_bits(&pbc, buf, sizeof(buf));
448  put_bits(&pbc, 2, info->substream[0].fscod);
449  put_bits(&pbc, 5, info->substream[0].bsid);
450  put_bits(&pbc, 3, info->substream[0].bsmod);
451  put_bits(&pbc, 3, info->substream[0].acmod);
452  put_bits(&pbc, 1, info->substream[0].lfeon);
453  put_bits(&pbc, 5, info->ac3_bit_rate_code); // bit_rate_code
454  put_bits(&pbc, 5, 0); // reserved
455 
456  flush_put_bits(&pbc);
457  avio_write(pb, buf, sizeof(buf));
458 
459  return 11;
460 }
461 
462 static int handle_eac3(MOVMuxContext *mov, AVPacket *pkt, MOVTrack *track)
463 {
464  AC3HeaderInfo *hdr = NULL;
465  struct eac3_info *info;
466  int num_blocks, ret;
467 
468  if (!track->eac3_priv) {
469  if (!(track->eac3_priv = av_mallocz(sizeof(*info))))
470  return AVERROR(ENOMEM);
471 
472  ((struct eac3_info *)track->eac3_priv)->ac3_bit_rate_code = -1;
473  }
474  info = track->eac3_priv;
475 
476  if (!info->pkt && !(info->pkt = av_packet_alloc()))
477  return AVERROR(ENOMEM);
478 
479  if ((ret = avpriv_ac3_parse_header(&hdr, pkt->data, pkt->size)) < 0) {
480  if (ret == AVERROR(ENOMEM))
481  goto end;
482 
483  /* drop the packets until we see a good one */
484  if (!track->entry) {
485  av_log(mov->fc, AV_LOG_WARNING, "Dropping invalid packet from start of the stream\n");
486  ret = 0;
487  } else
489  goto end;
490  }
491 
492  info->data_rate = FFMAX(info->data_rate, hdr->bit_rate / 1000);
493  info->ac3_bit_rate_code = FFMAX(info->ac3_bit_rate_code,
494  hdr->ac3_bit_rate_code);
495  info->complexity_index_type_a = hdr->complexity_index_type_a;
496 
497  num_blocks = hdr->num_blocks;
498 
499  if (!info->ec3_done) {
500  /* AC-3 substream must be the first one */
501  if (hdr->bitstream_id <= 10 && hdr->substreamid != 0) {
502  ret = AVERROR(EINVAL);
503  goto end;
504  }
505 
506  /* this should always be the case, given that our AC-3 parser
507  * concatenates dependent frames to their independent parent */
510  /* substream ids must be incremental */
511  if (hdr->substreamid > info->num_ind_sub + 1) {
512  ret = AVERROR(EINVAL);
513  goto end;
514  }
515 
516  if (hdr->substreamid == info->num_ind_sub + 1) {
517  //info->num_ind_sub++;
518  avpriv_request_sample(mov->fc, "Multiple independent substreams");
520  goto end;
521  } else if (hdr->substreamid < info->num_ind_sub ||
522  hdr->substreamid == 0 && info->substream[0].bsid) {
523  info->ec3_done = 1;
524  goto concatenate;
525  }
526  } else {
527  if (hdr->substreamid != 0) {
528  avpriv_request_sample(mov->fc, "Multiple non EAC3 independent substreams");
530  goto end;
531  }
532  }
533 
534  /* fill the info needed for the "dec3" atom */
535  info->substream[hdr->substreamid].fscod = hdr->sr_code;
536  info->substream[hdr->substreamid].bsid = hdr->bitstream_id;
537  info->substream[hdr->substreamid].bsmod = hdr->bitstream_mode;
538  info->substream[hdr->substreamid].acmod = hdr->channel_mode;
539  info->substream[hdr->substreamid].lfeon = hdr->lfe_on;
540 
541  if (track->par->codec_id == AV_CODEC_ID_AC3) {
542  // with AC-3 we only require the information of a single packet,
543  // so we can finish as soon as the basic values of the bit stream
544  // have been set to the track's informational structure.
545  info->ec3_done = 1;
546  goto concatenate;
547  }
548 
549  /* Parse dependent substream(s), if any */
550  if (pkt->size != hdr->frame_size) {
551  int cumul_size = hdr->frame_size;
552  int parent = hdr->substreamid;
553 
554  while (cumul_size != pkt->size) {
555  ret = avpriv_ac3_parse_header(&hdr, pkt->data + cumul_size, pkt->size - cumul_size);
556  if (ret < 0)
557  goto end;
559  ret = AVERROR(EINVAL);
560  goto end;
561  }
562  info->substream[parent].num_dep_sub++;
563  ret /= 8;
564 
565  /* get the dependent stream channel map, if exists */
566  if (hdr->channel_map_present)
567  info->substream[parent].chan_loc |= (hdr->channel_map >> 5) & 0x1f;
568  else
569  info->substream[parent].chan_loc |= hdr->channel_mode;
570  cumul_size += hdr->frame_size;
571  }
572  }
573  }
574 
575 concatenate:
576  if (!info->num_blocks && num_blocks == 6) {
577  ret = pkt->size;
578  goto end;
579  }
580  else if (info->num_blocks + num_blocks > 6) {
582  goto end;
583  }
584 
585  if (!info->num_blocks) {
586  ret = av_packet_ref(info->pkt, pkt);
587  if (!ret)
588  info->num_blocks = num_blocks;
589  goto end;
590  } else {
591  if ((ret = av_grow_packet(info->pkt, pkt->size)) < 0)
592  goto end;
593  memcpy(info->pkt->data + info->pkt->size - pkt->size, pkt->data, pkt->size);
594  info->num_blocks += num_blocks;
595  info->pkt->duration += pkt->duration;
596  if (info->num_blocks != 6)
597  goto end;
599  av_packet_move_ref(pkt, info->pkt);
600  info->num_blocks = 0;
601  }
602  ret = pkt->size;
603 
604 end:
605  av_free(hdr);
606 
607  return ret;
608 }
609 
611 {
612  PutBitContext pbc;
613  uint8_t *buf;
614  struct eac3_info *info;
615  int size, i;
616 
617  if (!track->eac3_priv) {
619  "Cannot write moov atom before EAC3 packets parsed.\n");
620  return AVERROR(EINVAL);
621  }
622 
623  info = track->eac3_priv;
624  size = 2 + (4 * (info->num_ind_sub + 1)) + (2 * !!info->complexity_index_type_a);
625  buf = av_malloc(size);
626  if (!buf) {
627  return AVERROR(ENOMEM);
628  }
629 
630  init_put_bits(&pbc, buf, size);
631  put_bits(&pbc, 13, info->data_rate);
632  put_bits(&pbc, 3, info->num_ind_sub);
633  for (i = 0; i <= info->num_ind_sub; i++) {
634  put_bits(&pbc, 2, info->substream[i].fscod);
635  put_bits(&pbc, 5, info->substream[i].bsid);
636  put_bits(&pbc, 1, 0); /* reserved */
637  put_bits(&pbc, 1, 0); /* asvc */
638  put_bits(&pbc, 3, info->substream[i].bsmod);
639  put_bits(&pbc, 3, info->substream[i].acmod);
640  put_bits(&pbc, 1, info->substream[i].lfeon);
641  put_bits(&pbc, 3, 0); /* reserved */
642  put_bits(&pbc, 4, info->substream[i].num_dep_sub);
643  if (!info->substream[i].num_dep_sub) {
644  put_bits(&pbc, 1, 0); /* reserved */
645  } else {
646  put_bits(&pbc, 9, info->substream[i].chan_loc);
647  }
648  }
649  if (info->complexity_index_type_a) {
650  put_bits(&pbc, 7, 0); /* reserved */
651  put_bits(&pbc, 1, 1); // flag_eac3_extension_type_a
652  put_bits(&pbc, 8, info->complexity_index_type_a);
653  }
654  flush_put_bits(&pbc);
655  size = put_bytes_output(&pbc);
656 
657  avio_wb32(pb, size + 8);
658  ffio_wfourcc(pb, "dec3");
659  avio_write(pb, buf, size);
660 
661  av_free(buf);
662 
663  return size;
664 }
665 
666 /**
667  * This function writes extradata "as is".
668  * Extradata must be formatted like a valid atom (with size and tag).
669  */
671 {
672  avio_write(pb, track->extradata[track->last_stsd_index], track->extradata_size[track->last_stsd_index]);
673  return track->extradata_size[track->last_stsd_index];
674 }
675 
677 {
678  avio_wb32(pb, 10);
679  ffio_wfourcc(pb, "enda");
680  avio_wb16(pb, 1); /* little endian */
681  return 10;
682 }
683 
685 {
686  avio_wb32(pb, 10);
687  ffio_wfourcc(pb, "enda");
688  avio_wb16(pb, 0); /* big endian */
689  return 10;
690 }
691 
692 static void put_descr(AVIOContext *pb, int tag, unsigned int size)
693 {
694  int i = 3;
695  avio_w8(pb, tag);
696  for (; i > 0; i--)
697  avio_w8(pb, (size >> (7 * i)) | 0x80);
698  avio_w8(pb, size & 0x7F);
699 }
700 
701 static unsigned compute_avg_bitrate(MOVTrack *track)
702 {
703  uint64_t size = 0;
704  int i;
705  if (!track->track_duration)
706  return 0;
707  for (i = 0; i < track->entry; i++)
708  size += track->cluster[i].size;
709  return size * 8 * track->timescale / track->track_duration;
710 }
711 
713  uint32_t buffer_size; ///< Size of the decoding buffer for the elementary stream in bytes.
714  uint32_t max_bit_rate; ///< Maximum rate in bits/second over any window of one second.
715  uint32_t avg_bit_rate; ///< Average rate in bits/second over the entire presentation.
716 };
717 
719 {
720  const AVPacketSideData *sd = track->st ?
722  track->st->codecpar->nb_coded_side_data,
724  AVCPBProperties *props = sd ? (AVCPBProperties *)sd->data : NULL;
725  struct mpeg4_bit_rate_values bit_rates = { 0 };
726 
727  bit_rates.avg_bit_rate = compute_avg_bitrate(track);
728  if (!bit_rates.avg_bit_rate) {
729  // if the average bit rate cannot be calculated at this point, such as
730  // in the case of fragmented MP4, utilize the following values as
731  // fall-back in priority order:
732  //
733  // 1. average bit rate property
734  // 2. bit rate (usually average over the whole clip)
735  // 3. maximum bit rate property
736 
737  if (props && props->avg_bitrate) {
738  bit_rates.avg_bit_rate = props->avg_bitrate;
739  } else if (track->par->bit_rate) {
740  bit_rates.avg_bit_rate = track->par->bit_rate;
741  } else if (props && props->max_bitrate) {
742  bit_rates.avg_bit_rate = props->max_bitrate;
743  }
744  }
745 
746  // (FIXME should be max rate in any 1 sec window)
747  bit_rates.max_bit_rate = FFMAX(track->par->bit_rate,
748  bit_rates.avg_bit_rate);
749 
750  // utilize values from properties if we have them available
751  if (props) {
752  // no avg_bitrate signals that the track is VBR
753  if (!props->avg_bitrate)
754  bit_rates.avg_bit_rate = props->avg_bitrate;
755  bit_rates.max_bit_rate = FFMAX(bit_rates.max_bit_rate,
756  props->max_bitrate);
757  bit_rates.buffer_size = props->buffer_size / 8;
758  }
759 
760  return bit_rates;
761 }
762 
763 static int mov_write_esds_tag(AVIOContext *pb, MOVTrack *track) // Basic
764 {
765  struct mpeg4_bit_rate_values bit_rates = calculate_mpeg4_bit_rates(track);
766  int64_t pos = avio_tell(pb);
767  int decoder_specific_info_len = track->extradata_size[track->last_stsd_index] ?
768  5 + track->extradata_size[track->last_stsd_index] : 0;
769 
770  avio_wb32(pb, 0); // size
771  ffio_wfourcc(pb, "esds");
772  avio_wb32(pb, 0); // Version
773 
774  // ES descriptor
775  put_descr(pb, 0x03, 3 + 5+13 + decoder_specific_info_len + 5+1);
776  avio_wb16(pb, track->track_id);
777  avio_w8(pb, 0x00); // flags (= no flags)
778 
779  // DecoderConfig descriptor
780  put_descr(pb, 0x04, 13 + decoder_specific_info_len);
781 
782  // Object type indication
783  if ((track->par->codec_id == AV_CODEC_ID_MP2 ||
784  track->par->codec_id == AV_CODEC_ID_MP3) &&
785  track->par->sample_rate > 24000)
786  avio_w8(pb, 0x6B); // 11172-3
787  else
789 
790  // the following fields is made of 6 bits to identify the streamtype (4 for video, 5 for audio)
791  // plus 1 bit to indicate upstream and 1 bit set to 1 (reserved)
792  if (track->par->codec_id == AV_CODEC_ID_DVD_SUBTITLE)
793  avio_w8(pb, (0x38 << 2) | 1); // flags (= NeroSubpicStream)
794  else if (track->par->codec_type == AVMEDIA_TYPE_AUDIO)
795  avio_w8(pb, 0x15); // flags (= Audiostream)
796  else
797  avio_w8(pb, 0x11); // flags (= Visualstream)
798 
799  avio_wb24(pb, bit_rates.buffer_size); // Buffersize DB
800  avio_wb32(pb, bit_rates.max_bit_rate); // maxbitrate
801  avio_wb32(pb, bit_rates.avg_bit_rate);
802 
803  if (track->extradata_size[track->last_stsd_index]) {
804  // DecoderSpecific info descriptor
805  put_descr(pb, 0x05, track->extradata_size[track->last_stsd_index]);
806  avio_write(pb, track->extradata[track->last_stsd_index],
807  track->extradata_size[track->last_stsd_index]);
808  }
809 
810  // SL descriptor
811  put_descr(pb, 0x06, 1);
812  avio_w8(pb, 0x02);
813  return update_size(pb, pos);
814 }
815 
817 {
818  return codec_id == AV_CODEC_ID_PCM_S24LE ||
822 }
823 
825 {
826  return codec_id == AV_CODEC_ID_PCM_S24BE ||
830 }
831 
833 {
834  int ret;
835  int64_t pos = avio_tell(pb);
836  avio_wb32(pb, 0);
837  avio_wl32(pb, track->tag); // store it byteswapped
838  track->par->codec_tag = av_bswap16(track->tag >> 16);
839  if ((ret = ff_put_wav_header(s, pb, track->par, 0)) < 0)
840  return ret;
841  return update_size(pb, pos);
842 }
843 
845 {
846  int ret;
847  int64_t pos = avio_tell(pb);
848  avio_wb32(pb, 0);
849  ffio_wfourcc(pb, "wfex");
851  return ret;
852  return update_size(pb, pos);
853 }
854 
855 static int mov_write_dfla_tag(AVIOContext *pb, MOVTrack *track)
856 {
857  int64_t pos = avio_tell(pb);
858  avio_wb32(pb, 0);
859  ffio_wfourcc(pb, "dfLa");
860  avio_w8(pb, 0); /* version */
861  avio_wb24(pb, 0); /* flags */
862 
863  /* Expect the encoder to pass a METADATA_BLOCK_TYPE_STREAMINFO. */
865  return AVERROR_INVALIDDATA;
866 
867  /* TODO: Write other METADATA_BLOCK_TYPEs if the encoder makes them available. */
868  avio_w8(pb, 1 << 7 | FLAC_METADATA_TYPE_STREAMINFO); /* LastMetadataBlockFlag << 7 | BlockType */
869  avio_wb24(pb, track->extradata_size[track->last_stsd_index]); /* Length */
870  avio_write(pb, track->extradata[track->last_stsd_index], track->extradata_size[track->last_stsd_index]); /* BlockData[Length] */
871 
872  return update_size(pb, pos);
873 }
874 
876 {
877  int64_t pos = avio_tell(pb);
878  int channels, channel_map;
879  avio_wb32(pb, 0);
880  ffio_wfourcc(pb, "dOps");
881  avio_w8(pb, 0); /* Version */
882  if (track->extradata_size[track->last_stsd_index] < 19) {
883  av_log(s, AV_LOG_ERROR, "invalid extradata size\n");
884  return AVERROR_INVALIDDATA;
885  }
886  /* extradata contains an Ogg OpusHead, other than byte-ordering and
887  OpusHead's preceding magic/version, OpusSpecificBox is currently
888  identical. */
889  channels = AV_RB8(track->extradata[track->last_stsd_index] + 9);
890  channel_map = AV_RB8(track->extradata[track->last_stsd_index] + 18);
891 
892  avio_w8(pb, channels); /* OuputChannelCount */
893  avio_wb16(pb, AV_RL16(track->extradata[track->last_stsd_index] + 10)); /* PreSkip */
894  avio_wb32(pb, AV_RL32(track->extradata[track->last_stsd_index] + 12)); /* InputSampleRate */
895  avio_wb16(pb, AV_RL16(track->extradata[track->last_stsd_index] + 16)); /* OutputGain */
896  avio_w8(pb, channel_map); /* ChannelMappingFamily */
897  /* Write the rest of the header out without byte-swapping. */
898  if (channel_map) {
899  if (track->extradata_size[track->last_stsd_index] < 21 + channels) {
900  av_log(s, AV_LOG_ERROR, "invalid extradata size\n");
901  return AVERROR_INVALIDDATA;
902  }
903  avio_write(pb, track->extradata[track->last_stsd_index] + 19, 2 + channels); /* ChannelMappingTable */
904  }
905 
906  return update_size(pb, pos);
907 }
908 
910 {
911  int64_t pos = avio_tell(pb);
912  int length;
913  avio_wb32(pb, 0);
914  ffio_wfourcc(pb, "dmlp");
915 
916  if (track->extradata_size[track->last_stsd_index] < 20) {
918  "Cannot write moov atom before TrueHD packets."
919  " Set the delay_moov flag to fix this.\n");
920  return AVERROR(EINVAL);
921  }
922 
923  length = (AV_RB16(track->extradata[track->last_stsd_index]) & 0xFFF) * 2;
924  if (length < 20 || length > track->extradata_size[track->last_stsd_index])
925  return AVERROR_INVALIDDATA;
926 
927  // Only TrueHD is supported
928  if (AV_RB32(track->extradata[track->last_stsd_index] + 4) != 0xF8726FBA)
929  return AVERROR_INVALIDDATA;
930 
931  avio_wb32(pb, AV_RB32(track->extradata[track->last_stsd_index] + 8)); /* format_info */
932  avio_wb16(pb, AV_RB16(track->extradata[track->last_stsd_index] + 18) << 1); /* peak_data_rate */
933  avio_wb32(pb, 0); /* reserved */
934 
935  return update_size(pb, pos);
936 }
937 
939 {
940  const AVDictionaryEntry *str = av_dict_get(track->st->metadata, "SA3D", NULL, 0);
941  AVChannelLayout ch_layout = { 0 };
942  int64_t pos;
943  int ambisonic_order, ambi_channels, non_diegetic_channels;
944  int i, ret;
945 
946  if (!str)
947  return 0;
948 
949  ret = av_channel_layout_from_string(&ch_layout, str->value);
950  if (ret < 0) {
951  if (ret == AVERROR(EINVAL)) {
952 invalid:
953  av_log(s, AV_LOG_ERROR, "Invalid SA3D layout: \"%s\"\n", str->value);
954  ret = 0;
955  }
956  av_channel_layout_uninit(&ch_layout);
957  return ret;
958  }
959 
960  if (track->st->codecpar->ch_layout.nb_channels != ch_layout.nb_channels)
961  goto invalid;
962 
963  ambisonic_order = av_channel_layout_ambisonic_order(&ch_layout);
964  if (ambisonic_order < 0)
965  goto invalid;
966 
967  ambi_channels = (ambisonic_order + 1LL) * (ambisonic_order + 1LL);
968  non_diegetic_channels = ch_layout.nb_channels - ambi_channels;
969  if (non_diegetic_channels &&
970  (non_diegetic_channels != 2 ||
972  goto invalid;
973 
974  av_log(s, AV_LOG_VERBOSE, "Inserting SA3D box with layout: \"%s\"\n", str->value);
975 
976  pos = avio_tell(pb);
977 
978  avio_wb32(pb, 0); // Size
979  ffio_wfourcc(pb, "SA3D");
980  avio_w8(pb, 0); // version
981  avio_w8(pb, (!!non_diegetic_channels) << 7); // head_locked_stereo and ambisonic_type
982  avio_wb32(pb, ambisonic_order); // ambisonic_order
983  avio_w8(pb, 0); // ambisonic_channel_ordering
984  avio_w8(pb, 0); // ambisonic_normalization
985  avio_wb32(pb, ch_layout.nb_channels); // num_channels
986  for (i = 0; i < ambi_channels; i++)
988  for (; i < ch_layout.nb_channels; i++)
989  avio_wb32(pb, av_channel_layout_channel_from_index(&ch_layout, i) + ambi_channels);
990 
991  av_channel_layout_uninit(&ch_layout);
992 
993  return update_size(pb, pos);
994 }
995 
997 {
998  uint32_t layout_tag, bitmap, *channel_desc;
999  int64_t pos = avio_tell(pb);
1000  int num_desc, ret;
1001 
1002  if (track->multichannel_as_mono)
1003  return 0;
1004 
1005  ret = ff_mov_get_channel_layout_tag(track->par, &layout_tag,
1006  &bitmap, &channel_desc);
1007 
1008  if (ret < 0) {
1009  if (ret == AVERROR(ENOSYS)) {
1010  av_log(s, AV_LOG_WARNING, "not writing 'chan' tag due to "
1011  "lack of channel information\n");
1012  ret = 0;
1013  }
1014 
1015  return ret;
1016  }
1017 
1018  if (layout_tag == MOV_CH_LAYOUT_MONO && track->mono_as_fc > 0) {
1019  av_assert0(!channel_desc);
1020  channel_desc = av_malloc(sizeof(*channel_desc));
1021  if (!channel_desc)
1022  return AVERROR(ENOMEM);
1023 
1024  layout_tag = 0;
1025  bitmap = 0;
1026  *channel_desc = 3; // channel label "Center"
1027  }
1028 
1029  num_desc = layout_tag ? 0 : track->par->ch_layout.nb_channels;
1030 
1031  avio_wb32(pb, 0); // Size
1032  ffio_wfourcc(pb, "chan"); // Type
1033  avio_w8(pb, 0); // Version
1034  avio_wb24(pb, 0); // Flags
1035  avio_wb32(pb, layout_tag); // mChannelLayoutTag
1036  avio_wb32(pb, bitmap); // mChannelBitmap
1037  avio_wb32(pb, num_desc); // mNumberChannelDescriptions
1038 
1039  for (int i = 0; i < num_desc; i++) {
1040  avio_wb32(pb, channel_desc[i]); // mChannelLabel
1041  avio_wb32(pb, 0); // mChannelFlags
1042  avio_wl32(pb, 0); // mCoordinates[0]
1043  avio_wl32(pb, 0); // mCoordinates[1]
1044  avio_wl32(pb, 0); // mCoordinates[2]
1045  }
1046 
1047  av_free(channel_desc);
1048 
1049  return update_size(pb, pos);
1050 }
1051 
1053 {
1054  int64_t pos = avio_tell(pb);
1055 
1056  avio_wb32(pb, 0); /* size */
1057  ffio_wfourcc(pb, "wave");
1058 
1059  if (track->par->codec_id != AV_CODEC_ID_QDM2) {
1060  avio_wb32(pb, 12); /* size */
1061  ffio_wfourcc(pb, "frma");
1062  avio_wl32(pb, track->tag);
1063  }
1064 
1065  if (track->par->codec_id == AV_CODEC_ID_AAC) {
1066  /* useless atom needed by mplayer, ipod, not needed by quicktime */
1067  avio_wb32(pb, 12); /* size */
1068  ffio_wfourcc(pb, "mp4a");
1069  avio_wb32(pb, 0);
1070  mov_write_esds_tag(pb, track);
1071  } else if (mov_pcm_le_gt16(track->par->codec_id)) {
1072  mov_write_enda_tag(pb);
1073  } else if (mov_pcm_be_gt16(track->par->codec_id)) {
1075  } else if (track->par->codec_id == AV_CODEC_ID_AMR_NB) {
1076  mov_write_amr_tag(pb, track);
1077  } else if (track->par->codec_id == AV_CODEC_ID_AC3) {
1078  mov_write_ac3_tag(s, pb, track);
1079  } else if (track->par->codec_id == AV_CODEC_ID_EAC3) {
1080  mov_write_eac3_tag(s, pb, track);
1081  } else if (track->par->codec_id == AV_CODEC_ID_ALAC ||
1082  track->par->codec_id == AV_CODEC_ID_QDM2) {
1083  mov_write_extradata_tag(pb, track);
1084  } else if (track->par->codec_id == AV_CODEC_ID_ADPCM_MS ||
1085  track->par->codec_id == AV_CODEC_ID_ADPCM_IMA_WAV) {
1086  mov_write_ms_tag(s, pb, track);
1087  }
1088 
1089  avio_wb32(pb, 8); /* size */
1090  avio_wb32(pb, 0); /* null tag */
1091 
1092  return update_size(pb, pos);
1093 }
1094 
1095 static int mov_write_dvc1_structs(MOVTrack *track, uint8_t *buf)
1096 {
1097  uint8_t *unescaped;
1098  const uint8_t *start, *next, *end = track->extradata[track->last_stsd_index] +
1099  track->extradata_size[track->last_stsd_index];
1100  int unescaped_size, seq_found = 0;
1101  int level = 0, interlace = 0;
1102  int packet_seq = track->vc1_info.packet_seq;
1103  int packet_entry = track->vc1_info.packet_entry;
1104  int slices = track->vc1_info.slices;
1105  PutBitContext pbc;
1106 
1107  if (track->start_dts == AV_NOPTS_VALUE) {
1108  /* No packets written yet, vc1_info isn't authoritative yet. */
1109  /* Assume inline sequence and entry headers. */
1110  packet_seq = packet_entry = 1;
1112  "moov atom written before any packets, unable to write correct "
1113  "dvc1 atom. Set the delay_moov flag to fix this.\n");
1114  }
1115 
1117  if (!unescaped)
1118  return AVERROR(ENOMEM);
1119  start = find_next_marker(track->extradata[track->last_stsd_index], end);
1120  for (next = start; next < end; start = next) {
1121  GetBitContext gb;
1122  int size;
1123  next = find_next_marker(start + 4, end);
1124  size = next - start - 4;
1125  if (size <= 0)
1126  continue;
1127  unescaped_size = vc1_unescape_buffer(start + 4, size, unescaped);
1128  init_get_bits(&gb, unescaped, 8 * unescaped_size);
1129  if (AV_RB32(start) == VC1_CODE_SEQHDR) {
1130  int profile = get_bits(&gb, 2);
1131  if (profile != PROFILE_ADVANCED) {
1132  av_free(unescaped);
1133  return AVERROR(ENOSYS);
1134  }
1135  seq_found = 1;
1136  level = get_bits(&gb, 3);
1137  /* chromaformat, frmrtq_postproc, bitrtq_postproc, postprocflag,
1138  * width, height */
1139  skip_bits_long(&gb, 2 + 3 + 5 + 1 + 2*12);
1140  skip_bits(&gb, 1); /* broadcast */
1141  interlace = get_bits1(&gb);
1142  skip_bits(&gb, 4); /* tfcntrflag, finterpflag, reserved, psf */
1143  }
1144  }
1145  if (!seq_found) {
1146  av_free(unescaped);
1147  return AVERROR(ENOSYS);
1148  }
1149 
1150  init_put_bits(&pbc, buf, 7);
1151  /* VC1DecSpecStruc */
1152  put_bits(&pbc, 4, 12); /* profile - advanced */
1153  put_bits(&pbc, 3, level);
1154  put_bits(&pbc, 1, 0); /* reserved */
1155  /* VC1AdvDecSpecStruc */
1156  put_bits(&pbc, 3, level);
1157  put_bits(&pbc, 1, 0); /* cbr */
1158  put_bits(&pbc, 6, 0); /* reserved */
1159  put_bits(&pbc, 1, !interlace); /* no interlace */
1160  put_bits(&pbc, 1, !packet_seq); /* no multiple seq */
1161  put_bits(&pbc, 1, !packet_entry); /* no multiple entry */
1162  put_bits(&pbc, 1, !slices); /* no slice code */
1163  put_bits(&pbc, 1, 0); /* no bframe */
1164  put_bits(&pbc, 1, 0); /* reserved */
1165 
1166  /* framerate */
1167  if (track->st->avg_frame_rate.num > 0 && track->st->avg_frame_rate.den > 0)
1168  put_bits32(&pbc, track->st->avg_frame_rate.num / track->st->avg_frame_rate.den);
1169  else
1170  put_bits32(&pbc, 0xffffffff);
1171 
1172  flush_put_bits(&pbc);
1173 
1174  av_free(unescaped);
1175 
1176  return 0;
1177 }
1178 
1179 static int mov_write_dvc1_tag(AVIOContext *pb, MOVTrack *track)
1180 {
1181  uint8_t buf[7] = { 0 };
1182  int ret;
1183 
1184  if ((ret = mov_write_dvc1_structs(track, buf)) < 0)
1185  return ret;
1186 
1187  avio_wb32(pb, track->extradata_size[track->last_stsd_index] + 8 + sizeof(buf));
1188  ffio_wfourcc(pb, "dvc1");
1189  avio_write(pb, buf, sizeof(buf));
1190  avio_write(pb, track->extradata[track->last_stsd_index],
1191  track->extradata_size[track->last_stsd_index]);
1192 
1193  return 0;
1194 }
1195 
1196 static int mov_write_glbl_tag(AVIOContext *pb, MOVTrack *track)
1197 {
1198  avio_wb32(pb, track->extradata_size[track->last_stsd_index] + 8);
1199  ffio_wfourcc(pb, "glbl");
1200  avio_write(pb, track->extradata[track->last_stsd_index],
1201  track->extradata_size[track->last_stsd_index]);
1202  return 8 + track->extradata_size[track->last_stsd_index];
1203 }
1204 
1205 /**
1206  * Compute flags for 'lpcm' tag.
1207  * See CoreAudioTypes and AudioStreamBasicDescription at Apple.
1208  */
1210 {
1211  switch (codec_id) {
1212  case AV_CODEC_ID_PCM_F32BE:
1213  case AV_CODEC_ID_PCM_F64BE:
1214  return 11;
1215  case AV_CODEC_ID_PCM_F32LE:
1216  case AV_CODEC_ID_PCM_F64LE:
1217  return 9;
1218  case AV_CODEC_ID_PCM_U8:
1219  return 10;
1220  case AV_CODEC_ID_PCM_S16BE:
1221  case AV_CODEC_ID_PCM_S24BE:
1222  case AV_CODEC_ID_PCM_S32BE:
1223  return 14;
1224  case AV_CODEC_ID_PCM_S8:
1225  case AV_CODEC_ID_PCM_S16LE:
1226  case AV_CODEC_ID_PCM_S24LE:
1227  case AV_CODEC_ID_PCM_S32LE:
1228  return 12;
1229  default:
1230  return 0;
1231  }
1232 }
1233 
1234 static int get_cluster_duration(MOVTrack *track, int cluster_idx)
1235 {
1236  int64_t next_dts;
1237 
1238  if (cluster_idx >= track->entry)
1239  return 0;
1240 
1241  if (cluster_idx + 1 == track->entry)
1242  next_dts = track->track_duration + track->start_dts;
1243  else
1244  next_dts = track->cluster[cluster_idx + 1].dts;
1245 
1246  next_dts -= track->cluster[cluster_idx].dts;
1247 
1248  av_assert0(next_dts >= 0);
1249  av_assert0(next_dts <= INT_MAX);
1250 
1251  return next_dts;
1252 }
1253 
1255 {
1256  int i, first_duration;
1257 
1258  /* use 1 for raw PCM */
1259  if (!track->audio_vbr)
1260  return 1;
1261 
1262  /* check to see if duration is constant for all clusters */
1263  if (!track->entry)
1264  return 0;
1265  first_duration = get_cluster_duration(track, 0);
1266  for (i = 1; i < track->entry; i++) {
1267  if (get_cluster_duration(track, i) != first_duration)
1268  return 0;
1269  }
1270  return first_duration;
1271 }
1272 
1273 static int mov_write_btrt_tag(AVIOContext *pb, MOVTrack *track)
1274 {
1275  int64_t pos = avio_tell(pb);
1276  struct mpeg4_bit_rate_values bit_rates = calculate_mpeg4_bit_rates(track);
1277  if (!bit_rates.max_bit_rate && !bit_rates.avg_bit_rate &&
1278  !bit_rates.buffer_size)
1279  // no useful data to be written, skip
1280  return 0;
1281 
1282  avio_wb32(pb, 0); /* size */
1283  ffio_wfourcc(pb, "btrt");
1284 
1285  avio_wb32(pb, bit_rates.buffer_size);
1286  avio_wb32(pb, bit_rates.max_bit_rate);
1287  avio_wb32(pb, bit_rates.avg_bit_rate);
1288 
1289  return update_size(pb, pos);
1290 }
1291 
1293 {
1294  int64_t pos = avio_tell(pb);
1295  int config = 0;
1296  int ret;
1297  uint8_t *speaker_pos = NULL;
1298  const AVChannelLayout *layout = &track->par->ch_layout;
1299 
1301  if (ret || !config) {
1302  config = 0;
1303  speaker_pos = av_malloc(layout->nb_channels);
1304  if (!speaker_pos)
1305  return AVERROR(ENOMEM);
1307  speaker_pos, layout->nb_channels);
1308  if (ret) {
1309  char buf[128] = {0};
1310 
1311  av_freep(&speaker_pos);
1312  av_channel_layout_describe(layout, buf, sizeof(buf));
1313  av_log(s, AV_LOG_ERROR, "unsupported channel layout %s\n", buf);
1314  return ret;
1315  }
1316  }
1317 
1318  avio_wb32(pb, 0); /* size */
1319  ffio_wfourcc(pb, "chnl");
1320  avio_wb32(pb, 0); /* version & flags */
1321 
1322  avio_w8(pb, 1); /* stream_structure */
1323  avio_w8(pb, config);
1324  if (config) {
1325  avio_wb64(pb, 0);
1326  } else {
1327  avio_write(pb, speaker_pos, layout->nb_channels);
1328  av_freep(&speaker_pos);
1329  }
1330 
1331  return update_size(pb, pos);
1332 }
1333 
1335 {
1336  int64_t pos = avio_tell(pb);
1337  int format_flags;
1338  int sample_size;
1339 
1340  avio_wb32(pb, 0); /* size */
1341  ffio_wfourcc(pb, "pcmC");
1342  avio_wb32(pb, 0); /* version & flags */
1343 
1344  /* 0x01: indicates little-endian format */
1345  format_flags = (track->par->codec_id == AV_CODEC_ID_PCM_F32LE ||
1346  track->par->codec_id == AV_CODEC_ID_PCM_F64LE ||
1347  track->par->codec_id == AV_CODEC_ID_PCM_S16LE ||
1348  track->par->codec_id == AV_CODEC_ID_PCM_S24LE ||
1349  track->par->codec_id == AV_CODEC_ID_PCM_S32LE);
1350  avio_w8(pb, format_flags);
1351  sample_size = track->par->bits_per_raw_sample;
1352  if (!sample_size)
1353  sample_size = av_get_exact_bits_per_sample(track->par->codec_id);
1354  av_assert0(sample_size);
1355  avio_w8(pb, sample_size);
1356 
1357  return update_size(pb, pos);
1358 }
1359 
1360 static int mov_write_srat_tag(AVIOContext *pb, MOVTrack *track)
1361 {
1362  int64_t pos = avio_tell(pb);
1363  avio_wb32(pb, 0); /* size */
1364  ffio_wfourcc(pb, "srat");
1365  avio_wb32(pb, 0); /* version & flags */
1366 
1367  avio_wb32(pb, track->par->sample_rate);
1368 
1369  return update_size(pb, pos);
1370 }
1371 
1373 {
1374  int64_t pos = avio_tell(pb);
1375  int version = 0;
1376  uint32_t tag = track->tag;
1377  int ret = 0;
1378 
1379  if (track->mode == MODE_MOV) {
1380  if (track->timescale > UINT16_MAX || !track->par->ch_layout.nb_channels) {
1381  if (mov_get_lpcm_flags(track->par->codec_id))
1382  tag = AV_RL32("lpcm");
1383  version = 2;
1384  } else if (track->audio_vbr || mov_pcm_le_gt16(track->par->codec_id) ||
1385  mov_pcm_be_gt16(track->par->codec_id) ||
1386  track->par->codec_id == AV_CODEC_ID_ADPCM_MS ||
1387  track->par->codec_id == AV_CODEC_ID_ADPCM_IMA_WAV ||
1388  track->par->codec_id == AV_CODEC_ID_QDM2) {
1389  version = 1;
1390  }
1391  } else if (track->mode == MODE_MP4) {
1392  if (track->par->sample_rate > UINT16_MAX &&
1394  version = 1;
1395  }
1396 
1397  avio_wb32(pb, 0); /* size */
1398  if (mov->encryption_scheme != MOV_ENC_NONE) {
1399  ffio_wfourcc(pb, "enca");
1400  } else {
1401  avio_wl32(pb, tag); // store it byteswapped
1402  }
1403  avio_wb32(pb, 0); /* Reserved */
1404  avio_wb16(pb, 0); /* Reserved */
1405  avio_wb16(pb, 1); /* Data-reference index, XXX == 1 */
1406 
1407  /* SoundDescription */
1408  avio_wb16(pb, version); /* Version */
1409  avio_wb16(pb, 0); /* Revision level */
1410  avio_wb32(pb, 0); /* Reserved */
1411 
1412  if (version == 2) {
1413  avio_wb16(pb, 3);
1414  avio_wb16(pb, 16);
1415  avio_wb16(pb, 0xfffe);
1416  avio_wb16(pb, 0);
1417  avio_wb32(pb, 0x00010000);
1418  avio_wb32(pb, 72);
1419  avio_wb64(pb, av_double2int(track->par->sample_rate));
1420  avio_wb32(pb, track->par->ch_layout.nb_channels);
1421  avio_wb32(pb, 0x7F000000);
1423  avio_wb32(pb, mov_get_lpcm_flags(track->par->codec_id));
1424  avio_wb32(pb, track->sample_size);
1425  avio_wb32(pb, get_samples_per_packet(track));
1426  } else {
1427  unsigned sample_rate = track->par->sample_rate;
1428 
1429  if (track->mode == MODE_MOV) {
1430  avio_wb16(pb, track->par->ch_layout.nb_channels);
1431  if (track->par->codec_id == AV_CODEC_ID_PCM_U8 ||
1432  track->par->codec_id == AV_CODEC_ID_PCM_S8)
1433  avio_wb16(pb, 8); /* bits per sample */
1434  else if (track->par->codec_id == AV_CODEC_ID_ADPCM_G726)
1435  avio_wb16(pb, track->par->bits_per_coded_sample);
1436  else
1437  avio_wb16(pb, 16);
1438  avio_wb16(pb, track->audio_vbr ? -2 : 0); /* compression ID */
1439  } else { /* reserved for mp4/3gp */
1440  avio_wb16(pb, track->tag == MKTAG('i', 'a', 'm', 'f') ?
1441  0 : track->par->ch_layout.nb_channels);
1442  if (track->par->codec_id == AV_CODEC_ID_FLAC ||
1443  track->par->codec_id == AV_CODEC_ID_ALAC) {
1444  avio_wb16(pb, track->par->bits_per_raw_sample);
1445  } else {
1446  avio_wb16(pb, 16);
1447  }
1448  avio_wb16(pb, 0);
1449 
1450  while (sample_rate > UINT16_MAX)
1451  sample_rate >>= 1;
1452  }
1453 
1454  avio_wb16(pb, 0); /* packet size (= 0) */
1455  if (track->tag == MKTAG('i','a','m','f'))
1456  avio_wb16(pb, 0); /* samplerate must be 0 for IAMF */
1457  else if (track->par->codec_id == AV_CODEC_ID_OPUS)
1458  avio_wb16(pb, 48000);
1459  else if (track->par->codec_id == AV_CODEC_ID_TRUEHD)
1460  avio_wb32(pb, track->par->sample_rate);
1461  else
1462  avio_wb16(pb, sample_rate);
1463 
1464  if (track->par->codec_id != AV_CODEC_ID_TRUEHD)
1465  avio_wb16(pb, 0); /* Reserved */
1466  }
1467 
1468  if (track->mode == MODE_MOV && version == 1) { /* SoundDescription V1 extended info */
1469  if (mov_pcm_le_gt16(track->par->codec_id) ||
1470  mov_pcm_be_gt16(track->par->codec_id))
1471  avio_wb32(pb, 1); /* must be 1 for uncompressed formats */
1472  else
1473  avio_wb32(pb, track->par->frame_size); /* Samples per packet */
1474  avio_wb32(pb, track->sample_size / track->par->ch_layout.nb_channels); /* Bytes per packet */
1475  avio_wb32(pb, track->sample_size); /* Bytes per frame */
1476  avio_wb32(pb, 2); /* Bytes per sample */
1477  }
1478 
1479  if (track->mode == MODE_MOV &&
1480  (track->par->codec_id == AV_CODEC_ID_AAC ||
1481  track->par->codec_id == AV_CODEC_ID_AC3 ||
1482  track->par->codec_id == AV_CODEC_ID_EAC3 ||
1483  track->par->codec_id == AV_CODEC_ID_AMR_NB ||
1484  track->par->codec_id == AV_CODEC_ID_ALAC ||
1485  track->par->codec_id == AV_CODEC_ID_ADPCM_MS ||
1486  track->par->codec_id == AV_CODEC_ID_ADPCM_IMA_WAV ||
1487  track->par->codec_id == AV_CODEC_ID_QDM2 ||
1488  (mov_pcm_le_gt16(track->par->codec_id) && version==1) ||
1489  (mov_pcm_be_gt16(track->par->codec_id) && version==1)))
1490  ret = mov_write_wave_tag(s, pb, track);
1491  else if (track->tag == MKTAG('m','p','4','a'))
1492  ret = mov_write_esds_tag(pb, track);
1493 #if CONFIG_IAMFENC
1494  else if (track->tag == MKTAG('i','a','m','f'))
1495  ret = mov_write_iacb_tag(mov->fc, pb, track);
1496 #endif
1497  else if (track->par->codec_id == AV_CODEC_ID_AMR_NB)
1498  ret = mov_write_amr_tag(pb, track);
1499  else if (track->par->codec_id == AV_CODEC_ID_AC3)
1500  ret = mov_write_ac3_tag(s, pb, track);
1501  else if (track->par->codec_id == AV_CODEC_ID_EAC3)
1502  ret = mov_write_eac3_tag(s, pb, track);
1503  else if (track->par->codec_id == AV_CODEC_ID_ALAC)
1504  ret = mov_write_extradata_tag(pb, track);
1505  else if (track->par->codec_id == AV_CODEC_ID_WMAPRO)
1506  ret = mov_write_wfex_tag(s, pb, track);
1507  else if (track->par->codec_id == AV_CODEC_ID_FLAC)
1508  ret = mov_write_dfla_tag(pb, track);
1509  else if (track->par->codec_id == AV_CODEC_ID_OPUS)
1510  ret = mov_write_dops_tag(s, pb, track);
1511  else if (track->par->codec_id == AV_CODEC_ID_TRUEHD)
1512  ret = mov_write_dmlp_tag(s, pb, track);
1513  else if (tag == MOV_MP4_IPCM_TAG || tag == MOV_MP4_FPCM_TAG) {
1514  if (track->par->sample_rate > UINT16_MAX)
1515  mov_write_srat_tag(pb, track);
1516  if (track->par->ch_layout.nb_channels > 1)
1517  ret = mov_write_chnl_tag(s, pb, track);
1518  if (ret < 0)
1519  return ret;
1520  ret = mov_write_pcmc_tag(s, pb, track);
1521  } else if (track->extradata_size[track->last_stsd_index] > 0)
1522  ret = mov_write_glbl_tag(pb, track);
1523 
1524  if (ret < 0)
1525  return ret;
1526 
1527  if (track->mode == MODE_MP4 && track->par->codec_type == AVMEDIA_TYPE_AUDIO
1528  && ((ret = mov_write_SA3D_tag(s, pb, track)) < 0)) {
1529  return ret;
1530  }
1531 
1532  if (track->mode == MODE_MOV && track->par->codec_type == AVMEDIA_TYPE_AUDIO
1533  && ((ret = mov_write_chan_tag(s, pb, track)) < 0)) {
1534  return ret;
1535  }
1536 
1537  if (mov->encryption_scheme != MOV_ENC_NONE
1538  && ((ret = ff_mov_cenc_write_sinf_tag(track, pb, mov->encryption_kid)) < 0)) {
1539  return ret;
1540  }
1541 
1542  if (mov->write_btrt &&
1543  ((ret = mov_write_btrt_tag(pb, track)) < 0))
1544  return ret;
1545 
1546  if (track->mode == MODE_MP4)
1547  track->entry_version = version;
1548 
1549  ret = update_size(pb, pos);
1550  return ret;
1551 }
1552 
1554 {
1555  avio_wb32(pb, 0xf); /* size */
1556  ffio_wfourcc(pb, "d263");
1557  ffio_wfourcc(pb, "FFMP");
1558  avio_w8(pb, 0); /* decoder version */
1559  /* FIXME use AVCodecContext level/profile, when encoder will set values */
1560  avio_w8(pb, 0xa); /* level */
1561  avio_w8(pb, 0); /* profile */
1562  return 0xf;
1563 }
1564 
1565 static int mov_write_av1c_tag(AVIOContext *pb, MOVTrack *track)
1566 {
1567  int64_t pos = avio_tell(pb);
1568 
1569  avio_wb32(pb, 0);
1570  ffio_wfourcc(pb, "av1C");
1571  ff_isom_write_av1c(pb, track->extradata[track->last_stsd_index],
1572  track->extradata_size[track->last_stsd_index], track->mode != MODE_AVIF);
1573  return update_size(pb, pos);
1574 }
1575 
1576 static int mov_write_avcc_tag(AVIOContext *pb, MOVTrack *track)
1577 {
1578  int64_t pos = avio_tell(pb);
1579 
1580  avio_wb32(pb, 0);
1581  ffio_wfourcc(pb, "avcC");
1582  ff_isom_write_avcc(pb, track->extradata[track->last_stsd_index],
1583  track->extradata_size[track->last_stsd_index]);
1584  return update_size(pb, pos);
1585 }
1586 
1587 /* AVS3 Intelligent Media Coding
1588  * Information Technology - Intelligent Media Coding
1589  * Part 6: Intelligent Media Format
1590  */
1591 static int mov_write_av3c(AVIOContext *pb, const uint8_t *data, int len)
1592 {
1593  if (len < 4)
1594  return AVERROR_INVALIDDATA;
1595 
1596  if (data[0] == 1) {
1597  // In Avs3DecoderConfigurationRecord format
1598  avio_write(pb, data, len);
1599  return 0;
1600  }
1601 
1602  avio_w8(pb, 1); // version
1603  avio_wb16(pb, len); // sequence_header_length
1604  avio_write(pb, data, len); // sequence_header
1605  avio_w8(pb, 0xFC); // Only support library_dependency_idc = 0
1606 
1607  return 0;
1608 }
1609 
1610 static int mov_write_av3c_tag(AVIOContext *pb, MOVTrack *track)
1611 {
1612  int64_t pos = avio_tell(pb);
1613  avio_wb32(pb, 0);
1614  ffio_wfourcc(pb, "av3c");
1615  mov_write_av3c(pb, track->extradata[track->last_stsd_index],
1616  track->extradata_size[track->last_stsd_index]);
1617  return update_size(pb, pos);
1618 }
1619 
1621 {
1622  int64_t pos = avio_tell(pb);
1623 
1624  avio_wb32(pb, 0);
1625  ffio_wfourcc(pb, "vpcC");
1626  ff_isom_write_vpcc(s, pb, track->extradata[track->last_stsd_index],
1627  track->extradata_size[track->last_stsd_index], track->par);
1628  return update_size(pb, pos);
1629 }
1630 
1632 {
1633  int64_t pos = avio_tell(pb);
1634 
1635  avio_wb32(pb, 0);
1636  ffio_wfourcc(pb, "hvcC");
1637  if (track->tag == MKTAG('h','v','c','1'))
1638  ff_isom_write_hvcc(pb, track->extradata[track->last_stsd_index],
1639  track->extradata_size[track->last_stsd_index], 1, s);
1640  else
1641  ff_isom_write_hvcc(pb, track->extradata[track->last_stsd_index],
1642  track->extradata_size[track->last_stsd_index], 0, s);
1643  return update_size(pb, pos);
1644 }
1645 
1647 {
1648  int64_t pos = avio_tell(pb);
1649  int ret;
1650 
1651  avio_wb32(pb, 0);
1652  ffio_wfourcc(pb, "lhvC");
1653  if (track->tag == MKTAG('h','v','c','1'))
1654  ret = ff_isom_write_lhvc(pb, track->extradata[track->last_stsd_index],
1655  track->extradata_size[track->last_stsd_index], 1, s);
1656  else
1657  ret = ff_isom_write_lhvc(pb, track->extradata[track->last_stsd_index],
1658  track->extradata_size[track->last_stsd_index], 0, s);
1659 
1660  if (ret < 0) {
1661  avio_seek(pb, pos, SEEK_SET);
1662  return ret;
1663  }
1664 
1665  return update_size(pb, pos);
1666 }
1667 
1668 static int mov_write_evcc_tag(AVIOContext *pb, MOVTrack *track)
1669 {
1670  int64_t pos = avio_tell(pb);
1671 
1672  avio_wb32(pb, 0);
1673  ffio_wfourcc(pb, "evcC");
1674 
1675  if (track->tag == MKTAG('e','v','c','1'))
1676  ff_isom_write_evcc(pb, track->extradata[track->last_stsd_index],
1677  track->extradata_size[track->last_stsd_index], 1);
1678  else
1679  ff_isom_write_evcc(pb, track->extradata[track->last_stsd_index],
1680  track->extradata_size[track->last_stsd_index], 0);
1681 
1682  return update_size(pb, pos);
1683 }
1684 
1685 static int mov_write_lvcc_tag(AVIOContext *pb, MOVTrack *track)
1686 {
1687  int64_t pos = avio_tell(pb);
1688 
1689  avio_wb32(pb, 0);
1690  ffio_wfourcc(pb, "lvcC");
1691 
1692  ff_isom_write_lvcc(pb, track->extradata[track->last_stsd_index],
1693  track->extradata_size[track->last_stsd_index]);
1694 
1695  return update_size(pb, pos);
1696 }
1697 
1698 static int mov_write_vvcc_tag(AVIOContext *pb, MOVTrack *track)
1699 {
1700  int64_t pos = avio_tell(pb);
1701 
1702  avio_wb32(pb, 0);
1703  ffio_wfourcc(pb, "vvcC");
1704 
1705  avio_w8 (pb, 0); /* version */
1706  avio_wb24(pb, 0); /* flags */
1707 
1708  if (track->tag == MKTAG('v','v','c','1'))
1709  ff_isom_write_vvcc(pb, track->extradata[track->last_stsd_index],
1710  track->extradata_size[track->last_stsd_index], 1);
1711  else
1712  ff_isom_write_vvcc(pb, track->extradata[track->last_stsd_index],
1713  track->extradata_size[track->last_stsd_index], 0);
1714  return update_size(pb, pos);
1715 }
1716 
1718 {
1719  int64_t pos = avio_tell(pb);
1720 
1721  avio_wb32(pb, 0);
1722  ffio_wfourcc(pb, "apvC");
1723 
1724  avio_w8 (pb, 0); /* version */
1725  avio_wb24(pb, 0); /* flags */
1726 
1727  ff_isom_write_apvc(pb, track->apv, s);
1728 
1729  return update_size(pb, pos);
1730 }
1731 
1732 /* also used by all avid codecs (dv, imx, meridien) and their variants */
1733 /* https://community.avid.com/forums/t/136517.aspx */
1734 static int mov_write_avid_tag(AVIOContext *pb, MOVTrack *track)
1735 {
1736  int interlaced;
1737  int cid;
1738  int display_width = track->par->width;
1739  const uint8_t *extradata;
1740 
1741  if (track->extradata[track->last_stsd_index] && track->extradata_size[track->last_stsd_index] > 0x29) {
1742  if (ff_dnxhd_parse_header_prefix(track->extradata[track->last_stsd_index]) != 0) {
1743  /* looks like a DNxHD bit stream */
1744  extradata = track->extradata[track->last_stsd_index];
1745  } else {
1746  av_log(NULL, AV_LOG_WARNING, "Could not locate DNxHD bit stream in vos_data\n");
1747  return 0;
1748  }
1749  } else {
1750  av_log(NULL, AV_LOG_WARNING, "Could not locate DNxHD bit stream, vos_data too small\n");
1751  return 0;
1752  }
1753 
1754  cid = AV_RB32(extradata + 0x28);
1755 
1756  avio_wb32(pb, 24); /* size */
1757  ffio_wfourcc(pb, "ACLR");
1758  ffio_wfourcc(pb, "ACLR");
1759  ffio_wfourcc(pb, "0001");
1760  // 1: CCIR (supercolors will be dropped, 16 will be displayed as black)
1761  // 2: FullRange (0 will be displayed as black, 16 will be displayed as dark grey)
1762  if (track->par->color_range == AVCOL_RANGE_MPEG || /* Legal range (16-235) */
1764  avio_wb32(pb, 1);
1765  } else {
1766  avio_wb32(pb, 2);
1767  }
1768  avio_wb32(pb, 0); /* reserved */
1769 
1770  if (track->tag == MKTAG('A','V','d','h')) {
1771  int alp = extradata[0x07] & 1;
1772  int pma = (extradata[0x07] >> 2) & 1;
1773  int sbd = (extradata[0x21] >> 5) & 3;
1774  int ssc = (extradata[0x2C] >> 5) & 3;
1775  int clv = (extradata[0x2C] >> 1) & 3;
1776  int clf = extradata[0x2C] & 1;
1777 
1778  avio_wb32(pb, 32);
1779  ffio_wfourcc(pb, "ADHR");
1780  ffio_wfourcc(pb, "0001");
1781  avio_wb32(pb, cid); // Compression ID
1782  // 0: 4:2:2 Sub Sampling
1783  // 1: 4:2:0 Sub Sampling
1784  // 2: 4:4:4 Sub Sampling
1785  avio_wb32(pb, ssc); // Sub Sampling Control
1786  // 1: 8-bits per sample
1787  // 2: 10-bits per sample
1788  // 3: 12-bits per sample
1789  avio_wb32(pb, sbd); // Sample Bit Depth
1790  // 0: Bitstream is encoded using the YCBCR format rules and tables
1791  // 1: Bitstream is encoded using the RGB format rules and tables – only Compression IDs 1256, 1270
1792  avio_wb16(pb, clf); // Color Format
1793  // 0: ITU-R BT.709
1794  // 1: ITU-R BT.2020
1795  // 2: ITU-R BT.2020 C
1796  // 3: Out-of-band
1797  avio_wb16(pb, clv); // Color Volume
1798  // 0: Alpha channel not present
1799  // 1: Alpha channel present
1800  avio_wb16(pb, alp); // Alpha Present
1801  // 0: Alpha has not been applied to video channels
1802  // 1: Alpha has been applied to the video channels prior to encoding
1803  avio_wb16(pb, pma); // Pre-Multiplied Alpha
1804  return 0;
1805  }
1806 
1807  interlaced = extradata[5] & 2;
1808 
1809  avio_wb32(pb, 24); /* size */
1810  ffio_wfourcc(pb, "APRG");
1811  ffio_wfourcc(pb, "APRG");
1812  ffio_wfourcc(pb, "0001");
1813  // 1 for progressive or 2 for interlaced
1814  if (interlaced)
1815  avio_wb32(pb, 2);
1816  else
1817  avio_wb32(pb, 1);
1818  avio_wb32(pb, 0); /* reserved */
1819 
1820  avio_wb32(pb, 120); /* size */
1821  ffio_wfourcc(pb, "ARES");
1822  ffio_wfourcc(pb, "ARES");
1823  ffio_wfourcc(pb, "0001");
1824  avio_wb32(pb, cid); /* cid */
1825  if ( track->par->sample_aspect_ratio.num > 0
1826  && track->par->sample_aspect_ratio.den > 0)
1827  display_width = display_width * track->par->sample_aspect_ratio.num / track->par->sample_aspect_ratio.den;
1828  avio_wb32(pb, display_width); // field width
1829  if (interlaced) {
1830  avio_wb32(pb, track->par->height / 2); // field height
1831  avio_wb32(pb, 2); // num fields
1832  avio_wb32(pb, 0); // num black lines (must be 0)
1833  // 4: HD1080i
1834  // 5: HD1080P
1835  // 6: HD720P
1836  avio_wb32(pb, 4); // video format
1837  } else {
1838  avio_wb32(pb, track->par->height);
1839  avio_wb32(pb, 1); // num fields
1840  avio_wb32(pb, 0);
1841  if (track->par->height == 1080)
1842  avio_wb32(pb, 5);
1843  else
1844  avio_wb32(pb, 6);
1845  }
1846  /* padding */
1847  ffio_fill(pb, 0, 10 * 8);
1848 
1849  return 0;
1850 }
1851 
1852 static int mov_write_dpxe_tag(AVIOContext *pb, MOVTrack *track)
1853 {
1854  avio_wb32(pb, 12);
1855  ffio_wfourcc(pb, "DpxE");
1856  if (track->extradata_size[track->last_stsd_index] >= 12 &&
1857  !memcmp(&track->extradata[track->last_stsd_index][4], "DpxE", 4)) {
1858  avio_wb32(pb, track->extradata[track->last_stsd_index][11]);
1859  } else {
1860  avio_wb32(pb, 1);
1861  }
1862  return 0;
1863 }
1864 
1866 {
1867  int tag;
1868 
1869  if (track->par->width == 720) { /* SD */
1870  if (track->par->height == 480) { /* NTSC */
1871  if (track->par->format == AV_PIX_FMT_YUV422P) tag = MKTAG('d','v','5','n');
1872  else tag = MKTAG('d','v','c',' ');
1873  }else if (track->par->format == AV_PIX_FMT_YUV422P) tag = MKTAG('d','v','5','p');
1874  else if (track->par->format == AV_PIX_FMT_YUV420P) tag = MKTAG('d','v','c','p');
1875  else tag = MKTAG('d','v','p','p');
1876  } else if (track->par->height == 720) { /* HD 720 line */
1877  if (track->st->time_base.den == 50) tag = MKTAG('d','v','h','q');
1878  else tag = MKTAG('d','v','h','p');
1879  } else if (track->par->height == 1080) { /* HD 1080 line */
1880  if (track->st->time_base.den == 25) tag = MKTAG('d','v','h','5');
1881  else tag = MKTAG('d','v','h','6');
1882  } else {
1883  av_log(s, AV_LOG_ERROR, "unsupported height for dv codec\n");
1884  return 0;
1885  }
1886 
1887  return tag;
1888 }
1889 
1891 {
1892  AVRational rational_framerate = st->avg_frame_rate;
1893  int rate = 0;
1894  if (rational_framerate.den != 0)
1895  rate = av_q2d(rational_framerate);
1896  return rate;
1897 }
1898 
1900 {
1901  int tag = track->par->codec_tag;
1903  AVStream *st = track->st;
1904  int rate = defined_frame_rate(s, st);
1905 
1906  if (!tag)
1907  tag = MKTAG('m', '2', 'v', '1'); //fallback tag
1908 
1909  if (track->par->format == AV_PIX_FMT_YUV420P) {
1910  if (track->par->width == 1280 && track->par->height == 720) {
1911  if (!interlaced) {
1912  if (rate == 24) tag = MKTAG('x','d','v','4');
1913  else if (rate == 25) tag = MKTAG('x','d','v','5');
1914  else if (rate == 30) tag = MKTAG('x','d','v','1');
1915  else if (rate == 50) tag = MKTAG('x','d','v','a');
1916  else if (rate == 60) tag = MKTAG('x','d','v','9');
1917  }
1918  } else if (track->par->width == 1440 && track->par->height == 1080) {
1919  if (!interlaced) {
1920  if (rate == 24) tag = MKTAG('x','d','v','6');
1921  else if (rate == 25) tag = MKTAG('x','d','v','7');
1922  else if (rate == 30) tag = MKTAG('x','d','v','8');
1923  } else {
1924  if (rate == 25) tag = MKTAG('x','d','v','3');
1925  else if (rate == 30) tag = MKTAG('x','d','v','2');
1926  }
1927  } else if (track->par->width == 1920 && track->par->height == 1080) {
1928  if (!interlaced) {
1929  if (rate == 24) tag = MKTAG('x','d','v','d');
1930  else if (rate == 25) tag = MKTAG('x','d','v','e');
1931  else if (rate == 30) tag = MKTAG('x','d','v','f');
1932  } else {
1933  if (rate == 25) tag = MKTAG('x','d','v','c');
1934  else if (rate == 30) tag = MKTAG('x','d','v','b');
1935  }
1936  }
1937  } else if (track->par->format == AV_PIX_FMT_YUV422P) {
1938  if (track->par->width == 1280 && track->par->height == 720) {
1939  if (!interlaced) {
1940  if (rate == 24) tag = MKTAG('x','d','5','4');
1941  else if (rate == 25) tag = MKTAG('x','d','5','5');
1942  else if (rate == 30) tag = MKTAG('x','d','5','1');
1943  else if (rate == 50) tag = MKTAG('x','d','5','a');
1944  else if (rate == 60) tag = MKTAG('x','d','5','9');
1945  }
1946  } else if (track->par->width == 1920 && track->par->height == 1080) {
1947  if (!interlaced) {
1948  if (rate == 24) tag = MKTAG('x','d','5','d');
1949  else if (rate == 25) tag = MKTAG('x','d','5','e');
1950  else if (rate == 30) tag = MKTAG('x','d','5','f');
1951  } else {
1952  if (rate == 25) tag = MKTAG('x','d','5','c');
1953  else if (rate == 30) tag = MKTAG('x','d','5','b');
1954  }
1955  }
1956  }
1957 
1958  return tag;
1959 }
1960 
1962 {
1963  int tag = track->par->codec_tag;
1965  AVStream *st = track->st;
1966  int rate = defined_frame_rate(s, st);
1967 
1968  if (!tag)
1969  tag = MKTAG('a', 'v', 'c', 'i'); //fallback tag
1970 
1971  if (track->par->profile == AV_PROFILE_UNKNOWN ||
1972  !(track->par->profile & AV_PROFILE_H264_INTRA))
1973  return tag;
1974 
1975  if (track->par->format == AV_PIX_FMT_YUV420P10) {
1976  if (track->par->width == 960 && track->par->height == 720) {
1977  if (!interlaced) {
1978  if (rate == 24) tag = MKTAG('a','i','5','p');
1979  else if (rate == 25) tag = MKTAG('a','i','5','q');
1980  else if (rate == 30) tag = MKTAG('a','i','5','p');
1981  else if (rate == 50) tag = MKTAG('a','i','5','q');
1982  else if (rate == 60) tag = MKTAG('a','i','5','p');
1983  }
1984  } else if (track->par->width == 1440 && track->par->height == 1080) {
1985  if (!interlaced) {
1986  if (rate == 24) tag = MKTAG('a','i','5','3');
1987  else if (rate == 25) tag = MKTAG('a','i','5','2');
1988  else if (rate == 30) tag = MKTAG('a','i','5','3');
1989  } else {
1990  if (rate == 50) tag = MKTAG('a','i','5','5');
1991  else if (rate == 60) tag = MKTAG('a','i','5','6');
1992  }
1993  }
1994  } else if (track->par->format == AV_PIX_FMT_YUV422P10) {
1995  if (track->par->width == 1280 && track->par->height == 720) {
1996  if (!interlaced) {
1997  if (rate == 24) tag = MKTAG('a','i','1','p');
1998  else if (rate == 25) tag = MKTAG('a','i','1','q');
1999  else if (rate == 30) tag = MKTAG('a','i','1','p');
2000  else if (rate == 50) tag = MKTAG('a','i','1','q');
2001  else if (rate == 60) tag = MKTAG('a','i','1','p');
2002  }
2003  } else if (track->par->width == 1920 && track->par->height == 1080) {
2004  if (!interlaced) {
2005  if (rate == 24) tag = MKTAG('a','i','1','3');
2006  else if (rate == 25) tag = MKTAG('a','i','1','2');
2007  else if (rate == 30) tag = MKTAG('a','i','1','3');
2008  } else {
2009  if (rate == 25) tag = MKTAG('a','i','1','5');
2010  else if (rate == 50) tag = MKTAG('a','i','1','5');
2011  else if (rate == 60) tag = MKTAG('a','i','1','6');
2012  }
2013  } else if ( track->par->width == 4096 && track->par->height == 2160
2014  || track->par->width == 3840 && track->par->height == 2160
2015  || track->par->width == 2048 && track->par->height == 1080) {
2016  tag = MKTAG('a','i','v','x');
2017  }
2018  }
2019 
2020  return tag;
2021 }
2022 
2024 {
2025  int tag = track->par->codec_tag;
2026 
2027  if (!tag)
2028  tag = MKTAG('e', 'v', 'c', '1');
2029 
2030  return tag;
2031 }
2032 
2034 {
2035  int tag = track->par->codec_tag;
2036 
2037  if (!tag)
2038  tag = MKTAG('a', 'p', 'v', '1');
2039 
2040  return tag;
2041 }
2042 
2043 
2044 static const struct {
2046  uint32_t tag;
2047  unsigned bps;
2048 } mov_pix_fmt_tags[] = {
2049  { AV_PIX_FMT_YUYV422, MKTAG('y','u','v','2'), 0 },
2050  { AV_PIX_FMT_YUYV422, MKTAG('y','u','v','s'), 0 },
2051  { AV_PIX_FMT_UYVY422, MKTAG('2','v','u','y'), 0 },
2052  { AV_PIX_FMT_VYU444, MKTAG('v','3','0','8'), 0 },
2053  { AV_PIX_FMT_UYVA, MKTAG('v','4','0','8'), 0 },
2054  { AV_PIX_FMT_V30XLE, MKTAG('v','4','1','0'), 0 },
2055  { AV_PIX_FMT_RGB555BE,MKTAG('r','a','w',' '), 16 },
2056  { AV_PIX_FMT_RGB555LE,MKTAG('L','5','5','5'), 16 },
2057  { AV_PIX_FMT_RGB565LE,MKTAG('L','5','6','5'), 16 },
2058  { AV_PIX_FMT_RGB565BE,MKTAG('B','5','6','5'), 16 },
2059  { AV_PIX_FMT_GRAY16BE,MKTAG('b','1','6','g'), 16 },
2060  { AV_PIX_FMT_RGB24, MKTAG('r','a','w',' '), 24 },
2061  { AV_PIX_FMT_BGR24, MKTAG('2','4','B','G'), 24 },
2062  { AV_PIX_FMT_ARGB, MKTAG('r','a','w',' '), 32 },
2063  { AV_PIX_FMT_BGRA, MKTAG('B','G','R','A'), 32 },
2064  { AV_PIX_FMT_RGBA, MKTAG('R','G','B','A'), 32 },
2065  { AV_PIX_FMT_ABGR, MKTAG('A','B','G','R'), 32 },
2066  { AV_PIX_FMT_RGB48BE, MKTAG('b','4','8','r'), 48 },
2067 };
2068 
2070 {
2071  int tag = MKTAG('A','V','d','n');
2072  if (track->par->profile != AV_PROFILE_UNKNOWN &&
2073  track->par->profile != AV_PROFILE_DNXHD)
2074  tag = MKTAG('A','V','d','h');
2075  return tag;
2076 }
2077 
2079 {
2080  int tag = track->par->codec_tag;
2081  int i;
2082  enum AVPixelFormat pix_fmt;
2083 
2084  for (i = 0; i < FF_ARRAY_ELEMS(mov_pix_fmt_tags); i++) {
2085  if (track->par->format == mov_pix_fmt_tags[i].pix_fmt) {
2086  tag = mov_pix_fmt_tags[i].tag;
2088  if (track->par->codec_tag == mov_pix_fmt_tags[i].tag)
2089  break;
2090  }
2091  }
2092 
2094  track->par->bits_per_coded_sample);
2095  if (tag == MKTAG('r','a','w',' ') &&
2096  track->par->format != pix_fmt &&
2097  track->par->format != AV_PIX_FMT_GRAY8 &&
2098  track->par->format != AV_PIX_FMT_NONE)
2099  av_log(s, AV_LOG_ERROR, "%s rawvideo cannot be written to mov, output file will be unreadable\n",
2100  av_get_pix_fmt_name(track->par->format));
2101  return tag;
2102 }
2103 
2104 static unsigned int mov_get_codec_tag(AVFormatContext *s, MOVTrack *track)
2105 {
2106  unsigned int tag = track->par->codec_tag;
2107 
2108  // "rtp " is used to distinguish internally created RTP-hint tracks
2109  // (with rtp_ctx) from other tracks.
2110  if (tag == MKTAG('r','t','p',' '))
2111  tag = 0;
2112  if (!tag || (s->strict_std_compliance >= FF_COMPLIANCE_NORMAL &&
2113  (track->par->codec_id == AV_CODEC_ID_DVVIDEO ||
2114  track->par->codec_id == AV_CODEC_ID_RAWVIDEO ||
2115  track->par->codec_id == AV_CODEC_ID_H263 ||
2116  track->par->codec_id == AV_CODEC_ID_H264 ||
2117  track->par->codec_id == AV_CODEC_ID_DNXHD ||
2118  track->par->codec_id == AV_CODEC_ID_MPEG2VIDEO ||
2119  av_get_bits_per_sample(track->par->codec_id)))) { // pcm audio
2120  if (track->par->codec_id == AV_CODEC_ID_DVVIDEO)
2121  tag = mov_get_dv_codec_tag(s, track);
2122  else if (track->par->codec_id == AV_CODEC_ID_RAWVIDEO)
2123  tag = mov_get_rawvideo_codec_tag(s, track);
2124  else if (track->par->codec_id == AV_CODEC_ID_MPEG2VIDEO)
2126  else if (track->par->codec_id == AV_CODEC_ID_H264)
2127  tag = mov_get_h264_codec_tag(s, track);
2128  else if (track->par->codec_id == AV_CODEC_ID_EVC)
2129  tag = mov_get_evc_codec_tag(s, track);
2130  else if (track->par->codec_id == AV_CODEC_ID_APV)
2131  tag = mov_get_apv_codec_tag(s, track);
2132  else if (track->par->codec_id == AV_CODEC_ID_DNXHD)
2133  tag = mov_get_dnxhd_codec_tag(s, track);
2134  else if (track->par->codec_type == AVMEDIA_TYPE_VIDEO) {
2136  if (!tag) { // if no mac fcc found, try with Microsoft tags
2138  if (tag)
2139  av_log(s, AV_LOG_WARNING, "Using MS style video codec tag, "
2140  "the file may be unplayable!\n");
2141  }
2142  } else if (track->par->codec_type == AVMEDIA_TYPE_AUDIO) {
2144  if (!tag) { // if no mac fcc found, try with Microsoft tags
2145  int ms_tag = ff_codec_get_tag(ff_codec_wav_tags, track->par->codec_id);
2146  if (ms_tag) {
2147  tag = MKTAG('m', 's', ((ms_tag >> 8) & 0xff), (ms_tag & 0xff));
2148  av_log(s, AV_LOG_WARNING, "Using MS style audio codec tag, "
2149  "the file may be unplayable!\n");
2150  }
2151  }
2152  } else if (track->par->codec_type == AVMEDIA_TYPE_SUBTITLE)
2154  }
2155 
2156  return tag;
2157 }
2158 
2160  { AV_CODEC_ID_MJPEG, 0xD },
2161  { AV_CODEC_ID_PNG, 0xE },
2162  { AV_CODEC_ID_BMP, 0x1B },
2163  { AV_CODEC_ID_NONE, 0 },
2164 };
2165 
2166 static unsigned int validate_codec_tag(const AVCodecTag *const *tags,
2167  unsigned int tag, int codec_id)
2168 {
2169  int i;
2170 
2171  /**
2172  * Check that tag + id is in the table
2173  */
2174  for (i = 0; tags && tags[i]; i++) {
2175  const AVCodecTag *codec_tags = tags[i];
2176  while (codec_tags->id != AV_CODEC_ID_NONE) {
2177  if (ff_toupper4(codec_tags->tag) == ff_toupper4(tag) &&
2178  codec_tags->id == codec_id)
2179  return codec_tags->tag;
2180  codec_tags++;
2181  }
2182  }
2183  return 0;
2184 }
2185 
2186 static unsigned int mov_find_codec_tag(AVFormatContext *s, MOVTrack *track)
2187 {
2188  if (is_cover_image(track->st))
2190 
2191  if (track->mode == MODE_IPOD)
2192  if (!av_match_ext(s->url, "m4a") &&
2193  !av_match_ext(s->url, "m4v") &&
2194  !av_match_ext(s->url, "m4b"))
2195  av_log(s, AV_LOG_WARNING, "Warning, extension is not .m4a nor .m4v "
2196  "Quicktime/Ipod might not play the file\n");
2197 
2198  if (track->mode == MODE_MOV) {
2199  return mov_get_codec_tag(s, track);
2200  } else
2201  return validate_codec_tag(s->oformat->codec_tag, track->par->codec_tag,
2202  track->par->codec_id);
2203 }
2204 
2205 /** Write uuid atom.
2206  * Needed to make file play in iPods running newest firmware
2207  * goes after avcC atom in moov.trak.mdia.minf.stbl.stsd.avc1
2208  */
2210 {
2211  avio_wb32(pb, 28);
2212  ffio_wfourcc(pb, "uuid");
2213  avio_wb32(pb, 0x6b6840f2);
2214  avio_wb32(pb, 0x5f244fc5);
2215  avio_wb32(pb, 0xba39a51b);
2216  avio_wb32(pb, 0xcf0323f3);
2217  avio_wb32(pb, 0x0);
2218  return 28;
2219 }
2220 
2221 static const uint16_t fiel_data[] = {
2222  0x0000, 0x0100, 0x0201, 0x0206, 0x0209, 0x020e
2223 };
2224 
2225 static int mov_write_fiel_tag(AVIOContext *pb, MOVTrack *track, int field_order)
2226 {
2227  unsigned mov_field_order = 0;
2228  if (field_order < FF_ARRAY_ELEMS(fiel_data))
2229  mov_field_order = fiel_data[field_order];
2230  else
2231  return 0;
2232  avio_wb32(pb, 10);
2233  ffio_wfourcc(pb, "fiel");
2234  avio_wb16(pb, mov_field_order);
2235  return 10;
2236 }
2237 
2239 {
2240  MOVMuxContext *mov = s->priv_data;
2241  int ret = AVERROR_BUG;
2242  int64_t pos = avio_tell(pb);
2243  avio_wb32(pb, 0); /* size */
2244  avio_wl32(pb, track->tag); // store it byteswapped
2245  avio_wb32(pb, 0); /* Reserved */
2246  avio_wb16(pb, 0); /* Reserved */
2247  avio_wb16(pb, 1); /* Data-reference index */
2248 
2249  if (track->par->codec_id == AV_CODEC_ID_DVD_SUBTITLE)
2250  mov_write_esds_tag(pb, track);
2251  else if (track->par->codec_id == AV_CODEC_ID_TTML) {
2252  switch (track->par->codec_tag) {
2253  case MOV_ISMV_TTML_TAG:
2254  // ISMV dfxp requires no extradata.
2255  break;
2256  case MOV_MP4_TTML_TAG:
2257  // As specified in 14496-30, XMLSubtitleSampleEntry
2258  // Namespace
2259  avio_put_str(pb, "http://www.w3.org/ns/ttml");
2260  // Empty schema_location
2261  avio_w8(pb, 0);
2262  // Empty auxiliary_mime_types
2263  avio_w8(pb, 0);
2264  break;
2265  default:
2267  "Unknown codec tag '%s' utilized for TTML stream with "
2268  "index %d (track id %d)!\n",
2269  av_fourcc2str(track->par->codec_tag), track->st->index,
2270  track->track_id);
2271  return AVERROR(EINVAL);
2272  }
2273  } else if (track->extradata_size[track->last_stsd_index])
2274  avio_write(pb, track->extradata[track->last_stsd_index], track->extradata_size[track->last_stsd_index]);
2275 
2276  if (mov->write_btrt &&
2277  ((ret = mov_write_btrt_tag(pb, track)) < 0))
2278  return ret;
2279 
2280  return update_size(pb, pos);
2281 }
2282 
2284 {
2285  int8_t stereo_mode;
2286 
2287  if (stereo_3d->flags != 0) {
2288  av_log(s, AV_LOG_WARNING, "Unsupported stereo_3d flags %x. st3d not written.\n", stereo_3d->flags);
2289  return 0;
2290  }
2291 
2292  switch (stereo_3d->type) {
2293  case AV_STEREO3D_2D:
2294  stereo_mode = 0;
2295  break;
2296  case AV_STEREO3D_TOPBOTTOM:
2297  stereo_mode = 1;
2298  break;
2300  stereo_mode = 2;
2301  break;
2302  default:
2303  av_log(s, AV_LOG_WARNING, "Unsupported stereo_3d type %s. st3d not written.\n", av_stereo3d_type_name(stereo_3d->type));
2304  return 0;
2305  }
2306  avio_wb32(pb, 13); /* size */
2307  ffio_wfourcc(pb, "st3d");
2308  avio_wb32(pb, 0); /* version = 0 & flags = 0 */
2309  avio_w8(pb, stereo_mode);
2310  return 13;
2311 }
2312 
2314 {
2315  int64_t sv3d_pos, svhd_pos, proj_pos;
2316  const char* metadata_source = s->flags & AVFMT_FLAG_BITEXACT ? "Lavf" : LIBAVFORMAT_IDENT;
2317 
2318  if (spherical_mapping->projection != AV_SPHERICAL_EQUIRECTANGULAR &&
2319  spherical_mapping->projection != AV_SPHERICAL_EQUIRECTANGULAR_TILE &&
2320  spherical_mapping->projection != AV_SPHERICAL_CUBEMAP) {
2321  av_log(s, AV_LOG_WARNING, "Unsupported projection %d. sv3d not written.\n", spherical_mapping->projection);
2322  return 0;
2323  }
2324 
2325  sv3d_pos = avio_tell(pb);
2326  avio_wb32(pb, 0); /* size */
2327  ffio_wfourcc(pb, "sv3d");
2328 
2329  svhd_pos = avio_tell(pb);
2330  avio_wb32(pb, 0); /* size */
2331  ffio_wfourcc(pb, "svhd");
2332  avio_wb32(pb, 0); /* version = 0 & flags = 0 */
2333  avio_put_str(pb, metadata_source);
2334  update_size(pb, svhd_pos);
2335 
2336  proj_pos = avio_tell(pb);
2337  avio_wb32(pb, 0); /* size */
2338  ffio_wfourcc(pb, "proj");
2339 
2340  avio_wb32(pb, 24); /* size */
2341  ffio_wfourcc(pb, "prhd");
2342  avio_wb32(pb, 0); /* version = 0 & flags = 0 */
2343  avio_wb32(pb, spherical_mapping->yaw);
2344  avio_wb32(pb, spherical_mapping->pitch);
2345  avio_wb32(pb, spherical_mapping->roll);
2346 
2347  switch (spherical_mapping->projection) {
2350  avio_wb32(pb, 28); /* size */
2351  ffio_wfourcc(pb, "equi");
2352  avio_wb32(pb, 0); /* version = 0 & flags = 0 */
2353  avio_wb32(pb, spherical_mapping->bound_top);
2354  avio_wb32(pb, spherical_mapping->bound_bottom);
2355  avio_wb32(pb, spherical_mapping->bound_left);
2356  avio_wb32(pb, spherical_mapping->bound_right);
2357  break;
2358  case AV_SPHERICAL_CUBEMAP:
2359  avio_wb32(pb, 20); /* size */
2360  ffio_wfourcc(pb, "cbmp");
2361  avio_wb32(pb, 0); /* version = 0 & flags = 0 */
2362  avio_wb32(pb, 0); /* layout */
2363  avio_wb32(pb, spherical_mapping->padding); /* padding */
2364  break;
2365  }
2366  update_size(pb, proj_pos);
2367 
2368  return update_size(pb, sv3d_pos);
2369 }
2370 
2371 static inline int64_t rescale_rational(AVRational q, int b)
2372 {
2373  return av_rescale(q.num, b, q.den);
2374 }
2375 
2377  const AVStereo3D *stereo3d)
2378 {
2379  if (!stereo3d->horizontal_field_of_view.num)
2380  return;
2381 
2382  avio_wb32(pb, 12); /* size */
2383  ffio_wfourcc(pb, "hfov");
2384  avio_wb32(pb, rescale_rational(stereo3d->horizontal_field_of_view, 1000));
2385 }
2386 
2388  const AVSphericalMapping *spherical_mapping)
2389 {
2390  avio_wb32(pb, 24); /* size */
2391  ffio_wfourcc(pb, "proj");
2392  avio_wb32(pb, 16); /* size */
2393  ffio_wfourcc(pb, "prji");
2394  avio_wb32(pb, 0); /* version + flags */
2395 
2396  switch (spherical_mapping->projection) {
2398  ffio_wfourcc(pb, "rect");
2399  break;
2401  ffio_wfourcc(pb, "equi");
2402  break;
2404  ffio_wfourcc(pb, "hequ");
2405  break;
2406  case AV_SPHERICAL_FISHEYE:
2407  ffio_wfourcc(pb, "fish");
2408  break;
2409  default:
2410  av_assert0(0);
2411  }
2412 }
2413 
2415  const AVStereo3D *stereo3d)
2416 {
2417  int64_t pos = avio_tell(pb);
2418  int view = 0;
2419 
2420  avio_wb32(pb, 0); /* size */
2421  ffio_wfourcc(pb, "eyes");
2422 
2423  // stri is mandatory
2424  avio_wb32(pb, 13); /* size */
2425  ffio_wfourcc(pb, "stri");
2426  avio_wb32(pb, 0); /* version + flags */
2427  switch (stereo3d->view) {
2428  case AV_STEREO3D_VIEW_LEFT:
2429  view |= 1 << 0;
2430  break;
2432  view |= 1 << 1;
2433  break;
2435  view |= (1 << 0) | (1 << 1);
2436  break;
2437  }
2438  view |= !!(stereo3d->flags & AV_STEREO3D_FLAG_INVERT) << 3;
2439  avio_w8(pb, view);
2440 
2441  // hero is optional
2442  if (stereo3d->primary_eye != AV_PRIMARY_EYE_NONE) {
2443  avio_wb32(pb, 13); /* size */
2444  ffio_wfourcc(pb, "hero");
2445  avio_wb32(pb, 0); /* version + flags */
2446  avio_w8(pb, stereo3d->primary_eye);
2447  }
2448 
2449  // it's not clear if cams is mandatory or optional
2450  if (stereo3d->baseline) {
2451  avio_wb32(pb, 24); /* size */
2452  ffio_wfourcc(pb, "cams");
2453  avio_wb32(pb, 16); /* size */
2454  ffio_wfourcc(pb, "blin");
2455  avio_wb32(pb, 0); /* version + flags */
2456  avio_wb32(pb, stereo3d->baseline);
2457  }
2458 
2459  // it's not clear if cmfy is mandatory or optional
2460  if (stereo3d->horizontal_disparity_adjustment.num) {
2461  avio_wb32(pb, 24); /* size */
2462  ffio_wfourcc(pb, "cmfy");
2463  avio_wb32(pb, 16); /* size */
2464  ffio_wfourcc(pb, "dadj");
2465  avio_wb32(pb, 0); /* version + flags */
2467  }
2468 
2469  return update_size(pb, pos);
2470 }
2471 
2473  const AVStereo3D *stereo3d,
2474  const AVSphericalMapping *spherical_mapping)
2475 {
2476  int64_t pos;
2477 
2478  if (spherical_mapping &&
2479  spherical_mapping->projection != AV_SPHERICAL_RECTILINEAR &&
2480  spherical_mapping->projection != AV_SPHERICAL_EQUIRECTANGULAR &&
2481  spherical_mapping->projection != AV_SPHERICAL_HALF_EQUIRECTANGULAR &&
2482  spherical_mapping->projection != AV_SPHERICAL_FISHEYE) {
2483  av_log(s, AV_LOG_WARNING, "Unsupported projection %d. proj not written.\n",
2484  spherical_mapping->projection);
2485  spherical_mapping = NULL;
2486  }
2487 
2488  if (stereo3d && (stereo3d->type == AV_STEREO3D_2D ||
2489  (!(stereo3d->flags & AV_STEREO3D_FLAG_INVERT) &&
2490  stereo3d->view == AV_STEREO3D_VIEW_UNSPEC &&
2491  stereo3d->primary_eye == AV_PRIMARY_EYE_NONE &&
2492  !stereo3d->baseline &&
2493  !stereo3d->horizontal_disparity_adjustment.num))) {
2494  av_log(s, AV_LOG_WARNING, "Unsupported stereo 3d metadata. eyes not written.\n");
2495  stereo3d = NULL;
2496  }
2497 
2498  if (!spherical_mapping && !stereo3d)
2499  return 0;
2500 
2501  pos = avio_tell(pb);
2502  avio_wb32(pb, 0); /* size */
2503  ffio_wfourcc(pb, "vexu");
2504 
2505  if (spherical_mapping)
2506  mov_write_vexu_proj_tag(s, pb, spherical_mapping);
2507 
2508  if (stereo3d)
2509  mov_write_eyes_tag(s, pb, stereo3d);
2510 
2511  return update_size(pb, pos);
2512 }
2513 
2515 {
2516  uint8_t buf[ISOM_DVCC_DVVC_SIZE];
2517 
2518  avio_wb32(pb, 32); /* size = 8 + 24 */
2519  if (dovi->dv_profile > 10)
2520  ffio_wfourcc(pb, "dvwC");
2521  else if (dovi->dv_profile > 7)
2522  ffio_wfourcc(pb, "dvvC");
2523  else
2524  ffio_wfourcc(pb, "dvcC");
2525 
2526  ff_isom_put_dvcc_dvvc(s, buf, dovi);
2527  avio_write(pb, buf, sizeof(buf));
2528 
2529  return 32; /* 8 + 24 */
2530 }
2531 
2532 static int mov_write_clap_tag(AVIOContext *pb, MOVTrack *track,
2533  uint32_t top, uint32_t bottom,
2534  uint32_t left, uint32_t right)
2535 {
2536  uint32_t cropped_width = track->par->width - left - right;
2537  uint32_t cropped_height = track->height - top - bottom;
2538  AVRational horizOff =
2539  av_sub_q((AVRational) { track->par->width - cropped_width, 2 },
2540  (AVRational) { left, 1 });
2541  AVRational vertOff =
2542  av_sub_q((AVRational) { track->height - cropped_height, 2 },
2543  (AVRational) { top, 1 });
2544 
2545  avio_wb32(pb, 40);
2546  ffio_wfourcc(pb, "clap");
2547  avio_wb32(pb, cropped_width); /* apertureWidthN */
2548  avio_wb32(pb, 1); /* apertureWidthD */
2549  avio_wb32(pb, cropped_height); /* apertureHeightN */
2550  avio_wb32(pb, 1); /* apertureHeightD */
2551 
2552  avio_wb32(pb, -horizOff.num);
2553  avio_wb32(pb, horizOff.den);
2554  avio_wb32(pb, -vertOff.num);
2555  avio_wb32(pb, vertOff.den);
2556 
2557  return 40;
2558 }
2559 
2560 static int mov_write_pasp_tag(AVIOContext *pb, MOVTrack *track)
2561 {
2562  AVRational sar;
2563  av_reduce(&sar.num, &sar.den, track->par->sample_aspect_ratio.num,
2564  track->par->sample_aspect_ratio.den, INT_MAX);
2565 
2566  avio_wb32(pb, 16);
2567  ffio_wfourcc(pb, "pasp");
2568  avio_wb32(pb, sar.num);
2569  avio_wb32(pb, sar.den);
2570  return 16;
2571 }
2572 
2573 static int mov_write_gama_tag(AVFormatContext *s, AVIOContext *pb, MOVTrack *track, double gamma)
2574 {
2575  uint32_t gama = 0;
2576  if (gamma <= 0.0)
2577  gamma = av_csp_approximate_eotf_gamma(track->par->color_trc);
2578  av_log(s, AV_LOG_DEBUG, "gamma value %g\n", gamma);
2579 
2580  if (gamma > 1e-6) {
2581  gama = (uint32_t)lrint((double)(1<<16) * gamma);
2582  av_log(s, AV_LOG_DEBUG, "writing gama value %"PRId32"\n", gama);
2583 
2584  av_assert0(track->mode == MODE_MOV);
2585  avio_wb32(pb, 12);
2586  ffio_wfourcc(pb, "gama");
2587  avio_wb32(pb, gama);
2588  return 12;
2589  } else {
2590  av_log(s, AV_LOG_WARNING, "gamma value unknown, unable to write gama atom\n");
2591  }
2592  return 0;
2593 }
2594 
2595 static int mov_write_colr_tag(AVIOContext *pb, MOVTrack *track, int prefer_icc)
2596 {
2597  int64_t pos = avio_tell(pb);
2598 
2599  // Ref (MOV): https://developer.apple.com/library/mac/technotes/tn2162/_index.html#//apple_ref/doc/uid/DTS40013070-CH1-TNTAG9
2600  // Ref (MP4): ISO/IEC 14496-12:2012
2601 
2602  if (prefer_icc) {
2604  track->st->codecpar->nb_coded_side_data,
2606 
2607  if (sd) {
2608  avio_wb32(pb, 12 + sd->size);
2609  ffio_wfourcc(pb, "colr");
2610  ffio_wfourcc(pb, "prof");
2611  avio_write(pb, sd->data, sd->size);
2612  return 12 + sd->size;
2613  }
2614  else {
2615  av_log(NULL, AV_LOG_INFO, "no ICC profile found, will write nclx/nclc colour info instead\n");
2616  }
2617  }
2618 
2619  /* We should only ever be called for MOV, MP4 and AVIF. */
2620  av_assert0(track->mode == MODE_MOV || track->mode == MODE_MP4 ||
2621  track->mode == MODE_AVIF);
2622 
2623  avio_wb32(pb, 0); /* size */
2624  ffio_wfourcc(pb, "colr");
2625  if (track->mode == MODE_MP4 || track->mode == MODE_AVIF)
2626  ffio_wfourcc(pb, "nclx");
2627  else
2628  ffio_wfourcc(pb, "nclc");
2629  // Do not try to guess the color info if it is AVCOL_PRI_UNSPECIFIED.
2630  // e.g., Dolby Vision for Apple devices should be set to AVCOL_PRI_UNSPECIFIED. See
2631  // https://developer.apple.com/av-foundation/High-Dynamic-Range-Metadata-for-Apple-Devices.pdf
2632  avio_wb16(pb, track->par->color_primaries);
2633  avio_wb16(pb, track->par->color_trc);
2634  avio_wb16(pb, track->par->color_space);
2635  if (track->mode == MODE_MP4 || track->mode == MODE_AVIF) {
2636  int full_range = track->par->color_range == AVCOL_RANGE_JPEG;
2637  avio_w8(pb, full_range << 7);
2638  }
2639 
2640  return update_size(pb, pos);
2641 }
2642 
2643 static int mov_write_clli_tag(AVIOContext *pb, MOVTrack *track)
2644 {
2645  const AVPacketSideData *side_data;
2646  const AVContentLightMetadata *content_light_metadata;
2647 
2648  side_data = av_packet_side_data_get(track->st->codecpar->coded_side_data,
2649  track->st->codecpar->nb_coded_side_data,
2651  if (!side_data) {
2652  return 0;
2653  }
2654  content_light_metadata = (const AVContentLightMetadata*)side_data->data;
2655 
2656  avio_wb32(pb, 12); // size
2657  ffio_wfourcc(pb, "clli");
2658  avio_wb16(pb, content_light_metadata->MaxCLL);
2659  avio_wb16(pb, content_light_metadata->MaxFALL);
2660  return 12;
2661 }
2662 
2663 static int mov_write_mdcv_tag(AVIOContext *pb, MOVTrack *track)
2664 {
2665  const int chroma_den = 50000;
2666  const int luma_den = 10000;
2667  const AVPacketSideData *side_data;
2669 
2670  side_data = av_packet_side_data_get(track->st->codecpar->coded_side_data,
2671  track->st->codecpar->nb_coded_side_data,
2673  if (side_data)
2674  metadata = (const AVMasteringDisplayMetadata*)side_data->data;
2675  if (!metadata || !metadata->has_primaries || !metadata->has_luminance) {
2676  return 0;
2677  }
2678 
2679  avio_wb32(pb, 32); // size
2680  ffio_wfourcc(pb, "mdcv");
2681  avio_wb16(pb, rescale_rational(metadata->display_primaries[1][0], chroma_den));
2682  avio_wb16(pb, rescale_rational(metadata->display_primaries[1][1], chroma_den));
2683  avio_wb16(pb, rescale_rational(metadata->display_primaries[2][0], chroma_den));
2684  avio_wb16(pb, rescale_rational(metadata->display_primaries[2][1], chroma_den));
2685  avio_wb16(pb, rescale_rational(metadata->display_primaries[0][0], chroma_den));
2686  avio_wb16(pb, rescale_rational(metadata->display_primaries[0][1], chroma_den));
2687  avio_wb16(pb, rescale_rational(metadata->white_point[0], chroma_den));
2688  avio_wb16(pb, rescale_rational(metadata->white_point[1], chroma_den));
2689  avio_wb32(pb, rescale_rational(metadata->max_luminance, luma_den));
2690  avio_wb32(pb, rescale_rational(metadata->min_luminance, luma_den));
2691  return 32;
2692 }
2693 
2694 static int mov_write_amve_tag(AVIOContext *pb, MOVTrack *track)
2695 {
2696  const int illuminance_den = 10000;
2697  const int ambient_den = 50000;
2698  const AVPacketSideData *side_data;
2699  const AVAmbientViewingEnvironment *ambient;
2700 
2701 
2702  side_data = av_packet_side_data_get(track->st->codecpar->coded_side_data,
2703  track->st->codecpar->nb_coded_side_data,
2705 
2706  if (!side_data)
2707  return 0;
2708 
2709  ambient = (const AVAmbientViewingEnvironment*)side_data->data;
2710  if (!ambient || !ambient->ambient_illuminance.num)
2711  return 0;
2712 
2713  avio_wb32(pb, 16); // size
2714  ffio_wfourcc(pb, "amve");
2715  avio_wb32(pb, rescale_rational(ambient->ambient_illuminance, illuminance_den));
2716  avio_wb16(pb, rescale_rational(ambient->ambient_light_x, ambient_den));
2717  avio_wb16(pb, rescale_rational(ambient->ambient_light_y, ambient_den));
2718  return 16;
2719 }
2720 
2721 static void find_compressor(char * compressor_name, int len, MOVTrack *track)
2722 {
2723  AVDictionaryEntry *encoder;
2724  int xdcam_res = (track->par->width == 1280 && track->par->height == 720)
2725  || (track->par->width == 1440 && track->par->height == 1080)
2726  || (track->par->width == 1920 && track->par->height == 1080);
2727 
2728  if ((track->mode == MODE_AVIF ||
2729  track->mode == MODE_MOV ||
2730  track->mode == MODE_MP4) &&
2731  (encoder = av_dict_get(track->st->metadata, "encoder", NULL, 0))) {
2732  av_strlcpy(compressor_name, encoder->value, 32);
2733  } else if (track->par->codec_id == AV_CODEC_ID_MPEG2VIDEO && xdcam_res) {
2735  AVStream *st = track->st;
2736  int rate = defined_frame_rate(NULL, st);
2737  av_strlcatf(compressor_name, len, "XDCAM");
2738  if (track->par->format == AV_PIX_FMT_YUV422P) {
2739  av_strlcatf(compressor_name, len, " HD422");
2740  } else if(track->par->width == 1440) {
2741  av_strlcatf(compressor_name, len, " HD");
2742  } else
2743  av_strlcatf(compressor_name, len, " EX");
2744 
2745  av_strlcatf(compressor_name, len, " %d%c", track->par->height, interlaced ? 'i' : 'p');
2746 
2747  av_strlcatf(compressor_name, len, "%d", rate * (interlaced + 1));
2748  }
2749 }
2750 
2752 {
2753  int64_t pos = avio_tell(pb);
2754  // Write sane defaults:
2755  // all_ref_pics_intra = 0 : all samples can use any type of reference.
2756  // intra_pred_used = 1 : intra prediction may or may not be used.
2757  // max_ref_per_pic = 15 : reserved value to indicate that any number of
2758  // reference images can be used.
2759  uint8_t ccstValue = (0 << 7) | /* all_ref_pics_intra */
2760  (1 << 6) | /* intra_pred_used */
2761  (15 << 2); /* max_ref_per_pic */
2762  avio_wb32(pb, 0); /* size */
2763  ffio_wfourcc(pb, "ccst");
2764  avio_wb32(pb, 0); /* Version & flags */
2765  avio_w8(pb, ccstValue);
2766  avio_wb24(pb, 0); /* reserved */
2767  return update_size(pb, pos);
2768 }
2769 
2770 static int mov_write_aux_tag(AVIOContext *pb, const char *aux_type)
2771 {
2772  int64_t pos = avio_tell(pb);
2773  avio_wb32(pb, 0); /* size */
2774  ffio_wfourcc(pb, aux_type);
2775  avio_wb32(pb, 0); /* Version & flags */
2776  avio_write(pb, "urn:mpeg:mpegB:cicp:systems:auxiliary:alpha\0", 44);
2777  return update_size(pb, pos);
2778 }
2779 
2781 {
2782  int ret = AVERROR_BUG;
2783  int64_t pos = avio_tell(pb);
2784  const AVPacketSideData *sd;
2785  char compressor_name[32] = { 0 };
2786  int avid = 0;
2787 
2788  int uncompressed_ycbcr = ((track->par->codec_id == AV_CODEC_ID_RAWVIDEO && track->par->format == AV_PIX_FMT_UYVY422)
2789  || (track->par->codec_id == AV_CODEC_ID_RAWVIDEO && track->par->format == AV_PIX_FMT_YUYV422)
2790  || (track->par->codec_id == AV_CODEC_ID_RAWVIDEO && track->par->format == AV_PIX_FMT_VYU444)
2791  || (track->par->codec_id == AV_CODEC_ID_RAWVIDEO && track->par->format == AV_PIX_FMT_UYVA)
2792  || (track->par->codec_id == AV_CODEC_ID_RAWVIDEO && track->par->format == AV_PIX_FMT_V30XLE)
2794  || track->par->codec_id == AV_CODEC_ID_V308
2795  || track->par->codec_id == AV_CODEC_ID_V408
2796  || track->par->codec_id == AV_CODEC_ID_V410
2797 #endif
2798  || track->par->codec_id == AV_CODEC_ID_V210);
2799 
2800  avio_wb32(pb, 0); /* size */
2801  if (mov->encryption_scheme != MOV_ENC_NONE) {
2802  ffio_wfourcc(pb, "encv");
2803  } else {
2804  avio_wl32(pb, track->tag); // store it byteswapped
2805  }
2806  avio_wb32(pb, 0); /* Reserved */
2807  avio_wb16(pb, 0); /* Reserved */
2808  avio_wb16(pb, 1); /* Data-reference index */
2809 
2810  if (uncompressed_ycbcr) {
2811  avio_wb16(pb, 2); /* Codec stream version */
2812  } else {
2813  avio_wb16(pb, 0); /* Codec stream version */
2814  }
2815  avio_wb16(pb, 0); /* Codec stream revision (=0) */
2816  if (track->mode == MODE_MOV) {
2817  ffio_wfourcc(pb, "FFMP"); /* Vendor */
2818  if (track->par->codec_id == AV_CODEC_ID_RAWVIDEO || uncompressed_ycbcr) {
2819  avio_wb32(pb, 0); /* Temporal Quality */
2820  avio_wb32(pb, 0x400); /* Spatial Quality = lossless*/
2821  } else {
2822  avio_wb32(pb, 0x200); /* Temporal Quality = normal */
2823  avio_wb32(pb, 0x200); /* Spatial Quality = normal */
2824  }
2825  } else {
2826  ffio_fill(pb, 0, 3 * 4); /* Reserved */
2827  }
2828  avio_wb16(pb, track->par->width); /* Video width */
2829  avio_wb16(pb, track->height); /* Video height */
2830  avio_wb32(pb, 0x00480000); /* Horizontal resolution 72dpi */
2831  avio_wb32(pb, 0x00480000); /* Vertical resolution 72dpi */
2832  avio_wb32(pb, 0); /* Data size (= 0) */
2833  avio_wb16(pb, 1); /* Frame count (= 1) */
2834 
2835  find_compressor(compressor_name, 32, track);
2836  avio_w8(pb, strlen(compressor_name));
2837  avio_write(pb, compressor_name, 31);
2838 
2839  if (track->mode == MODE_MOV &&
2840  (track->par->codec_id == AV_CODEC_ID_V410 || track->par->codec_id == AV_CODEC_ID_V210))
2841  avio_wb16(pb, 0x18);
2842  else if (track->mode == MODE_MOV && track->par->bits_per_coded_sample)
2843  avio_wb16(pb, track->par->bits_per_coded_sample |
2844  (track->par->format == AV_PIX_FMT_GRAY8 ? 0x20 : 0));
2845  else
2846  avio_wb16(pb, 0x18); /* Reserved */
2847 
2848  if (track->mode == MODE_MOV && track->par->format == AV_PIX_FMT_PAL8) {
2849  int pal_size, i;
2850  avio_wb16(pb, 0); /* Color table ID */
2851  avio_wb32(pb, 0); /* Color table seed */
2852  avio_wb16(pb, 0x8000); /* Color table flags */
2853  if (track->par->bits_per_coded_sample < 0 || track->par->bits_per_coded_sample > 8)
2854  return AVERROR(EINVAL);
2855  pal_size = 1 << track->par->bits_per_coded_sample;
2856  avio_wb16(pb, pal_size - 1); /* Color table size (zero-relative) */
2857  for (i = 0; i < pal_size; i++) {
2858  uint32_t rgb = track->palette[i];
2859  uint16_t r = (rgb >> 16) & 0xff;
2860  uint16_t g = (rgb >> 8) & 0xff;
2861  uint16_t b = rgb & 0xff;
2862  avio_wb16(pb, 0);
2863  avio_wb16(pb, (r << 8) | r);
2864  avio_wb16(pb, (g << 8) | g);
2865  avio_wb16(pb, (b << 8) | b);
2866  }
2867  } else
2868  avio_wb16(pb, 0xffff); /* Reserved */
2869 
2870  if (track->tag == MKTAG('m','p','4','v'))
2871  mov_write_esds_tag(pb, track);
2872  else if (track->par->codec_id == AV_CODEC_ID_H263)
2873  mov_write_d263_tag(pb);
2874  else if (track->par->codec_id == AV_CODEC_ID_AVUI ||
2875  track->par->codec_id == AV_CODEC_ID_SVQ3) {
2876  mov_write_extradata_tag(pb, track);
2877  avio_wb32(pb, 0);
2878  } else if (track->par->codec_id == AV_CODEC_ID_DNXHD) {
2879  mov_write_avid_tag(pb, track);
2880  avid = 1;
2881  } else if (track->par->codec_id == AV_CODEC_ID_HEVC) {
2882  mov_write_hvcc_tag(mov->fc, pb, track);
2883  if (track->st->disposition & AV_DISPOSITION_MULTILAYER) {
2884  ret = mov_write_lhvc_tag(mov->fc, pb, track);
2885  if (ret < 0)
2886  av_log(mov->fc, AV_LOG_WARNING, "Not writing 'lhvC' atom for multilayer stream.\n");
2887  }
2888  } else if (track->par->codec_id == AV_CODEC_ID_VVC)
2889  mov_write_vvcc_tag(pb, track);
2890  else if (track->par->codec_id == AV_CODEC_ID_H264 && !TAG_IS_AVCI(track->tag)) {
2891  mov_write_avcc_tag(pb, track);
2892  if (track->mode == MODE_IPOD)
2894  }
2895  else if (track->par->codec_id ==AV_CODEC_ID_EVC) {
2896  mov_write_evcc_tag(pb, track);
2897  } else if (track->par->codec_id == AV_CODEC_ID_LCEVC) {
2898  mov_write_lvcc_tag(pb, track);
2899  } else if (track->par->codec_id ==AV_CODEC_ID_APV) {
2900  mov_write_apvc_tag(mov->fc, pb, track);
2901  } else if (track->par->codec_id == AV_CODEC_ID_VP9) {
2902  mov_write_vpcc_tag(mov->fc, pb, track);
2903  } else if (track->par->codec_id == AV_CODEC_ID_AV1) {
2904  mov_write_av1c_tag(pb, track);
2905  } else if (track->par->codec_id == AV_CODEC_ID_VC1 && track->extradata_size[track->last_stsd_index] > 0)
2906  mov_write_dvc1_tag(pb, track);
2907  else if (track->par->codec_id == AV_CODEC_ID_VP6F ||
2908  track->par->codec_id == AV_CODEC_ID_VP6A) {
2909  /* Don't write any potential extradata here - the cropping
2910  * is signalled via the normal width/height fields. */
2911  } else if (track->par->codec_id == AV_CODEC_ID_R10K) {
2912  if (track->par->codec_tag == MKTAG('R','1','0','k'))
2913  mov_write_dpxe_tag(pb, track);
2914  } else if (track->par->codec_id == AV_CODEC_ID_AVS3) {
2915  mov_write_av3c_tag(pb, track);
2916  } else if (track->extradata_size[track->last_stsd_index] > 0)
2917  mov_write_glbl_tag(pb, track);
2918 
2919  if (track->par->codec_id != AV_CODEC_ID_H264 &&
2920  track->par->codec_id != AV_CODEC_ID_MPEG4 &&
2921  track->par->codec_id != AV_CODEC_ID_DNXHD) {
2922  int field_order = track->par->field_order;
2923 
2924  if (field_order != AV_FIELD_UNKNOWN)
2925  mov_write_fiel_tag(pb, track, field_order);
2926  }
2927 
2928  if (mov->flags & FF_MOV_FLAG_WRITE_GAMA) {
2929  if (track->mode == MODE_MOV)
2930  mov_write_gama_tag(s, pb, track, mov->gamma);
2931  else
2932  av_log(mov->fc, AV_LOG_WARNING, "Not writing 'gama' atom. Format is not MOV.\n");
2933  }
2934  if (track->mode == MODE_MOV || track->mode == MODE_MP4 || track->mode == MODE_AVIF) {
2935  int has_color_info = track->par->color_primaries != AVCOL_PRI_UNSPECIFIED &&
2936  track->par->color_trc != AVCOL_TRC_UNSPECIFIED &&
2938  if (has_color_info || mov->flags & FF_MOV_FLAG_WRITE_COLR ||
2941  int prefer_icc = mov->flags & FF_MOV_FLAG_PREFER_ICC || !has_color_info;
2942  mov_write_colr_tag(pb, track, prefer_icc);
2943  }
2944  } else if (mov->flags & FF_MOV_FLAG_WRITE_COLR) {
2945  av_log(mov->fc, AV_LOG_WARNING, "Not writing 'colr' atom. Format is not MOV or MP4 or AVIF.\n");
2946  }
2947 
2948  if (track->mode == MODE_MOV || track->mode == MODE_MP4) {
2949  mov_write_clli_tag(pb, track);
2950  mov_write_mdcv_tag(pb, track);
2951  mov_write_amve_tag(pb, track);
2952  }
2953 
2954  if (track->mode == MODE_MP4 && mov->fc->strict_std_compliance <= FF_COMPLIANCE_UNOFFICIAL) {
2956  track->st->codecpar->nb_coded_side_data,
2958  const AVPacketSideData *spherical_mapping = av_packet_side_data_get(track->st->codecpar->coded_side_data,
2959  track->st->codecpar->nb_coded_side_data,
2961  if (stereo_3d)
2962  mov_write_st3d_tag(s, pb, (AVStereo3D*)stereo_3d->data);
2963  if (spherical_mapping)
2964  mov_write_sv3d_tag(mov->fc, pb, (AVSphericalMapping*)spherical_mapping->data);
2965  }
2966 
2967  if (track->mode == MODE_MOV || (track->mode == MODE_MP4 &&
2969  const AVStereo3D *stereo3d = NULL;
2970  const AVSphericalMapping *spherical_mapping = NULL;
2971 
2973  track->st->codecpar->nb_coded_side_data,
2975  if (sd)
2976  stereo3d = (AVStereo3D *)sd->data;
2977 
2979  track->st->codecpar->nb_coded_side_data,
2981  if (sd)
2982  spherical_mapping = (AVSphericalMapping *)sd->data;
2983 
2984  if (stereo3d || spherical_mapping)
2985  mov_write_vexu_tag(s, pb, stereo3d, spherical_mapping);
2986  if (stereo3d)
2987  mov_write_hfov_tag(s, pb, stereo3d);
2988  }
2989 
2990  if (track->mode == MODE_MP4) {
2992  track->st->codecpar->nb_coded_side_data,
2994  if (dovi && mov->fc->strict_std_compliance <= FF_COMPLIANCE_UNOFFICIAL) {
2996  } else if (dovi) {
2997  av_log(mov->fc, AV_LOG_WARNING, "Not writing 'dvcC'/'dvvC' box. Requires -strict unofficial.\n");
2998  }
2999  }
3000 
3001  if (track->par->sample_aspect_ratio.den && track->par->sample_aspect_ratio.num) {
3002  mov_write_pasp_tag(pb, track);
3003  }
3004 
3006  track->st->codecpar->nb_coded_side_data,
3008  if (sd && sd->size >= sizeof(uint32_t) * 4) {
3009  uint64_t top = AV_RL32(sd->data + 0);
3010  uint64_t bottom = AV_RL32(sd->data + 4);
3011  uint64_t left = AV_RL32(sd->data + 8);
3012  uint64_t right = AV_RL32(sd->data + 12);
3013 
3014  if ((left + right) >= track->par->width ||
3015  (top + bottom) >= track->height) {
3016  av_log(s, AV_LOG_ERROR, "Invalid cropping dimensions in stream side data\n");
3017  return AVERROR(EINVAL);
3018  }
3019  if (top || bottom || left || right)
3020  mov_write_clap_tag(pb, track, top, bottom, left, right);
3021  } else if (uncompressed_ycbcr)
3022  mov_write_clap_tag(pb, track, 0, 0, 0, 0);
3023 
3024  if (mov->encryption_scheme != MOV_ENC_NONE) {
3025  ff_mov_cenc_write_sinf_tag(track, pb, mov->encryption_kid);
3026  }
3027 
3028  if (mov->write_btrt &&
3029  ((ret = mov_write_btrt_tag(pb, track)) < 0))
3030  return ret;
3031 
3032  /* extra padding for avid stsd */
3033  /* https://developer.apple.com/library/mac/documentation/QuickTime/QTFF/QTFFChap2/qtff2.html#//apple_ref/doc/uid/TP40000939-CH204-61112 */
3034  if (avid)
3035  avio_wb32(pb, 0);
3036 
3037  if (track->mode == MODE_AVIF) {
3038  mov_write_ccst_tag(pb);
3039  if (mov->nb_streams > 0 && track == &mov->tracks[1])
3040  mov_write_aux_tag(pb, "auxi");
3041  }
3042 
3043  return update_size(pb, pos);
3044 }
3045 
3046 static int mov_write_rtp_tag(AVIOContext *pb, MOVTrack *track)
3047 {
3048  int64_t pos = avio_tell(pb);
3049  avio_wb32(pb, 0); /* size */
3050  ffio_wfourcc(pb, "rtp ");
3051  avio_wb32(pb, 0); /* Reserved */
3052  avio_wb16(pb, 0); /* Reserved */
3053  avio_wb16(pb, 1); /* Data-reference index */
3054 
3055  avio_wb16(pb, 1); /* Hint track version */
3056  avio_wb16(pb, 1); /* Highest compatible version */
3057  avio_wb32(pb, track->max_packet_size); /* Max packet size */
3058 
3059  avio_wb32(pb, 12); /* size */
3060  ffio_wfourcc(pb, "tims");
3061  avio_wb32(pb, track->timescale);
3062 
3063  return update_size(pb, pos);
3064 }
3065 
3066 static int mov_write_source_reference_tag(AVIOContext *pb, MOVTrack *track, const char *reel_name)
3067 {
3068  uint64_t str_size =strlen(reel_name);
3069  int64_t pos = avio_tell(pb);
3070 
3071  if (str_size >= UINT16_MAX){
3072  av_log(NULL, AV_LOG_ERROR, "reel_name length %"PRIu64" is too large\n", str_size);
3073  avio_wb16(pb, 0);
3074  return AVERROR(EINVAL);
3075  }
3076 
3077  avio_wb32(pb, 0); /* size */
3078  ffio_wfourcc(pb, "name"); /* Data format */
3079  avio_wb16(pb, str_size); /* string size */
3080  avio_wb16(pb, track->language); /* langcode */
3081  avio_write(pb, reel_name, str_size); /* reel name */
3082  return update_size(pb,pos);
3083 }
3084 
3085 static int mov_write_tmcd_tag(AVIOContext *pb, MOVTrack *track)
3086 {
3087  int64_t pos = avio_tell(pb);
3088 #if 1
3089  int frame_duration;
3090  int nb_frames;
3091  AVDictionaryEntry *t = NULL;
3092 
3093  if (!track->st->avg_frame_rate.num || !track->st->avg_frame_rate.den) {
3094  av_log(NULL, AV_LOG_ERROR, "avg_frame_rate not set for tmcd track.\n");
3095  return AVERROR(EINVAL);
3096  } else {
3097  frame_duration = av_rescale(track->timescale, track->st->avg_frame_rate.den, track->st->avg_frame_rate.num);
3098  nb_frames = ROUNDED_DIV(track->st->avg_frame_rate.num, track->st->avg_frame_rate.den);
3099  }
3100 
3101  if (nb_frames > 255) {
3102  av_log(NULL, AV_LOG_ERROR, "fps %d is too large\n", nb_frames);
3103  return AVERROR(EINVAL);
3104  }
3105 
3106  avio_wb32(pb, 0); /* size */
3107  ffio_wfourcc(pb, "tmcd"); /* Data format */
3108  avio_wb32(pb, 0); /* Reserved */
3109  avio_wb32(pb, 1); /* Data reference index */
3110  avio_wb32(pb, 0); /* Flags */
3111  avio_wb32(pb, track->timecode_flags); /* Flags (timecode) */
3112  avio_wb32(pb, track->timescale); /* Timescale */
3113  avio_wb32(pb, frame_duration); /* Frame duration */
3114  avio_w8(pb, nb_frames); /* Number of frames */
3115  avio_w8(pb, 0); /* Reserved */
3116 
3117  t = av_dict_get(track->st->metadata, "reel_name", NULL, 0);
3118  if (t && utf8len(t->value) && track->mode != MODE_MP4)
3119  mov_write_source_reference_tag(pb, track, t->value);
3120  else
3121  avio_wb16(pb, 0); /* zero size */
3122 #else
3123 
3124  avio_wb32(pb, 0); /* size */
3125  ffio_wfourcc(pb, "tmcd"); /* Data format */
3126  avio_wb32(pb, 0); /* Reserved */
3127  avio_wb32(pb, 1); /* Data reference index */
3128  if (track->par->extradata_size)
3129  avio_write(pb, track->par->extradata, track->par->extradata_size);
3130 #endif
3131  return update_size(pb, pos);
3132 }
3133 
3134 static int mov_write_gpmd_tag(AVIOContext *pb, const MOVTrack *track)
3135 {
3136  int64_t pos = avio_tell(pb);
3137  avio_wb32(pb, 0); /* size */
3138  ffio_wfourcc(pb, "gpmd");
3139  avio_wb32(pb, 0); /* Reserved */
3140  avio_wb16(pb, 0); /* Reserved */
3141  avio_wb16(pb, 1); /* Data-reference index */
3142  avio_wb32(pb, 0); /* Reserved */
3143  return update_size(pb, pos);
3144 }
3145 
3147 {
3148  int64_t pos = avio_tell(pb);
3149  int ret = 0;
3150  avio_wb32(pb, 0); /* size */
3151  ffio_wfourcc(pb, "stsd");
3152  avio_wb32(pb, 0); /* version & flags */
3153  avio_wb32(pb, track->stsd_count);
3154 
3155  int stsd_index_back = track->last_stsd_index;
3156  for (track->last_stsd_index = 0;
3157  track->last_stsd_index < track->stsd_count;
3158  track->last_stsd_index++) {
3159  if (track->par->codec_type == AVMEDIA_TYPE_VIDEO)
3160  ret = mov_write_video_tag(s, pb, mov, track);
3161  else if (track->par->codec_type == AVMEDIA_TYPE_AUDIO)
3162  ret = mov_write_audio_tag(s, pb, mov, track);
3163  else if (track->par->codec_type == AVMEDIA_TYPE_SUBTITLE)
3164  ret = mov_write_subtitle_tag(s, pb, track);
3165  else if (track->par->codec_tag == MKTAG('r','t','p',' '))
3166  ret = mov_write_rtp_tag(pb, track);
3167  else if (track->par->codec_tag == MKTAG('t','m','c','d'))
3168  ret = mov_write_tmcd_tag(pb, track);
3169  else if (track->par->codec_tag == MKTAG('g','p','m','d'))
3170  ret = mov_write_gpmd_tag(pb, track);
3171 
3172  if (ret < 0)
3173  return ret;
3174  }
3175 
3176  track->last_stsd_index = stsd_index_back;
3177 
3178  return update_size_and_version(pb, pos, track->entry_version);
3179 }
3180 
3182 {
3183  MOVMuxContext *mov = s->priv_data;
3184  MOVCtts *ctts_entries;
3185  uint32_t entries = 0;
3186  uint32_t atom_size;
3187  int i;
3188 
3189  ctts_entries = av_malloc_array((track->entry + 1), sizeof(*ctts_entries)); /* worst case */
3190  if (!ctts_entries)
3191  return AVERROR(ENOMEM);
3192  ctts_entries[0].count = 1;
3193  ctts_entries[0].offset = track->cluster[0].cts;
3194  for (i = 1; i < track->entry; i++) {
3195  if (track->cluster[i].cts == ctts_entries[entries].offset) {
3196  ctts_entries[entries].count++; /* compress */
3197  } else {
3198  entries++;
3199  ctts_entries[entries].offset = track->cluster[i].cts;
3200  ctts_entries[entries].count = 1;
3201  }
3202  }
3203  entries++; /* last one */
3204  atom_size = 16 + (entries * 8);
3205  avio_wb32(pb, atom_size); /* size */
3206  ffio_wfourcc(pb, "ctts");
3208  avio_w8(pb, 1); /* version */
3209  else
3210  avio_w8(pb, 0); /* version */
3211  avio_wb24(pb, 0); /* flags */
3212  avio_wb32(pb, entries); /* entry count */
3213  for (i = 0; i < entries; i++) {
3214  avio_wb32(pb, ctts_entries[i].count);
3215  avio_wb32(pb, ctts_entries[i].offset);
3216  }
3217  av_free(ctts_entries);
3218  return atom_size;
3219 }
3220 
3221 /* Time to sample atom */
3222 static int mov_write_stts_tag(AVIOContext *pb, MOVTrack *track)
3223 {
3224  MOVStts *stts_entries = NULL;
3225  uint32_t entries = -1;
3226  uint32_t atom_size;
3227  int i;
3228 
3229  if (track->par->codec_type == AVMEDIA_TYPE_AUDIO && !track->audio_vbr) {
3230  stts_entries = av_malloc(sizeof(*stts_entries)); /* one entry */
3231  if (!stts_entries)
3232  return AVERROR(ENOMEM);
3233  stts_entries[0].count = track->sample_count;
3234  stts_entries[0].duration = 1;
3235  entries = 1;
3236  } else {
3237  if (track->entry) {
3238  stts_entries = av_malloc_array(track->entry, sizeof(*stts_entries)); /* worst case */
3239  if (!stts_entries)
3240  return AVERROR(ENOMEM);
3241  }
3242  for (i = 0; i < track->entry; i++) {
3243  int duration = get_cluster_duration(track, i);
3244 #if CONFIG_IAMFENC
3245  if (track->iamf && track->par->codec_id == AV_CODEC_ID_OPUS)
3246  duration = av_rescale(duration, 48000, track->par->sample_rate);
3247 #endif
3248  if (i && duration == stts_entries[entries].duration) {
3249  stts_entries[entries].count++; /* compress */
3250  } else {
3251  entries++;
3252  stts_entries[entries].duration = duration;
3253  stts_entries[entries].count = 1;
3254  }
3255  }
3256  entries++; /* last one */
3257  }
3258  atom_size = 16 + (entries * 8);
3259  avio_wb32(pb, atom_size); /* size */
3260  ffio_wfourcc(pb, "stts");
3261  avio_wb32(pb, 0); /* version & flags */
3262  avio_wb32(pb, entries); /* entry count */
3263  for (i = 0; i < entries; i++) {
3264  avio_wb32(pb, stts_entries[i].count);
3265  avio_wb32(pb, stts_entries[i].duration);
3266  }
3267  av_free(stts_entries);
3268  return atom_size;
3269 }
3270 
3272 {
3273  avio_wb32(pb, 28); /* size */
3274  ffio_wfourcc(pb, "dref");
3275  avio_wb32(pb, 0); /* version & flags */
3276  avio_wb32(pb, 1); /* entry count */
3277 
3278  avio_wb32(pb, 0xc); /* size */
3279  //FIXME add the alis and rsrc atom
3280  ffio_wfourcc(pb, "url ");
3281  avio_wb32(pb, 1); /* version & flags */
3282 
3283  return 28;
3284 }
3285 
3287 {
3288  struct sgpd_entry {
3289  int count;
3290  int16_t roll_distance;
3291  int group_description_index;
3292  };
3293 
3294  struct sgpd_entry *sgpd_entries = NULL;
3295  int entries = -1;
3296  int group = 0;
3297  int i, j;
3298 
3299  const int OPUS_SEEK_PREROLL_MS = 80;
3300  int roll_samples = av_rescale_q(OPUS_SEEK_PREROLL_MS,
3301  (AVRational){1, 1000},
3302  (AVRational){1, 48000});
3303 
3304  if (!track->entry)
3305  return 0;
3306 
3307  sgpd_entries = av_malloc_array(track->entry, sizeof(*sgpd_entries));
3308  if (!sgpd_entries)
3309  return AVERROR(ENOMEM);
3310 
3312 
3313  if (track->par->codec_id == AV_CODEC_ID_OPUS) {
3314  for (i = 0; i < track->entry; i++) {
3315  int roll_samples_remaining = roll_samples;
3316  int distance = 0;
3317  for (j = i - 1; j >= 0; j--) {
3318  roll_samples_remaining -= get_cluster_duration(track, j);
3319  distance++;
3320  if (roll_samples_remaining <= 0)
3321  break;
3322  }
3323  /* We don't have enough preceding samples to compute a valid
3324  roll_distance here, so this sample can't be independently
3325  decoded. */
3326  if (roll_samples_remaining > 0)
3327  distance = 0;
3328  /* Verify distance is a maximum of 32 (2.5ms) packets. */
3329  if (distance > 32)
3330  return AVERROR_INVALIDDATA;
3331  if (i && distance == sgpd_entries[entries].roll_distance) {
3332  sgpd_entries[entries].count++;
3333  } else {
3334  entries++;
3335  sgpd_entries[entries].count = 1;
3336  sgpd_entries[entries].roll_distance = distance;
3337  sgpd_entries[entries].group_description_index = distance ? ++group : 0;
3338  }
3339  }
3340  } else {
3341  entries++;
3342  sgpd_entries[entries].count = track->sample_count;
3343  sgpd_entries[entries].roll_distance = 1;
3344  sgpd_entries[entries].group_description_index = ++group;
3345  }
3346  entries++;
3347 
3348  if (!group) {
3349  av_free(sgpd_entries);
3350  return 0;
3351  }
3352 
3353  /* Write sgpd tag */
3354  avio_wb32(pb, 24 + (group * 2)); /* size */
3355  ffio_wfourcc(pb, "sgpd");
3356  avio_wb32(pb, 1 << 24); /* fullbox */
3357  ffio_wfourcc(pb, "roll");
3358  avio_wb32(pb, 2); /* default_length */
3359  avio_wb32(pb, group); /* entry_count */
3360  for (i = 0; i < entries; i++) {
3361  if (sgpd_entries[i].group_description_index) {
3362  avio_wb16(pb, -sgpd_entries[i].roll_distance); /* roll_distance */
3363  }
3364  }
3365 
3366  /* Write sbgp tag */
3367  avio_wb32(pb, 20 + (entries * 8)); /* size */
3368  ffio_wfourcc(pb, "sbgp");
3369  avio_wb32(pb, 0); /* fullbox */
3370  ffio_wfourcc(pb, "roll");
3371  avio_wb32(pb, entries); /* entry_count */
3372  for (i = 0; i < entries; i++) {
3373  avio_wb32(pb, sgpd_entries[i].count); /* sample_count */
3374  avio_wb32(pb, sgpd_entries[i].group_description_index); /* group_description_index */
3375  }
3376 
3377  av_free(sgpd_entries);
3378  return 0;
3379 }
3380 
3382 {
3383  int64_t pos = avio_tell(pb);
3384  int ret = 0;
3385 
3386  avio_wb32(pb, 0); /* size */
3387  ffio_wfourcc(pb, "stbl");
3388  if ((ret = mov_write_stsd_tag(s, pb, mov, track)) < 0)
3389  return ret;
3390  mov_write_stts_tag(pb, track);
3391  if ((track->par->codec_type == AVMEDIA_TYPE_VIDEO ||
3392  track->par->codec_id == AV_CODEC_ID_TRUEHD ||
3394  (track->par->codec_id == AV_CODEC_ID_AAC && track->par->profile == AV_PROFILE_AAC_USAC) ||
3395  track->par->codec_tag == MKTAG('r','t','p',' ')) &&
3396  track->has_keyframes && track->has_keyframes < track->entry)
3397  mov_write_stss_tag(pb, track, MOV_SYNC_SAMPLE);
3398  if (track->par->codec_type == AVMEDIA_TYPE_VIDEO && track->has_disposable && track->entry)
3399  mov_write_sdtp_tag(pb, track);
3400  if (track->mode == MODE_MOV && track->flags & MOV_TRACK_STPS)
3402  if (track->par->codec_type == AVMEDIA_TYPE_VIDEO &&
3403  track->flags & MOV_TRACK_CTTS && track->entry) {
3404 
3405  if ((ret = mov_write_ctts_tag(s, pb, track)) < 0)
3406  return ret;
3407  }
3408  mov_write_stsc_tag(pb, track);
3409  mov_write_stsz_tag(pb, track);
3410  mov_write_stco_tag(pb, track);
3411  if (track->cenc.aes_ctr && !(mov->flags & FF_MOV_FLAG_FRAGMENT)) {
3412  ff_mov_cenc_write_stbl_atoms(&track->cenc, pb, 0);
3413  }
3414  if (track->par->codec_id == AV_CODEC_ID_OPUS || track->par->codec_id == AV_CODEC_ID_AAC) {
3415  mov_preroll_write_stbl_atoms(pb, track);
3416  }
3417  return update_size(pb, pos);
3418 }
3419 
3421 {
3422  int64_t pos = avio_tell(pb);
3423  avio_wb32(pb, 0); /* size */
3424  ffio_wfourcc(pb, "dinf");
3425  mov_write_dref_tag(pb);
3426  return update_size(pb, pos);
3427 }
3428 
3430 {
3431  avio_wb32(pb, 12);
3432  ffio_wfourcc(pb, "nmhd");
3433  avio_wb32(pb, 0);
3434  return 12;
3435 }
3436 
3438 {
3439  avio_wb32(pb, 12);
3440  ffio_wfourcc(pb, "sthd");
3441  avio_wb32(pb, 0);
3442  return 12;
3443 }
3444 
3445 static int mov_write_tcmi_tag(AVIOContext *pb, MOVTrack *track)
3446 {
3447  int64_t pos = avio_tell(pb);
3448  const char *font = "Lucida Grande";
3449  avio_wb32(pb, 0); /* size */
3450  ffio_wfourcc(pb, "tcmi"); /* timecode media information atom */
3451  avio_wb32(pb, 0); /* version & flags */
3452  avio_wb16(pb, 0); /* text font */
3453  avio_wb16(pb, 0); /* text face */
3454  avio_wb16(pb, 12); /* text size */
3455  avio_wb16(pb, 0); /* (unknown, not in the QT specs...) */
3456  avio_wb16(pb, 0x0000); /* text color (red) */
3457  avio_wb16(pb, 0x0000); /* text color (green) */
3458  avio_wb16(pb, 0x0000); /* text color (blue) */
3459  avio_wb16(pb, 0xffff); /* background color (red) */
3460  avio_wb16(pb, 0xffff); /* background color (green) */
3461  avio_wb16(pb, 0xffff); /* background color (blue) */
3462  avio_w8(pb, strlen(font)); /* font len (part of the pascal string) */
3463  avio_write(pb, font, strlen(font)); /* font name */
3464  return update_size(pb, pos);
3465 }
3466 
3467 static int mov_write_gmhd_tag(AVIOContext *pb, MOVTrack *track)
3468 {
3469  int64_t pos = avio_tell(pb);
3470  avio_wb32(pb, 0); /* size */
3471  ffio_wfourcc(pb, "gmhd");
3472  avio_wb32(pb, 0x18); /* gmin size */
3473  ffio_wfourcc(pb, "gmin");/* generic media info */
3474  avio_wb32(pb, 0); /* version & flags */
3475  avio_wb16(pb, 0x40); /* graphics mode = */
3476  avio_wb16(pb, 0x8000); /* opColor (r?) */
3477  avio_wb16(pb, 0x8000); /* opColor (g?) */
3478  avio_wb16(pb, 0x8000); /* opColor (b?) */
3479  avio_wb16(pb, 0); /* balance */
3480  avio_wb16(pb, 0); /* reserved */
3481 
3482  /*
3483  * This special text atom is required for
3484  * Apple Quicktime chapters. The contents
3485  * don't appear to be documented, so the
3486  * bytes are copied verbatim.
3487  */
3488  if (track->tag != MKTAG('c','6','0','8')) {
3489  avio_wb32(pb, 0x2C); /* size */
3490  ffio_wfourcc(pb, "text");
3491  avio_wb16(pb, 0x01);
3492  avio_wb32(pb, 0x00);
3493  avio_wb32(pb, 0x00);
3494  avio_wb32(pb, 0x00);
3495  avio_wb32(pb, 0x01);
3496  avio_wb32(pb, 0x00);
3497  avio_wb32(pb, 0x00);
3498  avio_wb32(pb, 0x00);
3499  avio_wb32(pb, 0x00004000);
3500  avio_wb16(pb, 0x0000);
3501  }
3502 
3503  if (track->par->codec_tag == MKTAG('t','m','c','d')) {
3504  int64_t tmcd_pos = avio_tell(pb);
3505  avio_wb32(pb, 0); /* size */
3506  ffio_wfourcc(pb, "tmcd");
3507  mov_write_tcmi_tag(pb, track);
3508  update_size(pb, tmcd_pos);
3509  } else if (track->par->codec_tag == MKTAG('g','p','m','d')) {
3510  int64_t gpmd_pos = avio_tell(pb);
3511  avio_wb32(pb, 0); /* size */
3512  ffio_wfourcc(pb, "gpmd");
3513  avio_wb32(pb, 0); /* version */
3514  update_size(pb, gpmd_pos);
3515  }
3516  return update_size(pb, pos);
3517 }
3518 
3520 {
3521  avio_wb32(pb, 16); /* size */
3522  ffio_wfourcc(pb, "smhd");
3523  avio_wb32(pb, 0); /* version & flags */
3524  avio_wb16(pb, 0); /* reserved (balance, normally = 0) */
3525  avio_wb16(pb, 0); /* reserved */
3526  return 16;
3527 }
3528 
3530 {
3531  avio_wb32(pb, 0x14); /* size (always 0x14) */
3532  ffio_wfourcc(pb, "vmhd");
3533  avio_wb32(pb, 0x01); /* version & flags */
3534  avio_wb64(pb, 0); /* reserved (graphics mode = copy) */
3535  return 0x14;
3536 }
3537 
3538 static int is_clcp_track(MOVTrack *track)
3539 {
3540  return track->tag == MKTAG('c','7','0','8') ||
3541  track->tag == MKTAG('c','6','0','8');
3542 }
3543 
3545 {
3546  MOVMuxContext *mov = s->priv_data;
3547  const char *hdlr, *descr = NULL, *hdlr_type = NULL;
3548  int64_t pos = avio_tell(pb);
3549  size_t descr_len;
3550 
3551  hdlr = "dhlr";
3552  hdlr_type = "url ";
3553  descr = "DataHandler";
3554 
3555  if (track) {
3556  hdlr = (track->mode == MODE_MOV) ? "mhlr" : "\0\0\0\0";
3557  if (track->par->codec_type == AVMEDIA_TYPE_VIDEO) {
3558  if (track->mode == MODE_AVIF) {
3559  hdlr_type = (track == &mov->tracks[0]) ? "pict" : "auxv";
3560  descr = "PictureHandler";
3561  } else {
3562  hdlr_type = "vide";
3563  descr = "VideoHandler";
3564  }
3565  } else if (track->par->codec_type == AVMEDIA_TYPE_AUDIO) {
3566  hdlr_type = "soun";
3567  descr = "SoundHandler";
3568  } else if (track->par->codec_type == AVMEDIA_TYPE_SUBTITLE) {
3569  if (is_clcp_track(track)) {
3570  hdlr_type = "clcp";
3571  descr = "ClosedCaptionHandler";
3572  } else {
3573  if (track->tag == MKTAG('t','x','3','g')) {
3574  hdlr_type = "sbtl";
3575  } else if (track->tag == MKTAG('m','p','4','s')) {
3576  hdlr_type = "subp";
3577  } else if (track->tag == MOV_MP4_TTML_TAG) {
3578  hdlr_type = "subt";
3579  } else {
3580  hdlr_type = "text";
3581  }
3582  descr = "SubtitleHandler";
3583  }
3584  } else if (track->par->codec_tag == MKTAG('r','t','p',' ')) {
3585  hdlr_type = "hint";
3586  descr = "HintHandler";
3587  } else if (track->par->codec_tag == MKTAG('t','m','c','d')) {
3588  hdlr_type = "tmcd";
3589  descr = "TimeCodeHandler";
3590  } else if (track->par->codec_tag == MKTAG('g','p','m','d')) {
3591  hdlr_type = "meta";
3592  descr = "GoPro MET"; // GoPro Metadata
3593  } else {
3595  "Unknown hdlr_type for %s, writing dummy values\n",
3596  av_fourcc2str(track->par->codec_tag));
3597  }
3598  if (track->st) {
3599  // hdlr.name is used by some players to identify the content title
3600  // of the track. So if an alternate handler description is
3601  // specified, use it.
3602  AVDictionaryEntry *t;
3603  t = av_dict_get(track->st->metadata, "handler_name", NULL, 0);
3604  if (t && utf8len(t->value))
3605  descr = t->value;
3606  }
3607  }
3608 
3609  if (mov->empty_hdlr_name) /* expressly allowed by QTFF and not prohibited in ISO 14496-12 8.4.3.3 */
3610  descr = "";
3611 
3612  avio_wb32(pb, 0); /* size */
3613  ffio_wfourcc(pb, "hdlr");
3614  avio_wb32(pb, 0); /* Version & flags */
3615  avio_write(pb, hdlr, 4); /* handler */
3616  ffio_wfourcc(pb, hdlr_type); /* handler type */
3617  avio_wb32(pb, 0); /* reserved */
3618  avio_wb32(pb, 0); /* reserved */
3619  avio_wb32(pb, 0); /* reserved */
3620  descr_len = strlen(descr);
3621  if (!track || track->mode == MODE_MOV)
3622  avio_w8(pb, descr_len); /* pascal string */
3623  avio_write(pb, descr, descr_len); /* handler description */
3624  if (track && track->mode != MODE_MOV)
3625  avio_w8(pb, 0); /* c string */
3626  return update_size(pb, pos);
3627 }
3628 
3629 static int mov_write_pitm_tag(AVIOContext *pb, int item_id)
3630 {
3631  int64_t pos = avio_tell(pb);
3632  avio_wb32(pb, 0); /* size */
3633  ffio_wfourcc(pb, "pitm");
3634  avio_wb32(pb, 0); /* Version & flags */
3635  avio_wb16(pb, item_id); /* item_id */
3636  return update_size(pb, pos);
3637 }
3638 
3640 {
3641  int64_t pos = avio_tell(pb);
3642  avio_wb32(pb, 0); /* size */
3643  ffio_wfourcc(pb, "iloc");
3644  avio_wb32(pb, 0); /* Version & flags */
3645  avio_w8(pb, (4 << 4) + 4); /* offset_size(4) and length_size(4) */
3646  avio_w8(pb, 0); /* base_offset_size(4) and reserved(4) */
3647  avio_wb16(pb, mov->nb_streams); /* item_count */
3648 
3649  for (int i = 0; i < mov->nb_streams; i++) {
3650  avio_wb16(pb, i + 1); /* item_id */
3651  avio_wb16(pb, 0); /* data_reference_index */
3652  avio_wb16(pb, 1); /* extent_count */
3653  mov->avif_extent_pos[i] = avio_tell(pb);
3654  avio_wb32(pb, 0); /* extent_offset (written later) */
3655  // For animated AVIF, we simply write the first packet's size.
3656  avio_wb32(pb, mov->avif_extent_length[i]); /* extent_length */
3657  }
3658 
3659  return update_size(pb, pos);
3660 }
3661 
3663 {
3664  int64_t iinf_pos = avio_tell(pb);
3665  avio_wb32(pb, 0); /* size */
3666  ffio_wfourcc(pb, "iinf");
3667  avio_wb32(pb, 0); /* Version & flags */
3668  avio_wb16(pb, mov->nb_streams); /* entry_count */
3669 
3670  for (int i = 0; i < mov->nb_streams; i++) {
3671  int64_t infe_pos = avio_tell(pb);
3672  avio_wb32(pb, 0); /* size */
3673  ffio_wfourcc(pb, "infe");
3674  avio_w8(pb, 0x2); /* Version */
3675  avio_wb24(pb, 0); /* flags */
3676  avio_wb16(pb, i + 1); /* item_id */
3677  avio_wb16(pb, 0); /* item_protection_index */
3678  avio_write(pb, "av01", 4); /* item_type */
3679  avio_write(pb, !i ? "Color\0" : "Alpha\0", 6); /* item_name */
3680  update_size(pb, infe_pos);
3681  }
3682 
3683  return update_size(pb, iinf_pos);
3684 }
3685 
3686 
3688 {
3689  int64_t auxl_pos;
3690  int64_t iref_pos = avio_tell(pb);
3691  avio_wb32(pb, 0); /* size */
3692  ffio_wfourcc(pb, "iref");
3693  avio_wb32(pb, 0); /* Version & flags */
3694 
3695  auxl_pos = avio_tell(pb);
3696  avio_wb32(pb, 0); /* size */
3697  ffio_wfourcc(pb, "auxl");
3698  avio_wb16(pb, 2); /* from_item_ID */
3699  avio_wb16(pb, 1); /* reference_count */
3700  avio_wb16(pb, 1); /* to_item_ID */
3701  update_size(pb, auxl_pos);
3702 
3703  return update_size(pb, iref_pos);
3704 }
3705 
3707  int stream_index)
3708 {
3709  int64_t pos = avio_tell(pb);
3710  avio_wb32(pb, 0); /* size */
3711  ffio_wfourcc(pb, "ispe");
3712  avio_wb32(pb, 0); /* Version & flags */
3713  avio_wb32(pb, s->streams[stream_index]->codecpar->width); /* image_width */
3714  avio_wb32(pb, s->streams[stream_index]->codecpar->height); /* image_height */
3715  return update_size(pb, pos);
3716 }
3717 
3719  int stream_index)
3720 {
3721  int64_t pos = avio_tell(pb);
3722  const AVPixFmtDescriptor *pixdesc =
3723  av_pix_fmt_desc_get(s->streams[stream_index]->codecpar->format);
3724  avio_wb32(pb, 0); /* size */
3725  ffio_wfourcc(pb, "pixi");
3726  avio_wb32(pb, 0); /* Version & flags */
3727  avio_w8(pb, pixdesc->nb_components); /* num_channels */
3728  for (int i = 0; i < pixdesc->nb_components; ++i) {
3729  avio_w8(pb, pixdesc->comp[i].depth); /* bits_per_channel */
3730  }
3731  return update_size(pb, pos);
3732 }
3733 
3735 {
3736  int64_t pos = avio_tell(pb);
3737  avio_wb32(pb, 0); /* size */
3738  ffio_wfourcc(pb, "ipco");
3739  for (int i = 0; i < mov->nb_streams; i++) {
3740  mov_write_ispe_tag(pb, mov, s, i);
3741  mov_write_pixi_tag(pb, mov, s, i);
3742  mov_write_av1c_tag(pb, &mov->tracks[i]);
3743  if (!i)
3744  mov_write_colr_tag(pb, &mov->tracks[0], 0);
3745  else
3746  mov_write_aux_tag(pb, "auxC");
3747  }
3748  return update_size(pb, pos);
3749 }
3750 
3752 {
3753  int64_t pos = avio_tell(pb);
3754  avio_wb32(pb, 0); /* size */
3755  ffio_wfourcc(pb, "ipma");
3756  avio_wb32(pb, 0); /* Version & flags */
3757  avio_wb32(pb, mov->nb_streams); /* entry_count */
3758 
3759  for (int i = 0, index = 1; i < mov->nb_streams; i++) {
3760  avio_wb16(pb, i + 1); /* item_ID */
3761  avio_w8(pb, 4); /* association_count */
3762 
3763  // ispe association.
3764  avio_w8(pb, index++); /* essential and property_index */
3765  // pixi association.
3766  avio_w8(pb, index++); /* essential and property_index */
3767  // av1C association.
3768  avio_w8(pb, 0x80 | index++); /* essential and property_index */
3769  // colr/auxC association.
3770  avio_w8(pb, index++); /* essential and property_index */
3771  }
3772  return update_size(pb, pos);
3773 }
3774 
3776 {
3777  int64_t pos = avio_tell(pb);
3778  avio_wb32(pb, 0); /* size */
3779  ffio_wfourcc(pb, "iprp");
3780  mov_write_ipco_tag(pb, mov, s);
3781  mov_write_ipma_tag(pb, mov, s);
3782  return update_size(pb, pos);
3783 }
3784 
3786 {
3787  /* This atom must be present, but leaving the values at zero
3788  * seems harmless. */
3789  avio_wb32(pb, 28); /* size */
3790  ffio_wfourcc(pb, "hmhd");
3791  avio_wb32(pb, 0); /* version, flags */
3792  avio_wb16(pb, 0); /* maxPDUsize */
3793  avio_wb16(pb, 0); /* avgPDUsize */
3794  avio_wb32(pb, 0); /* maxbitrate */
3795  avio_wb32(pb, 0); /* avgbitrate */
3796  avio_wb32(pb, 0); /* reserved */
3797  return 28;
3798 }
3799 
3801 {
3802  int64_t pos = avio_tell(pb);
3803  int ret;
3804 
3805  avio_wb32(pb, 0); /* size */
3806  ffio_wfourcc(pb, "minf");
3807  if (track->par->codec_type == AVMEDIA_TYPE_VIDEO)
3808  mov_write_vmhd_tag(pb);
3809  else if (track->par->codec_type == AVMEDIA_TYPE_AUDIO)
3810  mov_write_smhd_tag(pb);
3811  else if (track->par->codec_type == AVMEDIA_TYPE_SUBTITLE) {
3812  if (track->tag == MKTAG('t','e','x','t') || is_clcp_track(track)) {
3813  mov_write_gmhd_tag(pb, track);
3814  } else if (track->tag == MOV_MP4_TTML_TAG) {
3815  mov_write_sthd_tag(pb);
3816  } else {
3817  mov_write_nmhd_tag(pb);
3818  }
3819  } else if (track->tag == MKTAG('r','t','p',' ')) {
3820  mov_write_hmhd_tag(pb);
3821  } else if (track->tag == MKTAG('t','m','c','d')) {
3822  if (track->mode != MODE_MOV)
3823  mov_write_nmhd_tag(pb);
3824  else
3825  mov_write_gmhd_tag(pb, track);
3826  } else if (track->tag == MKTAG('g','p','m','d')) {
3827  mov_write_gmhd_tag(pb, track);
3828  }
3829  if (track->mode == MODE_MOV) /* ISO 14496-12 8.4.3.1 specifies hdlr only within mdia or meta boxes */
3830  mov_write_hdlr_tag(s, pb, NULL);
3831  mov_write_dinf_tag(pb);
3832  if ((ret = mov_write_stbl_tag(s, pb, mov, track)) < 0)
3833  return ret;
3834  return update_size(pb, pos);
3835 }
3836 
3837 static void get_pts_range(MOVMuxContext *mov, MOVTrack *track,
3838  int64_t *start, int64_t *end, int elst)
3839 {
3840  if (track->tag == MKTAG('t','m','c','d') && mov->nb_meta_tmcd) {
3841  // tmcd tracks gets track_duration set in mov_write_moov_tag from
3842  // another track's duration, while the end_pts may be left at zero.
3843  // Calculate the pts duration for that track instead.
3844  get_pts_range(mov, &mov->tracks[track->src_track], start, end, elst);
3845  *start = av_rescale(*start, track->timescale,
3846  mov->tracks[track->src_track].timescale);
3847  *end = av_rescale(*end, track->timescale,
3848  mov->tracks[track->src_track].timescale);
3849  return;
3850  }
3851  if (track->end_pts != AV_NOPTS_VALUE &&
3852  track->start_dts != AV_NOPTS_VALUE &&
3853  track->start_cts != AV_NOPTS_VALUE) {
3854  *start = track->start_dts + track->start_cts;
3855  *end = elst ? track->elst_end_pts : track->end_pts;
3856  return;
3857  }
3858  *start = 0;
3859  *end = track->track_duration;
3860 }
3861 
3863 {
3864  int64_t start, end;
3865  get_pts_range(mov, track, &start, &end, 0);
3866  return end - start;
3867 }
3868 
3869 // Calculate the actual duration of the track, after edits.
3870 // If it starts with a pts < 0, that is removed by the edit list.
3871 // If it starts with a pts > 0, the edit list adds a delay before that.
3872 // Thus, with edit lists enabled, the post-edit output of the file is
3873 // starting with pts=0.
3875 {
3876  int64_t start, end;
3877  get_pts_range(mov, track, &start, &end, 0);
3878  if (mov->use_editlist != 0)
3879  start = 0;
3880  return end - start;
3881 }
3882 
3884 {
3885  int64_t start, end;
3886  get_pts_range(mov, track, &start, &end, 1);
3887  return end - start;
3888 }
3889 
3891 {
3892  if (track && track->mode == MODE_ISM)
3893  return 1;
3894  if (duration < INT32_MAX)
3895  return 0;
3896  return 1;
3897 }
3898 
3900  MOVTrack *track)
3901 {
3903  int version = mov_mdhd_mvhd_tkhd_version(mov, track, duration);
3904 
3905  (version == 1) ? avio_wb32(pb, 44) : avio_wb32(pb, 32); /* size */
3906  ffio_wfourcc(pb, "mdhd");
3907  avio_w8(pb, version);
3908  avio_wb24(pb, 0); /* flags */
3909  if (version == 1) {
3910  avio_wb64(pb, track->time);
3911  avio_wb64(pb, track->time);
3912  } else {
3913  avio_wb32(pb, track->time); /* creation time */
3914  avio_wb32(pb, track->time); /* modification time */
3915  }
3916  avio_wb32(pb, track->timescale); /* time scale (sample rate for audio) */
3917  if (!track->entry && mov->mode == MODE_ISM)
3918  (version == 1) ? avio_wb64(pb, UINT64_C(0xffffffffffffffff)) : avio_wb32(pb, 0xffffffff);
3919  else if (!track->entry)
3920  (version == 1) ? avio_wb64(pb, 0) : avio_wb32(pb, 0);
3921  else
3922  (version == 1) ? avio_wb64(pb, duration) : avio_wb32(pb, duration); /* duration */
3923  avio_wb16(pb, track->language); /* language */
3924  avio_wb16(pb, 0); /* reserved (quality) */
3925 
3926  if (version != 0 && track->mode == MODE_MOV) {
3928  "FATAL error, file duration too long for timebase, this file will not be\n"
3929  "playable with QuickTime. Choose a different timebase with "
3930  "-video_track_timescale or a different container format\n");
3931  }
3932 
3933  return 32;
3934 }
3935 
3937  MOVMuxContext *mov, MOVTrack *track)
3938 {
3939  int64_t pos = avio_tell(pb);
3940  int ret;
3941 
3942  avio_wb32(pb, 0); /* size */
3943  ffio_wfourcc(pb, "mdia");
3944  mov_write_mdhd_tag(pb, mov, track);
3945  mov_write_hdlr_tag(s, pb, track);
3946  if ((ret = mov_write_minf_tag(s, pb, mov, track)) < 0)
3947  return ret;
3948  return update_size(pb, pos);
3949 }
3950 
3951 /* transformation matrix
3952  |a b u|
3953  |c d v|
3954  |tx ty w| */
3955 static void write_matrix(AVIOContext *pb, int16_t a, int16_t b, int16_t c,
3956  int16_t d, int16_t tx, int16_t ty)
3957 {
3958  avio_wb32(pb, a << 16); /* 16.16 format */
3959  avio_wb32(pb, b << 16); /* 16.16 format */
3960  avio_wb32(pb, 0); /* u in 2.30 format */
3961  avio_wb32(pb, c << 16); /* 16.16 format */
3962  avio_wb32(pb, d << 16); /* 16.16 format */
3963  avio_wb32(pb, 0); /* v in 2.30 format */
3964  avio_wb32(pb, tx << 16); /* 16.16 format */
3965  avio_wb32(pb, ty << 16); /* 16.16 format */
3966  avio_wb32(pb, 1 << 30); /* w in 2.30 format */
3967 }
3968 
3970  MOVTrack *track, AVStream *st)
3971 {
3973  mov->movie_timescale, track->timescale,
3974  AV_ROUND_UP);
3975  int version;
3977  int group = 0;
3978 
3979  uint32_t *display_matrix = NULL;
3980  int i;
3981 
3982  if (mov->mode == MODE_AVIF)
3983  if (!mov->avif_loop_count)
3984  duration = INT64_MAX;
3985  else
3986  duration *= mov->avif_loop_count;
3987 
3988  if (st) {
3989  const AVPacketSideData *sd;
3990  if (mov->per_stream_grouping)
3991  group = st->index;
3992  else
3993  group = st->codecpar->codec_type;
3994 
3998  if (sd && sd->size == 9 * sizeof(*display_matrix))
3999  display_matrix = (uint32_t *)sd->data;
4000  }
4001 
4002  if (track->flags & MOV_TRACK_ENABLED)
4004 
4006 
4007  (version == 1) ? avio_wb32(pb, 104) : avio_wb32(pb, 92); /* size */
4008  ffio_wfourcc(pb, "tkhd");
4009  avio_w8(pb, version);
4010  avio_wb24(pb, flags);
4011  if (version == 1) {
4012  avio_wb64(pb, track->time);
4013  avio_wb64(pb, track->time);
4014  } else {
4015  avio_wb32(pb, track->time); /* creation time */
4016  avio_wb32(pb, track->time); /* modification time */
4017  }
4018  avio_wb32(pb, track->track_id); /* track-id */
4019  avio_wb32(pb, 0); /* reserved */
4020  if (!track->entry && mov->mode == MODE_ISM)
4021  (version == 1) ? avio_wb64(pb, UINT64_C(0xffffffffffffffff)) : avio_wb32(pb, 0xffffffff);
4022  else if (!track->entry)
4023  (version == 1) ? avio_wb64(pb, 0) : avio_wb32(pb, 0);
4024  else
4025  (version == 1) ? avio_wb64(pb, duration) : avio_wb32(pb, duration);
4026 
4027  avio_wb32(pb, 0); /* reserved */
4028  avio_wb32(pb, 0); /* reserved */
4029  avio_wb16(pb, 0); /* layer */
4030  avio_wb16(pb, group); /* alternate group) */
4031  /* Volume, only for audio */
4032  if (track->par->codec_type == AVMEDIA_TYPE_AUDIO)
4033  avio_wb16(pb, 0x0100);
4034  else
4035  avio_wb16(pb, 0);
4036  avio_wb16(pb, 0); /* reserved */
4037 
4038  /* Matrix structure */
4039  if (display_matrix) {
4040  for (i = 0; i < 9; i++)
4041  avio_wb32(pb, display_matrix[i]);
4042  } else {
4043  write_matrix(pb, 1, 0, 0, 1, 0, 0);
4044  }
4045  /* Track width and height, for visual only */
4046  if (st && (track->par->codec_type == AVMEDIA_TYPE_VIDEO ||
4047  track->par->codec_type == AVMEDIA_TYPE_SUBTITLE)) {
4048  int64_t track_width_1616;
4049  if (track->mode == MODE_MOV || track->mode == MODE_AVIF) {
4050  track_width_1616 = track->par->width * 0x10000ULL;
4051  } else {
4052  track_width_1616 = av_rescale(st->sample_aspect_ratio.num,
4053  track->par->width * 0x10000LL,
4054  st->sample_aspect_ratio.den);
4055  if (!track_width_1616 ||
4056  track->height != track->par->height ||
4057  track_width_1616 > UINT32_MAX)
4058  track_width_1616 = track->par->width * 0x10000ULL;
4059  }
4060  if (track_width_1616 > UINT32_MAX) {
4061  av_log(mov->fc, AV_LOG_WARNING, "track width is too large\n");
4062  track_width_1616 = 0;
4063  }
4064  avio_wb32(pb, track_width_1616);
4065  if (track->height > 0xFFFF) {
4066  av_log(mov->fc, AV_LOG_WARNING, "track height is too large\n");
4067  avio_wb32(pb, 0);
4068  } else
4069  avio_wb32(pb, track->height * 0x10000U);
4070  } else {
4071  avio_wb32(pb, 0);
4072  avio_wb32(pb, 0);
4073  }
4074  return 0x5c;
4075 }
4076 
4077 static int mov_write_tapt_tag(AVIOContext *pb, MOVTrack *track)
4078 {
4080  track->par->sample_aspect_ratio.den);
4081 
4082  int64_t pos = avio_tell(pb);
4083 
4084  avio_wb32(pb, 0); /* size */
4085  ffio_wfourcc(pb, "tapt");
4086 
4087  avio_wb32(pb, 20);
4088  ffio_wfourcc(pb, "clef");
4089  avio_wb32(pb, 0);
4090  avio_wb32(pb, width << 16);
4091  avio_wb32(pb, track->par->height << 16);
4092 
4093  avio_wb32(pb, 20);
4094  ffio_wfourcc(pb, "prof");
4095  avio_wb32(pb, 0);
4096  avio_wb32(pb, width << 16);
4097  avio_wb32(pb, track->par->height << 16);
4098 
4099  avio_wb32(pb, 20);
4100  ffio_wfourcc(pb, "enof");
4101  avio_wb32(pb, 0);
4102  avio_wb32(pb, track->par->width << 16);
4103  avio_wb32(pb, track->par->height << 16);
4104 
4105  return update_size(pb, pos);
4106 }
4107 
4108 // This box is written in the following cases:
4109 // * Seems important for the psp playback. Without it the movie seems to hang.
4110 // * Used for specifying the looping behavior of animated AVIF (as specified
4111 // in Section 9.6 of the HEIF specification ISO/IEC 23008-12).
4113  MOVTrack *track)
4114 {
4116  mov->movie_timescale, track->timescale,
4117  AV_ROUND_UP);
4118  int version = duration < INT32_MAX ? 0 : 1;
4119  int entry_size, entry_count, size;
4120  int64_t delay, start_ct = track->start_cts;
4121  int64_t start_dts = track->start_dts;
4122  int flags = 0;
4123 
4124  if (track->entry) {
4125  if (start_dts != track->cluster[0].dts || (start_ct != track->cluster[0].cts && track->cluster[0].dts >= 0)) {
4126 
4127  av_log(mov->fc, AV_LOG_DEBUG,
4128  "EDTS using dts:%"PRId64" cts:%d instead of dts:%"PRId64" cts:%"PRId64" tid:%d\n",
4129  track->cluster[0].dts, track->cluster[0].cts,
4130  start_dts, start_ct, track->track_id);
4131  start_dts = track->cluster[0].dts;
4132  start_ct = track->cluster[0].cts;
4133  }
4134  }
4135 
4136  delay = av_rescale_rnd(start_dts + start_ct, mov->movie_timescale,
4137  track->timescale, AV_ROUND_DOWN);
4138 
4139  if (mov->mode == MODE_AVIF) {
4140  delay = 0;
4141  // Section 9.6.3 of ISO/IEC 23008-12: flags specifies repetition of the
4142  // edit list as follows: (flags & 1) equal to 0 specifies that the edit
4143  // list is not repeated, while (flags & 1) equal to 1 specifies that the
4144  // edit list is repeated.
4145  flags = mov->avif_loop_count != 1;
4146  start_ct = 0;
4147  }
4148 
4149  version |= delay < INT32_MAX ? 0 : 1;
4150 
4151  entry_size = (version == 1) ? 20 : 12;
4152  entry_count = 1 + (delay > 0);
4153  size = 24 + entry_count * entry_size;
4154 
4155  /* write the atom data */
4156  avio_wb32(pb, size);
4157  ffio_wfourcc(pb, "edts");
4158  avio_wb32(pb, size - 8);
4159  ffio_wfourcc(pb, "elst");
4160  avio_w8(pb, version);
4161  avio_wb24(pb, flags); /* flags */
4162 
4163  avio_wb32(pb, entry_count);
4164  if (delay > 0) { /* add an empty edit to delay presentation */
4165  /* In the positive delay case, the delay includes the cts
4166  * offset, and the second edit list entry below trims out
4167  * the same amount from the actual content. This makes sure
4168  * that the offset last sample is included in the edit
4169  * list duration as well. */
4170  if (version == 1) {
4171  avio_wb64(pb, delay);
4172  avio_wb64(pb, -1);
4173  } else {
4174  avio_wb32(pb, delay);
4175  avio_wb32(pb, -1);
4176  }
4177  avio_wb32(pb, 0x00010000);
4178  } else if (mov->mode != MODE_AVIF) {
4179  /* Avoid accidentally ending up with start_ct = -1 which has got a
4180  * special meaning. Normally start_ct should end up positive or zero
4181  * here, but use FFMIN in case dts is a small positive integer
4182  * rounded to 0 when represented in movie timescale units. */
4183  av_assert0(av_rescale_rnd(start_dts, mov->movie_timescale, track->timescale, AV_ROUND_DOWN) <= 0);
4184  start_ct = -FFMIN(start_dts, 0);
4185 
4186 #if CONFIG_IAMFENC
4187  if (track->iamf && track->par->codec_id == AV_CODEC_ID_OPUS)
4188  start_ct = av_rescale(start_ct, 48000, track->par->sample_rate);
4189 #endif
4190  /* Note, this delay is calculated from the pts of the first sample,
4191  * ensuring that we don't reduce the duration for cases with
4192  * dts<0 pts=0. */
4193  duration += delay;
4194  }
4195 
4196  /* For fragmented files, we don't know the full length yet. Setting
4197  * duration to 0 allows us to only specify the offset, including
4198  * the rest of the content (from all future fragments) without specifying
4199  * an explicit duration.
4200  *
4201  * For hybrid_fragmented during mov_write_trailer (mov->moov_written != 0),
4202  * don't reset duration to zero.
4203  */
4204  if (mov->flags & FF_MOV_FLAG_FRAGMENT &&
4206  duration = 0;
4207 
4208  /* duration */
4209  if (version == 1) {
4210  avio_wb64(pb, duration);
4211  avio_wb64(pb, start_ct);
4212  } else {
4213  avio_wb32(pb, duration);
4214  avio_wb32(pb, start_ct);
4215  }
4216  avio_wb32(pb, 0x00010000);
4217  return size;
4218 }
4219 
4220 static int mov_write_tref_tag(AVIOContext *pb, MOVTrack *track)
4221 {
4222  avio_wb32(pb, 20); // size
4223  ffio_wfourcc(pb, "tref");
4224  avio_wb32(pb, 12); // size (subatom)
4225  avio_wl32(pb, track->tref_tag);
4226  avio_wb32(pb, track->tref_id);
4227  return 20;
4228 }
4229 
4230 // goes at the end of each track! ... Critical for PSP playback ("Incompatible data" without it)
4232 {
4233  avio_wb32(pb, 0x34); /* size ... reports as 28 in mp4box! */
4234  ffio_wfourcc(pb, "uuid");
4235  ffio_wfourcc(pb, "USMT");
4236  avio_wb32(pb, 0x21d24fce);
4237  avio_wb32(pb, 0xbb88695c);
4238  avio_wb32(pb, 0xfac9c740);
4239  avio_wb32(pb, 0x1c); // another size here!
4240  ffio_wfourcc(pb, "MTDT");
4241  avio_wb32(pb, 0x00010012);
4242  avio_wb32(pb, 0x0a);
4243  avio_wb32(pb, 0x55c40000);
4244  avio_wb32(pb, 0x1);
4245  avio_wb32(pb, 0x0);
4246  return 0x34;
4247 }
4248 
4249 static int mov_write_udta_sdp(AVIOContext *pb, MOVTrack *track)
4250 {
4251  AVFormatContext *ctx = track->rtp_ctx;
4252  char buf[1000] = "";
4253  int len;
4254 
4255  ff_sdp_write_media(buf, sizeof(buf), ctx->streams[0], track->src_track,
4256  NULL, NULL, 0, 0, ctx);
4257  av_strlcatf(buf, sizeof(buf), "a=control:streamid=%d\r\n", track->track_id);
4258  len = strlen(buf);
4259 
4260  avio_wb32(pb, len + 24);
4261  ffio_wfourcc(pb, "udta");
4262  avio_wb32(pb, len + 16);
4263  ffio_wfourcc(pb, "hnti");
4264  avio_wb32(pb, len + 8);
4265  ffio_wfourcc(pb, "sdp ");
4266  avio_write(pb, buf, len);
4267  return len + 24;
4268 }
4269 
4271  const char *tag, const char *str)
4272 {
4273  int64_t pos = avio_tell(pb);
4274  AVDictionaryEntry *t = av_dict_get(st->metadata, str, NULL, 0);
4275  if (!t || !utf8len(t->value))
4276  return 0;
4277 
4278  avio_wb32(pb, 0); /* size */
4279  ffio_wfourcc(pb, tag); /* type */
4280  avio_write(pb, t->value, strlen(t->value)); /* UTF8 string value */
4281  return update_size(pb, pos);
4282 }
4283 
4284 static int mov_write_track_kind(AVIOContext *pb, const char *scheme_uri,
4285  const char *value)
4286 {
4287  int64_t pos = avio_tell(pb);
4288 
4289  /* Box|FullBox basics */
4290  avio_wb32(pb, 0); /* size placeholder */
4291  ffio_wfourcc(pb, (const unsigned char *)"kind");
4292  avio_w8(pb, 0); /* version = 0 */
4293  avio_wb24(pb, 0); /* flags = 0 */
4294 
4295  /* Required null-terminated scheme URI */
4296  avio_write(pb, (const unsigned char *)scheme_uri,
4297  strlen(scheme_uri));
4298  avio_w8(pb, 0);
4299 
4300  /* Optional value string */
4301  if (value && value[0])
4302  avio_write(pb, (const unsigned char *)value,
4303  strlen(value));
4304 
4305  avio_w8(pb, 0);
4306 
4307  return update_size(pb, pos);
4308 }
4309 
4311 {
4312  int ret = AVERROR_BUG;
4313 
4314  for (int i = 0; ff_mov_track_kind_table[i].scheme_uri; i++) {
4316 
4317  for (int j = 0; map.value_maps[j].disposition; j++) {
4318  const struct MP4TrackKindValueMapping value_map = map.value_maps[j];
4319  if (!(st->disposition & value_map.disposition))
4320  continue;
4321 
4322  if ((ret = mov_write_track_kind(pb, map.scheme_uri, value_map.value)) < 0)
4323  return ret;
4324  }
4325  }
4326 
4327  return 0;
4328 }
4329 
4331  AVStream *st)
4332 {
4333  AVIOContext *pb_buf;
4334  int ret, size;
4335  uint8_t *buf;
4336 
4337  if (!st)
4338  return 0;
4339 
4340  ret = avio_open_dyn_buf(&pb_buf);
4341  if (ret < 0)
4342  return ret;
4343 
4344  if (mov->mode & (MODE_MP4|MODE_MOV))
4345  mov_write_track_metadata(pb_buf, st, "name", "title");
4346 
4347  if (mov->mode & MODE_MP4) {
4348  if ((ret = mov_write_track_kinds(pb_buf, st)) < 0)
4349  return ret;
4350  }
4351 
4352  if ((size = avio_get_dyn_buf(pb_buf, &buf)) > 0) {
4353  avio_wb32(pb, size + 8);
4354  ffio_wfourcc(pb, "udta");
4355  avio_write(pb, buf, size);
4356  }
4357  ffio_free_dyn_buf(&pb_buf);
4358 
4359  return 0;
4360 }
4361 
4363  MOVTrack *track, AVStream *st)
4364 {
4365  int64_t pos = avio_tell(pb);
4366  int entry_backup = track->entry;
4367  int chunk_backup = track->chunkCount;
4368  int ret;
4369 
4370  /* If we want to have an empty moov, but some samples already have been
4371  * buffered (delay_moov), pretend that no samples have been written yet. */
4372  if (mov->flags & FF_MOV_FLAG_EMPTY_MOOV)
4373  track->chunkCount = track->entry = 0;
4374 
4375  avio_wb32(pb, 0); /* size */
4376  ffio_wfourcc(pb, "trak");
4377  mov_write_tkhd_tag(pb, mov, track, st);
4378 
4379  av_assert2(mov->use_editlist >= 0);
4380 
4381  if (track->start_dts != AV_NOPTS_VALUE) {
4382  if (mov->use_editlist)
4383  mov_write_edts_tag(pb, mov, track); // PSP Movies and several other cases require edts box
4384  else if ((track->entry && track->cluster[0].dts) || track->mode == MODE_PSP || is_clcp_track(track))
4385  av_log(mov->fc, AV_LOG_WARNING,
4386  "Not writing any edit list even though one would have been required\n");
4387  }
4388 
4389  if (mov->is_animated_avif)
4390  mov_write_edts_tag(pb, mov, track);
4391 
4392  if (track->tref_tag)
4393  mov_write_tref_tag(pb, track);
4394 
4395  if ((ret = mov_write_mdia_tag(s, pb, mov, track)) < 0)
4396  return ret;
4397  if (track->mode == MODE_PSP)
4398  mov_write_uuid_tag_psp(pb, track); // PSP Movies require this uuid box
4399  if (track->tag == MKTAG('r','t','p',' '))
4400  mov_write_udta_sdp(pb, track);
4401  if (track->mode == MODE_MOV) {
4402  if (track->par->codec_type == AVMEDIA_TYPE_VIDEO) {
4403  double sample_aspect_ratio = av_q2d(st->sample_aspect_ratio);
4404  if (st->sample_aspect_ratio.num && 1.0 != sample_aspect_ratio) {
4405  mov_write_tapt_tag(pb, track);
4406  }
4407  }
4408  if (is_clcp_track(track) && st->sample_aspect_ratio.num) {
4409  mov_write_tapt_tag(pb, track);
4410  }
4411  }
4412  mov_write_track_udta_tag(pb, mov, st);
4413  track->entry = entry_backup;
4414  track->chunkCount = chunk_backup;
4415  return update_size(pb, pos);
4416 }
4417 
4419 {
4420  int i, has_audio = 0, has_video = 0;
4421  int64_t pos = avio_tell(pb);
4422  int audio_profile = mov->iods_audio_profile;
4423  int video_profile = mov->iods_video_profile;
4424  for (i = 0; i < mov->nb_tracks; i++) {
4425  if (mov->tracks[i].entry > 0 || mov->flags & FF_MOV_FLAG_EMPTY_MOOV) {
4426  has_audio |= mov->tracks[i].par->codec_type == AVMEDIA_TYPE_AUDIO;
4427  has_video |= mov->tracks[i].par->codec_type == AVMEDIA_TYPE_VIDEO;
4428  }
4429  }
4430  if (audio_profile < 0)
4431  audio_profile = 0xFF - has_audio;
4432  if (video_profile < 0)
4433  video_profile = 0xFF - has_video;
4434  avio_wb32(pb, 0x0); /* size */
4435  ffio_wfourcc(pb, "iods");
4436  avio_wb32(pb, 0); /* version & flags */
4437  put_descr(pb, 0x10, 7);
4438  avio_wb16(pb, 0x004f);
4439  avio_w8(pb, 0xff);
4440  avio_w8(pb, 0xff);
4441  avio_w8(pb, audio_profile);
4442  avio_w8(pb, video_profile);
4443  avio_w8(pb, 0xff);
4444  return update_size(pb, pos);
4445 }
4446 
4447 static int mov_write_trex_tag(AVIOContext *pb, MOVTrack *track)
4448 {
4449  avio_wb32(pb, 0x20); /* size */
4450  ffio_wfourcc(pb, "trex");
4451  avio_wb32(pb, 0); /* version & flags */
4452  avio_wb32(pb, track->track_id); /* track ID */
4453  avio_wb32(pb, 1); /* default sample description index */
4454  avio_wb32(pb, 0); /* default sample duration */
4455  avio_wb32(pb, 0); /* default sample size */
4456  avio_wb32(pb, 0); /* default sample flags */
4457  return 0;
4458 }
4459 
4461 {
4462  int64_t pos = avio_tell(pb);
4463  int i;
4464  avio_wb32(pb, 0x0); /* size */
4465  ffio_wfourcc(pb, "mvex");
4466  for (i = 0; i < mov->nb_tracks; i++)
4467  mov_write_trex_tag(pb, &mov->tracks[i]);
4468  return update_size(pb, pos);
4469 }
4470 
4472 {
4473  int max_track_id = 1, i;
4474  int64_t max_track_len = 0;
4475  int version;
4476  int timescale;
4477 
4478  for (i = 0; i < mov->nb_tracks; i++) {
4479  if (mov->tracks[i].entry > 0 && mov->tracks[i].timescale) {
4480  int64_t max_track_len_temp = av_rescale_rnd(
4481  calc_pts_duration(mov, &mov->tracks[i]),
4482  mov->movie_timescale,
4483  mov->tracks[i].timescale,
4484  AV_ROUND_UP);
4485  if (max_track_len < max_track_len_temp)
4486  max_track_len = max_track_len_temp;
4487  if (max_track_id < mov->tracks[i].track_id)
4488  max_track_id = mov->tracks[i].track_id;
4489  }
4490  }
4491  /* If using delay_moov, make sure the output is the same as if no
4492  * samples had been written yet. */
4493  if (mov->flags & FF_MOV_FLAG_EMPTY_MOOV) {
4494  max_track_len = 0;
4495  max_track_id = 1;
4496  }
4497 
4498  version = mov_mdhd_mvhd_tkhd_version(mov, NULL, max_track_len);
4499  avio_wb32(pb, version == 1 ? 120 : 108); /* size */
4500 
4501  ffio_wfourcc(pb, "mvhd");
4502  avio_w8(pb, version);
4503  avio_wb24(pb, 0); /* flags */
4504  if (version == 1) {
4505  avio_wb64(pb, mov->time);
4506  avio_wb64(pb, mov->time);
4507  } else {
4508  avio_wb32(pb, mov->time); /* creation time */
4509  avio_wb32(pb, mov->time); /* modification time */
4510  }
4511 
4512  timescale = mov->movie_timescale;
4513  if (mov->mode == MODE_AVIF && !timescale)
4514  timescale = mov->tracks[0].timescale;
4515 
4516  avio_wb32(pb, timescale);
4517  (version == 1) ? avio_wb64(pb, max_track_len) : avio_wb32(pb, max_track_len); /* duration of longest track */
4518 
4519  avio_wb32(pb, 0x00010000); /* reserved (preferred rate) 1.0 = normal */
4520  avio_wb16(pb, 0x0100); /* reserved (preferred volume) 1.0 = normal */
4521  ffio_fill(pb, 0, 2 + 2 * 4); /* reserved */
4522 
4523  /* Matrix structure */
4524  write_matrix(pb, 1, 0, 0, 1, 0, 0);
4525 
4526  avio_wb32(pb, 0); /* reserved (preview time) */
4527  avio_wb32(pb, 0); /* reserved (preview duration) */
4528  avio_wb32(pb, 0); /* reserved (poster time) */
4529  avio_wb32(pb, 0); /* reserved (selection time) */
4530  avio_wb32(pb, 0); /* reserved (selection duration) */
4531  avio_wb32(pb, 0); /* reserved (current time) */
4532  avio_wb32(pb, max_track_id + 1); /* Next track id */
4533  return 0x6c;
4534 }
4535 
4537  AVFormatContext *s)
4538 {
4539  avio_wb32(pb, 33); /* size */
4540  ffio_wfourcc(pb, "hdlr");
4541  avio_wb32(pb, 0);
4542  avio_wb32(pb, 0);
4543  ffio_wfourcc(pb, "mdir");
4544  ffio_wfourcc(pb, "appl");
4545  avio_wb32(pb, 0);
4546  avio_wb32(pb, 0);
4547  avio_w8(pb, 0);
4548  return 33;
4549 }
4550 
4551 /* helper function to write a data tag with the specified string as data */
4552 static int mov_write_string_data_tag(AVIOContext *pb, const char *data, int lang, int long_style)
4553 {
4554  size_t data_len = strlen(data);
4555  if (long_style) {
4556  int size = 16 + data_len;
4557  avio_wb32(pb, size); /* size */
4558  ffio_wfourcc(pb, "data");
4559  avio_wb32(pb, 1);
4560  avio_wb32(pb, 0);
4561  avio_write(pb, data, data_len);
4562  return size;
4563  } else {
4564  avio_wb16(pb, data_len); /* string length */
4565  if (!lang)
4566  lang = ff_mov_iso639_to_lang("und", 1);
4567  avio_wb16(pb, lang);
4568  avio_write(pb, data, data_len);
4569  return data_len + 4;
4570  }
4571 }
4572 
4573 static int mov_write_string_tag(AVIOContext *pb, const char *name,
4574  const char *value, int lang, int long_style)
4575 {
4576  int size = 0;
4577  if (value && value[0]) {
4578  int64_t pos = avio_tell(pb);
4579  avio_wb32(pb, 0); /* size */
4580  ffio_wfourcc(pb, name);
4581  mov_write_string_data_tag(pb, value, lang, long_style);
4582  size = update_size(pb, pos);
4583  }
4584  return size;
4585 }
4586 
4588  const char *tag, int *lang)
4589 {
4590  int l, len, len2;
4591  AVDictionaryEntry *t, *t2 = NULL;
4592  char tag2[16];
4593 
4594  *lang = 0;
4595 
4596  if (!(t = av_dict_get(s->metadata, tag, NULL, 0)))
4597  return NULL;
4598 
4599  len = strlen(t->key);
4600  snprintf(tag2, sizeof(tag2), "%s-", tag);
4601  while ((t2 = av_dict_get(s->metadata, tag2, t2, AV_DICT_IGNORE_SUFFIX))) {
4602  len2 = strlen(t2->key);
4603  if (len2 == len + 4 && !strcmp(t->value, t2->value)
4604  && (l = ff_mov_iso639_to_lang(&t2->key[len2 - 3], 1)) >= 0) {
4605  *lang = l;
4606  return t;
4607  }
4608  }
4609  return t;
4610 }
4611 
4613  const char *name, const char *tag,
4614  int long_style)
4615 {
4616  int lang;
4617  AVDictionaryEntry *t = get_metadata_lang(s, tag, &lang);
4618  if (!t)
4619  return 0;
4620  return mov_write_string_tag(pb, name, t->value, lang, long_style);
4621 }
4622 
4623 /* iTunes bpm number */
4625 {
4626  AVDictionaryEntry *t = av_dict_get(s->metadata, "tmpo", NULL, 0);
4627  int size = 0, tmpo = t ? atoi(t->value) : 0;
4628  if (tmpo) {
4629  size = 26;
4630  avio_wb32(pb, size);
4631  ffio_wfourcc(pb, "tmpo");
4632  avio_wb32(pb, size-8); /* size */
4633  ffio_wfourcc(pb, "data");
4634  avio_wb32(pb, 0x15); //type specifier
4635  avio_wb32(pb, 0);
4636  avio_wb16(pb, tmpo); // data
4637  }
4638  return size;
4639 }
4640 
4641 /* 3GPP TS 26.244 */
4643 {
4644  int lang;
4645  int64_t pos = avio_tell(pb);
4646  double latitude, longitude, altitude;
4647  int32_t latitude_fix, longitude_fix, altitude_fix;
4648  AVDictionaryEntry *t = get_metadata_lang(s, "location", &lang);
4649  const char *ptr, *place = "";
4650  char *end;
4651  static const char *astronomical_body = "earth";
4652  if (!t)
4653  return 0;
4654 
4655  ptr = t->value;
4656  latitude = strtod(ptr, &end);
4657  if (end == ptr) {
4658  av_log(s, AV_LOG_WARNING, "malformed location metadata\n");
4659  return 0;
4660  }
4661  ptr = end;
4662  longitude = strtod(ptr, &end);
4663  if (end == ptr) {
4664  av_log(s, AV_LOG_WARNING, "malformed location metadata\n");
4665  return 0;
4666  }
4667  ptr = end;
4668  altitude = strtod(ptr, &end);
4669  /* If no altitude was present, the default 0 should be fine */
4670  if (*end == '/')
4671  place = end + 1;
4672 
4673  latitude_fix = (int32_t) ((1 << 16) * latitude);
4674  longitude_fix = (int32_t) ((1 << 16) * longitude);
4675  altitude_fix = (int32_t) ((1 << 16) * altitude);
4676 
4677  avio_wb32(pb, 0); /* size */
4678  ffio_wfourcc(pb, "loci"); /* type */
4679  avio_wb32(pb, 0); /* version + flags */
4680  avio_wb16(pb, lang);
4681  avio_write(pb, place, strlen(place) + 1);
4682  avio_w8(pb, 0); /* role of place (0 == shooting location, 1 == real location, 2 == fictional location) */
4683  avio_wb32(pb, longitude_fix);
4684  avio_wb32(pb, latitude_fix);
4685  avio_wb32(pb, altitude_fix);
4686  avio_write(pb, astronomical_body, strlen(astronomical_body) + 1);
4687  avio_w8(pb, 0); /* additional notes, null terminated string */
4688 
4689  return update_size(pb, pos);
4690 }
4691 
4692 /* iTunes track or disc number */
4694  AVFormatContext *s, int disc)
4695 {
4696  AVDictionaryEntry *t = av_dict_get(s->metadata,
4697  disc ? "disc" : "track",
4698  NULL, 0);
4699  int size = 0, track = t ? atoi(t->value) : 0;
4700  if (track) {
4701  int tracks = 0;
4702  char *slash = strchr(t->value, '/');
4703  if (slash)
4704  tracks = atoi(slash + 1);
4705  avio_wb32(pb, 32); /* size */
4706  ffio_wfourcc(pb, disc ? "disk" : "trkn");
4707  avio_wb32(pb, 24); /* size */
4708  ffio_wfourcc(pb, "data");
4709  avio_wb32(pb, 0); // 8 bytes empty
4710  avio_wb32(pb, 0);
4711  avio_wb16(pb, 0); // empty
4712  avio_wb16(pb, track); // track / disc number
4713  avio_wb16(pb, tracks); // total track / disc number
4714  avio_wb16(pb, 0); // empty
4715  size = 32;
4716  }
4717  return size;
4718 }
4719 
4721  const char *name, const char *tag,
4722  int len)
4723 {
4724  AVDictionaryEntry *t = NULL;
4725  uint8_t num;
4726  int size = 24 + len;
4727 
4728  if (len != 1 && len != 4)
4729  return -1;
4730 
4731  if (!(t = av_dict_get(s->metadata, tag, NULL, 0)))
4732  return 0;
4733  num = atoi(t->value);
4734 
4735  avio_wb32(pb, size);
4736  ffio_wfourcc(pb, name);
4737  avio_wb32(pb, size - 8);
4738  ffio_wfourcc(pb, "data");
4739  avio_wb32(pb, 0x15);
4740  avio_wb32(pb, 0);
4741  if (len==4) avio_wb32(pb, num);
4742  else avio_w8 (pb, num);
4743 
4744  return size;
4745 }
4746 
4748 {
4749  MOVMuxContext *mov = s->priv_data;
4750  int64_t pos = 0;
4751 
4752  for (int i = 0; i < mov->nb_streams; i++) {
4753  MOVTrack *trk = &mov->tracks[i];
4754 
4755  if (!is_cover_image(trk->st) || trk->cover_image->size <= 0)
4756  continue;
4757 
4758  if (!pos) {
4759  pos = avio_tell(pb);
4760  avio_wb32(pb, 0);
4761  ffio_wfourcc(pb, "covr");
4762  }
4763  avio_wb32(pb, 16 + trk->cover_image->size);
4764  ffio_wfourcc(pb, "data");
4765  avio_wb32(pb, trk->tag);
4766  avio_wb32(pb , 0);
4767  avio_write(pb, trk->cover_image->data, trk->cover_image->size);
4768  }
4769 
4770  return pos ? update_size(pb, pos) : 0;
4771 }
4772 
4773 /* iTunes meta data list */
4775  AVFormatContext *s)
4776 {
4777  int64_t pos = avio_tell(pb);
4778  avio_wb32(pb, 0); /* size */
4779  ffio_wfourcc(pb, "ilst");
4780  mov_write_string_metadata(s, pb, "\251nam", "title" , 1);
4781  mov_write_string_metadata(s, pb, "\251ART", "artist" , 1);
4782  mov_write_string_metadata(s, pb, "aART", "album_artist", 1);
4783  mov_write_string_metadata(s, pb, "\251wrt", "composer" , 1);
4784  mov_write_string_metadata(s, pb, "\251alb", "album" , 1);
4785  mov_write_string_metadata(s, pb, "\251day", "date" , 1);
4786  if (!mov_write_string_metadata(s, pb, "\251too", "encoding_tool", 1)) {
4787  if (!(s->flags & AVFMT_FLAG_BITEXACT))
4788  mov_write_string_tag(pb, "\251too", LIBAVFORMAT_IDENT, 0, 1);
4789  }
4790  mov_write_string_metadata(s, pb, "\251cmt", "comment" , 1);
4791  mov_write_string_metadata(s, pb, "\251gen", "genre" , 1);
4792  mov_write_string_metadata(s, pb, "cprt", "copyright", 1);
4793  mov_write_string_metadata(s, pb, "\251grp", "grouping" , 1);
4794  mov_write_string_metadata(s, pb, "\251lyr", "lyrics" , 1);
4795  mov_write_string_metadata(s, pb, "desc", "description",1);
4796  mov_write_string_metadata(s, pb, "ldes", "synopsis" , 1);
4797  mov_write_string_metadata(s, pb, "tvsh", "show" , 1);
4798  mov_write_string_metadata(s, pb, "tven", "episode_id",1);
4799  mov_write_string_metadata(s, pb, "tvnn", "network" , 1);
4800  mov_write_string_metadata(s, pb, "keyw", "keywords" , 1);
4801  mov_write_int8_metadata (s, pb, "tves", "episode_sort",4);
4802  mov_write_int8_metadata (s, pb, "tvsn", "season_number",4);
4803  mov_write_int8_metadata (s, pb, "stik", "media_type",1);
4804  mov_write_int8_metadata (s, pb, "hdvd", "hd_video", 1);
4805  mov_write_int8_metadata (s, pb, "pgap", "gapless_playback",1);
4806  mov_write_int8_metadata (s, pb, "cpil", "compilation", 1);
4807  mov_write_covr(pb, s);
4808  mov_write_trkn_tag(pb, mov, s, 0); // track number
4809  mov_write_trkn_tag(pb, mov, s, 1); // disc number
4810  mov_write_tmpo_tag(pb, s);
4811  return update_size(pb, pos);
4812 }
4813 
4815  AVFormatContext *s)
4816 {
4817  avio_wb32(pb, 33); /* size */
4818  ffio_wfourcc(pb, "hdlr");
4819  avio_wb32(pb, 0);
4820  avio_wb32(pb, 0);
4821  ffio_wfourcc(pb, "mdta");
4822  avio_wb32(pb, 0);
4823  avio_wb32(pb, 0);
4824  avio_wb32(pb, 0);
4825  avio_w8(pb, 0);
4826  return 33;
4827 }
4828 
4830  AVFormatContext *s)
4831 {
4832  const AVDictionaryEntry *t = NULL;
4833  int64_t pos = avio_tell(pb);
4834  int64_t curpos, entry_pos;
4835  int count = 0;
4836 
4837  avio_wb32(pb, 0); /* size */
4838  ffio_wfourcc(pb, "keys");
4839  avio_wb32(pb, 0);
4840  entry_pos = avio_tell(pb);
4841  avio_wb32(pb, 0); /* entry count */
4842 
4843  while (t = av_dict_iterate(s->metadata, t)) {
4844  size_t key_len = strlen(t->key);
4845  avio_wb32(pb, key_len + 8);
4846  ffio_wfourcc(pb, "mdta");
4847  avio_write(pb, t->key, key_len);
4848  count += 1;
4849  }
4850  curpos = avio_tell(pb);
4851  avio_seek(pb, entry_pos, SEEK_SET);
4852  avio_wb32(pb, count); // rewrite entry count
4853  avio_seek(pb, curpos, SEEK_SET);
4854 
4855  return update_size(pb, pos);
4856 }
4857 
4859  AVFormatContext *s)
4860 {
4861  const AVDictionaryEntry *t = NULL;
4862  int64_t pos = avio_tell(pb);
4863  int count = 1; /* keys are 1-index based */
4864 
4865  avio_wb32(pb, 0); /* size */
4866  ffio_wfourcc(pb, "ilst");
4867 
4868  while (t = av_dict_iterate(s->metadata, t)) {
4869  int64_t entry_pos = avio_tell(pb);
4870  avio_wb32(pb, 0); /* size */
4871  avio_wb32(pb, count); /* key */
4872  mov_write_string_data_tag(pb, t->value, 0, 1);
4873  update_size(pb, entry_pos);
4874  count += 1;
4875  }
4876  return update_size(pb, pos);
4877 }
4878 
4879 /* meta data tags */
4881  AVFormatContext *s)
4882 {
4883  int size = 0;
4884  int64_t pos = avio_tell(pb);
4885  avio_wb32(pb, 0); /* size */
4886  ffio_wfourcc(pb, "meta");
4887  avio_wb32(pb, 0);
4888  if (mov->flags & FF_MOV_FLAG_USE_MDTA) {
4889  mov_write_mdta_hdlr_tag(pb, mov, s);
4890  mov_write_mdta_keys_tag(pb, mov, s);
4891  mov_write_mdta_ilst_tag(pb, mov, s);
4892  } else if (mov->mode == MODE_AVIF) {
4893  mov_write_hdlr_tag(s, pb, &mov->tracks[0]);
4894  // We always write the primary item id as 1 since only one track is
4895  // supported for AVIF.
4896  mov_write_pitm_tag(pb, 1);
4897  mov_write_iloc_tag(pb, mov, s);
4898  mov_write_iinf_tag(pb, mov, s);
4899  if (mov->nb_streams > 1)
4900  mov_write_iref_tag(pb, mov, s);
4901  mov_write_iprp_tag(pb, mov, s);
4902  } else {
4903  /* iTunes metadata tag */
4904  mov_write_itunes_hdlr_tag(pb, mov, s);
4905  mov_write_ilst_tag(pb, mov, s);
4906  }
4907  size = update_size(pb, pos);
4908  return size;
4909 }
4910 
4912  const char *name, const char *key)
4913 {
4914  int len;
4915  AVDictionaryEntry *t;
4916 
4917  if (!(t = av_dict_get(s->metadata, key, NULL, 0)))
4918  return 0;
4919 
4920  len = strlen(t->value);
4921  if (len > 0) {
4922  int size = len + 8;
4923  avio_wb32(pb, size);
4924  ffio_wfourcc(pb, name);
4925  avio_write(pb, t->value, len);
4926  return size;
4927  }
4928  return 0;
4929 }
4930 
4931 static int ascii_to_wc(AVIOContext *pb, const uint8_t *b)
4932 {
4933  int val;
4934  while (*b) {
4935  GET_UTF8(val, *b++, return -1;)
4936  avio_wb16(pb, val);
4937  }
4938  avio_wb16(pb, 0x00);
4939  return 0;
4940 }
4941 
4942 static uint16_t language_code(const char *str)
4943 {
4944  return (((str[0] - 0x60) & 0x1F) << 10) +
4945  (((str[1] - 0x60) & 0x1F) << 5) +
4946  (( str[2] - 0x60) & 0x1F);
4947 }
4948 
4950  const char *tag, const char *str)
4951 {
4952  int64_t pos = avio_tell(pb);
4953  AVDictionaryEntry *t = av_dict_get(s->metadata, str, NULL, 0);
4954  if (!t || !utf8len(t->value))
4955  return 0;
4956  avio_wb32(pb, 0); /* size */
4957  ffio_wfourcc(pb, tag); /* type */
4958  avio_wb32(pb, 0); /* version + flags */
4959  if (!strcmp(tag, "yrrc"))
4960  avio_wb16(pb, atoi(t->value));
4961  else {
4962  avio_wb16(pb, language_code("eng")); /* language */
4963  avio_write(pb, t->value, strlen(t->value) + 1); /* UTF8 string value */
4964  if (!strcmp(tag, "albm") &&
4965  (t = av_dict_get(s->metadata, "track", NULL, 0)))
4966  avio_w8(pb, atoi(t->value));
4967  }
4968  return update_size(pb, pos);
4969 }
4970 
4972 {
4973  int64_t pos = avio_tell(pb);
4974  int i, nb_chapters = FFMIN(s->nb_chapters, 255);
4975 
4976  avio_wb32(pb, 0); // size
4977  ffio_wfourcc(pb, "chpl");
4978  avio_wb32(pb, 0x01000000); // version + flags
4979  avio_wb32(pb, 0); // unknown
4980  avio_w8(pb, nb_chapters);
4981 
4982  for (i = 0; i < nb_chapters; i++) {
4983  AVChapter *c = s->chapters[i];
4984  AVDictionaryEntry *t;
4985  avio_wb64(pb, av_rescale_q(c->start, c->time_base, (AVRational){1,10000000}));
4986 
4987  if ((t = av_dict_get(c->metadata, "title", NULL, 0))) {
4988  int len = FFMIN(strlen(t->value), 255);
4989  avio_w8(pb, len);
4990  avio_write(pb, t->value, len);
4991  } else
4992  avio_w8(pb, 0);
4993  }
4994  return update_size(pb, pos);
4995 }
4996 
4998  AVFormatContext *s)
4999 {
5000  AVIOContext *pb_buf;
5001  int ret, size;
5002  uint8_t *buf;
5003 
5004  ret = avio_open_dyn_buf(&pb_buf);
5005  if (ret < 0)
5006  return ret;
5007 
5008  if (mov->mode & MODE_3GP) {
5009  mov_write_3gp_udta_tag(pb_buf, s, "perf", "artist");
5010  mov_write_3gp_udta_tag(pb_buf, s, "titl", "title");
5011  mov_write_3gp_udta_tag(pb_buf, s, "auth", "author");
5012  mov_write_3gp_udta_tag(pb_buf, s, "gnre", "genre");
5013  mov_write_3gp_udta_tag(pb_buf, s, "dscp", "comment");
5014  mov_write_3gp_udta_tag(pb_buf, s, "albm", "album");
5015  mov_write_3gp_udta_tag(pb_buf, s, "cprt", "copyright");
5016  mov_write_3gp_udta_tag(pb_buf, s, "yrrc", "date");
5017  mov_write_loci_tag(s, pb_buf);
5018  } 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
5019  mov_write_string_metadata(s, pb_buf, "\251ART", "artist", 0);
5020  mov_write_string_metadata(s, pb_buf, "\251nam", "title", 0);
5021  mov_write_string_metadata(s, pb_buf, "\251aut", "author", 0);
5022  mov_write_string_metadata(s, pb_buf, "\251alb", "album", 0);
5023  mov_write_string_metadata(s, pb_buf, "\251day", "date", 0);
5024  mov_write_string_metadata(s, pb_buf, "\251swr", "encoder", 0);
5025  // currently ignored by mov.c
5026  mov_write_string_metadata(s, pb_buf, "\251des", "comment", 0);
5027  // add support for libquicktime, this atom is also actually read by mov.c
5028  mov_write_string_metadata(s, pb_buf, "\251cmt", "comment", 0);
5029  mov_write_string_metadata(s, pb_buf, "\251gen", "genre", 0);
5030  mov_write_string_metadata(s, pb_buf, "\251cpy", "copyright", 0);
5031  mov_write_string_metadata(s, pb_buf, "\251mak", "make", 0);
5032  mov_write_string_metadata(s, pb_buf, "\251mod", "model", 0);
5033  mov_write_string_metadata(s, pb_buf, "\251xyz", "location", 0);
5034  mov_write_string_metadata(s, pb_buf, "\251key", "keywords", 0);
5035  mov_write_raw_metadata_tag(s, pb_buf, "XMP_", "xmp");
5036  } else {
5037  /* iTunes meta data */
5038  mov_write_meta_tag(pb_buf, mov, s);
5039  mov_write_loci_tag(s, pb_buf);
5040  }
5041 
5042  if (s->nb_chapters && !(mov->flags & FF_MOV_FLAG_DISABLE_CHPL))
5043  mov_write_chpl_tag(pb_buf, s);
5044 
5045  if ((size = avio_get_dyn_buf(pb_buf, &buf)) > 0) {
5046  avio_wb32(pb, size + 8);
5047  ffio_wfourcc(pb, "udta");
5048  avio_write(pb, buf, size);
5049  }
5050  ffio_free_dyn_buf(&pb_buf);
5051 
5052  return 0;
5053 }
5054 
5056  const char *str, const char *lang, int type)
5057 {
5058  int len = utf8len(str) + 1;
5059  if (len <= 0)
5060  return;
5061  avio_wb16(pb, len * 2 + 10); /* size */
5062  avio_wb32(pb, type); /* type */
5063  avio_wb16(pb, language_code(lang)); /* language */
5064  avio_wb16(pb, 0x01); /* ? */
5065  ascii_to_wc(pb, str);
5066 }
5067 
5069 {
5070  AVDictionaryEntry *title = av_dict_get(s->metadata, "title", NULL, 0);
5071  int64_t pos, pos2;
5072 
5073  if (title) {
5074  pos = avio_tell(pb);
5075  avio_wb32(pb, 0); /* size placeholder*/
5076  ffio_wfourcc(pb, "uuid");
5077  ffio_wfourcc(pb, "USMT");
5078  avio_wb32(pb, 0x21d24fce); /* 96 bit UUID */
5079  avio_wb32(pb, 0xbb88695c);
5080  avio_wb32(pb, 0xfac9c740);
5081 
5082  pos2 = avio_tell(pb);
5083  avio_wb32(pb, 0); /* size placeholder*/
5084  ffio_wfourcc(pb, "MTDT");
5085  avio_wb16(pb, 4);
5086 
5087  // ?
5088  avio_wb16(pb, 0x0C); /* size */
5089  avio_wb32(pb, 0x0B); /* type */
5090  avio_wb16(pb, language_code("und")); /* language */
5091  avio_wb16(pb, 0x0); /* ? */
5092  avio_wb16(pb, 0x021C); /* data */
5093 
5094  if (!(s->flags & AVFMT_FLAG_BITEXACT))
5095  mov_write_psp_udta_tag(pb, LIBAVFORMAT_IDENT, "eng", 0x04);
5096  mov_write_psp_udta_tag(pb, title->value, "eng", 0x01);
5097  mov_write_psp_udta_tag(pb, "2006/04/01 11:11:11", "und", 0x03);
5098 
5099  update_size(pb, pos2);
5100  return update_size(pb, pos);
5101  }
5102 
5103  return 0;
5104 }
5105 
5107 {
5112  if (!sd)
5113  return 0;
5114 
5116  for (AVEncryptionInitInfo *copy = info; copy; copy = copy->next) {
5117  int64_t pos;
5118 
5119  if (!copy->data_size && !copy->num_key_ids)
5120  continue;
5121 
5122  pos = avio_tell(pb);
5123  avio_wb32(pb, 0); /* size placeholder */
5124  ffio_wfourcc(pb, "pssh");
5125  avio_w8(pb, 1); /* version */
5126  avio_wb24(pb, 0);
5127  for (int i = 0; i < copy->system_id_size; i++)
5128  avio_w8(pb, copy->system_id[i]);
5129  avio_wb32(pb, copy->num_key_ids);
5130  for (int i = 0; i < copy->num_key_ids; i++)
5131  for (int j = 0; j < copy->key_id_size; j++)
5132  avio_w8(pb, copy->key_ids[i][j]);
5133  avio_wb32(pb, copy->data_size);
5134  avio_write(pb, copy->data, copy->data_size);
5135  update_size(pb, pos);
5136  }
5137 
5139 
5140  return 0;
5141 }
5142 
5143 static void build_chunks(MOVTrack *trk)
5144 {
5145  int i;
5146  MOVIentry *chunk = &trk->cluster[0];
5147  uint64_t chunkSize = chunk->size;
5148  chunk->chunkNum = 1;
5149  if (trk->chunkCount)
5150  return;
5151  trk->chunkCount = 1;
5152  for (i = 1; i<trk->entry; i++){
5153  if (chunk->pos + chunkSize == trk->cluster[i].pos &&
5154  chunk->stsd_index == trk->cluster[i].stsd_index &&
5155  chunkSize + trk->cluster[i].size < (1<<20)){
5156  chunkSize += trk->cluster[i].size;
5157  chunk->samples_in_chunk += trk->cluster[i].entries;
5158  } else {
5159  trk->cluster[i].chunkNum = chunk->chunkNum+1;
5160  chunk=&trk->cluster[i];
5161  chunkSize = chunk->size;
5162  trk->chunkCount++;
5163  }
5164  }
5165 }
5166 
5167 /**
5168  * Assign track ids. If option "use_stream_ids_as_track_ids" is set,
5169  * the stream ids are used as track ids.
5170  *
5171  * This assumes mov->tracks and s->streams are in the same order and
5172  * there are no gaps in either of them (so mov->tracks[n] refers to
5173  * s->streams[n]).
5174  *
5175  * As an exception, there can be more entries in
5176  * s->streams than in mov->tracks, in which case new track ids are
5177  * generated (starting after the largest found stream id).
5178  */
5180 {
5181  int i;
5182 
5183  if (mov->track_ids_ok)
5184  return 0;
5185 
5186  if (mov->use_stream_ids_as_track_ids) {
5187  int next_generated_track_id = 0;
5188  for (i = 0; i < mov->nb_streams; i++) {
5189  AVStream *st = mov->tracks[i].st;
5190  if (st->id > next_generated_track_id)
5191  next_generated_track_id = st->id;
5192  }
5193 
5194  for (i = 0; i < mov->nb_tracks; i++) {
5195  if (mov->tracks[i].entry <= 0 && !(mov->flags & FF_MOV_FLAG_FRAGMENT))
5196  continue;
5197 
5198  mov->tracks[i].track_id = i >= mov->nb_streams ? ++next_generated_track_id : mov->tracks[i].st->id;
5199  }
5200  } else {
5201  int last_track_id = 0;
5202  for (i = 0; i < mov->nb_tracks; i++) {
5203  if (mov->tracks[i].entry <= 0 && !(mov->flags & FF_MOV_FLAG_FRAGMENT))
5204  continue;
5205 
5206  last_track_id =
5207  mov->tracks[i].track_id = (mov->tracks[i].st
5208  ? FFMAX(mov->tracks[i].st->index, last_track_id)
5209  : FFMAX(i, last_track_id)) + 1;
5210  }
5211  }
5212 
5213  mov->track_ids_ok = 1;
5214 
5215  return 0;
5216 }
5217 
5219  AVFormatContext *s)
5220 {
5221  int i;
5222  int64_t pos = avio_tell(pb);
5223  avio_wb32(pb, 0); /* size placeholder*/
5224  ffio_wfourcc(pb, "moov");
5225 
5226  mov_setup_track_ids(mov, s);
5227 
5228  for (i = 0; i < mov->nb_tracks; i++) {
5229  if (mov->tracks[i].entry <= 0 && !(mov->flags & FF_MOV_FLAG_FRAGMENT))
5230  continue;
5231 
5232  mov->tracks[i].time = mov->time;
5233 
5234  if (mov->tracks[i].entry)
5235  build_chunks(&mov->tracks[i]);
5236  }
5237 
5238  if (mov->chapter_track)
5239  for (i = 0; i < mov->nb_streams; i++) {
5240  mov->tracks[i].tref_tag = MKTAG('c','h','a','p');
5241  mov->tracks[i].tref_id = mov->tracks[mov->chapter_track].track_id;
5242  }
5243  for (i = 0; i < mov->nb_tracks; i++) {
5244  MOVTrack *track = &mov->tracks[i];
5245  if (track->tag == MKTAG('r','t','p',' ')) {
5246  track->tref_tag = MKTAG('h','i','n','t');
5247  track->tref_id = mov->tracks[track->src_track].track_id;
5248  } else if (track->tag == MKTAG('l','v','c','1')) {
5249  track->tref_tag = MKTAG('s','b','a','s');
5250  track->tref_id = mov->tracks[track->src_track].track_id;
5251  } else if (track->par->codec_type == AVMEDIA_TYPE_AUDIO) {
5253  track->st->codecpar->nb_coded_side_data,
5255  if (sd && sd->size == sizeof(int)) {
5256  int *fallback = (int *)sd->data;
5257  if (*fallback >= 0 && *fallback < mov->nb_tracks) {
5258  track->tref_tag = MKTAG('f','a','l','l');
5259  track->tref_id = mov->tracks[*fallback].track_id;
5260  }
5261  }
5262  }
5263  }
5264  for (i = 0; i < mov->nb_tracks; i++) {
5265  if (mov->tracks[i].tag == MKTAG('t','m','c','d')) {
5266  int src_trk = mov->tracks[i].src_track;
5267  mov->tracks[src_trk].tref_tag = mov->tracks[i].tag;
5268  mov->tracks[src_trk].tref_id = mov->tracks[i].track_id;
5269  //src_trk may have a different timescale than the tmcd track
5270  mov->tracks[i].track_duration = av_rescale(mov->tracks[src_trk].track_duration,
5271  mov->tracks[i].timescale,
5272  mov->tracks[src_trk].timescale);
5273  }
5274  }
5275 
5276  mov_write_mvhd_tag(pb, mov);
5277  if (mov->mode != MODE_MOV && mov->mode != MODE_AVIF && !mov->iods_skip)
5278  mov_write_iods_tag(pb, mov);
5279  for (i = 0; i < mov->nb_tracks; i++) {
5280  if (mov->tracks[i].entry > 0 || mov->flags & FF_MOV_FLAG_FRAGMENT ||
5281  mov->mode == MODE_AVIF) {
5282  int ret = mov_write_trak_tag(s, pb, mov, &(mov->tracks[i]), i < mov->nb_streams ? mov->tracks[i].st : NULL);
5283  if (ret < 0)
5284  return ret;
5285  }
5286  }
5287  /* Don't write mvex for hybrid_fragmented during mov_write_trailer
5288  * (mov->moov_written != 0)
5289  */
5290  if (mov->flags & FF_MOV_FLAG_FRAGMENT &&
5292  mov_write_mvex_tag(pb, mov); /* QuickTime requires trak to precede this */
5293 
5294  if (mov->mode == MODE_PSP)
5296  else if (mov->mode != MODE_AVIF)
5297  mov_write_udta_tag(pb, mov, s);
5298  for (i = 0; i < mov->nb_streams; i++)
5299  mov_write_pssh_tag(pb, mov->tracks[i].st);
5300 
5301  return update_size(pb, pos);
5302 }
5303 
5304 static void param_write_int(AVIOContext *pb, const char *name, int value)
5305 {
5306  avio_printf(pb, "<param name=\"%s\" value=\"%d\" valuetype=\"data\"/>\n", name, value);
5307 }
5308 
5309 static void param_write_string(AVIOContext *pb, const char *name, const char *value)
5310 {
5311  avio_printf(pb, "<param name=\"%s\" value=\"%s\" valuetype=\"data\"/>\n", name, value);
5312 }
5313 
5314 static void param_write_hex(AVIOContext *pb, const char *name, const uint8_t *value, int len)
5315 {
5316  char buf[150];
5317  len = FFMIN(sizeof(buf) / 2 - 1, len);
5318  ff_data_to_hex(buf, value, len, 0);
5319  avio_printf(pb, "<param name=\"%s\" value=\"%s\" valuetype=\"data\"/>\n", name, buf);
5320 }
5321 
5323 {
5324  int64_t pos = avio_tell(pb);
5325  int i;
5326 
5327  static const AVUUID uuid = {
5328  0xa5, 0xd4, 0x0b, 0x30, 0xe8, 0x14, 0x11, 0xdd,
5329  0xba, 0x2f, 0x08, 0x00, 0x20, 0x0c, 0x9a, 0x66
5330  };
5331 
5332  avio_wb32(pb, 0);
5333  ffio_wfourcc(pb, "uuid");
5334  avio_write(pb, uuid, AV_UUID_LEN);
5335  avio_wb32(pb, 0);
5336 
5337  avio_printf(pb, "<?xml version=\"1.0\" encoding=\"utf-8\"?>\n");
5338  avio_printf(pb, "<smil xmlns=\"http://www.w3.org/2001/SMIL20/Language\">\n");
5339  avio_printf(pb, "<head>\n");
5340  if (!(mov->fc->flags & AVFMT_FLAG_BITEXACT))
5341  avio_printf(pb, "<meta name=\"creator\" content=\"%s\" />\n",
5343  avio_printf(pb, "</head>\n");
5344  avio_printf(pb, "<body>\n");
5345  avio_printf(pb, "<switch>\n");
5346 
5347  mov_setup_track_ids(mov, s);
5348 
5349  for (i = 0; i < mov->nb_tracks; i++) {
5350  MOVTrack *track = &mov->tracks[i];
5351  struct mpeg4_bit_rate_values bit_rates =
5353  const char *type;
5354  int track_id = track->track_id;
5355  char track_name_buf[32] = { 0 };
5356 
5357  AVStream *st = track->st;
5358  AVDictionaryEntry *lang = av_dict_get(st->metadata, "language", NULL,0);
5359 
5360  if (track->par->codec_type == AVMEDIA_TYPE_VIDEO && !is_cover_image(st)) {
5361  type = "video";
5362  } else if (track->par->codec_type == AVMEDIA_TYPE_AUDIO) {
5363  type = "audio";
5364  } else {
5365  continue;
5366  }
5367 
5368  avio_printf(pb, "<%s systemBitrate=\"%"PRIu32"\">\n", type,
5369  bit_rates.avg_bit_rate);
5370  param_write_int(pb, "systemBitrate", bit_rates.avg_bit_rate);
5371  param_write_int(pb, "trackID", track_id);
5372  param_write_string(pb, "systemLanguage", lang ? lang->value : "und");
5373 
5374  /* Build track name piece by piece: */
5375  /* 1. track type */
5376  av_strlcat(track_name_buf, type, sizeof(track_name_buf));
5377  /* 2. track language, if available */
5378  if (lang)
5379  av_strlcatf(track_name_buf, sizeof(track_name_buf),
5380  "_%s", lang->value);
5381  /* 3. special type suffix */
5382  /* "_cc" = closed captions, "_ad" = audio_description */
5384  av_strlcat(track_name_buf, "_cc", sizeof(track_name_buf));
5386  av_strlcat(track_name_buf, "_ad", sizeof(track_name_buf));
5387 
5388  param_write_string(pb, "trackName", track_name_buf);
5389 
5390  if (track->par->codec_type == AVMEDIA_TYPE_VIDEO) {
5391  if (track->par->codec_id == AV_CODEC_ID_H264) {
5392  uint8_t *ptr;
5393  int size = track->extradata_size[track->last_stsd_index];
5394  if (!ff_avc_write_annexb_extradata(track->extradata[track->last_stsd_index], &ptr,
5395  &size)) {
5396  param_write_hex(pb, "CodecPrivateData",
5397  ptr ? ptr : track->extradata[track->last_stsd_index],
5398  size);
5399  av_free(ptr);
5400  }
5401  param_write_string(pb, "FourCC", "H264");
5402  } else if (track->par->codec_id == AV_CODEC_ID_VC1) {
5403  param_write_string(pb, "FourCC", "WVC1");
5404  param_write_hex(pb, "CodecPrivateData", track->extradata[track->last_stsd_index],
5405  track->extradata_size[track->last_stsd_index]);
5406  }
5407  param_write_int(pb, "MaxWidth", track->par->width);
5408  param_write_int(pb, "MaxHeight", track->par->height);
5409  param_write_int(pb, "DisplayWidth", track->par->width);
5410  param_write_int(pb, "DisplayHeight", track->par->height);
5411  } else {
5412  if (track->par->codec_id == AV_CODEC_ID_AAC) {
5413  switch (track->par->profile) {
5414  case AV_PROFILE_AAC_HE_V2:
5415  param_write_string(pb, "FourCC", "AACP");
5416  break;
5417  case AV_PROFILE_AAC_HE:
5418  param_write_string(pb, "FourCC", "AACH");
5419  break;
5420  default:
5421  param_write_string(pb, "FourCC", "AACL");
5422  }
5423  } else if (track->par->codec_id == AV_CODEC_ID_WMAPRO) {
5424  param_write_string(pb, "FourCC", "WMAP");
5425  }
5426  param_write_hex(pb, "CodecPrivateData", track->extradata[track->last_stsd_index],
5427  track->extradata_size[track->last_stsd_index]);
5429  track->par->codec_id));
5430  param_write_int(pb, "Channels", track->par->ch_layout.nb_channels);
5431  param_write_int(pb, "SamplingRate", track->tag == MKTAG('i','a','m','f') ?
5432  0 : track->par->sample_rate);
5433  param_write_int(pb, "BitsPerSample", 16);
5434  param_write_int(pb, "PacketSize", track->par->block_align ?
5435  track->par->block_align : 4);
5436  }
5437  avio_printf(pb, "</%s>\n", type);
5438  }
5439  avio_printf(pb, "</switch>\n");
5440  avio_printf(pb, "</body>\n");
5441  avio_printf(pb, "</smil>\n");
5442 
5443  return update_size(pb, pos);
5444 }
5445 
5447 {
5448  avio_wb32(pb, 16);
5449  ffio_wfourcc(pb, "mfhd");
5450  avio_wb32(pb, 0);
5451  avio_wb32(pb, mov->fragments);
5452  return 0;
5453 }
5454 
5455 static uint32_t get_sample_flags(MOVTrack *track, MOVIentry *entry)
5456 {
5459 }
5460 
5462  MOVTrack *track, int64_t moof_offset)
5463 {
5464  int64_t pos = avio_tell(pb);
5467  if (!track->entry) {
5469  } else {
5471  }
5474  if (mov->flags & FF_MOV_FLAG_DEFAULT_BASE_MOOF) {
5477  }
5478  /* CMAF requires all values to be explicit in tfhd atoms */
5479  if (mov->flags & FF_MOV_FLAG_CMAF)
5481 
5482  /* Don't set a default sample size, the silverlight player refuses
5483  * to play files with that set. Don't set a default sample duration,
5484  * WMP freaks out if it is set. Don't set a base data offset, PIFF
5485  * file format says it MUST NOT be set. */
5486  if (track->mode == MODE_ISM)
5489 
5490  avio_wb32(pb, 0); /* size placeholder */
5491  ffio_wfourcc(pb, "tfhd");
5492  avio_w8(pb, 0); /* version */
5493  avio_wb24(pb, flags);
5494 
5495  avio_wb32(pb, track->track_id); /* track-id */
5497  avio_wb64(pb, moof_offset);
5498  if (flags & MOV_TFHD_STSD_ID) {
5499  avio_wb32(pb, 1);
5500  }
5502  track->default_duration = get_cluster_duration(track, 0);
5503  avio_wb32(pb, track->default_duration);
5504  }
5505  if (flags & MOV_TFHD_DEFAULT_SIZE) {
5506  track->default_size = track->entry ? track->cluster[0].size : 1;
5507  avio_wb32(pb, track->default_size);
5508  } else
5509  track->default_size = -1;
5510 
5511  if (flags & MOV_TFHD_DEFAULT_FLAGS) {
5512  /* Set the default flags based on the second sample, if available.
5513  * If the first sample is different, that can be signaled via a separate field. */
5514  if (track->entry > 1)
5515  track->default_sample_flags = get_sample_flags(track, &track->cluster[1]);
5516  else
5517  track->default_sample_flags =
5518  track->par->codec_type == AVMEDIA_TYPE_VIDEO ?
5521  avio_wb32(pb, track->default_sample_flags);
5522  }
5523 
5524  return update_size(pb, pos);
5525 }
5526 
5528  MOVTrack *track, int moof_size,
5529  int first, int end)
5530 {
5531  int64_t pos = avio_tell(pb);
5532  uint32_t flags = MOV_TRUN_DATA_OFFSET;
5533  int i;
5534 
5535  for (i = first; i < end; i++) {
5536  if (get_cluster_duration(track, i) != track->default_duration)
5538  if (track->cluster[i].size != track->default_size)
5540  if (i > first && get_sample_flags(track, &track->cluster[i]) != track->default_sample_flags)
5542  }
5543  if (!(flags & MOV_TRUN_SAMPLE_FLAGS) && track->entry > first &&
5544  get_sample_flags(track, &track->cluster[first]) != track->default_sample_flags)
5546  if (track->flags & MOV_TRACK_CTTS)
5548 
5549  avio_wb32(pb, 0); /* size placeholder */
5550  ffio_wfourcc(pb, "trun");
5552  avio_w8(pb, 1); /* version */
5553  else
5554  avio_w8(pb, 0); /* version */
5555  avio_wb24(pb, flags);
5556 
5557  avio_wb32(pb, end - first); /* sample count */
5558  if (mov->flags & FF_MOV_FLAG_OMIT_TFHD_OFFSET &&
5560  !mov->first_trun)
5561  avio_wb32(pb, 0); /* Later tracks follow immediately after the previous one */
5562  else
5563  avio_wb32(pb, moof_size + 8 + track->data_offset +
5564  track->cluster[first].pos); /* data offset */
5566  avio_wb32(pb, get_sample_flags(track, &track->cluster[first]));
5567 
5568  for (i = first; i < end; i++) {
5570  avio_wb32(pb, get_cluster_duration(track, i));
5572  avio_wb32(pb, track->cluster[i].size);
5574  avio_wb32(pb, get_sample_flags(track, &track->cluster[i]));
5575  if (flags & MOV_TRUN_SAMPLE_CTS)
5576  avio_wb32(pb, track->cluster[i].cts);
5577  }
5578 
5579  mov->first_trun = 0;
5580  return update_size(pb, pos);
5581 }
5582 
5583 static int mov_write_tfxd_tag(AVIOContext *pb, MOVTrack *track)
5584 {
5585  int64_t pos = avio_tell(pb);
5586  static const uint8_t uuid[] = {
5587  0x6d, 0x1d, 0x9b, 0x05, 0x42, 0xd5, 0x44, 0xe6,
5588  0x80, 0xe2, 0x14, 0x1d, 0xaf, 0xf7, 0x57, 0xb2
5589  };
5590 
5591  avio_wb32(pb, 0); /* size placeholder */
5592  ffio_wfourcc(pb, "uuid");
5593  avio_write(pb, uuid, AV_UUID_LEN);
5594  avio_w8(pb, 1);
5595  avio_wb24(pb, 0);
5596  avio_wb64(pb, track->cluster[0].dts + track->cluster[0].cts);
5597  avio_wb64(pb, track->end_pts -
5598  (track->cluster[0].dts + track->cluster[0].cts));
5599 
5600  return update_size(pb, pos);
5601 }
5602 
5604  MOVTrack *track, int entry)
5605 {
5606  int n = track->nb_frag_info - 1 - entry, i;
5607  int size = 8 + 16 + 4 + 1 + 16*n;
5608  static const uint8_t uuid[] = {
5609  0xd4, 0x80, 0x7e, 0xf2, 0xca, 0x39, 0x46, 0x95,
5610  0x8e, 0x54, 0x26, 0xcb, 0x9e, 0x46, 0xa7, 0x9f
5611  };
5612 
5613  if (entry < 0)
5614  return 0;
5615 
5616  avio_seek(pb, track->frag_info[entry].tfrf_offset, SEEK_SET);
5617  avio_wb32(pb, size);
5618  ffio_wfourcc(pb, "uuid");
5619  avio_write(pb, uuid, AV_UUID_LEN);
5620  avio_w8(pb, 1);
5621  avio_wb24(pb, 0);
5622  avio_w8(pb, n);
5623  for (i = 0; i < n; i++) {
5624  int index = entry + 1 + i;
5625  avio_wb64(pb, track->frag_info[index].time);
5626  avio_wb64(pb, track->frag_info[index].duration);
5627  }
5628  if (n < mov->ism_lookahead) {
5629  int free_size = 16 * (mov->ism_lookahead - n);
5630  avio_wb32(pb, free_size);
5631  ffio_wfourcc(pb, "free");
5632  ffio_fill(pb, 0, free_size - 8);
5633  }
5634 
5635  return 0;
5636 }
5637 
5639  MOVTrack *track)
5640 {
5641  int64_t pos = avio_tell(pb);
5642  int i;
5643  for (i = 0; i < mov->ism_lookahead; i++) {
5644  /* Update the tfrf tag for the last ism_lookahead fragments,
5645  * nb_frag_info - 1 is the next fragment to be written. */
5646  mov_write_tfrf_tag(pb, mov, track, track->nb_frag_info - 2 - i);
5647  }
5648  avio_seek(pb, pos, SEEK_SET);
5649  return 0;
5650 }
5651 
5652 static int mov_add_tfra_entries(AVIOContext *pb, MOVMuxContext *mov, int tracks,
5653  int size)
5654 {
5655  int i;
5656  for (i = 0; i < mov->nb_tracks; i++) {
5657  MOVTrack *track = &mov->tracks[i];
5659  if ((tracks >= 0 && i != tracks) || !track->entry)
5660  continue;
5661  track->nb_frag_info++;
5662  if (track->nb_frag_info >= track->frag_info_capacity) {
5663  unsigned new_capacity = track->nb_frag_info + MOV_FRAG_INFO_ALLOC_INCREMENT;
5664  if (av_reallocp_array(&track->frag_info,
5665  new_capacity,
5666  sizeof(*track->frag_info)))
5667  return AVERROR(ENOMEM);
5668  track->frag_info_capacity = new_capacity;
5669  }
5670  info = &track->frag_info[track->nb_frag_info - 1];
5671  info->offset = avio_tell(pb);
5672  info->size = size;
5673  // Try to recreate the original pts for the first packet
5674  // from the fields we have stored
5675  info->time = track->cluster[0].dts + track->cluster[0].cts;
5676  info->duration = track->end_pts -
5677  (track->cluster[0].dts + track->cluster[0].cts);
5678  // If the pts is less than zero, we will have trimmed
5679  // away parts of the media track using an edit list,
5680  // and the corresponding start presentation time is zero.
5681  if (info->time < 0) {
5682  info->duration += info->time;
5683  info->time = 0;
5684  }
5685  info->tfrf_offset = 0;
5686  mov_write_tfrf_tags(pb, mov, track);
5687  }
5688  return 0;
5689 }
5690 
5691 static void mov_prune_frag_info(MOVMuxContext *mov, int tracks, int max)
5692 {
5693  int i;
5694  for (i = 0; i < mov->nb_tracks; i++) {
5695  MOVTrack *track = &mov->tracks[i];
5696  if ((tracks >= 0 && i != tracks) || !track->entry)
5697  continue;
5698  if (track->nb_frag_info > max) {
5699  memmove(track->frag_info, track->frag_info + (track->nb_frag_info - max), max * sizeof(*track->frag_info));
5700  track->nb_frag_info = max;
5701  }
5702  }
5703 }
5704 
5705 static int mov_write_tfdt_tag(AVIOContext *pb, MOVTrack *track)
5706 {
5707  int64_t pos = avio_tell(pb);
5708 
5709  avio_wb32(pb, 0); /* size */
5710  ffio_wfourcc(pb, "tfdt");
5711  avio_w8(pb, 1); /* version */
5712  avio_wb24(pb, 0);
5713  avio_wb64(pb, track->cluster[0].dts - track->start_dts);
5714  return update_size(pb, pos);
5715 }
5716 
5718  MOVTrack *track, int64_t moof_offset,
5719  int moof_size)
5720 {
5721  int64_t pos = avio_tell(pb);
5722  int i, start = 0;
5723  avio_wb32(pb, 0); /* size placeholder */
5724  ffio_wfourcc(pb, "traf");
5725 
5726  mov_write_tfhd_tag(pb, mov, track, moof_offset);
5727  if (mov->mode != MODE_ISM)
5728  mov_write_tfdt_tag(pb, track);
5729  for (i = 1; i < track->entry; i++) {
5730  if (track->cluster[i].pos != track->cluster[i - 1].pos + track->cluster[i - 1].size) {
5731  mov_write_trun_tag(pb, mov, track, moof_size, start, i);
5732  start = i;
5733  }
5734  }
5735  mov_write_trun_tag(pb, mov, track, moof_size, start, track->entry);
5736  if (mov->mode == MODE_ISM) {
5737  mov_write_tfxd_tag(pb, track);
5738 
5739  if (mov->ism_lookahead) {
5740  int size = 16 + 4 + 1 + 16 * mov->ism_lookahead;
5741 
5742  if (track->nb_frag_info > 0) {
5743  MOVFragmentInfo *info = &track->frag_info[track->nb_frag_info - 1];
5744  if (!info->tfrf_offset)
5745  info->tfrf_offset = avio_tell(pb);
5746  }
5747  avio_wb32(pb, 8 + size);
5748  ffio_wfourcc(pb, "free");
5749  ffio_fill(pb, 0, size);
5750  }
5751  }
5752 
5753  if (track->cenc.aes_ctr && (mov->flags & FF_MOV_FLAG_FRAGMENT))
5754  ff_mov_cenc_write_stbl_atoms(&track->cenc, pb, moof_offset);
5755 
5756  return update_size(pb, pos);
5757 }
5758 
5760  int tracks, int moof_size)
5761 {
5762  int64_t pos = avio_tell(pb);
5763  int i;
5764 
5765  avio_wb32(pb, 0); /* size placeholder */
5766  ffio_wfourcc(pb, "moof");
5767  mov->first_trun = 1;
5768 
5769  mov_write_mfhd_tag(pb, mov);
5770  for (i = 0; i < mov->nb_tracks; i++) {
5771  MOVTrack *track = &mov->tracks[i];
5772  if (tracks >= 0 && i != tracks)
5773  continue;
5774  if (!track->entry)
5775  continue;
5776  if (track->cenc.aes_ctr && (mov->flags & FF_MOV_FLAG_FRAGMENT))
5777  mov_write_pssh_tag(pb, track->st);
5778  mov_write_traf_tag(pb, mov, track, pos, moof_size);
5779  }
5780 
5781  return update_size(pb, pos);
5782 }
5783 
5785  MOVTrack *track, int ref_size, int total_sidx_size)
5786 {
5787  int64_t pos = avio_tell(pb), offset_pos, end_pos;
5788  int64_t presentation_time, duration, offset;
5789  unsigned starts_with_SAP;
5790  int i, entries;
5791 
5792  if (track->entry) {
5793  entries = 1;
5794  presentation_time = track->cluster[0].dts + track->cluster[0].cts;
5795  duration = track->end_pts -
5796  (track->cluster[0].dts + track->cluster[0].cts);
5797  starts_with_SAP = track->cluster[0].flags & MOV_SYNC_SAMPLE;
5798 
5799  // pts<0 should be cut away using edts
5800  if (presentation_time < 0) {
5801  duration += presentation_time;
5802  presentation_time = 0;
5803  }
5804  } else {
5805  entries = track->nb_frag_info;
5806  if (entries <= 0)
5807  return 0;
5808  presentation_time = track->frag_info[0].time;
5809  }
5810 
5811  avio_wb32(pb, 0); /* size */
5812  ffio_wfourcc(pb, "sidx");
5813  avio_w8(pb, 1); /* version */
5814  avio_wb24(pb, 0);
5815  avio_wb32(pb, track->track_id); /* reference_ID */
5816  avio_wb32(pb, track->timescale); /* timescale */
5817  avio_wb64(pb, presentation_time); /* earliest_presentation_time */
5818  offset_pos = avio_tell(pb);
5819  avio_wb64(pb, 0); /* first_offset (offset to referenced moof) */
5820  avio_wb16(pb, 0); /* reserved */
5821 
5822  avio_wb16(pb, entries); /* reference_count */
5823  for (i = 0; i < entries; i++) {
5824  if (!track->entry) {
5825  if (i > 1 && track->frag_info[i].offset != track->frag_info[i - 1].offset + track->frag_info[i - 1].size) {
5826  av_log(NULL, AV_LOG_ERROR, "Non-consecutive fragments, writing incorrect sidx\n");
5827  }
5828  duration = track->frag_info[i].duration;
5829  ref_size = track->frag_info[i].size;
5830  starts_with_SAP = 1;
5831  }
5832  avio_wb32(pb, (0 << 31) | (ref_size & 0x7fffffff)); /* reference_type (0 = media) | referenced_size */
5833  avio_wb32(pb, duration); /* subsegment_duration */
5834  avio_wb32(pb, (starts_with_SAP << 31) | (0 << 28) | 0); /* starts_with_SAP | SAP_type | SAP_delta_time */
5835  }
5836 
5837  end_pos = avio_tell(pb);
5838  offset = pos + total_sidx_size - end_pos;
5839  avio_seek(pb, offset_pos, SEEK_SET);
5840  avio_wb64(pb, offset);
5841  avio_seek(pb, end_pos, SEEK_SET);
5842  return update_size(pb, pos);
5843 }
5844 
5846  int tracks, int ref_size)
5847 {
5848  int i, round, ret;
5849  AVIOContext *avio_buf;
5850  int total_size = 0;
5851  for (round = 0; round < 2; round++) {
5852  // First run one round to calculate the total size of all
5853  // sidx atoms.
5854  // This would be much simpler if we'd only write one sidx
5855  // atom, for the first track in the moof.
5856  if (round == 0) {
5857  if ((ret = ffio_open_null_buf(&avio_buf)) < 0)
5858  return ret;
5859  } else {
5860  avio_buf = pb;
5861  }
5862  for (i = 0; i < mov->nb_tracks; i++) {
5863  MOVTrack *track = &mov->tracks[i];
5864  if (tracks >= 0 && i != tracks)
5865  continue;
5866  // When writing a sidx for the full file, entry is 0, but
5867  // we want to include all tracks. ref_size is 0 in this case,
5868  // since we read it from frag_info instead.
5869  if (!track->entry && ref_size > 0)
5870  continue;
5871  total_size -= mov_write_sidx_tag(avio_buf, track, ref_size,
5872  total_size);
5873  }
5874  if (round == 0) {
5875  total_size = ffio_close_null_buf(avio_buf);
5876  if (total_size < 0)
5877  return total_size;
5878  }
5879  }
5880  return 0;
5881 }
5882 
5883 static int mov_write_prft_tag(AVIOContext *pb, MOVMuxContext *mov, int tracks)
5884 {
5885  int64_t pos = avio_tell(pb), pts_us, ntp_ts;
5886  MOVTrack *first_track;
5887  int flags = 24;
5888 
5889  /* PRFT should be associated with at most one track. So, choosing only the
5890  * first track. */
5891  if (tracks > 0)
5892  return 0;
5893  first_track = &(mov->tracks[0]);
5894 
5895  if (!first_track->entry) {
5896  av_log(mov->fc, AV_LOG_WARNING, "Unable to write PRFT, no entries in the track\n");
5897  return 0;
5898  }
5899 
5900  if (first_track->cluster[0].pts == AV_NOPTS_VALUE) {
5901  av_log(mov->fc, AV_LOG_WARNING, "Unable to write PRFT, first PTS is invalid\n");
5902  return 0;
5903  }
5904 
5905  if (mov->write_prft == MOV_PRFT_SRC_WALLCLOCK) {
5906  if (first_track->cluster[0].prft.wallclock) {
5907  /* Round the NTP time to whole milliseconds. */
5908  ntp_ts = ff_get_formatted_ntp_time((first_track->cluster[0].prft.wallclock / 1000) * 1000 +
5909  NTP_OFFSET_US);
5910  flags = first_track->cluster[0].prft.flags;
5911  } else
5913  } else if (mov->write_prft == MOV_PRFT_SRC_PTS) {
5914  pts_us = av_rescale_q(first_track->cluster[0].pts,
5915  first_track->st->time_base, AV_TIME_BASE_Q);
5916  ntp_ts = ff_get_formatted_ntp_time(pts_us + NTP_OFFSET_US);
5917  } else {
5918  av_log(mov->fc, AV_LOG_WARNING, "Unsupported PRFT box configuration: %d\n",
5919  mov->write_prft);
5920  return 0;
5921  }
5922 
5923  avio_wb32(pb, 0); // Size place holder
5924  ffio_wfourcc(pb, "prft"); // Type
5925  avio_w8(pb, 1); // Version
5926  avio_wb24(pb, flags); // Flags
5927  avio_wb32(pb, first_track->track_id); // reference track ID
5928  avio_wb64(pb, ntp_ts); // NTP time stamp
5929  avio_wb64(pb, first_track->cluster[0].pts); //media time
5930  return update_size(pb, pos);
5931 }
5932 
5933 static int mov_write_moof_tag(AVIOContext *pb, MOVMuxContext *mov, int tracks,
5934  int64_t mdat_size)
5935 {
5936  AVIOContext *avio_buf;
5937  int ret, moof_size;
5938 
5939  if ((ret = ffio_open_null_buf(&avio_buf)) < 0)
5940  return ret;
5941  mov_write_moof_tag_internal(avio_buf, mov, tracks, 0);
5942  moof_size = ffio_close_null_buf(avio_buf);
5943  if (moof_size < 0)
5944  return moof_size;
5945 
5946  if (mov->flags & FF_MOV_FLAG_DASH &&
5948  mov_write_sidx_tags(pb, mov, tracks, moof_size + 8 + mdat_size);
5949 
5950  if (mov->write_prft > MOV_PRFT_NONE && mov->write_prft < MOV_PRFT_NB)
5951  mov_write_prft_tag(pb, mov, tracks);
5952 
5953  if (mov->flags & FF_MOV_FLAG_GLOBAL_SIDX ||
5954  !(mov->flags & FF_MOV_FLAG_SKIP_TRAILER) ||
5955  mov->ism_lookahead) {
5956  if ((ret = mov_add_tfra_entries(pb, mov, tracks, moof_size + 8 + mdat_size)) < 0)
5957  return ret;
5958  if (!(mov->flags & FF_MOV_FLAG_GLOBAL_SIDX) &&
5960  mov_prune_frag_info(mov, tracks, mov->ism_lookahead + 1);
5961  }
5962  }
5963 
5964  return mov_write_moof_tag_internal(pb, mov, tracks, moof_size);
5965 }
5966 
5967 static int mov_write_tfra_tag(AVIOContext *pb, MOVTrack *track)
5968 {
5969  int64_t pos = avio_tell(pb);
5970  int i;
5971 
5972  avio_wb32(pb, 0); /* size placeholder */
5973  ffio_wfourcc(pb, "tfra");
5974  avio_w8(pb, 1); /* version */
5975  avio_wb24(pb, 0);
5976 
5977  avio_wb32(pb, track->track_id);
5978  avio_wb32(pb, 0); /* length of traf/trun/sample num */
5979  avio_wb32(pb, track->nb_frag_info);
5980  for (i = 0; i < track->nb_frag_info; i++) {
5981  avio_wb64(pb, track->frag_info[i].time);
5982  avio_wb64(pb, track->frag_info[i].offset + track->data_offset);
5983  avio_w8(pb, 1); /* traf number */
5984  avio_w8(pb, 1); /* trun number */
5985  avio_w8(pb, 1); /* sample number */
5986  }
5987 
5988  return update_size(pb, pos);
5989 }
5990 
5992 {
5993  AVIOContext *mfra_pb;
5994  int i, ret, sz;
5995  uint8_t *buf;
5996 
5997  ret = avio_open_dyn_buf(&mfra_pb);
5998  if (ret < 0)
5999  return ret;
6000 
6001  avio_wb32(mfra_pb, 0); /* size placeholder */
6002  ffio_wfourcc(mfra_pb, "mfra");
6003  /* An empty mfra atom is enough to indicate to the publishing point that
6004  * the stream has ended. */
6005  if (mov->flags & FF_MOV_FLAG_ISML)
6006  goto done_mfra;
6007 
6008  for (i = 0; i < mov->nb_tracks; i++) {
6009  MOVTrack *track = &mov->tracks[i];
6010  if (track->nb_frag_info)
6011  mov_write_tfra_tag(mfra_pb, track);
6012  }
6013 
6014  avio_wb32(mfra_pb, 16);
6015  ffio_wfourcc(mfra_pb, "mfro");
6016  avio_wb32(mfra_pb, 0); /* version + flags */
6017  avio_wb32(mfra_pb, avio_tell(mfra_pb) + 4);
6018 
6019 done_mfra:
6020 
6021  sz = update_size(mfra_pb, 0);
6022  ret = avio_get_dyn_buf(mfra_pb, &buf);
6023  avio_write(pb, buf, ret);
6024  ffio_free_dyn_buf(&mfra_pb);
6025 
6026  return sz;
6027 }
6028 
6030 {
6031  avio_wb32(pb, 8); // placeholder for extended size field (64 bit)
6032  ffio_wfourcc(pb, mov->mode == MODE_MOV ? "wide" : "free");
6033 
6034  mov->mdat_pos = avio_tell(pb);
6035  avio_wb32(pb, 0); /* size placeholder*/
6036  ffio_wfourcc(pb, "mdat");
6037  return 0;
6038 }
6039 
6041  int has_h264, int has_video, int write_minor)
6042 {
6043  MOVMuxContext *mov = s->priv_data;
6044  int minor = 0x200;
6045 
6046  if (mov->major_brand && strlen(mov->major_brand) >= 4)
6047  ffio_wfourcc(pb, mov->major_brand);
6048  else if (mov->mode == MODE_3GP) {
6049  ffio_wfourcc(pb, has_h264 ? "3gp6" : "3gp4");
6050  minor = has_h264 ? 0x100 : 0x200;
6051  } else if (mov->mode == MODE_AVIF) {
6052  ffio_wfourcc(pb, mov->is_animated_avif ? "avis" : "avif");
6053  minor = 0;
6054  } else if (mov->mode & MODE_3G2) {
6055  ffio_wfourcc(pb, has_h264 ? "3g2b" : "3g2a");
6056  minor = has_h264 ? 0x20000 : 0x10000;
6057  } else if (mov->mode == MODE_PSP)
6058  ffio_wfourcc(pb, "MSNV");
6059  else if (mov->mode == MODE_MP4 && mov->flags & FF_MOV_FLAG_FRAGMENT &&
6061  ffio_wfourcc(pb, "iso6"); // Required when using signed CTS offsets in trun boxes
6062  else if (mov->mode == MODE_MP4 && mov->flags & FF_MOV_FLAG_DEFAULT_BASE_MOOF)
6063  ffio_wfourcc(pb, "iso5"); // Required when using default-base-is-moof
6064  else if (mov->mode == MODE_MP4 && mov->flags & FF_MOV_FLAG_NEGATIVE_CTS_OFFSETS)
6065  ffio_wfourcc(pb, "iso4");
6066  else if (mov->mode == MODE_MP4)
6067  ffio_wfourcc(pb, "isom");
6068  else if (mov->mode == MODE_IPOD)
6069  ffio_wfourcc(pb, has_video ? "M4V ":"M4A ");
6070  else if (mov->mode == MODE_ISM)
6071  ffio_wfourcc(pb, "isml");
6072  else if (mov->mode == MODE_F4V)
6073  ffio_wfourcc(pb, "f4v ");
6074  else
6075  ffio_wfourcc(pb, "qt ");
6076 
6077  if (write_minor)
6078  avio_wb32(pb, minor);
6079 }
6080 
6082 {
6083  MOVMuxContext *mov = s->priv_data;
6084  int64_t pos = avio_tell(pb);
6085  int has_h264 = 0, has_av1 = 0, has_video = 0, has_dolby = 0, has_id3 = 0;
6086  int has_iamf = 0;
6087 
6088 #if CONFIG_IAMFENC
6089  for (int i = 0; i < s->nb_stream_groups; i++) {
6090  const AVStreamGroup *stg = s->stream_groups[i];
6091 
6094  has_iamf = 1;
6095  break;
6096  }
6097  }
6098 #endif
6099  for (int i = 0; i < mov->nb_streams; i++) {
6100  AVStream *st = mov->tracks[i].st;
6101  if (is_cover_image(st))
6102  continue;
6104  has_video = 1;
6105  if (st->codecpar->codec_id == AV_CODEC_ID_H264)
6106  has_h264 = 1;
6107  if (st->codecpar->codec_id == AV_CODEC_ID_AV1)
6108  has_av1 = 1;
6109  if (st->codecpar->codec_id == AV_CODEC_ID_AC3 ||
6115  has_dolby = 1;
6117  has_id3 = 1;
6118  }
6119 
6120  avio_wb32(pb, 0); /* size */
6121  ffio_wfourcc(pb, "ftyp");
6122 
6123  // Write major brand
6124  mov_write_ftyp_tag_internal(pb, s, has_h264, has_video, 1);
6125  // Write the major brand as the first compatible brand as well
6126  mov_write_ftyp_tag_internal(pb, s, has_h264, has_video, 0);
6127 
6128  // Write compatible brands, ensuring that we don't write the major brand as a
6129  // compatible brand a second time.
6130  if (mov->mode == MODE_ISM) {
6131  ffio_wfourcc(pb, "piff");
6132  } else if (mov->mode == MODE_AVIF) {
6133  const AVPixFmtDescriptor *pix_fmt_desc =
6134  av_pix_fmt_desc_get(s->streams[0]->codecpar->format);
6135  const int depth = pix_fmt_desc->comp[0].depth;
6136  if (mov->is_animated_avif) {
6137  // For animated AVIF, major brand is "avis". Add "avif" as a
6138  // compatible brand.
6139  ffio_wfourcc(pb, "avif");
6140  ffio_wfourcc(pb, "msf1");
6141  ffio_wfourcc(pb, "iso8");
6142  }
6143  ffio_wfourcc(pb, "mif1");
6144  ffio_wfourcc(pb, "miaf");
6145  if (depth == 8 || depth == 10) {
6146  // MA1B and MA1A brands are based on AV1 profile. Short hand for
6147  // computing that is based on chroma subsampling type. 420 chroma
6148  // subsampling is MA1B. 444 chroma subsampling is MA1A.
6149  if (!pix_fmt_desc->log2_chroma_w && !pix_fmt_desc->log2_chroma_h) {
6150  // 444 chroma subsampling.
6151  ffio_wfourcc(pb, "MA1A");
6152  } else {
6153  // 420 chroma subsampling.
6154  ffio_wfourcc(pb, "MA1B");
6155  }
6156  }
6157  } else if (mov->mode != MODE_MOV) {
6158  // We add tfdt atoms when fragmenting, signal this with the iso6 compatible
6159  // brand, if not already the major brand. This is compatible with users that
6160  // don't understand tfdt.
6161  if (mov->mode == MODE_MP4) {
6162  if (mov->flags & FF_MOV_FLAG_CMAF)
6163  ffio_wfourcc(pb, "cmfc");
6165  ffio_wfourcc(pb, "iso6");
6166  if (has_av1)
6167  ffio_wfourcc(pb, "av01");
6168  if (has_dolby)
6169  ffio_wfourcc(pb, "dby1");
6170  if (has_iamf)
6171  ffio_wfourcc(pb, "iamf");
6172  } else {
6173  if (mov->flags & FF_MOV_FLAG_FRAGMENT)
6174  ffio_wfourcc(pb, "iso6");
6176  ffio_wfourcc(pb, "iso5");
6177  else if (mov->flags & FF_MOV_FLAG_NEGATIVE_CTS_OFFSETS)
6178  ffio_wfourcc(pb, "iso4");
6179  }
6180  // Brands prior to iso5 can't be signaled when using default-base-is-moof
6181  if (!(mov->flags & FF_MOV_FLAG_DEFAULT_BASE_MOOF)) {
6182  // write isom for mp4 only if it it's not the major brand already.
6183  if (mov->mode != MODE_MP4 || mov->flags & FF_MOV_FLAG_NEGATIVE_CTS_OFFSETS)
6184  ffio_wfourcc(pb, "isom");
6185  ffio_wfourcc(pb, "iso2");
6186  if (has_h264)
6187  ffio_wfourcc(pb, "avc1");
6188  }
6189  }
6190 
6191  if (mov->mode == MODE_MP4)
6192  ffio_wfourcc(pb, "mp41");
6193 
6194  if (mov->flags & FF_MOV_FLAG_DASH && mov->flags & FF_MOV_FLAG_GLOBAL_SIDX)
6195  ffio_wfourcc(pb, "dash");
6196 
6197  if (has_id3)
6198  ffio_wfourcc(pb, "aid3");
6199 
6200  return update_size(pb, pos);
6201 }
6202 
6204 {
6205  AVStream *video_st = s->streams[0];
6206  AVCodecParameters *video_par = s->streams[0]->codecpar;
6207  AVCodecParameters *audio_par = s->streams[1]->codecpar;
6208  int audio_rate = audio_par->sample_rate;
6209  int64_t frame_rate = video_st->avg_frame_rate.den ?
6211  0;
6212  int audio_kbitrate = audio_par->bit_rate / 1000;
6213  int video_kbitrate = FFMIN(video_par->bit_rate / 1000, 800 - audio_kbitrate);
6214 
6215  if (frame_rate < 0 || frame_rate > INT32_MAX) {
6216  av_log(s, AV_LOG_ERROR, "Frame rate %f outside supported range\n", frame_rate / (double)0x10000);
6217  return AVERROR(EINVAL);
6218  }
6219 
6220  avio_wb32(pb, 0x94); /* size */
6221  ffio_wfourcc(pb, "uuid");
6222  ffio_wfourcc(pb, "PROF");
6223 
6224  avio_wb32(pb, 0x21d24fce); /* 96 bit UUID */
6225  avio_wb32(pb, 0xbb88695c);
6226  avio_wb32(pb, 0xfac9c740);
6227 
6228  avio_wb32(pb, 0x0); /* ? */
6229  avio_wb32(pb, 0x3); /* 3 sections ? */
6230 
6231  avio_wb32(pb, 0x14); /* size */
6232  ffio_wfourcc(pb, "FPRF");
6233  avio_wb32(pb, 0x0); /* ? */
6234  avio_wb32(pb, 0x0); /* ? */
6235  avio_wb32(pb, 0x0); /* ? */
6236 
6237  avio_wb32(pb, 0x2c); /* size */
6238  ffio_wfourcc(pb, "APRF"); /* audio */
6239  avio_wb32(pb, 0x0);
6240  avio_wb32(pb, 0x2); /* TrackID */
6241  ffio_wfourcc(pb, "mp4a");
6242  avio_wb32(pb, 0x20f);
6243  avio_wb32(pb, 0x0);
6244  avio_wb32(pb, audio_kbitrate);
6245  avio_wb32(pb, audio_kbitrate);
6246  avio_wb32(pb, audio_rate);
6247  avio_wb32(pb, audio_par->ch_layout.nb_channels);
6248 
6249  avio_wb32(pb, 0x34); /* size */
6250  ffio_wfourcc(pb, "VPRF"); /* video */
6251  avio_wb32(pb, 0x0);
6252  avio_wb32(pb, 0x1); /* TrackID */
6253  if (video_par->codec_id == AV_CODEC_ID_H264) {
6254  ffio_wfourcc(pb, "avc1");
6255  avio_wb16(pb, 0x014D);
6256  avio_wb16(pb, 0x0015);
6257  } else {
6258  ffio_wfourcc(pb, "mp4v");
6259  avio_wb16(pb, 0x0000);
6260  avio_wb16(pb, 0x0103);
6261  }
6262  avio_wb32(pb, 0x0);
6263  avio_wb32(pb, video_kbitrate);
6264  avio_wb32(pb, video_kbitrate);
6265  avio_wb32(pb, frame_rate);
6266  avio_wb32(pb, frame_rate);
6267  avio_wb16(pb, video_par->width);
6268  avio_wb16(pb, video_par->height);
6269  avio_wb32(pb, 0x010001); /* ? */
6270 
6271  return 0;
6272 }
6273 
6275 {
6276  MOVMuxContext *mov = s->priv_data;
6277  int i;
6278 
6279  mov_write_ftyp_tag(pb,s);
6280  if (mov->mode == MODE_PSP) {
6281  int video_streams_nb = 0, audio_streams_nb = 0, other_streams_nb = 0;
6282  for (i = 0; i < mov->nb_streams; i++) {
6283  AVStream *st = mov->tracks[i].st;
6284  if (is_cover_image(st))
6285  continue;
6287  video_streams_nb++;
6288  else if (st->codecpar->codec_type == AVMEDIA_TYPE_AUDIO)
6289  audio_streams_nb++;
6290  else
6291  other_streams_nb++;
6292  }
6293 
6294  if (video_streams_nb != 1 || audio_streams_nb != 1 || other_streams_nb) {
6295  av_log(s, AV_LOG_ERROR, "PSP mode need one video and one audio stream\n");
6296  return AVERROR(EINVAL);
6297  }
6298  return mov_write_uuidprof_tag(pb, s);
6299  }
6300  return 0;
6301 }
6302 
6303 static int mov_parse_mpeg2_frame(AVPacket *pkt, uint32_t *flags)
6304 {
6305  uint32_t c = -1;
6306  int i, closed_gop = 0;
6307 
6308  for (i = 0; i < pkt->size - 4; i++) {
6309  c = (c << 8) + pkt->data[i];
6310  if (c == 0x1b8) { // gop
6311  closed_gop = pkt->data[i + 4] >> 6 & 0x01;
6312  } else if (c == 0x100) { // pic
6313  int temp_ref = (pkt->data[i + 1] << 2) | (pkt->data[i + 2] >> 6);
6314  if (!temp_ref || closed_gop) // I picture is not reordered
6316  else
6318  break;
6319  }
6320  }
6321  return 0;
6322 }
6323 
6325 {
6326  const uint8_t *start, *next, *end = pkt->data + pkt->size;
6327  int seq = 0, entry = 0;
6328  int key = pkt->flags & AV_PKT_FLAG_KEY;
6329  start = find_next_marker(pkt->data, end);
6330  for (next = start; next < end; start = next) {
6331  next = find_next_marker(start + 4, end);
6332  switch (AV_RB32(start)) {
6333  case VC1_CODE_SEQHDR:
6334  seq = 1;
6335  break;
6336  case VC1_CODE_ENTRYPOINT:
6337  entry = 1;
6338  break;
6339  case VC1_CODE_SLICE:
6340  trk->vc1_info.slices = 1;
6341  break;
6342  }
6343  }
6344  if (!trk->entry && trk->vc1_info.first_packet_seen)
6345  trk->vc1_info.first_frag_written = 1;
6346  if (!trk->entry && !trk->vc1_info.first_frag_written) {
6347  /* First packet in first fragment */
6348  trk->vc1_info.first_packet_seq = seq;
6350  trk->vc1_info.first_packet_seen = 1;
6351  } else if ((seq && !trk->vc1_info.packet_seq) ||
6352  (entry && !trk->vc1_info.packet_entry)) {
6353  int i;
6354  for (i = 0; i < trk->entry; i++)
6355  trk->cluster[i].flags &= ~MOV_SYNC_SAMPLE;
6356  trk->has_keyframes = 0;
6357  if (seq)
6358  trk->vc1_info.packet_seq = 1;
6359  if (entry)
6360  trk->vc1_info.packet_entry = 1;
6361  if (!trk->vc1_info.first_frag_written) {
6362  /* First fragment */
6363  if ((!seq || trk->vc1_info.first_packet_seq) &&
6364  (!entry || trk->vc1_info.first_packet_entry)) {
6365  /* First packet had the same headers as this one, readd the
6366  * sync sample flag. */
6367  trk->cluster[0].flags |= MOV_SYNC_SAMPLE;
6368  trk->has_keyframes = 1;
6369  }
6370  }
6371  }
6372  if (trk->vc1_info.packet_seq && trk->vc1_info.packet_entry)
6373  key = seq && entry;
6374  else if (trk->vc1_info.packet_seq)
6375  key = seq;
6376  else if (trk->vc1_info.packet_entry)
6377  key = entry;
6378  if (key) {
6379  trk->cluster[trk->entry].flags |= MOV_SYNC_SAMPLE;
6380  trk->has_keyframes++;
6381  }
6382 }
6383 
6385 {
6386  int length;
6387 
6388  if (pkt->size < 8)
6389  return;
6390 
6391  length = (AV_RB16(pkt->data) & 0xFFF) * 2;
6392  if (length < 8 || length > pkt->size)
6393  return;
6394 
6395  if (AV_RB32(pkt->data + 4) == 0xF8726FBA) {
6396  trk->cluster[trk->entry].flags |= MOV_SYNC_SAMPLE;
6397  trk->has_keyframes++;
6398  }
6399 
6400  return;
6401 }
6402 
6404 {
6405  MOVMuxContext *mov = s->priv_data;
6406  int ret, buf_size;
6407  uint8_t *buf;
6408  int i, offset;
6409 
6410  if (!track->mdat_buf)
6411  return 0;
6412  if (!mov->mdat_buf) {
6413  if ((ret = avio_open_dyn_buf(&mov->mdat_buf)) < 0)
6414  return ret;
6415  }
6416  buf_size = avio_get_dyn_buf(track->mdat_buf, &buf);
6417 
6418  offset = avio_tell(mov->mdat_buf);
6419  avio_write(mov->mdat_buf, buf, buf_size);
6420  ffio_reset_dyn_buf(track->mdat_buf);
6421 
6422  for (i = track->entries_flushed; i < track->entry; i++)
6423  track->cluster[i].pos += offset;
6424  track->entries_flushed = track->entry;
6425  return 0;
6426 }
6427 
6429 {
6430  MOVMuxContext *mov = s->priv_data;
6431  AVPacket *squashed_packet = mov->pkt;
6432  int ret = AVERROR_BUG;
6433 
6434  switch (track->st->codecpar->codec_id) {
6435  case AV_CODEC_ID_TTML: {
6436  int had_packets = !!track->squashed_packet_queue.head;
6437 
6438  if ((ret = ff_mov_generate_squashed_ttml_packet(s, track, squashed_packet)) < 0) {
6439  goto finish_squash;
6440  }
6441 
6442  // We have generated a padding packet (no actual input packets in
6443  // queue) and its duration is zero. Skipping writing it.
6444  if (!had_packets && squashed_packet->duration == 0) {
6445  goto finish_squash;
6446  }
6447 
6448  track->end_reliable = 1;
6449  break;
6450  }
6451  default:
6452  ret = AVERROR(EINVAL);
6453  goto finish_squash;
6454  }
6455 
6456  squashed_packet->stream_index = track->st->index;
6457 
6458  ret = mov_write_single_packet(s, squashed_packet);
6459 
6460 finish_squash:
6461  av_packet_unref(squashed_packet);
6462 
6463  return ret;
6464 }
6465 
6467 {
6468  MOVMuxContext *mov = s->priv_data;
6469 
6470  for (int i = 0; i < mov->nb_streams; i++) {
6471  MOVTrack *track = &mov->tracks[i];
6472  int ret = AVERROR_BUG;
6473 
6474  if (track->squash_fragment_samples_to_one && !track->entry) {
6475  if ((ret = mov_write_squashed_packet(s, track)) < 0) {
6477  "Failed to write squashed packet for %s stream with "
6478  "index %d and track id %d. Error: %s\n",
6480  track->st->index, track->track_id,
6481  av_err2str(ret));
6482  return ret;
6483  }
6484  }
6485  }
6486 
6487  return 0;
6488 }
6489 
6491  int64_t ref_pos)
6492 {
6493  int i;
6494  if (!track->entry)
6495  return 0;
6496  if (mov->flags & FF_MOV_FLAG_HYBRID_FRAGMENTED) {
6497  for (i = 0; i < track->entry; i++)
6498  track->cluster[i].pos += ref_pos + track->data_offset;
6499  if (track->cluster_written == 0) {
6500  // First flush. Chunking for this fragment may already have been
6501  // done, either if we didn't use empty_moov, or if we did use
6502  // delay_moov. In either case, reset chunking here.
6503  for (i = 0; i < track->entry; i++) {
6504  track->cluster[i].chunkNum = 0;
6505  track->cluster[i].samples_in_chunk = track->cluster[i].entries;
6506  }
6507  }
6508  if (av_reallocp_array(&track->cluster_written,
6509  track->entry_written + track->entry,
6510  sizeof(*track->cluster)))
6511  return AVERROR(ENOMEM);
6512  memcpy(&track->cluster_written[track->entry_written],
6513  track->cluster, track->entry * sizeof(*track->cluster));
6514  track->entry_written += track->entry;
6515  }
6516  track->entry = 0;
6517  track->entries_flushed = 0;
6518  track->end_reliable = 0;
6519  return 0;
6520 }
6521 
6522 static int mov_flush_fragment(AVFormatContext *s, int force)
6523 {
6524  MOVMuxContext *mov = s->priv_data;
6525  int i, first_track = -1;
6526  int64_t mdat_size = 0, mdat_start = 0;
6527  int ret;
6528  int has_video = 0, starts_with_key = 0, first_video_track = 1;
6529 
6530  if (!(mov->flags & FF_MOV_FLAG_FRAGMENT))
6531  return 0;
6532 
6533  // Check if we have any tracks that require squashing.
6534  // In that case, we'll have to write the packet here.
6535  if ((ret = mov_write_squashed_packets(s)) < 0)
6536  return ret;
6537 
6538  // Try to fill in the duration of the last packet in each stream
6539  // from queued packets in the interleave queues. If the flushing
6540  // of fragments was triggered automatically by an AVPacket, we
6541  // already have reliable info for the end of that track, but other
6542  // tracks may need to be filled in.
6543  for (i = 0; i < mov->nb_streams; i++) {
6544  MOVTrack *track = &mov->tracks[i];
6545  if (!track->end_reliable) {
6546  const AVPacket *pkt = ff_interleaved_peek(s, i);
6547  if (pkt) {
6548  int64_t offset, dts, pts;
6550  pts = pkt->pts + offset;
6551  dts = pkt->dts + offset;
6552  if (track->dts_shift != AV_NOPTS_VALUE)
6553  dts += track->dts_shift;
6554  track->track_duration = dts - track->start_dts;
6555  if (pts != AV_NOPTS_VALUE)
6556  track->end_pts = pts;
6557  else
6558  track->end_pts = dts;
6559  if (!(pkt->flags & AV_PKT_FLAG_DISCARD))
6560  track->elst_end_pts = track->end_pts;
6561  }
6562  }
6563  }
6564 
6565  for (i = 0; i < mov->nb_tracks; i++) {
6566  MOVTrack *track = &mov->tracks[i];
6567  if (track->entry <= 1)
6568  continue;
6569  // Sample durations are calculated as the diff of dts values,
6570  // but for the last sample in a fragment, we don't know the dts
6571  // of the first sample in the next fragment, so we have to rely
6572  // on what was set as duration in the AVPacket. Not all callers
6573  // set this though, so we might want to replace it with an
6574  // estimate if it currently is zero.
6575  if (get_cluster_duration(track, track->entry - 1) != 0)
6576  continue;
6577  // Use the duration (i.e. dts diff) of the second last sample for
6578  // the last one. This is a wild guess (and fatal if it turns out
6579  // to be too long), but probably the best we can do - having a zero
6580  // duration is bad as well.
6581  track->track_duration += get_cluster_duration(track, track->entry - 2);
6582  track->end_pts += get_cluster_duration(track, track->entry - 2);
6583  if (!mov->missing_duration_warned) {
6585  "Estimating the duration of the last packet in a "
6586  "fragment, consider setting the duration field in "
6587  "AVPacket instead.\n");
6588  mov->missing_duration_warned = 1;
6589  }
6590  }
6591 
6592  if (!mov->moov_written) {
6593  int64_t pos = avio_tell(s->pb);
6594  uint8_t *buf;
6595  int buf_size, moov_size;
6596 
6597  for (i = 0; i < mov->nb_tracks; i++)
6598  if (!mov->tracks[i].entry && !is_cover_image(mov->tracks[i].st))
6599  break;
6600  /* Don't write the initial moov unless all tracks have data */
6601  if (i < mov->nb_tracks && !force)
6602  return 0;
6603 
6604  moov_size = get_moov_size(s);
6605  for (i = 0; i < mov->nb_tracks; i++)
6606  mov->tracks[i].data_offset = pos + moov_size + 8;
6607 
6609  if (mov->flags & FF_MOV_FLAG_DELAY_MOOV &&
6612  if ((ret = mov_write_moov_tag(s->pb, mov, s)) < 0)
6613  return ret;
6614 
6615  if (mov->flags & FF_MOV_FLAG_DELAY_MOOV) {
6616  if (mov->flags & FF_MOV_FLAG_GLOBAL_SIDX)
6617  mov->reserved_header_pos = avio_tell(s->pb);
6619  mov->moov_written = 1;
6620  return 0;
6621  }
6622 
6623  buf_size = avio_get_dyn_buf(mov->mdat_buf, &buf);
6624  avio_wb32(s->pb, buf_size + 8);
6625  ffio_wfourcc(s->pb, "mdat");
6626  avio_write(s->pb, buf, buf_size);
6628 
6629  if (mov->flags & FF_MOV_FLAG_GLOBAL_SIDX)
6630  mov->reserved_header_pos = avio_tell(s->pb);
6631 
6632  mov->moov_written = 1;
6633  mov->mdat_size = 0;
6634  for (i = 0; i < mov->nb_tracks; i++)
6635  mov_finish_fragment(mov, &mov->tracks[i], 0);
6637  return 0;
6638  }
6639 
6640  if (mov->frag_interleave) {
6641  for (i = 0; i < mov->nb_tracks; i++) {
6642  MOVTrack *track = &mov->tracks[i];
6643  int ret;
6644  if ((ret = mov_flush_fragment_interleaving(s, track)) < 0)
6645  return ret;
6646  }
6647 
6648  if (!mov->mdat_buf)
6649  return 0;
6650  mdat_size = avio_tell(mov->mdat_buf);
6651  }
6652 
6653  for (i = 0; i < mov->nb_tracks; i++) {
6654  MOVTrack *track = &mov->tracks[i];
6655  if (mov->flags & FF_MOV_FLAG_SEPARATE_MOOF || mov->frag_interleave)
6656  track->data_offset = 0;
6657  else
6658  track->data_offset = mdat_size;
6659  if (track->par->codec_type == AVMEDIA_TYPE_VIDEO) {
6660  has_video = 1;
6661  if (first_video_track) {
6662  if (track->entry)
6663  starts_with_key = track->cluster[0].flags & MOV_SYNC_SAMPLE;
6664  first_video_track = 0;
6665  }
6666  }
6667  if (!track->entry)
6668  continue;
6669  if (track->mdat_buf)
6670  mdat_size += avio_tell(track->mdat_buf);
6671  if (first_track < 0)
6672  first_track = i;
6673  }
6674 
6675  if (!mdat_size)
6676  return 0;
6677 
6678  avio_write_marker(s->pb,
6679  av_rescale(mov->tracks[first_track].cluster[0].dts, AV_TIME_BASE, mov->tracks[first_track].timescale),
6680  (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);
6681 
6682  for (i = first_track; i < mov->nb_tracks; i++) {
6683  MOVTrack *track = &mov->tracks[i];
6684  int buf_size, write_moof = 1, moof_tracks = -1;
6685  uint8_t *buf;
6686 
6687  if (!track->entry)
6688  continue;
6689  if (mov->flags & FF_MOV_FLAG_SEPARATE_MOOF) {
6690  mdat_size = avio_tell(track->mdat_buf);
6691  moof_tracks = i;
6692  } else {
6693  write_moof = i == first_track;
6694  }
6695 
6696  if (write_moof) {
6698 
6699  mov_write_moof_tag(s->pb, mov, moof_tracks, mdat_size);
6700  mov->fragments++;
6701 
6702  if (track->cenc.aes_ctr)
6703  ff_mov_cenc_flush(&track->cenc);
6704 
6705  avio_wb32(s->pb, mdat_size + 8);
6706  ffio_wfourcc(s->pb, "mdat");
6707  mdat_start = avio_tell(s->pb);
6708  }
6709 
6710  mov_finish_fragment(mov, &mov->tracks[i], mdat_start);
6711  if (!mov->frag_interleave) {
6712  if (!track->mdat_buf)
6713  continue;
6714  buf_size = avio_get_dyn_buf(track->mdat_buf, &buf);
6715  avio_write(s->pb, buf, buf_size);
6716  ffio_reset_dyn_buf(track->mdat_buf);
6717  } else {
6718  if (!mov->mdat_buf)
6719  continue;
6720  buf_size = avio_get_dyn_buf(mov->mdat_buf, &buf);
6721  avio_write(s->pb, buf, buf_size);
6723  }
6724  }
6725 
6726  mov->mdat_size = 0;
6727 
6729  return 0;
6730 }
6731 
6733 {
6734  MOVMuxContext *mov = s->priv_data;
6735  int had_moov = mov->moov_written;
6736  int ret = mov_flush_fragment(s, force);
6737  if (ret < 0)
6738  return ret;
6739  // If using delay_moov, the first flush only wrote the moov,
6740  // not the actual moof+mdat pair, thus flush once again.
6741  if (!had_moov && mov->flags & FF_MOV_FLAG_DELAY_MOOV)
6742  ret = mov_flush_fragment(s, force);
6743  return ret;
6744 }
6745 
6747 {
6748  int64_t ref;
6749  uint64_t duration;
6750 
6751  if (trk->entry) {
6752  ref = trk->cluster[trk->entry - 1].dts;
6753  } else if ( trk->start_dts != AV_NOPTS_VALUE
6754  && !trk->frag_discont) {
6755  ref = trk->start_dts + trk->track_duration;
6756  } else
6757  ref = pkt->dts; // Skip tests for the first packet
6758 
6759  if (trk->dts_shift != AV_NOPTS_VALUE) {
6760  /* With negative CTS offsets we have set an offset to the DTS,
6761  * reverse this for the check. */
6762  ref -= trk->dts_shift;
6763  }
6764 
6765  duration = pkt->dts - ref;
6766  if (pkt->dts < ref || duration >= INT_MAX) {
6767  av_log(s, AV_LOG_WARNING, "Packet duration: %"PRId64" / dts: %"PRId64" in stream %d is out of range\n",
6769 
6770  pkt->dts = ref + 1;
6771  pkt->pts = AV_NOPTS_VALUE;
6772  }
6773 
6774  if (pkt->duration < 0 || pkt->duration > INT_MAX) {
6775  av_log(s, AV_LOG_ERROR, "Application provided duration: %"PRId64" in stream %d is invalid\n", pkt->duration, pkt->stream_index);
6776  return AVERROR(EINVAL);
6777  }
6778  return 0;
6779 }
6780 
6782 {
6783  MOVMuxContext *mov = s->priv_data;
6784  AVIOContext *pb = s->pb;
6785  MOVTrack *trk;
6786  AVCodecParameters *par;
6788  unsigned int samples_in_chunk = 0;
6789  int size = pkt->size, ret = 0, offset = 0;
6790  size_t prft_size;
6791  uint8_t *reformatted_data = NULL;
6792 
6793  if (pkt->stream_index < s->nb_streams)
6794  trk = s->streams[pkt->stream_index]->priv_data;
6795  else // Timecode or chapter
6796  trk = &mov->tracks[pkt->stream_index];
6797  par = trk->par;
6798 
6799  ret = check_pkt(s, trk, pkt);
6800  if (ret < 0)
6801  return ret;
6802 
6803  if (pkt->pts != AV_NOPTS_VALUE &&
6804  (uint64_t)pkt->dts - pkt->pts != (int32_t)((uint64_t)pkt->dts - pkt->pts)) {
6805  av_log(s, AV_LOG_WARNING, "pts/dts pair unsupported\n");
6806  return AVERROR_PATCHWELCOME;
6807  }
6808 
6809  if (mov->flags & FF_MOV_FLAG_FRAGMENT || mov->mode == MODE_AVIF) {
6810  int ret;
6811  if (mov->moov_written || mov->flags & FF_MOV_FLAG_EMPTY_MOOV) {
6812  if (mov->frag_interleave && mov->fragments > 0) {
6813  if (trk->entry - trk->entries_flushed >= mov->frag_interleave) {
6814  if ((ret = mov_flush_fragment_interleaving(s, trk)) < 0)
6815  return ret;
6816  }
6817  }
6818 
6819  if (!trk->mdat_buf) {
6820  if ((ret = avio_open_dyn_buf(&trk->mdat_buf)) < 0)
6821  return ret;
6822  }
6823  pb = trk->mdat_buf;
6824  } else {
6825  if (!mov->mdat_buf) {
6826  if ((ret = avio_open_dyn_buf(&mov->mdat_buf)) < 0)
6827  return ret;
6828  }
6829  pb = mov->mdat_buf;
6830  }
6831  }
6832 
6833  if (par->codec_id == AV_CODEC_ID_AMR_NB) {
6834  /* We must find out how many AMR blocks there are in one packet */
6835  static const uint16_t packed_size[16] =
6836  {13, 14, 16, 18, 20, 21, 27, 32, 6, 0, 0, 0, 0, 0, 0, 1};
6837  int len = 0;
6838 
6839  while (len < size && samples_in_chunk < 100) {
6840  len += packed_size[(pkt->data[len] >> 3) & 0x0F];
6841  samples_in_chunk++;
6842  }
6843  if (samples_in_chunk > 1) {
6844  av_log(s, AV_LOG_ERROR, "fatal error, input is not a single packet, implement a AVParser for it\n");
6845  return -1;
6846  }
6847  } else if (par->codec_id == AV_CODEC_ID_ADPCM_MS ||
6849  samples_in_chunk = trk->par->frame_size;
6850  } else if (trk->sample_size)
6851  samples_in_chunk = size / trk->sample_size;
6852  else
6853  samples_in_chunk = 1;
6854 
6855  if (samples_in_chunk < 1) {
6856  av_log(s, AV_LOG_ERROR, "fatal error, input packet contains no samples\n");
6857  return AVERROR_PATCHWELCOME;
6858  }
6859 
6860  /* copy extradata if it exists */
6861  if (trk->extradata_size[0] == 0 && par->extradata_size > 0 &&
6862  !TAG_IS_AVCI(trk->tag) &&
6863  (par->codec_id != AV_CODEC_ID_DNXHD)) {
6864  trk->extradata[0] = av_memdup(par->extradata, par->extradata_size);
6865  if (!trk->extradata[0]) {
6866  ret = AVERROR(ENOMEM);
6867  goto err;
6868  }
6869  trk->extradata_size[0] = par->extradata_size;
6870  }
6871 
6872  if ((par->codec_id == AV_CODEC_ID_DNXHD ||
6873  par->codec_id == AV_CODEC_ID_H264 ||
6874  par->codec_id == AV_CODEC_ID_HEVC ||
6875  par->codec_id == AV_CODEC_ID_VVC ||
6876  par->codec_id == AV_CODEC_ID_VP9 ||
6877  par->codec_id == AV_CODEC_ID_EVC ||
6878  par->codec_id == AV_CODEC_ID_LCEVC ||
6879  par->codec_id == AV_CODEC_ID_TRUEHD) && !trk->extradata_size[0] &&
6880  !TAG_IS_AVCI(trk->tag)) {
6881  /* copy frame to create needed atoms */
6882  trk->extradata_size[0] = size;
6884  if (!trk->extradata[0]) {
6885  ret = AVERROR(ENOMEM);
6886  goto err;
6887  }
6888  memcpy(trk->extradata[0], pkt->data, size);
6889  memset(trk->extradata[0] + size, 0, AV_INPUT_BUFFER_PADDING_SIZE);
6890  }
6891 
6893  if (pkt->size && sd && sd->size > 0) {
6894  int i;
6895  for (i = 0; i < trk->stsd_count; i++) {
6896  if (trk->extradata_size[i] == sd->size && !memcmp(trk->extradata[i], sd->data, sd->size))
6897  break;
6898  }
6899 
6900  if (i < trk->stsd_count)
6901  trk->last_stsd_index = i;
6902  else if (trk->stsd_count <= INT_MAX - 1) {
6903  int new_count = trk->stsd_count + 1;
6904  uint8_t **extradata = av_realloc_array(trk->extradata, new_count, sizeof(*trk->extradata));
6905  if (!extradata)
6906  return AVERROR(ENOMEM);
6907  trk->extradata = extradata;
6908 
6909  int *extradata_size = av_realloc_array(trk->extradata_size, new_count, sizeof(*trk->extradata_size));
6910  if (!extradata_size)
6911  return AVERROR(ENOMEM);
6912  trk->extradata_size = extradata_size;
6913 
6914  trk->extradata[trk->stsd_count] = av_memdup(sd->data, sd->size);
6915  if (!trk->extradata[trk->stsd_count])
6916  return AVERROR(ENOMEM);
6917 
6918  trk->extradata_size[trk->stsd_count] = sd->size;
6919  trk->last_stsd_index = trk->stsd_count;
6920  trk->stsd_count = new_count;
6921  } else
6922  return AVERROR(ENOMEM);
6923  }
6924 
6925  if (par->codec_id == AV_CODEC_ID_AAC && pkt->size > 2 &&
6926  (AV_RB16(pkt->data) & 0xfff0) == 0xfff0) {
6927  if (!trk->st->nb_frames) {
6928  av_log(s, AV_LOG_ERROR, "Malformed AAC bitstream detected: "
6929  "use the audio bitstream filter 'aac_adtstoasc' to fix it "
6930  "('-bsf:a aac_adtstoasc' option with ffmpeg)\n");
6931  return -1;
6932  }
6933  av_log(s, AV_LOG_WARNING, "aac bitstream error\n");
6934  }
6935  if (par->codec_id == AV_CODEC_ID_H264 && trk->extradata_size[trk->last_stsd_index] > 0 &&
6936  *(uint8_t *)trk->extradata[trk->last_stsd_index] != 1 && !TAG_IS_AVCI(trk->tag)) {
6937  /* from x264 or from bytestream H.264 */
6938  /* NAL reformatting needed */
6939  if (trk->hint_track >= 0 && trk->hint_track < mov->nb_tracks) {
6940  ret = ff_nal_parse_units_buf(pkt->data, &reformatted_data,
6941  &size);
6942  if (ret < 0)
6943  return ret;
6944  avio_write(pb, reformatted_data, size);
6945  } else {
6946  if (trk->cenc.aes_ctr) {
6948  if (size < 0) {
6949  ret = size;
6950  goto err;
6951  }
6952  } else {
6953  size = ff_nal_parse_units(pb, pkt->data, pkt->size);
6954  }
6955  }
6956  } else if (par->codec_id == AV_CODEC_ID_HEVC && trk->extradata_size[trk->last_stsd_index] > 6 &&
6957  (AV_RB24(trk->extradata[trk->last_stsd_index]) == 1 || AV_RB32(trk->extradata[trk->last_stsd_index]) == 1)) {
6958  /* extradata is Annex B, assume the bitstream is too and convert it */
6959  int filter_ps = (trk->tag == MKTAG('h','v','c','1'));
6960  if (trk->hint_track >= 0 && trk->hint_track < mov->nb_tracks) {
6961  ret = ff_hevc_annexb2mp4_buf(pkt->data, &reformatted_data,
6962  &size, filter_ps, NULL);
6963  if (ret < 0)
6964  return ret;
6965  avio_write(pb, reformatted_data, size);
6966  } else {
6967  if (trk->cenc.aes_ctr) {
6969  if (size < 0) {
6970  ret = size;
6971  goto err;
6972  }
6973  } else {
6974  size = ff_hevc_annexb2mp4(pb, pkt->data, pkt->size, filter_ps, NULL);
6975  }
6976  }
6977  } else if (par->codec_id == AV_CODEC_ID_VVC && trk->extradata_size[trk->last_stsd_index] > 6 &&
6978  (AV_RB24(trk->extradata[trk->last_stsd_index]) == 1 || AV_RB32(trk->extradata[trk->last_stsd_index]) == 1)) {
6979  /* extradata is Annex B, assume the bitstream is too and convert it */
6980  if (trk->hint_track >= 0 && trk->hint_track < mov->nb_tracks) {
6981  ret = ff_vvc_annexb2mp4_buf(pkt->data, &reformatted_data,
6982  &size, 0, NULL);
6983  if (ret < 0)
6984  return ret;
6985  avio_write(pb, reformatted_data, size);
6986  } else {
6987  size = ff_vvc_annexb2mp4(pb, pkt->data, pkt->size, 0, NULL);
6988  }
6989  } else if (par->codec_id == AV_CODEC_ID_LCEVC && trk->extradata_size[trk->last_stsd_index] > 0 &&
6990  *(uint8_t *)trk->extradata[trk->last_stsd_index] != 1) {
6991  /* extradata is Annex B, assume the bitstream is too and convert it */
6992  if (trk->hint_track >= 0 && trk->hint_track < mov->nb_tracks) {
6993  ret = ff_nal_parse_units_buf(pkt->data, &reformatted_data, &size);
6994  if (ret < 0)
6995  return ret;
6996  avio_write(pb, reformatted_data, size);
6997  } else {
6998  if (trk->cenc.aes_ctr) {
7000  if (size < 0) {
7001  ret = size;
7002  goto err;
7003  }
7004  } else {
7005  size = ff_nal_parse_units(pb, pkt->data, pkt->size);
7006  }
7007  }
7008  } else if (par->codec_id == AV_CODEC_ID_AV1 && !trk->cenc.aes_ctr) {
7009  if (trk->hint_track >= 0 && trk->hint_track < mov->nb_tracks) {
7010  ret = ff_av1_filter_obus_buf(pkt->data, &reformatted_data,
7011  &size, &offset);
7012  if (ret < 0)
7013  return ret;
7014  avio_write(pb, reformatted_data, size);
7015  } else {
7016  size = ff_av1_filter_obus(pb, pkt->data, pkt->size);
7017  if (trk->mode == MODE_AVIF && !mov->avif_extent_length[pkt->stream_index]) {
7019  }
7020  }
7021 
7022  } else if (par->codec_id == AV_CODEC_ID_AC3 ||
7023  par->codec_id == AV_CODEC_ID_EAC3) {
7024  size = handle_eac3(mov, pkt, trk);
7025  if (size < 0)
7026  return size;
7027  else if (!size)
7028  goto end;
7029  avio_write(pb, pkt->data, size);
7030  } else if (par->codec_id == AV_CODEC_ID_EIA_608) {
7031  size = 8;
7032 
7033  for (int i = 0; i < pkt->size; i += 3) {
7034  if (pkt->data[i] == 0xFC) {
7035  size += 2;
7036  }
7037  }
7038  avio_wb32(pb, size);
7039  ffio_wfourcc(pb, "cdat");
7040  for (int i = 0; i < pkt->size; i += 3) {
7041  if (pkt->data[i] == 0xFC) {
7042  avio_w8(pb, pkt->data[i + 1]);
7043  avio_w8(pb, pkt->data[i + 2]);
7044  }
7045  }
7046  } else if (par->codec_id == AV_CODEC_ID_APV) {
7047  ff_isom_parse_apvc(trk->apv, pkt, s);
7048  avio_wb32(s->pb, pkt->size);
7049  size += 4;
7050 
7051  avio_write(s->pb, pkt->data, pkt->size);
7052  } else {
7053  if (trk->cenc.aes_ctr) {
7054  uint8_t *extradata = trk->extradata[trk->last_stsd_index];
7055  int extradata_size = trk->extradata_size[trk->last_stsd_index];
7056  if (par->codec_id == AV_CODEC_ID_H264 && extradata_size > 4) {
7057  int nal_size_length = (extradata[4] & 0x3) + 1;
7058  ret = ff_mov_cenc_avc_write_nal_units(s, &trk->cenc, nal_size_length, pb, pkt->data, size);
7059  } else if(par->codec_id == AV_CODEC_ID_HEVC && extradata_size > 21) {
7060  int nal_size_length = (extradata[21] & 0x3) + 1;
7061  ret = ff_mov_cenc_avc_write_nal_units(s, &trk->cenc, nal_size_length, pb, pkt->data, size);
7062  } else if(par->codec_id == AV_CODEC_ID_VVC) {
7064  } else if(par->codec_id == AV_CODEC_ID_AV1) {
7065  av_assert0(size == pkt->size);
7066  ret = ff_mov_cenc_av1_write_obus(s, &trk->cenc, pb, pkt);
7067  if (ret > 0) {
7068  size = ret;
7069  ret = 0;
7070  }
7071  } else {
7072  ret = ff_mov_cenc_write_packet(&trk->cenc, pb, pkt->data, size);
7073  }
7074 
7075  if (ret) {
7076  goto err;
7077  }
7078  } else {
7079  avio_write(pb, pkt->data, size);
7080  }
7081  }
7082 
7083  if (trk->entry >= trk->cluster_capacity) {
7084  unsigned new_capacity = trk->entry + MOV_INDEX_CLUSTER_SIZE;
7085  void *cluster = av_realloc_array(trk->cluster, new_capacity, sizeof(*trk->cluster));
7086  if (!cluster) {
7087  ret = AVERROR(ENOMEM);
7088  goto err;
7089  }
7090  trk->cluster = cluster;
7091  trk->cluster_capacity = new_capacity;
7092  }
7093 
7094  trk->cluster[trk->entry].pos = avio_tell(pb) - size;
7095  trk->cluster[trk->entry].stsd_index = trk->last_stsd_index;
7096  trk->cluster[trk->entry].samples_in_chunk = samples_in_chunk;
7097  trk->cluster[trk->entry].chunkNum = 0;
7098  trk->cluster[trk->entry].size = size;
7099  trk->cluster[trk->entry].entries = samples_in_chunk;
7100  trk->cluster[trk->entry].dts = pkt->dts;
7101  trk->cluster[trk->entry].pts = pkt->pts;
7102  if (!trk->squash_fragment_samples_to_one &&
7103  !trk->entry && trk->start_dts != AV_NOPTS_VALUE) {
7104  if (!trk->frag_discont) {
7105  /* First packet of a new fragment. We already wrote the duration
7106  * of the last packet of the previous fragment based on track_duration,
7107  * which might not exactly match our dts. Therefore adjust the dts
7108  * of this packet to be what the previous packets duration implies. */
7109  trk->cluster[trk->entry].dts = trk->start_dts + trk->track_duration;
7110  /* We also may have written the pts and the corresponding duration
7111  * in sidx/tfrf/tfxd tags; make sure the sidx pts and duration match up with
7112  * the next fragment. This means the cts of the first sample must
7113  * be the same in all fragments, unless end_pts was updated by
7114  * the packet causing the fragment to be written. */
7115  if ((mov->flags & FF_MOV_FLAG_DASH &&
7117  mov->mode == MODE_ISM)
7118  pkt->pts = pkt->dts + trk->end_pts - trk->cluster[trk->entry].dts;
7119  } else {
7120  /* New fragment, but discontinuous from previous fragments.
7121  * Pretend the duration sum of the earlier fragments is
7122  * pkt->dts - trk->start_dts. */
7123  trk->end_pts = trk->elst_end_pts = AV_NOPTS_VALUE;
7124  trk->frag_discont = 0;
7125  }
7126  }
7127 
7128  if (!trk->entry && trk->start_dts == AV_NOPTS_VALUE && !mov->use_editlist &&
7129  s->avoid_negative_ts == AVFMT_AVOID_NEG_TS_MAKE_ZERO) {
7130  /* Not using edit lists and shifting the first track to start from zero.
7131  * If the other streams start from a later timestamp, we won't be able
7132  * to signal the difference in starting time without an edit list.
7133  * Thus move the timestamp for this first sample to 0, increasing
7134  * its duration instead. */
7135  trk->cluster[trk->entry].dts = trk->start_dts = 0;
7136  }
7137  if (trk->start_dts == AV_NOPTS_VALUE) {
7138  trk->start_dts = pkt->dts;
7139  if (trk->frag_discont) {
7140  if (mov->use_editlist) {
7141  /* Pretend the whole stream started at pts=0, with earlier fragments
7142  * already written. If the stream started at pts=0, the duration sum
7143  * of earlier fragments would have been pkt->pts. */
7144  trk->start_dts = pkt->dts - pkt->pts;
7145  } else {
7146  /* Pretend the whole stream started at dts=0, with earlier fragments
7147  * already written, with a duration summing up to pkt->dts. */
7148  trk->start_dts = 0;
7149  }
7150  trk->frag_discont = 0;
7151  } else if (pkt->dts && mov->moov_written)
7153  "Track %d starts with a nonzero dts %"PRId64", while the moov "
7154  "already has been written. Set the delay_moov flag to handle "
7155  "this case.\n",
7156  pkt->stream_index, pkt->dts);
7157  }
7158  trk->track_duration = pkt->dts - trk->start_dts + pkt->duration;
7159  trk->last_sample_is_subtitle_end = 0;
7160 
7161  if (pkt->pts == AV_NOPTS_VALUE) {
7162  av_log(s, AV_LOG_WARNING, "pts has no value\n");
7163  pkt->pts = pkt->dts;
7164  }
7165  if (pkt->dts != pkt->pts)
7166  trk->flags |= MOV_TRACK_CTTS;
7167  trk->cluster[trk->entry].cts = pkt->pts - pkt->dts;
7168  trk->cluster[trk->entry].flags = 0;
7169  if (trk->start_cts == AV_NOPTS_VALUE || (pkt->dts <= 0 && trk->start_cts > pkt->pts - pkt->dts))
7170  trk->start_cts = pkt->pts - pkt->dts;
7171  if (trk->end_pts == AV_NOPTS_VALUE)
7172  trk->end_pts = trk->cluster[trk->entry].dts +
7173  trk->cluster[trk->entry].cts + pkt->duration;
7174  else
7175  trk->end_pts = FFMAX(trk->end_pts, trk->cluster[trk->entry].dts +
7176  trk->cluster[trk->entry].cts +
7177  pkt->duration);
7178  if (!(pkt->flags & AV_PKT_FLAG_DISCARD))
7179  trk->elst_end_pts = trk->end_pts;
7180 
7181  if (par->codec_id == AV_CODEC_ID_VC1) {
7182  mov_parse_vc1_frame(pkt, trk);
7183  } else if (par->codec_id == AV_CODEC_ID_TRUEHD) {
7185  } else if (pkt->flags & AV_PKT_FLAG_KEY) {
7186  if (mov->mode == MODE_MOV && par->codec_id == AV_CODEC_ID_MPEG2VIDEO &&
7187  trk->entry > 0) { // force sync sample for the first key frame
7189  if (trk->cluster[trk->entry].flags & MOV_PARTIAL_SYNC_SAMPLE)
7190  trk->flags |= MOV_TRACK_STPS;
7191  } else {
7192  trk->cluster[trk->entry].flags = MOV_SYNC_SAMPLE;
7193  }
7194  if (trk->cluster[trk->entry].flags & MOV_SYNC_SAMPLE)
7195  trk->has_keyframes++;
7196  }
7197  if (pkt->flags & AV_PKT_FLAG_DISPOSABLE) {
7198  trk->cluster[trk->entry].flags |= MOV_DISPOSABLE_SAMPLE;
7199  trk->has_disposable++;
7200  }
7201 
7203  if (prft && prft_size == sizeof(AVProducerReferenceTime))
7204  memcpy(&trk->cluster[trk->entry].prft, prft, prft_size);
7205  else
7206  memset(&trk->cluster[trk->entry].prft, 0, sizeof(AVProducerReferenceTime));
7207 
7208  trk->entry++;
7209  trk->sample_count += samples_in_chunk;
7210  mov->mdat_size += size;
7211 
7212  if (trk->hint_track >= 0 && trk->hint_track < mov->nb_tracks)
7214  reformatted_data ? reformatted_data + offset
7215  : NULL, size);
7216 
7217 end:
7218 err:
7219 
7220  if (pkt->data != reformatted_data)
7221  av_free(reformatted_data);
7222  return ret;
7223 }
7224 
7226 {
7227  MOVMuxContext *mov = s->priv_data;
7228  MOVTrack *trk = s->streams[pkt->stream_index]->priv_data;
7229  AVCodecParameters *par = trk->par;
7230  int64_t frag_duration = 0;
7231  int size = pkt->size;
7232 
7233  int ret = check_pkt(s, trk, pkt);
7234  if (ret < 0)
7235  return ret;
7236 
7237  if (mov->flags & FF_MOV_FLAG_FRAG_DISCONT) {
7238  for (int i = 0; i < mov->nb_streams; i++)
7239  mov->tracks[i].frag_discont = 1;
7241  }
7242 
7244  if (trk->dts_shift == AV_NOPTS_VALUE)
7245  trk->dts_shift = pkt->pts - pkt->dts;
7246  pkt->dts += trk->dts_shift;
7247  }
7248 
7249  if (trk->par->codec_id == AV_CODEC_ID_MP4ALS ||
7250  trk->par->codec_id == AV_CODEC_ID_AAC ||
7251  trk->par->codec_id == AV_CODEC_ID_AV1 ||
7252  trk->par->codec_id == AV_CODEC_ID_FLAC) {
7253  size_t side_size;
7254  uint8_t *side = av_packet_get_side_data(pkt, AV_PKT_DATA_NEW_EXTRADATA, &side_size);
7255  /* Overwrite extradata only on flush packets or when no extradata was available during init */
7256  if (side_size > 0 && (!pkt->size || !trk->extradata_size[trk->last_stsd_index])) {
7257  void *newextra = av_malloc(side_size + AV_INPUT_BUFFER_PADDING_SIZE);
7258  if (!newextra)
7259  return AVERROR(ENOMEM);
7260  memset((uint8_t*)newextra + side_size, 0, AV_INPUT_BUFFER_PADDING_SIZE);
7261  memcpy(newextra, side, side_size);
7262  av_free(trk->extradata[trk->last_stsd_index]);
7263  trk->extradata[trk->last_stsd_index] = newextra;
7264  trk->extradata_size[trk->last_stsd_index] = side_size;
7265  }
7266  }
7267 
7268  if (!pkt->size) {
7269  if (trk->start_dts == AV_NOPTS_VALUE && trk->frag_discont) {
7270  trk->start_dts = pkt->dts;
7271  if (pkt->pts != AV_NOPTS_VALUE)
7272  trk->start_cts = pkt->pts - pkt->dts;
7273  else
7274  trk->start_cts = 0;
7275  }
7276 
7277  return 0; /* Discard 0 sized packets */
7278  }
7279 
7280  if (trk->entry && pkt->stream_index < mov->nb_streams)
7281  frag_duration = av_rescale_q(pkt->dts - trk->cluster[0].dts,
7282  s->streams[pkt->stream_index]->time_base,
7283  AV_TIME_BASE_Q);
7284  if ((mov->max_fragment_duration &&
7285  frag_duration >= mov->max_fragment_duration) ||
7286  (mov->max_fragment_size && mov->mdat_size + size >= mov->max_fragment_size) ||
7287  (mov->flags & FF_MOV_FLAG_FRAG_KEYFRAME &&
7288  par->codec_type == AVMEDIA_TYPE_VIDEO &&
7289  trk->entry && pkt->flags & AV_PKT_FLAG_KEY) ||
7291  if (frag_duration >= mov->min_fragment_duration) {
7292  if (trk->entry) {
7293  // Set the duration of this track to line up with the next
7294  // sample in this track. This avoids relying on AVPacket
7295  // duration, but only helps for this particular track, not
7296  // for the other ones that are flushed at the same time.
7297  //
7298  // If we have trk->entry == 0, no fragment will be written
7299  // for this track, and we can't adjust the track end here.
7300  trk->track_duration = pkt->dts - trk->start_dts;
7301  if (pkt->pts != AV_NOPTS_VALUE)
7302  trk->end_pts = pkt->pts;
7303  else
7304  trk->end_pts = pkt->dts;
7305  if (!(pkt->flags & AV_PKT_FLAG_DISCARD))
7306  trk->elst_end_pts = trk->end_pts;
7307  trk->end_reliable = 1;
7308  }
7310  }
7311  }
7312 
7313  return ff_mov_write_packet(s, pkt);
7314 }
7315 
7317  int stream_index,
7318  int64_t dts) {
7319  MOVMuxContext *mov = s->priv_data;
7320  AVPacket *end = mov->pkt;
7321  uint8_t data[2] = {0};
7322  int ret;
7323 
7324  end->size = sizeof(data);
7325  end->data = data;
7326  end->pts = dts;
7327  end->dts = dts;
7328  end->duration = 0;
7329  end->stream_index = stream_index;
7330 
7331  ret = mov_write_single_packet(s, end);
7332  av_packet_unref(end);
7333 
7334  return ret;
7335 }
7336 
7337 #if CONFIG_IAMFENC
7338 static int mov_build_iamf_packet(AVFormatContext *s, MOVTrack *trk, AVPacket *pkt)
7339 {
7340  uint8_t *data;
7341  int ret;
7342 
7343  if (pkt->stream_index == trk->first_iamf_idx) {
7345  if (ret < 0)
7346  return ret;
7347  }
7348 
7350  s->streams[pkt->stream_index]->id, pkt);
7351  if (ret < 0)
7352  return ret;
7353 
7354  if (pkt->stream_index != trk->last_iamf_idx)
7355  return AVERROR(EAGAIN);
7356 
7357  ret = avio_close_dyn_buf(trk->iamf_buf, &data);
7358  trk->iamf_buf = NULL;
7359  if (!ret) {
7360  if (pkt->size) {
7361  // Either all or none of the packets for a single
7362  // IA Sample may be empty.
7363  av_log(s, AV_LOG_ERROR, "Unexpected packet from "
7364  "stream #%d\n", pkt->stream_index);
7366  }
7367  av_free(data);
7368  return ret;
7369  }
7370 
7371  av_buffer_unref(&pkt->buf);
7372  pkt->buf = av_buffer_create(data, ret, NULL, NULL, 0);
7373  if (!pkt->buf) {
7374  av_free(data);
7375  return AVERROR(ENOMEM);
7376  }
7377  pkt->data = data;
7378  pkt->size = ret;
7380 
7381  return avio_open_dyn_buf(&trk->iamf_buf);
7382 }
7383 #endif
7384 
7386 {
7387  int64_t pos = avio_tell(pb);
7388  const char *scheme_id_uri = "https://aomedia.org/emsg/ID3";
7389  const char *value = "";
7390 
7391  av_assert0(st->time_base.num == 1);
7392 
7393  avio_write_marker(pb,
7396 
7397  avio_wb32(pb, 0); /* size */
7398  ffio_wfourcc(pb, "emsg");
7399  avio_w8(pb, 1); /* version */
7400  avio_wb24(pb, 0);
7401  avio_wb32(pb, st->time_base.den); /* timescale */
7402  avio_wb64(pb, pkt->pts); /* presentation_time */
7403  avio_wb32(pb, 0xFFFFFFFFU); /* event_duration */
7404  avio_wb32(pb, 0); /* id */
7405  /* null terminated UTF8 strings */
7406  avio_write(pb, scheme_id_uri, strlen(scheme_id_uri) + 1);
7407  avio_write(pb, value, strlen(value) + 1);
7408  avio_write(pb, pkt->data, pkt->size);
7409 
7410  return update_size(pb, pos);
7411 }
7412 
7414 {
7415  MOVMuxContext *mov = s->priv_data;
7416  MOVTrack *trk;
7417 
7418  if (!pkt) {
7419  mov_flush_fragment(s, 1);
7420  return 1;
7421  }
7422 
7423  if (s->streams[pkt->stream_index]->codecpar->codec_id == AV_CODEC_ID_TIMED_ID3) {
7424  mov_write_emsg_tag(s->pb, s->streams[pkt->stream_index], pkt);
7425  return 0;
7426  }
7427 
7428  trk = s->streams[pkt->stream_index]->priv_data;
7429 
7430 #if CONFIG_IAMFENC
7431  if (trk->iamf) {
7432  int ret = mov_build_iamf_packet(s, trk, pkt);
7433  if (ret < 0) {
7434  if (ret == AVERROR(EAGAIN))
7435  return 0;
7436  av_log(s, AV_LOG_ERROR, "Error assembling an IAMF packet "
7437  "for stream #%d\n", trk->st->index);
7438  return ret;
7439  }
7440  }
7441 #endif
7442 
7443  if (is_cover_image(trk->st)) {
7444  int ret;
7445 
7446  if (trk->st->nb_frames >= 1) {
7447  if (trk->st->nb_frames == 1)
7448  av_log(s, AV_LOG_WARNING, "Got more than one picture in stream %d,"
7449  " ignoring.\n", pkt->stream_index);
7450  return 0;
7451  }
7452 
7453  if ((ret = av_packet_ref(trk->cover_image, pkt)) < 0)
7454  return ret;
7455 
7456  return 0;
7457  } else {
7458  int i;
7459 
7460  if (!pkt->size)
7461  return mov_write_single_packet(s, pkt); /* Passthrough. */
7462 
7463  /*
7464  * Subtitles require special handling.
7465  *
7466  * 1) For full compliance, every track must have a sample at
7467  * dts == 0, which is rarely true for subtitles. So, as soon
7468  * as we see any packet with dts > 0, write an empty subtitle
7469  * at dts == 0 for any subtitle track with no samples in it.
7470  *
7471  * 2) For each subtitle track, check if the current packet's
7472  * dts is past the duration of the last subtitle sample. If
7473  * so, we now need to write an end sample for that subtitle.
7474  *
7475  * This must be done conditionally to allow for subtitles that
7476  * immediately replace each other, in which case an end sample
7477  * is not needed, and is, in fact, actively harmful.
7478  *
7479  * 3) See mov_write_trailer for how the final end sample is
7480  * handled.
7481  */
7482  for (i = 0; i < mov->nb_tracks; i++) {
7483  MOVTrack *trk = &mov->tracks[i];
7484  int ret;
7485 
7486  if (trk->par->codec_id == AV_CODEC_ID_MOV_TEXT &&
7487  trk->track_duration < pkt->dts &&
7488  (trk->entry == 0 || !trk->last_sample_is_subtitle_end)) {
7490  if (ret < 0) return ret;
7491  trk->last_sample_is_subtitle_end = 1;
7492  }
7493  }
7494 
7495  if (trk->squash_fragment_samples_to_one) {
7496  /*
7497  * If the track has to have its samples squashed into one sample,
7498  * we just take it into the track's queue.
7499  * This will then be utilized as the samples get written in either
7500  * mov_flush_fragment or when the mux is finalized in
7501  * mov_write_trailer.
7502  */
7503  int ret = AVERROR_BUG;
7504 
7505  if (pkt->pts == AV_NOPTS_VALUE) {
7507  "Packets without a valid presentation timestamp are "
7508  "not supported with packet squashing!\n");
7509  return AVERROR(EINVAL);
7510  }
7511 
7512  /* The following will reset pkt and is only allowed to be used
7513  * because we return immediately. afterwards. */
7515  pkt, NULL, 0)) < 0) {
7516  return ret;
7517  }
7518 
7519  return 0;
7520  }
7521 
7522 
7523  if (trk->mode == MODE_MOV && trk->par->codec_type == AVMEDIA_TYPE_VIDEO) {
7524  AVPacket *opkt = pkt;
7525  int reshuffle_ret, ret;
7526  if (trk->is_unaligned_qt_rgb) {
7527  int64_t bpc = trk->par->bits_per_coded_sample != 15 ? trk->par->bits_per_coded_sample : 16;
7528  int expected_stride = ((trk->par->width * bpc + 15) >> 4)*2;
7529  reshuffle_ret = ff_reshuffle_raw_rgb(s, &pkt, trk->par, expected_stride);
7530  if (reshuffle_ret < 0)
7531  return reshuffle_ret;
7532  } else
7533  reshuffle_ret = 0;
7534  if (trk->par->format == AV_PIX_FMT_PAL8 && !trk->pal_done) {
7535  ret = ff_get_packet_palette(s, opkt, reshuffle_ret, trk->palette);
7536  if (ret < 0)
7537  goto fail;
7538  if (ret)
7539  trk->pal_done++;
7540  } else if (trk->par->codec_id == AV_CODEC_ID_RAWVIDEO &&
7541  (trk->par->format == AV_PIX_FMT_GRAY8 ||
7542  trk->par->format == AV_PIX_FMT_MONOBLACK)) {
7544  if (ret < 0)
7545  goto fail;
7546  for (i = 0; i < pkt->size; i++)
7547  pkt->data[i] = ~pkt->data[i];
7548  }
7549  if (reshuffle_ret) {
7551 fail:
7552  if (reshuffle_ret)
7553  av_packet_free(&pkt);
7554  return ret;
7555  }
7556  }
7557 
7558  return mov_write_single_packet(s, pkt);
7559  }
7560 }
7561 
7562 // QuickTime chapters involve an additional text track with the chapter names
7563 // as samples, and a tref pointing from the other tracks to the chapter one.
7564 static int mov_create_chapter_track(AVFormatContext *s, int tracknum)
7565 {
7566  static const uint8_t stub_header[] = {
7567  // TextSampleEntry
7568  0x00, 0x00, 0x00, 0x01, // displayFlags
7569  0x00, 0x00, // horizontal + vertical justification
7570  0x00, 0x00, 0x00, 0x00, // bgColourRed/Green/Blue/Alpha
7571  // BoxRecord
7572  0x00, 0x00, 0x00, 0x00, // defTextBoxTop/Left
7573  0x00, 0x00, 0x00, 0x00, // defTextBoxBottom/Right
7574  // StyleRecord
7575  0x00, 0x00, 0x00, 0x00, // startChar + endChar
7576  0x00, 0x01, // fontID
7577  0x00, 0x00, // fontStyleFlags + fontSize
7578  0x00, 0x00, 0x00, 0x00, // fgColourRed/Green/Blue/Alpha
7579  // FontTableBox
7580  0x00, 0x00, 0x00, 0x0D, // box size
7581  'f', 't', 'a', 'b', // box atom name
7582  0x00, 0x01, // entry count
7583  // FontRecord
7584  0x00, 0x01, // font ID
7585  0x00, // font name length
7586  };
7587  MOVMuxContext *mov = s->priv_data;
7588  MOVTrack *track = &mov->tracks[tracknum];
7589  AVPacket *pkt = mov->pkt;
7590  int i, len;
7591  int ret;
7592 
7593  track->mode = mov->mode;
7594  track->tag = MKTAG('t','e','x','t');
7595  track->timescale = mov->movie_timescale;
7596  track->par = avcodec_parameters_alloc();
7597  if (!track->par)
7598  return AVERROR(ENOMEM);
7600  ret = ff_alloc_extradata(track->par, sizeof(stub_header));
7601  if (ret < 0)
7602  return ret;
7603  memcpy(track->par->extradata, stub_header, sizeof(stub_header));
7604 
7605  if (track->extradata == NULL) {
7606  track->stsd_count = 1;
7607  track->extradata = av_calloc(1, sizeof(*track->extradata));
7608  track->extradata_size = av_calloc(1, sizeof(*track->extradata_size));
7609  if (!track->extradata || !track->extradata_size)
7610  return AVERROR(ENOMEM);
7611  }
7612 
7613  track->extradata[0] = av_memdup(stub_header, sizeof(stub_header));
7614  if (!track->extradata[0])
7615  return AVERROR(ENOMEM);
7616  track->extradata_size[0] = sizeof(stub_header);
7617 
7618  pkt->stream_index = tracknum;
7620 
7621  for (i = 0; i < s->nb_chapters; i++) {
7622  AVChapter *c = s->chapters[i];
7623  AVDictionaryEntry *t;
7624 
7625  int64_t end = av_rescale_q(c->end, c->time_base, (AVRational){1,mov->movie_timescale});
7626  pkt->pts = pkt->dts = av_rescale_q(c->start, c->time_base, (AVRational){1,mov->movie_timescale});
7627  pkt->duration = end - pkt->dts;
7628 
7629  if ((t = av_dict_get(c->metadata, "title", NULL, 0))) {
7630  static const char encd[12] = {
7631  0x00, 0x00, 0x00, 0x0C,
7632  'e', 'n', 'c', 'd',
7633  0x00, 0x00, 0x01, 0x00 };
7634  len = strlen(t->value);
7635  pkt->size = len + 2 + 12;
7636  pkt->data = av_malloc(pkt->size);
7637  if (!pkt->data) {
7639  return AVERROR(ENOMEM);
7640  }
7641  AV_WB16(pkt->data, len);
7642  memcpy(pkt->data + 2, t->value, len);
7643  memcpy(pkt->data + len + 2, encd, sizeof(encd));
7645  av_freep(&pkt->data);
7646  }
7647  }
7648 
7649  av_packet_unref(mov->pkt);
7650 
7651  return 0;
7652 }
7653 
7654 
7655 static int mov_check_timecode_track(AVFormatContext *s, AVTimecode *tc, AVStream *src_st, const char *tcstr)
7656 {
7657  int ret;
7658 
7659  /* compute the frame number */
7660  ret = av_timecode_init_from_string(tc, src_st->avg_frame_rate, tcstr, s);
7661  return ret;
7662 }
7663 
7664 static int mov_create_timecode_track(AVFormatContext *s, int index, int src_index, AVTimecode tc)
7665 {
7666  MOVMuxContext *mov = s->priv_data;
7667  MOVTrack *track = &mov->tracks[index];
7668  AVStream *src_st = mov->tracks[src_index].st;
7669  uint8_t data[4];
7670  AVPacket *pkt = mov->pkt;
7671  AVRational rate = src_st->avg_frame_rate;
7672  int ret;
7673 
7674  /* tmcd track based on video stream */
7675  track->mode = mov->mode;
7676  track->tag = MKTAG('t','m','c','d');
7677  track->src_track = src_index;
7678  track->timescale = mov->tracks[src_index].timescale;
7681 
7682  /* set st to src_st for metadata access*/
7683  track->st = src_st;
7684 
7685  /* encode context: tmcd data stream */
7686  track->par = avcodec_parameters_alloc();
7687  if (!track->par)
7688  return AVERROR(ENOMEM);
7689  track->par->codec_type = AVMEDIA_TYPE_DATA;
7690  track->par->codec_tag = track->tag;
7691  track->st->avg_frame_rate = rate;
7692 
7693  /* the tmcd track just contains one packet with the frame number */
7694  pkt->data = data;
7695  pkt->stream_index = index;
7697  pkt->pts = pkt->dts = av_rescale_q(tc.start, av_inv_q(rate), (AVRational){1,mov->movie_timescale});
7698  pkt->size = 4;
7699  AV_WB32(pkt->data, tc.start);
7702  return ret;
7703 }
7704 
7705 /*
7706  * st->disposition controls the "enabled" flag in the tkhd tag.
7707  * QuickTime will not play a track if it is not enabled. So make sure
7708  * that one track of each type (audio, video, subtitle) is enabled.
7709  *
7710  * Subtitles are special. For audio and video, setting "enabled" also
7711  * makes the track "default" (i.e. it is rendered when played). For
7712  * subtitles, an "enabled" subtitle is not rendered by default, but
7713  * if no subtitle is enabled, the subtitle menu in QuickTime will be
7714  * empty!
7715  */
7717 {
7718  MOVMuxContext *mov = s->priv_data;
7719  int i;
7720  int enabled[AVMEDIA_TYPE_NB];
7721  int first[AVMEDIA_TYPE_NB];
7722 
7723  for (i = 0; i < AVMEDIA_TYPE_NB; i++) {
7724  enabled[i] = 0;
7725  first[i] = -1;
7726  }
7727 
7728  for (i = 0; i < mov->nb_streams; i++) {
7729  AVStream *st = mov->tracks[i].st;
7730 
7733  is_cover_image(st))
7734  continue;
7735 
7736  if (first[st->codecpar->codec_type] < 0)
7737  first[st->codecpar->codec_type] = i;
7738  if (st->disposition & AV_DISPOSITION_DEFAULT) {
7739  mov->tracks[i].flags |= MOV_TRACK_ENABLED;
7740  enabled[st->codecpar->codec_type]++;
7741  }
7742  }
7743 
7744  for (i = 0; i < AVMEDIA_TYPE_NB; i++) {
7745  switch (i) {
7746  case AVMEDIA_TYPE_VIDEO:
7747  case AVMEDIA_TYPE_AUDIO:
7748  case AVMEDIA_TYPE_SUBTITLE:
7749  if (enabled[i] > 1)
7750  mov->per_stream_grouping = 1;
7751  if (!enabled[i] && first[i] >= 0)
7752  mov->tracks[first[i]].flags |= MOV_TRACK_ENABLED;
7753  break;
7754  }
7755  }
7756 }
7757 
7759 {
7760  MOVMuxContext *mov = s->priv_data;
7761 
7762  for (int i = 0; i < s->nb_streams; i++)
7763  s->streams[i]->priv_data = NULL;
7764 
7765  if (!mov->tracks)
7766  return;
7767 
7768  if (mov->chapter_track) {
7770  }
7771 
7772  for (int i = 0; i < mov->nb_tracks; i++) {
7773  MOVTrack *const track = &mov->tracks[i];
7774 
7775  if (track->tag == MKTAG('r','t','p',' '))
7776  ff_mov_close_hinting(track);
7777  else if (track->tag == MKTAG('t','m','c','d') && mov->nb_meta_tmcd)
7778  av_freep(&track->par);
7779  av_freep(&track->cluster);
7780  av_freep(&track->cluster_written);
7781  av_freep(&track->frag_info);
7782  av_packet_free(&track->cover_image);
7783 
7784  if (track->eac3_priv) {
7785  struct eac3_info *info = track->eac3_priv;
7786  av_packet_free(&info->pkt);
7787  av_freep(&track->eac3_priv);
7788  }
7789  for (int j = 0; j < track->stsd_count; j++)
7790  av_freep(&track->extradata[j]);
7791  av_freep(&track->extradata);
7792  av_freep(&track->extradata_size);
7793 
7794  ff_mov_cenc_free(&track->cenc);
7795  ffio_free_dyn_buf(&track->mdat_buf);
7796 
7797 #if CONFIG_IAMFENC
7798  ffio_free_dyn_buf(&track->iamf_buf);
7799  if (track->iamf)
7800  ff_iamf_uninit_context(track->iamf);
7801  av_freep(&track->iamf);
7802 #endif
7803  ff_isom_close_apvc(&track->apv);
7804 
7806  }
7807 
7808  av_freep(&mov->tracks);
7809  ffio_free_dyn_buf(&mov->mdat_buf);
7810 }
7811 
7812 static uint32_t rgb_to_yuv(uint32_t rgb)
7813 {
7814  uint8_t r, g, b;
7815  int y, cb, cr;
7816 
7817  r = (rgb >> 16) & 0xFF;
7818  g = (rgb >> 8) & 0xFF;
7819  b = (rgb ) & 0xFF;
7820 
7821  y = av_clip_uint8(( 16000 + 257 * r + 504 * g + 98 * b)/1000);
7822  cb = av_clip_uint8((128000 - 148 * r - 291 * g + 439 * b)/1000);
7823  cr = av_clip_uint8((128000 + 439 * r - 368 * g - 71 * b)/1000);
7824 
7825  return (y << 16) | (cr << 8) | cb;
7826 }
7827 
7829  AVStream *st)
7830 {
7831  int i, width = 720, height = 480;
7832  int have_palette = 0, have_size = 0;
7833  uint32_t palette[16];
7834  char *cur = track->extradata[track->last_stsd_index];
7835 
7836  while (cur && *cur) {
7837  if (strncmp("palette:", cur, 8) == 0) {
7838  int i, count;
7839  count = sscanf(cur + 8,
7840  "%06"PRIx32", %06"PRIx32", %06"PRIx32", %06"PRIx32", "
7841  "%06"PRIx32", %06"PRIx32", %06"PRIx32", %06"PRIx32", "
7842  "%06"PRIx32", %06"PRIx32", %06"PRIx32", %06"PRIx32", "
7843  "%06"PRIx32", %06"PRIx32", %06"PRIx32", %06"PRIx32"",
7844  &palette[ 0], &palette[ 1], &palette[ 2], &palette[ 3],
7845  &palette[ 4], &palette[ 5], &palette[ 6], &palette[ 7],
7846  &palette[ 8], &palette[ 9], &palette[10], &palette[11],
7847  &palette[12], &palette[13], &palette[14], &palette[15]);
7848 
7849  for (i = 0; i < count; i++) {
7850  palette[i] = rgb_to_yuv(palette[i]);
7851  }
7852  have_palette = 1;
7853  } else if (!strncmp("size:", cur, 5)) {
7854  sscanf(cur + 5, "%dx%d", &width, &height);
7855  have_size = 1;
7856  }
7857  if (have_palette && have_size)
7858  break;
7859  cur += strcspn(cur, "\n\r");
7860  cur += strspn(cur, "\n\r");
7861  }
7862  if (have_palette) {
7864  if (!track->extradata[track->last_stsd_index])
7865  return AVERROR(ENOMEM);
7866  for (i = 0; i < 16; i++) {
7867  AV_WB32(track->extradata[track->last_stsd_index] + i * 4, palette[i]);
7868  }
7869  memset(track->extradata[track->last_stsd_index] + 16*4, 0, AV_INPUT_BUFFER_PADDING_SIZE);
7870  track->extradata_size[track->last_stsd_index] = 16 * 4;
7871  }
7872  st->codecpar->width = width;
7873  st->codecpar->height = track->height = height;
7874 
7875  return 0;
7876 }
7877 
7878 #if CONFIG_IAMFENC
7879 static int mov_init_iamf_track(AVFormatContext *s)
7880 {
7881  MOVMuxContext *mov = s->priv_data;
7882  MOVTrack *track;
7883  IAMFContext *iamf;
7884  int first_iamf_idx = INT_MAX, last_iamf_idx = 0;
7885  int nb_audio_elements = 0, nb_mix_presentations = 0;
7886  int ret;
7887 
7888  for (int i = 0; i < s->nb_stream_groups; i++) {
7889  const AVStreamGroup *stg = s->stream_groups[i];
7890 
7892  nb_audio_elements++;
7894  nb_mix_presentations++;
7895  }
7896 
7897  if (!nb_audio_elements && !nb_mix_presentations)
7898  return 0;
7899 
7900  if (nb_audio_elements < 1 || nb_audio_elements > 2 || nb_mix_presentations < 1) {
7901  av_log(s, AV_LOG_ERROR, "There must be >= 1 and <= 2 IAMF_AUDIO_ELEMENT and at least "
7902  "one IAMF_MIX_PRESENTATION stream groups to write a IMAF track\n");
7903  return AVERROR(EINVAL);
7904  }
7905 
7906  iamf = av_mallocz(sizeof(*iamf));
7907  if (!iamf)
7908  return AVERROR(ENOMEM);
7909 
7910 
7911  for (int i = 0; i < s->nb_stream_groups; i++) {
7912  const AVStreamGroup *stg = s->stream_groups[i];
7913  switch(stg->type) {
7915  for (int j = 0; j < stg->nb_streams; j++) {
7916  first_iamf_idx = FFMIN(stg->streams[j]->index, first_iamf_idx);
7917  last_iamf_idx = FFMAX(stg->streams[j]->index, last_iamf_idx);
7918  }
7919 
7920  ret = ff_iamf_add_audio_element(iamf, stg, s);
7921  break;
7923  ret = ff_iamf_add_mix_presentation(iamf, stg, s);
7924  break;
7925  default:
7926  av_assert0(0);
7927  }
7928  if (ret < 0) {
7929  ff_iamf_uninit_context(iamf);
7930  av_free(iamf);
7931  return ret;
7932  }
7933  }
7934 
7935  track = &mov->tracks[first_iamf_idx];
7936  track->iamf = iamf;
7937  track->first_iamf_idx = first_iamf_idx;
7938  track->last_iamf_idx = last_iamf_idx;
7939  track->tag = MKTAG('i','a','m','f');
7940 
7941  for (int i = 0; i < s->nb_stream_groups; i++) {
7942  AVStreamGroup *stg = s->stream_groups[i];
7944  continue;
7945  for (int j = 0; j < stg->nb_streams; j++)
7946  stg->streams[j]->priv_data = track;
7947  }
7948 
7949  ret = avio_open_dyn_buf(&track->iamf_buf);
7950  if (ret < 0)
7951  return ret;
7952 
7953  return 0;
7954 }
7955 #endif
7956 
7958 {
7959  MOVMuxContext *mov = s->priv_data;
7960  int has_iamf = 0;
7961  int i, ret;
7962 
7963  mov->fc = s;
7964  mov->pkt = ffformatcontext(s)->pkt;
7965 
7966  /* Default mode == MP4 */
7967  mov->mode = MODE_MP4;
7968 
7969 #define IS_MODE(muxer, config) (CONFIG_ ## config ## _MUXER && !strcmp(#muxer, s->oformat->name))
7970  if (IS_MODE(3gp, TGP)) mov->mode = MODE_3GP;
7971  else if (IS_MODE(3g2, TG2)) mov->mode = MODE_3GP|MODE_3G2;
7972  else if (IS_MODE(mov, MOV)) mov->mode = MODE_MOV;
7973  else if (IS_MODE(psp, PSP)) mov->mode = MODE_PSP;
7974  else if (IS_MODE(ipod, IPOD)) mov->mode = MODE_IPOD;
7975  else if (IS_MODE(ismv, ISMV)) mov->mode = MODE_ISM;
7976  else if (IS_MODE(f4v, F4V)) mov->mode = MODE_F4V;
7977  else if (IS_MODE(avif, AVIF)) mov->mode = MODE_AVIF;
7978 #undef IS_MODE
7979 
7980  if (mov->flags & FF_MOV_FLAG_DELAY_MOOV)
7981  mov->flags |= FF_MOV_FLAG_EMPTY_MOOV;
7982 
7983  if (mov->mode == MODE_AVIF)
7984  mov->flags |= FF_MOV_FLAG_DELAY_MOOV;
7985 
7986  /* Set the FRAGMENT flag if any of the fragmentation methods are
7987  * enabled. */
7988  if (mov->max_fragment_duration || mov->max_fragment_size ||
7989  mov->flags & (FF_MOV_FLAG_EMPTY_MOOV |
7993  mov->flags |= FF_MOV_FLAG_FRAGMENT;
7994 
7995  if (mov->flags & FF_MOV_FLAG_HYBRID_FRAGMENTED &&
7996  mov->flags & FF_MOV_FLAG_FASTSTART) {
7997  av_log(s, AV_LOG_ERROR, "Setting both hybrid_fragmented and faststart is not supported.\n");
7998  return AVERROR(EINVAL);
7999  }
8000 
8001  /* Set other implicit flags immediately */
8003  mov->flags |= FF_MOV_FLAG_FRAGMENT;
8004 
8005  if (mov->mode == MODE_ISM)
8008  if (mov->flags & FF_MOV_FLAG_DASH)
8011  if (mov->flags & FF_MOV_FLAG_CMAF)
8014 
8015  if (mov->flags & FF_MOV_FLAG_EMPTY_MOOV && s->flags & AVFMT_FLAG_AUTO_BSF) {
8016  av_log(s, AV_LOG_VERBOSE, "Empty MOOV enabled; disabling automatic bitstream filtering\n");
8017  s->flags &= ~AVFMT_FLAG_AUTO_BSF;
8018  }
8019 
8021  av_log(s, AV_LOG_WARNING, "Global SIDX enabled; Ignoring skip_sidx option\n");
8022  mov->flags &= ~FF_MOV_FLAG_SKIP_SIDX;
8023  }
8024 
8025  if (mov->flags & FF_MOV_FLAG_FASTSTART) {
8026  mov->reserved_moov_size = -1;
8027  }
8028 
8029  if (mov->use_editlist < 0) {
8030  mov->use_editlist = 1;
8031  if (mov->flags & FF_MOV_FLAG_FRAGMENT &&
8032  !(mov->flags & FF_MOV_FLAG_DELAY_MOOV)) {
8033  // If we can avoid needing an edit list by shifting the
8034  // tracks, prefer that over (trying to) write edit lists
8035  // in fragmented output.
8036  if (s->avoid_negative_ts == AVFMT_AVOID_NEG_TS_AUTO ||
8037  s->avoid_negative_ts == AVFMT_AVOID_NEG_TS_MAKE_ZERO)
8038  mov->use_editlist = 0;
8039  }
8040  }
8041  if (mov->flags & FF_MOV_FLAG_EMPTY_MOOV &&
8042  !(mov->flags & FF_MOV_FLAG_DELAY_MOOV) && mov->use_editlist)
8043  av_log(s, AV_LOG_WARNING, "No meaningful edit list will be written when using empty_moov without delay_moov\n");
8044 
8045  if (!mov->use_editlist && s->avoid_negative_ts == AVFMT_AVOID_NEG_TS_AUTO &&
8047  s->avoid_negative_ts = AVFMT_AVOID_NEG_TS_MAKE_ZERO;
8048 
8049  /* Clear the omit_tfhd_offset flag if default_base_moof is set;
8050  * if the latter is set that's enough and omit_tfhd_offset doesn't
8051  * add anything extra on top of that. */
8052  if (mov->flags & FF_MOV_FLAG_OMIT_TFHD_OFFSET &&
8055 
8056  if (mov->frag_interleave &&
8059  "Sample interleaving in fragments is mutually exclusive with "
8060  "omit_tfhd_offset and separate_moof\n");
8061  return AVERROR(EINVAL);
8062  }
8063 
8064  /* Non-seekable output is ok if using fragmentation. If ism_lookahead
8065  * is enabled, we don't support non-seekable output at all. */
8066  if (!(s->pb->seekable & AVIO_SEEKABLE_NORMAL) &&
8067  (!(mov->flags & FF_MOV_FLAG_FRAGMENT) || mov->ism_lookahead ||
8068  mov->mode == MODE_AVIF)) {
8069  av_log(s, AV_LOG_ERROR, "muxer does not support non seekable output\n");
8070  return AVERROR(EINVAL);
8071  }
8072 
8073  /* AVIF output must have at most two video streams (one for YUV and one for
8074  * alpha). */
8075  if (mov->mode == MODE_AVIF) {
8076  if (s->nb_streams > 2) {
8077  av_log(s, AV_LOG_ERROR, "AVIF output requires exactly one or two streams\n");
8078  return AVERROR(EINVAL);
8079  }
8080  if (s->streams[0]->codecpar->codec_type != AVMEDIA_TYPE_VIDEO &&
8081  (s->nb_streams > 1 && s->streams[1]->codecpar->codec_type != AVMEDIA_TYPE_VIDEO)) {
8082  av_log(s, AV_LOG_ERROR, "AVIF output supports only video streams\n");
8083  return AVERROR(EINVAL);
8084  }
8085  if (s->nb_streams > 1) {
8086  const AVPixFmtDescriptor *pixdesc =
8087  av_pix_fmt_desc_get(s->streams[1]->codecpar->format);
8088  if (pixdesc->nb_components != 1) {
8089  av_log(s, AV_LOG_ERROR, "Second stream for AVIF (alpha) output must have exactly one plane\n");
8090  return AVERROR(EINVAL);
8091  }
8092  }
8093  s->streams[0]->disposition |= AV_DISPOSITION_DEFAULT;
8094  }
8095 
8096  for (i = 0; i < s->nb_stream_groups; i++) {
8097  AVStreamGroup *stg = s->stream_groups[i];
8098 
8099  if (stg->type == AV_STREAM_GROUP_PARAMS_LCEVC) {
8100  if (stg->nb_streams != 2) {
8101  av_log(s, AV_LOG_ERROR, "Exactly two Streams are supported for Stream Groups of type LCEVC\n");
8102  return AVERROR(EINVAL);
8103  }
8104  AVStreamGroupLCEVC *lcevc = stg->params.lcevc;
8105  if (lcevc->lcevc_index > 1)
8106  return AVERROR(EINVAL);
8107  AVStream *st = stg->streams[lcevc->lcevc_index];
8108  if (st->codecpar->codec_id != AV_CODEC_ID_LCEVC) {
8109  av_log(s, AV_LOG_ERROR, "Stream #%u is not an LCEVC stream\n", lcevc->lcevc_index);
8110  return AVERROR(EINVAL);
8111  }
8112  }
8113 
8114 #if CONFIG_IAMFENC
8116  continue;
8117 
8118  for (int j = 0; j < stg->nb_streams; j++) {
8119  AVStream *st = stg->streams[j];
8120 
8121  if (st->priv_data) {
8122  av_log(s, AV_LOG_ERROR, "Stream %d is present in more than one Stream Group of type "
8123  "IAMF Audio Element\n", j);
8124  return AVERROR(EINVAL);
8125  }
8126  st->priv_data = st;
8127  }
8128  has_iamf = 1;
8129 
8130  if (!mov->nb_tracks) // We support one track for the entire IAMF structure
8131  mov->nb_tracks++;
8132 #endif
8133  }
8134 
8135  for (i = 0; i < s->nb_streams; i++) {
8136  AVStream *st = s->streams[i];
8137  if (st->priv_data)
8138  continue;
8139  // Don't produce a track in the output file for timed ID3 streams.
8140  if (st->codecpar->codec_id == AV_CODEC_ID_TIMED_ID3) {
8141  // Leave priv_data set to NULL for these AVStreams that don't
8142  // have a corresponding track.
8143  continue;
8144  }
8145  st->priv_data = st;
8146  mov->nb_tracks++;
8147  }
8148 
8149  mov->nb_streams = mov->nb_tracks;
8150 
8151  if (mov->mode & (MODE_MP4|MODE_MOV|MODE_IPOD) && s->nb_chapters)
8152  mov->chapter_track = mov->nb_tracks++;
8153 
8154  if (mov->flags & FF_MOV_FLAG_RTP_HINT) {
8155  for (i = 0; i < s->nb_streams; i++)
8156  if (rtp_hinting_needed(s->streams[i]))
8157  mov->nb_tracks++;
8158  }
8159 
8160  if (mov->write_btrt < 0) {
8161  mov->write_btrt = mov->mode == MODE_MP4;
8162  }
8163 
8164  if ( mov->write_tmcd == -1 && (mov->mode == MODE_MOV || mov->mode == MODE_MP4)
8165  || mov->write_tmcd == 1) {
8166  AVDictionaryEntry *global_tcr = av_dict_get(s->metadata, "timecode",
8167  NULL, 0);
8168 
8169  /* +1 tmcd track for each video stream with a timecode */
8170  for (i = 0; i < s->nb_streams; i++) {
8171  AVStream *st = s->streams[i];
8172  AVDictionaryEntry *t = global_tcr;
8173  if (st->codecpar->codec_type == AVMEDIA_TYPE_VIDEO &&
8174  (t || (t=av_dict_get(st->metadata, "timecode", NULL, 0)))) {
8175  AVTimecode tc;
8176  ret = mov_check_timecode_track(s, &tc, st, t->value);
8177  if (ret >= 0)
8178  mov->nb_meta_tmcd++;
8179  }
8180  }
8181 
8182  /* check if there is already a tmcd track to remux */
8183  if (mov->nb_meta_tmcd) {
8184  for (i = 0; i < s->nb_streams; i++) {
8185  AVStream *st = s->streams[i];
8186  if (st->codecpar->codec_tag == MKTAG('t','m','c','d')) {
8187  av_log(s, AV_LOG_WARNING, "You requested a copy of the original timecode track "
8188  "so timecode metadata are now ignored\n");
8189  mov->nb_meta_tmcd = 0;
8190  }
8191  }
8192  }
8193 
8194  mov->nb_tracks += mov->nb_meta_tmcd;
8195  }
8196 
8197  // Reserve an extra stream for chapters for the case where chapters
8198  // are written in the trailer
8199  mov->tracks = av_calloc(mov->nb_tracks + 1, sizeof(*mov->tracks));
8200  if (!mov->tracks)
8201  return AVERROR(ENOMEM);
8202 
8203  for (i = 0; i < mov->nb_tracks; i++) {
8204  MOVTrack *track = &mov->tracks[i];
8205 
8206  track->stsd_count = 1;
8207  track->extradata = av_calloc(track->stsd_count, sizeof(*track->extradata));
8208  track->extradata_size = av_calloc(track->stsd_count, sizeof(*track->extradata_size));
8209  if (!track->extradata || !track->extradata_size)
8210  return AVERROR(ENOMEM);
8211  }
8212 
8213  if (mov->encryption_scheme_str != NULL && strcmp(mov->encryption_scheme_str, "none") != 0) {
8214  if (strcmp(mov->encryption_scheme_str, "cenc-aes-ctr") == 0) {
8216 
8217  if (mov->encryption_key_len != AES_CTR_KEY_SIZE) {
8218  av_log(s, AV_LOG_ERROR, "Invalid encryption key len %d expected %d\n",
8220  return AVERROR(EINVAL);
8221  }
8222 
8223  if (mov->encryption_kid_len != CENC_KID_SIZE) {
8224  av_log(s, AV_LOG_ERROR, "Invalid encryption kid len %d expected %d\n",
8226  return AVERROR(EINVAL);
8227  }
8228  } else {
8229  av_log(s, AV_LOG_ERROR, "unsupported encryption scheme %s\n",
8230  mov->encryption_scheme_str);
8231  return AVERROR(EINVAL);
8232  }
8233  }
8234 
8235 #if CONFIG_IAMFENC
8236  ret = mov_init_iamf_track(s);
8237  if (ret < 0)
8238  return ret;
8239 #endif
8240 
8241  for (int j = 0, i = 0; j < s->nb_streams; j++) {
8242  AVStream *st = s->streams[j];
8243 
8244  if (st != st->priv_data) {
8245  if (has_iamf)
8246  i += has_iamf--;
8247  continue;
8248  }
8249  st->priv_data = &mov->tracks[i++];
8250  }
8251 
8252  for (i = 0; i < s->nb_streams; i++) {
8253  AVStream *st= s->streams[i];
8254  MOVTrack *track = st->priv_data;
8255  AVDictionaryEntry *lang = av_dict_get(st->metadata, "language", NULL,0);
8256 
8257  if (!track)
8258  continue;
8259 
8260  if (!track->st) {
8261  track->st = st;
8262  track->par = st->codecpar;
8263  }
8264  track->language = ff_mov_iso639_to_lang(lang?lang->value:"und", mov->mode!=MODE_MOV);
8265  if (track->language < 0)
8266  track->language = 32767; // Unspecified Macintosh language code
8267  track->mode = mov->mode;
8268  if (!track->tag)
8269  track->tag = mov_find_codec_tag(s, track);
8270  if (!track->tag) {
8271  av_log(s, AV_LOG_ERROR, "Could not find tag for codec %s in stream #%d, "
8272  "codec not currently supported in container\n",
8274  return AVERROR(EINVAL);
8275  }
8276  /* If hinting of this track is enabled by a later hint track,
8277  * this is updated. */
8278  track->hint_track = -1;
8279  track->start_dts = AV_NOPTS_VALUE;
8280  track->start_cts = AV_NOPTS_VALUE;
8281  track->end_pts = AV_NOPTS_VALUE;
8282  track->dts_shift = AV_NOPTS_VALUE;
8283  if (st->codecpar->codec_type == AVMEDIA_TYPE_VIDEO) {
8284  if (track->tag == MKTAG('m','x','3','p') || track->tag == MKTAG('m','x','3','n') ||
8285  track->tag == MKTAG('m','x','4','p') || track->tag == MKTAG('m','x','4','n') ||
8286  track->tag == MKTAG('m','x','5','p') || track->tag == MKTAG('m','x','5','n')) {
8287  if (st->codecpar->width != 720 || (st->codecpar->height != 608 && st->codecpar->height != 512)) {
8288  av_log(s, AV_LOG_ERROR, "D-10/IMX must use 720x608 or 720x512 video resolution\n");
8289  return AVERROR(EINVAL);
8290  }
8291  track->height = track->tag >> 24 == 'n' ? 486 : 576;
8292  }
8293  if (mov->video_track_timescale) {
8294  track->timescale = mov->video_track_timescale;
8295  if (mov->mode == MODE_ISM && mov->video_track_timescale != 10000000)
8296  av_log(s, AV_LOG_WARNING, "Warning: some tools, like mp4split, assume a timescale of 10000000 for ISMV.\n");
8297  } else {
8298  track->timescale = st->time_base.den;
8299  while(track->timescale < 10000)
8300  track->timescale *= 2;
8301  }
8302  if (st->codecpar->width > 65535 || st->codecpar->height > 65535) {
8303  av_log(s, AV_LOG_ERROR, "Resolution %dx%d too large for mov/mp4\n", st->codecpar->width, st->codecpar->height);
8304  return AVERROR(EINVAL);
8305  }
8306  if (track->mode == MODE_MOV && track->timescale > 100000)
8308  "WARNING codec timebase is very high. If duration is too long,\n"
8309  "file may not be playable by quicktime. Specify a shorter timebase\n"
8310  "or choose different container.\n");
8311  if (track->mode == MODE_MOV &&
8312  track->par->codec_id == AV_CODEC_ID_RAWVIDEO &&
8313  track->tag == MKTAG('r','a','w',' ')) {
8314  enum AVPixelFormat pix_fmt = track->par->format;
8315  if (pix_fmt == AV_PIX_FMT_NONE && track->par->bits_per_coded_sample == 1)
8317  track->is_unaligned_qt_rgb =
8320  pix_fmt == AV_PIX_FMT_PAL8 ||
8324  }
8325  if (track->par->codec_id == AV_CODEC_ID_VP9 && track->mode != MODE_MP4) {
8326  av_log(s, AV_LOG_ERROR, "%s only supported in MP4.\n", avcodec_get_name(track->par->codec_id));
8327  return AVERROR(EINVAL);
8328  } else if (track->par->codec_id == AV_CODEC_ID_AV1 &&
8329  track->mode != MODE_MP4 && track->mode != MODE_AVIF) {
8330  av_log(s, AV_LOG_ERROR, "%s only supported in MP4 and AVIF.\n", avcodec_get_name(track->par->codec_id));
8331  return AVERROR(EINVAL);
8332  } else if (track->par->codec_id == AV_CODEC_ID_VP8) {
8333  /* altref frames handling is not defined in the spec as of version v1.0,
8334  * so just forbid muxing VP8 streams altogether until a new version does */
8335  av_log(s, AV_LOG_ERROR, "VP8 muxing is currently not supported.\n");
8336  return AVERROR_PATCHWELCOME;
8337  } else if (track->par->codec_id == AV_CODEC_ID_APV) {
8338  ret = ff_isom_init_apvc(&track->apv, s);
8339  if (ret < 0)
8340  return ret;
8341  }
8342  if (is_cover_image(st)) {
8343  track->cover_image = av_packet_alloc();
8344  if (!track->cover_image)
8345  return AVERROR(ENOMEM);
8346  }
8347  } else if (st->codecpar->codec_type == AVMEDIA_TYPE_AUDIO) {
8348  track->timescale = st->codecpar->sample_rate;
8350  av_log(s, AV_LOG_WARNING, "track %d: codec frame size is not set\n", i);
8351  track->audio_vbr = 1;
8352  }else if (st->codecpar->codec_id == AV_CODEC_ID_ADPCM_MS ||
8355  if (!st->codecpar->block_align) {
8356  av_log(s, AV_LOG_ERROR, "track %d: codec block align is not set for adpcm\n", i);
8357  return AVERROR(EINVAL);
8358  }
8359  track->sample_size = st->codecpar->block_align;
8360  }else if (st->codecpar->frame_size > 1){ /* assume compressed audio */
8361  track->audio_vbr = 1;
8362  }else{
8363  track->sample_size = (av_get_bits_per_sample(st->codecpar->codec_id) >> 3) *
8365  }
8366  if (st->codecpar->codec_id == AV_CODEC_ID_ILBC ||
8368  track->audio_vbr = 1;
8369  }
8370  if (track->mode != MODE_MOV &&
8371  track->par->codec_id == AV_CODEC_ID_MP3 && track->timescale < 16000) {
8372  if (s->strict_std_compliance >= FF_COMPLIANCE_NORMAL) {
8373  av_log(s, AV_LOG_ERROR, "track %d: muxing mp3 at %dhz is not standard, to mux anyway set strict to -1\n",
8374  i, track->par->sample_rate);
8375  return AVERROR(EINVAL);
8376  } else {
8377  av_log(s, AV_LOG_WARNING, "track %d: muxing mp3 at %dhz is not standard in MP4\n",
8378  i, track->par->sample_rate);
8379  }
8380  }
8381  if (track->par->codec_id == AV_CODEC_ID_FLAC ||
8382  track->par->codec_id == AV_CODEC_ID_TRUEHD ||
8383  track->par->codec_id == AV_CODEC_ID_OPUS) {
8384  if (track->mode != MODE_MP4) {
8385  av_log(s, AV_LOG_ERROR, "%s only supported in MP4.\n", avcodec_get_name(track->par->codec_id));
8386  return AVERROR(EINVAL);
8387  }
8388  if (track->par->codec_id == AV_CODEC_ID_TRUEHD &&
8389  s->strict_std_compliance > FF_COMPLIANCE_EXPERIMENTAL) {
8391  "%s in MP4 support is experimental, add "
8392  "'-strict %d' if you want to use it.\n",
8394  return AVERROR_EXPERIMENTAL;
8395  }
8396  }
8397  } else if (st->codecpar->codec_type == AVMEDIA_TYPE_SUBTITLE) {
8398  track->timescale = st->time_base.den;
8399 
8400  if (track->par->codec_id == AV_CODEC_ID_TTML) {
8401  /* 14496-30 requires us to use a single sample per fragment
8402  for TTML, for which we define a per-track flag.
8403 
8404  We set the flag in case we are receiving TTML paragraphs
8405  from the input, in other words in case we are not doing
8406  stream copy. */
8409 
8410  if (track->mode != MODE_ISM &&
8411  track->par->codec_tag == MOV_ISMV_TTML_TAG &&
8412  s->strict_std_compliance > FF_COMPLIANCE_UNOFFICIAL) {
8414  "ISMV style TTML support with the 'dfxp' tag in "
8415  "non-ISMV formats is not officially supported. Add "
8416  "'-strict unofficial' if you want to use it.\n");
8417  return AVERROR_EXPERIMENTAL;
8418  }
8419  }
8420  } else if (st->codecpar->codec_type == AVMEDIA_TYPE_DATA) {
8421  track->timescale = st->time_base.den;
8422  } else {
8423  track->timescale = mov->movie_timescale;
8424  }
8425  if (!track->height)
8426  track->height = st->codecpar->height;
8427  /* The Protected Interoperable File Format (PIFF) standard, used by ISMV recommends but
8428  doesn't mandate a track timescale of 10,000,000. The muxer allows a custom timescale
8429  for video tracks, so if user-set, it isn't overwritten */
8430  if (mov->mode == MODE_ISM &&
8433  track->timescale = 10000000;
8434  }
8435 
8436  avpriv_set_pts_info(st, 64, 1, track->timescale);
8437 
8439  ret = ff_mov_cenc_init(&track->cenc, mov->encryption_key,
8440  (track->par->codec_id == AV_CODEC_ID_H264 || track->par->codec_id == AV_CODEC_ID_HEVC ||
8441  track->par->codec_id == AV_CODEC_ID_VVC || track->par->codec_id == AV_CODEC_ID_AV1),
8442  track->par->codec_id, s->flags & AVFMT_FLAG_BITEXACT);
8443  if (ret)
8444  return ret;
8445  }
8446  }
8447 
8448  for (i = 0; i < s->nb_stream_groups; i++) {
8449  AVStreamGroup *stg = s->stream_groups[i];
8450 
8451  if (stg->type != AV_STREAM_GROUP_PARAMS_LCEVC)
8452  continue;
8453 
8454  AVStreamGroupLCEVC *lcevc = stg->params.lcevc;
8455  AVStream *st = stg->streams[lcevc->lcevc_index];
8456  MOVTrack *track = st->priv_data;
8457 
8458  for (int j = 0; j < mov->nb_tracks; j++) {
8459  MOVTrack *trk = &mov->tracks[j];
8460 
8461  if (trk->st == stg->streams[!lcevc->lcevc_index]) {
8462  track->src_track = j;
8463  break;
8464  }
8465  }
8466 
8467  track->par->width = lcevc->width;
8468  track->par->height = track->height = lcevc->height;
8469  }
8470 
8471  enable_tracks(s);
8472  return 0;
8473 }
8474 
8476 {
8477  AVIOContext *pb = s->pb;
8478  MOVMuxContext *mov = s->priv_data;
8479  int ret, hint_track = 0, tmcd_track = 0, nb_tracks = mov->nb_streams;
8480 
8481  if (mov->mode & (MODE_MP4|MODE_MOV|MODE_IPOD) && s->nb_chapters)
8482  nb_tracks++;
8483 
8484  if (mov->flags & FF_MOV_FLAG_RTP_HINT) {
8485  hint_track = nb_tracks;
8486  for (int i = 0; i < mov->nb_streams; i++) {
8487  if (rtp_hinting_needed(mov->tracks[i].st))
8488  nb_tracks++;
8489  }
8490  }
8491 
8492  if (mov->nb_meta_tmcd)
8493  tmcd_track = nb_tracks;
8494 
8495  for (int i = 0; i < mov->nb_streams; i++) {
8496  MOVTrack *track = &mov->tracks[i];
8497  AVStream *st = track->st;
8498 
8499  /* copy extradata if it exists */
8500  if (st->codecpar->extradata_size) {
8503  else if (!TAG_IS_AVCI(track->tag) && st->codecpar->codec_id != AV_CODEC_ID_DNXHD) {
8504  track->extradata_size[track->last_stsd_index] = st->codecpar->extradata_size;
8505  track->extradata[track->last_stsd_index] =
8507  if (!track->extradata[track->last_stsd_index]) {
8508  return AVERROR(ENOMEM);
8509  }
8510  memcpy(track->extradata[track->last_stsd_index],
8511  st->codecpar->extradata, track->extradata_size[track->last_stsd_index]);
8512  memset(track->extradata[track->last_stsd_index] + track->extradata_size[track->last_stsd_index],
8514  }
8515  }
8516 
8517  if (st->codecpar->codec_type != AVMEDIA_TYPE_AUDIO ||
8520  continue;
8521 
8522  for (int j = 0; j < mov->nb_streams; j++) {
8523  AVStream *stj= mov->tracks[j].st;
8524  MOVTrack *trackj= &mov->tracks[j];
8525  if (j == i)
8526  continue;
8527 
8528  if (stj->codecpar->codec_type == AVMEDIA_TYPE_AUDIO &&
8529  (trackj->par->ch_layout.nb_channels != 1 ||
8532  )
8533  track->mono_as_fc = -1;
8534 
8535  if (stj->codecpar->codec_type == AVMEDIA_TYPE_AUDIO &&
8538  trackj->par->ch_layout.nb_channels == 1 && track->mono_as_fc >= 0
8539  )
8540  track->mono_as_fc++;
8541 
8542  if (stj->codecpar->codec_type != AVMEDIA_TYPE_AUDIO ||
8545  trackj->language != track->language ||
8546  trackj->tag != track->tag
8547  )
8548  continue;
8549  track->multichannel_as_mono++;
8550  }
8551  }
8552 
8553  if (!(mov->flags & FF_MOV_FLAG_DELAY_MOOV) ||
8555  if ((ret = mov_write_identification(pb, s)) < 0)
8556  return ret;
8557  }
8558 
8559  if (mov->reserved_moov_size){
8560  mov->reserved_header_pos = avio_tell(pb);
8561  if (mov->reserved_moov_size > 0)
8562  avio_skip(pb, mov->reserved_moov_size);
8563  }
8564 
8565  if (mov->flags & FF_MOV_FLAG_FRAGMENT) {
8566  /* If no fragmentation options have been set, set a default. */
8567  if (!(mov->flags & (FF_MOV_FLAG_FRAG_KEYFRAME |
8572  if (mov->flags & FF_MOV_FLAG_HYBRID_FRAGMENTED) {
8573  avio_wb32(pb, 8); // placeholder for extended size field (64 bit)
8574  ffio_wfourcc(pb, mov->mode == MODE_MOV ? "wide" : "free");
8575  mov->mdat_pos = avio_tell(pb);
8576  // The free/wide header that later will be converted into an
8577  // mdat, covering the initial moov and all the fragments.
8578  avio_wb32(pb, 0);
8579  ffio_wfourcc(pb, mov->mode == MODE_MOV ? "wide" : "free");
8580  // Write an ftyp atom, hidden in a free/wide. This is neither
8581  // exposed while the file is written, as fragmented, nor when the
8582  // file is finalized into non-fragmented form. However, this allows
8583  // accessing a pristine, sequential ftyp+moov init segment, even
8584  // after the file is finalized. It also allows dumping the whole
8585  // contents of the mdat box, to get the fragmented form of the
8586  // file.
8587  if ((ret = mov_write_identification(pb, s)) < 0)
8588  return ret;
8589  update_size(pb, mov->mdat_pos);
8590  }
8591  } else if (mov->mode != MODE_AVIF) {
8592  if (mov->flags & FF_MOV_FLAG_FASTSTART)
8593  mov->reserved_header_pos = avio_tell(pb);
8594  mov_write_mdat_tag(pb, mov);
8595  }
8596 
8598  if (mov->time)
8599  mov->time += 0x7C25B080; // 1970 based -> 1904 based
8600 
8601  if (mov->chapter_track)
8602  if ((ret = mov_create_chapter_track(s, mov->chapter_track)) < 0)
8603  return ret;
8604 
8605  if (mov->flags & FF_MOV_FLAG_RTP_HINT) {
8606  for (int i = 0; i < mov->nb_streams; i++) {
8607  if (rtp_hinting_needed(mov->tracks[i].st)) {
8608  if ((ret = ff_mov_init_hinting(s, hint_track, i)) < 0)
8609  return ret;
8610  hint_track++;
8611  }
8612  }
8613  }
8614 
8615  if (mov->nb_meta_tmcd) {
8616  const AVDictionaryEntry *t, *global_tcr = av_dict_get(s->metadata,
8617  "timecode", NULL, 0);
8618  /* Initialize the tmcd tracks */
8619  for (int i = 0; i < mov->nb_streams; i++) {
8620  AVStream *st = mov->tracks[i].st;
8621  t = global_tcr;
8622 
8623  if (st->codecpar->codec_type == AVMEDIA_TYPE_VIDEO) {
8624  AVTimecode tc;
8625  if (!t)
8626  t = av_dict_get(st->metadata, "timecode", NULL, 0);
8627  if (!t)
8628  continue;
8629  if (mov_check_timecode_track(s, &tc, st, t->value) < 0)
8630  continue;
8631  if ((ret = mov_create_timecode_track(s, tmcd_track, i, tc)) < 0)
8632  return ret;
8633  tmcd_track++;
8634  }
8635  }
8636  }
8637 
8638  avio_flush(pb);
8639 
8640  if (mov->flags & FF_MOV_FLAG_ISML)
8641  mov_write_isml_manifest(pb, mov, s);
8642 
8643  if (mov->flags & FF_MOV_FLAG_EMPTY_MOOV &&
8644  !(mov->flags & FF_MOV_FLAG_DELAY_MOOV)) {
8645  if ((ret = mov_write_moov_tag(pb, mov, s)) < 0)
8646  return ret;
8647  mov->moov_written = 1;
8648  if (mov->flags & FF_MOV_FLAG_GLOBAL_SIDX)
8649  mov->reserved_header_pos = avio_tell(pb);
8650  }
8651 
8652  return 0;
8653 }
8654 
8656 {
8657  int ret;
8658  AVIOContext *moov_buf;
8659  MOVMuxContext *mov = s->priv_data;
8660 
8661  if ((ret = ffio_open_null_buf(&moov_buf)) < 0)
8662  return ret;
8663  if ((ret = mov_write_moov_tag(moov_buf, mov, s)) < 0)
8664  return ret;
8665  return ffio_close_null_buf(moov_buf);
8666 }
8667 
8669 {
8670  int ret;
8671  AVIOContext *buf;
8672  MOVMuxContext *mov = s->priv_data;
8673 
8674  if ((ret = ffio_open_null_buf(&buf)) < 0)
8675  return ret;
8676  mov_write_sidx_tags(buf, mov, -1, 0);
8677  return ffio_close_null_buf(buf);
8678 }
8679 
8680 /*
8681  * This function gets the moov size if moved to the top of the file: the chunk
8682  * offset table can switch between stco (32-bit entries) to co64 (64-bit
8683  * entries) when the moov is moved to the beginning, so the size of the moov
8684  * would change. It also updates the chunk offset tables.
8685  */
8687 {
8688  int i, moov_size, moov_size2;
8689  MOVMuxContext *mov = s->priv_data;
8690 
8691  moov_size = get_moov_size(s);
8692  if (moov_size < 0)
8693  return moov_size;
8694 
8695  for (i = 0; i < mov->nb_tracks; i++)
8696  mov->tracks[i].data_offset += moov_size;
8697 
8698  moov_size2 = get_moov_size(s);
8699  if (moov_size2 < 0)
8700  return moov_size2;
8701 
8702  /* if the size changed, we just switched from stco to co64 and need to
8703  * update the offsets */
8704  if (moov_size2 != moov_size)
8705  for (i = 0; i < mov->nb_tracks; i++)
8706  mov->tracks[i].data_offset += moov_size2 - moov_size;
8707 
8708  return moov_size2;
8709 }
8710 
8712 {
8713  int i, sidx_size;
8714  MOVMuxContext *mov = s->priv_data;
8715 
8716  sidx_size = get_sidx_size(s);
8717  if (sidx_size < 0)
8718  return sidx_size;
8719 
8720  for (i = 0; i < mov->nb_tracks; i++)
8721  mov->tracks[i].data_offset += sidx_size;
8722 
8723  return sidx_size;
8724 }
8725 
8727 {
8728  int moov_size;
8729  MOVMuxContext *mov = s->priv_data;
8730 
8731  if (mov->flags & FF_MOV_FLAG_FRAGMENT)
8732  moov_size = compute_sidx_size(s);
8733  else
8734  moov_size = compute_moov_size(s);
8735  if (moov_size < 0)
8736  return moov_size;
8737 
8738  return ff_format_shift_data(s, mov->reserved_header_pos, moov_size);
8739 }
8740 
8742 {
8743  MOVMuxContext *mov = s->priv_data;
8744  AVIOContext *pb = s->pb;
8745 
8746  /* Write size of mdat tag */
8747  if (mov->mdat_size + 8 <= UINT32_MAX) {
8748  avio_seek(pb, mov->mdat_pos, SEEK_SET);
8749  avio_wb32(pb, mov->mdat_size + 8);
8751  ffio_wfourcc(pb, "mdat"); // overwrite the original free/wide into a mdat
8752  } else {
8753  /* overwrite 'wide' placeholder atom */
8754  avio_seek(pb, mov->mdat_pos - 8, SEEK_SET);
8755  /* special value: real atom size will be 64 bit value after
8756  * tag field */
8757  avio_wb32(pb, 1);
8758  ffio_wfourcc(pb, "mdat");
8759  avio_wb64(pb, mov->mdat_size + 16);
8760  }
8761 }
8762 
8764 {
8765  MOVMuxContext *mov = s->priv_data;
8766  AVIOContext *pb = s->pb;
8767  int res = 0;
8768  int i;
8769  int64_t moov_pos;
8770 
8771  /*
8772  * Before actually writing the trailer, make sure that there are no
8773  * dangling subtitles, that need a terminating sample.
8774  */
8775  for (i = 0; i < mov->nb_tracks; i++) {
8776  MOVTrack *trk = &mov->tracks[i];
8777  if (trk->par->codec_id == AV_CODEC_ID_MOV_TEXT &&
8780  trk->last_sample_is_subtitle_end = 1;
8781  }
8782  }
8783 
8784  // Check if we have any tracks that require squashing.
8785  // In that case, we'll have to write the packet here.
8786  if ((res = mov_write_squashed_packets(s)) < 0)
8787  return res;
8788 
8789  // If there were no chapters when the header was written, but there
8790  // are chapters now, write them in the trailer. This only works
8791  // when we are not doing fragments.
8792  if (!mov->chapter_track && !(mov->flags & FF_MOV_FLAG_FRAGMENT)) {
8793  if (mov->mode & (MODE_MP4|MODE_MOV|MODE_IPOD) && s->nb_chapters) {
8794  mov->chapter_track = mov->nb_tracks++;
8795  if ((res = mov_create_chapter_track(s, mov->chapter_track)) < 0)
8796  return res;
8797  }
8798  }
8799 
8800  if (!(mov->flags & FF_MOV_FLAG_FRAGMENT) ||
8802  if (mov->flags & FF_MOV_FLAG_HYBRID_FRAGMENTED) {
8804  mov->mdat_size = avio_tell(pb) - mov->mdat_pos - 8;
8805  for (i = 0; i < mov->nb_tracks; i++) {
8806  MOVTrack *track = &mov->tracks[i];
8807  track->data_offset = 0;
8808  av_free(track->cluster);
8809  track->cluster = track->cluster_written;
8810  track->entry = track->entry_written;
8811  track->cluster_written = NULL;
8812  track->entry_written = 0;
8813  track->chunkCount = 0; // Force build_chunks to rebuild the list of chunks
8814  }
8815  // Clear the empty_moov flag, as we do want the moov to include
8816  // all the samples at this point.
8817  mov->flags &= ~FF_MOV_FLAG_EMPTY_MOOV;
8818  }
8819 
8820  moov_pos = avio_tell(pb);
8821 
8822  if (!(mov->flags & FF_MOV_FLAG_HYBRID_FRAGMENTED))
8824 
8825  avio_seek(pb, mov->reserved_moov_size > 0 ? mov->reserved_header_pos : moov_pos, SEEK_SET);
8826 
8827  if (mov->flags & FF_MOV_FLAG_FASTSTART) {
8828  av_log(s, AV_LOG_INFO, "Starting second pass: moving the moov atom to the beginning of the file\n");
8829  res = shift_data(s);
8830  if (res < 0)
8831  return res;
8832  avio_seek(pb, mov->reserved_header_pos, SEEK_SET);
8833  if ((res = mov_write_moov_tag(pb, mov, s)) < 0)
8834  return res;
8835  } else if (mov->reserved_moov_size > 0) {
8836  int64_t size;
8837  if ((res = mov_write_moov_tag(pb, mov, s)) < 0)
8838  return res;
8839  size = mov->reserved_moov_size - (avio_tell(pb) - mov->reserved_header_pos);
8840  if (size < 8){
8841  av_log(s, AV_LOG_ERROR, "reserved_moov_size is too small, needed %"PRId64" additional\n", 8-size);
8842  return AVERROR(EINVAL);
8843  }
8844  avio_wb32(pb, size);
8845  ffio_wfourcc(pb, "free");
8846  ffio_fill(pb, 0, size - 8);
8847  avio_seek(pb, moov_pos, SEEK_SET);
8848  } else {
8849  if ((res = mov_write_moov_tag(pb, mov, s)) < 0)
8850  return res;
8851  }
8852 
8853  if (mov->flags & FF_MOV_FLAG_HYBRID_FRAGMENTED) {
8854  // With hybrid fragmentation, only write the mdat size (hiding
8855  // the original moov and all the fragments within the mdat)
8856  // after we've successfully written the complete moov, to avoid
8857  // risk for an unreadable file if writing the final moov fails.
8859  }
8860 
8861  res = 0;
8862  } else {
8864  for (i = 0; i < mov->nb_tracks; i++)
8865  mov->tracks[i].data_offset = 0;
8866  if (mov->flags & FF_MOV_FLAG_GLOBAL_SIDX) {
8867  int64_t end;
8868  av_log(s, AV_LOG_INFO, "Starting second pass: inserting sidx atoms\n");
8869  res = shift_data(s);
8870  if (res < 0)
8871  return res;
8872  end = avio_tell(pb);
8873  avio_seek(pb, mov->reserved_header_pos, SEEK_SET);
8874  mov_write_sidx_tags(pb, mov, -1, 0);
8875  avio_seek(pb, end, SEEK_SET);
8876  }
8877  if (!(mov->flags & FF_MOV_FLAG_SKIP_TRAILER)) {
8879  res = mov_write_mfra_tag(pb, mov);
8880  if (res < 0)
8881  return res;
8882  }
8883  }
8884 
8885  return res;
8886 }
8887 
8889  const AVPacket *pkt)
8890 {
8891  int ret = 1;
8892 
8893  if (st->codecpar->codec_id == AV_CODEC_ID_AAC) {
8894  if (pkt->size > 2 && (AV_RB16(pkt->data) & 0xfff0) == 0xfff0)
8895  ret = ff_stream_add_bitstream_filter(st, "aac_adtstoasc", NULL);
8896  } else if (st->codecpar->codec_id == AV_CODEC_ID_VP9) {
8897  ret = ff_stream_add_bitstream_filter(st, "vp9_superframe", NULL);
8898  }
8899 
8900  return ret;
8901 }
8902 
8903 #if CONFIG_AVIF_MUXER
8904 static int avif_write_trailer(AVFormatContext *s)
8905 {
8906  AVIOContext *pb = s->pb;
8907  MOVMuxContext *mov = s->priv_data;
8908  int64_t pos_backup, extent_offsets[2];
8909  uint8_t *buf;
8910  int buf_size, moov_size;
8911 
8912  if (mov->moov_written) return 0;
8913 
8914  mov->is_animated_avif = s->streams[0]->nb_frames > 1;
8915  if (mov->is_animated_avif && mov->nb_streams > 1) {
8916  // For animated avif with alpha channel, we need to write a tref tag
8917  // with type "auxl".
8918  mov->tracks[1].tref_tag = MKTAG('a', 'u', 'x', 'l');
8919  mov->tracks[1].tref_id = 1;
8920  }
8922  mov_write_meta_tag(pb, mov, s);
8923 
8924  moov_size = get_moov_size(s);
8925  for (int i = 0; i < mov->nb_tracks; i++)
8926  mov->tracks[i].data_offset = avio_tell(pb) + moov_size + 8;
8927 
8928  if (mov->is_animated_avif) {
8929  int ret;
8930  if ((ret = mov_write_moov_tag(pb, mov, s)) < 0)
8931  return ret;
8932  }
8933 
8934  buf_size = avio_get_dyn_buf(mov->mdat_buf, &buf);
8935  avio_wb32(pb, buf_size + 8);
8936  ffio_wfourcc(pb, "mdat");
8937 
8938  // The offset for the YUV planes is the starting position of mdat.
8939  extent_offsets[0] = avio_tell(pb);
8940  // The offset for alpha plane is YUV offset + YUV size.
8941  extent_offsets[1] = extent_offsets[0] + mov->avif_extent_length[0];
8942 
8943  avio_write(pb, buf, buf_size);
8944 
8945  // write extent offsets.
8946  pos_backup = avio_tell(pb);
8947  for (int i = 0; i < mov->nb_streams; i++) {
8948  if (extent_offsets[i] != (uint32_t)extent_offsets[i]) {
8949  av_log(s, AV_LOG_ERROR, "extent offset does not fit in 32 bits\n");
8950  return AVERROR_INVALIDDATA;
8951  }
8952  avio_seek(pb, mov->avif_extent_pos[i], SEEK_SET);
8953  avio_wb32(pb, extent_offsets[i]); /* rewrite offset */
8954  }
8955  avio_seek(pb, pos_backup, SEEK_SET);
8956 
8957  return 0;
8958 }
8959 #endif
8960 
8961 #if CONFIG_TGP_MUXER || CONFIG_TG2_MUXER
8962 static const AVCodecTag codec_3gp_tags[] = {
8963  { AV_CODEC_ID_H263, MKTAG('s','2','6','3') },
8964  { AV_CODEC_ID_H264, MKTAG('a','v','c','1') },
8965  { AV_CODEC_ID_MPEG4, MKTAG('m','p','4','v') },
8966  { AV_CODEC_ID_AAC, MKTAG('m','p','4','a') },
8967  { AV_CODEC_ID_AMR_NB, MKTAG('s','a','m','r') },
8968  { AV_CODEC_ID_AMR_WB, MKTAG('s','a','w','b') },
8969  { AV_CODEC_ID_MOV_TEXT, MKTAG('t','x','3','g') },
8970  { AV_CODEC_ID_NONE, 0 },
8971 };
8972 static const AVCodecTag *const codec_3gp_tags_list[] = { codec_3gp_tags, NULL };
8973 #endif
8974 
8975 static const AVCodecTag codec_mp4_tags[] = {
8976  { AV_CODEC_ID_MPEG4, MKTAG('m', 'p', '4', 'v') },
8977  { AV_CODEC_ID_H264, MKTAG('a', 'v', 'c', '1') },
8978  { AV_CODEC_ID_H264, MKTAG('a', 'v', 'c', '3') },
8979  { AV_CODEC_ID_HEVC, MKTAG('h', 'e', 'v', '1') },
8980  { AV_CODEC_ID_HEVC, MKTAG('h', 'v', 'c', '1') },
8981  { AV_CODEC_ID_HEVC, MKTAG('d', 'v', 'h', '1') },
8982  { AV_CODEC_ID_VVC, MKTAG('v', 'v', 'c', '1') },
8983  { AV_CODEC_ID_VVC, MKTAG('v', 'v', 'i', '1') },
8984  { AV_CODEC_ID_EVC, MKTAG('e', 'v', 'c', '1') },
8985  { AV_CODEC_ID_LCEVC, MKTAG('l', 'v', 'c', '1') },
8986  { AV_CODEC_ID_APV, MKTAG('a', 'p', 'v', '1') },
8987  { AV_CODEC_ID_MPEG2VIDEO, MKTAG('m', 'p', '4', 'v') },
8988  { AV_CODEC_ID_MPEG1VIDEO, MKTAG('m', 'p', '4', 'v') },
8989  { AV_CODEC_ID_MJPEG, MKTAG('m', 'p', '4', 'v') },
8990  { AV_CODEC_ID_PNG, MKTAG('m', 'p', '4', 'v') },
8991  { AV_CODEC_ID_JPEG2000, MKTAG('m', 'p', '4', 'v') },
8992  { AV_CODEC_ID_VC1, MKTAG('v', 'c', '-', '1') },
8993  { AV_CODEC_ID_DIRAC, MKTAG('d', 'r', 'a', 'c') },
8994  { AV_CODEC_ID_TSCC2, MKTAG('m', 'p', '4', 'v') },
8995  { AV_CODEC_ID_VP9, MKTAG('v', 'p', '0', '9') },
8996  { AV_CODEC_ID_AV1, MKTAG('a', 'v', '0', '1') },
8997  { AV_CODEC_ID_AAC, MKTAG('m', 'p', '4', 'a') },
8998  { AV_CODEC_ID_ALAC, MKTAG('a', 'l', 'a', 'c') },
8999  { AV_CODEC_ID_MP4ALS, MKTAG('m', 'p', '4', 'a') },
9000  { AV_CODEC_ID_MP3, MKTAG('m', 'p', '4', 'a') },
9001  { AV_CODEC_ID_MP2, MKTAG('m', 'p', '4', 'a') },
9002  { AV_CODEC_ID_AC3, MKTAG('a', 'c', '-', '3') },
9003  { AV_CODEC_ID_EAC3, MKTAG('e', 'c', '-', '3') },
9004  { AV_CODEC_ID_DTS, MKTAG('m', 'p', '4', 'a') },
9005  { AV_CODEC_ID_TRUEHD, MKTAG('m', 'l', 'p', 'a') },
9006  { AV_CODEC_ID_FLAC, MKTAG('f', 'L', 'a', 'C') },
9007  { AV_CODEC_ID_OPUS, MKTAG('O', 'p', 'u', 's') },
9008  { AV_CODEC_ID_VORBIS, MKTAG('m', 'p', '4', 'a') },
9009  { AV_CODEC_ID_QCELP, MKTAG('m', 'p', '4', 'a') },
9010  { AV_CODEC_ID_EVRC, MKTAG('m', 'p', '4', 'a') },
9011  { AV_CODEC_ID_DVD_SUBTITLE, MKTAG('m', 'p', '4', 's') },
9012  { AV_CODEC_ID_MOV_TEXT, MKTAG('t', 'x', '3', 'g') },
9013  { AV_CODEC_ID_BIN_DATA, MKTAG('g', 'p', 'm', 'd') },
9014  { AV_CODEC_ID_MPEGH_3D_AUDIO, MKTAG('m', 'h', 'm', '1') },
9017  { AV_CODEC_ID_FFV1, MKTAG('F', 'F', 'V', '1') },
9018 
9019  /* ISO/IEC 23003-5 integer formats */
9026  /* ISO/IEC 23003-5 floating-point formats */
9031 
9032  { AV_CODEC_ID_AVS3, MKTAG('a', 'v', 's', '3') },
9033 
9034  { AV_CODEC_ID_NONE, 0 },
9035 };
9036 #if CONFIG_MP4_MUXER || CONFIG_PSP_MUXER
9037 static const AVCodecTag *const mp4_codec_tags_list[] = { codec_mp4_tags, NULL };
9038 #endif
9039 
9040 static const AVCodecTag codec_ism_tags[] = {
9041  { AV_CODEC_ID_WMAPRO , MKTAG('w', 'm', 'a', ' ') },
9043  { AV_CODEC_ID_NONE , 0 },
9044 };
9045 
9046 static const AVCodecTag codec_ipod_tags[] = {
9047  { AV_CODEC_ID_H264, MKTAG('a','v','c','1') },
9048  { AV_CODEC_ID_MPEG4, MKTAG('m','p','4','v') },
9049  { AV_CODEC_ID_AAC, MKTAG('m','p','4','a') },
9050  { AV_CODEC_ID_ALAC, MKTAG('a','l','a','c') },
9051  { AV_CODEC_ID_AC3, MKTAG('a','c','-','3') },
9052  { AV_CODEC_ID_MOV_TEXT, MKTAG('t','x','3','g') },
9053  { AV_CODEC_ID_MOV_TEXT, MKTAG('t','e','x','t') },
9054  { AV_CODEC_ID_NONE, 0 },
9055 };
9056 
9057 static const AVCodecTag codec_f4v_tags[] = {
9058  { AV_CODEC_ID_MP3, MKTAG('.','m','p','3') },
9059  { AV_CODEC_ID_AAC, MKTAG('m','p','4','a') },
9060  { AV_CODEC_ID_H264, MKTAG('a','v','c','1') },
9061  { AV_CODEC_ID_VP6A, MKTAG('V','P','6','A') },
9062  { AV_CODEC_ID_VP6F, MKTAG('V','P','6','F') },
9063  { AV_CODEC_ID_NONE, 0 },
9064 };
9065 
9066 #if CONFIG_AVIF_MUXER
9067 
9068 static const AVOption avif_options[] = {
9069  { "movie_timescale", "set movie timescale", offsetof(MOVMuxContext, movie_timescale), AV_OPT_TYPE_INT, {.i64 = MOV_TIMESCALE}, 1, INT_MAX, AV_OPT_FLAG_ENCODING_PARAM},
9070  { "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 },
9071  { NULL },
9072 };
9073 static const AVCodecTag codec_avif_tags[] = {
9074  { AV_CODEC_ID_AV1, MKTAG('a','v','0','1') },
9075  { AV_CODEC_ID_NONE, 0 },
9076 };
9077 static const AVCodecTag *const codec_avif_tags_list[] = { codec_avif_tags, NULL };
9078 
9079 static const AVClass mov_avif_muxer_class = {
9080  .class_name = "avif muxer",
9081  .item_name = av_default_item_name,
9082  .option = avif_options,
9083  .version = LIBAVUTIL_VERSION_INT,
9084 };
9085 #endif
9086 
9087 #if CONFIG_MOV_MUXER
9088 const FFOutputFormat ff_mov_muxer = {
9089  .p.name = "mov",
9090  .p.long_name = NULL_IF_CONFIG_SMALL("QuickTime / MOV"),
9091  .p.extensions = "mov",
9092  .priv_data_size = sizeof(MOVMuxContext),
9093  .p.audio_codec = AV_CODEC_ID_AAC,
9094  .p.video_codec = CONFIG_LIBX264_ENCODER ?
9096  .init = mov_init,
9097  .write_header = mov_write_header,
9098  .write_packet = mov_write_packet,
9099  .write_trailer = mov_write_trailer,
9100  .deinit = mov_free,
9102  .p.codec_tag = (const AVCodecTag* const []){
9104  },
9105  .check_bitstream = mov_check_bitstream,
9106  .p.priv_class = &mov_isobmff_muxer_class,
9107  .flags_internal = FF_OFMT_FLAG_ALLOW_FLUSH,
9108 };
9109 #endif
9110 #if CONFIG_TGP_MUXER
9111 const FFOutputFormat ff_tgp_muxer = {
9112  .p.name = "3gp",
9113  .p.long_name = NULL_IF_CONFIG_SMALL("3GP (3GPP file format)"),
9114  .p.extensions = "3gp",
9115  .priv_data_size = sizeof(MOVMuxContext),
9116  .p.audio_codec = AV_CODEC_ID_AMR_NB,
9117  .p.video_codec = AV_CODEC_ID_H263,
9118  .init = mov_init,
9119  .write_header = mov_write_header,
9120  .write_packet = mov_write_packet,
9121  .write_trailer = mov_write_trailer,
9122  .deinit = mov_free,
9124  .p.codec_tag = codec_3gp_tags_list,
9125  .check_bitstream = mov_check_bitstream,
9126  .p.priv_class = &mov_isobmff_muxer_class,
9127  .flags_internal = FF_OFMT_FLAG_ALLOW_FLUSH,
9128 };
9129 #endif
9130 #if CONFIG_MP4_MUXER
9131 const FFOutputFormat ff_mp4_muxer = {
9132  .p.name = "mp4",
9133  .p.long_name = NULL_IF_CONFIG_SMALL("MP4 (MPEG-4 Part 14)"),
9134  .p.mime_type = "video/mp4",
9135  .p.extensions = "mp4",
9136  .priv_data_size = sizeof(MOVMuxContext),
9137  .p.audio_codec = AV_CODEC_ID_AAC,
9138  .p.video_codec = CONFIG_LIBX264_ENCODER ?
9140  .init = mov_init,
9141  .write_header = mov_write_header,
9142  .write_packet = mov_write_packet,
9143  .write_trailer = mov_write_trailer,
9144  .deinit = mov_free,
9146  .p.codec_tag = mp4_codec_tags_list,
9147  .check_bitstream = mov_check_bitstream,
9148  .p.priv_class = &mov_isobmff_muxer_class,
9149  .flags_internal = FF_OFMT_FLAG_ALLOW_FLUSH,
9150 };
9151 #endif
9152 #if CONFIG_PSP_MUXER
9153 const FFOutputFormat ff_psp_muxer = {
9154  .p.name = "psp",
9155  .p.long_name = NULL_IF_CONFIG_SMALL("PSP MP4 (MPEG-4 Part 14)"),
9156  .p.extensions = "mp4,psp",
9157  .priv_data_size = sizeof(MOVMuxContext),
9158  .p.audio_codec = AV_CODEC_ID_AAC,
9159  .p.video_codec = CONFIG_LIBX264_ENCODER ?
9161  .init = mov_init,
9162  .write_header = mov_write_header,
9163  .write_packet = mov_write_packet,
9164  .write_trailer = mov_write_trailer,
9165  .deinit = mov_free,
9167  .p.codec_tag = mp4_codec_tags_list,
9168  .check_bitstream = mov_check_bitstream,
9169  .p.priv_class = &mov_isobmff_muxer_class,
9170  .flags_internal = FF_OFMT_FLAG_ALLOW_FLUSH,
9171 };
9172 #endif
9173 #if CONFIG_TG2_MUXER
9174 const FFOutputFormat ff_tg2_muxer = {
9175  .p.name = "3g2",
9176  .p.long_name = NULL_IF_CONFIG_SMALL("3GP2 (3GPP2 file format)"),
9177  .p.extensions = "3g2",
9178  .priv_data_size = sizeof(MOVMuxContext),
9179  .p.audio_codec = AV_CODEC_ID_AMR_NB,
9180  .p.video_codec = AV_CODEC_ID_H263,
9181  .init = mov_init,
9182  .write_header = mov_write_header,
9183  .write_packet = mov_write_packet,
9184  .write_trailer = mov_write_trailer,
9185  .deinit = mov_free,
9187  .p.codec_tag = codec_3gp_tags_list,
9188  .check_bitstream = mov_check_bitstream,
9189  .p.priv_class = &mov_isobmff_muxer_class,
9190  .flags_internal = FF_OFMT_FLAG_ALLOW_FLUSH,
9191 };
9192 #endif
9193 #if CONFIG_IPOD_MUXER
9194 const FFOutputFormat ff_ipod_muxer = {
9195  .p.name = "ipod",
9196  .p.long_name = NULL_IF_CONFIG_SMALL("iPod H.264 MP4 (MPEG-4 Part 14)"),
9197  .p.mime_type = "video/mp4",
9198  .p.extensions = "m4v,m4a,m4b",
9199  .priv_data_size = sizeof(MOVMuxContext),
9200  .p.audio_codec = AV_CODEC_ID_AAC,
9201  .p.video_codec = AV_CODEC_ID_H264,
9202  .init = mov_init,
9203  .write_header = mov_write_header,
9204  .write_packet = mov_write_packet,
9205  .write_trailer = mov_write_trailer,
9206  .deinit = mov_free,
9208  .p.codec_tag = (const AVCodecTag* const []){ codec_ipod_tags, 0 },
9209  .check_bitstream = mov_check_bitstream,
9210  .p.priv_class = &mov_isobmff_muxer_class,
9211  .flags_internal = FF_OFMT_FLAG_ALLOW_FLUSH,
9212 };
9213 #endif
9214 #if CONFIG_ISMV_MUXER
9215 const FFOutputFormat ff_ismv_muxer = {
9216  .p.name = "ismv",
9217  .p.long_name = NULL_IF_CONFIG_SMALL("ISMV/ISMA (Smooth Streaming)"),
9218  .p.mime_type = "video/mp4",
9219  .p.extensions = "ismv,isma",
9220  .priv_data_size = sizeof(MOVMuxContext),
9221  .p.audio_codec = AV_CODEC_ID_AAC,
9222  .p.video_codec = AV_CODEC_ID_H264,
9223  .init = mov_init,
9224  .write_header = mov_write_header,
9225  .write_packet = mov_write_packet,
9226  .write_trailer = mov_write_trailer,
9227  .deinit = mov_free,
9229  .p.codec_tag = (const AVCodecTag* const []){
9231  .check_bitstream = mov_check_bitstream,
9232  .p.priv_class = &mov_isobmff_muxer_class,
9233  .flags_internal = FF_OFMT_FLAG_ALLOW_FLUSH,
9234 };
9235 #endif
9236 #if CONFIG_F4V_MUXER
9237 const FFOutputFormat ff_f4v_muxer = {
9238  .p.name = "f4v",
9239  .p.long_name = NULL_IF_CONFIG_SMALL("F4V Adobe Flash Video"),
9240  .p.mime_type = "application/f4v",
9241  .p.extensions = "f4v",
9242  .priv_data_size = sizeof(MOVMuxContext),
9243  .p.audio_codec = AV_CODEC_ID_AAC,
9244  .p.video_codec = AV_CODEC_ID_H264,
9245  .init = mov_init,
9246  .write_header = mov_write_header,
9247  .write_packet = mov_write_packet,
9248  .write_trailer = mov_write_trailer,
9249  .deinit = mov_free,
9250  .p.flags = AVFMT_GLOBALHEADER,
9251  .p.codec_tag = (const AVCodecTag* const []){ codec_f4v_tags, 0 },
9252  .check_bitstream = mov_check_bitstream,
9253  .p.priv_class = &mov_isobmff_muxer_class,
9254  .flags_internal = FF_OFMT_FLAG_ALLOW_FLUSH,
9255 };
9256 #endif
9257 #if CONFIG_AVIF_MUXER
9258 const FFOutputFormat ff_avif_muxer = {
9259  .p.name = "avif",
9260  .p.long_name = NULL_IF_CONFIG_SMALL("AVIF"),
9261  .p.mime_type = "image/avif",
9262  .p.extensions = "avif",
9263  .priv_data_size = sizeof(MOVMuxContext),
9264  .p.video_codec = AV_CODEC_ID_AV1,
9265  .init = mov_init,
9266  .write_header = mov_write_header,
9267  .write_packet = mov_write_packet,
9268  .write_trailer = avif_write_trailer,
9269  .deinit = mov_free,
9270  .p.flags = AVFMT_GLOBALHEADER,
9271  .p.codec_tag = codec_avif_tags_list,
9272  .p.priv_class = &mov_avif_muxer_class,
9273  .flags_internal = FF_OFMT_FLAG_ALLOW_FLUSH,
9274 };
9275 #endif
AV_CODEC_ID_PCM_S16LE
@ AV_CODEC_ID_PCM_S16LE
Definition: codec_id.h:338
flags
const SwsFlags flags[]
Definition: swscale.c:71
codec_ism_tags
static const AVCodecTag codec_ism_tags[]
Definition: movenc.c:9040
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:127
MOVMuxContext::mdat_pos
int64_t mdat_pos
Definition: movenc.h:211
MOVTrack::elst_end_pts
int64_t elst_end_pts
Definition: movenc.h:133
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:5717
AV_CODEC_ID_EIA_608
@ AV_CODEC_ID_EIA_608
Definition: codec_id.h:582
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:432
eac3_info
Definition: movenc.c:381
MOVMuxContext::nb_tracks
int nb_tracks
Definition: movenc.h:208
MOVMuxContext::fc
AVFormatContext * fc
Definition: movenc.h:239
MOVTrack::end_pts
int64_t end_pts
Definition: movenc.h:132
MOVMuxContext::iods_audio_profile
int iods_audio_profile
Definition: movenc.h:220
MODE_PSP
#define MODE_PSP
Definition: movenc.h:40
mov_write_udta_sdp
static int mov_write_udta_sdp(AVIOContext *pb, MOVTrack *track)
Definition: movenc.c:4249
AVMEDIA_TYPE_SUBTITLE
@ AVMEDIA_TYPE_SUBTITLE
Definition: avutil.h:203
AV_CODEC_ID_VP6F
@ AV_CODEC_ID_VP6F
Definition: codec_id.h:144
FF_MOV_FLAG_GLOBAL_SIDX
#define FF_MOV_FLAG_GLOBAL_SIDX
Definition: movenc.h:284
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:407
MODE_IPOD
#define MODE_IPOD
Definition: movenc.h:43
MODE_MP4
#define MODE_MP4
Definition: movenc.h:37
AV_CODEC_ID_PCM_F32BE
@ AV_CODEC_ID_PCM_F32BE
Definition: codec_id.h:358
AVCodecParameters::extradata
uint8_t * extradata
Extra binary data needed for initializing the decoder, codec-dependent.
Definition: codec_par.h:69
AV_CODEC_ID_ADPCM_MS
@ AV_CODEC_ID_ADPCM_MS
Definition: codec_id.h:383
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:2069
calc_elst_duration
static int64_t calc_elst_duration(MOVMuxContext *mov, MOVTrack *track)
Definition: movenc.c:3883
name
it s the only field you need to keep assuming you have a context There is some magic you don t need to care about around this just let it vf default minimum maximum flags name is the option name
Definition: writing_filters.txt:88
LIBAVFORMAT_IDENT
#define LIBAVFORMAT_IDENT
Definition: version.h:45
PacketList::head
PacketListEntry * head
Definition: packet_internal.h:34
AV_CODEC_ID_ADPCM_IMA_QT
@ AV_CODEC_ID_ADPCM_IMA_QT
Definition: codec_id.h:377
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:407
MOVTrack::chunkCount
long chunkCount
Definition: movenc.h:104
MOVTrack::cluster_written
MOVIentry * cluster_written
Definition: movenc.h:124
level
uint8_t level
Definition: svq3.c:208
AV_CODEC_ID_AC3
@ AV_CODEC_ID_AC3
Definition: codec_id.h:463
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:5218
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:2414
MOV_TRUN_SAMPLE_FLAGS
#define MOV_TRUN_SAMPLE_FLAGS
Definition: isom.h:415
mov_write_vmhd_tag
static int mov_write_vmhd_tag(AVIOContext *pb)
Definition: movenc.c:3529
MOVFragmentInfo::tfrf_offset
int64_t tfrf_offset
Definition: movenc.h:83
AV_PKT_DATA_AMBIENT_VIEWING_ENVIRONMENT
@ AV_PKT_DATA_AMBIENT_VIEWING_ENVIRONMENT
Ambient viewing environment metadata, as defined by H.274.
Definition: packet.h:327
AVOutputFormat::name
const char * name
Definition: avformat.h:506
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
MOVTrack::vc1_info
struct MOVTrack::@487 vc1_info
opt.h
mov_write_track_kinds
static int mov_write_track_kinds(AVIOContext *pb, AVStream *st)
Definition: movenc.c:4310
MOVTrack::squash_fragment_samples_to_one
unsigned int squash_fragment_samples_to_one
Definition: movenc.h:179
MOVMuxContext::mode
int mode
Definition: movenc.h:205
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:273
mov_write_wfex_tag
static int mov_write_wfex_tag(AVFormatContext *s, AVIOContext *pb, MOVTrack *track)
Definition: movenc.c:844
MOV_TKHD_FLAG_ENABLED
#define MOV_TKHD_FLAG_ENABLED
Definition: isom.h:428
mov_write_mfra_tag
static int mov_write_mfra_tag(AVIOContext *pb, MOVMuxContext *mov)
Definition: movenc.c:5991
AVCodecParameters::codec_type
enum AVMediaType codec_type
General type of the encoded data.
Definition: codec_par.h:51
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:4997
AV_STREAM_GROUP_PARAMS_LCEVC
@ AV_STREAM_GROUP_PARAMS_LCEVC
Definition: avformat.h:1091
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:5652
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:4949
ffio_wfourcc
static av_always_inline void ffio_wfourcc(AVIOContext *pb, const uint8_t *s)
Definition: avio_internal.h:124
AV_CODEC_ID_V308
@ AV_CODEC_ID_V308
Definition: codec_id.h:260
AVUUID
uint8_t AVUUID[AV_UUID_LEN]
Definition: uuid.h:60
put_bytes_output
static int put_bytes_output(const PutBitContext *s)
Definition: put_bits.h:99
FF_MOV_FLAG_HYBRID_FRAGMENTED
#define FF_MOV_FLAG_HYBRID_FRAGMENTED
Definition: movenc.h:294
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:713
ff_mp4_obj_type
const AVCodecTag ff_mp4_obj_type[]
Definition: isom.c:34
MOVMuxContext::encryption_scheme
MOVEncryptionScheme encryption_scheme
Definition: movenc.h:250
FF_MOV_FLAG_WRITE_COLR
#define FF_MOV_FLAG_WRITE_COLR
Definition: movenc.h:285
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:7225
AVCodecParameters
This struct describes the properties of an encoded stream.
Definition: codec_par.h:47
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:5527
MOVTrack::mode
int mode
Definition: movenc.h:88
mov_write_mvhd_tag
static int mov_write_mvhd_tag(AVIOContext *pb, MOVMuxContext *mov)
Definition: movenc.c:4471
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:5455
AVCodecParameters::color_space
enum AVColorSpace color_space
Definition: codec_par.h:169
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:4330
MOVIentry
Definition: movenc.h:48
AVStream::priv_data
void * priv_data
Definition: avformat.h:769
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:481
FF_MOV_FLAG_SKIP_TRAILER
#define FF_MOV_FLAG_SKIP_TRAILER
Definition: movenc.h:288
mov_write_gama_tag
static int mov_write_gama_tag(AVFormatContext *s, AVIOContext *pb, MOVTrack *track, double gamma)
Definition: movenc.c:2573
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:670
AV_FIELD_PROGRESSIVE
@ AV_FIELD_PROGRESSIVE
Definition: defs.h:213
AV_PKT_DATA_MASTERING_DISPLAY_METADATA
@ AV_PKT_DATA_MASTERING_DISPLAY_METADATA
Mastering display metadata (based on SMPTE-2086:2014).
Definition: packet.h:219
MOVFragmentInfo::size
int size
Definition: movenc.h:84
AV_PKT_FLAG_DISCARD
#define AV_PKT_FLAG_DISCARD
Flag is used to discard packets which are required to maintain valid decoder state but are not requir...
Definition: packet.h:650
IS_MODE
#define IS_MODE(muxer, config)
MOVFragmentInfo
Definition: movenc.h:79
MOVTrack::last_iamf_idx
int last_iamf_idx
Definition: movenc.h:185
AV_TIME_BASE_Q
#define AV_TIME_BASE_Q
Internal time base represented as fractional value.
Definition: avutil.h:263
AV_CODEC_ID_DIRAC
@ AV_CODEC_ID_DIRAC
Definition: codec_id.h:168
AVCodecTag::id
enum AVCodecID id
Definition: internal.h:43
eac3_info::num_blocks
uint8_t num_blocks
Definition: movenc.c:384
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:832
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:186
mov_auto_flush_fragment
static int mov_auto_flush_fragment(AVFormatContext *s, int force)
Definition: movenc.c:6732
AV_CODEC_ID_RAWVIDEO
@ AV_CODEC_ID_RAWVIDEO
Definition: codec_id.h:65
mov_pcm_le_gt16
static int mov_pcm_le_gt16(enum AVCodecID codec_id)
Definition: movenc.c:816
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:617
MOVMuxContext::min_fragment_duration
int min_fragment_duration
Definition: movenc.h:225
AV_CODEC_ID_MPEG4
@ AV_CODEC_ID_MPEG4
Definition: codec_id.h:64
MOVMuxContext::avif_extent_length
int avif_extent_length[2]
Definition: movenc.h:265
AVContentLightMetadata::MaxCLL
unsigned MaxCLL
Max content light level (cd/m^2).
Definition: mastering_display_metadata.h:111
ff_isom_write_vvcc
int ff_isom_write_vvcc(AVIOContext *pb, const uint8_t *data, int size, int ps_array_completeness)
Writes H.266/VVC extradata (parameter sets, declarative SEI NAL units) to the provided AVIOContext.
Definition: vvc.c:879
MODE_MOV
#define MODE_MOV
Definition: movenc.h:38
MOVMuxContext::encryption_scheme_str
char * encryption_scheme_str
Definition: movenc.h:249
FF_MOV_FLAG_FRAG_CUSTOM
#define FF_MOV_FLAG_FRAG_CUSTOM
Definition: movenc.h:275
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:676
mov_write_apvc_tag
static int mov_write_apvc_tag(AVFormatContext *s, AVIOContext *pb, MOVTrack *track)
Definition: movenc.c:1717
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:1331
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:485
MOVCtts
Definition: isom.h:68
AVPacketSideData
This structure stores auxiliary information for decoding, presenting, or otherwise processing the cod...
Definition: packet.h:409
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:1617
mov_write_iods_tag
static int mov_write_iods_tag(AVIOContext *pb, MOVMuxContext *mov)
Definition: movenc.c:4418
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:673
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:3969
internal.h
AVPacket::data
uint8_t * data
Definition: packet.h:588
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:7957
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:7716
mov_write_ccst_tag
static int mov_write_ccst_tag(AVIOContext *pb)
Definition: movenc.c:2751
AVOption
AVOption.
Definition: opt.h:429
MOVFragmentInfo::duration
int64_t duration
Definition: movenc.h:82
b
#define b
Definition: input.c:42
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:4814
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:4911
AVStream::avg_frame_rate
AVRational avg_frame_rate
Average framerate.
Definition: avformat.h:833
MOVTrack::flags
uint32_t flags
Definition: movenc.h:110
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:476
MOVTrack::tag
int tag
stsd fourcc
Definition: movenc.h:117
MOVTrack::pal_done
int pal_done
Definition: movenc.h:175
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:441
MOVIentry::dts
int64_t dts
Definition: movenc.h:50
ff_isom_write_lvcc
int ff_isom_write_lvcc(AVIOContext *pb, const uint8_t *data, int len)
Definition: lcevc.c:251
MOV_TIMESCALE
#define MOV_TIMESCALE
Definition: movenc.h:33
co64_required
static int co64_required(const MOVTrack *track)
Definition: movenc.c:177
mov_write_aux_tag
static int mov_write_aux_tag(AVIOContext *pb, const char *aux_type)
Definition: movenc.c:2770
MOVMuxContext::encryption_key
uint8_t * encryption_key
Definition: movenc.h:251
ff_toupper4
unsigned int ff_toupper4(unsigned int x)
Definition: to_upper4.h:29
ff_parse_creation_time_metadata
int ff_parse_creation_time_metadata(AVFormatContext *s, int64_t *timestamp, int return_seconds)
Parse creation_time in AVFormatContext metadata if exists and warn if the parsing fails.
Definition: mux_utils.c:137
AV_LOG_VERBOSE
#define AV_LOG_VERBOSE
Detailed information.
Definition: log.h:226
ff_codec_wav_tags
const AVCodecTag ff_codec_wav_tags[]
Definition: riff.c:530
MOVIentry::flags
uint32_t flags
Definition: movenc.h:61
mov_write_itunes_hdlr_tag
static int mov_write_itunes_hdlr_tag(AVIOContext *pb, MOVMuxContext *mov, AVFormatContext *s)
Definition: movenc.c:4536
mov_write_header
static int mov_write_header(AVFormatContext *s)
Definition: movenc.c:8475
mov_write_sv3d_tag
static int mov_write_sv3d_tag(AVFormatContext *s, AVIOContext *pb, AVSphericalMapping *spherical_mapping)
Definition: movenc.c:2313
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:490
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:4642
AVPacket::duration
int64_t duration
Duration of this packet in AVStream->time_base units, 0 if unknown.
Definition: packet.h:606
get_sidx_size
static int get_sidx_size(AVFormatContext *s)
Definition: movenc.c:8668
AVCodecParameters::codec_tag
uint32_t codec_tag
Additional information about the codec (corresponds to the AVI FOURCC).
Definition: codec_par.h:59
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:286
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:1553
MOVTrack::track_id
int track_id
Definition: movenc.h:116
AV_CODEC_ID_FLAC
@ AV_CODEC_ID_FLAC
Definition: codec_id.h:472
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:662
FFMAX
#define FFMAX(a, b)
Definition: macros.h:47
fiel_data
static const uint16_t fiel_data[]
Definition: movenc.c:2221
av_sub_q
AVRational av_sub_q(AVRational b, AVRational c)
Subtract one rational from another.
Definition: rational.c:101
ff_mov_init_hinting
int ff_mov_init_hinting(AVFormatContext *s, int index, int src_index)
Definition: movenchint.c:30
ff_isom_write_apvc
void ff_isom_write_apvc(AVIOContext *pb, const APVDecoderConfigurationRecord *apvc, void *logctx)
Definition: apv.c:80
ff_mov_get_channel_layout_tag
int ff_mov_get_channel_layout_tag(const AVCodecParameters *par, uint32_t *layout, uint32_t *bitmap, uint32_t **pchannel_desc)
Get the channel layout tag for the specified codec id and channel layout.
Definition: mov_chan.c:463
AVChannelLayout::nb_channels
int nb_channels
Number of channels in this layout.
Definition: channel_layout.h:329
mov_write_srat_tag
static int mov_write_srat_tag(AVIOContext *pb, MOVTrack *track)
Definition: movenc.c:1360
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:3046
MOVTrack::track_duration
int64_t track_duration
Definition: movenc.h:93
MOV_SAMPLE_DEPENDENCY_UNKNOWN
#define MOV_SAMPLE_DEPENDENCY_UNKNOWN
Definition: isom.h:433
is_clcp_track
static int is_clcp_track(MOVTrack *track)
Definition: movenc.c:3538
AV_CODEC_ID_R10K
@ AV_CODEC_ID_R10K
Definition: codec_id.h:197
codec_cover_image_tags
static const AVCodecTag codec_cover_image_tags[]
Definition: movenc.c:2159
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:504
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:643
MOVTrack::dts_shift
int64_t dts_shift
Definition: movenc.h:135
init_get_bits
static int init_get_bits(GetBitContext *s, const uint8_t *buffer, int bit_size)
Initialize GetBitContext.
Definition: get_bits.h:517
ff_get_muxer_ts_offset
int ff_get_muxer_ts_offset(AVFormatContext *s, int stream_index, int64_t *offset)
Definition: mux.c:1027
av_packet_free
void av_packet_free(AVPacket **pkt)
Free the packet, if the packet is reference counted, it will be unreferenced first.
Definition: packet.c:74
MOVIentry::entries
unsigned int entries
Definition: movenc.h:56
AV_PIX_FMT_RGB555BE
@ AV_PIX_FMT_RGB555BE
packed RGB 5:5:5, 16bpp, (msb)1X 5R 5G 5B(lsb), big-endian , X=unused/undefined
Definition: pixfmt.h:114
MOVMuxContext::write_prft
MOVPrftBox write_prft
Definition: movenc.h:260
MOVTrack::first_frag_written
int first_frag_written
Definition: movenc.h:164
ascii_to_wc
static int ascii_to_wc(AVIOContext *pb, const uint8_t *b)
Definition: movenc.c:4931
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:442
AV_CODEC_ID_BIN_DATA
@ AV_CODEC_ID_BIN_DATA
Definition: codec_id.h:613
MOVMuxContext::mdat_size
uint64_t mdat_size
Definition: movenc.h:212
mov_write_chnl_tag
static int mov_write_chnl_tag(AVFormatContext *s, AVIOContext *pb, MOVTrack *track)
Definition: movenc.c:1292
MOVMuxContext::write_tmcd
int write_tmcd
Definition: movenc.h:259
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:292
mov_write_tfdt_tag
static int mov_write_tfdt_tag(AVIOContext *pb, MOVTrack *track)
Definition: movenc.c:5705
MOVTrack::frag_info
MOVFragmentInfo * frag_info
Definition: movenc.h:157
mov_write_wave_tag
static int mov_write_wave_tag(AVFormatContext *s, AVIOContext *pb, MOVTrack *track)
Definition: movenc.c:1052
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
AV_CODEC_ID_MPEGH_3D_AUDIO
@ AV_CODEC_ID_MPEGH_3D_AUDIO
Definition: codec_id.h:551
MOV_PRFT_SRC_PTS
@ MOV_PRFT_SRC_PTS
Definition: movenc.h:199
MOVTrack
Definition: movenc.h:87
av_memdup
void * av_memdup(const void *p, size_t size)
Duplicate a buffer with av_malloc().
Definition: mem.c:304
AVContentLightMetadata
Content light level needed by to transmit HDR over HDMI (CTA-861.3).
Definition: mastering_display_metadata.h:107
AV_PKT_DATA_DOVI_CONF
@ AV_PKT_DATA_DOVI_CONF
DOVI configuration ref: dolby-vision-bitstreams-within-the-iso-base-media-file-format-v2....
Definition: packet.h:280
MOVFragmentInfo::offset
int64_t offset
Definition: movenc.h:80
AVStereo3D::horizontal_field_of_view
AVRational horizontal_field_of_view
Horizontal field of view, in degrees.
Definition: stereo3d.h:239
skip_bits
static void skip_bits(GetBitContext *s, int n)
Definition: get_bits.h:383
AVCodecParameters::color_primaries
enum AVColorPrimaries color_primaries
Definition: codec_par.h:167
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:411
eac3_info::substream
struct eac3_info::@486 substream[1]
mov_write_trex_tag
static int mov_write_trex_tag(AVIOContext *pb, MOVTrack *track)
Definition: movenc.c:4447
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:290
mov_write_dvc1_tag
static int mov_write_dvc1_tag(AVIOContext *pb, MOVTrack *track)
Definition: movenc.c:1179
rgb
Definition: rpzaenc.c:60
MOVTrack::entry_version
int entry_version
Definition: movenc.h:89
put_descr
static void put_descr(AVIOContext *pb, int tag, unsigned int size)
Definition: movenc.c:692
eac3_info::ac3_bit_rate_code
int8_t ac3_bit_rate_code
Definition: movenc.c:389
mov_write_vexu_proj_tag
static void mov_write_vexu_proj_tag(AVFormatContext *s, AVIOContext *pb, const AVSphericalMapping *spherical_mapping)
Definition: movenc.c:2387
MOV_ENC_NONE
@ MOV_ENC_NONE
Definition: movenc.h:192
MODE_ISM
#define MODE_ISM
Definition: movenc.h:44
get_pts_range
static void get_pts_range(MOVMuxContext *mov, MOVTrack *track, int64_t *start, int64_t *end, int elst)
Definition: movenc.c:3837
mov_write_pcmc_tag
static int mov_write_pcmc_tag(AVFormatContext *s, AVIOContext *pb, MOVTrack *track)
Definition: movenc.c:1334
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:781
AV_OPT_TYPE_BINARY
@ AV_OPT_TYPE_BINARY
Underlying C type is a uint8_t* that is either NULL or points to an array allocated with the av_mallo...
Definition: opt.h:286
calc_samples_pts_duration
static int64_t calc_samples_pts_duration(MOVMuxContext *mov, MOVTrack *track)
Definition: movenc.c:3862
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:280
mov_write_audio_tag
static int mov_write_audio_tag(AVFormatContext *s, AVIOContext *pb, MOVMuxContext *mov, MOVTrack *track)
Definition: movenc.c:1372
eac3_info::acmod
uint8_t acmod
Definition: movenc.c:402
MOV_TRACK_CTTS
#define MOV_TRACK_CTTS
Definition: movenc.h:107
AV_CODEC_ID_PCM_S16BE
@ AV_CODEC_ID_PCM_S16BE
Definition: codec_id.h:339
defined_frame_rate
static int defined_frame_rate(AVFormatContext *s, AVStream *st)
Definition: movenc.c:1890
MOV_FRAG_SAMPLE_FLAG_IS_NON_SYNC
#define MOV_FRAG_SAMPLE_FLAG_IS_NON_SYNC
Definition: isom.h:419
fail
#define fail()
Definition: checkasm.h:223
mov_write_gpmd_tag
static int mov_write_gpmd_tag(AVIOContext *pb, const MOVTrack *track)
Definition: movenc.c:3134
AVCodecParameters::bits_per_raw_sample
int bits_per_raw_sample
This is the number of valid bits in each output sample.
Definition: codec_par.h:123
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:4612
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:1434
MOVMuxContext::use_editlist
int use_editlist
Definition: movenc.h:243
mov_write_mvex_tag
static int mov_write_mvex_tag(AVIOContext *pb, MOVMuxContext *mov)
Definition: movenc.c:4460
timecode.h
MOV_TRACK_STPS
#define MOV_TRACK_STPS
Definition: movenc.h:108
eac3_info::chan_loc
uint16_t chan_loc
Definition: movenc.c:409
mov_write_dref_tag
static int mov_write_dref_tag(AVIOContext *pb)
Definition: movenc.c:3271
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:3899
mov_write_video_tag
static int mov_write_video_tag(AVFormatContext *s, AVIOContext *pb, MOVMuxContext *mov, MOVTrack *track)
Definition: movenc.c:2780
AC3HeaderInfo
Definition: ac3_parser_internal.h:34
mov_write_evcc_tag
static int mov_write_evcc_tag(AVIOContext *pb, MOVTrack *track)
Definition: movenc.c:1668
MOVTrack::frag_discont
int frag_discont
Definition: movenc.h:153
mov_get_rawvideo_codec_tag
static int mov_get_rawvideo_codec_tag(AVFormatContext *s, MOVTrack *track)
Definition: movenc.c:2078
mov_write_esds_tag
static int mov_write_esds_tag(AVIOContext *pb, MOVTrack *track)
Definition: movenc.c:763
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:162
mov_write_ftyp_tag
static int mov_write_ftyp_tag(AVIOContext *pb, AVFormatContext *s)
Definition: movenc.c:6081
EAC3_FRAME_TYPE_DEPENDENT
@ EAC3_FRAME_TYPE_DEPENDENT
Definition: ac3defs.h:112
AVChapter
Definition: avformat.h:1222
MOV_TRUN_SAMPLE_DURATION
#define MOV_TRUN_SAMPLE_DURATION
Definition: isom.h:413
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:701
MOVTrack::apv
struct APVDecoderConfigurationRecord * apv
Definition: movenc.h:188
MOVIentry::size
unsigned int size
Definition: movenc.h:52
validate_codec_tag
static unsigned int validate_codec_tag(const AVCodecTag *const *tags, unsigned int tag, int codec_id)
Definition: movenc.c:2166
MOVTrack::mdat_buf
AVIOContext * mdat_buf
Definition: movenc.h:151
MOVTrack::cluster
MOVIentry * cluster
Definition: movenc.h:123
AVFMT_AVOID_NEG_TS_MAKE_ZERO
#define AVFMT_AVOID_NEG_TS_MAKE_ZERO
Shift timestamps so that they start at 0.
Definition: avformat.h:1651
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:1685
mov_setup_track_ids
static int mov_setup_track_ids(MOVMuxContext *mov, AVFormatContext *s)
Assign track ids.
Definition: movenc.c:5179
pts
static int64_t pts
Definition: transcode_aac.c:644
AVStreamGroupLCEVC
AVStreamGroupLCEVC is meant to define the relation between video streams and a data stream containing...
Definition: avformat.h:1069
MOV_SYNC_SAMPLE
#define MOV_SYNC_SAMPLE
Definition: movenc.h:58
FF_MOV_FLAG_USE_MDTA
#define FF_MOV_FLAG_USE_MDTA
Definition: movenc.h:287
AV_CODEC_ID_MP3
@ AV_CODEC_ID_MP3
preferred ID for decoding MPEG audio layer 1, 2 or 3
Definition: codec_id.h:461
mov_finish_fragment
static int mov_finish_fragment(MOVMuxContext *mov, MOVTrack *track, int64_t ref_pos)
Definition: movenc.c:6490
mov_write_iref_tag
static int mov_write_iref_tag(AVIOContext *pb, MOVMuxContext *mov, AVFormatContext *s)
Definition: movenc.c:3687
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:5106
MOVMuxContext::iods_video_profile
int iods_video_profile
Definition: movenc.h:219
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:200
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:1865
MOVIentry::prft
AVProducerReferenceTime prft
Definition: movenc.h:62
MOV_FRAG_SAMPLE_FLAG_DEPENDS_YES
#define MOV_FRAG_SAMPLE_FLAG_DEPENDS_YES
Definition: isom.h:426
MOV_TRUN_DATA_OFFSET
#define MOV_TRUN_DATA_OFFSET
Definition: isom.h:411
eac3_info::lfeon
uint8_t lfeon
Definition: movenc.c:404
handle_eac3
static int handle_eac3(MOVMuxContext *mov, AVPacket *pkt, MOVTrack *track)
Definition: movenc.c:462
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:638
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:5691
av_get_bits_per_sample
int av_get_bits_per_sample(enum AVCodecID codec_id)
Return codec bits per sample.
Definition: utils.c:549
GET_UTF8
#define GET_UTF8(val, GET_BYTE, ERROR)
Convert a UTF-8 character (up to 4 bytes) to its 32-bit UCS-4 encoded form.
Definition: common.h:488
AVCodecParameters::color_trc
enum AVColorTransferCharacteristic color_trc
Definition: codec_par.h:168
MOVTrack::st
AVStream * st
Definition: movenc.h:118
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:4624
ff_mp4_muxer
const FFOutputFormat ff_mp4_muxer
mov_write_trak_tag
static int mov_write_trak_tag(AVFormatContext *s, AVIOContext *pb, MOVMuxContext *mov, MOVTrack *track, AVStream *st)
Definition: movenc.c:4362
AV_CODEC_ID_PCM_S8
@ AV_CODEC_ID_PCM_S8
Definition: codec_id.h:342
first
trying all byte sequences megabyte in length and selecting the best looking sequence will yield cases to try But first
Definition: rate_distortion.txt:12
MODE_AVIF
#define MODE_AVIF
Definition: movenc.h:46
pix_fmt
enum AVPixelFormat pix_fmt
Definition: movenc.c:2045
lrint
#define lrint
Definition: tablegen.h:53
eac3_info::pkt
AVPacket * pkt
Definition: movenc.c:382
eac3_info::bsmod
uint8_t bsmod
Definition: movenc.c:400
MOVTrack::palette
uint32_t palette[AVPALETTE_COUNT]
Definition: movenc.h:174
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:282
mov_write_trailer
static int mov_write_trailer(AVFormatContext *s)
Definition: movenc.c:8763
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:7385
MOVTrack::squashed_packet_queue
PacketList squashed_packet_queue
Definition: movenc.h:181
MOVTrack::mono_as_fc
int mono_as_fc
Definition: movenc.h:120
MOVMuxContext::encryption_kid_len
int encryption_kid_len
Definition: movenc.h:254
MOVMuxContext::pkt
AVPacket * pkt
Definition: movenc.h:241
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 only.
Definition: codec_par.h:195
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:653
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:1089
MOVMuxContext::chapter_track
int chapter_track
qt chapter track number
Definition: movenc.h:210
FF_MOV_FLAG_FRAGMENT
#define FF_MOV_FLAG_FRAGMENT
Definition: movenc.h:271
full_range
bool full_range
Definition: hwcontext_videotoolbox.c:46
AV_CODEC_ID_ADPCM_G726
@ AV_CODEC_ID_ADPCM_G726
Definition: codec_id.h:388
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:212
stereo3d.h
s
#define s(width, name)
Definition: cbs_vp9.c:198
MOV_TFHD_DEFAULT_BASE_IS_MOOF
#define MOV_TFHD_DEFAULT_BASE_IS_MOOF
Definition: isom.h:409
AV_CODEC_ID_BMP
@ AV_CODEC_ID_BMP
Definition: codec_id.h:130
mov_write_chpl_tag
static int mov_write_chpl_tag(AVIOContext *pb, AVFormatContext *s)
Definition: movenc.c:4971
AV_CODEC_ID_EVC
@ AV_CODEC_ID_EVC
Definition: codec_id.h:325
AV_CODEC_ID_WMAPRO
@ AV_CODEC_ID_WMAPRO
Definition: codec_id.h:497
MOV_TFHD_DEFAULT_DURATION
#define MOV_TFHD_DEFAULT_DURATION
Definition: isom.h:405
MOVMuxContext::movie_timescale
int movie_timescale
Definition: movenc.h:262
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:1414
AVCodecParameters::sample_aspect_ratio
AVRational sample_aspect_ratio
Video only.
Definition: codec_par.h:144
FF_MOV_FLAG_DELAY_MOOV
#define FF_MOV_FLAG_DELAY_MOOV
Definition: movenc.h:283
mov_write_av3c
static int mov_write_av3c(AVIOContext *pb, const uint8_t *data, int len)
Definition: movenc.c:1591
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:416
MOVTrack::tref_tag
uint32_t tref_tag
Definition: movenc.h:128
MOVMuxContext::per_stream_grouping
int per_stream_grouping
Definition: movenc.h:238
AVDictionaryEntry::key
char * key
Definition: dict.h:91
AVSphericalMapping::bound_top
uint32_t bound_top
Distance from the top edge.
Definition: spherical.h:186
AVMEDIA_TYPE_AUDIO
@ AVMEDIA_TYPE_AUDIO
Definition: avutil.h:201
AV_CODEC_ID_VP9
@ AV_CODEC_ID_VP9
Definition: codec_id.h:222
AVCodecParameters::width
int width
Video only.
Definition: codec_par.h:134
AV_CODEC_ID_MP2
@ AV_CODEC_ID_MP2
Definition: codec_id.h:460
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:412
MOVTrack::stsd_count
int stsd_count
Definition: movenc.h:97
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:209
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:5967
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:114
AVStreamGroup::params
union AVStreamGroup::@442 params
Group type-specific parameters.
MOVIentry::pts
int64_t pts
Definition: movenc.h:51
MOVTrack::has_disposable
int has_disposable
Definition: movenc.h:106
FF_MOV_FLAG_NEGATIVE_CTS_OFFSETS
#define FF_MOV_FLAG_NEGATIVE_CTS_OFFSETS
Definition: movenc.h:289
av_assert0
#define av_assert0(cond)
assert() equivalent, that is always enabled.
Definition: avassert.h:42
MODE_F4V
#define MODE_F4V
Definition: movenc.h:45
AVMEDIA_TYPE_NB
@ AVMEDIA_TYPE_NB
Definition: avutil.h:205
EAC3_FRAME_TYPE_INDEPENDENT
@ EAC3_FRAME_TYPE_INDEPENDENT
Definition: ac3defs.h:111
mov_write_trkn_tag
static int mov_write_trkn_tag(AVIOContext *pb, MOVMuxContext *mov, AVFormatContext *s, int disc)
Definition: movenc.c:4693
MOVTrack::entry_written
int entry_written
Definition: movenc.h:90
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:293
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:253
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:410
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:3734
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:3639
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:246
nb_streams
static int nb_streams
Definition: ffprobe.c:352
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
FLAC_METADATA_TYPE_STREAMINFO
@ FLAC_METADATA_TYPE_STREAMINFO
Definition: flac.h:46
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:142
MOVTrack::sample_size
long sample_size
Definition: movenc.h:103
codec_id
enum AVCodecID codec_id
Definition: vaapi_decode.c:410
AV_PIX_FMT_YUV420P
@ AV_PIX_FMT_YUV420P
planar YUV 4:2:0, 12bpp, (1 Cr & Cb sample per 2x2 Y samples)
Definition: pixfmt.h:73
AV_CODEC_ID_SVQ3
@ AV_CODEC_ID_SVQ3
Definition: codec_id.h:75
key
const char * key
Definition: hwcontext_opencl.c:189
AVCodecParameters::nb_coded_side_data
int nb_coded_side_data
Amount of entries in coded_side_data.
Definition: codec_par.h:86
AVMEDIA_TYPE_DATA
@ AVMEDIA_TYPE_DATA
Opaque data information usually continuous.
Definition: avutil.h:202
av_mallocz
#define av_mallocz(s)
Definition: tableprint_vlc.h:31
MOVIentry::pos
uint64_t pos
Definition: movenc.h:49
mov_parse_mpeg2_frame
static int mov_parse_mpeg2_frame(AVPacket *pkt, uint32_t *flags)
Definition: movenc.c:6303
mov_write_tcmi_tag
static int mov_write_tcmi_tag(AVIOContext *pb, MOVTrack *track)
Definition: movenc.c:3445
build_chunks
static void build_chunks(MOVTrack *trk)
Definition: movenc.c:5143
MOV_PRFT_NONE
@ MOV_PRFT_NONE
Definition: movenc.h:197
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:4112
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:2595
AV_CODEC_ID_H264
@ AV_CODEC_ID_H264
Definition: codec_id.h:79
PutBitContext
Definition: put_bits.h:50
mov_write_hdlr_tag
static int mov_write_hdlr_tag(AVFormatContext *s, AVIOContext *pb, MOVTrack *track)
Definition: movenc.c:3544
MOVMuxContext::time
int64_t time
Definition: movenc.h:206
MOVTrack::packet_entry
int packet_entry
Definition: movenc.h:166
AV_PIX_FMT_RGBA
@ AV_PIX_FMT_RGBA
packed RGBA 8:8:8:8, 32bpp, RGBARGBA...
Definition: pixfmt.h:100
AVStereo3D::flags
int flags
Additional information about the frame packing.
Definition: stereo3d.h:212
AV_CODEC_ID_PNG
@ AV_CODEC_ID_PNG
Definition: codec_id.h:113
AV_CODEC_ID_AVUI
@ AV_CODEC_ID_AVUI
Definition: codec_id.h:257
FF_MOV_FLAG_RTP_HINT
#define FF_MOV_FLAG_RTP_HINT
Definition: movenc.h:270
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:5446
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:5055
mov_write_vpcc_tag
static int mov_write_vpcc_tag(AVFormatContext *s, AVIOContext *pb, MOVTrack *track)
Definition: movenc.c:1620
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:256
avpriv_packet_list_free
void avpriv_packet_list_free(PacketList *pkt_buf)
Wipe the list and unref all the packets in it.
Definition: packet.c:609
MOVTrack::sample_count
long sample_count
Definition: movenc.h:102
MOVTrack::start_dts
int64_t start_dts
Definition: movenc.h:130
AV_CODEC_ID_AVS3
@ AV_CODEC_ID_AVS3
Definition: codec_id.h:250
AVFormatContext
Format I/O context.
Definition: avformat.h:1263
MOVMuxContext::iods_skip
int iods_skip
Definition: movenc.h:218
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:718
evc.h
AVStreamGroupLCEVC::height
int height
Height of the final image for presentation.
Definition: avformat.h:1083
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:571
AVStream::codecpar
AVCodecParameters * codecpar
Codec parameters associated with this stream.
Definition: avformat.h:767
compute_moov_size
static int compute_moov_size(AVFormatContext *s)
Definition: movenc.c:8686
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:783
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
MOVTrack::src_track
int src_track
the track that this hint (or tmcd) track describes
Definition: movenc.h:138
mov_write_pitm_tag
static int mov_write_pitm_tag(AVIOContext *pb, int item_id)
Definition: movenc.c:3629
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:824
AV_CODEC_ID_AV1
@ AV_CODEC_ID_AV1
Definition: codec_id.h:284
avcodec_parameters_free
void avcodec_parameters_free(AVCodecParameters **ppar)
Free an AVCodecParameters instance and everything associated with it and write NULL to the supplied p...
Definition: codec_par.c:67
AVPixFmtDescriptor::nb_components
uint8_t nb_components
The number of components each pixel has, (1-4)
Definition: pixdesc.h:71
AVEncryptionInitInfo
This describes info used to initialize an encryption key system.
Definition: encryption_info.h:88
isom.h
AV_CODEC_ID_TIMED_ID3
@ AV_CODEC_ID_TIMED_ID3
Definition: codec_id.h:612
mov_check_timecode_track
static int mov_check_timecode_track(AVFormatContext *s, AVTimecode *tc, AVStream *src_st, const char *tcstr)
Definition: movenc.c:7655
codec_f4v_tags
static const AVCodecTag codec_f4v_tags[]
Definition: movenc.c:9057
mov_create_timecode_track
static int mov_create_timecode_track(AVFormatContext *s, int index, int src_index, AVTimecode tc)
Definition: movenc.c:7664
mov_write_extradata_tag
static int mov_write_extradata_tag(AVIOContext *pb, MOVTrack *track)
This function writes extradata "as is".
Definition: movenc.c:670
mov_write_packet
static int mov_write_packet(AVFormatContext *s, AVPacket *pkt)
Definition: movenc.c:7413
MP4TrackKindValueMapping::disposition
int disposition
Definition: isom.h:485
mov_write_stsc_tag
static int mov_write_stsc_tag(AVIOContext *pb, MOVTrack *track)
Definition: movenc.c:261
AV_WB16
#define AV_WB16(p, v)
Definition: intreadwrite.h:401
avpriv_packet_list_put
int avpriv_packet_list_put(PacketList *packet_buffer, AVPacket *pkt, int(*copy)(AVPacket *dst, const AVPacket *src), int flags)
Append an AVPacket to the list.
Definition: packet.c:546
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:8655
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:252
AV_CODEC_ID_MOV_TEXT
@ AV_CODEC_ID_MOV_TEXT
Definition: codec_id.h:577
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:237
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:2033
check_pkt
static int check_pkt(AVFormatContext *s, MOVTrack *trk, AVPacket *pkt)
Definition: movenc.c:6746
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:6466
MOVMuxContext::max_fragment_size
int max_fragment_size
Definition: movenc.h:226
ROUNDED_DIV
#define ROUNDED_DIV(a, b)
Definition: common.h:58
AV_CODEC_ID_DVD_SUBTITLE
@ AV_CODEC_ID_DVD_SUBTITLE
Definition: codec_id.h:572
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:5759
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:2532
avc.h
MOVTrack::cenc
MOVMuxCencContext cenc
Definition: movenc.h:172
options
Definition: swscale.c:44
TAG_IS_AVCI
#define TAG_IS_AVCI(tag)
Definition: isom.h:439
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:94
VC1_CODE_ENTRYPOINT
@ VC1_CODE_ENTRYPOINT
Definition: vc1_common.h:39
AVStream::metadata
AVDictionary * metadata
Definition: avformat.h:824
get_cluster_duration
static int get_cluster_duration(MOVTrack *track, int cluster_idx)
Definition: movenc.c:1234
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:2560
MOV_SAMPLE_DEPENDENCY_NO
#define MOV_SAMPLE_DEPENDENCY_NO
Definition: isom.h:435
MOVMuxContext
Definition: movenc.h:203
ff_iamf_add_mix_presentation
int ff_iamf_add_mix_presentation(IAMFContext *iamf, const AVStreamGroup *stg, void *log_ctx)
Definition: iamf_writer.c:422
MOVMuxContext::missing_duration_warned
int missing_duration_warned
Definition: movenc.h:247
MOVTrack::data_offset
int64_t data_offset
Definition: movenc.h:152
mov_write_track_metadata
static int mov_write_track_metadata(AVIOContext *pb, AVStream *st, const char *tag, const char *str)
Definition: movenc.c:4270
ff_mov_close_hinting
void ff_mov_close_hinting(MOVTrack *track)
Definition: movenchint.c:460
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:2694
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:702
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:1209
ffio_fill
void ffio_fill(AVIOContext *s, int b, int64_t count)
Definition: aviobuf.c:192
MOVIentry::cts
int cts
Definition: movenc.h:57
AV_DISPOSITION_MULTILAYER
#define AV_DISPOSITION_MULTILAYER
The video stream contains multiple layers, e.g.
Definition: avformat.h:714
AV_CODEC_ID_QDM2
@ AV_CODEC_ID_QDM2
Definition: codec_id.h:479
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:3429
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:440
AVCodecParameters::ch_layout
AVChannelLayout ch_layout
Audio only.
Definition: codec_par.h:180
mov_get_codec_tag
static unsigned int mov_get_codec_tag(AVFormatContext *s, MOVTrack *track)
Definition: movenc.c:2104
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:489
mov_write_minf_tag
static int mov_write_minf_tag(AVFormatContext *s, AVIOContext *pb, MOVMuxContext *mov, MOVTrack *track)
Definition: movenc.c:3800
mov_write_SA3D_tag
static int mov_write_SA3D_tag(AVFormatContext *s, AVIOContext *pb, MOVTrack *track)
Definition: movenc.c:938
AV_CODEC_ID_VP6A
@ AV_CODEC_ID_VP6A
Definition: codec_id.h:158
MOVTrack::packet_seq
int packet_seq
Definition: movenc.h:165
param_write_int
static void param_write_int(AVIOContext *pb, const char *name, int value)
Definition: movenc.c:5304
FF_MOV_FLAG_DISABLE_CHPL
#define FF_MOV_FLAG_DISABLE_CHPL
Definition: movenc.h:279
mov_write_ctts_tag
static int mov_write_ctts_tag(AVFormatContext *s, AVIOContext *pb, MOVTrack *track)
Definition: movenc.c:3181
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:4552
AVProducerReferenceTime::flags
int flags
Definition: defs.h:336
MOV_MP4_TTML_TAG
#define MOV_MP4_TTML_TAG
Definition: isom.h:480
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:403
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:505
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:5322
MOVMuxContext::empty_hdlr_name
int empty_hdlr_name
Definition: movenc.h:261
ff_codec_movaudio_tags
const AVCodecTag ff_codec_movaudio_tags[]
Definition: isom_tags.c:311
AV_OPT_FLAG_ENCODING_PARAM
#define AV_OPT_FLAG_ENCODING_PARAM
A generic parameter which can be set by the user for muxing or encoding.
Definition: opt.h:352
index
int index
Definition: gxfenc.c:90
c
Undefined Behavior In the C some operations are like signed integer dereferencing freed accessing outside allocated Undefined Behavior must not occur in a C it is not safe even if the output of undefined operations is unused The unsafety may seem nit picking but Optimizing compilers have in fact optimized code on the assumption that no undefined Behavior occurs Optimizing code based on wrong assumptions can and has in some cases lead to effects beyond the output of computations The signed integer overflow problem in speed critical code Code which is highly optimized and works with signed integers sometimes has the problem that often the output of the computation does not c
Definition: undefined.txt:32
mov_write_subtitle_end_packet
static int mov_write_subtitle_end_packet(AVFormatContext *s, int stream_index, int64_t dts)
Definition: movenc.c:7316
AVCodecParameters::sample_rate
int sample_rate
Audio only.
Definition: codec_par.h:184
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:3381
cid
uint16_t cid
Definition: mxfenc.c:2333
compute_sidx_size
static int compute_sidx_size(AVFormatContext *s)
Definition: movenc.c:8711
MOVStts
Definition: isom.h:63
AC3HeaderInfo::num_blocks
int num_blocks
number of audio blocks
Definition: ac3_parser_internal.h:51
AV_CODEC_ID_MPEG1VIDEO
@ AV_CODEC_ID_MPEG1VIDEO
Definition: codec_id.h:53
av_buffer_create
AVBufferRef * av_buffer_create(uint8_t *data, size_t size, void(*free)(void *opaque, uint8_t *data), void *opaque, int flags)
Create an AVBuffer from an existing array.
Definition: buffer.c:55
ff_ipod_muxer
const FFOutputFormat ff_ipod_muxer
find_compressor
static void find_compressor(char *compressor_name, int len, MOVTrack *track)
Definition: movenc.c:2721
AVStream::nb_frames
int64_t nb_frames
number of frames in this stream if known or 0
Definition: avformat.h:805
movenc.h
AVCodecID
AVCodecID
Identify the syntax and semantics of the bitstream.
Definition: codec_id.h:49
av_packet_side_data_get
const AVPacketSideData * av_packet_side_data_get(const AVPacketSideData *sd, int nb_sd, enum AVPacketSideDataType type)
Get side information from a side data array.
Definition: packet.c:644
AV_CODEC_ID_EAC3
@ AV_CODEC_ID_EAC3
Definition: codec_id.h:500
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:73
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:425
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:462
ff_mov_get_channel_config_from_layout
int ff_mov_get_channel_config_from_layout(const AVChannelLayout *layout, int *config)
Get ISO/IEC 23001-8 ChannelConfiguration from AVChannelLayout.
Definition: mov_chan.c:673
AVStereo3D::primary_eye
enum AVStereo3DPrimaryEye primary_eye
Which eye is the primary eye when rendering in 2D.
Definition: stereo3d.h:222
AV_ROUND_DOWN
@ AV_ROUND_DOWN
Round toward -infinity.
Definition: mathematics.h:133
AV_UUID_LEN
#define AV_UUID_LEN
Definition: uuid.h:57
av_rescale_rnd
int64_t av_rescale_rnd(int64_t a, int64_t b, int64_t c, enum AVRounding rnd)
Rescale a 64-bit integer with specified rounding.
Definition: mathematics.c:58
AV_CODEC_ID_QCELP
@ AV_CODEC_ID_QCELP
Definition: codec_id.h:484
AV_SPHERICAL_HALF_EQUIRECTANGULAR
@ AV_SPHERICAL_HALF_EQUIRECTANGULAR
Video frame displays as a 180 degree equirectangular projection.
Definition: spherical.h:73
av_get_exact_bits_per_sample
int av_get_exact_bits_per_sample(enum AVCodecID codec_id)
Return codec bits per sample.
Definition: utils.c:454
ff_mov_generate_squashed_ttml_packet
int ff_mov_generate_squashed_ttml_packet(AVFormatContext *s, MOVTrack *track, AVPacket *pkt)
Definition: movenc_ttml.c:236
AV_CODEC_ID_FFV1
@ AV_CODEC_ID_FFV1
Definition: codec_id.h:85
AVIOContext
Bytestream IO Context.
Definition: avio.h:160
AV_CODEC_ID_PCM_S24LE
@ AV_CODEC_ID_PCM_S24LE
Definition: codec_id.h:350
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:386
ac3_parser_internal.h
AVPacket::size
int size
Definition: packet.h:589
NULL_IF_CONFIG_SMALL
#define NULL_IF_CONFIG_SMALL(x)
Return NULL if CONFIG_SMALL is true, otherwise the argument without modification.
Definition: internal.h:94
avpriv_pix_fmt_find
enum AVPixelFormat avpriv_pix_fmt_find(enum PixelFormatTagLists list, unsigned fourcc)
Definition: raw.c:78
codec_ipod_tags
static const AVCodecTag codec_ipod_tags[]
Definition: movenc.c:9046
copy
static void copy(const float *p1, float *p2, const int length)
Definition: vf_vaguedenoiser.c:186
FF_OFMT_FLAG_ALLOW_FLUSH
#define FF_OFMT_FLAG_ALLOW_FLUSH
This flag indicates that the muxer stores data internally and supports flushing it.
Definition: mux.h:38
ff_isom_write_avcc
int ff_isom_write_avcc(AVIOContext *pb, const uint8_t *data, int len)
Definition: avc.c:31
height
#define height
Definition: dsp.h:89
AC3HeaderInfo::channel_map_present
uint8_t channel_map_present
Definition: ac3_parser_internal.h:49
MOVTrack::cover_image
AVPacket * cover_image
Definition: movenc.h:149
AVChannelLayout
An AVChannelLayout holds information about the channel layout of audio data.
Definition: channel_layout.h:319
MOVFragmentInfo::time
int64_t time
Definition: movenc.h:81
AVSphericalMapping::bound_right
uint32_t bound_right
Distance from the right edge.
Definition: spherical.h:187
mov_write_dpxe_tag
static int mov_write_dpxe_tag(AVIOContext *pb, MOVTrack *track)
Definition: movenc.c:1852
mov_write_vvcc_tag
static int mov_write_vvcc_tag(AVIOContext *pb, MOVTrack *track)
Definition: movenc.c:1698
FF_MOV_FLAG_FASTSTART
#define FF_MOV_FLAG_FASTSTART
Definition: movenc.h:277
mpeg4_bit_rate_values::avg_bit_rate
uint32_t avg_bit_rate
Average rate in bits/second over the entire presentation.
Definition: movenc.c:715
MOVTrack::language
int language
Definition: movenc.h:115
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:229
MOVMuxContext::ism_lookahead
int ism_lookahead
Definition: movenc.h:227
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:610
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:2376
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:541
AV_CODEC_ID_DTS
@ AV_CODEC_ID_DTS
Definition: codec_id.h:464
bps
unsigned bps
Definition: movenc.c:2047
MOVTrack::default_sample_flags
uint32_t default_sample_flags
Definition: movenc.h:145
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:2472
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:172
AC3HeaderInfo::lfe_on
uint8_t lfe_on
Definition: ac3_parser_internal.h:44
mpeg4_bit_rate_values
Definition: movenc.c:712
AV_CODEC_ID_H263
@ AV_CODEC_ID_H263
Definition: codec_id.h:56
MOV_TFHD_STSD_ID
#define MOV_TFHD_STSD_ID
Definition: isom.h:404
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:264
mov_write_mdta_keys_tag
static int mov_write_mdta_keys_tag(AVIOContext *pb, MOVMuxContext *mov, AVFormatContext *s)
Definition: movenc.c:4829
AV_CODEC_ID_V408
@ AV_CODEC_ID_V408
Definition: codec_id.h:261
avio.h
mov_write_uuid_tag_psp
static int mov_write_uuid_tag_psp(AVIOContext *pb, MOVTrack *mov)
Definition: movenc.c:4231
video_st
static AVStream * video_st
Definition: movenc.c:61
AV_NOPTS_VALUE
#define AV_NOPTS_VALUE
Undefined timestamp value.
Definition: avutil.h:247
NTP_OFFSET_US
#define NTP_OFFSET_US
Definition: internal.h:419
codec_mp4_tags
static const AVCodecTag codec_mp4_tags[]
Definition: movenc.c:8975
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:1161
AV_RB32
uint64_t_TMPL AV_WL64 unsigned int_TMPL AV_WL32 unsigned int_TMPL AV_WL24 unsigned int_TMPL AV_WL16 uint64_t_TMPL AV_WB64 unsigned int_TMPL AV_RB32
Definition: bytestream.h:96
AV_CODEC_ID_V210
@ AV_CODEC_ID_V210
Definition: codec_id.h:179
mov_write_lhvc_tag
static int mov_write_lhvc_tag(AVFormatContext *s, AVIOContext *pb, MOVTrack *track)
Definition: movenc.c:1646
get_metadata_lang
static AVDictionaryEntry * get_metadata_lang(AVFormatContext *s, const char *tag, int *lang)
Definition: movenc.c:4587
FF_MOV_FLAG_ISML
#define FF_MOV_FLAG_ISML
Definition: movenc.h:276
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:128
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:3955
mov_create_dvd_sub_decoder_specific_info
static int mov_create_dvd_sub_decoder_specific_info(MOVTrack *track, AVStream *st)
Definition: movenc.c:7828
AV_CODEC_ID_OPUS
@ AV_CODEC_ID_OPUS
Definition: codec_id.h:520
MOVMuxContext::reserved_header_pos
int64_t reserved_header_pos
Definition: movenc.h:234
MOVTrack::audio_vbr
int audio_vbr
Definition: movenc.h:126
mov_write_gmhd_tag
static int mov_write_gmhd_tag(AVIOContext *pb, MOVTrack *track)
Definition: movenc.c:3467
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:3146
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:822
mov_write_tmcd_tag
static int mov_write_tmcd_tag(AVIOContext *pb, MOVTrack *track)
Definition: movenc.c:3085
mov_write_dmlp_tag
static int mov_write_dmlp_tag(AVFormatContext *s, AVIOContext *pb, MOVTrack *track)
Definition: movenc.c:909
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:134
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:3874
dovi_isom.h
AV_DISPOSITION_HEARING_IMPAIRED
#define AV_DISPOSITION_HEARING_IMPAIRED
The stream is intended for hearing impaired audiences.
Definition: avformat.h:654
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:587
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:167
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:2023
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:481
avio_wl32
void avio_wl32(AVIOContext *s, unsigned int val)
Definition: aviobuf.c:360
csp.h
AV_CODEC_ID_VVC
@ AV_CODEC_ID_VVC
Definition: codec_id.h:252
MOVTrack::first_packet_seen
int first_packet_seen
Definition: movenc.h:163
mov_write_subtitle_tag
static int mov_write_subtitle_tag(AVFormatContext *s, AVIOContext *pb, MOVTrack *track)
Definition: movenc.c:2238
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:4284
offset
it s the only field you need to keep assuming you have a context There is some magic you don t need to care about around this just let it vf offset
Definition: writing_filters.txt:86
AVStreamGroupLCEVC::lcevc_index
unsigned int lcevc_index
Index of the LCEVC data stream in AVStreamGroup.
Definition: avformat.h:1075
AVStreamGroup::lcevc
struct AVStreamGroupLCEVC * lcevc
Definition: avformat.h:1133
AV_CODEC_ID_LCEVC
@ AV_CODEC_ID_LCEVC
Definition: codec_id.h:615
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:594
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:131
version
version
Definition: libkvazaar.c:313
AV_STREAM_GROUP_PARAMS_IAMF_AUDIO_ELEMENT
@ AV_STREAM_GROUP_PARAMS_IAMF_AUDIO_ELEMENT
Definition: avformat.h:1088
mov_write_avid_tag
static int mov_write_avid_tag(AVIOContext *pb, MOVTrack *track)
Definition: movenc.c:1734
mov_write_mdta_ilst_tag
static int mov_write_mdta_ilst_tag(AVIOContext *pb, MOVMuxContext *mov, AVFormatContext *s)
Definition: movenc.c:4858
AV_STEREO3D_FLAG_INVERT
#define AV_STEREO3D_FLAG_INVERT
Inverted views, Right/Bottom represents the left view.
Definition: stereo3d.h:194
MOVIentry::chunkNum
unsigned int chunkNum
Chunk number if the current entry is a chunk start otherwise 0.
Definition: movenc.h:55
AVStreamGroup::streams
AVStream ** streams
A list of streams in the group.
Definition: avformat.h:1164
vc1_common.h
mov_write_meta_tag
static int mov_write_meta_tag(AVIOContext *pb, MOVMuxContext *mov, AVFormatContext *s)
Definition: movenc.c:4880
FF_MOV_FLAG_OMIT_TFHD_OFFSET
#define FF_MOV_FLAG_OMIT_TFHD_OFFSET
Definition: movenc.h:278
MOV_MP4_IPCM_TAG
#define MOV_MP4_IPCM_TAG
Definition: isom.h:482
MOV_DISPOSABLE_SAMPLE
#define MOV_DISPOSABLE_SAMPLE
Definition: movenc.h:60
shift_data
static int shift_data(AVFormatContext *s)
Definition: movenc.c:8726
mov_write_dvc1_structs
static int mov_write_dvc1_structs(MOVTrack *track, uint8_t *buf)
Definition: movenc.c:1095
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:809
mov_write_iinf_tag
static int mov_write_iinf_tag(AVIOContext *pb, MOVMuxContext *mov, AVFormatContext *s)
Definition: movenc.c:3662
AC3HeaderInfo::ac3_bit_rate_code
int8_t ac3_bit_rate_code
Definition: ac3_parser_internal.h:64
AV_CODEC_ID_TSCC2
@ AV_CODEC_ID_TSCC2
Definition: codec_id.h:218
AV_LOG_INFO
#define AV_LOG_INFO
Standard information.
Definition: log.h:221
mov_free
static void mov_free(AVFormatContext *s)
Definition: movenc.c:7758
MODE_3GP
#define MODE_3GP
Definition: movenc.h:39
MOVTrack::time
uint64_t time
Definition: movenc.h:92
FF_MOV_FLAG_SKIP_SIDX
#define FF_MOV_FLAG_SKIP_SIDX
Definition: movenc.h:291
AV_PIX_FMT_ARGB
@ AV_PIX_FMT_ARGB
packed ARGB 8:8:8:8, 32bpp, ARGBARGB...
Definition: pixfmt.h:99
AV_OPT_TYPE_FLOAT
@ AV_OPT_TYPE_FLOAT
Underlying C type is float.
Definition: opt.h:271
apv.h
ff_mov_add_hinted_packet
int ff_mov_add_hinted_packet(AVFormatContext *s, AVPacket *pkt, int track_index, int sample, uint8_t *sample_data, int sample_size)
Definition: movenchint.c:401
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:4747
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
avcodec_get_name
const char * avcodec_get_name(enum AVCodecID id)
Get the name of a codec.
Definition: utils.c:406
AV_CODEC_ID_MJPEG
@ AV_CODEC_ID_MJPEG
Definition: codec_id.h:59
MOVTrack::hint_track
int hint_track
the track that hints this track, -1 if no hint track is set
Definition: movenc.h:137
MOVTrack::has_keyframes
int has_keyframes
Definition: movenc.h:105
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:3775
interlaced
uint8_t interlaced
Definition: mxfenc.c:2334
MOVTrack::entry
int entry
Definition: movenc.h:90
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:6203
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:312
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:3420
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:1610
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:477
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:272
AV_CODEC_ID_NONE
@ AV_CODEC_ID_NONE
Definition: codec_id.h:50
AVPacket::pts
int64_t pts
Presentation timestamp in AVStream->time_base units; the time at which the decompressed packet will b...
Definition: packet.h:581
avio_internal.h
ff_mov_write_packet
int ff_mov_write_packet(AVFormatContext *s, AVPacket *pkt)
Definition: movenc.c:6781
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:207
av_packet_get_side_data
uint8_t * av_packet_get_side_data(const AVPacket *pkt, enum AVPacketSideDataType type, size_t *size)
Get side information from packet.
Definition: packet.c:252
AV_SPHERICAL_FISHEYE
@ AV_SPHERICAL_FISHEYE
Fisheye projection (Apple).
Definition: spherical.h:84
AV_CODEC_ID_EVRC
@ AV_CODEC_ID_EVRC
Definition: codec_id.h:531
AVCodecParameters::height
int height
Definition: codec_par.h:135
mov_write_avcc_tag
static int mov_write_avcc_tag(AVIOContext *pb, MOVTrack *track)
Definition: movenc.c:1576
AV_TIME_BASE
#define AV_TIME_BASE
Internal time base represented as integer.
Definition: avutil.h:253
MOVMuxContext::fragments
int fragments
Definition: movenc.h:223
AVCodecParameters::block_align
int block_align
Audio only.
Definition: codec_par.h:191
AV_CODEC_ID_TTML
@ AV_CODEC_ID_TTML
Definition: codec_id.h:596
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:1899
MOV_PRFT_SRC_WALLCLOCK
@ MOV_PRFT_SRC_WALLCLOCK
Definition: movenc.h:198
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:632
MOVTrack::extradata_size
int * extradata_size
Definition: movenc.h:100
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:4573
MOVTrack::first_packet_seq
int first_packet_seq
Definition: movenc.h:161
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:388
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:360
mov_write_mdat_size
static void mov_write_mdat_size(AVFormatContext *s)
Definition: movenc.c:8741
AV_CODEC_ID_HEVC
@ AV_CODEC_ID_HEVC
Definition: codec_id.h:228
value
it s the only field you need to keep assuming you have a context There is some magic you don t need to care about around this just let it vf default value
Definition: writing_filters.txt:86
MOVMuxContext::video_track_timescale
int video_track_timescale
Definition: movenc.h:231
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:111
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:6384
AV_CODEC_ID_DVVIDEO
@ AV_CODEC_ID_DVVIDEO
Definition: codec_id.h:76
AV_CODEC_ID_PCM_S32BE
@ AV_CODEC_ID_PCM_S32BE
Definition: codec_id.h:347
AC3HeaderInfo::channel_map
uint16_t channel_map
Definition: ac3_parser_internal.h:50
MOVMuxContext::max_fragment_duration
int max_fragment_duration
Definition: movenc.h:224
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:599
MOVTrack::rtp_ctx
AVFormatContext * rtp_ctx
the format context for the hinting rtp muxer
Definition: movenc.h:139
av_inv_q
static av_always_inline AVRational av_inv_q(AVRational q)
Invert a rational.
Definition: rational.h:159
AV_CODEC_ID_VC1
@ AV_CODEC_ID_VC1
Definition: codec_id.h:122
AVCodecParameters::color_range
enum AVColorRange color_range
Video only.
Definition: codec_par.h:166
AVMasteringDisplayMetadata
Mastering display metadata capable of representing the color volume of the display used to master the...
Definition: mastering_display_metadata.h:38
len
int len
Definition: vorbis_enc_data.h:426
AV_CODEC_ID_JPEG2000
@ AV_CODEC_ID_JPEG2000
Definition: codec_id.h:140
MOV_TFHD_DEFAULT_SIZE
#define MOV_TFHD_DEFAULT_SIZE
Definition: isom.h:406
mov_write_tapt_tag
static int mov_write_tapt_tag(AVIOContext *pb, MOVTrack *track)
Definition: movenc.c:4077
mov_write_stsz_tag
static int mov_write_stsz_tag(AVIOContext *pb, MOVTrack *track)
Definition: movenc.c:225
profile
int profile
Definition: mxfenc.c:2297
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:8888
MOV_SAMPLE_DEPENDENCY_YES
#define MOV_SAMPLE_DEPENDENCY_YES
Definition: isom.h:434
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:81
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:183
AVCodecParameters::field_order
enum AVFieldOrder field_order
Video only.
Definition: codec_par.h:161
update_size
static int64_t update_size(AVIOContext *pb, int64_t pos)
Definition: movenc.c:155
MP4TrackKindValueMapping
Definition: isom.h:484
ff_tgp_muxer
const FFOutputFormat ff_tgp_muxer
AVFMT_TS_NEGATIVE
#define AVFMT_TS_NEGATIVE
Format allows muxing negative timestamps.
Definition: avformat.h:490
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:1211
ff_iamf_write_descriptors
int ff_iamf_write_descriptors(const IAMFContext *iamf, AVIOContext *pb, void *log_ctx)
Definition: iamf_writer.c:1003
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:5461
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:3222
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:813
AV_DISPOSITION_VISUAL_IMPAIRED
#define AV_DISPOSITION_VISUAL_IMPAIRED
The stream is intended for visually impaired audiences.
Definition: avformat.h:658
mov_write_moof_tag
static int mov_write_moof_tag(AVIOContext *pb, MOVMuxContext *mov, int tracks, int64_t mdat_size)
Definition: movenc.c:5933
AV_PROFILE_DNXHD
#define AV_PROFILE_DNXHD
Definition: defs.h:80
tag
uint32_t tag
Definition: movenc.c:2046
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:756
AVFMT_FLAG_BITEXACT
#define AVFMT_FLAG_BITEXACT
When muxing, try to avoid writing any random/volatile data to the output.
Definition: avformat.h:1431
ret
ret
Definition: filter_design.txt:187
AVStream
Stream structure.
Definition: avformat.h:744
AV_CODEC_ID_APV
@ AV_CODEC_ID_APV
Definition: codec_id.h:332
mov_get_h264_codec_tag
static int mov_get_h264_codec_tag(AVFormatContext *s, MOVTrack *track)
Definition: movenc.c:1961
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:4720
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:3718
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:567
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:257
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:1631
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:154
MOV_TKHD_FLAG_IN_MOVIE
#define MOV_TKHD_FLAG_IN_MOVIE
Definition: isom.h:429
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:281
mov_write_tref_tag
static int mov_write_tref_tag(AVIOContext *pb, MOVTrack *track)
Definition: movenc.c:4220
mov_write_uuid_tag_ipod
static int mov_write_uuid_tag_ipod(AVIOContext *pb)
Write uuid atom.
Definition: movenc.c:2209
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:599
MOVMuxContext::is_animated_avif
int is_animated_avif
Definition: movenc.h:266
flag
#define flag(name)
Definition: cbs_av1.c:496
AV_INPUT_BUFFER_PADDING_SIZE
#define AV_INPUT_BUFFER_PADDING_SIZE
Definition: defs.h:40
left
Tag MUST be and< 10hcoeff half pel interpolation filter coefficients, hcoeff[0] are the 2 middle coefficients[1] are the next outer ones and so on, resulting in a filter like:...eff[2], hcoeff[1], hcoeff[0], hcoeff[0], hcoeff[1], hcoeff[2] ... the sign of the coefficients is not explicitly stored but alternates after each coeff and coeff[0] is positive, so ...,+,-,+,-,+,+,-,+,-,+,... hcoeff[0] is not explicitly stored but found by subtracting the sum of all stored coefficients with signs from 32 hcoeff[0]=32 - hcoeff[1] - hcoeff[2] - ... a good choice for hcoeff and htaps is htaps=6 hcoeff={40,-10, 2} an alternative which requires more computations at both encoder and decoder side and may or may not be better is htaps=8 hcoeff={42,-14, 6,-2}ref_frames minimum of the number of available reference frames and max_ref_frames for example the first frame after a key frame always has ref_frames=1spatial_decomposition_type wavelet type 0 is a 9/7 symmetric compact integer wavelet 1 is a 5/3 symmetric compact integer wavelet others are reserved stored as delta from last, last is reset to 0 if always_reset||keyframeqlog quality(logarithmic quantizer scale) stored as delta from last, last is reset to 0 if always_reset||keyframemv_scale stored as delta from last, last is reset to 0 if always_reset||keyframe FIXME check that everything works fine if this changes between framesqbias dequantization bias stored as delta from last, last is reset to 0 if always_reset||keyframeblock_max_depth maximum depth of the block tree stored as delta from last, last is reset to 0 if always_reset||keyframequant_table quantization tableHighlevel bitstream structure:==============================--------------------------------------------|Header|--------------------------------------------|------------------------------------|||Block0||||split?||||yes no||||......... intra?||||:Block01 :yes no||||:Block02 :....... ..........||||:Block03 ::y DC ::ref index:||||:Block04 ::cb DC ::motion x :||||......... :cr DC ::motion y :||||....... ..........|||------------------------------------||------------------------------------|||Block1|||...|--------------------------------------------|------------ ------------ ------------|||Y subbands||Cb subbands||Cr subbands||||--- ---||--- ---||--- ---|||||LL0||HL0||||LL0||HL0||||LL0||HL0|||||--- ---||--- ---||--- ---||||--- ---||--- ---||--- ---|||||LH0||HH0||||LH0||HH0||||LH0||HH0|||||--- ---||--- ---||--- ---||||--- ---||--- ---||--- ---|||||HL1||LH1||||HL1||LH1||||HL1||LH1|||||--- ---||--- ---||--- ---||||--- ---||--- ---||--- ---|||||HH1||HL2||||HH1||HL2||||HH1||HL2|||||...||...||...|||------------ ------------ ------------|--------------------------------------------Decoding process:=================------------|||Subbands|------------||||------------|Intra DC||||LL0 subband prediction ------------|\ Dequantization ------------------- \||Reference frames|\ IDWT|------- -------|Motion \|||Frame 0||Frame 1||Compensation . OBMC v -------|------- -------|--------------. \------> Frame n output Frame Frame<----------------------------------/|...|------------------- Range Coder:============Binary Range Coder:------------------- The implemented range coder is an adapted version based upon "Range encoding: an algorithm for removing redundancy from a digitised message." by G. N. N. Martin. The symbols encoded by the Snow range coder are bits(0|1). The associated probabilities are not fix but change depending on the symbol mix seen so far. bit seen|new state ---------+----------------------------------------------- 0|256 - state_transition_table[256 - old_state];1|state_transition_table[old_state];state_transition_table={ 0, 0, 0, 0, 0, 0, 0, 0, 20, 21, 22, 23, 24, 25, 26, 27, 28, 29, 30, 31, 32, 33, 34, 35, 36, 37, 37, 38, 39, 40, 41, 42, 43, 44, 45, 46, 47, 48, 49, 50, 51, 52, 53, 54, 55, 56, 56, 57, 58, 59, 60, 61, 62, 63, 64, 65, 66, 67, 68, 69, 70, 71, 72, 73, 74, 75, 75, 76, 77, 78, 79, 80, 81, 82, 83, 84, 85, 86, 87, 88, 89, 90, 91, 92, 93, 94, 94, 95, 96, 97, 98, 99, 100, 101, 102, 103, 104, 105, 106, 107, 108, 109, 110, 111, 112, 113, 114, 114, 115, 116, 117, 118, 119, 120, 121, 122, 123, 124, 125, 126, 127, 128, 129, 130, 131, 132, 133, 133, 134, 135, 136, 137, 138, 139, 140, 141, 142, 143, 144, 145, 146, 147, 148, 149, 150, 151, 152, 152, 153, 154, 155, 156, 157, 158, 159, 160, 161, 162, 163, 164, 165, 166, 167, 168, 169, 170, 171, 171, 172, 173, 174, 175, 176, 177, 178, 179, 180, 181, 182, 183, 184, 185, 186, 187, 188, 189, 190, 190, 191, 192, 194, 194, 195, 196, 197, 198, 199, 200, 201, 202, 202, 204, 205, 206, 207, 208, 209, 209, 210, 211, 212, 213, 215, 215, 216, 217, 218, 219, 220, 220, 222, 223, 224, 225, 226, 227, 227, 229, 229, 230, 231, 232, 234, 234, 235, 236, 237, 238, 239, 240, 241, 242, 243, 244, 245, 246, 247, 248, 248, 0, 0, 0, 0, 0, 0, 0};FIXME Range Coding of integers:------------------------- FIXME Neighboring Blocks:===================left and top are set to the respective blocks unless they are outside of the image in which case they are set to the Null block top-left is set to the top left block unless it is outside of the image in which case it is set to the left block if this block has no larger parent block or it is at the left side of its parent block and the top right block is not outside of the image then the top right block is used for top-right else the top-left block is used Null block y, cb, cr are 128 level, ref, mx and my are 0 Motion Vector Prediction:=========================1. the motion vectors of all the neighboring blocks are scaled to compensate for the difference of reference frames scaled_mv=(mv *(256 *(current_reference+1)/(mv.reference+1))+128)> the median of the scaled left
Definition: snow.txt:386
AV_PIX_FMT_UYVY422
@ AV_PIX_FMT_UYVY422
packed YUV 4:2:2, 16bpp, Cb Y0 Cr Y1
Definition: pixfmt.h:88
AV_RL32
uint64_t_TMPL AV_WL64 unsigned int_TMPL AV_RL32
Definition: bytestream.h:92
MODE_3G2
#define MODE_3G2
Definition: movenc.h:42
mov_flush_fragment
static int mov_flush_fragment(AVFormatContext *s, int force)
Definition: movenc.c:6522
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:3437
MOVTrack::par
AVCodecParameters * par
Definition: movenc.h:119
ff_isom_parse_apvc
int ff_isom_parse_apvc(APVDecoderConfigurationRecord *apvc, const AVPacket *pkt, void *logctx)
Definition: apv.c:252
AVStreamGroup
Definition: avformat.h:1097
AVStream::index
int index
stream index in AVFormatContext
Definition: avformat.h:750
eac3_info::num_ind_sub
uint8_t num_ind_sub
Definition: movenc.c:391
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:274
AVStreamGroup::nb_streams
unsigned int nb_streams
Number of elements in AVStreamGroup.streams.
Definition: avformat.h:1151
channel_layout.h
ff_avc_write_annexb_extradata
int ff_avc_write_annexb_extradata(const uint8_t *in, uint8_t **buf, int *size)
Definition: avc.c:144
MOVMuxContext::flags
int flags
Definition: movenc.h:215
AV_PROFILE_AAC_HE_V2
#define AV_PROFILE_AAC_HE_V2
Definition: defs.h:73
AV_CODEC_ID_V410
@ AV_CODEC_ID_V410
Definition: codec_id.h:210
MOVTrack::last_stsd_index
int last_stsd_index
Definition: movenc.h:98
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:865
MOVMuxContext::reserved_moov_size
int reserved_moov_size
0 for disabled, -1 for automatic, size otherwise
Definition: movenc.h:233
ISOM_DVCC_DVVC_SIZE
#define ISOM_DVCC_DVVC_SIZE
Definition: dovi_isom.h:29
AVIO_SEEKABLE_NORMAL
#define AVIO_SEEKABLE_NORMAL
Seeking works like for a local file.
Definition: avio.h:41
is_cover_image
static int is_cover_image(const AVStream *st)
Definition: movenc.c:184
AVRational::den
int den
Denominator.
Definition: rational.h:60
rgb_to_yuv
static uint32_t rgb_to_yuv(uint32_t rgb)
Definition: movenc.c:7812
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:7564
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:6040
mov_write_prft_tag
static int mov_write_prft_tag(AVIOContext *pb, MOVMuxContext *mov, int tracks)
Definition: movenc.c:5883
mov_write_fiel_tag
static int mov_write_fiel_tag(AVIOContext *pb, MOVTrack *track, int field_order)
Definition: movenc.c:2225
AV_OPT_TYPE_INT
@ AV_OPT_TYPE_INT
Underlying C type is int.
Definition: opt.h:259
av_channel_layout_uninit
void av_channel_layout_uninit(AVChannelLayout *channel_layout)
Free any allocated data in the channel layout and reset the channel count to 0.
Definition: channel_layout.c:442
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:177
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:514
mov_write_identification
static int mov_write_identification(AVIOContext *pb, AVFormatContext *s)
Definition: movenc.c:6274
mov_write_sidx_tags
static int mov_write_sidx_tags(AVIOContext *pb, MOVMuxContext *mov, int tracks, int ref_size)
Definition: movenc.c:5845
eac3_info::bsid
uint8_t bsid
Definition: movenc.c:396
MOVMuxContext::tracks
MOVTrack * tracks
Definition: movenc.h:213
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:121
mov_write_ilst_tag
static int mov_write_ilst_tag(AVIOContext *pb, MOVMuxContext *mov, AVFormatContext *s)
Definition: movenc.c:4774
mov_flush_fragment_interleaving
static int mov_flush_fragment_interleaving(AVFormatContext *s, MOVTrack *track)
Definition: movenc.c:6403
eac3_info::complexity_index_type_a
uint8_t complexity_index_type_a
Definition: movenc.c:413
mov_write_btrt_tag
static int mov_write_btrt_tag(AVIOContext *pb, MOVTrack *track)
Definition: movenc.c:1273
mov_write_glbl_tag
static int mov_write_glbl_tag(AVIOContext *pb, MOVTrack *track)
Definition: movenc.c:1196
AVStreamGroupLCEVC::width
int width
Width of the final stream for presentation.
Definition: avformat.h:1079
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:383
mov_mdhd_mvhd_tkhd_version
static int mov_mdhd_mvhd_tkhd_version(MOVMuxContext *mov, MOVTrack *track, int64_t duration)
Definition: movenc.c:3890
ff_codec_movsubtitle_tags
const AVCodecTag ff_codec_movsubtitle_tags[]
Definition: isom.c:75
AVPacket::stream_index
int stream_index
Definition: packet.h:590
mov_write_mdia_tag
static int mov_write_mdia_tag(AVFormatContext *s, AVIOContext *pb, MOVMuxContext *mov, MOVTrack *track)
Definition: movenc.c:3936
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:109
mov_write_ispe_tag
static int mov_write_ispe_tag(AVIOContext *pb, MOVMuxContext *mov, AVFormatContext *s, int stream_index)
Definition: movenc.c:3706
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:346
AVCodecParameters::bits_per_coded_sample
int bits_per_coded_sample
The number of bits per sample in the codedwords.
Definition: codec_par.h:110
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:1124
param_write_hex
static void param_write_hex(AVIOContext *pb, const char *name, const uint8_t *value, int len)
Definition: movenc.c:5314
MOVTrack::timescale
unsigned timescale
Definition: movenc.h:91
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:1565
AV_CODEC_ID_PCM_U8
@ AV_CODEC_ID_PCM_U8
Definition: codec_id.h:343
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:92
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:5068
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:267
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:714
AV_CODEC_ID_PCM_F64LE
@ AV_CODEC_ID_PCM_F64LE
Definition: codec_id.h:361
mov_write_dvcc_dvvc_tag
static int mov_write_dvcc_dvvc_tag(AVFormatContext *s, AVIOContext *pb, AVDOVIDecoderConfigurationRecord *dovi)
Definition: movenc.c:2514
mov_preroll_write_stbl_atoms
static int mov_preroll_write_stbl_atoms(AVIOContext *pb, MOVTrack *track)
Definition: movenc.c:3286
AVStereo3D::view
enum AVStereo3DView view
Determines which views are packed.
Definition: stereo3d.h:217
MOVMuxContext::major_brand
char * major_brand
Definition: movenc.h:236
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:996
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:2283
MOVTrack::cluster_capacity
unsigned cluster_capacity
Definition: movenc.h:125
MOVMuxContext::write_btrt
int write_btrt
Definition: movenc.h:258
MOVIentry::stsd_index
unsigned int stsd_index
Definition: movenc.h:53
language_code
static uint16_t language_code(const char *str)
Definition: movenc.c:4942
AVCodecParameters::codec_id
enum AVCodecID codec_id
Specific type of the encoded data (the codec used).
Definition: codec_par.h:55
mov_write_ipma_tag
static int mov_write_ipma_tag(AVIOContext *pb, MOVMuxContext *mov, AVFormatContext *s)
Definition: movenc.c:3751
get_samples_per_packet
static int get_samples_per_packet(MOVTrack *track)
Definition: movenc.c:1254
MOV_ENC_CENC_AES_CTR
@ MOV_ENC_CENC_AES_CTR
Definition: movenc.h:193
mov_write_smhd_tag
static int mov_write_smhd_tag(AVIOContext *pb)
Definition: movenc.c:3519
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:565
MOVTrack::extradata
uint8_t ** extradata
Definition: movenc.h:99
cr
static double cr(void *priv, double x, double y)
Definition: vf_geq.c:248
AV_OPT_TYPE_BOOL
@ AV_OPT_TYPE_BOOL
Underlying C type is int.
Definition: opt.h:327
PIX_FMT_LIST_MOV
@ PIX_FMT_LIST_MOV
Definition: raw.h:40
AV_CODEC_ID_ADPCM_IMA_WAV
@ AV_CODEC_ID_ADPCM_IMA_WAV
Definition: codec_id.h:378
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:3066
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:6324
riff.h
MOV_TFHD_DURATION_IS_EMPTY
#define MOV_TFHD_DURATION_IS_EMPTY
Definition: isom.h:408
AV_CODEC_ID_ILBC
@ AV_CODEC_ID_ILBC
Definition: codec_id.h:519
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:414
ff_isom_init_apvc
int ff_isom_init_apvc(APVDecoderConfigurationRecord **papvc, void *logctx)
Definition: apv.c:352
AV_OPT_TYPE_FLAGS
@ AV_OPT_TYPE_FLAGS
Underlying C type is unsigned int.
Definition: opt.h:255
int32_t
int32_t
Definition: audioconvert.c:56
distance
static float distance(float x, float y, int band)
Definition: nellymoserenc.c:231
MOVTrack::eac3_priv
void * eac3_priv
Definition: movenc.h:170
mov_write_dops_tag
static int mov_write_dops_tag(AVFormatContext *s, AVIOContext *pb, MOVTrack *track)
Definition: movenc.c:875
mov_write_squashed_packet
static int mov_write_squashed_packet(AVFormatContext *s, MOVTrack *track)
Definition: movenc.c:6428
avio_wb16
void avio_wb16(AVIOContext *s, unsigned int val)
Definition: aviobuf.c:446
AV_CODEC_ID_VP8
@ AV_CODEC_ID_VP8
Definition: codec_id.h:192
mov_write_hmhd_tag
static int mov_write_hmhd_tag(AVIOContext *pb)
Definition: movenc.c:3785
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:486
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:359
param_write_string
static void param_write_string(AVIOContext *pb, const char *name, const char *value)
Definition: movenc.c:5309
AVCodecParameters::bit_rate
int64_t bit_rate
The average bitrate of the encoded data (in bits per second).
Definition: codec_par.h:97
mov_write_mdcv_tag
static int mov_write_mdcv_tag(AVIOContext *pb, MOVTrack *track)
Definition: movenc.c:2663
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:684
rescale_rational
static int64_t rescale_rational(AVRational q, int b)
Definition: movenc.c:2371
ff_isom_write_lhvc
int ff_isom_write_lhvc(AVIOContext *pb, const uint8_t *data, int size, int ps_array_completeness, void *logctx)
Writes L-HEVC extradata (parameter sets with nuh_layer_id > 0, as a LHEVCDecoderConfigurationRecord) ...
Definition: hevc.c:1405
AVERROR_INVALIDDATA
#define AVERROR_INVALIDDATA
Invalid data found when processing input.
Definition: error.h:61
ff_mov_track_kind_table
const struct MP4TrackKindMapping ff_mov_track_kind_table[]
Definition: isom.c:451
av_stereo3d_type_name
const char * av_stereo3d_type_name(unsigned int type)
Provide a human-readable name of a given stereo3d type.
Definition: stereo3d.c:92
MOVMuxContext::mdat_buf
AVIOContext * mdat_buf
Definition: movenc.h:228
mov_write_amr_tag
static int mov_write_amr_tag(AVIOContext *pb, MOVTrack *track)
Definition: movenc.c:367
mov_write_mdat_tag
static int mov_write_mdat_tag(AVIOContext *pb, MOVMuxContext *mov)
Definition: movenc.c:6029
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:5603
AV_CODEC_ID_VORBIS
@ AV_CODEC_ID_VORBIS
Definition: codec_id.h:465
MOVTrack::default_duration
int64_t default_duration
Definition: movenc.h:144
AVFMT_AVOID_NEG_TS_AUTO
#define AVFMT_AVOID_NEG_TS_AUTO
Enabled when required by target format.
Definition: avformat.h:1648
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:197
AV_OPT_TYPE_STRING
@ AV_OPT_TYPE_STRING
Underlying C type is a uint8_t* that is either NULL or points to a C string allocated with the av_mal...
Definition: opt.h:276
width
#define width
Definition: dsp.h:89
AVAmbientViewingEnvironment::ambient_light_y
AVRational ambient_light_y
Normalized y chromaticity coordinate of the environmental ambient light in the nominal viewing enviro...
Definition: ambient_viewing_environment.h:54
flac.h
MOVTrack::frag_info_capacity
unsigned frag_info_capacity
Definition: movenc.h:158
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:184
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
MOVTrack::tref_id
int tref_id
trackID of the referenced track
Definition: movenc.h:129
AV_CODEC_ID_MPEG2VIDEO
@ AV_CODEC_ID_MPEG2VIDEO
preferred ID for MPEG-1/2 video decoding
Definition: codec_id.h:54
AC3HeaderInfo::sr_code
uint8_t sr_code
Definition: ac3_parser_internal.h:40
MOV_TRUN_SAMPLE_CTS
#define MOV_TRUN_SAMPLE_CTS
Definition: isom.h:416
AV_OPT_TYPE_CONST
@ AV_OPT_TYPE_CONST
Special option type for declaring named constants.
Definition: opt.h:299
MOV_ISMV_TTML_TAG
#define MOV_ISMV_TTML_TAG
Definition: isom.h:479
snprintf
#define snprintf
Definition: snprintf.h:34
mov_write_tfrf_tags
static int mov_write_tfrf_tags(AVIOContext *pb, MOVMuxContext *mov, MOVTrack *track)
Definition: movenc.c:5638
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:351
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:2186
AVSphericalMapping
This structure describes how to handle spherical videos, outlining information about projection,...
Definition: spherical.h:100
mov_pix_fmt_tags
static const struct @485 mov_pix_fmt_tags[]
MOVMuxContext::moov_written
int moov_written
Definition: movenc.h:222
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:5583
MOV_PARTIAL_SYNC_SAMPLE
#define MOV_PARTIAL_SYNC_SAMPLE
Definition: movenc.h:59
AVSphericalMapping::yaw
int32_t yaw
Rotation around the up vector [-180, 180].
Definition: spherical.h:144
AV_CODEC_ID_DNXHD
@ AV_CODEC_ID_DNXHD
Definition: codec_id.h:151
MOVTrack::default_size
uint32_t default_size
Definition: movenc.h:146
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:2643
FF_API_V408_CODECID
#define FF_API_V408_CODECID
Definition: version_major.h:42
MOVMuxContext::gamma
float gamma
Definition: movenc.h:244
AVPacket::side_data_elems
int side_data_elems
Definition: packet.h:600
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:156
iamf_writer.h
av_fourcc2str
#define av_fourcc2str(fourcc)
Definition: avutil.h:347
mov_write_dfla_tag
static int mov_write_dfla_tag(AVIOContext *pb, MOVTrack *track)
Definition: movenc.c:855
MP4TrackKindMapping
Definition: isom.h:489
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:5784
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:394
MOVIentry::samples_in_chunk
unsigned int samples_in_chunk
Definition: movenc.h:54