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