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