Thanks to visit codestin.com
Credit goes to www.ffmpeg.org

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