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 static int mov_write_avid_tag(AVIOContext *pb, MOVTrack *track)
1683 {
1684  int interlaced;
1685  int cid;
1686  int display_width = track->par->width;
1687 
1688  if (track->extradata[track->last_stsd_index] && track->extradata_size[track->last_stsd_index] > 0x29) {
1689  if (ff_dnxhd_parse_header_prefix(track->extradata[track->last_stsd_index]) != 0) {
1690  /* looks like a DNxHD bit stream */
1691  interlaced = (track->extradata[track->last_stsd_index][5] & 2);
1692  cid = AV_RB32(track->extradata[track->last_stsd_index] + 0x28);
1693  } else {
1694  av_log(NULL, AV_LOG_WARNING, "Could not locate DNxHD bit stream in vos_data\n");
1695  return 0;
1696  }
1697  } else {
1698  av_log(NULL, AV_LOG_WARNING, "Could not locate DNxHD bit stream, vos_data too small\n");
1699  return 0;
1700  }
1701 
1702  avio_wb32(pb, 24); /* size */
1703  ffio_wfourcc(pb, "ACLR");
1704  ffio_wfourcc(pb, "ACLR");
1705  ffio_wfourcc(pb, "0001");
1706  if (track->par->color_range == AVCOL_RANGE_MPEG || /* Legal range (16-235) */
1708  avio_wb32(pb, 1); /* Corresponds to 709 in official encoder */
1709  } else { /* Full range (0-255) */
1710  avio_wb32(pb, 2); /* Corresponds to RGB in official encoder */
1711  }
1712  avio_wb32(pb, 0); /* unknown */
1713 
1714  if (track->tag == MKTAG('A','V','d','h')) {
1715  avio_wb32(pb, 32);
1716  ffio_wfourcc(pb, "ADHR");
1717  ffio_wfourcc(pb, "0001");
1718  avio_wb32(pb, cid);
1719  avio_wb32(pb, 0); /* unknown */
1720  avio_wb32(pb, 1); /* unknown */
1721  avio_wb32(pb, 0); /* unknown */
1722  avio_wb32(pb, 0); /* unknown */
1723  return 0;
1724  }
1725 
1726  avio_wb32(pb, 24); /* size */
1727  ffio_wfourcc(pb, "APRG");
1728  ffio_wfourcc(pb, "APRG");
1729  ffio_wfourcc(pb, "0001");
1730  avio_wb32(pb, 1); /* unknown */
1731  avio_wb32(pb, 0); /* unknown */
1732 
1733  avio_wb32(pb, 120); /* size */
1734  ffio_wfourcc(pb, "ARES");
1735  ffio_wfourcc(pb, "ARES");
1736  ffio_wfourcc(pb, "0001");
1737  avio_wb32(pb, cid); /* dnxhd cid, some id ? */
1738  if ( track->par->sample_aspect_ratio.num > 0
1739  && track->par->sample_aspect_ratio.den > 0)
1740  display_width = display_width * track->par->sample_aspect_ratio.num / track->par->sample_aspect_ratio.den;
1741  avio_wb32(pb, display_width);
1742  /* values below are based on samples created with quicktime and avid codecs */
1743  if (interlaced) {
1744  avio_wb32(pb, track->par->height / 2);
1745  avio_wb32(pb, 2); /* unknown */
1746  avio_wb32(pb, 0); /* unknown */
1747  avio_wb32(pb, 4); /* unknown */
1748  } else {
1749  avio_wb32(pb, track->par->height);
1750  avio_wb32(pb, 1); /* unknown */
1751  avio_wb32(pb, 0); /* unknown */
1752  if (track->par->height == 1080)
1753  avio_wb32(pb, 5); /* unknown */
1754  else
1755  avio_wb32(pb, 6); /* unknown */
1756  }
1757  /* padding */
1758  ffio_fill(pb, 0, 10 * 8);
1759 
1760  return 0;
1761 }
1762 
1763 static int mov_write_dpxe_tag(AVIOContext *pb, MOVTrack *track)
1764 {
1765  avio_wb32(pb, 12);
1766  ffio_wfourcc(pb, "DpxE");
1767  if (track->extradata_size[track->last_stsd_index] >= 12 &&
1768  !memcmp(&track->extradata[track->last_stsd_index][4], "DpxE", 4)) {
1769  avio_wb32(pb, track->extradata[track->last_stsd_index][11]);
1770  } else {
1771  avio_wb32(pb, 1);
1772  }
1773  return 0;
1774 }
1775 
1777 {
1778  int tag;
1779 
1780  if (track->par->width == 720) { /* SD */
1781  if (track->par->height == 480) { /* NTSC */
1782  if (track->par->format == AV_PIX_FMT_YUV422P) tag = MKTAG('d','v','5','n');
1783  else tag = MKTAG('d','v','c',' ');
1784  }else if (track->par->format == AV_PIX_FMT_YUV422P) tag = MKTAG('d','v','5','p');
1785  else if (track->par->format == AV_PIX_FMT_YUV420P) tag = MKTAG('d','v','c','p');
1786  else tag = MKTAG('d','v','p','p');
1787  } else if (track->par->height == 720) { /* HD 720 line */
1788  if (track->st->time_base.den == 50) tag = MKTAG('d','v','h','q');
1789  else tag = MKTAG('d','v','h','p');
1790  } else if (track->par->height == 1080) { /* HD 1080 line */
1791  if (track->st->time_base.den == 25) tag = MKTAG('d','v','h','5');
1792  else tag = MKTAG('d','v','h','6');
1793  } else {
1794  av_log(s, AV_LOG_ERROR, "unsupported height for dv codec\n");
1795  return 0;
1796  }
1797 
1798  return tag;
1799 }
1800 
1802 {
1803  AVRational rational_framerate = st->avg_frame_rate;
1804  int rate = 0;
1805  if (rational_framerate.den != 0)
1806  rate = av_q2d(rational_framerate);
1807  return rate;
1808 }
1809 
1811 {
1812  int tag = track->par->codec_tag;
1814  AVStream *st = track->st;
1815  int rate = defined_frame_rate(s, st);
1816 
1817  if (!tag)
1818  tag = MKTAG('m', '2', 'v', '1'); //fallback tag
1819 
1820  if (track->par->format == AV_PIX_FMT_YUV420P) {
1821  if (track->par->width == 1280 && track->par->height == 720) {
1822  if (!interlaced) {
1823  if (rate == 24) tag = MKTAG('x','d','v','4');
1824  else if (rate == 25) tag = MKTAG('x','d','v','5');
1825  else if (rate == 30) tag = MKTAG('x','d','v','1');
1826  else if (rate == 50) tag = MKTAG('x','d','v','a');
1827  else if (rate == 60) tag = MKTAG('x','d','v','9');
1828  }
1829  } else if (track->par->width == 1440 && track->par->height == 1080) {
1830  if (!interlaced) {
1831  if (rate == 24) tag = MKTAG('x','d','v','6');
1832  else if (rate == 25) tag = MKTAG('x','d','v','7');
1833  else if (rate == 30) tag = MKTAG('x','d','v','8');
1834  } else {
1835  if (rate == 25) tag = MKTAG('x','d','v','3');
1836  else if (rate == 30) tag = MKTAG('x','d','v','2');
1837  }
1838  } else if (track->par->width == 1920 && track->par->height == 1080) {
1839  if (!interlaced) {
1840  if (rate == 24) tag = MKTAG('x','d','v','d');
1841  else if (rate == 25) tag = MKTAG('x','d','v','e');
1842  else if (rate == 30) tag = MKTAG('x','d','v','f');
1843  } else {
1844  if (rate == 25) tag = MKTAG('x','d','v','c');
1845  else if (rate == 30) tag = MKTAG('x','d','v','b');
1846  }
1847  }
1848  } else if (track->par->format == AV_PIX_FMT_YUV422P) {
1849  if (track->par->width == 1280 && track->par->height == 720) {
1850  if (!interlaced) {
1851  if (rate == 24) tag = MKTAG('x','d','5','4');
1852  else if (rate == 25) tag = MKTAG('x','d','5','5');
1853  else if (rate == 30) tag = MKTAG('x','d','5','1');
1854  else if (rate == 50) tag = MKTAG('x','d','5','a');
1855  else if (rate == 60) tag = MKTAG('x','d','5','9');
1856  }
1857  } else if (track->par->width == 1920 && track->par->height == 1080) {
1858  if (!interlaced) {
1859  if (rate == 24) tag = MKTAG('x','d','5','d');
1860  else if (rate == 25) tag = MKTAG('x','d','5','e');
1861  else if (rate == 30) tag = MKTAG('x','d','5','f');
1862  } else {
1863  if (rate == 25) tag = MKTAG('x','d','5','c');
1864  else if (rate == 30) tag = MKTAG('x','d','5','b');
1865  }
1866  }
1867  }
1868 
1869  return tag;
1870 }
1871 
1873 {
1874  int tag = track->par->codec_tag;
1876  AVStream *st = track->st;
1877  int rate = defined_frame_rate(s, st);
1878 
1879  if (!tag)
1880  tag = MKTAG('a', 'v', 'c', 'i'); //fallback tag
1881 
1882  if (track->par->profile == AV_PROFILE_UNKNOWN ||
1883  !(track->par->profile & AV_PROFILE_H264_INTRA))
1884  return tag;
1885 
1886  if (track->par->format == AV_PIX_FMT_YUV420P10) {
1887  if (track->par->width == 960 && track->par->height == 720) {
1888  if (!interlaced) {
1889  if (rate == 24) tag = MKTAG('a','i','5','p');
1890  else if (rate == 25) tag = MKTAG('a','i','5','q');
1891  else if (rate == 30) tag = MKTAG('a','i','5','p');
1892  else if (rate == 50) tag = MKTAG('a','i','5','q');
1893  else if (rate == 60) tag = MKTAG('a','i','5','p');
1894  }
1895  } else if (track->par->width == 1440 && track->par->height == 1080) {
1896  if (!interlaced) {
1897  if (rate == 24) tag = MKTAG('a','i','5','3');
1898  else if (rate == 25) tag = MKTAG('a','i','5','2');
1899  else if (rate == 30) tag = MKTAG('a','i','5','3');
1900  } else {
1901  if (rate == 50) tag = MKTAG('a','i','5','5');
1902  else if (rate == 60) tag = MKTAG('a','i','5','6');
1903  }
1904  }
1905  } else if (track->par->format == AV_PIX_FMT_YUV422P10) {
1906  if (track->par->width == 1280 && track->par->height == 720) {
1907  if (!interlaced) {
1908  if (rate == 24) tag = MKTAG('a','i','1','p');
1909  else if (rate == 25) tag = MKTAG('a','i','1','q');
1910  else if (rate == 30) tag = MKTAG('a','i','1','p');
1911  else if (rate == 50) tag = MKTAG('a','i','1','q');
1912  else if (rate == 60) tag = MKTAG('a','i','1','p');
1913  }
1914  } else if (track->par->width == 1920 && track->par->height == 1080) {
1915  if (!interlaced) {
1916  if (rate == 24) tag = MKTAG('a','i','1','3');
1917  else if (rate == 25) tag = MKTAG('a','i','1','2');
1918  else if (rate == 30) tag = MKTAG('a','i','1','3');
1919  } else {
1920  if (rate == 25) tag = MKTAG('a','i','1','5');
1921  else if (rate == 50) tag = MKTAG('a','i','1','5');
1922  else if (rate == 60) tag = MKTAG('a','i','1','6');
1923  }
1924  } else if ( track->par->width == 4096 && track->par->height == 2160
1925  || track->par->width == 3840 && track->par->height == 2160
1926  || track->par->width == 2048 && track->par->height == 1080) {
1927  tag = MKTAG('a','i','v','x');
1928  }
1929  }
1930 
1931  return tag;
1932 }
1933 
1935 {
1936  int tag = track->par->codec_tag;
1937 
1938  if (!tag)
1939  tag = MKTAG('e', 'v', 'c', '1');
1940 
1941  return tag;
1942 }
1943 
1945 {
1946  int tag = track->par->codec_tag;
1947 
1948  if (!tag)
1949  tag = MKTAG('a', 'p', 'v', '1');
1950 
1951  return tag;
1952 }
1953 
1954 
1955 static const struct {
1957  uint32_t tag;
1958  unsigned bps;
1959 } mov_pix_fmt_tags[] = {
1960  { AV_PIX_FMT_YUYV422, MKTAG('y','u','v','2'), 0 },
1961  { AV_PIX_FMT_YUYV422, MKTAG('y','u','v','s'), 0 },
1962  { AV_PIX_FMT_UYVY422, MKTAG('2','v','u','y'), 0 },
1963  { AV_PIX_FMT_VYU444, MKTAG('v','3','0','8'), 0 },
1964  { AV_PIX_FMT_UYVA, MKTAG('v','4','0','8'), 0 },
1965  { AV_PIX_FMT_V30XLE, MKTAG('v','4','1','0'), 0 },
1966  { AV_PIX_FMT_RGB555BE,MKTAG('r','a','w',' '), 16 },
1967  { AV_PIX_FMT_RGB555LE,MKTAG('L','5','5','5'), 16 },
1968  { AV_PIX_FMT_RGB565LE,MKTAG('L','5','6','5'), 16 },
1969  { AV_PIX_FMT_RGB565BE,MKTAG('B','5','6','5'), 16 },
1970  { AV_PIX_FMT_GRAY16BE,MKTAG('b','1','6','g'), 16 },
1971  { AV_PIX_FMT_RGB24, MKTAG('r','a','w',' '), 24 },
1972  { AV_PIX_FMT_BGR24, MKTAG('2','4','B','G'), 24 },
1973  { AV_PIX_FMT_ARGB, MKTAG('r','a','w',' '), 32 },
1974  { AV_PIX_FMT_BGRA, MKTAG('B','G','R','A'), 32 },
1975  { AV_PIX_FMT_RGBA, MKTAG('R','G','B','A'), 32 },
1976  { AV_PIX_FMT_ABGR, MKTAG('A','B','G','R'), 32 },
1977  { AV_PIX_FMT_RGB48BE, MKTAG('b','4','8','r'), 48 },
1978 };
1979 
1981 {
1982  int tag = MKTAG('A','V','d','n');
1983  if (track->par->profile != AV_PROFILE_UNKNOWN &&
1984  track->par->profile != AV_PROFILE_DNXHD)
1985  tag = MKTAG('A','V','d','h');
1986  return tag;
1987 }
1988 
1990 {
1991  int tag = track->par->codec_tag;
1992  int i;
1993  enum AVPixelFormat pix_fmt;
1994 
1995  for (i = 0; i < FF_ARRAY_ELEMS(mov_pix_fmt_tags); i++) {
1996  if (track->par->format == mov_pix_fmt_tags[i].pix_fmt) {
1997  tag = mov_pix_fmt_tags[i].tag;
1999  if (track->par->codec_tag == mov_pix_fmt_tags[i].tag)
2000  break;
2001  }
2002  }
2003 
2005  track->par->bits_per_coded_sample);
2006  if (tag == MKTAG('r','a','w',' ') &&
2007  track->par->format != pix_fmt &&
2008  track->par->format != AV_PIX_FMT_GRAY8 &&
2009  track->par->format != AV_PIX_FMT_NONE)
2010  av_log(s, AV_LOG_ERROR, "%s rawvideo cannot be written to mov, output file will be unreadable\n",
2011  av_get_pix_fmt_name(track->par->format));
2012  return tag;
2013 }
2014 
2015 static unsigned int mov_get_codec_tag(AVFormatContext *s, MOVTrack *track)
2016 {
2017  unsigned int tag = track->par->codec_tag;
2018 
2019  // "rtp " is used to distinguish internally created RTP-hint tracks
2020  // (with rtp_ctx) from other tracks.
2021  if (tag == MKTAG('r','t','p',' '))
2022  tag = 0;
2023  if (!tag || (s->strict_std_compliance >= FF_COMPLIANCE_NORMAL &&
2024  (track->par->codec_id == AV_CODEC_ID_DVVIDEO ||
2025  track->par->codec_id == AV_CODEC_ID_RAWVIDEO ||
2026  track->par->codec_id == AV_CODEC_ID_H263 ||
2027  track->par->codec_id == AV_CODEC_ID_H264 ||
2028  track->par->codec_id == AV_CODEC_ID_DNXHD ||
2029  track->par->codec_id == AV_CODEC_ID_MPEG2VIDEO ||
2030  av_get_bits_per_sample(track->par->codec_id)))) { // pcm audio
2031  if (track->par->codec_id == AV_CODEC_ID_DVVIDEO)
2032  tag = mov_get_dv_codec_tag(s, track);
2033  else if (track->par->codec_id == AV_CODEC_ID_RAWVIDEO)
2034  tag = mov_get_rawvideo_codec_tag(s, track);
2035  else if (track->par->codec_id == AV_CODEC_ID_MPEG2VIDEO)
2037  else if (track->par->codec_id == AV_CODEC_ID_H264)
2038  tag = mov_get_h264_codec_tag(s, track);
2039  else if (track->par->codec_id == AV_CODEC_ID_EVC)
2040  tag = mov_get_evc_codec_tag(s, track);
2041  else if (track->par->codec_id == AV_CODEC_ID_APV)
2042  tag = mov_get_apv_codec_tag(s, track);
2043  else if (track->par->codec_id == AV_CODEC_ID_DNXHD)
2044  tag = mov_get_dnxhd_codec_tag(s, track);
2045  else if (track->par->codec_type == AVMEDIA_TYPE_VIDEO) {
2047  if (!tag) { // if no mac fcc found, try with Microsoft tags
2049  if (tag)
2050  av_log(s, AV_LOG_WARNING, "Using MS style video codec tag, "
2051  "the file may be unplayable!\n");
2052  }
2053  } else if (track->par->codec_type == AVMEDIA_TYPE_AUDIO) {
2055  if (!tag) { // if no mac fcc found, try with Microsoft tags
2056  int ms_tag = ff_codec_get_tag(ff_codec_wav_tags, track->par->codec_id);
2057  if (ms_tag) {
2058  tag = MKTAG('m', 's', ((ms_tag >> 8) & 0xff), (ms_tag & 0xff));
2059  av_log(s, AV_LOG_WARNING, "Using MS style audio codec tag, "
2060  "the file may be unplayable!\n");
2061  }
2062  }
2063  } else if (track->par->codec_type == AVMEDIA_TYPE_SUBTITLE)
2065  }
2066 
2067  return tag;
2068 }
2069 
2071  { AV_CODEC_ID_MJPEG, 0xD },
2072  { AV_CODEC_ID_PNG, 0xE },
2073  { AV_CODEC_ID_BMP, 0x1B },
2074  { AV_CODEC_ID_NONE, 0 },
2075 };
2076 
2077 static unsigned int validate_codec_tag(const AVCodecTag *const *tags,
2078  unsigned int tag, int codec_id)
2079 {
2080  int i;
2081 
2082  /**
2083  * Check that tag + id is in the table
2084  */
2085  for (i = 0; tags && tags[i]; i++) {
2086  const AVCodecTag *codec_tags = tags[i];
2087  while (codec_tags->id != AV_CODEC_ID_NONE) {
2088  if (ff_toupper4(codec_tags->tag) == ff_toupper4(tag) &&
2089  codec_tags->id == codec_id)
2090  return codec_tags->tag;
2091  codec_tags++;
2092  }
2093  }
2094  return 0;
2095 }
2096 
2097 static unsigned int mov_find_codec_tag(AVFormatContext *s, MOVTrack *track)
2098 {
2099  if (is_cover_image(track->st))
2101 
2102  if (track->mode == MODE_IPOD)
2103  if (!av_match_ext(s->url, "m4a") &&
2104  !av_match_ext(s->url, "m4v") &&
2105  !av_match_ext(s->url, "m4b"))
2106  av_log(s, AV_LOG_WARNING, "Warning, extension is not .m4a nor .m4v "
2107  "Quicktime/Ipod might not play the file\n");
2108 
2109  if (track->mode == MODE_MOV) {
2110  return mov_get_codec_tag(s, track);
2111  } else
2112  return validate_codec_tag(s->oformat->codec_tag, track->par->codec_tag,
2113  track->par->codec_id);
2114 }
2115 
2116 /** Write uuid atom.
2117  * Needed to make file play in iPods running newest firmware
2118  * goes after avcC atom in moov.trak.mdia.minf.stbl.stsd.avc1
2119  */
2121 {
2122  avio_wb32(pb, 28);
2123  ffio_wfourcc(pb, "uuid");
2124  avio_wb32(pb, 0x6b6840f2);
2125  avio_wb32(pb, 0x5f244fc5);
2126  avio_wb32(pb, 0xba39a51b);
2127  avio_wb32(pb, 0xcf0323f3);
2128  avio_wb32(pb, 0x0);
2129  return 28;
2130 }
2131 
2132 static const uint16_t fiel_data[] = {
2133  0x0000, 0x0100, 0x0201, 0x0206, 0x0209, 0x020e
2134 };
2135 
2136 static int mov_write_fiel_tag(AVIOContext *pb, MOVTrack *track, int field_order)
2137 {
2138  unsigned mov_field_order = 0;
2139  if (field_order < FF_ARRAY_ELEMS(fiel_data))
2140  mov_field_order = fiel_data[field_order];
2141  else
2142  return 0;
2143  avio_wb32(pb, 10);
2144  ffio_wfourcc(pb, "fiel");
2145  avio_wb16(pb, mov_field_order);
2146  return 10;
2147 }
2148 
2150 {
2151  MOVMuxContext *mov = s->priv_data;
2152  int ret = AVERROR_BUG;
2153  int64_t pos = avio_tell(pb);
2154  avio_wb32(pb, 0); /* size */
2155  avio_wl32(pb, track->tag); // store it byteswapped
2156  avio_wb32(pb, 0); /* Reserved */
2157  avio_wb16(pb, 0); /* Reserved */
2158  avio_wb16(pb, 1); /* Data-reference index */
2159 
2160  if (track->par->codec_id == AV_CODEC_ID_DVD_SUBTITLE)
2161  mov_write_esds_tag(pb, track);
2162  else if (track->par->codec_id == AV_CODEC_ID_TTML) {
2163  switch (track->par->codec_tag) {
2164  case MOV_ISMV_TTML_TAG:
2165  // ISMV dfxp requires no extradata.
2166  break;
2167  case MOV_MP4_TTML_TAG:
2168  // As specified in 14496-30, XMLSubtitleSampleEntry
2169  // Namespace
2170  avio_put_str(pb, "http://www.w3.org/ns/ttml");
2171  // Empty schema_location
2172  avio_w8(pb, 0);
2173  // Empty auxiliary_mime_types
2174  avio_w8(pb, 0);
2175  break;
2176  default:
2178  "Unknown codec tag '%s' utilized for TTML stream with "
2179  "index %d (track id %d)!\n",
2180  av_fourcc2str(track->par->codec_tag), track->st->index,
2181  track->track_id);
2182  return AVERROR(EINVAL);
2183  }
2184  } else if (track->extradata_size[track->last_stsd_index])
2185  avio_write(pb, track->extradata[track->last_stsd_index], track->extradata_size[track->last_stsd_index]);
2186 
2187  if (mov->write_btrt &&
2188  ((ret = mov_write_btrt_tag(pb, track)) < 0))
2189  return ret;
2190 
2191  return update_size(pb, pos);
2192 }
2193 
2195 {
2196  int8_t stereo_mode;
2197 
2198  if (stereo_3d->flags != 0) {
2199  av_log(s, AV_LOG_WARNING, "Unsupported stereo_3d flags %x. st3d not written.\n", stereo_3d->flags);
2200  return 0;
2201  }
2202 
2203  switch (stereo_3d->type) {
2204  case AV_STEREO3D_2D:
2205  stereo_mode = 0;
2206  break;
2207  case AV_STEREO3D_TOPBOTTOM:
2208  stereo_mode = 1;
2209  break;
2211  stereo_mode = 2;
2212  break;
2213  default:
2214  av_log(s, AV_LOG_WARNING, "Unsupported stereo_3d type %s. st3d not written.\n", av_stereo3d_type_name(stereo_3d->type));
2215  return 0;
2216  }
2217  avio_wb32(pb, 13); /* size */
2218  ffio_wfourcc(pb, "st3d");
2219  avio_wb32(pb, 0); /* version = 0 & flags = 0 */
2220  avio_w8(pb, stereo_mode);
2221  return 13;
2222 }
2223 
2225 {
2226  int64_t sv3d_pos, svhd_pos, proj_pos;
2227  const char* metadata_source = s->flags & AVFMT_FLAG_BITEXACT ? "Lavf" : LIBAVFORMAT_IDENT;
2228 
2229  if (spherical_mapping->projection != AV_SPHERICAL_EQUIRECTANGULAR &&
2230  spherical_mapping->projection != AV_SPHERICAL_EQUIRECTANGULAR_TILE &&
2231  spherical_mapping->projection != AV_SPHERICAL_CUBEMAP) {
2232  av_log(s, AV_LOG_WARNING, "Unsupported projection %d. sv3d not written.\n", spherical_mapping->projection);
2233  return 0;
2234  }
2235 
2236  sv3d_pos = avio_tell(pb);
2237  avio_wb32(pb, 0); /* size */
2238  ffio_wfourcc(pb, "sv3d");
2239 
2240  svhd_pos = avio_tell(pb);
2241  avio_wb32(pb, 0); /* size */
2242  ffio_wfourcc(pb, "svhd");
2243  avio_wb32(pb, 0); /* version = 0 & flags = 0 */
2244  avio_put_str(pb, metadata_source);
2245  update_size(pb, svhd_pos);
2246 
2247  proj_pos = avio_tell(pb);
2248  avio_wb32(pb, 0); /* size */
2249  ffio_wfourcc(pb, "proj");
2250 
2251  avio_wb32(pb, 24); /* size */
2252  ffio_wfourcc(pb, "prhd");
2253  avio_wb32(pb, 0); /* version = 0 & flags = 0 */
2254  avio_wb32(pb, spherical_mapping->yaw);
2255  avio_wb32(pb, spherical_mapping->pitch);
2256  avio_wb32(pb, spherical_mapping->roll);
2257 
2258  switch (spherical_mapping->projection) {
2261  avio_wb32(pb, 28); /* size */
2262  ffio_wfourcc(pb, "equi");
2263  avio_wb32(pb, 0); /* version = 0 & flags = 0 */
2264  avio_wb32(pb, spherical_mapping->bound_top);
2265  avio_wb32(pb, spherical_mapping->bound_bottom);
2266  avio_wb32(pb, spherical_mapping->bound_left);
2267  avio_wb32(pb, spherical_mapping->bound_right);
2268  break;
2269  case AV_SPHERICAL_CUBEMAP:
2270  avio_wb32(pb, 20); /* size */
2271  ffio_wfourcc(pb, "cbmp");
2272  avio_wb32(pb, 0); /* version = 0 & flags = 0 */
2273  avio_wb32(pb, 0); /* layout */
2274  avio_wb32(pb, spherical_mapping->padding); /* padding */
2275  break;
2276  }
2277  update_size(pb, proj_pos);
2278 
2279  return update_size(pb, sv3d_pos);
2280 }
2281 
2282 static inline int64_t rescale_rational(AVRational q, int b)
2283 {
2284  return av_rescale(q.num, b, q.den);
2285 }
2286 
2288  const AVStereo3D *stereo3d)
2289 {
2290  if (!stereo3d->horizontal_field_of_view.num)
2291  return;
2292 
2293  avio_wb32(pb, 12); /* size */
2294  ffio_wfourcc(pb, "hfov");
2295  avio_wb32(pb, rescale_rational(stereo3d->horizontal_field_of_view, 1000));
2296 }
2297 
2299  const AVSphericalMapping *spherical_mapping)
2300 {
2301  avio_wb32(pb, 24); /* size */
2302  ffio_wfourcc(pb, "proj");
2303  avio_wb32(pb, 16); /* size */
2304  ffio_wfourcc(pb, "prji");
2305  avio_wb32(pb, 0); /* version + flags */
2306 
2307  switch (spherical_mapping->projection) {
2309  ffio_wfourcc(pb, "rect");
2310  break;
2312  ffio_wfourcc(pb, "equi");
2313  break;
2315  ffio_wfourcc(pb, "hequ");
2316  break;
2317  case AV_SPHERICAL_FISHEYE:
2318  ffio_wfourcc(pb, "fish");
2319  break;
2320  default:
2321  av_assert0(0);
2322  }
2323 }
2324 
2326  const AVStereo3D *stereo3d)
2327 {
2328  int64_t pos = avio_tell(pb);
2329  int view = 0;
2330 
2331  avio_wb32(pb, 0); /* size */
2332  ffio_wfourcc(pb, "eyes");
2333 
2334  // stri is mandatory
2335  avio_wb32(pb, 13); /* size */
2336  ffio_wfourcc(pb, "stri");
2337  avio_wb32(pb, 0); /* version + flags */
2338  switch (stereo3d->view) {
2339  case AV_STEREO3D_VIEW_LEFT:
2340  view |= 1 << 0;
2341  break;
2343  view |= 1 << 1;
2344  break;
2346  view |= (1 << 0) | (1 << 1);
2347  break;
2348  }
2349  view |= !!(stereo3d->flags & AV_STEREO3D_FLAG_INVERT) << 3;
2350  avio_w8(pb, view);
2351 
2352  // hero is optional
2353  if (stereo3d->primary_eye != AV_PRIMARY_EYE_NONE) {
2354  avio_wb32(pb, 13); /* size */
2355  ffio_wfourcc(pb, "hero");
2356  avio_wb32(pb, 0); /* version + flags */
2357  avio_w8(pb, stereo3d->primary_eye);
2358  }
2359 
2360  // it's not clear if cams is mandatory or optional
2361  if (stereo3d->baseline) {
2362  avio_wb32(pb, 24); /* size */
2363  ffio_wfourcc(pb, "cams");
2364  avio_wb32(pb, 16); /* size */
2365  ffio_wfourcc(pb, "blin");
2366  avio_wb32(pb, 0); /* version + flags */
2367  avio_wb32(pb, stereo3d->baseline);
2368  }
2369 
2370  // it's not clear if cmfy is mandatory or optional
2371  if (stereo3d->horizontal_disparity_adjustment.num) {
2372  avio_wb32(pb, 24); /* size */
2373  ffio_wfourcc(pb, "cmfy");
2374  avio_wb32(pb, 16); /* size */
2375  ffio_wfourcc(pb, "dadj");
2376  avio_wb32(pb, 0); /* version + flags */
2378  }
2379 
2380  return update_size(pb, pos);
2381 }
2382 
2384  const AVStereo3D *stereo3d,
2385  const AVSphericalMapping *spherical_mapping)
2386 {
2387  int64_t pos;
2388 
2389  if (spherical_mapping &&
2390  spherical_mapping->projection != AV_SPHERICAL_RECTILINEAR &&
2391  spherical_mapping->projection != AV_SPHERICAL_EQUIRECTANGULAR &&
2392  spherical_mapping->projection != AV_SPHERICAL_HALF_EQUIRECTANGULAR &&
2393  spherical_mapping->projection != AV_SPHERICAL_FISHEYE) {
2394  av_log(s, AV_LOG_WARNING, "Unsupported projection %d. proj not written.\n",
2395  spherical_mapping->projection);
2396  spherical_mapping = NULL;
2397  }
2398 
2399  if (stereo3d && (stereo3d->type == AV_STEREO3D_2D ||
2400  (!(stereo3d->flags & AV_STEREO3D_FLAG_INVERT) &&
2401  stereo3d->view == AV_STEREO3D_VIEW_UNSPEC &&
2402  stereo3d->primary_eye == AV_PRIMARY_EYE_NONE &&
2403  !stereo3d->baseline &&
2404  !stereo3d->horizontal_disparity_adjustment.num))) {
2405  av_log(s, AV_LOG_WARNING, "Unsupported stereo 3d metadata. eyes not written.\n");
2406  stereo3d = NULL;
2407  }
2408 
2409  if (!spherical_mapping && !stereo3d)
2410  return 0;
2411 
2412  pos = avio_tell(pb);
2413  avio_wb32(pb, 0); /* size */
2414  ffio_wfourcc(pb, "vexu");
2415 
2416  if (spherical_mapping)
2417  mov_write_vexu_proj_tag(s, pb, spherical_mapping);
2418 
2419  if (stereo3d)
2420  mov_write_eyes_tag(s, pb, stereo3d);
2421 
2422  return update_size(pb, pos);
2423 }
2424 
2426 {
2427  uint8_t buf[ISOM_DVCC_DVVC_SIZE];
2428 
2429  avio_wb32(pb, 32); /* size = 8 + 24 */
2430  if (dovi->dv_profile > 10)
2431  ffio_wfourcc(pb, "dvwC");
2432  else if (dovi->dv_profile > 7)
2433  ffio_wfourcc(pb, "dvvC");
2434  else
2435  ffio_wfourcc(pb, "dvcC");
2436 
2437  ff_isom_put_dvcc_dvvc(s, buf, dovi);
2438  avio_write(pb, buf, sizeof(buf));
2439 
2440  return 32; /* 8 + 24 */
2441 }
2442 
2443 static int mov_write_clap_tag(AVIOContext *pb, MOVTrack *track,
2444  uint32_t top, uint32_t bottom,
2445  uint32_t left, uint32_t right)
2446 {
2447  uint32_t cropped_width = track->par->width - left - right;
2448  uint32_t cropped_height = track->height - top - bottom;
2449  AVRational horizOff =
2450  av_sub_q((AVRational) { track->par->width - cropped_width, 2 },
2451  (AVRational) { left, 1 });
2452  AVRational vertOff =
2453  av_sub_q((AVRational) { track->height - cropped_height, 2 },
2454  (AVRational) { top, 1 });
2455 
2456  avio_wb32(pb, 40);
2457  ffio_wfourcc(pb, "clap");
2458  avio_wb32(pb, cropped_width); /* apertureWidthN */
2459  avio_wb32(pb, 1); /* apertureWidthD */
2460  avio_wb32(pb, cropped_height); /* apertureHeightN */
2461  avio_wb32(pb, 1); /* apertureHeightD */
2462 
2463  avio_wb32(pb, -horizOff.num);
2464  avio_wb32(pb, horizOff.den);
2465  avio_wb32(pb, -vertOff.num);
2466  avio_wb32(pb, vertOff.den);
2467 
2468  return 40;
2469 }
2470 
2471 static int mov_write_pasp_tag(AVIOContext *pb, MOVTrack *track)
2472 {
2473  AVRational sar;
2474  av_reduce(&sar.num, &sar.den, track->par->sample_aspect_ratio.num,
2475  track->par->sample_aspect_ratio.den, INT_MAX);
2476 
2477  avio_wb32(pb, 16);
2478  ffio_wfourcc(pb, "pasp");
2479  avio_wb32(pb, sar.num);
2480  avio_wb32(pb, sar.den);
2481  return 16;
2482 }
2483 
2484 static int mov_write_gama_tag(AVFormatContext *s, AVIOContext *pb, MOVTrack *track, double gamma)
2485 {
2486  uint32_t gama = 0;
2487  if (gamma <= 0.0)
2488  gamma = av_csp_approximate_trc_gamma(track->par->color_trc);
2489  av_log(s, AV_LOG_DEBUG, "gamma value %g\n", gamma);
2490 
2491  if (gamma > 1e-6) {
2492  gama = (uint32_t)lrint((double)(1<<16) * gamma);
2493  av_log(s, AV_LOG_DEBUG, "writing gama value %"PRId32"\n", gama);
2494 
2495  av_assert0(track->mode == MODE_MOV);
2496  avio_wb32(pb, 12);
2497  ffio_wfourcc(pb, "gama");
2498  avio_wb32(pb, gama);
2499  return 12;
2500  } else {
2501  av_log(s, AV_LOG_WARNING, "gamma value unknown, unable to write gama atom\n");
2502  }
2503  return 0;
2504 }
2505 
2506 static int mov_write_colr_tag(AVIOContext *pb, MOVTrack *track, int prefer_icc)
2507 {
2508  int64_t pos = avio_tell(pb);
2509 
2510  // Ref (MOV): https://developer.apple.com/library/mac/technotes/tn2162/_index.html#//apple_ref/doc/uid/DTS40013070-CH1-TNTAG9
2511  // Ref (MP4): ISO/IEC 14496-12:2012
2512 
2513  if (prefer_icc) {
2515  track->st->codecpar->nb_coded_side_data,
2517 
2518  if (sd) {
2519  avio_wb32(pb, 12 + sd->size);
2520  ffio_wfourcc(pb, "colr");
2521  ffio_wfourcc(pb, "prof");
2522  avio_write(pb, sd->data, sd->size);
2523  return 12 + sd->size;
2524  }
2525  else {
2526  av_log(NULL, AV_LOG_INFO, "no ICC profile found, will write nclx/nclc colour info instead\n");
2527  }
2528  }
2529 
2530  /* We should only ever be called for MOV, MP4 and AVIF. */
2531  av_assert0(track->mode == MODE_MOV || track->mode == MODE_MP4 ||
2532  track->mode == MODE_AVIF);
2533 
2534  avio_wb32(pb, 0); /* size */
2535  ffio_wfourcc(pb, "colr");
2536  if (track->mode == MODE_MP4 || track->mode == MODE_AVIF)
2537  ffio_wfourcc(pb, "nclx");
2538  else
2539  ffio_wfourcc(pb, "nclc");
2540  // Do not try to guess the color info if it is AVCOL_PRI_UNSPECIFIED.
2541  // e.g., Dolby Vision for Apple devices should be set to AVCOL_PRI_UNSPECIFIED. See
2542  // https://developer.apple.com/av-foundation/High-Dynamic-Range-Metadata-for-Apple-Devices.pdf
2543  avio_wb16(pb, track->par->color_primaries);
2544  avio_wb16(pb, track->par->color_trc);
2545  avio_wb16(pb, track->par->color_space);
2546  if (track->mode == MODE_MP4 || track->mode == MODE_AVIF) {
2547  int full_range = track->par->color_range == AVCOL_RANGE_JPEG;
2548  avio_w8(pb, full_range << 7);
2549  }
2550 
2551  return update_size(pb, pos);
2552 }
2553 
2554 static int mov_write_clli_tag(AVIOContext *pb, MOVTrack *track)
2555 {
2556  const AVPacketSideData *side_data;
2557  const AVContentLightMetadata *content_light_metadata;
2558 
2559  side_data = av_packet_side_data_get(track->st->codecpar->coded_side_data,
2560  track->st->codecpar->nb_coded_side_data,
2562  if (!side_data) {
2563  return 0;
2564  }
2565  content_light_metadata = (const AVContentLightMetadata*)side_data->data;
2566 
2567  avio_wb32(pb, 12); // size
2568  ffio_wfourcc(pb, "clli");
2569  avio_wb16(pb, content_light_metadata->MaxCLL);
2570  avio_wb16(pb, content_light_metadata->MaxFALL);
2571  return 12;
2572 }
2573 
2574 static int mov_write_mdcv_tag(AVIOContext *pb, MOVTrack *track)
2575 {
2576  const int chroma_den = 50000;
2577  const int luma_den = 10000;
2578  const AVPacketSideData *side_data;
2580 
2581  side_data = av_packet_side_data_get(track->st->codecpar->coded_side_data,
2582  track->st->codecpar->nb_coded_side_data,
2584  if (side_data)
2585  metadata = (const AVMasteringDisplayMetadata*)side_data->data;
2586  if (!metadata || !metadata->has_primaries || !metadata->has_luminance) {
2587  return 0;
2588  }
2589 
2590  avio_wb32(pb, 32); // size
2591  ffio_wfourcc(pb, "mdcv");
2592  avio_wb16(pb, rescale_rational(metadata->display_primaries[1][0], chroma_den));
2593  avio_wb16(pb, rescale_rational(metadata->display_primaries[1][1], chroma_den));
2594  avio_wb16(pb, rescale_rational(metadata->display_primaries[2][0], chroma_den));
2595  avio_wb16(pb, rescale_rational(metadata->display_primaries[2][1], chroma_den));
2596  avio_wb16(pb, rescale_rational(metadata->display_primaries[0][0], chroma_den));
2597  avio_wb16(pb, rescale_rational(metadata->display_primaries[0][1], chroma_den));
2598  avio_wb16(pb, rescale_rational(metadata->white_point[0], chroma_den));
2599  avio_wb16(pb, rescale_rational(metadata->white_point[1], chroma_den));
2600  avio_wb32(pb, rescale_rational(metadata->max_luminance, luma_den));
2601  avio_wb32(pb, rescale_rational(metadata->min_luminance, luma_den));
2602  return 32;
2603 }
2604 
2605 static int mov_write_amve_tag(AVIOContext *pb, MOVTrack *track)
2606 {
2607  const int illuminance_den = 10000;
2608  const int ambient_den = 50000;
2609  const AVPacketSideData *side_data;
2610  const AVAmbientViewingEnvironment *ambient;
2611 
2612 
2613  side_data = av_packet_side_data_get(track->st->codecpar->coded_side_data,
2614  track->st->codecpar->nb_coded_side_data,
2616 
2617  if (!side_data)
2618  return 0;
2619 
2620  ambient = (const AVAmbientViewingEnvironment*)side_data->data;
2621  if (!ambient || !ambient->ambient_illuminance.num)
2622  return 0;
2623 
2624  avio_wb32(pb, 16); // size
2625  ffio_wfourcc(pb, "amve");
2626  avio_wb32(pb, rescale_rational(ambient->ambient_illuminance, illuminance_den));
2627  avio_wb16(pb, rescale_rational(ambient->ambient_light_x, ambient_den));
2628  avio_wb16(pb, rescale_rational(ambient->ambient_light_y, ambient_den));
2629  return 16;
2630 }
2631 
2632 static void find_compressor(char * compressor_name, int len, MOVTrack *track)
2633 {
2634  AVDictionaryEntry *encoder;
2635  int xdcam_res = (track->par->width == 1280 && track->par->height == 720)
2636  || (track->par->width == 1440 && track->par->height == 1080)
2637  || (track->par->width == 1920 && track->par->height == 1080);
2638 
2639  if ((track->mode == MODE_AVIF ||
2640  track->mode == MODE_MOV ||
2641  track->mode == MODE_MP4) &&
2642  (encoder = av_dict_get(track->st->metadata, "encoder", NULL, 0))) {
2643  av_strlcpy(compressor_name, encoder->value, 32);
2644  } else if (track->par->codec_id == AV_CODEC_ID_MPEG2VIDEO && xdcam_res) {
2646  AVStream *st = track->st;
2647  int rate = defined_frame_rate(NULL, st);
2648  av_strlcatf(compressor_name, len, "XDCAM");
2649  if (track->par->format == AV_PIX_FMT_YUV422P) {
2650  av_strlcatf(compressor_name, len, " HD422");
2651  } else if(track->par->width == 1440) {
2652  av_strlcatf(compressor_name, len, " HD");
2653  } else
2654  av_strlcatf(compressor_name, len, " EX");
2655 
2656  av_strlcatf(compressor_name, len, " %d%c", track->par->height, interlaced ? 'i' : 'p');
2657 
2658  av_strlcatf(compressor_name, len, "%d", rate * (interlaced + 1));
2659  }
2660 }
2661 
2663 {
2664  int64_t pos = avio_tell(pb);
2665  // Write sane defaults:
2666  // all_ref_pics_intra = 0 : all samples can use any type of reference.
2667  // intra_pred_used = 1 : intra prediction may or may not be used.
2668  // max_ref_per_pic = 15 : reserved value to indicate that any number of
2669  // reference images can be used.
2670  uint8_t ccstValue = (0 << 7) | /* all_ref_pics_intra */
2671  (1 << 6) | /* intra_pred_used */
2672  (15 << 2); /* max_ref_per_pic */
2673  avio_wb32(pb, 0); /* size */
2674  ffio_wfourcc(pb, "ccst");
2675  avio_wb32(pb, 0); /* Version & flags */
2676  avio_w8(pb, ccstValue);
2677  avio_wb24(pb, 0); /* reserved */
2678  return update_size(pb, pos);
2679 }
2680 
2681 static int mov_write_aux_tag(AVIOContext *pb, const char *aux_type)
2682 {
2683  int64_t pos = avio_tell(pb);
2684  avio_wb32(pb, 0); /* size */
2685  ffio_wfourcc(pb, aux_type);
2686  avio_wb32(pb, 0); /* Version & flags */
2687  avio_write(pb, "urn:mpeg:mpegB:cicp:systems:auxiliary:alpha\0", 44);
2688  return update_size(pb, pos);
2689 }
2690 
2692 {
2693  int ret = AVERROR_BUG;
2694  int64_t pos = avio_tell(pb);
2695  const AVPacketSideData *sd;
2696  char compressor_name[32] = { 0 };
2697  int avid = 0;
2698 
2699  int uncompressed_ycbcr = ((track->par->codec_id == AV_CODEC_ID_RAWVIDEO && track->par->format == AV_PIX_FMT_UYVY422)
2700  || (track->par->codec_id == AV_CODEC_ID_RAWVIDEO && track->par->format == AV_PIX_FMT_YUYV422)
2701  || (track->par->codec_id == AV_CODEC_ID_RAWVIDEO && track->par->format == AV_PIX_FMT_VYU444)
2702  || (track->par->codec_id == AV_CODEC_ID_RAWVIDEO && track->par->format == AV_PIX_FMT_UYVA)
2703  || (track->par->codec_id == AV_CODEC_ID_RAWVIDEO && track->par->format == AV_PIX_FMT_V30XLE)
2705  || track->par->codec_id == AV_CODEC_ID_V308
2706  || track->par->codec_id == AV_CODEC_ID_V408
2707  || track->par->codec_id == AV_CODEC_ID_V410
2708 #endif
2709  || track->par->codec_id == AV_CODEC_ID_V210);
2710 
2711  avio_wb32(pb, 0); /* size */
2712  if (mov->encryption_scheme != MOV_ENC_NONE) {
2713  ffio_wfourcc(pb, "encv");
2714  } else {
2715  avio_wl32(pb, track->tag); // store it byteswapped
2716  }
2717  avio_wb32(pb, 0); /* Reserved */
2718  avio_wb16(pb, 0); /* Reserved */
2719  avio_wb16(pb, 1); /* Data-reference index */
2720 
2721  if (uncompressed_ycbcr) {
2722  avio_wb16(pb, 2); /* Codec stream version */
2723  } else {
2724  avio_wb16(pb, 0); /* Codec stream version */
2725  }
2726  avio_wb16(pb, 0); /* Codec stream revision (=0) */
2727  if (track->mode == MODE_MOV) {
2728  ffio_wfourcc(pb, "FFMP"); /* Vendor */
2729  if (track->par->codec_id == AV_CODEC_ID_RAWVIDEO || uncompressed_ycbcr) {
2730  avio_wb32(pb, 0); /* Temporal Quality */
2731  avio_wb32(pb, 0x400); /* Spatial Quality = lossless*/
2732  } else {
2733  avio_wb32(pb, 0x200); /* Temporal Quality = normal */
2734  avio_wb32(pb, 0x200); /* Spatial Quality = normal */
2735  }
2736  } else {
2737  ffio_fill(pb, 0, 3 * 4); /* Reserved */
2738  }
2739  avio_wb16(pb, track->par->width); /* Video width */
2740  avio_wb16(pb, track->height); /* Video height */
2741  avio_wb32(pb, 0x00480000); /* Horizontal resolution 72dpi */
2742  avio_wb32(pb, 0x00480000); /* Vertical resolution 72dpi */
2743  avio_wb32(pb, 0); /* Data size (= 0) */
2744  avio_wb16(pb, 1); /* Frame count (= 1) */
2745 
2746  find_compressor(compressor_name, 32, track);
2747  avio_w8(pb, strlen(compressor_name));
2748  avio_write(pb, compressor_name, 31);
2749 
2750  if (track->mode == MODE_MOV &&
2751  (track->par->codec_id == AV_CODEC_ID_V410 || track->par->codec_id == AV_CODEC_ID_V210))
2752  avio_wb16(pb, 0x18);
2753  else if (track->mode == MODE_MOV && track->par->bits_per_coded_sample)
2754  avio_wb16(pb, track->par->bits_per_coded_sample |
2755  (track->par->format == AV_PIX_FMT_GRAY8 ? 0x20 : 0));
2756  else
2757  avio_wb16(pb, 0x18); /* Reserved */
2758 
2759  if (track->mode == MODE_MOV && track->par->format == AV_PIX_FMT_PAL8) {
2760  int pal_size, i;
2761  avio_wb16(pb, 0); /* Color table ID */
2762  avio_wb32(pb, 0); /* Color table seed */
2763  avio_wb16(pb, 0x8000); /* Color table flags */
2764  if (track->par->bits_per_coded_sample < 0 || track->par->bits_per_coded_sample > 8)
2765  return AVERROR(EINVAL);
2766  pal_size = 1 << track->par->bits_per_coded_sample;
2767  avio_wb16(pb, pal_size - 1); /* Color table size (zero-relative) */
2768  for (i = 0; i < pal_size; i++) {
2769  uint32_t rgb = track->palette[i];
2770  uint16_t r = (rgb >> 16) & 0xff;
2771  uint16_t g = (rgb >> 8) & 0xff;
2772  uint16_t b = rgb & 0xff;
2773  avio_wb16(pb, 0);
2774  avio_wb16(pb, (r << 8) | r);
2775  avio_wb16(pb, (g << 8) | g);
2776  avio_wb16(pb, (b << 8) | b);
2777  }
2778  } else
2779  avio_wb16(pb, 0xffff); /* Reserved */
2780 
2781  if (track->tag == MKTAG('m','p','4','v'))
2782  mov_write_esds_tag(pb, track);
2783  else if (track->par->codec_id == AV_CODEC_ID_H263)
2784  mov_write_d263_tag(pb);
2785  else if (track->par->codec_id == AV_CODEC_ID_AVUI ||
2786  track->par->codec_id == AV_CODEC_ID_SVQ3) {
2787  mov_write_extradata_tag(pb, track);
2788  avio_wb32(pb, 0);
2789  } else if (track->par->codec_id == AV_CODEC_ID_DNXHD) {
2790  mov_write_avid_tag(pb, track);
2791  avid = 1;
2792  } else if (track->par->codec_id == AV_CODEC_ID_HEVC) {
2793  mov_write_hvcc_tag(mov->fc, pb, track);
2794  if (track->st->disposition & AV_DISPOSITION_MULTILAYER) {
2795  ret = mov_write_lhvc_tag(mov->fc, pb, track);
2796  if (ret < 0)
2797  av_log(mov->fc, AV_LOG_WARNING, "Not writing 'lhvC' atom for multilayer stream.\n");
2798  }
2799  } else if (track->par->codec_id == AV_CODEC_ID_VVC)
2800  mov_write_vvcc_tag(pb, track);
2801  else if (track->par->codec_id == AV_CODEC_ID_H264 && !TAG_IS_AVCI(track->tag)) {
2802  mov_write_avcc_tag(pb, track);
2803  if (track->mode == MODE_IPOD)
2805  }
2806  else if (track->par->codec_id ==AV_CODEC_ID_EVC) {
2807  mov_write_evcc_tag(pb, track);
2808  } else if (track->par->codec_id ==AV_CODEC_ID_APV) {
2809  mov_write_apvc_tag(mov->fc, pb, track);
2810  } else if (track->par->codec_id == AV_CODEC_ID_VP9) {
2811  mov_write_vpcc_tag(mov->fc, pb, track);
2812  } else if (track->par->codec_id == AV_CODEC_ID_AV1) {
2813  mov_write_av1c_tag(pb, track);
2814  } else if (track->par->codec_id == AV_CODEC_ID_VC1 && track->extradata_size[track->last_stsd_index] > 0)
2815  mov_write_dvc1_tag(pb, track);
2816  else if (track->par->codec_id == AV_CODEC_ID_VP6F ||
2817  track->par->codec_id == AV_CODEC_ID_VP6A) {
2818  /* Don't write any potential extradata here - the cropping
2819  * is signalled via the normal width/height fields. */
2820  } else if (track->par->codec_id == AV_CODEC_ID_R10K) {
2821  if (track->par->codec_tag == MKTAG('R','1','0','k'))
2822  mov_write_dpxe_tag(pb, track);
2823  } else if (track->par->codec_id == AV_CODEC_ID_AVS3) {
2824  mov_write_av3c_tag(pb, track);
2825  } else if (track->extradata_size[track->last_stsd_index] > 0)
2826  mov_write_glbl_tag(pb, track);
2827 
2828  if (track->par->codec_id != AV_CODEC_ID_H264 &&
2829  track->par->codec_id != AV_CODEC_ID_MPEG4 &&
2830  track->par->codec_id != AV_CODEC_ID_DNXHD) {
2831  int field_order = track->par->field_order;
2832 
2833  if (field_order != AV_FIELD_UNKNOWN)
2834  mov_write_fiel_tag(pb, track, field_order);
2835  }
2836 
2837  if (mov->flags & FF_MOV_FLAG_WRITE_GAMA) {
2838  if (track->mode == MODE_MOV)
2839  mov_write_gama_tag(s, pb, track, mov->gamma);
2840  else
2841  av_log(mov->fc, AV_LOG_WARNING, "Not writing 'gama' atom. Format is not MOV.\n");
2842  }
2843  if (track->mode == MODE_MOV || track->mode == MODE_MP4 || track->mode == MODE_AVIF) {
2844  int has_color_info = track->par->color_primaries != AVCOL_PRI_UNSPECIFIED &&
2845  track->par->color_trc != AVCOL_TRC_UNSPECIFIED &&
2847  if (has_color_info || mov->flags & FF_MOV_FLAG_WRITE_COLR ||
2850  int prefer_icc = mov->flags & FF_MOV_FLAG_PREFER_ICC || !has_color_info;
2851  mov_write_colr_tag(pb, track, prefer_icc);
2852  }
2853  } else if (mov->flags & FF_MOV_FLAG_WRITE_COLR) {
2854  av_log(mov->fc, AV_LOG_WARNING, "Not writing 'colr' atom. Format is not MOV or MP4 or AVIF.\n");
2855  }
2856 
2857  if (track->mode == MODE_MOV || track->mode == MODE_MP4) {
2858  mov_write_clli_tag(pb, track);
2859  mov_write_mdcv_tag(pb, track);
2860  mov_write_amve_tag(pb, track);
2861  }
2862 
2863  if (track->mode == MODE_MP4 && mov->fc->strict_std_compliance <= FF_COMPLIANCE_UNOFFICIAL) {
2865  track->st->codecpar->nb_coded_side_data,
2867  const AVPacketSideData *spherical_mapping = av_packet_side_data_get(track->st->codecpar->coded_side_data,
2868  track->st->codecpar->nb_coded_side_data,
2870  if (stereo_3d)
2871  mov_write_st3d_tag(s, pb, (AVStereo3D*)stereo_3d->data);
2872  if (spherical_mapping)
2873  mov_write_sv3d_tag(mov->fc, pb, (AVSphericalMapping*)spherical_mapping->data);
2874  }
2875 
2876  if (track->mode == MODE_MOV || (track->mode == MODE_MP4 &&
2878  const AVStereo3D *stereo3d = NULL;
2879  const AVSphericalMapping *spherical_mapping = NULL;
2880 
2882  track->st->codecpar->nb_coded_side_data,
2884  if (sd)
2885  stereo3d = (AVStereo3D *)sd->data;
2886 
2888  track->st->codecpar->nb_coded_side_data,
2890  if (sd)
2891  spherical_mapping = (AVSphericalMapping *)sd->data;
2892 
2893  if (stereo3d || spherical_mapping)
2894  mov_write_vexu_tag(s, pb, stereo3d, spherical_mapping);
2895  if (stereo3d)
2896  mov_write_hfov_tag(s, pb, stereo3d);
2897  }
2898 
2899  if (track->mode == MODE_MP4) {
2901  track->st->codecpar->nb_coded_side_data,
2903  if (dovi && mov->fc->strict_std_compliance <= FF_COMPLIANCE_UNOFFICIAL) {
2905  } else if (dovi) {
2906  av_log(mov->fc, AV_LOG_WARNING, "Not writing 'dvcC'/'dvvC' box. Requires -strict unofficial.\n");
2907  }
2908  }
2909 
2910  if (track->par->sample_aspect_ratio.den && track->par->sample_aspect_ratio.num) {
2911  mov_write_pasp_tag(pb, track);
2912  }
2913 
2915  track->st->codecpar->nb_coded_side_data,
2917  if (sd && sd->size >= sizeof(uint32_t) * 4) {
2918  uint64_t top = AV_RL32(sd->data + 0);
2919  uint64_t bottom = AV_RL32(sd->data + 4);
2920  uint64_t left = AV_RL32(sd->data + 8);
2921  uint64_t right = AV_RL32(sd->data + 12);
2922 
2923  if ((left + right) >= track->par->width ||
2924  (top + bottom) >= track->height) {
2925  av_log(s, AV_LOG_ERROR, "Invalid cropping dimensions in stream side data\n");
2926  return AVERROR(EINVAL);
2927  }
2928  if (top || bottom || left || right)
2929  mov_write_clap_tag(pb, track, top, bottom, left, right);
2930  } else if (uncompressed_ycbcr)
2931  mov_write_clap_tag(pb, track, 0, 0, 0, 0);
2932 
2933  if (mov->encryption_scheme != MOV_ENC_NONE) {
2934  ff_mov_cenc_write_sinf_tag(track, pb, mov->encryption_kid);
2935  }
2936 
2937  if (mov->write_btrt &&
2938  ((ret = mov_write_btrt_tag(pb, track)) < 0))
2939  return ret;
2940 
2941  /* extra padding for avid stsd */
2942  /* https://developer.apple.com/library/mac/documentation/QuickTime/QTFF/QTFFChap2/qtff2.html#//apple_ref/doc/uid/TP40000939-CH204-61112 */
2943  if (avid)
2944  avio_wb32(pb, 0);
2945 
2946  if (track->mode == MODE_AVIF) {
2947  mov_write_ccst_tag(pb);
2948  if (mov->nb_streams > 0 && track == &mov->tracks[1])
2949  mov_write_aux_tag(pb, "auxi");
2950  }
2951 
2952  return update_size(pb, pos);
2953 }
2954 
2955 static int mov_write_rtp_tag(AVIOContext *pb, MOVTrack *track)
2956 {
2957  int64_t pos = avio_tell(pb);
2958  avio_wb32(pb, 0); /* size */
2959  ffio_wfourcc(pb, "rtp ");
2960  avio_wb32(pb, 0); /* Reserved */
2961  avio_wb16(pb, 0); /* Reserved */
2962  avio_wb16(pb, 1); /* Data-reference index */
2963 
2964  avio_wb16(pb, 1); /* Hint track version */
2965  avio_wb16(pb, 1); /* Highest compatible version */
2966  avio_wb32(pb, track->max_packet_size); /* Max packet size */
2967 
2968  avio_wb32(pb, 12); /* size */
2969  ffio_wfourcc(pb, "tims");
2970  avio_wb32(pb, track->timescale);
2971 
2972  return update_size(pb, pos);
2973 }
2974 
2975 static int mov_write_source_reference_tag(AVIOContext *pb, MOVTrack *track, const char *reel_name)
2976 {
2977  uint64_t str_size =strlen(reel_name);
2978  int64_t pos = avio_tell(pb);
2979 
2980  if (str_size >= UINT16_MAX){
2981  av_log(NULL, AV_LOG_ERROR, "reel_name length %"PRIu64" is too large\n", str_size);
2982  avio_wb16(pb, 0);
2983  return AVERROR(EINVAL);
2984  }
2985 
2986  avio_wb32(pb, 0); /* size */
2987  ffio_wfourcc(pb, "name"); /* Data format */
2988  avio_wb16(pb, str_size); /* string size */
2989  avio_wb16(pb, track->language); /* langcode */
2990  avio_write(pb, reel_name, str_size); /* reel name */
2991  return update_size(pb,pos);
2992 }
2993 
2994 static int mov_write_tmcd_tag(AVIOContext *pb, MOVTrack *track)
2995 {
2996  int64_t pos = avio_tell(pb);
2997 #if 1
2998  int frame_duration;
2999  int nb_frames;
3000  AVDictionaryEntry *t = NULL;
3001 
3002  if (!track->st->avg_frame_rate.num || !track->st->avg_frame_rate.den) {
3003  av_log(NULL, AV_LOG_ERROR, "avg_frame_rate not set for tmcd track.\n");
3004  return AVERROR(EINVAL);
3005  } else {
3006  frame_duration = av_rescale(track->timescale, track->st->avg_frame_rate.den, track->st->avg_frame_rate.num);
3007  nb_frames = ROUNDED_DIV(track->st->avg_frame_rate.num, track->st->avg_frame_rate.den);
3008  }
3009 
3010  if (nb_frames > 255) {
3011  av_log(NULL, AV_LOG_ERROR, "fps %d is too large\n", nb_frames);
3012  return AVERROR(EINVAL);
3013  }
3014 
3015  avio_wb32(pb, 0); /* size */
3016  ffio_wfourcc(pb, "tmcd"); /* Data format */
3017  avio_wb32(pb, 0); /* Reserved */
3018  avio_wb32(pb, 1); /* Data reference index */
3019  avio_wb32(pb, 0); /* Flags */
3020  avio_wb32(pb, track->timecode_flags); /* Flags (timecode) */
3021  avio_wb32(pb, track->timescale); /* Timescale */
3022  avio_wb32(pb, frame_duration); /* Frame duration */
3023  avio_w8(pb, nb_frames); /* Number of frames */
3024  avio_w8(pb, 0); /* Reserved */
3025 
3026  t = av_dict_get(track->st->metadata, "reel_name", NULL, 0);
3027  if (t && utf8len(t->value) && track->mode != MODE_MP4)
3028  mov_write_source_reference_tag(pb, track, t->value);
3029  else
3030  avio_wb16(pb, 0); /* zero size */
3031 #else
3032 
3033  avio_wb32(pb, 0); /* size */
3034  ffio_wfourcc(pb, "tmcd"); /* Data format */
3035  avio_wb32(pb, 0); /* Reserved */
3036  avio_wb32(pb, 1); /* Data reference index */
3037  if (track->par->extradata_size)
3038  avio_write(pb, track->par->extradata, track->par->extradata_size);
3039 #endif
3040  return update_size(pb, pos);
3041 }
3042 
3043 static int mov_write_gpmd_tag(AVIOContext *pb, const MOVTrack *track)
3044 {
3045  int64_t pos = avio_tell(pb);
3046  avio_wb32(pb, 0); /* size */
3047  ffio_wfourcc(pb, "gpmd");
3048  avio_wb32(pb, 0); /* Reserved */
3049  avio_wb16(pb, 0); /* Reserved */
3050  avio_wb16(pb, 1); /* Data-reference index */
3051  avio_wb32(pb, 0); /* Reserved */
3052  return update_size(pb, pos);
3053 }
3054 
3056 {
3057  int64_t pos = avio_tell(pb);
3058  int ret = 0;
3059  avio_wb32(pb, 0); /* size */
3060  ffio_wfourcc(pb, "stsd");
3061  avio_wb32(pb, 0); /* version & flags */
3062  avio_wb32(pb, track->stsd_count);
3063 
3064  int stsd_index_back = track->last_stsd_index;
3065  for (track->last_stsd_index = 0;
3066  track->last_stsd_index < track->stsd_count;
3067  track->last_stsd_index++) {
3068  if (track->par->codec_type == AVMEDIA_TYPE_VIDEO)
3069  ret = mov_write_video_tag(s, pb, mov, track);
3070  else if (track->par->codec_type == AVMEDIA_TYPE_AUDIO)
3071  ret = mov_write_audio_tag(s, pb, mov, track);
3072  else if (track->par->codec_type == AVMEDIA_TYPE_SUBTITLE)
3073  ret = mov_write_subtitle_tag(s, pb, track);
3074  else if (track->par->codec_tag == MKTAG('r','t','p',' '))
3075  ret = mov_write_rtp_tag(pb, track);
3076  else if (track->par->codec_tag == MKTAG('t','m','c','d'))
3077  ret = mov_write_tmcd_tag(pb, track);
3078  else if (track->par->codec_tag == MKTAG('g','p','m','d'))
3079  ret = mov_write_gpmd_tag(pb, track);
3080 
3081  if (ret < 0)
3082  return ret;
3083  }
3084 
3085  track->last_stsd_index = stsd_index_back;
3086 
3087  return update_size(pb, pos);
3088 }
3089 
3091 {
3092  MOVMuxContext *mov = s->priv_data;
3093  MOVCtts *ctts_entries;
3094  uint32_t entries = 0;
3095  uint32_t atom_size;
3096  int i;
3097 
3098  ctts_entries = av_malloc_array((track->entry + 1), sizeof(*ctts_entries)); /* worst case */
3099  if (!ctts_entries)
3100  return AVERROR(ENOMEM);
3101  ctts_entries[0].count = 1;
3102  ctts_entries[0].offset = track->cluster[0].cts;
3103  for (i = 1; i < track->entry; i++) {
3104  if (track->cluster[i].cts == ctts_entries[entries].offset) {
3105  ctts_entries[entries].count++; /* compress */
3106  } else {
3107  entries++;
3108  ctts_entries[entries].offset = track->cluster[i].cts;
3109  ctts_entries[entries].count = 1;
3110  }
3111  }
3112  entries++; /* last one */
3113  atom_size = 16 + (entries * 8);
3114  avio_wb32(pb, atom_size); /* size */
3115  ffio_wfourcc(pb, "ctts");
3117  avio_w8(pb, 1); /* version */
3118  else
3119  avio_w8(pb, 0); /* version */
3120  avio_wb24(pb, 0); /* flags */
3121  avio_wb32(pb, entries); /* entry count */
3122  for (i = 0; i < entries; i++) {
3123  avio_wb32(pb, ctts_entries[i].count);
3124  avio_wb32(pb, ctts_entries[i].offset);
3125  }
3126  av_free(ctts_entries);
3127  return atom_size;
3128 }
3129 
3130 /* Time to sample atom */
3131 static int mov_write_stts_tag(AVIOContext *pb, MOVTrack *track)
3132 {
3133  MOVStts *stts_entries = NULL;
3134  uint32_t entries = -1;
3135  uint32_t atom_size;
3136  int i;
3137 
3138  if (track->par->codec_type == AVMEDIA_TYPE_AUDIO && !track->audio_vbr) {
3139  stts_entries = av_malloc(sizeof(*stts_entries)); /* one entry */
3140  if (!stts_entries)
3141  return AVERROR(ENOMEM);
3142  stts_entries[0].count = track->sample_count;
3143  stts_entries[0].duration = 1;
3144  entries = 1;
3145  } else {
3146  if (track->entry) {
3147  stts_entries = av_malloc_array(track->entry, sizeof(*stts_entries)); /* worst case */
3148  if (!stts_entries)
3149  return AVERROR(ENOMEM);
3150  }
3151  for (i = 0; i < track->entry; i++) {
3152  int duration = get_cluster_duration(track, i);
3153 #if CONFIG_IAMFENC
3154  if (track->iamf && track->par->codec_id == AV_CODEC_ID_OPUS)
3155  duration = av_rescale(duration, 48000, track->par->sample_rate);
3156 #endif
3157  if (i && duration == stts_entries[entries].duration) {
3158  stts_entries[entries].count++; /* compress */
3159  } else {
3160  entries++;
3161  stts_entries[entries].duration = duration;
3162  stts_entries[entries].count = 1;
3163  }
3164  }
3165  entries++; /* last one */
3166  }
3167  atom_size = 16 + (entries * 8);
3168  avio_wb32(pb, atom_size); /* size */
3169  ffio_wfourcc(pb, "stts");
3170  avio_wb32(pb, 0); /* version & flags */
3171  avio_wb32(pb, entries); /* entry count */
3172  for (i = 0; i < entries; i++) {
3173  avio_wb32(pb, stts_entries[i].count);
3174  avio_wb32(pb, stts_entries[i].duration);
3175  }
3176  av_free(stts_entries);
3177  return atom_size;
3178 }
3179 
3181 {
3182  avio_wb32(pb, 28); /* size */
3183  ffio_wfourcc(pb, "dref");
3184  avio_wb32(pb, 0); /* version & flags */
3185  avio_wb32(pb, 1); /* entry count */
3186 
3187  avio_wb32(pb, 0xc); /* size */
3188  //FIXME add the alis and rsrc atom
3189  ffio_wfourcc(pb, "url ");
3190  avio_wb32(pb, 1); /* version & flags */
3191 
3192  return 28;
3193 }
3194 
3196 {
3197  struct sgpd_entry {
3198  int count;
3199  int16_t roll_distance;
3200  int group_description_index;
3201  };
3202 
3203  struct sgpd_entry *sgpd_entries = NULL;
3204  int entries = -1;
3205  int group = 0;
3206  int i, j;
3207 
3208  const int OPUS_SEEK_PREROLL_MS = 80;
3209  int roll_samples = av_rescale_q(OPUS_SEEK_PREROLL_MS,
3210  (AVRational){1, 1000},
3211  (AVRational){1, 48000});
3212 
3213  if (!track->entry)
3214  return 0;
3215 
3216  sgpd_entries = av_malloc_array(track->entry, sizeof(*sgpd_entries));
3217  if (!sgpd_entries)
3218  return AVERROR(ENOMEM);
3219 
3221 
3222  if (track->par->codec_id == AV_CODEC_ID_OPUS) {
3223  for (i = 0; i < track->entry; i++) {
3224  int roll_samples_remaining = roll_samples;
3225  int distance = 0;
3226  for (j = i - 1; j >= 0; j--) {
3227  roll_samples_remaining -= get_cluster_duration(track, j);
3228  distance++;
3229  if (roll_samples_remaining <= 0)
3230  break;
3231  }
3232  /* We don't have enough preceding samples to compute a valid
3233  roll_distance here, so this sample can't be independently
3234  decoded. */
3235  if (roll_samples_remaining > 0)
3236  distance = 0;
3237  /* Verify distance is a maximum of 32 (2.5ms) packets. */
3238  if (distance > 32)
3239  return AVERROR_INVALIDDATA;
3240  if (i && distance == sgpd_entries[entries].roll_distance) {
3241  sgpd_entries[entries].count++;
3242  } else {
3243  entries++;
3244  sgpd_entries[entries].count = 1;
3245  sgpd_entries[entries].roll_distance = distance;
3246  sgpd_entries[entries].group_description_index = distance ? ++group : 0;
3247  }
3248  }
3249  } else {
3250  entries++;
3251  sgpd_entries[entries].count = track->sample_count;
3252  sgpd_entries[entries].roll_distance = 1;
3253  sgpd_entries[entries].group_description_index = ++group;
3254  }
3255  entries++;
3256 
3257  if (!group) {
3258  av_free(sgpd_entries);
3259  return 0;
3260  }
3261 
3262  /* Write sgpd tag */
3263  avio_wb32(pb, 24 + (group * 2)); /* size */
3264  ffio_wfourcc(pb, "sgpd");
3265  avio_wb32(pb, 1 << 24); /* fullbox */
3266  ffio_wfourcc(pb, "roll");
3267  avio_wb32(pb, 2); /* default_length */
3268  avio_wb32(pb, group); /* entry_count */
3269  for (i = 0; i < entries; i++) {
3270  if (sgpd_entries[i].group_description_index) {
3271  avio_wb16(pb, -sgpd_entries[i].roll_distance); /* roll_distance */
3272  }
3273  }
3274 
3275  /* Write sbgp tag */
3276  avio_wb32(pb, 20 + (entries * 8)); /* size */
3277  ffio_wfourcc(pb, "sbgp");
3278  avio_wb32(pb, 0); /* fullbox */
3279  ffio_wfourcc(pb, "roll");
3280  avio_wb32(pb, entries); /* entry_count */
3281  for (i = 0; i < entries; i++) {
3282  avio_wb32(pb, sgpd_entries[i].count); /* sample_count */
3283  avio_wb32(pb, sgpd_entries[i].group_description_index); /* group_description_index */
3284  }
3285 
3286  av_free(sgpd_entries);
3287  return 0;
3288 }
3289 
3291 {
3292  int64_t pos = avio_tell(pb);
3293  int ret = 0;
3294 
3295  avio_wb32(pb, 0); /* size */
3296  ffio_wfourcc(pb, "stbl");
3297  if ((ret = mov_write_stsd_tag(s, pb, mov, track)) < 0)
3298  return ret;
3299  mov_write_stts_tag(pb, track);
3300  if ((track->par->codec_type == AVMEDIA_TYPE_VIDEO ||
3301  track->par->codec_id == AV_CODEC_ID_TRUEHD ||
3303  (track->par->codec_id == AV_CODEC_ID_AAC && track->par->profile == AV_PROFILE_AAC_USAC) ||
3304  track->par->codec_tag == MKTAG('r','t','p',' ')) &&
3305  track->has_keyframes && track->has_keyframes < track->entry)
3306  mov_write_stss_tag(pb, track, MOV_SYNC_SAMPLE);
3307  if (track->par->codec_type == AVMEDIA_TYPE_VIDEO && track->has_disposable && track->entry)
3308  mov_write_sdtp_tag(pb, track);
3309  if (track->mode == MODE_MOV && track->flags & MOV_TRACK_STPS)
3311  if (track->par->codec_type == AVMEDIA_TYPE_VIDEO &&
3312  track->flags & MOV_TRACK_CTTS && track->entry) {
3313 
3314  if ((ret = mov_write_ctts_tag(s, pb, track)) < 0)
3315  return ret;
3316  }
3317  mov_write_stsc_tag(pb, track);
3318  mov_write_stsz_tag(pb, track);
3319  mov_write_stco_tag(pb, track);
3320  if (track->cenc.aes_ctr && !(mov->flags & FF_MOV_FLAG_FRAGMENT)) {
3321  ff_mov_cenc_write_stbl_atoms(&track->cenc, pb, 0);
3322  }
3323  if (track->par->codec_id == AV_CODEC_ID_OPUS || track->par->codec_id == AV_CODEC_ID_AAC) {
3324  mov_preroll_write_stbl_atoms(pb, track);
3325  }
3326  return update_size(pb, pos);
3327 }
3328 
3330 {
3331  int64_t pos = avio_tell(pb);
3332  avio_wb32(pb, 0); /* size */
3333  ffio_wfourcc(pb, "dinf");
3334  mov_write_dref_tag(pb);
3335  return update_size(pb, pos);
3336 }
3337 
3339 {
3340  avio_wb32(pb, 12);
3341  ffio_wfourcc(pb, "nmhd");
3342  avio_wb32(pb, 0);
3343  return 12;
3344 }
3345 
3347 {
3348  avio_wb32(pb, 12);
3349  ffio_wfourcc(pb, "sthd");
3350  avio_wb32(pb, 0);
3351  return 12;
3352 }
3353 
3354 static int mov_write_tcmi_tag(AVIOContext *pb, MOVTrack *track)
3355 {
3356  int64_t pos = avio_tell(pb);
3357  const char *font = "Lucida Grande";
3358  avio_wb32(pb, 0); /* size */
3359  ffio_wfourcc(pb, "tcmi"); /* timecode media information atom */
3360  avio_wb32(pb, 0); /* version & flags */
3361  avio_wb16(pb, 0); /* text font */
3362  avio_wb16(pb, 0); /* text face */
3363  avio_wb16(pb, 12); /* text size */
3364  avio_wb16(pb, 0); /* (unknown, not in the QT specs...) */
3365  avio_wb16(pb, 0x0000); /* text color (red) */
3366  avio_wb16(pb, 0x0000); /* text color (green) */
3367  avio_wb16(pb, 0x0000); /* text color (blue) */
3368  avio_wb16(pb, 0xffff); /* background color (red) */
3369  avio_wb16(pb, 0xffff); /* background color (green) */
3370  avio_wb16(pb, 0xffff); /* background color (blue) */
3371  avio_w8(pb, strlen(font)); /* font len (part of the pascal string) */
3372  avio_write(pb, font, strlen(font)); /* font name */
3373  return update_size(pb, pos);
3374 }
3375 
3376 static int mov_write_gmhd_tag(AVIOContext *pb, MOVTrack *track)
3377 {
3378  int64_t pos = avio_tell(pb);
3379  avio_wb32(pb, 0); /* size */
3380  ffio_wfourcc(pb, "gmhd");
3381  avio_wb32(pb, 0x18); /* gmin size */
3382  ffio_wfourcc(pb, "gmin");/* generic media info */
3383  avio_wb32(pb, 0); /* version & flags */
3384  avio_wb16(pb, 0x40); /* graphics mode = */
3385  avio_wb16(pb, 0x8000); /* opColor (r?) */
3386  avio_wb16(pb, 0x8000); /* opColor (g?) */
3387  avio_wb16(pb, 0x8000); /* opColor (b?) */
3388  avio_wb16(pb, 0); /* balance */
3389  avio_wb16(pb, 0); /* reserved */
3390 
3391  /*
3392  * This special text atom is required for
3393  * Apple Quicktime chapters. The contents
3394  * don't appear to be documented, so the
3395  * bytes are copied verbatim.
3396  */
3397  if (track->tag != MKTAG('c','6','0','8')) {
3398  avio_wb32(pb, 0x2C); /* size */
3399  ffio_wfourcc(pb, "text");
3400  avio_wb16(pb, 0x01);
3401  avio_wb32(pb, 0x00);
3402  avio_wb32(pb, 0x00);
3403  avio_wb32(pb, 0x00);
3404  avio_wb32(pb, 0x01);
3405  avio_wb32(pb, 0x00);
3406  avio_wb32(pb, 0x00);
3407  avio_wb32(pb, 0x00);
3408  avio_wb32(pb, 0x00004000);
3409  avio_wb16(pb, 0x0000);
3410  }
3411 
3412  if (track->par->codec_tag == MKTAG('t','m','c','d')) {
3413  int64_t tmcd_pos = avio_tell(pb);
3414  avio_wb32(pb, 0); /* size */
3415  ffio_wfourcc(pb, "tmcd");
3416  mov_write_tcmi_tag(pb, track);
3417  update_size(pb, tmcd_pos);
3418  } else if (track->par->codec_tag == MKTAG('g','p','m','d')) {
3419  int64_t gpmd_pos = avio_tell(pb);
3420  avio_wb32(pb, 0); /* size */
3421  ffio_wfourcc(pb, "gpmd");
3422  avio_wb32(pb, 0); /* version */
3423  update_size(pb, gpmd_pos);
3424  }
3425  return update_size(pb, pos);
3426 }
3427 
3429 {
3430  avio_wb32(pb, 16); /* size */
3431  ffio_wfourcc(pb, "smhd");
3432  avio_wb32(pb, 0); /* version & flags */
3433  avio_wb16(pb, 0); /* reserved (balance, normally = 0) */
3434  avio_wb16(pb, 0); /* reserved */
3435  return 16;
3436 }
3437 
3439 {
3440  avio_wb32(pb, 0x14); /* size (always 0x14) */
3441  ffio_wfourcc(pb, "vmhd");
3442  avio_wb32(pb, 0x01); /* version & flags */
3443  avio_wb64(pb, 0); /* reserved (graphics mode = copy) */
3444  return 0x14;
3445 }
3446 
3447 static int is_clcp_track(MOVTrack *track)
3448 {
3449  return track->tag == MKTAG('c','7','0','8') ||
3450  track->tag == MKTAG('c','6','0','8');
3451 }
3452 
3454 {
3455  MOVMuxContext *mov = s->priv_data;
3456  const char *hdlr, *descr = NULL, *hdlr_type = NULL;
3457  int64_t pos = avio_tell(pb);
3458  size_t descr_len;
3459 
3460  hdlr = "dhlr";
3461  hdlr_type = "url ";
3462  descr = "DataHandler";
3463 
3464  if (track) {
3465  hdlr = (track->mode == MODE_MOV) ? "mhlr" : "\0\0\0\0";
3466  if (track->par->codec_type == AVMEDIA_TYPE_VIDEO) {
3467  if (track->mode == MODE_AVIF) {
3468  hdlr_type = (track == &mov->tracks[0]) ? "pict" : "auxv";
3469  descr = "PictureHandler";
3470  } else {
3471  hdlr_type = "vide";
3472  descr = "VideoHandler";
3473  }
3474  } else if (track->par->codec_type == AVMEDIA_TYPE_AUDIO) {
3475  hdlr_type = "soun";
3476  descr = "SoundHandler";
3477  } else if (track->par->codec_type == AVMEDIA_TYPE_SUBTITLE) {
3478  if (is_clcp_track(track)) {
3479  hdlr_type = "clcp";
3480  descr = "ClosedCaptionHandler";
3481  } else {
3482  if (track->tag == MKTAG('t','x','3','g')) {
3483  hdlr_type = "sbtl";
3484  } else if (track->tag == MKTAG('m','p','4','s')) {
3485  hdlr_type = "subp";
3486  } else if (track->tag == MOV_MP4_TTML_TAG) {
3487  hdlr_type = "subt";
3488  } else {
3489  hdlr_type = "text";
3490  }
3491  descr = "SubtitleHandler";
3492  }
3493  } else if (track->par->codec_tag == MKTAG('r','t','p',' ')) {
3494  hdlr_type = "hint";
3495  descr = "HintHandler";
3496  } else if (track->par->codec_tag == MKTAG('t','m','c','d')) {
3497  hdlr_type = "tmcd";
3498  descr = "TimeCodeHandler";
3499  } else if (track->par->codec_tag == MKTAG('g','p','m','d')) {
3500  hdlr_type = "meta";
3501  descr = "GoPro MET"; // GoPro Metadata
3502  } else {
3504  "Unknown hdlr_type for %s, writing dummy values\n",
3505  av_fourcc2str(track->par->codec_tag));
3506  }
3507  if (track->st) {
3508  // hdlr.name is used by some players to identify the content title
3509  // of the track. So if an alternate handler description is
3510  // specified, use it.
3511  AVDictionaryEntry *t;
3512  t = av_dict_get(track->st->metadata, "handler_name", NULL, 0);
3513  if (t && utf8len(t->value))
3514  descr = t->value;
3515  }
3516  }
3517 
3518  if (mov->empty_hdlr_name) /* expressly allowed by QTFF and not prohibited in ISO 14496-12 8.4.3.3 */
3519  descr = "";
3520 
3521  avio_wb32(pb, 0); /* size */
3522  ffio_wfourcc(pb, "hdlr");
3523  avio_wb32(pb, 0); /* Version & flags */
3524  avio_write(pb, hdlr, 4); /* handler */
3525  ffio_wfourcc(pb, hdlr_type); /* handler type */
3526  avio_wb32(pb, 0); /* reserved */
3527  avio_wb32(pb, 0); /* reserved */
3528  avio_wb32(pb, 0); /* reserved */
3529  descr_len = strlen(descr);
3530  if (!track || track->mode == MODE_MOV)
3531  avio_w8(pb, descr_len); /* pascal string */
3532  avio_write(pb, descr, descr_len); /* handler description */
3533  if (track && track->mode != MODE_MOV)
3534  avio_w8(pb, 0); /* c string */
3535  return update_size(pb, pos);
3536 }
3537 
3538 static int mov_write_pitm_tag(AVIOContext *pb, int item_id)
3539 {
3540  int64_t pos = avio_tell(pb);
3541  avio_wb32(pb, 0); /* size */
3542  ffio_wfourcc(pb, "pitm");
3543  avio_wb32(pb, 0); /* Version & flags */
3544  avio_wb16(pb, item_id); /* item_id */
3545  return update_size(pb, pos);
3546 }
3547 
3549 {
3550  int64_t pos = avio_tell(pb);
3551  avio_wb32(pb, 0); /* size */
3552  ffio_wfourcc(pb, "iloc");
3553  avio_wb32(pb, 0); /* Version & flags */
3554  avio_w8(pb, (4 << 4) + 4); /* offset_size(4) and length_size(4) */
3555  avio_w8(pb, 0); /* base_offset_size(4) and reserved(4) */
3556  avio_wb16(pb, mov->nb_streams); /* item_count */
3557 
3558  for (int i = 0; i < mov->nb_streams; i++) {
3559  avio_wb16(pb, i + 1); /* item_id */
3560  avio_wb16(pb, 0); /* data_reference_index */
3561  avio_wb16(pb, 1); /* extent_count */
3562  mov->avif_extent_pos[i] = avio_tell(pb);
3563  avio_wb32(pb, 0); /* extent_offset (written later) */
3564  // For animated AVIF, we simply write the first packet's size.
3565  avio_wb32(pb, mov->avif_extent_length[i]); /* extent_length */
3566  }
3567 
3568  return update_size(pb, pos);
3569 }
3570 
3572 {
3573  int64_t iinf_pos = avio_tell(pb);
3574  avio_wb32(pb, 0); /* size */
3575  ffio_wfourcc(pb, "iinf");
3576  avio_wb32(pb, 0); /* Version & flags */
3577  avio_wb16(pb, mov->nb_streams); /* entry_count */
3578 
3579  for (int i = 0; i < mov->nb_streams; i++) {
3580  int64_t infe_pos = avio_tell(pb);
3581  avio_wb32(pb, 0); /* size */
3582  ffio_wfourcc(pb, "infe");
3583  avio_w8(pb, 0x2); /* Version */
3584  avio_wb24(pb, 0); /* flags */
3585  avio_wb16(pb, i + 1); /* item_id */
3586  avio_wb16(pb, 0); /* item_protection_index */
3587  avio_write(pb, "av01", 4); /* item_type */
3588  avio_write(pb, !i ? "Color\0" : "Alpha\0", 6); /* item_name */
3589  update_size(pb, infe_pos);
3590  }
3591 
3592  return update_size(pb, iinf_pos);
3593 }
3594 
3595 
3597 {
3598  int64_t auxl_pos;
3599  int64_t iref_pos = avio_tell(pb);
3600  avio_wb32(pb, 0); /* size */
3601  ffio_wfourcc(pb, "iref");
3602  avio_wb32(pb, 0); /* Version & flags */
3603 
3604  auxl_pos = avio_tell(pb);
3605  avio_wb32(pb, 0); /* size */
3606  ffio_wfourcc(pb, "auxl");
3607  avio_wb16(pb, 2); /* from_item_ID */
3608  avio_wb16(pb, 1); /* reference_count */
3609  avio_wb16(pb, 1); /* to_item_ID */
3610  update_size(pb, auxl_pos);
3611 
3612  return update_size(pb, iref_pos);
3613 }
3614 
3616  int stream_index)
3617 {
3618  int64_t pos = avio_tell(pb);
3619  avio_wb32(pb, 0); /* size */
3620  ffio_wfourcc(pb, "ispe");
3621  avio_wb32(pb, 0); /* Version & flags */
3622  avio_wb32(pb, s->streams[stream_index]->codecpar->width); /* image_width */
3623  avio_wb32(pb, s->streams[stream_index]->codecpar->height); /* image_height */
3624  return update_size(pb, pos);
3625 }
3626 
3628  int stream_index)
3629 {
3630  int64_t pos = avio_tell(pb);
3631  const AVPixFmtDescriptor *pixdesc =
3632  av_pix_fmt_desc_get(s->streams[stream_index]->codecpar->format);
3633  avio_wb32(pb, 0); /* size */
3634  ffio_wfourcc(pb, "pixi");
3635  avio_wb32(pb, 0); /* Version & flags */
3636  avio_w8(pb, pixdesc->nb_components); /* num_channels */
3637  for (int i = 0; i < pixdesc->nb_components; ++i) {
3638  avio_w8(pb, pixdesc->comp[i].depth); /* bits_per_channel */
3639  }
3640  return update_size(pb, pos);
3641 }
3642 
3644 {
3645  int64_t pos = avio_tell(pb);
3646  avio_wb32(pb, 0); /* size */
3647  ffio_wfourcc(pb, "ipco");
3648  for (int i = 0; i < mov->nb_streams; i++) {
3649  mov_write_ispe_tag(pb, mov, s, i);
3650  mov_write_pixi_tag(pb, mov, s, i);
3651  mov_write_av1c_tag(pb, &mov->tracks[i]);
3652  if (!i)
3653  mov_write_colr_tag(pb, &mov->tracks[0], 0);
3654  else
3655  mov_write_aux_tag(pb, "auxC");
3656  }
3657  return update_size(pb, pos);
3658 }
3659 
3661 {
3662  int64_t pos = avio_tell(pb);
3663  avio_wb32(pb, 0); /* size */
3664  ffio_wfourcc(pb, "ipma");
3665  avio_wb32(pb, 0); /* Version & flags */
3666  avio_wb32(pb, mov->nb_streams); /* entry_count */
3667 
3668  for (int i = 0, index = 1; i < mov->nb_streams; i++) {
3669  avio_wb16(pb, i + 1); /* item_ID */
3670  avio_w8(pb, 4); /* association_count */
3671 
3672  // ispe association.
3673  avio_w8(pb, index++); /* essential and property_index */
3674  // pixi association.
3675  avio_w8(pb, index++); /* essential and property_index */
3676  // av1C association.
3677  avio_w8(pb, 0x80 | index++); /* essential and property_index */
3678  // colr/auxC association.
3679  avio_w8(pb, index++); /* essential and property_index */
3680  }
3681  return update_size(pb, pos);
3682 }
3683 
3685 {
3686  int64_t pos = avio_tell(pb);
3687  avio_wb32(pb, 0); /* size */
3688  ffio_wfourcc(pb, "iprp");
3689  mov_write_ipco_tag(pb, mov, s);
3690  mov_write_ipma_tag(pb, mov, s);
3691  return update_size(pb, pos);
3692 }
3693 
3695 {
3696  /* This atom must be present, but leaving the values at zero
3697  * seems harmless. */
3698  avio_wb32(pb, 28); /* size */
3699  ffio_wfourcc(pb, "hmhd");
3700  avio_wb32(pb, 0); /* version, flags */
3701  avio_wb16(pb, 0); /* maxPDUsize */
3702  avio_wb16(pb, 0); /* avgPDUsize */
3703  avio_wb32(pb, 0); /* maxbitrate */
3704  avio_wb32(pb, 0); /* avgbitrate */
3705  avio_wb32(pb, 0); /* reserved */
3706  return 28;
3707 }
3708 
3710 {
3711  int64_t pos = avio_tell(pb);
3712  int ret;
3713 
3714  avio_wb32(pb, 0); /* size */
3715  ffio_wfourcc(pb, "minf");
3716  if (track->par->codec_type == AVMEDIA_TYPE_VIDEO)
3717  mov_write_vmhd_tag(pb);
3718  else if (track->par->codec_type == AVMEDIA_TYPE_AUDIO)
3719  mov_write_smhd_tag(pb);
3720  else if (track->par->codec_type == AVMEDIA_TYPE_SUBTITLE) {
3721  if (track->tag == MKTAG('t','e','x','t') || is_clcp_track(track)) {
3722  mov_write_gmhd_tag(pb, track);
3723  } else if (track->tag == MOV_MP4_TTML_TAG) {
3724  mov_write_sthd_tag(pb);
3725  } else {
3726  mov_write_nmhd_tag(pb);
3727  }
3728  } else if (track->tag == MKTAG('r','t','p',' ')) {
3729  mov_write_hmhd_tag(pb);
3730  } else if (track->tag == MKTAG('t','m','c','d')) {
3731  if (track->mode != MODE_MOV)
3732  mov_write_nmhd_tag(pb);
3733  else
3734  mov_write_gmhd_tag(pb, track);
3735  } else if (track->tag == MKTAG('g','p','m','d')) {
3736  mov_write_gmhd_tag(pb, track);
3737  }
3738  if (track->mode == MODE_MOV) /* ISO 14496-12 8.4.3.1 specifies hdlr only within mdia or meta boxes */
3739  mov_write_hdlr_tag(s, pb, NULL);
3740  mov_write_dinf_tag(pb);
3741  if ((ret = mov_write_stbl_tag(s, pb, mov, track)) < 0)
3742  return ret;
3743  return update_size(pb, pos);
3744 }
3745 
3746 static void get_pts_range(MOVMuxContext *mov, MOVTrack *track,
3747  int64_t *start, int64_t *end)
3748 {
3749  if (track->tag == MKTAG('t','m','c','d') && mov->nb_meta_tmcd) {
3750  // tmcd tracks gets track_duration set in mov_write_moov_tag from
3751  // another track's duration, while the end_pts may be left at zero.
3752  // Calculate the pts duration for that track instead.
3753  get_pts_range(mov, &mov->tracks[track->src_track], start, end);
3754  *start = av_rescale(*start, track->timescale,
3755  mov->tracks[track->src_track].timescale);
3756  *end = av_rescale(*end, track->timescale,
3757  mov->tracks[track->src_track].timescale);
3758  return;
3759  }
3760  if (track->end_pts != AV_NOPTS_VALUE &&
3761  track->start_dts != AV_NOPTS_VALUE &&
3762  track->start_cts != AV_NOPTS_VALUE) {
3763  *start = track->start_dts + track->start_cts;
3764  *end = track->end_pts;
3765  return;
3766  }
3767  *start = 0;
3768  *end = track->track_duration;
3769 }
3770 
3772 {
3773  int64_t start, end;
3774  get_pts_range(mov, track, &start, &end);
3775  return end - start;
3776 }
3777 
3778 // Calculate the actual duration of the track, after edits.
3779 // If it starts with a pts < 0, that is removed by the edit list.
3780 // If it starts with a pts > 0, the edit list adds a delay before that.
3781 // Thus, with edit lists enabled, the post-edit output of the file is
3782 // starting with pts=0.
3784 {
3785  int64_t start, end;
3786  get_pts_range(mov, track, &start, &end);
3787  if (mov->use_editlist != 0)
3788  start = 0;
3789  return end - start;
3790 }
3791 
3793 {
3794  if (track && track->mode == MODE_ISM)
3795  return 1;
3796  if (duration < INT32_MAX)
3797  return 0;
3798  return 1;
3799 }
3800 
3802  MOVTrack *track)
3803 {
3805  int version = mov_mdhd_mvhd_tkhd_version(mov, track, duration);
3806 
3807  (version == 1) ? avio_wb32(pb, 44) : avio_wb32(pb, 32); /* size */
3808  ffio_wfourcc(pb, "mdhd");
3809  avio_w8(pb, version);
3810  avio_wb24(pb, 0); /* flags */
3811  if (version == 1) {
3812  avio_wb64(pb, track->time);
3813  avio_wb64(pb, track->time);
3814  } else {
3815  avio_wb32(pb, track->time); /* creation time */
3816  avio_wb32(pb, track->time); /* modification time */
3817  }
3818  avio_wb32(pb, track->timescale); /* time scale (sample rate for audio) */
3819  if (!track->entry && mov->mode == MODE_ISM)
3820  (version == 1) ? avio_wb64(pb, UINT64_C(0xffffffffffffffff)) : avio_wb32(pb, 0xffffffff);
3821  else if (!track->entry)
3822  (version == 1) ? avio_wb64(pb, 0) : avio_wb32(pb, 0);
3823  else
3824  (version == 1) ? avio_wb64(pb, duration) : avio_wb32(pb, duration); /* duration */
3825  avio_wb16(pb, track->language); /* language */
3826  avio_wb16(pb, 0); /* reserved (quality) */
3827 
3828  if (version != 0 && track->mode == MODE_MOV) {
3830  "FATAL error, file duration too long for timebase, this file will not be\n"
3831  "playable with QuickTime. Choose a different timebase with "
3832  "-video_track_timescale or a different container format\n");
3833  }
3834 
3835  return 32;
3836 }
3837 
3839  MOVMuxContext *mov, MOVTrack *track)
3840 {
3841  int64_t pos = avio_tell(pb);
3842  int ret;
3843 
3844  avio_wb32(pb, 0); /* size */
3845  ffio_wfourcc(pb, "mdia");
3846  mov_write_mdhd_tag(pb, mov, track);
3847  mov_write_hdlr_tag(s, pb, track);
3848  if ((ret = mov_write_minf_tag(s, pb, mov, track)) < 0)
3849  return ret;
3850  return update_size(pb, pos);
3851 }
3852 
3853 /* transformation matrix
3854  |a b u|
3855  |c d v|
3856  |tx ty w| */
3857 static void write_matrix(AVIOContext *pb, int16_t a, int16_t b, int16_t c,
3858  int16_t d, int16_t tx, int16_t ty)
3859 {
3860  avio_wb32(pb, a << 16); /* 16.16 format */
3861  avio_wb32(pb, b << 16); /* 16.16 format */
3862  avio_wb32(pb, 0); /* u in 2.30 format */
3863  avio_wb32(pb, c << 16); /* 16.16 format */
3864  avio_wb32(pb, d << 16); /* 16.16 format */
3865  avio_wb32(pb, 0); /* v in 2.30 format */
3866  avio_wb32(pb, tx << 16); /* 16.16 format */
3867  avio_wb32(pb, ty << 16); /* 16.16 format */
3868  avio_wb32(pb, 1 << 30); /* w in 2.30 format */
3869 }
3870 
3872  MOVTrack *track, AVStream *st)
3873 {
3875  mov->movie_timescale, track->timescale,
3876  AV_ROUND_UP);
3877  int version;
3879  int group = 0;
3880 
3881  uint32_t *display_matrix = NULL;
3882  int i;
3883 
3884  if (mov->mode == MODE_AVIF)
3885  if (!mov->avif_loop_count)
3886  duration = INT64_MAX;
3887  else
3888  duration *= mov->avif_loop_count;
3889 
3890  if (st) {
3891  const AVPacketSideData *sd;
3892  if (mov->per_stream_grouping)
3893  group = st->index;
3894  else
3895  group = st->codecpar->codec_type;
3896 
3900  if (sd && sd->size == 9 * sizeof(*display_matrix))
3901  display_matrix = (uint32_t *)sd->data;
3902  }
3903 
3904  if (track->flags & MOV_TRACK_ENABLED)
3906 
3908 
3909  (version == 1) ? avio_wb32(pb, 104) : avio_wb32(pb, 92); /* size */
3910  ffio_wfourcc(pb, "tkhd");
3911  avio_w8(pb, version);
3912  avio_wb24(pb, flags);
3913  if (version == 1) {
3914  avio_wb64(pb, track->time);
3915  avio_wb64(pb, track->time);
3916  } else {
3917  avio_wb32(pb, track->time); /* creation time */
3918  avio_wb32(pb, track->time); /* modification time */
3919  }
3920  avio_wb32(pb, track->track_id); /* track-id */
3921  avio_wb32(pb, 0); /* reserved */
3922  if (!track->entry && mov->mode == MODE_ISM)
3923  (version == 1) ? avio_wb64(pb, UINT64_C(0xffffffffffffffff)) : avio_wb32(pb, 0xffffffff);
3924  else if (!track->entry)
3925  (version == 1) ? avio_wb64(pb, 0) : avio_wb32(pb, 0);
3926  else
3927  (version == 1) ? avio_wb64(pb, duration) : avio_wb32(pb, duration);
3928 
3929  avio_wb32(pb, 0); /* reserved */
3930  avio_wb32(pb, 0); /* reserved */
3931  avio_wb16(pb, 0); /* layer */
3932  avio_wb16(pb, group); /* alternate group) */
3933  /* Volume, only for audio */
3934  if (track->par->codec_type == AVMEDIA_TYPE_AUDIO)
3935  avio_wb16(pb, 0x0100);
3936  else
3937  avio_wb16(pb, 0);
3938  avio_wb16(pb, 0); /* reserved */
3939 
3940  /* Matrix structure */
3941  if (display_matrix) {
3942  for (i = 0; i < 9; i++)
3943  avio_wb32(pb, display_matrix[i]);
3944  } else {
3945  write_matrix(pb, 1, 0, 0, 1, 0, 0);
3946  }
3947  /* Track width and height, for visual only */
3948  if (st && (track->par->codec_type == AVMEDIA_TYPE_VIDEO ||
3949  track->par->codec_type == AVMEDIA_TYPE_SUBTITLE)) {
3950  int64_t track_width_1616;
3951  if (track->mode == MODE_MOV || track->mode == MODE_AVIF) {
3952  track_width_1616 = track->par->width * 0x10000ULL;
3953  } else {
3954  track_width_1616 = av_rescale(st->sample_aspect_ratio.num,
3955  track->par->width * 0x10000LL,
3956  st->sample_aspect_ratio.den);
3957  if (!track_width_1616 ||
3958  track->height != track->par->height ||
3959  track_width_1616 > UINT32_MAX)
3960  track_width_1616 = track->par->width * 0x10000ULL;
3961  }
3962  if (track_width_1616 > UINT32_MAX) {
3963  av_log(mov->fc, AV_LOG_WARNING, "track width is too large\n");
3964  track_width_1616 = 0;
3965  }
3966  avio_wb32(pb, track_width_1616);
3967  if (track->height > 0xFFFF) {
3968  av_log(mov->fc, AV_LOG_WARNING, "track height is too large\n");
3969  avio_wb32(pb, 0);
3970  } else
3971  avio_wb32(pb, track->height * 0x10000U);
3972  } else {
3973  avio_wb32(pb, 0);
3974  avio_wb32(pb, 0);
3975  }
3976  return 0x5c;
3977 }
3978 
3979 static int mov_write_tapt_tag(AVIOContext *pb, MOVTrack *track)
3980 {
3982  track->par->sample_aspect_ratio.den);
3983 
3984  int64_t pos = avio_tell(pb);
3985 
3986  avio_wb32(pb, 0); /* size */
3987  ffio_wfourcc(pb, "tapt");
3988 
3989  avio_wb32(pb, 20);
3990  ffio_wfourcc(pb, "clef");
3991  avio_wb32(pb, 0);
3992  avio_wb32(pb, width << 16);
3993  avio_wb32(pb, track->par->height << 16);
3994 
3995  avio_wb32(pb, 20);
3996  ffio_wfourcc(pb, "prof");
3997  avio_wb32(pb, 0);
3998  avio_wb32(pb, width << 16);
3999  avio_wb32(pb, track->par->height << 16);
4000 
4001  avio_wb32(pb, 20);
4002  ffio_wfourcc(pb, "enof");
4003  avio_wb32(pb, 0);
4004  avio_wb32(pb, track->par->width << 16);
4005  avio_wb32(pb, track->par->height << 16);
4006 
4007  return update_size(pb, pos);
4008 }
4009 
4010 // This box is written in the following cases:
4011 // * Seems important for the psp playback. Without it the movie seems to hang.
4012 // * Used for specifying the looping behavior of animated AVIF (as specified
4013 // in Section 9.6 of the HEIF specification ISO/IEC 23008-12).
4015  MOVTrack *track)
4016 {
4018  mov->movie_timescale, track->timescale,
4019  AV_ROUND_UP);
4020  int version = duration < INT32_MAX ? 0 : 1;
4021  int entry_size, entry_count, size;
4022  int64_t delay, start_ct = track->start_cts;
4023  int64_t start_dts = track->start_dts;
4024  int flags = 0;
4025 
4026  if (track->entry) {
4027  if (start_dts != track->cluster[0].dts || (start_ct != track->cluster[0].cts && track->cluster[0].dts >= 0)) {
4028 
4029  av_log(mov->fc, AV_LOG_DEBUG,
4030  "EDTS using dts:%"PRId64" cts:%d instead of dts:%"PRId64" cts:%"PRId64" tid:%d\n",
4031  track->cluster[0].dts, track->cluster[0].cts,
4032  start_dts, start_ct, track->track_id);
4033  start_dts = track->cluster[0].dts;
4034  start_ct = track->cluster[0].cts;
4035  }
4036  }
4037 
4038  delay = av_rescale_rnd(start_dts + start_ct, mov->movie_timescale,
4039  track->timescale, AV_ROUND_DOWN);
4040 
4041  if (mov->mode == MODE_AVIF) {
4042  delay = 0;
4043  // Section 9.6.3 of ISO/IEC 23008-12: flags specifies repetition of the
4044  // edit list as follows: (flags & 1) equal to 0 specifies that the edit
4045  // list is not repeated, while (flags & 1) equal to 1 specifies that the
4046  // edit list is repeated.
4047  flags = mov->avif_loop_count != 1;
4048  start_ct = 0;
4049  }
4050 
4051  version |= delay < INT32_MAX ? 0 : 1;
4052 
4053  entry_size = (version == 1) ? 20 : 12;
4054  entry_count = 1 + (delay > 0);
4055  size = 24 + entry_count * entry_size;
4056 
4057  /* write the atom data */
4058  avio_wb32(pb, size);
4059  ffio_wfourcc(pb, "edts");
4060  avio_wb32(pb, size - 8);
4061  ffio_wfourcc(pb, "elst");
4062  avio_w8(pb, version);
4063  avio_wb24(pb, flags); /* flags */
4064 
4065  avio_wb32(pb, entry_count);
4066  if (delay > 0) { /* add an empty edit to delay presentation */
4067  /* In the positive delay case, the delay includes the cts
4068  * offset, and the second edit list entry below trims out
4069  * the same amount from the actual content. This makes sure
4070  * that the offset last sample is included in the edit
4071  * list duration as well. */
4072  if (version == 1) {
4073  avio_wb64(pb, delay);
4074  avio_wb64(pb, -1);
4075  } else {
4076  avio_wb32(pb, delay);
4077  avio_wb32(pb, -1);
4078  }
4079  avio_wb32(pb, 0x00010000);
4080  } else if (mov->mode != MODE_AVIF) {
4081  /* Avoid accidentally ending up with start_ct = -1 which has got a
4082  * special meaning. Normally start_ct should end up positive or zero
4083  * here, but use FFMIN in case dts is a small positive integer
4084  * rounded to 0 when represented in movie timescale units. */
4085  av_assert0(av_rescale_rnd(start_dts, mov->movie_timescale, track->timescale, AV_ROUND_DOWN) <= 0);
4086  start_ct = -FFMIN(start_dts, 0);
4087 
4088 #if CONFIG_IAMFENC
4089  if (track->iamf && track->par->codec_id == AV_CODEC_ID_OPUS)
4090  start_ct = av_rescale(start_ct, 48000, track->par->sample_rate);
4091 #endif
4092  /* Note, this delay is calculated from the pts of the first sample,
4093  * ensuring that we don't reduce the duration for cases with
4094  * dts<0 pts=0. */
4095  duration += delay;
4096  }
4097 
4098  /* For fragmented files, we don't know the full length yet. Setting
4099  * duration to 0 allows us to only specify the offset, including
4100  * the rest of the content (from all future fragments) without specifying
4101  * an explicit duration.
4102  *
4103  * For hybrid_fragmented during mov_write_trailer (mov->moov_written != 0),
4104  * don't reset duration to zero.
4105  */
4106  if (mov->flags & FF_MOV_FLAG_FRAGMENT &&
4108  duration = 0;
4109 
4110  /* duration */
4111  if (version == 1) {
4112  avio_wb64(pb, duration);
4113  avio_wb64(pb, start_ct);
4114  } else {
4115  avio_wb32(pb, duration);
4116  avio_wb32(pb, start_ct);
4117  }
4118  avio_wb32(pb, 0x00010000);
4119  return size;
4120 }
4121 
4122 static int mov_write_tref_tag(AVIOContext *pb, MOVTrack *track)
4123 {
4124  avio_wb32(pb, 20); // size
4125  ffio_wfourcc(pb, "tref");
4126  avio_wb32(pb, 12); // size (subatom)
4127  avio_wl32(pb, track->tref_tag);
4128  avio_wb32(pb, track->tref_id);
4129  return 20;
4130 }
4131 
4132 // goes at the end of each track! ... Critical for PSP playback ("Incompatible data" without it)
4134 {
4135  avio_wb32(pb, 0x34); /* size ... reports as 28 in mp4box! */
4136  ffio_wfourcc(pb, "uuid");
4137  ffio_wfourcc(pb, "USMT");
4138  avio_wb32(pb, 0x21d24fce);
4139  avio_wb32(pb, 0xbb88695c);
4140  avio_wb32(pb, 0xfac9c740);
4141  avio_wb32(pb, 0x1c); // another size here!
4142  ffio_wfourcc(pb, "MTDT");
4143  avio_wb32(pb, 0x00010012);
4144  avio_wb32(pb, 0x0a);
4145  avio_wb32(pb, 0x55c40000);
4146  avio_wb32(pb, 0x1);
4147  avio_wb32(pb, 0x0);
4148  return 0x34;
4149 }
4150 
4151 static int mov_write_udta_sdp(AVIOContext *pb, MOVTrack *track)
4152 {
4153  AVFormatContext *ctx = track->rtp_ctx;
4154  char buf[1000] = "";
4155  int len;
4156 
4157  ff_sdp_write_media(buf, sizeof(buf), ctx->streams[0], track->src_track,
4158  NULL, NULL, 0, 0, ctx);
4159  av_strlcatf(buf, sizeof(buf), "a=control:streamid=%d\r\n", track->track_id);
4160  len = strlen(buf);
4161 
4162  avio_wb32(pb, len + 24);
4163  ffio_wfourcc(pb, "udta");
4164  avio_wb32(pb, len + 16);
4165  ffio_wfourcc(pb, "hnti");
4166  avio_wb32(pb, len + 8);
4167  ffio_wfourcc(pb, "sdp ");
4168  avio_write(pb, buf, len);
4169  return len + 24;
4170 }
4171 
4173  const char *tag, const char *str)
4174 {
4175  int64_t pos = avio_tell(pb);
4176  AVDictionaryEntry *t = av_dict_get(st->metadata, str, NULL, 0);
4177  if (!t || !utf8len(t->value))
4178  return 0;
4179 
4180  avio_wb32(pb, 0); /* size */
4181  ffio_wfourcc(pb, tag); /* type */
4182  avio_write(pb, t->value, strlen(t->value)); /* UTF8 string value */
4183  return update_size(pb, pos);
4184 }
4185 
4186 static int mov_write_track_kind(AVIOContext *pb, const char *scheme_uri,
4187  const char *value)
4188 {
4189  int64_t pos = avio_tell(pb);
4190 
4191  /* Box|FullBox basics */
4192  avio_wb32(pb, 0); /* size placeholder */
4193  ffio_wfourcc(pb, (const unsigned char *)"kind");
4194  avio_w8(pb, 0); /* version = 0 */
4195  avio_wb24(pb, 0); /* flags = 0 */
4196 
4197  /* Required null-terminated scheme URI */
4198  avio_write(pb, (const unsigned char *)scheme_uri,
4199  strlen(scheme_uri));
4200  avio_w8(pb, 0);
4201 
4202  /* Optional value string */
4203  if (value && value[0])
4204  avio_write(pb, (const unsigned char *)value,
4205  strlen(value));
4206 
4207  avio_w8(pb, 0);
4208 
4209  return update_size(pb, pos);
4210 }
4211 
4213 {
4214  int ret = AVERROR_BUG;
4215 
4216  for (int i = 0; ff_mov_track_kind_table[i].scheme_uri; i++) {
4218 
4219  for (int j = 0; map.value_maps[j].disposition; j++) {
4220  const struct MP4TrackKindValueMapping value_map = map.value_maps[j];
4221  if (!(st->disposition & value_map.disposition))
4222  continue;
4223 
4224  if ((ret = mov_write_track_kind(pb, map.scheme_uri, value_map.value)) < 0)
4225  return ret;
4226  }
4227  }
4228 
4229  return 0;
4230 }
4231 
4233  AVStream *st)
4234 {
4235  AVIOContext *pb_buf;
4236  int ret, size;
4237  uint8_t *buf;
4238 
4239  if (!st)
4240  return 0;
4241 
4242  ret = avio_open_dyn_buf(&pb_buf);
4243  if (ret < 0)
4244  return ret;
4245 
4246  if (mov->mode & (MODE_MP4|MODE_MOV))
4247  mov_write_track_metadata(pb_buf, st, "name", "title");
4248 
4249  if (mov->mode & MODE_MP4) {
4250  if ((ret = mov_write_track_kinds(pb_buf, st)) < 0)
4251  return ret;
4252  }
4253 
4254  if ((size = avio_get_dyn_buf(pb_buf, &buf)) > 0) {
4255  avio_wb32(pb, size + 8);
4256  ffio_wfourcc(pb, "udta");
4257  avio_write(pb, buf, size);
4258  }
4259  ffio_free_dyn_buf(&pb_buf);
4260 
4261  return 0;
4262 }
4263 
4265  MOVTrack *track, AVStream *st)
4266 {
4267  int64_t pos = avio_tell(pb);
4268  int entry_backup = track->entry;
4269  int chunk_backup = track->chunkCount;
4270  int ret;
4271 
4272  /* If we want to have an empty moov, but some samples already have been
4273  * buffered (delay_moov), pretend that no samples have been written yet. */
4274  if (mov->flags & FF_MOV_FLAG_EMPTY_MOOV)
4275  track->chunkCount = track->entry = 0;
4276 
4277  avio_wb32(pb, 0); /* size */
4278  ffio_wfourcc(pb, "trak");
4279  mov_write_tkhd_tag(pb, mov, track, st);
4280 
4281  av_assert2(mov->use_editlist >= 0);
4282 
4283  if (track->start_dts != AV_NOPTS_VALUE) {
4284  if (mov->use_editlist)
4285  mov_write_edts_tag(pb, mov, track); // PSP Movies and several other cases require edts box
4286  else if ((track->entry && track->cluster[0].dts) || track->mode == MODE_PSP || is_clcp_track(track))
4287  av_log(mov->fc, AV_LOG_WARNING,
4288  "Not writing any edit list even though one would have been required\n");
4289  }
4290 
4291  if (mov->is_animated_avif)
4292  mov_write_edts_tag(pb, mov, track);
4293 
4294  if (track->tref_tag)
4295  mov_write_tref_tag(pb, track);
4296 
4297  if ((ret = mov_write_mdia_tag(s, pb, mov, track)) < 0)
4298  return ret;
4299  if (track->mode == MODE_PSP)
4300  mov_write_uuid_tag_psp(pb, track); // PSP Movies require this uuid box
4301  if (track->tag == MKTAG('r','t','p',' '))
4302  mov_write_udta_sdp(pb, track);
4303  if (track->mode == MODE_MOV) {
4304  if (track->par->codec_type == AVMEDIA_TYPE_VIDEO) {
4305  double sample_aspect_ratio = av_q2d(st->sample_aspect_ratio);
4306  if (st->sample_aspect_ratio.num && 1.0 != sample_aspect_ratio) {
4307  mov_write_tapt_tag(pb, track);
4308  }
4309  }
4310  if (is_clcp_track(track) && st->sample_aspect_ratio.num) {
4311  mov_write_tapt_tag(pb, track);
4312  }
4313  }
4314  mov_write_track_udta_tag(pb, mov, st);
4315  track->entry = entry_backup;
4316  track->chunkCount = chunk_backup;
4317  return update_size(pb, pos);
4318 }
4319 
4321 {
4322  int i, has_audio = 0, has_video = 0;
4323  int64_t pos = avio_tell(pb);
4324  int audio_profile = mov->iods_audio_profile;
4325  int video_profile = mov->iods_video_profile;
4326  for (i = 0; i < mov->nb_tracks; i++) {
4327  if (mov->tracks[i].entry > 0 || mov->flags & FF_MOV_FLAG_EMPTY_MOOV) {
4328  has_audio |= mov->tracks[i].par->codec_type == AVMEDIA_TYPE_AUDIO;
4329  has_video |= mov->tracks[i].par->codec_type == AVMEDIA_TYPE_VIDEO;
4330  }
4331  }
4332  if (audio_profile < 0)
4333  audio_profile = 0xFF - has_audio;
4334  if (video_profile < 0)
4335  video_profile = 0xFF - has_video;
4336  avio_wb32(pb, 0x0); /* size */
4337  ffio_wfourcc(pb, "iods");
4338  avio_wb32(pb, 0); /* version & flags */
4339  put_descr(pb, 0x10, 7);
4340  avio_wb16(pb, 0x004f);
4341  avio_w8(pb, 0xff);
4342  avio_w8(pb, 0xff);
4343  avio_w8(pb, audio_profile);
4344  avio_w8(pb, video_profile);
4345  avio_w8(pb, 0xff);
4346  return update_size(pb, pos);
4347 }
4348 
4349 static int mov_write_trex_tag(AVIOContext *pb, MOVTrack *track)
4350 {
4351  avio_wb32(pb, 0x20); /* size */
4352  ffio_wfourcc(pb, "trex");
4353  avio_wb32(pb, 0); /* version & flags */
4354  avio_wb32(pb, track->track_id); /* track ID */
4355  avio_wb32(pb, 1); /* default sample description index */
4356  avio_wb32(pb, 0); /* default sample duration */
4357  avio_wb32(pb, 0); /* default sample size */
4358  avio_wb32(pb, 0); /* default sample flags */
4359  return 0;
4360 }
4361 
4363 {
4364  int64_t pos = avio_tell(pb);
4365  int i;
4366  avio_wb32(pb, 0x0); /* size */
4367  ffio_wfourcc(pb, "mvex");
4368  for (i = 0; i < mov->nb_tracks; i++)
4369  mov_write_trex_tag(pb, &mov->tracks[i]);
4370  return update_size(pb, pos);
4371 }
4372 
4374 {
4375  int max_track_id = 1, i;
4376  int64_t max_track_len = 0;
4377  int version;
4378  int timescale;
4379 
4380  for (i = 0; i < mov->nb_tracks; i++) {
4381  if (mov->tracks[i].entry > 0 && mov->tracks[i].timescale) {
4382  int64_t max_track_len_temp = av_rescale_rnd(
4383  calc_pts_duration(mov, &mov->tracks[i]),
4384  mov->movie_timescale,
4385  mov->tracks[i].timescale,
4386  AV_ROUND_UP);
4387  if (max_track_len < max_track_len_temp)
4388  max_track_len = max_track_len_temp;
4389  if (max_track_id < mov->tracks[i].track_id)
4390  max_track_id = mov->tracks[i].track_id;
4391  }
4392  }
4393  /* If using delay_moov, make sure the output is the same as if no
4394  * samples had been written yet. */
4395  if (mov->flags & FF_MOV_FLAG_EMPTY_MOOV) {
4396  max_track_len = 0;
4397  max_track_id = 1;
4398  }
4399 
4400  version = mov_mdhd_mvhd_tkhd_version(mov, NULL, max_track_len);
4401  avio_wb32(pb, version == 1 ? 120 : 108); /* size */
4402 
4403  ffio_wfourcc(pb, "mvhd");
4404  avio_w8(pb, version);
4405  avio_wb24(pb, 0); /* flags */
4406  if (version == 1) {
4407  avio_wb64(pb, mov->time);
4408  avio_wb64(pb, mov->time);
4409  } else {
4410  avio_wb32(pb, mov->time); /* creation time */
4411  avio_wb32(pb, mov->time); /* modification time */
4412  }
4413 
4414  timescale = mov->movie_timescale;
4415  if (mov->mode == MODE_AVIF && !timescale)
4416  timescale = mov->tracks[0].timescale;
4417 
4418  avio_wb32(pb, timescale);
4419  (version == 1) ? avio_wb64(pb, max_track_len) : avio_wb32(pb, max_track_len); /* duration of longest track */
4420 
4421  avio_wb32(pb, 0x00010000); /* reserved (preferred rate) 1.0 = normal */
4422  avio_wb16(pb, 0x0100); /* reserved (preferred volume) 1.0 = normal */
4423  ffio_fill(pb, 0, 2 + 2 * 4); /* reserved */
4424 
4425  /* Matrix structure */
4426  write_matrix(pb, 1, 0, 0, 1, 0, 0);
4427 
4428  avio_wb32(pb, 0); /* reserved (preview time) */
4429  avio_wb32(pb, 0); /* reserved (preview duration) */
4430  avio_wb32(pb, 0); /* reserved (poster time) */
4431  avio_wb32(pb, 0); /* reserved (selection time) */
4432  avio_wb32(pb, 0); /* reserved (selection duration) */
4433  avio_wb32(pb, 0); /* reserved (current time) */
4434  avio_wb32(pb, max_track_id + 1); /* Next track id */
4435  return 0x6c;
4436 }
4437 
4439  AVFormatContext *s)
4440 {
4441  avio_wb32(pb, 33); /* size */
4442  ffio_wfourcc(pb, "hdlr");
4443  avio_wb32(pb, 0);
4444  avio_wb32(pb, 0);
4445  ffio_wfourcc(pb, "mdir");
4446  ffio_wfourcc(pb, "appl");
4447  avio_wb32(pb, 0);
4448  avio_wb32(pb, 0);
4449  avio_w8(pb, 0);
4450  return 33;
4451 }
4452 
4453 /* helper function to write a data tag with the specified string as data */
4454 static int mov_write_string_data_tag(AVIOContext *pb, const char *data, int lang, int long_style)
4455 {
4456  size_t data_len = strlen(data);
4457  if (long_style) {
4458  int size = 16 + data_len;
4459  avio_wb32(pb, size); /* size */
4460  ffio_wfourcc(pb, "data");
4461  avio_wb32(pb, 1);
4462  avio_wb32(pb, 0);
4463  avio_write(pb, data, data_len);
4464  return size;
4465  } else {
4466  avio_wb16(pb, data_len); /* string length */
4467  if (!lang)
4468  lang = ff_mov_iso639_to_lang("und", 1);
4469  avio_wb16(pb, lang);
4470  avio_write(pb, data, data_len);
4471  return data_len + 4;
4472  }
4473 }
4474 
4475 static int mov_write_string_tag(AVIOContext *pb, const char *name,
4476  const char *value, int lang, int long_style)
4477 {
4478  int size = 0;
4479  if (value && value[0]) {
4480  int64_t pos = avio_tell(pb);
4481  avio_wb32(pb, 0); /* size */
4482  ffio_wfourcc(pb, name);
4483  mov_write_string_data_tag(pb, value, lang, long_style);
4484  size = update_size(pb, pos);
4485  }
4486  return size;
4487 }
4488 
4490  const char *tag, int *lang)
4491 {
4492  int l, len, len2;
4493  AVDictionaryEntry *t, *t2 = NULL;
4494  char tag2[16];
4495 
4496  *lang = 0;
4497 
4498  if (!(t = av_dict_get(s->metadata, tag, NULL, 0)))
4499  return NULL;
4500 
4501  len = strlen(t->key);
4502  snprintf(tag2, sizeof(tag2), "%s-", tag);
4503  while ((t2 = av_dict_get(s->metadata, tag2, t2, AV_DICT_IGNORE_SUFFIX))) {
4504  len2 = strlen(t2->key);
4505  if (len2 == len + 4 && !strcmp(t->value, t2->value)
4506  && (l = ff_mov_iso639_to_lang(&t2->key[len2 - 3], 1)) >= 0) {
4507  *lang = l;
4508  return t;
4509  }
4510  }
4511  return t;
4512 }
4513 
4515  const char *name, const char *tag,
4516  int long_style)
4517 {
4518  int lang;
4519  AVDictionaryEntry *t = get_metadata_lang(s, tag, &lang);
4520  if (!t)
4521  return 0;
4522  return mov_write_string_tag(pb, name, t->value, lang, long_style);
4523 }
4524 
4525 /* iTunes bpm number */
4527 {
4528  AVDictionaryEntry *t = av_dict_get(s->metadata, "tmpo", NULL, 0);
4529  int size = 0, tmpo = t ? atoi(t->value) : 0;
4530  if (tmpo) {
4531  size = 26;
4532  avio_wb32(pb, size);
4533  ffio_wfourcc(pb, "tmpo");
4534  avio_wb32(pb, size-8); /* size */
4535  ffio_wfourcc(pb, "data");
4536  avio_wb32(pb, 0x15); //type specifier
4537  avio_wb32(pb, 0);
4538  avio_wb16(pb, tmpo); // data
4539  }
4540  return size;
4541 }
4542 
4543 /* 3GPP TS 26.244 */
4545 {
4546  int lang;
4547  int64_t pos = avio_tell(pb);
4548  double latitude, longitude, altitude;
4549  int32_t latitude_fix, longitude_fix, altitude_fix;
4550  AVDictionaryEntry *t = get_metadata_lang(s, "location", &lang);
4551  const char *ptr, *place = "";
4552  char *end;
4553  static const char *astronomical_body = "earth";
4554  if (!t)
4555  return 0;
4556 
4557  ptr = t->value;
4558  latitude = strtod(ptr, &end);
4559  if (end == ptr) {
4560  av_log(s, AV_LOG_WARNING, "malformed location metadata\n");
4561  return 0;
4562  }
4563  ptr = end;
4564  longitude = strtod(ptr, &end);
4565  if (end == ptr) {
4566  av_log(s, AV_LOG_WARNING, "malformed location metadata\n");
4567  return 0;
4568  }
4569  ptr = end;
4570  altitude = strtod(ptr, &end);
4571  /* If no altitude was present, the default 0 should be fine */
4572  if (*end == '/')
4573  place = end + 1;
4574 
4575  latitude_fix = (int32_t) ((1 << 16) * latitude);
4576  longitude_fix = (int32_t) ((1 << 16) * longitude);
4577  altitude_fix = (int32_t) ((1 << 16) * altitude);
4578 
4579  avio_wb32(pb, 0); /* size */
4580  ffio_wfourcc(pb, "loci"); /* type */
4581  avio_wb32(pb, 0); /* version + flags */
4582  avio_wb16(pb, lang);
4583  avio_write(pb, place, strlen(place) + 1);
4584  avio_w8(pb, 0); /* role of place (0 == shooting location, 1 == real location, 2 == fictional location) */
4585  avio_wb32(pb, longitude_fix);
4586  avio_wb32(pb, latitude_fix);
4587  avio_wb32(pb, altitude_fix);
4588  avio_write(pb, astronomical_body, strlen(astronomical_body) + 1);
4589  avio_w8(pb, 0); /* additional notes, null terminated string */
4590 
4591  return update_size(pb, pos);
4592 }
4593 
4594 /* iTunes track or disc number */
4596  AVFormatContext *s, int disc)
4597 {
4598  AVDictionaryEntry *t = av_dict_get(s->metadata,
4599  disc ? "disc" : "track",
4600  NULL, 0);
4601  int size = 0, track = t ? atoi(t->value) : 0;
4602  if (track) {
4603  int tracks = 0;
4604  char *slash = strchr(t->value, '/');
4605  if (slash)
4606  tracks = atoi(slash + 1);
4607  avio_wb32(pb, 32); /* size */
4608  ffio_wfourcc(pb, disc ? "disk" : "trkn");
4609  avio_wb32(pb, 24); /* size */
4610  ffio_wfourcc(pb, "data");
4611  avio_wb32(pb, 0); // 8 bytes empty
4612  avio_wb32(pb, 0);
4613  avio_wb16(pb, 0); // empty
4614  avio_wb16(pb, track); // track / disc number
4615  avio_wb16(pb, tracks); // total track / disc number
4616  avio_wb16(pb, 0); // empty
4617  size = 32;
4618  }
4619  return size;
4620 }
4621 
4623  const char *name, const char *tag,
4624  int len)
4625 {
4626  AVDictionaryEntry *t = NULL;
4627  uint8_t num;
4628  int size = 24 + len;
4629 
4630  if (len != 1 && len != 4)
4631  return -1;
4632 
4633  if (!(t = av_dict_get(s->metadata, tag, NULL, 0)))
4634  return 0;
4635  num = atoi(t->value);
4636 
4637  avio_wb32(pb, size);
4638  ffio_wfourcc(pb, name);
4639  avio_wb32(pb, size - 8);
4640  ffio_wfourcc(pb, "data");
4641  avio_wb32(pb, 0x15);
4642  avio_wb32(pb, 0);
4643  if (len==4) avio_wb32(pb, num);
4644  else avio_w8 (pb, num);
4645 
4646  return size;
4647 }
4648 
4650 {
4651  MOVMuxContext *mov = s->priv_data;
4652  int64_t pos = 0;
4653 
4654  for (int i = 0; i < mov->nb_streams; i++) {
4655  MOVTrack *trk = &mov->tracks[i];
4656 
4657  if (!is_cover_image(trk->st) || trk->cover_image->size <= 0)
4658  continue;
4659 
4660  if (!pos) {
4661  pos = avio_tell(pb);
4662  avio_wb32(pb, 0);
4663  ffio_wfourcc(pb, "covr");
4664  }
4665  avio_wb32(pb, 16 + trk->cover_image->size);
4666  ffio_wfourcc(pb, "data");
4667  avio_wb32(pb, trk->tag);
4668  avio_wb32(pb , 0);
4669  avio_write(pb, trk->cover_image->data, trk->cover_image->size);
4670  }
4671 
4672  return pos ? update_size(pb, pos) : 0;
4673 }
4674 
4675 /* iTunes meta data list */
4677  AVFormatContext *s)
4678 {
4679  int64_t pos = avio_tell(pb);
4680  avio_wb32(pb, 0); /* size */
4681  ffio_wfourcc(pb, "ilst");
4682  mov_write_string_metadata(s, pb, "\251nam", "title" , 1);
4683  mov_write_string_metadata(s, pb, "\251ART", "artist" , 1);
4684  mov_write_string_metadata(s, pb, "aART", "album_artist", 1);
4685  mov_write_string_metadata(s, pb, "\251wrt", "composer" , 1);
4686  mov_write_string_metadata(s, pb, "\251alb", "album" , 1);
4687  mov_write_string_metadata(s, pb, "\251day", "date" , 1);
4688  if (!mov_write_string_metadata(s, pb, "\251too", "encoding_tool", 1)) {
4689  if (!(s->flags & AVFMT_FLAG_BITEXACT))
4690  mov_write_string_tag(pb, "\251too", LIBAVFORMAT_IDENT, 0, 1);
4691  }
4692  mov_write_string_metadata(s, pb, "\251cmt", "comment" , 1);
4693  mov_write_string_metadata(s, pb, "\251gen", "genre" , 1);
4694  mov_write_string_metadata(s, pb, "cprt", "copyright", 1);
4695  mov_write_string_metadata(s, pb, "\251grp", "grouping" , 1);
4696  mov_write_string_metadata(s, pb, "\251lyr", "lyrics" , 1);
4697  mov_write_string_metadata(s, pb, "desc", "description",1);
4698  mov_write_string_metadata(s, pb, "ldes", "synopsis" , 1);
4699  mov_write_string_metadata(s, pb, "tvsh", "show" , 1);
4700  mov_write_string_metadata(s, pb, "tven", "episode_id",1);
4701  mov_write_string_metadata(s, pb, "tvnn", "network" , 1);
4702  mov_write_string_metadata(s, pb, "keyw", "keywords" , 1);
4703  mov_write_int8_metadata (s, pb, "tves", "episode_sort",4);
4704  mov_write_int8_metadata (s, pb, "tvsn", "season_number",4);
4705  mov_write_int8_metadata (s, pb, "stik", "media_type",1);
4706  mov_write_int8_metadata (s, pb, "hdvd", "hd_video", 1);
4707  mov_write_int8_metadata (s, pb, "pgap", "gapless_playback",1);
4708  mov_write_int8_metadata (s, pb, "cpil", "compilation", 1);
4709  mov_write_covr(pb, s);
4710  mov_write_trkn_tag(pb, mov, s, 0); // track number
4711  mov_write_trkn_tag(pb, mov, s, 1); // disc number
4712  mov_write_tmpo_tag(pb, s);
4713  return update_size(pb, pos);
4714 }
4715 
4717  AVFormatContext *s)
4718 {
4719  avio_wb32(pb, 33); /* size */
4720  ffio_wfourcc(pb, "hdlr");
4721  avio_wb32(pb, 0);
4722  avio_wb32(pb, 0);
4723  ffio_wfourcc(pb, "mdta");
4724  avio_wb32(pb, 0);
4725  avio_wb32(pb, 0);
4726  avio_wb32(pb, 0);
4727  avio_w8(pb, 0);
4728  return 33;
4729 }
4730 
4732  AVFormatContext *s)
4733 {
4734  const AVDictionaryEntry *t = NULL;
4735  int64_t pos = avio_tell(pb);
4736  int64_t curpos, entry_pos;
4737  int count = 0;
4738 
4739  avio_wb32(pb, 0); /* size */
4740  ffio_wfourcc(pb, "keys");
4741  avio_wb32(pb, 0);
4742  entry_pos = avio_tell(pb);
4743  avio_wb32(pb, 0); /* entry count */
4744 
4745  while (t = av_dict_iterate(s->metadata, t)) {
4746  size_t key_len = strlen(t->key);
4747  avio_wb32(pb, key_len + 8);
4748  ffio_wfourcc(pb, "mdta");
4749  avio_write(pb, t->key, key_len);
4750  count += 1;
4751  }
4752  curpos = avio_tell(pb);
4753  avio_seek(pb, entry_pos, SEEK_SET);
4754  avio_wb32(pb, count); // rewrite entry count
4755  avio_seek(pb, curpos, SEEK_SET);
4756 
4757  return update_size(pb, pos);
4758 }
4759 
4761  AVFormatContext *s)
4762 {
4763  const AVDictionaryEntry *t = NULL;
4764  int64_t pos = avio_tell(pb);
4765  int count = 1; /* keys are 1-index based */
4766 
4767  avio_wb32(pb, 0); /* size */
4768  ffio_wfourcc(pb, "ilst");
4769 
4770  while (t = av_dict_iterate(s->metadata, t)) {
4771  int64_t entry_pos = avio_tell(pb);
4772  avio_wb32(pb, 0); /* size */
4773  avio_wb32(pb, count); /* key */
4774  mov_write_string_data_tag(pb, t->value, 0, 1);
4775  update_size(pb, entry_pos);
4776  count += 1;
4777  }
4778  return update_size(pb, pos);
4779 }
4780 
4781 /* meta data tags */
4783  AVFormatContext *s)
4784 {
4785  int size = 0;
4786  int64_t pos = avio_tell(pb);
4787  avio_wb32(pb, 0); /* size */
4788  ffio_wfourcc(pb, "meta");
4789  avio_wb32(pb, 0);
4790  if (mov->flags & FF_MOV_FLAG_USE_MDTA) {
4791  mov_write_mdta_hdlr_tag(pb, mov, s);
4792  mov_write_mdta_keys_tag(pb, mov, s);
4793  mov_write_mdta_ilst_tag(pb, mov, s);
4794  } else if (mov->mode == MODE_AVIF) {
4795  mov_write_hdlr_tag(s, pb, &mov->tracks[0]);
4796  // We always write the primary item id as 1 since only one track is
4797  // supported for AVIF.
4798  mov_write_pitm_tag(pb, 1);
4799  mov_write_iloc_tag(pb, mov, s);
4800  mov_write_iinf_tag(pb, mov, s);
4801  if (mov->nb_streams > 1)
4802  mov_write_iref_tag(pb, mov, s);
4803  mov_write_iprp_tag(pb, mov, s);
4804  } else {
4805  /* iTunes metadata tag */
4806  mov_write_itunes_hdlr_tag(pb, mov, s);
4807  mov_write_ilst_tag(pb, mov, s);
4808  }
4809  size = update_size(pb, pos);
4810  return size;
4811 }
4812 
4814  const char *name, const char *key)
4815 {
4816  int len;
4817  AVDictionaryEntry *t;
4818 
4819  if (!(t = av_dict_get(s->metadata, key, NULL, 0)))
4820  return 0;
4821 
4822  len = strlen(t->value);
4823  if (len > 0) {
4824  int size = len + 8;
4825  avio_wb32(pb, size);
4826  ffio_wfourcc(pb, name);
4827  avio_write(pb, t->value, len);
4828  return size;
4829  }
4830  return 0;
4831 }
4832 
4833 static int ascii_to_wc(AVIOContext *pb, const uint8_t *b)
4834 {
4835  int val;
4836  while (*b) {
4837  GET_UTF8(val, *b++, return -1;)
4838  avio_wb16(pb, val);
4839  }
4840  avio_wb16(pb, 0x00);
4841  return 0;
4842 }
4843 
4844 static uint16_t language_code(const char *str)
4845 {
4846  return (((str[0] - 0x60) & 0x1F) << 10) +
4847  (((str[1] - 0x60) & 0x1F) << 5) +
4848  (( str[2] - 0x60) & 0x1F);
4849 }
4850 
4852  const char *tag, const char *str)
4853 {
4854  int64_t pos = avio_tell(pb);
4855  AVDictionaryEntry *t = av_dict_get(s->metadata, str, NULL, 0);
4856  if (!t || !utf8len(t->value))
4857  return 0;
4858  avio_wb32(pb, 0); /* size */
4859  ffio_wfourcc(pb, tag); /* type */
4860  avio_wb32(pb, 0); /* version + flags */
4861  if (!strcmp(tag, "yrrc"))
4862  avio_wb16(pb, atoi(t->value));
4863  else {
4864  avio_wb16(pb, language_code("eng")); /* language */
4865  avio_write(pb, t->value, strlen(t->value) + 1); /* UTF8 string value */
4866  if (!strcmp(tag, "albm") &&
4867  (t = av_dict_get(s->metadata, "track", NULL, 0)))
4868  avio_w8(pb, atoi(t->value));
4869  }
4870  return update_size(pb, pos);
4871 }
4872 
4874 {
4875  int64_t pos = avio_tell(pb);
4876  int i, nb_chapters = FFMIN(s->nb_chapters, 255);
4877 
4878  avio_wb32(pb, 0); // size
4879  ffio_wfourcc(pb, "chpl");
4880  avio_wb32(pb, 0x01000000); // version + flags
4881  avio_wb32(pb, 0); // unknown
4882  avio_w8(pb, nb_chapters);
4883 
4884  for (i = 0; i < nb_chapters; i++) {
4885  AVChapter *c = s->chapters[i];
4886  AVDictionaryEntry *t;
4887  avio_wb64(pb, av_rescale_q(c->start, c->time_base, (AVRational){1,10000000}));
4888 
4889  if ((t = av_dict_get(c->metadata, "title", NULL, 0))) {
4890  int len = FFMIN(strlen(t->value), 255);
4891  avio_w8(pb, len);
4892  avio_write(pb, t->value, len);
4893  } else
4894  avio_w8(pb, 0);
4895  }
4896  return update_size(pb, pos);
4897 }
4898 
4900  AVFormatContext *s)
4901 {
4902  AVIOContext *pb_buf;
4903  int ret, size;
4904  uint8_t *buf;
4905 
4906  ret = avio_open_dyn_buf(&pb_buf);
4907  if (ret < 0)
4908  return ret;
4909 
4910  if (mov->mode & MODE_3GP) {
4911  mov_write_3gp_udta_tag(pb_buf, s, "perf", "artist");
4912  mov_write_3gp_udta_tag(pb_buf, s, "titl", "title");
4913  mov_write_3gp_udta_tag(pb_buf, s, "auth", "author");
4914  mov_write_3gp_udta_tag(pb_buf, s, "gnre", "genre");
4915  mov_write_3gp_udta_tag(pb_buf, s, "dscp", "comment");
4916  mov_write_3gp_udta_tag(pb_buf, s, "albm", "album");
4917  mov_write_3gp_udta_tag(pb_buf, s, "cprt", "copyright");
4918  mov_write_3gp_udta_tag(pb_buf, s, "yrrc", "date");
4919  mov_write_loci_tag(s, pb_buf);
4920  } 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
4921  mov_write_string_metadata(s, pb_buf, "\251ART", "artist", 0);
4922  mov_write_string_metadata(s, pb_buf, "\251nam", "title", 0);
4923  mov_write_string_metadata(s, pb_buf, "\251aut", "author", 0);
4924  mov_write_string_metadata(s, pb_buf, "\251alb", "album", 0);
4925  mov_write_string_metadata(s, pb_buf, "\251day", "date", 0);
4926  mov_write_string_metadata(s, pb_buf, "\251swr", "encoder", 0);
4927  // currently ignored by mov.c
4928  mov_write_string_metadata(s, pb_buf, "\251des", "comment", 0);
4929  // add support for libquicktime, this atom is also actually read by mov.c
4930  mov_write_string_metadata(s, pb_buf, "\251cmt", "comment", 0);
4931  mov_write_string_metadata(s, pb_buf, "\251gen", "genre", 0);
4932  mov_write_string_metadata(s, pb_buf, "\251cpy", "copyright", 0);
4933  mov_write_string_metadata(s, pb_buf, "\251mak", "make", 0);
4934  mov_write_string_metadata(s, pb_buf, "\251mod", "model", 0);
4935  mov_write_string_metadata(s, pb_buf, "\251xyz", "location", 0);
4936  mov_write_string_metadata(s, pb_buf, "\251key", "keywords", 0);
4937  mov_write_raw_metadata_tag(s, pb_buf, "XMP_", "xmp");
4938  } else {
4939  /* iTunes meta data */
4940  mov_write_meta_tag(pb_buf, mov, s);
4941  mov_write_loci_tag(s, pb_buf);
4942  }
4943 
4944  if (s->nb_chapters && !(mov->flags & FF_MOV_FLAG_DISABLE_CHPL))
4945  mov_write_chpl_tag(pb_buf, s);
4946 
4947  if ((size = avio_get_dyn_buf(pb_buf, &buf)) > 0) {
4948  avio_wb32(pb, size + 8);
4949  ffio_wfourcc(pb, "udta");
4950  avio_write(pb, buf, size);
4951  }
4952  ffio_free_dyn_buf(&pb_buf);
4953 
4954  return 0;
4955 }
4956 
4958  const char *str, const char *lang, int type)
4959 {
4960  int len = utf8len(str) + 1;
4961  if (len <= 0)
4962  return;
4963  avio_wb16(pb, len * 2 + 10); /* size */
4964  avio_wb32(pb, type); /* type */
4965  avio_wb16(pb, language_code(lang)); /* language */
4966  avio_wb16(pb, 0x01); /* ? */
4967  ascii_to_wc(pb, str);
4968 }
4969 
4971 {
4972  AVDictionaryEntry *title = av_dict_get(s->metadata, "title", NULL, 0);
4973  int64_t pos, pos2;
4974 
4975  if (title) {
4976  pos = avio_tell(pb);
4977  avio_wb32(pb, 0); /* size placeholder*/
4978  ffio_wfourcc(pb, "uuid");
4979  ffio_wfourcc(pb, "USMT");
4980  avio_wb32(pb, 0x21d24fce); /* 96 bit UUID */
4981  avio_wb32(pb, 0xbb88695c);
4982  avio_wb32(pb, 0xfac9c740);
4983 
4984  pos2 = avio_tell(pb);
4985  avio_wb32(pb, 0); /* size placeholder*/
4986  ffio_wfourcc(pb, "MTDT");
4987  avio_wb16(pb, 4);
4988 
4989  // ?
4990  avio_wb16(pb, 0x0C); /* size */
4991  avio_wb32(pb, 0x0B); /* type */
4992  avio_wb16(pb, language_code("und")); /* language */
4993  avio_wb16(pb, 0x0); /* ? */
4994  avio_wb16(pb, 0x021C); /* data */
4995 
4996  if (!(s->flags & AVFMT_FLAG_BITEXACT))
4997  mov_write_psp_udta_tag(pb, LIBAVFORMAT_IDENT, "eng", 0x04);
4998  mov_write_psp_udta_tag(pb, title->value, "eng", 0x01);
4999  mov_write_psp_udta_tag(pb, "2006/04/01 11:11:11", "und", 0x03);
5000 
5001  update_size(pb, pos2);
5002  return update_size(pb, pos);
5003  }
5004 
5005  return 0;
5006 }
5007 
5009 {
5014  if (!sd)
5015  return 0;
5016 
5018  for (AVEncryptionInitInfo *copy = info; copy; copy = copy->next) {
5019  int64_t pos;
5020 
5021  if (!copy->data_size && !copy->num_key_ids)
5022  continue;
5023 
5024  pos = avio_tell(pb);
5025  avio_wb32(pb, 0); /* size placeholder */
5026  ffio_wfourcc(pb, "pssh");
5027  avio_w8(pb, 1); /* version */
5028  avio_wb24(pb, 0);
5029  for (int i = 0; i < copy->system_id_size; i++)
5030  avio_w8(pb, copy->system_id[i]);
5031  avio_wb32(pb, copy->num_key_ids);
5032  for (int i = 0; i < copy->num_key_ids; i++)
5033  for (int j = 0; j < copy->key_id_size; j++)
5034  avio_w8(pb, copy->key_ids[i][j]);
5035  avio_wb32(pb, copy->data_size);
5036  avio_write(pb, copy->data, copy->data_size);
5037  update_size(pb, pos);
5038  }
5039 
5041 
5042  return 0;
5043 }
5044 
5045 static void build_chunks(MOVTrack *trk)
5046 {
5047  int i;
5048  MOVIentry *chunk = &trk->cluster[0];
5049  uint64_t chunkSize = chunk->size;
5050  chunk->chunkNum = 1;
5051  if (trk->chunkCount)
5052  return;
5053  trk->chunkCount = 1;
5054  for (i = 1; i<trk->entry; i++){
5055  if (chunk->pos + chunkSize == trk->cluster[i].pos &&
5056  chunk->stsd_index == trk->cluster[i].stsd_index &&
5057  chunkSize + trk->cluster[i].size < (1<<20)){
5058  chunkSize += trk->cluster[i].size;
5059  chunk->samples_in_chunk += trk->cluster[i].entries;
5060  } else {
5061  trk->cluster[i].chunkNum = chunk->chunkNum+1;
5062  chunk=&trk->cluster[i];
5063  chunkSize = chunk->size;
5064  trk->chunkCount++;
5065  }
5066  }
5067 }
5068 
5069 /**
5070  * Assign track ids. If option "use_stream_ids_as_track_ids" is set,
5071  * the stream ids are used as track ids.
5072  *
5073  * This assumes mov->tracks and s->streams are in the same order and
5074  * there are no gaps in either of them (so mov->tracks[n] refers to
5075  * s->streams[n]).
5076  *
5077  * As an exception, there can be more entries in
5078  * s->streams than in mov->tracks, in which case new track ids are
5079  * generated (starting after the largest found stream id).
5080  */
5082 {
5083  int i;
5084 
5085  if (mov->track_ids_ok)
5086  return 0;
5087 
5088  if (mov->use_stream_ids_as_track_ids) {
5089  int next_generated_track_id = 0;
5090  for (i = 0; i < mov->nb_streams; i++) {
5091  AVStream *st = mov->tracks[i].st;
5092  if (st->id > next_generated_track_id)
5093  next_generated_track_id = st->id;
5094  }
5095 
5096  for (i = 0; i < mov->nb_tracks; i++) {
5097  if (mov->tracks[i].entry <= 0 && !(mov->flags & FF_MOV_FLAG_FRAGMENT))
5098  continue;
5099 
5100  mov->tracks[i].track_id = i >= mov->nb_streams ? ++next_generated_track_id : mov->tracks[i].st->id;
5101  }
5102  } else {
5103  int last_track_id = 0;
5104  for (i = 0; i < mov->nb_tracks; i++) {
5105  if (mov->tracks[i].entry <= 0 && !(mov->flags & FF_MOV_FLAG_FRAGMENT))
5106  continue;
5107 
5108  last_track_id =
5109  mov->tracks[i].track_id = (mov->tracks[i].st
5110  ? FFMAX(mov->tracks[i].st->index, last_track_id)
5111  : FFMAX(i, last_track_id)) + 1;
5112  }
5113  }
5114 
5115  mov->track_ids_ok = 1;
5116 
5117  return 0;
5118 }
5119 
5121  AVFormatContext *s)
5122 {
5123  int i;
5124  int64_t pos = avio_tell(pb);
5125  avio_wb32(pb, 0); /* size placeholder*/
5126  ffio_wfourcc(pb, "moov");
5127 
5128  mov_setup_track_ids(mov, s);
5129 
5130  for (i = 0; i < mov->nb_tracks; i++) {
5131  if (mov->tracks[i].entry <= 0 && !(mov->flags & FF_MOV_FLAG_FRAGMENT))
5132  continue;
5133 
5134  mov->tracks[i].time = mov->time;
5135 
5136  if (mov->tracks[i].entry)
5137  build_chunks(&mov->tracks[i]);
5138  }
5139 
5140  if (mov->chapter_track)
5141  for (i = 0; i < mov->nb_streams; i++) {
5142  mov->tracks[i].tref_tag = MKTAG('c','h','a','p');
5143  mov->tracks[i].tref_id = mov->tracks[mov->chapter_track].track_id;
5144  }
5145  for (i = 0; i < mov->nb_tracks; i++) {
5146  MOVTrack *track = &mov->tracks[i];
5147  if (track->tag == MKTAG('r','t','p',' ')) {
5148  track->tref_tag = MKTAG('h','i','n','t');
5149  track->tref_id = mov->tracks[track->src_track].track_id;
5150  } else if (track->par->codec_type == AVMEDIA_TYPE_AUDIO) {
5152  track->st->codecpar->nb_coded_side_data,
5154  if (sd && sd->size == sizeof(int)) {
5155  int *fallback = (int *)sd->data;
5156  if (*fallback >= 0 && *fallback < mov->nb_tracks) {
5157  track->tref_tag = MKTAG('f','a','l','l');
5158  track->tref_id = mov->tracks[*fallback].track_id;
5159  }
5160  }
5161  }
5162  }
5163  for (i = 0; i < mov->nb_tracks; i++) {
5164  if (mov->tracks[i].tag == MKTAG('t','m','c','d')) {
5165  int src_trk = mov->tracks[i].src_track;
5166  mov->tracks[src_trk].tref_tag = mov->tracks[i].tag;
5167  mov->tracks[src_trk].tref_id = mov->tracks[i].track_id;
5168  //src_trk may have a different timescale than the tmcd track
5169  mov->tracks[i].track_duration = av_rescale(mov->tracks[src_trk].track_duration,
5170  mov->tracks[i].timescale,
5171  mov->tracks[src_trk].timescale);
5172  }
5173  }
5174 
5175  mov_write_mvhd_tag(pb, mov);
5176  if (mov->mode != MODE_MOV && mov->mode != MODE_AVIF && !mov->iods_skip)
5177  mov_write_iods_tag(pb, mov);
5178  for (i = 0; i < mov->nb_tracks; i++) {
5179  if (mov->tracks[i].entry > 0 || mov->flags & FF_MOV_FLAG_FRAGMENT ||
5180  mov->mode == MODE_AVIF) {
5181  int ret = mov_write_trak_tag(s, pb, mov, &(mov->tracks[i]), i < mov->nb_streams ? mov->tracks[i].st : NULL);
5182  if (ret < 0)
5183  return ret;
5184  }
5185  }
5186  /* Don't write mvex for hybrid_fragmented during mov_write_trailer
5187  * (mov->moov_written != 0)
5188  */
5189  if (mov->flags & FF_MOV_FLAG_FRAGMENT &&
5191  mov_write_mvex_tag(pb, mov); /* QuickTime requires trak to precede this */
5192 
5193  if (mov->mode == MODE_PSP)
5195  else if (mov->mode != MODE_AVIF)
5196  mov_write_udta_tag(pb, mov, s);
5197  for (i = 0; i < mov->nb_streams; i++)
5198  mov_write_pssh_tag(pb, mov->tracks[i].st);
5199 
5200  return update_size(pb, pos);
5201 }
5202 
5203 static void param_write_int(AVIOContext *pb, const char *name, int value)
5204 {
5205  avio_printf(pb, "<param name=\"%s\" value=\"%d\" valuetype=\"data\"/>\n", name, value);
5206 }
5207 
5208 static void param_write_string(AVIOContext *pb, const char *name, const char *value)
5209 {
5210  avio_printf(pb, "<param name=\"%s\" value=\"%s\" valuetype=\"data\"/>\n", name, value);
5211 }
5212 
5213 static void param_write_hex(AVIOContext *pb, const char *name, const uint8_t *value, int len)
5214 {
5215  char buf[150];
5216  len = FFMIN(sizeof(buf) / 2 - 1, len);
5217  ff_data_to_hex(buf, value, len, 0);
5218  avio_printf(pb, "<param name=\"%s\" value=\"%s\" valuetype=\"data\"/>\n", name, buf);
5219 }
5220 
5222 {
5223  int64_t pos = avio_tell(pb);
5224  int i;
5225 
5226  static const AVUUID uuid = {
5227  0xa5, 0xd4, 0x0b, 0x30, 0xe8, 0x14, 0x11, 0xdd,
5228  0xba, 0x2f, 0x08, 0x00, 0x20, 0x0c, 0x9a, 0x66
5229  };
5230 
5231  avio_wb32(pb, 0);
5232  ffio_wfourcc(pb, "uuid");
5233  avio_write(pb, uuid, AV_UUID_LEN);
5234  avio_wb32(pb, 0);
5235 
5236  avio_printf(pb, "<?xml version=\"1.0\" encoding=\"utf-8\"?>\n");
5237  avio_printf(pb, "<smil xmlns=\"http://www.w3.org/2001/SMIL20/Language\">\n");
5238  avio_printf(pb, "<head>\n");
5239  if (!(mov->fc->flags & AVFMT_FLAG_BITEXACT))
5240  avio_printf(pb, "<meta name=\"creator\" content=\"%s\" />\n",
5242  avio_printf(pb, "</head>\n");
5243  avio_printf(pb, "<body>\n");
5244  avio_printf(pb, "<switch>\n");
5245 
5246  mov_setup_track_ids(mov, s);
5247 
5248  for (i = 0; i < mov->nb_tracks; i++) {
5249  MOVTrack *track = &mov->tracks[i];
5250  struct mpeg4_bit_rate_values bit_rates =
5252  const char *type;
5253  int track_id = track->track_id;
5254  char track_name_buf[32] = { 0 };
5255 
5256  AVStream *st = track->st;
5257  AVDictionaryEntry *lang = av_dict_get(st->metadata, "language", NULL,0);
5258 
5259  if (track->par->codec_type == AVMEDIA_TYPE_VIDEO && !is_cover_image(st)) {
5260  type = "video";
5261  } else if (track->par->codec_type == AVMEDIA_TYPE_AUDIO) {
5262  type = "audio";
5263  } else {
5264  continue;
5265  }
5266 
5267  avio_printf(pb, "<%s systemBitrate=\"%"PRIu32"\">\n", type,
5268  bit_rates.avg_bit_rate);
5269  param_write_int(pb, "systemBitrate", bit_rates.avg_bit_rate);
5270  param_write_int(pb, "trackID", track_id);
5271  param_write_string(pb, "systemLanguage", lang ? lang->value : "und");
5272 
5273  /* Build track name piece by piece: */
5274  /* 1. track type */
5275  av_strlcat(track_name_buf, type, sizeof(track_name_buf));
5276  /* 2. track language, if available */
5277  if (lang)
5278  av_strlcatf(track_name_buf, sizeof(track_name_buf),
5279  "_%s", lang->value);
5280  /* 3. special type suffix */
5281  /* "_cc" = closed captions, "_ad" = audio_description */
5283  av_strlcat(track_name_buf, "_cc", sizeof(track_name_buf));
5285  av_strlcat(track_name_buf, "_ad", sizeof(track_name_buf));
5286 
5287  param_write_string(pb, "trackName", track_name_buf);
5288 
5289  if (track->par->codec_type == AVMEDIA_TYPE_VIDEO) {
5290  if (track->par->codec_id == AV_CODEC_ID_H264) {
5291  uint8_t *ptr;
5292  int size = track->extradata_size[track->last_stsd_index];
5293  if (!ff_avc_write_annexb_extradata(track->extradata[track->last_stsd_index], &ptr,
5294  &size)) {
5295  param_write_hex(pb, "CodecPrivateData",
5296  ptr ? ptr : track->extradata[track->last_stsd_index],
5297  size);
5298  av_free(ptr);
5299  }
5300  param_write_string(pb, "FourCC", "H264");
5301  } else if (track->par->codec_id == AV_CODEC_ID_VC1) {
5302  param_write_string(pb, "FourCC", "WVC1");
5303  param_write_hex(pb, "CodecPrivateData", track->extradata[track->last_stsd_index],
5304  track->extradata_size[track->last_stsd_index]);
5305  }
5306  param_write_int(pb, "MaxWidth", track->par->width);
5307  param_write_int(pb, "MaxHeight", track->par->height);
5308  param_write_int(pb, "DisplayWidth", track->par->width);
5309  param_write_int(pb, "DisplayHeight", track->par->height);
5310  } else {
5311  if (track->par->codec_id == AV_CODEC_ID_AAC) {
5312  switch (track->par->profile) {
5313  case AV_PROFILE_AAC_HE_V2:
5314  param_write_string(pb, "FourCC", "AACP");
5315  break;
5316  case AV_PROFILE_AAC_HE:
5317  param_write_string(pb, "FourCC", "AACH");
5318  break;
5319  default:
5320  param_write_string(pb, "FourCC", "AACL");
5321  }
5322  } else if (track->par->codec_id == AV_CODEC_ID_WMAPRO) {
5323  param_write_string(pb, "FourCC", "WMAP");
5324  }
5325  param_write_hex(pb, "CodecPrivateData", track->extradata[track->last_stsd_index],
5326  track->extradata_size[track->last_stsd_index]);
5328  track->par->codec_id));
5329  param_write_int(pb, "Channels", track->par->ch_layout.nb_channels);
5330  param_write_int(pb, "SamplingRate", track->tag == MKTAG('i','a','m','f') ?
5331  0 : track->par->sample_rate);
5332  param_write_int(pb, "BitsPerSample", 16);
5333  param_write_int(pb, "PacketSize", track->par->block_align ?
5334  track->par->block_align : 4);
5335  }
5336  avio_printf(pb, "</%s>\n", type);
5337  }
5338  avio_printf(pb, "</switch>\n");
5339  avio_printf(pb, "</body>\n");
5340  avio_printf(pb, "</smil>\n");
5341 
5342  return update_size(pb, pos);
5343 }
5344 
5346 {
5347  avio_wb32(pb, 16);
5348  ffio_wfourcc(pb, "mfhd");
5349  avio_wb32(pb, 0);
5350  avio_wb32(pb, mov->fragments);
5351  return 0;
5352 }
5353 
5354 static uint32_t get_sample_flags(MOVTrack *track, MOVIentry *entry)
5355 {
5358 }
5359 
5361  MOVTrack *track, int64_t moof_offset)
5362 {
5363  int64_t pos = avio_tell(pb);
5366  if (!track->entry) {
5368  } else {
5370  }
5373  if (mov->flags & FF_MOV_FLAG_DEFAULT_BASE_MOOF) {
5376  }
5377  /* CMAF requires all values to be explicit in tfhd atoms */
5378  if (mov->flags & FF_MOV_FLAG_CMAF)
5380 
5381  /* Don't set a default sample size, the silverlight player refuses
5382  * to play files with that set. Don't set a default sample duration,
5383  * WMP freaks out if it is set. Don't set a base data offset, PIFF
5384  * file format says it MUST NOT be set. */
5385  if (track->mode == MODE_ISM)
5388 
5389  avio_wb32(pb, 0); /* size placeholder */
5390  ffio_wfourcc(pb, "tfhd");
5391  avio_w8(pb, 0); /* version */
5392  avio_wb24(pb, flags);
5393 
5394  avio_wb32(pb, track->track_id); /* track-id */
5396  avio_wb64(pb, moof_offset);
5397  if (flags & MOV_TFHD_STSD_ID) {
5398  avio_wb32(pb, 1);
5399  }
5401  track->default_duration = get_cluster_duration(track, 0);
5402  avio_wb32(pb, track->default_duration);
5403  }
5404  if (flags & MOV_TFHD_DEFAULT_SIZE) {
5405  track->default_size = track->entry ? track->cluster[0].size : 1;
5406  avio_wb32(pb, track->default_size);
5407  } else
5408  track->default_size = -1;
5409 
5410  if (flags & MOV_TFHD_DEFAULT_FLAGS) {
5411  /* Set the default flags based on the second sample, if available.
5412  * If the first sample is different, that can be signaled via a separate field. */
5413  if (track->entry > 1)
5414  track->default_sample_flags = get_sample_flags(track, &track->cluster[1]);
5415  else
5416  track->default_sample_flags =
5417  track->par->codec_type == AVMEDIA_TYPE_VIDEO ?
5420  avio_wb32(pb, track->default_sample_flags);
5421  }
5422 
5423  return update_size(pb, pos);
5424 }
5425 
5427  MOVTrack *track, int moof_size,
5428  int first, int end)
5429 {
5430  int64_t pos = avio_tell(pb);
5431  uint32_t flags = MOV_TRUN_DATA_OFFSET;
5432  int i;
5433 
5434  for (i = first; i < end; i++) {
5435  if (get_cluster_duration(track, i) != track->default_duration)
5437  if (track->cluster[i].size != track->default_size)
5439  if (i > first && get_sample_flags(track, &track->cluster[i]) != track->default_sample_flags)
5441  }
5442  if (!(flags & MOV_TRUN_SAMPLE_FLAGS) && track->entry > first &&
5443  get_sample_flags(track, &track->cluster[first]) != track->default_sample_flags)
5445  if (track->flags & MOV_TRACK_CTTS)
5447 
5448  avio_wb32(pb, 0); /* size placeholder */
5449  ffio_wfourcc(pb, "trun");
5451  avio_w8(pb, 1); /* version */
5452  else
5453  avio_w8(pb, 0); /* version */
5454  avio_wb24(pb, flags);
5455 
5456  avio_wb32(pb, end - first); /* sample count */
5457  if (mov->flags & FF_MOV_FLAG_OMIT_TFHD_OFFSET &&
5459  !mov->first_trun)
5460  avio_wb32(pb, 0); /* Later tracks follow immediately after the previous one */
5461  else
5462  avio_wb32(pb, moof_size + 8 + track->data_offset +
5463  track->cluster[first].pos); /* data offset */
5465  avio_wb32(pb, get_sample_flags(track, &track->cluster[first]));
5466 
5467  for (i = first; i < end; i++) {
5469  avio_wb32(pb, get_cluster_duration(track, i));
5471  avio_wb32(pb, track->cluster[i].size);
5473  avio_wb32(pb, get_sample_flags(track, &track->cluster[i]));
5474  if (flags & MOV_TRUN_SAMPLE_CTS)
5475  avio_wb32(pb, track->cluster[i].cts);
5476  }
5477 
5478  mov->first_trun = 0;
5479  return update_size(pb, pos);
5480 }
5481 
5482 static int mov_write_tfxd_tag(AVIOContext *pb, MOVTrack *track)
5483 {
5484  int64_t pos = avio_tell(pb);
5485  static const uint8_t uuid[] = {
5486  0x6d, 0x1d, 0x9b, 0x05, 0x42, 0xd5, 0x44, 0xe6,
5487  0x80, 0xe2, 0x14, 0x1d, 0xaf, 0xf7, 0x57, 0xb2
5488  };
5489 
5490  avio_wb32(pb, 0); /* size placeholder */
5491  ffio_wfourcc(pb, "uuid");
5492  avio_write(pb, uuid, AV_UUID_LEN);
5493  avio_w8(pb, 1);
5494  avio_wb24(pb, 0);
5495  avio_wb64(pb, track->cluster[0].dts + track->cluster[0].cts);
5496  avio_wb64(pb, track->end_pts -
5497  (track->cluster[0].dts + track->cluster[0].cts));
5498 
5499  return update_size(pb, pos);
5500 }
5501 
5503  MOVTrack *track, int entry)
5504 {
5505  int n = track->nb_frag_info - 1 - entry, i;
5506  int size = 8 + 16 + 4 + 1 + 16*n;
5507  static const uint8_t uuid[] = {
5508  0xd4, 0x80, 0x7e, 0xf2, 0xca, 0x39, 0x46, 0x95,
5509  0x8e, 0x54, 0x26, 0xcb, 0x9e, 0x46, 0xa7, 0x9f
5510  };
5511 
5512  if (entry < 0)
5513  return 0;
5514 
5515  avio_seek(pb, track->frag_info[entry].tfrf_offset, SEEK_SET);
5516  avio_wb32(pb, size);
5517  ffio_wfourcc(pb, "uuid");
5518  avio_write(pb, uuid, AV_UUID_LEN);
5519  avio_w8(pb, 1);
5520  avio_wb24(pb, 0);
5521  avio_w8(pb, n);
5522  for (i = 0; i < n; i++) {
5523  int index = entry + 1 + i;
5524  avio_wb64(pb, track->frag_info[index].time);
5525  avio_wb64(pb, track->frag_info[index].duration);
5526  }
5527  if (n < mov->ism_lookahead) {
5528  int free_size = 16 * (mov->ism_lookahead - n);
5529  avio_wb32(pb, free_size);
5530  ffio_wfourcc(pb, "free");
5531  ffio_fill(pb, 0, free_size - 8);
5532  }
5533 
5534  return 0;
5535 }
5536 
5538  MOVTrack *track)
5539 {
5540  int64_t pos = avio_tell(pb);
5541  int i;
5542  for (i = 0; i < mov->ism_lookahead; i++) {
5543  /* Update the tfrf tag for the last ism_lookahead fragments,
5544  * nb_frag_info - 1 is the next fragment to be written. */
5545  mov_write_tfrf_tag(pb, mov, track, track->nb_frag_info - 2 - i);
5546  }
5547  avio_seek(pb, pos, SEEK_SET);
5548  return 0;
5549 }
5550 
5551 static int mov_add_tfra_entries(AVIOContext *pb, MOVMuxContext *mov, int tracks,
5552  int size)
5553 {
5554  int i;
5555  for (i = 0; i < mov->nb_tracks; i++) {
5556  MOVTrack *track = &mov->tracks[i];
5558  if ((tracks >= 0 && i != tracks) || !track->entry)
5559  continue;
5560  track->nb_frag_info++;
5561  if (track->nb_frag_info >= track->frag_info_capacity) {
5562  unsigned new_capacity = track->nb_frag_info + MOV_FRAG_INFO_ALLOC_INCREMENT;
5563  if (av_reallocp_array(&track->frag_info,
5564  new_capacity,
5565  sizeof(*track->frag_info)))
5566  return AVERROR(ENOMEM);
5567  track->frag_info_capacity = new_capacity;
5568  }
5569  info = &track->frag_info[track->nb_frag_info - 1];
5570  info->offset = avio_tell(pb);
5571  info->size = size;
5572  // Try to recreate the original pts for the first packet
5573  // from the fields we have stored
5574  info->time = track->cluster[0].dts + track->cluster[0].cts;
5575  info->duration = track->end_pts -
5576  (track->cluster[0].dts + track->cluster[0].cts);
5577  // If the pts is less than zero, we will have trimmed
5578  // away parts of the media track using an edit list,
5579  // and the corresponding start presentation time is zero.
5580  if (info->time < 0) {
5581  info->duration += info->time;
5582  info->time = 0;
5583  }
5584  info->tfrf_offset = 0;
5585  mov_write_tfrf_tags(pb, mov, track);
5586  }
5587  return 0;
5588 }
5589 
5590 static void mov_prune_frag_info(MOVMuxContext *mov, int tracks, int max)
5591 {
5592  int i;
5593  for (i = 0; i < mov->nb_tracks; i++) {
5594  MOVTrack *track = &mov->tracks[i];
5595  if ((tracks >= 0 && i != tracks) || !track->entry)
5596  continue;
5597  if (track->nb_frag_info > max) {
5598  memmove(track->frag_info, track->frag_info + (track->nb_frag_info - max), max * sizeof(*track->frag_info));
5599  track->nb_frag_info = max;
5600  }
5601  }
5602 }
5603 
5604 static int mov_write_tfdt_tag(AVIOContext *pb, MOVTrack *track)
5605 {
5606  int64_t pos = avio_tell(pb);
5607 
5608  avio_wb32(pb, 0); /* size */
5609  ffio_wfourcc(pb, "tfdt");
5610  avio_w8(pb, 1); /* version */
5611  avio_wb24(pb, 0);
5612  avio_wb64(pb, track->cluster[0].dts - track->start_dts);
5613  return update_size(pb, pos);
5614 }
5615 
5617  MOVTrack *track, int64_t moof_offset,
5618  int moof_size)
5619 {
5620  int64_t pos = avio_tell(pb);
5621  int i, start = 0;
5622  avio_wb32(pb, 0); /* size placeholder */
5623  ffio_wfourcc(pb, "traf");
5624 
5625  mov_write_tfhd_tag(pb, mov, track, moof_offset);
5626  if (mov->mode != MODE_ISM)
5627  mov_write_tfdt_tag(pb, track);
5628  for (i = 1; i < track->entry; i++) {
5629  if (track->cluster[i].pos != track->cluster[i - 1].pos + track->cluster[i - 1].size) {
5630  mov_write_trun_tag(pb, mov, track, moof_size, start, i);
5631  start = i;
5632  }
5633  }
5634  mov_write_trun_tag(pb, mov, track, moof_size, start, track->entry);
5635  if (mov->mode == MODE_ISM) {
5636  mov_write_tfxd_tag(pb, track);
5637 
5638  if (mov->ism_lookahead) {
5639  int size = 16 + 4 + 1 + 16 * mov->ism_lookahead;
5640 
5641  if (track->nb_frag_info > 0) {
5642  MOVFragmentInfo *info = &track->frag_info[track->nb_frag_info - 1];
5643  if (!info->tfrf_offset)
5644  info->tfrf_offset = avio_tell(pb);
5645  }
5646  avio_wb32(pb, 8 + size);
5647  ffio_wfourcc(pb, "free");
5648  ffio_fill(pb, 0, size);
5649  }
5650  }
5651 
5652  if (track->cenc.aes_ctr && (mov->flags & FF_MOV_FLAG_FRAGMENT))
5653  ff_mov_cenc_write_stbl_atoms(&track->cenc, pb, moof_offset);
5654 
5655  return update_size(pb, pos);
5656 }
5657 
5659  int tracks, int moof_size)
5660 {
5661  int64_t pos = avio_tell(pb);
5662  int i;
5663 
5664  avio_wb32(pb, 0); /* size placeholder */
5665  ffio_wfourcc(pb, "moof");
5666  mov->first_trun = 1;
5667 
5668  mov_write_mfhd_tag(pb, mov);
5669  for (i = 0; i < mov->nb_tracks; i++) {
5670  MOVTrack *track = &mov->tracks[i];
5671  if (tracks >= 0 && i != tracks)
5672  continue;
5673  if (!track->entry)
5674  continue;
5675  if (track->cenc.aes_ctr && (mov->flags & FF_MOV_FLAG_FRAGMENT))
5676  mov_write_pssh_tag(pb, track->st);
5677  mov_write_traf_tag(pb, mov, track, pos, moof_size);
5678  }
5679 
5680  return update_size(pb, pos);
5681 }
5682 
5684  MOVTrack *track, int ref_size, int total_sidx_size)
5685 {
5686  int64_t pos = avio_tell(pb), offset_pos, end_pos;
5687  int64_t presentation_time, duration, offset;
5688  unsigned starts_with_SAP;
5689  int i, entries;
5690 
5691  if (track->entry) {
5692  entries = 1;
5693  presentation_time = track->cluster[0].dts + track->cluster[0].cts;
5694  duration = track->end_pts -
5695  (track->cluster[0].dts + track->cluster[0].cts);
5696  starts_with_SAP = track->cluster[0].flags & MOV_SYNC_SAMPLE;
5697 
5698  // pts<0 should be cut away using edts
5699  if (presentation_time < 0) {
5700  duration += presentation_time;
5701  presentation_time = 0;
5702  }
5703  } else {
5704  entries = track->nb_frag_info;
5705  if (entries <= 0)
5706  return 0;
5707  presentation_time = track->frag_info[0].time;
5708  }
5709 
5710  avio_wb32(pb, 0); /* size */
5711  ffio_wfourcc(pb, "sidx");
5712  avio_w8(pb, 1); /* version */
5713  avio_wb24(pb, 0);
5714  avio_wb32(pb, track->track_id); /* reference_ID */
5715  avio_wb32(pb, track->timescale); /* timescale */
5716  avio_wb64(pb, presentation_time); /* earliest_presentation_time */
5717  offset_pos = avio_tell(pb);
5718  avio_wb64(pb, 0); /* first_offset (offset to referenced moof) */
5719  avio_wb16(pb, 0); /* reserved */
5720 
5721  avio_wb16(pb, entries); /* reference_count */
5722  for (i = 0; i < entries; i++) {
5723  if (!track->entry) {
5724  if (i > 1 && track->frag_info[i].offset != track->frag_info[i - 1].offset + track->frag_info[i - 1].size) {
5725  av_log(NULL, AV_LOG_ERROR, "Non-consecutive fragments, writing incorrect sidx\n");
5726  }
5727  duration = track->frag_info[i].duration;
5728  ref_size = track->frag_info[i].size;
5729  starts_with_SAP = 1;
5730  }
5731  avio_wb32(pb, (0 << 31) | (ref_size & 0x7fffffff)); /* reference_type (0 = media) | referenced_size */
5732  avio_wb32(pb, duration); /* subsegment_duration */
5733  avio_wb32(pb, (starts_with_SAP << 31) | (0 << 28) | 0); /* starts_with_SAP | SAP_type | SAP_delta_time */
5734  }
5735 
5736  end_pos = avio_tell(pb);
5737  offset = pos + total_sidx_size - end_pos;
5738  avio_seek(pb, offset_pos, SEEK_SET);
5739  avio_wb64(pb, offset);
5740  avio_seek(pb, end_pos, SEEK_SET);
5741  return update_size(pb, pos);
5742 }
5743 
5745  int tracks, int ref_size)
5746 {
5747  int i, round, ret;
5748  AVIOContext *avio_buf;
5749  int total_size = 0;
5750  for (round = 0; round < 2; round++) {
5751  // First run one round to calculate the total size of all
5752  // sidx atoms.
5753  // This would be much simpler if we'd only write one sidx
5754  // atom, for the first track in the moof.
5755  if (round == 0) {
5756  if ((ret = ffio_open_null_buf(&avio_buf)) < 0)
5757  return ret;
5758  } else {
5759  avio_buf = pb;
5760  }
5761  for (i = 0; i < mov->nb_tracks; i++) {
5762  MOVTrack *track = &mov->tracks[i];
5763  if (tracks >= 0 && i != tracks)
5764  continue;
5765  // When writing a sidx for the full file, entry is 0, but
5766  // we want to include all tracks. ref_size is 0 in this case,
5767  // since we read it from frag_info instead.
5768  if (!track->entry && ref_size > 0)
5769  continue;
5770  total_size -= mov_write_sidx_tag(avio_buf, track, ref_size,
5771  total_size);
5772  }
5773  if (round == 0)
5774  total_size = ffio_close_null_buf(avio_buf);
5775  }
5776  return 0;
5777 }
5778 
5779 static int mov_write_prft_tag(AVIOContext *pb, MOVMuxContext *mov, int tracks)
5780 {
5781  int64_t pos = avio_tell(pb), pts_us, ntp_ts;
5782  MOVTrack *first_track;
5783  int flags = 24;
5784 
5785  /* PRFT should be associated with at most one track. So, choosing only the
5786  * first track. */
5787  if (tracks > 0)
5788  return 0;
5789  first_track = &(mov->tracks[0]);
5790 
5791  if (!first_track->entry) {
5792  av_log(mov->fc, AV_LOG_WARNING, "Unable to write PRFT, no entries in the track\n");
5793  return 0;
5794  }
5795 
5796  if (first_track->cluster[0].pts == AV_NOPTS_VALUE) {
5797  av_log(mov->fc, AV_LOG_WARNING, "Unable to write PRFT, first PTS is invalid\n");
5798  return 0;
5799  }
5800 
5801  if (mov->write_prft == MOV_PRFT_SRC_WALLCLOCK) {
5802  if (first_track->cluster[0].prft.wallclock) {
5803  /* Round the NTP time to whole milliseconds. */
5804  ntp_ts = ff_get_formatted_ntp_time((first_track->cluster[0].prft.wallclock / 1000) * 1000 +
5805  NTP_OFFSET_US);
5806  flags = first_track->cluster[0].prft.flags;
5807  } else
5809  } else if (mov->write_prft == MOV_PRFT_SRC_PTS) {
5810  pts_us = av_rescale_q(first_track->cluster[0].pts,
5811  first_track->st->time_base, AV_TIME_BASE_Q);
5812  ntp_ts = ff_get_formatted_ntp_time(pts_us + NTP_OFFSET_US);
5813  } else {
5814  av_log(mov->fc, AV_LOG_WARNING, "Unsupported PRFT box configuration: %d\n",
5815  mov->write_prft);
5816  return 0;
5817  }
5818 
5819  avio_wb32(pb, 0); // Size place holder
5820  ffio_wfourcc(pb, "prft"); // Type
5821  avio_w8(pb, 1); // Version
5822  avio_wb24(pb, flags); // Flags
5823  avio_wb32(pb, first_track->track_id); // reference track ID
5824  avio_wb64(pb, ntp_ts); // NTP time stamp
5825  avio_wb64(pb, first_track->cluster[0].pts); //media time
5826  return update_size(pb, pos);
5827 }
5828 
5829 static int mov_write_moof_tag(AVIOContext *pb, MOVMuxContext *mov, int tracks,
5830  int64_t mdat_size)
5831 {
5832  AVIOContext *avio_buf;
5833  int ret, moof_size;
5834 
5835  if ((ret = ffio_open_null_buf(&avio_buf)) < 0)
5836  return ret;
5837  mov_write_moof_tag_internal(avio_buf, mov, tracks, 0);
5838  moof_size = ffio_close_null_buf(avio_buf);
5839 
5840  if (mov->flags & FF_MOV_FLAG_DASH &&
5842  mov_write_sidx_tags(pb, mov, tracks, moof_size + 8 + mdat_size);
5843 
5844  if (mov->write_prft > MOV_PRFT_NONE && mov->write_prft < MOV_PRFT_NB)
5845  mov_write_prft_tag(pb, mov, tracks);
5846 
5847  if (mov->flags & FF_MOV_FLAG_GLOBAL_SIDX ||
5848  !(mov->flags & FF_MOV_FLAG_SKIP_TRAILER) ||
5849  mov->ism_lookahead) {
5850  if ((ret = mov_add_tfra_entries(pb, mov, tracks, moof_size + 8 + mdat_size)) < 0)
5851  return ret;
5852  if (!(mov->flags & FF_MOV_FLAG_GLOBAL_SIDX) &&
5854  mov_prune_frag_info(mov, tracks, mov->ism_lookahead + 1);
5855  }
5856  }
5857 
5858  return mov_write_moof_tag_internal(pb, mov, tracks, moof_size);
5859 }
5860 
5861 static int mov_write_tfra_tag(AVIOContext *pb, MOVTrack *track)
5862 {
5863  int64_t pos = avio_tell(pb);
5864  int i;
5865 
5866  avio_wb32(pb, 0); /* size placeholder */
5867  ffio_wfourcc(pb, "tfra");
5868  avio_w8(pb, 1); /* version */
5869  avio_wb24(pb, 0);
5870 
5871  avio_wb32(pb, track->track_id);
5872  avio_wb32(pb, 0); /* length of traf/trun/sample num */
5873  avio_wb32(pb, track->nb_frag_info);
5874  for (i = 0; i < track->nb_frag_info; i++) {
5875  avio_wb64(pb, track->frag_info[i].time);
5876  avio_wb64(pb, track->frag_info[i].offset + track->data_offset);
5877  avio_w8(pb, 1); /* traf number */
5878  avio_w8(pb, 1); /* trun number */
5879  avio_w8(pb, 1); /* sample number */
5880  }
5881 
5882  return update_size(pb, pos);
5883 }
5884 
5886 {
5887  AVIOContext *mfra_pb;
5888  int i, ret, sz;
5889  uint8_t *buf;
5890 
5891  ret = avio_open_dyn_buf(&mfra_pb);
5892  if (ret < 0)
5893  return ret;
5894 
5895  avio_wb32(mfra_pb, 0); /* size placeholder */
5896  ffio_wfourcc(mfra_pb, "mfra");
5897  /* An empty mfra atom is enough to indicate to the publishing point that
5898  * the stream has ended. */
5899  if (mov->flags & FF_MOV_FLAG_ISML)
5900  goto done_mfra;
5901 
5902  for (i = 0; i < mov->nb_tracks; i++) {
5903  MOVTrack *track = &mov->tracks[i];
5904  if (track->nb_frag_info)
5905  mov_write_tfra_tag(mfra_pb, track);
5906  }
5907 
5908  avio_wb32(mfra_pb, 16);
5909  ffio_wfourcc(mfra_pb, "mfro");
5910  avio_wb32(mfra_pb, 0); /* version + flags */
5911  avio_wb32(mfra_pb, avio_tell(mfra_pb) + 4);
5912 
5913 done_mfra:
5914 
5915  sz = update_size(mfra_pb, 0);
5916  ret = avio_get_dyn_buf(mfra_pb, &buf);
5917  avio_write(pb, buf, ret);
5918  ffio_free_dyn_buf(&mfra_pb);
5919 
5920  return sz;
5921 }
5922 
5924 {
5925  avio_wb32(pb, 8); // placeholder for extended size field (64 bit)
5926  ffio_wfourcc(pb, mov->mode == MODE_MOV ? "wide" : "free");
5927 
5928  mov->mdat_pos = avio_tell(pb);
5929  avio_wb32(pb, 0); /* size placeholder*/
5930  ffio_wfourcc(pb, "mdat");
5931  return 0;
5932 }
5933 
5935  int has_h264, int has_video, int write_minor)
5936 {
5937  MOVMuxContext *mov = s->priv_data;
5938  int minor = 0x200;
5939 
5940  if (mov->major_brand && strlen(mov->major_brand) >= 4)
5941  ffio_wfourcc(pb, mov->major_brand);
5942  else if (mov->mode == MODE_3GP) {
5943  ffio_wfourcc(pb, has_h264 ? "3gp6" : "3gp4");
5944  minor = has_h264 ? 0x100 : 0x200;
5945  } else if (mov->mode == MODE_AVIF) {
5946  ffio_wfourcc(pb, mov->is_animated_avif ? "avis" : "avif");
5947  minor = 0;
5948  } else if (mov->mode & MODE_3G2) {
5949  ffio_wfourcc(pb, has_h264 ? "3g2b" : "3g2a");
5950  minor = has_h264 ? 0x20000 : 0x10000;
5951  } else if (mov->mode == MODE_PSP)
5952  ffio_wfourcc(pb, "MSNV");
5953  else if (mov->mode == MODE_MP4 && mov->flags & FF_MOV_FLAG_FRAGMENT &&
5955  ffio_wfourcc(pb, "iso6"); // Required when using signed CTS offsets in trun boxes
5956  else if (mov->mode == MODE_MP4 && mov->flags & FF_MOV_FLAG_DEFAULT_BASE_MOOF)
5957  ffio_wfourcc(pb, "iso5"); // Required when using default-base-is-moof
5958  else if (mov->mode == MODE_MP4 && mov->flags & FF_MOV_FLAG_NEGATIVE_CTS_OFFSETS)
5959  ffio_wfourcc(pb, "iso4");
5960  else if (mov->mode == MODE_MP4)
5961  ffio_wfourcc(pb, "isom");
5962  else if (mov->mode == MODE_IPOD)
5963  ffio_wfourcc(pb, has_video ? "M4V ":"M4A ");
5964  else if (mov->mode == MODE_ISM)
5965  ffio_wfourcc(pb, "isml");
5966  else if (mov->mode == MODE_F4V)
5967  ffio_wfourcc(pb, "f4v ");
5968  else
5969  ffio_wfourcc(pb, "qt ");
5970 
5971  if (write_minor)
5972  avio_wb32(pb, minor);
5973 }
5974 
5976 {
5977  MOVMuxContext *mov = s->priv_data;
5978  int64_t pos = avio_tell(pb);
5979  int has_h264 = 0, has_av1 = 0, has_video = 0, has_dolby = 0, has_id3 = 0;
5980  int has_iamf = 0;
5981 
5982 #if CONFIG_IAMFENC
5983  for (int i = 0; i < s->nb_stream_groups; i++) {
5984  const AVStreamGroup *stg = s->stream_groups[i];
5985 
5988  has_iamf = 1;
5989  break;
5990  }
5991  }
5992 #endif
5993  for (int i = 0; i < mov->nb_streams; i++) {
5994  AVStream *st = mov->tracks[i].st;
5995  if (is_cover_image(st))
5996  continue;
5998  has_video = 1;
5999  if (st->codecpar->codec_id == AV_CODEC_ID_H264)
6000  has_h264 = 1;
6001  if (st->codecpar->codec_id == AV_CODEC_ID_AV1)
6002  has_av1 = 1;
6003  if (st->codecpar->codec_id == AV_CODEC_ID_AC3 ||
6009  has_dolby = 1;
6011  has_id3 = 1;
6012  }
6013 
6014  avio_wb32(pb, 0); /* size */
6015  ffio_wfourcc(pb, "ftyp");
6016 
6017  // Write major brand
6018  mov_write_ftyp_tag_internal(pb, s, has_h264, has_video, 1);
6019  // Write the major brand as the first compatible brand as well
6020  mov_write_ftyp_tag_internal(pb, s, has_h264, has_video, 0);
6021 
6022  // Write compatible brands, ensuring that we don't write the major brand as a
6023  // compatible brand a second time.
6024  if (mov->mode == MODE_ISM) {
6025  ffio_wfourcc(pb, "piff");
6026  } else if (mov->mode == MODE_AVIF) {
6027  const AVPixFmtDescriptor *pix_fmt_desc =
6028  av_pix_fmt_desc_get(s->streams[0]->codecpar->format);
6029  const int depth = pix_fmt_desc->comp[0].depth;
6030  if (mov->is_animated_avif) {
6031  // For animated AVIF, major brand is "avis". Add "avif" as a
6032  // compatible brand.
6033  ffio_wfourcc(pb, "avif");
6034  ffio_wfourcc(pb, "msf1");
6035  ffio_wfourcc(pb, "iso8");
6036  }
6037  ffio_wfourcc(pb, "mif1");
6038  ffio_wfourcc(pb, "miaf");
6039  if (depth == 8 || depth == 10) {
6040  // MA1B and MA1A brands are based on AV1 profile. Short hand for
6041  // computing that is based on chroma subsampling type. 420 chroma
6042  // subsampling is MA1B. 444 chroma subsampling is MA1A.
6043  if (!pix_fmt_desc->log2_chroma_w && !pix_fmt_desc->log2_chroma_h) {
6044  // 444 chroma subsampling.
6045  ffio_wfourcc(pb, "MA1A");
6046  } else {
6047  // 420 chroma subsampling.
6048  ffio_wfourcc(pb, "MA1B");
6049  }
6050  }
6051  } else if (mov->mode != MODE_MOV) {
6052  // We add tfdt atoms when fragmenting, signal this with the iso6 compatible
6053  // brand, if not already the major brand. This is compatible with users that
6054  // don't understand tfdt.
6055  if (mov->mode == MODE_MP4) {
6056  if (mov->flags & FF_MOV_FLAG_CMAF)
6057  ffio_wfourcc(pb, "cmfc");
6059  ffio_wfourcc(pb, "iso6");
6060  if (has_av1)
6061  ffio_wfourcc(pb, "av01");
6062  if (has_dolby)
6063  ffio_wfourcc(pb, "dby1");
6064  if (has_iamf)
6065  ffio_wfourcc(pb, "iamf");
6066  } else {
6067  if (mov->flags & FF_MOV_FLAG_FRAGMENT)
6068  ffio_wfourcc(pb, "iso6");
6070  ffio_wfourcc(pb, "iso5");
6071  else if (mov->flags & FF_MOV_FLAG_NEGATIVE_CTS_OFFSETS)
6072  ffio_wfourcc(pb, "iso4");
6073  }
6074  // Brands prior to iso5 can't be signaled when using default-base-is-moof
6075  if (!(mov->flags & FF_MOV_FLAG_DEFAULT_BASE_MOOF)) {
6076  // write isom for mp4 only if it it's not the major brand already.
6077  if (mov->mode != MODE_MP4 || mov->flags & FF_MOV_FLAG_NEGATIVE_CTS_OFFSETS)
6078  ffio_wfourcc(pb, "isom");
6079  ffio_wfourcc(pb, "iso2");
6080  if (has_h264)
6081  ffio_wfourcc(pb, "avc1");
6082  }
6083  }
6084 
6085  if (mov->mode == MODE_MP4)
6086  ffio_wfourcc(pb, "mp41");
6087 
6088  if (mov->flags & FF_MOV_FLAG_DASH && mov->flags & FF_MOV_FLAG_GLOBAL_SIDX)
6089  ffio_wfourcc(pb, "dash");
6090 
6091  if (has_id3)
6092  ffio_wfourcc(pb, "aid3");
6093 
6094  return update_size(pb, pos);
6095 }
6096 
6098 {
6099  AVStream *video_st = s->streams[0];
6100  AVCodecParameters *video_par = s->streams[0]->codecpar;
6101  AVCodecParameters *audio_par = s->streams[1]->codecpar;
6102  int audio_rate = audio_par->sample_rate;
6103  int64_t frame_rate = video_st->avg_frame_rate.den ?
6105  0;
6106  int audio_kbitrate = audio_par->bit_rate / 1000;
6107  int video_kbitrate = FFMIN(video_par->bit_rate / 1000, 800 - audio_kbitrate);
6108 
6109  if (frame_rate < 0 || frame_rate > INT32_MAX) {
6110  av_log(s, AV_LOG_ERROR, "Frame rate %f outside supported range\n", frame_rate / (double)0x10000);
6111  return AVERROR(EINVAL);
6112  }
6113 
6114  avio_wb32(pb, 0x94); /* size */
6115  ffio_wfourcc(pb, "uuid");
6116  ffio_wfourcc(pb, "PROF");
6117 
6118  avio_wb32(pb, 0x21d24fce); /* 96 bit UUID */
6119  avio_wb32(pb, 0xbb88695c);
6120  avio_wb32(pb, 0xfac9c740);
6121 
6122  avio_wb32(pb, 0x0); /* ? */
6123  avio_wb32(pb, 0x3); /* 3 sections ? */
6124 
6125  avio_wb32(pb, 0x14); /* size */
6126  ffio_wfourcc(pb, "FPRF");
6127  avio_wb32(pb, 0x0); /* ? */
6128  avio_wb32(pb, 0x0); /* ? */
6129  avio_wb32(pb, 0x0); /* ? */
6130 
6131  avio_wb32(pb, 0x2c); /* size */
6132  ffio_wfourcc(pb, "APRF"); /* audio */
6133  avio_wb32(pb, 0x0);
6134  avio_wb32(pb, 0x2); /* TrackID */
6135  ffio_wfourcc(pb, "mp4a");
6136  avio_wb32(pb, 0x20f);
6137  avio_wb32(pb, 0x0);
6138  avio_wb32(pb, audio_kbitrate);
6139  avio_wb32(pb, audio_kbitrate);
6140  avio_wb32(pb, audio_rate);
6141  avio_wb32(pb, audio_par->ch_layout.nb_channels);
6142 
6143  avio_wb32(pb, 0x34); /* size */
6144  ffio_wfourcc(pb, "VPRF"); /* video */
6145  avio_wb32(pb, 0x0);
6146  avio_wb32(pb, 0x1); /* TrackID */
6147  if (video_par->codec_id == AV_CODEC_ID_H264) {
6148  ffio_wfourcc(pb, "avc1");
6149  avio_wb16(pb, 0x014D);
6150  avio_wb16(pb, 0x0015);
6151  } else {
6152  ffio_wfourcc(pb, "mp4v");
6153  avio_wb16(pb, 0x0000);
6154  avio_wb16(pb, 0x0103);
6155  }
6156  avio_wb32(pb, 0x0);
6157  avio_wb32(pb, video_kbitrate);
6158  avio_wb32(pb, video_kbitrate);
6159  avio_wb32(pb, frame_rate);
6160  avio_wb32(pb, frame_rate);
6161  avio_wb16(pb, video_par->width);
6162  avio_wb16(pb, video_par->height);
6163  avio_wb32(pb, 0x010001); /* ? */
6164 
6165  return 0;
6166 }
6167 
6169 {
6170  MOVMuxContext *mov = s->priv_data;
6171  int i;
6172 
6173  mov_write_ftyp_tag(pb,s);
6174  if (mov->mode == MODE_PSP) {
6175  int video_streams_nb = 0, audio_streams_nb = 0, other_streams_nb = 0;
6176  for (i = 0; i < mov->nb_streams; i++) {
6177  AVStream *st = mov->tracks[i].st;
6178  if (is_cover_image(st))
6179  continue;
6181  video_streams_nb++;
6182  else if (st->codecpar->codec_type == AVMEDIA_TYPE_AUDIO)
6183  audio_streams_nb++;
6184  else
6185  other_streams_nb++;
6186  }
6187 
6188  if (video_streams_nb != 1 || audio_streams_nb != 1 || other_streams_nb) {
6189  av_log(s, AV_LOG_ERROR, "PSP mode need one video and one audio stream\n");
6190  return AVERROR(EINVAL);
6191  }
6192  return mov_write_uuidprof_tag(pb, s);
6193  }
6194  return 0;
6195 }
6196 
6197 static int mov_parse_mpeg2_frame(AVPacket *pkt, uint32_t *flags)
6198 {
6199  uint32_t c = -1;
6200  int i, closed_gop = 0;
6201 
6202  for (i = 0; i < pkt->size - 4; i++) {
6203  c = (c << 8) + pkt->data[i];
6204  if (c == 0x1b8) { // gop
6205  closed_gop = pkt->data[i + 4] >> 6 & 0x01;
6206  } else if (c == 0x100) { // pic
6207  int temp_ref = (pkt->data[i + 1] << 2) | (pkt->data[i + 2] >> 6);
6208  if (!temp_ref || closed_gop) // I picture is not reordered
6210  else
6212  break;
6213  }
6214  }
6215  return 0;
6216 }
6217 
6219 {
6220  const uint8_t *start, *next, *end = pkt->data + pkt->size;
6221  int seq = 0, entry = 0;
6222  int key = pkt->flags & AV_PKT_FLAG_KEY;
6223  start = find_next_marker(pkt->data, end);
6224  for (next = start; next < end; start = next) {
6225  next = find_next_marker(start + 4, end);
6226  switch (AV_RB32(start)) {
6227  case VC1_CODE_SEQHDR:
6228  seq = 1;
6229  break;
6230  case VC1_CODE_ENTRYPOINT:
6231  entry = 1;
6232  break;
6233  case VC1_CODE_SLICE:
6234  trk->vc1_info.slices = 1;
6235  break;
6236  }
6237  }
6238  if (!trk->entry && trk->vc1_info.first_packet_seen)
6239  trk->vc1_info.first_frag_written = 1;
6240  if (!trk->entry && !trk->vc1_info.first_frag_written) {
6241  /* First packet in first fragment */
6242  trk->vc1_info.first_packet_seq = seq;
6244  trk->vc1_info.first_packet_seen = 1;
6245  } else if ((seq && !trk->vc1_info.packet_seq) ||
6246  (entry && !trk->vc1_info.packet_entry)) {
6247  int i;
6248  for (i = 0; i < trk->entry; i++)
6249  trk->cluster[i].flags &= ~MOV_SYNC_SAMPLE;
6250  trk->has_keyframes = 0;
6251  if (seq)
6252  trk->vc1_info.packet_seq = 1;
6253  if (entry)
6254  trk->vc1_info.packet_entry = 1;
6255  if (!trk->vc1_info.first_frag_written) {
6256  /* First fragment */
6257  if ((!seq || trk->vc1_info.first_packet_seq) &&
6258  (!entry || trk->vc1_info.first_packet_entry)) {
6259  /* First packet had the same headers as this one, readd the
6260  * sync sample flag. */
6261  trk->cluster[0].flags |= MOV_SYNC_SAMPLE;
6262  trk->has_keyframes = 1;
6263  }
6264  }
6265  }
6266  if (trk->vc1_info.packet_seq && trk->vc1_info.packet_entry)
6267  key = seq && entry;
6268  else if (trk->vc1_info.packet_seq)
6269  key = seq;
6270  else if (trk->vc1_info.packet_entry)
6271  key = entry;
6272  if (key) {
6273  trk->cluster[trk->entry].flags |= MOV_SYNC_SAMPLE;
6274  trk->has_keyframes++;
6275  }
6276 }
6277 
6279 {
6280  int length;
6281 
6282  if (pkt->size < 8)
6283  return;
6284 
6285  length = (AV_RB16(pkt->data) & 0xFFF) * 2;
6286  if (length < 8 || length > pkt->size)
6287  return;
6288 
6289  if (AV_RB32(pkt->data + 4) == 0xF8726FBA) {
6290  trk->cluster[trk->entry].flags |= MOV_SYNC_SAMPLE;
6291  trk->has_keyframes++;
6292  }
6293 
6294  return;
6295 }
6296 
6298 {
6299  MOVMuxContext *mov = s->priv_data;
6300  int ret, buf_size;
6301  uint8_t *buf;
6302  int i, offset;
6303 
6304  if (!track->mdat_buf)
6305  return 0;
6306  if (!mov->mdat_buf) {
6307  if ((ret = avio_open_dyn_buf(&mov->mdat_buf)) < 0)
6308  return ret;
6309  }
6310  buf_size = avio_get_dyn_buf(track->mdat_buf, &buf);
6311 
6312  offset = avio_tell(mov->mdat_buf);
6313  avio_write(mov->mdat_buf, buf, buf_size);
6314  ffio_free_dyn_buf(&track->mdat_buf);
6315 
6316  for (i = track->entries_flushed; i < track->entry; i++)
6317  track->cluster[i].pos += offset;
6318  track->entries_flushed = track->entry;
6319  return 0;
6320 }
6321 
6323 {
6324  MOVMuxContext *mov = s->priv_data;
6325  AVPacket *squashed_packet = mov->pkt;
6326  int ret = AVERROR_BUG;
6327 
6328  switch (track->st->codecpar->codec_id) {
6329  case AV_CODEC_ID_TTML: {
6330  int had_packets = !!track->squashed_packet_queue.head;
6331 
6332  if ((ret = ff_mov_generate_squashed_ttml_packet(s, track, squashed_packet)) < 0) {
6333  goto finish_squash;
6334  }
6335 
6336  // We have generated a padding packet (no actual input packets in
6337  // queue) and its duration is zero. Skipping writing it.
6338  if (!had_packets && squashed_packet->duration == 0) {
6339  goto finish_squash;
6340  }
6341 
6342  track->end_reliable = 1;
6343  break;
6344  }
6345  default:
6346  ret = AVERROR(EINVAL);
6347  goto finish_squash;
6348  }
6349 
6350  squashed_packet->stream_index = track->st->index;
6351 
6352  ret = mov_write_single_packet(s, squashed_packet);
6353 
6354 finish_squash:
6355  av_packet_unref(squashed_packet);
6356 
6357  return ret;
6358 }
6359 
6361 {
6362  MOVMuxContext *mov = s->priv_data;
6363 
6364  for (int i = 0; i < mov->nb_streams; i++) {
6365  MOVTrack *track = &mov->tracks[i];
6366  int ret = AVERROR_BUG;
6367 
6368  if (track->squash_fragment_samples_to_one && !track->entry) {
6369  if ((ret = mov_write_squashed_packet(s, track)) < 0) {
6371  "Failed to write squashed packet for %s stream with "
6372  "index %d and track id %d. Error: %s\n",
6374  track->st->index, track->track_id,
6375  av_err2str(ret));
6376  return ret;
6377  }
6378  }
6379  }
6380 
6381  return 0;
6382 }
6383 
6385  int64_t ref_pos)
6386 {
6387  int i;
6388  if (!track->entry)
6389  return 0;
6390  if (mov->flags & FF_MOV_FLAG_HYBRID_FRAGMENTED) {
6391  for (i = 0; i < track->entry; i++)
6392  track->cluster[i].pos += ref_pos + track->data_offset;
6393  if (track->cluster_written == 0) {
6394  // First flush. Chunking for this fragment may already have been
6395  // done, either if we didn't use empty_moov, or if we did use
6396  // delay_moov. In either case, reset chunking here.
6397  for (i = 0; i < track->entry; i++) {
6398  track->cluster[i].chunkNum = 0;
6399  track->cluster[i].samples_in_chunk = track->cluster[i].entries;
6400  }
6401  }
6402  if (av_reallocp_array(&track->cluster_written,
6403  track->entry_written + track->entry,
6404  sizeof(*track->cluster)))
6405  return AVERROR(ENOMEM);
6406  memcpy(&track->cluster_written[track->entry_written],
6407  track->cluster, track->entry * sizeof(*track->cluster));
6408  track->entry_written += track->entry;
6409  }
6410  track->entry = 0;
6411  track->entries_flushed = 0;
6412  track->end_reliable = 0;
6413  return 0;
6414 }
6415 
6416 static int mov_flush_fragment(AVFormatContext *s, int force)
6417 {
6418  MOVMuxContext *mov = s->priv_data;
6419  int i, first_track = -1;
6420  int64_t mdat_size = 0, mdat_start = 0;
6421  int ret;
6422  int has_video = 0, starts_with_key = 0, first_video_track = 1;
6423 
6424  if (!(mov->flags & FF_MOV_FLAG_FRAGMENT))
6425  return 0;
6426 
6427  // Check if we have any tracks that require squashing.
6428  // In that case, we'll have to write the packet here.
6429  if ((ret = mov_write_squashed_packets(s)) < 0)
6430  return ret;
6431 
6432  // Try to fill in the duration of the last packet in each stream
6433  // from queued packets in the interleave queues. If the flushing
6434  // of fragments was triggered automatically by an AVPacket, we
6435  // already have reliable info for the end of that track, but other
6436  // tracks may need to be filled in.
6437  for (i = 0; i < mov->nb_streams; i++) {
6438  MOVTrack *track = &mov->tracks[i];
6439  if (!track->end_reliable) {
6440  const AVPacket *pkt = ff_interleaved_peek(s, i);
6441  if (pkt) {
6442  int64_t offset, dts, pts;
6444  pts = pkt->pts + offset;
6445  dts = pkt->dts + offset;
6446  if (track->dts_shift != AV_NOPTS_VALUE)
6447  dts += track->dts_shift;
6448  track->track_duration = dts - track->start_dts;
6449  if (pts != AV_NOPTS_VALUE)
6450  track->end_pts = pts;
6451  else
6452  track->end_pts = dts;
6453  }
6454  }
6455  }
6456 
6457  for (i = 0; i < mov->nb_tracks; i++) {
6458  MOVTrack *track = &mov->tracks[i];
6459  if (track->entry <= 1)
6460  continue;
6461  // Sample durations are calculated as the diff of dts values,
6462  // but for the last sample in a fragment, we don't know the dts
6463  // of the first sample in the next fragment, so we have to rely
6464  // on what was set as duration in the AVPacket. Not all callers
6465  // set this though, so we might want to replace it with an
6466  // estimate if it currently is zero.
6467  if (get_cluster_duration(track, track->entry - 1) != 0)
6468  continue;
6469  // Use the duration (i.e. dts diff) of the second last sample for
6470  // the last one. This is a wild guess (and fatal if it turns out
6471  // to be too long), but probably the best we can do - having a zero
6472  // duration is bad as well.
6473  track->track_duration += get_cluster_duration(track, track->entry - 2);
6474  track->end_pts += get_cluster_duration(track, track->entry - 2);
6475  if (!mov->missing_duration_warned) {
6477  "Estimating the duration of the last packet in a "
6478  "fragment, consider setting the duration field in "
6479  "AVPacket instead.\n");
6480  mov->missing_duration_warned = 1;
6481  }
6482  }
6483 
6484  if (!mov->moov_written) {
6485  int64_t pos = avio_tell(s->pb);
6486  uint8_t *buf;
6487  int buf_size, moov_size;
6488 
6489  for (i = 0; i < mov->nb_tracks; i++)
6490  if (!mov->tracks[i].entry && !is_cover_image(mov->tracks[i].st))
6491  break;
6492  /* Don't write the initial moov unless all tracks have data */
6493  if (i < mov->nb_tracks && !force)
6494  return 0;
6495 
6496  moov_size = get_moov_size(s);
6497  for (i = 0; i < mov->nb_tracks; i++)
6498  mov->tracks[i].data_offset = pos + moov_size + 8;
6499 
6501  if (mov->flags & FF_MOV_FLAG_DELAY_MOOV)
6503  if ((ret = mov_write_moov_tag(s->pb, mov, s)) < 0)
6504  return ret;
6505 
6506  if (mov->flags & FF_MOV_FLAG_DELAY_MOOV) {
6507  if (mov->flags & FF_MOV_FLAG_GLOBAL_SIDX)
6508  mov->reserved_header_pos = avio_tell(s->pb);
6510  mov->moov_written = 1;
6511  return 0;
6512  }
6513 
6514  buf_size = avio_get_dyn_buf(mov->mdat_buf, &buf);
6515  avio_wb32(s->pb, buf_size + 8);
6516  ffio_wfourcc(s->pb, "mdat");
6517  avio_write(s->pb, buf, buf_size);
6518  ffio_free_dyn_buf(&mov->mdat_buf);
6519 
6520  if (mov->flags & FF_MOV_FLAG_GLOBAL_SIDX)
6521  mov->reserved_header_pos = avio_tell(s->pb);
6522 
6523  mov->moov_written = 1;
6524  mov->mdat_size = 0;
6525  for (i = 0; i < mov->nb_tracks; i++)
6526  mov_finish_fragment(mov, &mov->tracks[i], 0);
6528  return 0;
6529  }
6530 
6531  if (mov->frag_interleave) {
6532  for (i = 0; i < mov->nb_tracks; i++) {
6533  MOVTrack *track = &mov->tracks[i];
6534  int ret;
6535  if ((ret = mov_flush_fragment_interleaving(s, track)) < 0)
6536  return ret;
6537  }
6538 
6539  if (!mov->mdat_buf)
6540  return 0;
6541  mdat_size = avio_tell(mov->mdat_buf);
6542  }
6543 
6544  for (i = 0; i < mov->nb_tracks; i++) {
6545  MOVTrack *track = &mov->tracks[i];
6546  if (mov->flags & FF_MOV_FLAG_SEPARATE_MOOF || mov->frag_interleave)
6547  track->data_offset = 0;
6548  else
6549  track->data_offset = mdat_size;
6550  if (track->par->codec_type == AVMEDIA_TYPE_VIDEO) {
6551  has_video = 1;
6552  if (first_video_track) {
6553  if (track->entry)
6554  starts_with_key = track->cluster[0].flags & MOV_SYNC_SAMPLE;
6555  first_video_track = 0;
6556  }
6557  }
6558  if (!track->entry)
6559  continue;
6560  if (track->mdat_buf)
6561  mdat_size += avio_tell(track->mdat_buf);
6562  if (first_track < 0)
6563  first_track = i;
6564  }
6565 
6566  if (!mdat_size)
6567  return 0;
6568 
6569  avio_write_marker(s->pb,
6570  av_rescale(mov->tracks[first_track].cluster[0].dts, AV_TIME_BASE, mov->tracks[first_track].timescale),
6571  (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);
6572 
6573  for (i = first_track; i < mov->nb_tracks; i++) {
6574  MOVTrack *track = &mov->tracks[i];
6575  int buf_size, write_moof = 1, moof_tracks = -1;
6576  uint8_t *buf;
6577 
6578  if (!track->entry)
6579  continue;
6580  if (mov->flags & FF_MOV_FLAG_SEPARATE_MOOF) {
6581  mdat_size = avio_tell(track->mdat_buf);
6582  moof_tracks = i;
6583  } else {
6584  write_moof = i == first_track;
6585  }
6586 
6587  if (write_moof) {
6589 
6590  mov_write_moof_tag(s->pb, mov, moof_tracks, mdat_size);
6591  mov->fragments++;
6592 
6593  if (track->cenc.aes_ctr)
6594  ff_mov_cenc_flush(&track->cenc);
6595 
6596  avio_wb32(s->pb, mdat_size + 8);
6597  ffio_wfourcc(s->pb, "mdat");
6598  mdat_start = avio_tell(s->pb);
6599  }
6600 
6601  mov_finish_fragment(mov, &mov->tracks[i], mdat_start);
6602  if (!mov->frag_interleave) {
6603  if (!track->mdat_buf)
6604  continue;
6605  buf_size = avio_close_dyn_buf(track->mdat_buf, &buf);
6606  track->mdat_buf = NULL;
6607  } else {
6608  if (!mov->mdat_buf)
6609  continue;
6610  buf_size = avio_close_dyn_buf(mov->mdat_buf, &buf);
6611  mov->mdat_buf = NULL;
6612  }
6613 
6614  avio_write(s->pb, buf, buf_size);
6615  av_free(buf);
6616  }
6617 
6618  mov->mdat_size = 0;
6619 
6621  return 0;
6622 }
6623 
6625 {
6626  MOVMuxContext *mov = s->priv_data;
6627  int had_moov = mov->moov_written;
6628  int ret = mov_flush_fragment(s, force);
6629  if (ret < 0)
6630  return ret;
6631  // If using delay_moov, the first flush only wrote the moov,
6632  // not the actual moof+mdat pair, thus flush once again.
6633  if (!had_moov && mov->flags & FF_MOV_FLAG_DELAY_MOOV)
6634  ret = mov_flush_fragment(s, force);
6635  return ret;
6636 }
6637 
6639 {
6640  int64_t ref;
6641  uint64_t duration;
6642 
6643  if (trk->entry) {
6644  ref = trk->cluster[trk->entry - 1].dts;
6645  } else if ( trk->start_dts != AV_NOPTS_VALUE
6646  && !trk->frag_discont) {
6647  ref = trk->start_dts + trk->track_duration;
6648  } else
6649  ref = pkt->dts; // Skip tests for the first packet
6650 
6651  if (trk->dts_shift != AV_NOPTS_VALUE) {
6652  /* With negative CTS offsets we have set an offset to the DTS,
6653  * reverse this for the check. */
6654  ref -= trk->dts_shift;
6655  }
6656 
6657  duration = pkt->dts - ref;
6658  if (pkt->dts < ref || duration >= INT_MAX) {
6659  av_log(s, AV_LOG_WARNING, "Packet duration: %"PRId64" / dts: %"PRId64" in stream %d is out of range\n",
6661 
6662  pkt->dts = ref + 1;
6663  pkt->pts = AV_NOPTS_VALUE;
6664  }
6665 
6666  if (pkt->duration < 0 || pkt->duration > INT_MAX) {
6667  av_log(s, AV_LOG_ERROR, "Application provided duration: %"PRId64" in stream %d is invalid\n", pkt->duration, pkt->stream_index);
6668  return AVERROR(EINVAL);
6669  }
6670  return 0;
6671 }
6672 
6674 {
6675  MOVMuxContext *mov = s->priv_data;
6676  AVIOContext *pb = s->pb;
6677  MOVTrack *trk;
6678  AVCodecParameters *par;
6680  unsigned int samples_in_chunk = 0;
6681  int size = pkt->size, ret = 0, offset = 0;
6682  size_t prft_size;
6683  uint8_t *reformatted_data = NULL;
6684 
6685  if (pkt->stream_index < s->nb_streams)
6686  trk = s->streams[pkt->stream_index]->priv_data;
6687  else // Timecode or chapter
6688  trk = &mov->tracks[pkt->stream_index];
6689  par = trk->par;
6690 
6691  ret = check_pkt(s, trk, pkt);
6692  if (ret < 0)
6693  return ret;
6694 
6695  if (pkt->pts != AV_NOPTS_VALUE &&
6696  (uint64_t)pkt->dts - pkt->pts != (int32_t)((uint64_t)pkt->dts - pkt->pts)) {
6697  av_log(s, AV_LOG_WARNING, "pts/dts pair unsupported\n");
6698  return AVERROR_PATCHWELCOME;
6699  }
6700 
6701  if (mov->flags & FF_MOV_FLAG_FRAGMENT || mov->mode == MODE_AVIF) {
6702  int ret;
6703  if (mov->moov_written || mov->flags & FF_MOV_FLAG_EMPTY_MOOV) {
6704  if (mov->frag_interleave && mov->fragments > 0) {
6705  if (trk->entry - trk->entries_flushed >= mov->frag_interleave) {
6706  if ((ret = mov_flush_fragment_interleaving(s, trk)) < 0)
6707  return ret;
6708  }
6709  }
6710 
6711  if (!trk->mdat_buf) {
6712  if ((ret = avio_open_dyn_buf(&trk->mdat_buf)) < 0)
6713  return ret;
6714  }
6715  pb = trk->mdat_buf;
6716  } else {
6717  if (!mov->mdat_buf) {
6718  if ((ret = avio_open_dyn_buf(&mov->mdat_buf)) < 0)
6719  return ret;
6720  }
6721  pb = mov->mdat_buf;
6722  }
6723  }
6724 
6725  if (par->codec_id == AV_CODEC_ID_AMR_NB) {
6726  /* We must find out how many AMR blocks there are in one packet */
6727  static const uint16_t packed_size[16] =
6728  {13, 14, 16, 18, 20, 21, 27, 32, 6, 0, 0, 0, 0, 0, 0, 1};
6729  int len = 0;
6730 
6731  while (len < size && samples_in_chunk < 100) {
6732  len += packed_size[(pkt->data[len] >> 3) & 0x0F];
6733  samples_in_chunk++;
6734  }
6735  if (samples_in_chunk > 1) {
6736  av_log(s, AV_LOG_ERROR, "fatal error, input is not a single packet, implement a AVParser for it\n");
6737  return -1;
6738  }
6739  } else if (par->codec_id == AV_CODEC_ID_ADPCM_MS ||
6741  samples_in_chunk = trk->par->frame_size;
6742  } else if (trk->sample_size)
6743  samples_in_chunk = size / trk->sample_size;
6744  else
6745  samples_in_chunk = 1;
6746 
6747  if (samples_in_chunk < 1) {
6748  av_log(s, AV_LOG_ERROR, "fatal error, input packet contains no samples\n");
6749  return AVERROR_PATCHWELCOME;
6750  }
6751 
6752  /* copy extradata if it exists */
6753  if (trk->extradata_size[0] == 0 && par->extradata_size > 0 &&
6754  !TAG_IS_AVCI(trk->tag) &&
6755  (par->codec_id != AV_CODEC_ID_DNXHD)) {
6756  trk->extradata[0] = av_memdup(par->extradata, par->extradata_size);
6757  if (!trk->extradata[0]) {
6758  ret = AVERROR(ENOMEM);
6759  goto err;
6760  }
6761  trk->extradata_size[0] = par->extradata_size;
6762  }
6763 
6764  if ((par->codec_id == AV_CODEC_ID_DNXHD ||
6765  par->codec_id == AV_CODEC_ID_H264 ||
6766  par->codec_id == AV_CODEC_ID_HEVC ||
6767  par->codec_id == AV_CODEC_ID_VVC ||
6768  par->codec_id == AV_CODEC_ID_VP9 ||
6769  par->codec_id == AV_CODEC_ID_EVC ||
6770  par->codec_id == AV_CODEC_ID_TRUEHD) && !trk->extradata_size[0] &&
6771  !TAG_IS_AVCI(trk->tag)) {
6772  /* copy frame to create needed atoms */
6773  trk->extradata_size[0] = size;
6775  if (!trk->extradata[0]) {
6776  ret = AVERROR(ENOMEM);
6777  goto err;
6778  }
6779  memcpy(trk->extradata[0], pkt->data, size);
6780  memset(trk->extradata[0] + size, 0, AV_INPUT_BUFFER_PADDING_SIZE);
6781  }
6782 
6784  if (pkt->size && sd && sd->size > 0) {
6785  int i;
6786  for (i = 0; i < trk->stsd_count; i++) {
6787  if (trk->extradata_size[i] == sd->size && !memcmp(trk->extradata[i], sd->data, sd->size))
6788  break;
6789  }
6790 
6791  if (i < trk->stsd_count)
6792  trk->last_stsd_index = i;
6793  else if (trk->stsd_count <= INT_MAX - 1) {
6794  int new_count = trk->stsd_count + 1;
6795  uint8_t **extradata = av_realloc_array(trk->extradata, new_count, sizeof(*trk->extradata));
6796  if (!extradata)
6797  return AVERROR(ENOMEM);
6798  trk->extradata = extradata;
6799 
6800  int *extradata_size = av_realloc_array(trk->extradata_size, new_count, sizeof(*trk->extradata_size));
6801  if (!extradata_size)
6802  return AVERROR(ENOMEM);
6803  trk->extradata_size = extradata_size;
6804 
6805  trk->extradata[trk->stsd_count] = av_memdup(sd->data, sd->size);
6806  if (!trk->extradata[trk->stsd_count])
6807  return AVERROR(ENOMEM);
6808 
6809  trk->extradata_size[trk->stsd_count] = sd->size;
6810  trk->last_stsd_index = trk->stsd_count;
6811  trk->stsd_count = new_count;
6812  } else
6813  return AVERROR(ENOMEM);
6814  }
6815 
6816  if (par->codec_id == AV_CODEC_ID_AAC && pkt->size > 2 &&
6817  (AV_RB16(pkt->data) & 0xfff0) == 0xfff0) {
6818  if (!trk->st->nb_frames) {
6819  av_log(s, AV_LOG_ERROR, "Malformed AAC bitstream detected: "
6820  "use the audio bitstream filter 'aac_adtstoasc' to fix it "
6821  "('-bsf:a aac_adtstoasc' option with ffmpeg)\n");
6822  return -1;
6823  }
6824  av_log(s, AV_LOG_WARNING, "aac bitstream error\n");
6825  }
6826  if (par->codec_id == AV_CODEC_ID_H264 && trk->extradata_size[trk->last_stsd_index] > 0 &&
6827  *(uint8_t *)trk->extradata[trk->last_stsd_index] != 1 && !TAG_IS_AVCI(trk->tag)) {
6828  /* from x264 or from bytestream H.264 */
6829  /* NAL reformatting needed */
6830  if (trk->hint_track >= 0 && trk->hint_track < mov->nb_tracks) {
6831  ret = ff_nal_parse_units_buf(pkt->data, &reformatted_data,
6832  &size);
6833  if (ret < 0)
6834  return ret;
6835  avio_write(pb, reformatted_data, size);
6836  } else {
6837  if (trk->cenc.aes_ctr) {
6839  if (size < 0) {
6840  ret = size;
6841  goto err;
6842  }
6843  } else {
6844  size = ff_nal_parse_units(pb, pkt->data, pkt->size);
6845  }
6846  }
6847  } else if (par->codec_id == AV_CODEC_ID_HEVC && trk->extradata_size[trk->last_stsd_index] > 6 &&
6848  (AV_RB24(trk->extradata[trk->last_stsd_index]) == 1 || AV_RB32(trk->extradata[trk->last_stsd_index]) == 1)) {
6849  /* extradata is Annex B, assume the bitstream is too and convert it */
6850  int filter_ps = (trk->tag == MKTAG('h','v','c','1'));
6851  if (trk->hint_track >= 0 && trk->hint_track < mov->nb_tracks) {
6852  ret = ff_hevc_annexb2mp4_buf(pkt->data, &reformatted_data,
6853  &size, filter_ps, NULL);
6854  if (ret < 0)
6855  return ret;
6856  avio_write(pb, reformatted_data, size);
6857  } else {
6858  if (trk->cenc.aes_ctr) {
6860  if (size < 0) {
6861  ret = size;
6862  goto err;
6863  }
6864  } else {
6865  size = ff_hevc_annexb2mp4(pb, pkt->data, pkt->size, filter_ps, NULL);
6866  }
6867  }
6868  } else if (par->codec_id == AV_CODEC_ID_VVC && trk->extradata_size[trk->last_stsd_index] > 6 &&
6869  (AV_RB24(trk->extradata[trk->last_stsd_index]) == 1 || AV_RB32(trk->extradata[trk->last_stsd_index]) == 1)) {
6870  /* extradata is Annex B, assume the bitstream is too and convert it */
6871  if (trk->hint_track >= 0 && trk->hint_track < mov->nb_tracks) {
6872  ret = ff_vvc_annexb2mp4_buf(pkt->data, &reformatted_data,
6873  &size, 0, NULL);
6874  if (ret < 0)
6875  return ret;
6876  avio_write(pb, reformatted_data, size);
6877  } else {
6878  size = ff_vvc_annexb2mp4(pb, pkt->data, pkt->size, 0, NULL);
6879  }
6880  } else if (par->codec_id == AV_CODEC_ID_AV1 && !trk->cenc.aes_ctr) {
6881  if (trk->hint_track >= 0 && trk->hint_track < mov->nb_tracks) {
6882  ret = ff_av1_filter_obus_buf(pkt->data, &reformatted_data,
6883  &size, &offset);
6884  if (ret < 0)
6885  return ret;
6886  avio_write(pb, reformatted_data, size);
6887  } else {
6888  size = ff_av1_filter_obus(pb, pkt->data, pkt->size);
6889  if (trk->mode == MODE_AVIF && !mov->avif_extent_length[pkt->stream_index]) {
6891  }
6892  }
6893 
6894  } else if (par->codec_id == AV_CODEC_ID_AC3 ||
6895  par->codec_id == AV_CODEC_ID_EAC3) {
6896  size = handle_eac3(mov, pkt, trk);
6897  if (size < 0)
6898  return size;
6899  else if (!size)
6900  goto end;
6901  avio_write(pb, pkt->data, size);
6902  } else if (par->codec_id == AV_CODEC_ID_EIA_608) {
6903  size = 8;
6904 
6905  for (int i = 0; i < pkt->size; i += 3) {
6906  if (pkt->data[i] == 0xFC) {
6907  size += 2;
6908  }
6909  }
6910  avio_wb32(pb, size);
6911  ffio_wfourcc(pb, "cdat");
6912  for (int i = 0; i < pkt->size; i += 3) {
6913  if (pkt->data[i] == 0xFC) {
6914  avio_w8(pb, pkt->data[i + 1]);
6915  avio_w8(pb, pkt->data[i + 2]);
6916  }
6917  }
6918  } else if (par->codec_id == AV_CODEC_ID_APV) {
6919  ff_isom_parse_apvc(trk->apv, pkt, s);
6920  avio_wb32(s->pb, pkt->size);
6921  size += 4;
6922 
6923  avio_write(s->pb, pkt->data, pkt->size);
6924  } else {
6925  if (trk->cenc.aes_ctr) {
6926  uint8_t *extradata = trk->extradata[trk->last_stsd_index];
6927  int extradata_size = trk->extradata_size[trk->last_stsd_index];
6928  if (par->codec_id == AV_CODEC_ID_H264 && extradata_size > 4) {
6929  int nal_size_length = (extradata[4] & 0x3) + 1;
6930  ret = ff_mov_cenc_avc_write_nal_units(s, &trk->cenc, nal_size_length, pb, pkt->data, size);
6931  } else if(par->codec_id == AV_CODEC_ID_HEVC && extradata_size > 21) {
6932  int nal_size_length = (extradata[21] & 0x3) + 1;
6933  ret = ff_mov_cenc_avc_write_nal_units(s, &trk->cenc, nal_size_length, pb, pkt->data, size);
6934  } else if(par->codec_id == AV_CODEC_ID_VVC) {
6936  } else if(par->codec_id == AV_CODEC_ID_AV1) {
6937  av_assert0(size == pkt->size);
6938  ret = ff_mov_cenc_av1_write_obus(s, &trk->cenc, pb, pkt);
6939  if (ret > 0) {
6940  size = ret;
6941  ret = 0;
6942  }
6943  } else {
6944  ret = ff_mov_cenc_write_packet(&trk->cenc, pb, pkt->data, size);
6945  }
6946 
6947  if (ret) {
6948  goto err;
6949  }
6950  } else {
6951  avio_write(pb, pkt->data, size);
6952  }
6953  }
6954 
6955  if (trk->entry >= trk->cluster_capacity) {
6956  unsigned new_capacity = trk->entry + MOV_INDEX_CLUSTER_SIZE;
6957  void *cluster = av_realloc_array(trk->cluster, new_capacity, sizeof(*trk->cluster));
6958  if (!cluster) {
6959  ret = AVERROR(ENOMEM);
6960  goto err;
6961  }
6962  trk->cluster = cluster;
6963  trk->cluster_capacity = new_capacity;
6964  }
6965 
6966  trk->cluster[trk->entry].pos = avio_tell(pb) - size;
6967  trk->cluster[trk->entry].stsd_index = trk->last_stsd_index;
6968  trk->cluster[trk->entry].samples_in_chunk = samples_in_chunk;
6969  trk->cluster[trk->entry].chunkNum = 0;
6970  trk->cluster[trk->entry].size = size;
6971  trk->cluster[trk->entry].entries = samples_in_chunk;
6972  trk->cluster[trk->entry].dts = pkt->dts;
6973  trk->cluster[trk->entry].pts = pkt->pts;
6974  if (!trk->squash_fragment_samples_to_one &&
6975  !trk->entry && trk->start_dts != AV_NOPTS_VALUE) {
6976  if (!trk->frag_discont) {
6977  /* First packet of a new fragment. We already wrote the duration
6978  * of the last packet of the previous fragment based on track_duration,
6979  * which might not exactly match our dts. Therefore adjust the dts
6980  * of this packet to be what the previous packets duration implies. */
6981  trk->cluster[trk->entry].dts = trk->start_dts + trk->track_duration;
6982  /* We also may have written the pts and the corresponding duration
6983  * in sidx/tfrf/tfxd tags; make sure the sidx pts and duration match up with
6984  * the next fragment. This means the cts of the first sample must
6985  * be the same in all fragments, unless end_pts was updated by
6986  * the packet causing the fragment to be written. */
6987  if ((mov->flags & FF_MOV_FLAG_DASH &&
6989  mov->mode == MODE_ISM)
6990  pkt->pts = pkt->dts + trk->end_pts - trk->cluster[trk->entry].dts;
6991  } else {
6992  /* New fragment, but discontinuous from previous fragments.
6993  * Pretend the duration sum of the earlier fragments is
6994  * pkt->dts - trk->start_dts. */
6995  trk->end_pts = AV_NOPTS_VALUE;
6996  trk->frag_discont = 0;
6997  }
6998  }
6999 
7000  if (!trk->entry && trk->start_dts == AV_NOPTS_VALUE && !mov->use_editlist &&
7001  s->avoid_negative_ts == AVFMT_AVOID_NEG_TS_MAKE_ZERO) {
7002  /* Not using edit lists and shifting the first track to start from zero.
7003  * If the other streams start from a later timestamp, we won't be able
7004  * to signal the difference in starting time without an edit list.
7005  * Thus move the timestamp for this first sample to 0, increasing
7006  * its duration instead. */
7007  trk->cluster[trk->entry].dts = trk->start_dts = 0;
7008  }
7009  if (trk->start_dts == AV_NOPTS_VALUE) {
7010  trk->start_dts = pkt->dts;
7011  if (trk->frag_discont) {
7012  if (mov->use_editlist) {
7013  /* Pretend the whole stream started at pts=0, with earlier fragments
7014  * already written. If the stream started at pts=0, the duration sum
7015  * of earlier fragments would have been pkt->pts. */
7016  trk->start_dts = pkt->dts - pkt->pts;
7017  } else {
7018  /* Pretend the whole stream started at dts=0, with earlier fragments
7019  * already written, with a duration summing up to pkt->dts. */
7020  trk->start_dts = 0;
7021  }
7022  trk->frag_discont = 0;
7023  } else if (pkt->dts && mov->moov_written)
7025  "Track %d starts with a nonzero dts %"PRId64", while the moov "
7026  "already has been written. Set the delay_moov flag to handle "
7027  "this case.\n",
7028  pkt->stream_index, pkt->dts);
7029  }
7030  trk->track_duration = pkt->dts - trk->start_dts + pkt->duration;
7031  trk->last_sample_is_subtitle_end = 0;
7032 
7033  if (pkt->pts == AV_NOPTS_VALUE) {
7034  av_log(s, AV_LOG_WARNING, "pts has no value\n");
7035  pkt->pts = pkt->dts;
7036  }
7037  if (pkt->dts != pkt->pts)
7038  trk->flags |= MOV_TRACK_CTTS;
7039  trk->cluster[trk->entry].cts = pkt->pts - pkt->dts;
7040  trk->cluster[trk->entry].flags = 0;
7041  if (trk->start_cts == AV_NOPTS_VALUE || (pkt->dts <= 0 && trk->start_cts > pkt->pts - pkt->dts))
7042  trk->start_cts = pkt->pts - pkt->dts;
7043  if (trk->end_pts == AV_NOPTS_VALUE)
7044  trk->end_pts = trk->cluster[trk->entry].dts +
7045  trk->cluster[trk->entry].cts + pkt->duration;
7046  else
7047  trk->end_pts = FFMAX(trk->end_pts, trk->cluster[trk->entry].dts +
7048  trk->cluster[trk->entry].cts +
7049  pkt->duration);
7050 
7051  if (par->codec_id == AV_CODEC_ID_VC1) {
7052  mov_parse_vc1_frame(pkt, trk);
7053  } else if (par->codec_id == AV_CODEC_ID_TRUEHD) {
7055  } else if (pkt->flags & AV_PKT_FLAG_KEY) {
7056  if (mov->mode == MODE_MOV && par->codec_id == AV_CODEC_ID_MPEG2VIDEO &&
7057  trk->entry > 0) { // force sync sample for the first key frame
7059  if (trk->cluster[trk->entry].flags & MOV_PARTIAL_SYNC_SAMPLE)
7060  trk->flags |= MOV_TRACK_STPS;
7061  } else {
7062  trk->cluster[trk->entry].flags = MOV_SYNC_SAMPLE;
7063  }
7064  if (trk->cluster[trk->entry].flags & MOV_SYNC_SAMPLE)
7065  trk->has_keyframes++;
7066  }
7067  if (pkt->flags & AV_PKT_FLAG_DISPOSABLE) {
7068  trk->cluster[trk->entry].flags |= MOV_DISPOSABLE_SAMPLE;
7069  trk->has_disposable++;
7070  }
7071 
7073  if (prft && prft_size == sizeof(AVProducerReferenceTime))
7074  memcpy(&trk->cluster[trk->entry].prft, prft, prft_size);
7075  else
7076  memset(&trk->cluster[trk->entry].prft, 0, sizeof(AVProducerReferenceTime));
7077 
7078  trk->entry++;
7079  trk->sample_count += samples_in_chunk;
7080  mov->mdat_size += size;
7081 
7082  if (trk->hint_track >= 0 && trk->hint_track < mov->nb_tracks)
7084  reformatted_data ? reformatted_data + offset
7085  : NULL, size);
7086 
7087 end:
7088 err:
7089 
7090  if (pkt->data != reformatted_data)
7091  av_free(reformatted_data);
7092  return ret;
7093 }
7094 
7096 {
7097  MOVMuxContext *mov = s->priv_data;
7098  MOVTrack *trk = s->streams[pkt->stream_index]->priv_data;
7099  AVCodecParameters *par = trk->par;
7100  int64_t frag_duration = 0;
7101  int size = pkt->size;
7102 
7103  int ret = check_pkt(s, trk, pkt);
7104  if (ret < 0)
7105  return ret;
7106 
7107  if (mov->flags & FF_MOV_FLAG_FRAG_DISCONT) {
7108  for (int i = 0; i < mov->nb_streams; i++)
7109  mov->tracks[i].frag_discont = 1;
7111  }
7112 
7114  if (trk->dts_shift == AV_NOPTS_VALUE)
7115  trk->dts_shift = pkt->pts - pkt->dts;
7116  pkt->dts += trk->dts_shift;
7117  }
7118 
7119  if (trk->par->codec_id == AV_CODEC_ID_MP4ALS ||
7120  trk->par->codec_id == AV_CODEC_ID_AAC ||
7121  trk->par->codec_id == AV_CODEC_ID_AV1 ||
7122  trk->par->codec_id == AV_CODEC_ID_FLAC) {
7123  size_t side_size;
7124  uint8_t *side = av_packet_get_side_data(pkt, AV_PKT_DATA_NEW_EXTRADATA, &side_size);
7125  /* Overwrite extradata only on flush packets or when no extradata was available during init */
7126  if (side_size > 0 && (!pkt->size || !trk->extradata_size[trk->last_stsd_index])) {
7127  void *newextra = av_memdup(side, side_size);
7128  if (!newextra)
7129  return AVERROR(ENOMEM);
7130  av_free(trk->extradata[trk->last_stsd_index]);
7131  trk->extradata[trk->last_stsd_index] = newextra;
7132  trk->extradata_size[trk->last_stsd_index] = side_size;
7133  }
7134  }
7135 
7136  if (!pkt->size) {
7137  if (trk->start_dts == AV_NOPTS_VALUE && trk->frag_discont) {
7138  trk->start_dts = pkt->dts;
7139  if (pkt->pts != AV_NOPTS_VALUE)
7140  trk->start_cts = pkt->pts - pkt->dts;
7141  else
7142  trk->start_cts = 0;
7143  }
7144 
7145  return 0; /* Discard 0 sized packets */
7146  }
7147 
7148  if (trk->entry && pkt->stream_index < mov->nb_streams)
7149  frag_duration = av_rescale_q(pkt->dts - trk->cluster[0].dts,
7150  s->streams[pkt->stream_index]->time_base,
7151  AV_TIME_BASE_Q);
7152  if ((mov->max_fragment_duration &&
7153  frag_duration >= mov->max_fragment_duration) ||
7154  (mov->max_fragment_size && mov->mdat_size + size >= mov->max_fragment_size) ||
7155  (mov->flags & FF_MOV_FLAG_FRAG_KEYFRAME &&
7156  par->codec_type == AVMEDIA_TYPE_VIDEO &&
7157  trk->entry && pkt->flags & AV_PKT_FLAG_KEY) ||
7159  if (frag_duration >= mov->min_fragment_duration) {
7160  if (trk->entry) {
7161  // Set the duration of this track to line up with the next
7162  // sample in this track. This avoids relying on AVPacket
7163  // duration, but only helps for this particular track, not
7164  // for the other ones that are flushed at the same time.
7165  //
7166  // If we have trk->entry == 0, no fragment will be written
7167  // for this track, and we can't adjust the track end here.
7168  trk->track_duration = pkt->dts - trk->start_dts;
7169  if (pkt->pts != AV_NOPTS_VALUE)
7170  trk->end_pts = pkt->pts;
7171  else
7172  trk->end_pts = pkt->dts;
7173  trk->end_reliable = 1;
7174  }
7176  }
7177  }
7178 
7179  return ff_mov_write_packet(s, pkt);
7180 }
7181 
7183  int stream_index,
7184  int64_t dts) {
7185  MOVMuxContext *mov = s->priv_data;
7186  AVPacket *end = mov->pkt;
7187  uint8_t data[2] = {0};
7188  int ret;
7189 
7190  end->size = sizeof(data);
7191  end->data = data;
7192  end->pts = dts;
7193  end->dts = dts;
7194  end->duration = 0;
7195  end->stream_index = stream_index;
7196 
7197  ret = mov_write_single_packet(s, end);
7198  av_packet_unref(end);
7199 
7200  return ret;
7201 }
7202 
7203 #if CONFIG_IAMFENC
7204 static int mov_build_iamf_packet(AVFormatContext *s, MOVTrack *trk, AVPacket *pkt)
7205 {
7206  uint8_t *data;
7207  int ret;
7208 
7209  if (pkt->stream_index == trk->first_iamf_idx) {
7211  if (ret < 0)
7212  return ret;
7213  }
7214 
7216  s->streams[pkt->stream_index]->id, pkt);
7217  if (ret < 0)
7218  return ret;
7219 
7220  if (pkt->stream_index != trk->last_iamf_idx)
7221  return AVERROR(EAGAIN);
7222 
7223  ret = avio_close_dyn_buf(trk->iamf_buf, &data);
7224  trk->iamf_buf = NULL;
7225  if (!ret) {
7226  if (pkt->size) {
7227  // Either all or none of the packets for a single
7228  // IA Sample may be empty.
7229  av_log(s, AV_LOG_ERROR, "Unexpected packet from "
7230  "stream #%d\n", pkt->stream_index);
7232  }
7233  av_free(data);
7234  return ret;
7235  }
7236 
7237  av_buffer_unref(&pkt->buf);
7238  pkt->buf = av_buffer_create(data, ret, NULL, NULL, 0);
7239  if (!pkt->buf) {
7240  av_free(data);
7241  return AVERROR(ENOMEM);
7242  }
7243  pkt->data = data;
7244  pkt->size = ret;
7246 
7247  return avio_open_dyn_buf(&trk->iamf_buf);
7248 }
7249 #endif
7250 
7252 {
7253  int64_t pos = avio_tell(pb);
7254  const char *scheme_id_uri = "https://aomedia.org/emsg/ID3";
7255  const char *value = "";
7256 
7257  av_assert0(st->time_base.num == 1);
7258 
7259  avio_write_marker(pb,
7262 
7263  avio_wb32(pb, 0); /* size */
7264  ffio_wfourcc(pb, "emsg");
7265  avio_w8(pb, 1); /* version */
7266  avio_wb24(pb, 0);
7267  avio_wb32(pb, st->time_base.den); /* timescale */
7268  avio_wb64(pb, pkt->pts); /* presentation_time */
7269  avio_wb32(pb, 0xFFFFFFFFU); /* event_duration */
7270  avio_wb32(pb, 0); /* id */
7271  /* null terminated UTF8 strings */
7272  avio_write(pb, scheme_id_uri, strlen(scheme_id_uri) + 1);
7273  avio_write(pb, value, strlen(value) + 1);
7274  avio_write(pb, pkt->data, pkt->size);
7275 
7276  return update_size(pb, pos);
7277 }
7278 
7280 {
7281  MOVMuxContext *mov = s->priv_data;
7282  MOVTrack *trk;
7283 
7284  if (!pkt) {
7285  mov_flush_fragment(s, 1);
7286  return 1;
7287  }
7288 
7289  if (s->streams[pkt->stream_index]->codecpar->codec_id == AV_CODEC_ID_TIMED_ID3) {
7290  mov_write_emsg_tag(s->pb, s->streams[pkt->stream_index], pkt);
7291  return 0;
7292  }
7293 
7294  trk = s->streams[pkt->stream_index]->priv_data;
7295 
7296 #if CONFIG_IAMFENC
7297  if (trk->iamf) {
7298  int ret = mov_build_iamf_packet(s, trk, pkt);
7299  if (ret < 0) {
7300  if (ret == AVERROR(EAGAIN))
7301  return 0;
7302  av_log(s, AV_LOG_ERROR, "Error assembling an IAMF packet "
7303  "for stream #%d\n", trk->st->index);
7304  return ret;
7305  }
7306  }
7307 #endif
7308 
7309  if (is_cover_image(trk->st)) {
7310  int ret;
7311 
7312  if (trk->st->nb_frames >= 1) {
7313  if (trk->st->nb_frames == 1)
7314  av_log(s, AV_LOG_WARNING, "Got more than one picture in stream %d,"
7315  " ignoring.\n", pkt->stream_index);
7316  return 0;
7317  }
7318 
7319  if ((ret = av_packet_ref(trk->cover_image, pkt)) < 0)
7320  return ret;
7321 
7322  return 0;
7323  } else {
7324  int i;
7325 
7326  if (!pkt->size)
7327  return mov_write_single_packet(s, pkt); /* Passthrough. */
7328 
7329  /*
7330  * Subtitles require special handling.
7331  *
7332  * 1) For full compliance, every track must have a sample at
7333  * dts == 0, which is rarely true for subtitles. So, as soon
7334  * as we see any packet with dts > 0, write an empty subtitle
7335  * at dts == 0 for any subtitle track with no samples in it.
7336  *
7337  * 2) For each subtitle track, check if the current packet's
7338  * dts is past the duration of the last subtitle sample. If
7339  * so, we now need to write an end sample for that subtitle.
7340  *
7341  * This must be done conditionally to allow for subtitles that
7342  * immediately replace each other, in which case an end sample
7343  * is not needed, and is, in fact, actively harmful.
7344  *
7345  * 3) See mov_write_trailer for how the final end sample is
7346  * handled.
7347  */
7348  for (i = 0; i < mov->nb_tracks; i++) {
7349  MOVTrack *trk = &mov->tracks[i];
7350  int ret;
7351 
7352  if (trk->par->codec_id == AV_CODEC_ID_MOV_TEXT &&
7353  trk->track_duration < pkt->dts &&
7354  (trk->entry == 0 || !trk->last_sample_is_subtitle_end)) {
7356  if (ret < 0) return ret;
7357  trk->last_sample_is_subtitle_end = 1;
7358  }
7359  }
7360 
7361  if (trk->squash_fragment_samples_to_one) {
7362  /*
7363  * If the track has to have its samples squashed into one sample,
7364  * we just take it into the track's queue.
7365  * This will then be utilized as the samples get written in either
7366  * mov_flush_fragment or when the mux is finalized in
7367  * mov_write_trailer.
7368  */
7369  int ret = AVERROR_BUG;
7370 
7371  if (pkt->pts == AV_NOPTS_VALUE) {
7373  "Packets without a valid presentation timestamp are "
7374  "not supported with packet squashing!\n");
7375  return AVERROR(EINVAL);
7376  }
7377 
7378  /* The following will reset pkt and is only allowed to be used
7379  * because we return immediately. afterwards. */
7381  pkt, NULL, 0)) < 0) {
7382  return ret;
7383  }
7384 
7385  return 0;
7386  }
7387 
7388 
7389  if (trk->mode == MODE_MOV && trk->par->codec_type == AVMEDIA_TYPE_VIDEO) {
7390  AVPacket *opkt = pkt;
7391  int reshuffle_ret, ret;
7392  if (trk->is_unaligned_qt_rgb) {
7393  int64_t bpc = trk->par->bits_per_coded_sample != 15 ? trk->par->bits_per_coded_sample : 16;
7394  int expected_stride = ((trk->par->width * bpc + 15) >> 4)*2;
7395  reshuffle_ret = ff_reshuffle_raw_rgb(s, &pkt, trk->par, expected_stride);
7396  if (reshuffle_ret < 0)
7397  return reshuffle_ret;
7398  } else
7399  reshuffle_ret = 0;
7400  if (trk->par->format == AV_PIX_FMT_PAL8 && !trk->pal_done) {
7401  ret = ff_get_packet_palette(s, opkt, reshuffle_ret, trk->palette);
7402  if (ret < 0)
7403  goto fail;
7404  if (ret)
7405  trk->pal_done++;
7406  } else if (trk->par->codec_id == AV_CODEC_ID_RAWVIDEO &&
7407  (trk->par->format == AV_PIX_FMT_GRAY8 ||
7408  trk->par->format == AV_PIX_FMT_MONOBLACK)) {
7410  if (ret < 0)
7411  goto fail;
7412  for (i = 0; i < pkt->size; i++)
7413  pkt->data[i] = ~pkt->data[i];
7414  }
7415  if (reshuffle_ret) {
7417 fail:
7418  if (reshuffle_ret)
7419  av_packet_free(&pkt);
7420  return ret;
7421  }
7422  }
7423 
7424  return mov_write_single_packet(s, pkt);
7425  }
7426 }
7427 
7428 // QuickTime chapters involve an additional text track with the chapter names
7429 // as samples, and a tref pointing from the other tracks to the chapter one.
7430 static int mov_create_chapter_track(AVFormatContext *s, int tracknum)
7431 {
7432  static const uint8_t stub_header[] = {
7433  // TextSampleEntry
7434  0x00, 0x00, 0x00, 0x01, // displayFlags
7435  0x00, 0x00, // horizontal + vertical justification
7436  0x00, 0x00, 0x00, 0x00, // bgColourRed/Green/Blue/Alpha
7437  // BoxRecord
7438  0x00, 0x00, 0x00, 0x00, // defTextBoxTop/Left
7439  0x00, 0x00, 0x00, 0x00, // defTextBoxBottom/Right
7440  // StyleRecord
7441  0x00, 0x00, 0x00, 0x00, // startChar + endChar
7442  0x00, 0x01, // fontID
7443  0x00, 0x00, // fontStyleFlags + fontSize
7444  0x00, 0x00, 0x00, 0x00, // fgColourRed/Green/Blue/Alpha
7445  // FontTableBox
7446  0x00, 0x00, 0x00, 0x0D, // box size
7447  'f', 't', 'a', 'b', // box atom name
7448  0x00, 0x01, // entry count
7449  // FontRecord
7450  0x00, 0x01, // font ID
7451  0x00, // font name length
7452  };
7453  MOVMuxContext *mov = s->priv_data;
7454  MOVTrack *track = &mov->tracks[tracknum];
7455  AVPacket *pkt = mov->pkt;
7456  int i, len;
7457  int ret;
7458 
7459  track->mode = mov->mode;
7460  track->tag = MKTAG('t','e','x','t');
7461  track->timescale = mov->movie_timescale;
7462  track->par = avcodec_parameters_alloc();
7463  if (!track->par)
7464  return AVERROR(ENOMEM);
7466  ret = ff_alloc_extradata(track->par, sizeof(stub_header));
7467  if (ret < 0)
7468  return ret;
7469  memcpy(track->par->extradata, stub_header, sizeof(stub_header));
7470 
7471  if (track->extradata == NULL) {
7472  track->stsd_count = 1;
7473  track->extradata = av_calloc(1, sizeof(*track->extradata));
7474  track->extradata_size = av_calloc(1, sizeof(*track->extradata_size));
7475  if (!track->extradata || !track->extradata_size)
7476  return AVERROR(ENOMEM);
7477  }
7478 
7479  track->extradata[0] = av_memdup(stub_header, sizeof(stub_header));
7480  if (!track->extradata[0])
7481  return AVERROR(ENOMEM);
7482  track->extradata_size[0] = sizeof(stub_header);
7483 
7484  pkt->stream_index = tracknum;
7486 
7487  for (i = 0; i < s->nb_chapters; i++) {
7488  AVChapter *c = s->chapters[i];
7489  AVDictionaryEntry *t;
7490 
7491  int64_t end = av_rescale_q(c->end, c->time_base, (AVRational){1,mov->movie_timescale});
7492  pkt->pts = pkt->dts = av_rescale_q(c->start, c->time_base, (AVRational){1,mov->movie_timescale});
7493  pkt->duration = end - pkt->dts;
7494 
7495  if ((t = av_dict_get(c->metadata, "title", NULL, 0))) {
7496  static const char encd[12] = {
7497  0x00, 0x00, 0x00, 0x0C,
7498  'e', 'n', 'c', 'd',
7499  0x00, 0x00, 0x01, 0x00 };
7500  len = strlen(t->value);
7501  pkt->size = len + 2 + 12;
7502  pkt->data = av_malloc(pkt->size);
7503  if (!pkt->data) {
7505  return AVERROR(ENOMEM);
7506  }
7507  AV_WB16(pkt->data, len);
7508  memcpy(pkt->data + 2, t->value, len);
7509  memcpy(pkt->data + len + 2, encd, sizeof(encd));
7511  av_freep(&pkt->data);
7512  }
7513  }
7514 
7515  av_packet_unref(mov->pkt);
7516 
7517  return 0;
7518 }
7519 
7520 
7521 static int mov_check_timecode_track(AVFormatContext *s, AVTimecode *tc, AVStream *src_st, const char *tcstr)
7522 {
7523  int ret;
7524 
7525  /* compute the frame number */
7526  ret = av_timecode_init_from_string(tc, src_st->avg_frame_rate, tcstr, s);
7527  return ret;
7528 }
7529 
7530 static int mov_create_timecode_track(AVFormatContext *s, int index, int src_index, AVTimecode tc)
7531 {
7532  MOVMuxContext *mov = s->priv_data;
7533  MOVTrack *track = &mov->tracks[index];
7534  AVStream *src_st = mov->tracks[src_index].st;
7535  uint8_t data[4];
7536  AVPacket *pkt = mov->pkt;
7537  AVRational rate = src_st->avg_frame_rate;
7538  int ret;
7539 
7540  /* tmcd track based on video stream */
7541  track->mode = mov->mode;
7542  track->tag = MKTAG('t','m','c','d');
7543  track->src_track = src_index;
7544  track->timescale = mov->tracks[src_index].timescale;
7547 
7548  /* set st to src_st for metadata access*/
7549  track->st = src_st;
7550 
7551  /* encode context: tmcd data stream */
7552  track->par = avcodec_parameters_alloc();
7553  if (!track->par)
7554  return AVERROR(ENOMEM);
7555  track->par->codec_type = AVMEDIA_TYPE_DATA;
7556  track->par->codec_tag = track->tag;
7557  track->st->avg_frame_rate = rate;
7558 
7559  /* the tmcd track just contains one packet with the frame number */
7560  pkt->data = data;
7561  pkt->stream_index = index;
7563  pkt->pts = pkt->dts = av_rescale_q(tc.start, av_inv_q(rate), (AVRational){1,mov->movie_timescale});
7564  pkt->size = 4;
7565  AV_WB32(pkt->data, tc.start);
7568  return ret;
7569 }
7570 
7571 /*
7572  * st->disposition controls the "enabled" flag in the tkhd tag.
7573  * QuickTime will not play a track if it is not enabled. So make sure
7574  * that one track of each type (audio, video, subtitle) is enabled.
7575  *
7576  * Subtitles are special. For audio and video, setting "enabled" also
7577  * makes the track "default" (i.e. it is rendered when played). For
7578  * subtitles, an "enabled" subtitle is not rendered by default, but
7579  * if no subtitle is enabled, the subtitle menu in QuickTime will be
7580  * empty!
7581  */
7583 {
7584  MOVMuxContext *mov = s->priv_data;
7585  int i;
7586  int enabled[AVMEDIA_TYPE_NB];
7587  int first[AVMEDIA_TYPE_NB];
7588 
7589  for (i = 0; i < AVMEDIA_TYPE_NB; i++) {
7590  enabled[i] = 0;
7591  first[i] = -1;
7592  }
7593 
7594  for (i = 0; i < mov->nb_streams; i++) {
7595  AVStream *st = mov->tracks[i].st;
7596 
7599  is_cover_image(st))
7600  continue;
7601 
7602  if (first[st->codecpar->codec_type] < 0)
7603  first[st->codecpar->codec_type] = i;
7604  if (st->disposition & AV_DISPOSITION_DEFAULT) {
7605  mov->tracks[i].flags |= MOV_TRACK_ENABLED;
7606  enabled[st->codecpar->codec_type]++;
7607  }
7608  }
7609 
7610  for (i = 0; i < AVMEDIA_TYPE_NB; i++) {
7611  switch (i) {
7612  case AVMEDIA_TYPE_VIDEO:
7613  case AVMEDIA_TYPE_AUDIO:
7614  case AVMEDIA_TYPE_SUBTITLE:
7615  if (enabled[i] > 1)
7616  mov->per_stream_grouping = 1;
7617  if (!enabled[i] && first[i] >= 0)
7618  mov->tracks[first[i]].flags |= MOV_TRACK_ENABLED;
7619  break;
7620  }
7621  }
7622 }
7623 
7625 {
7626  MOVMuxContext *mov = s->priv_data;
7627 
7628  for (int i = 0; i < s->nb_streams; i++)
7629  s->streams[i]->priv_data = NULL;
7630 
7631  if (!mov->tracks)
7632  return;
7633 
7634  if (mov->chapter_track) {
7636  }
7637 
7638  for (int i = 0; i < mov->nb_tracks; i++) {
7639  MOVTrack *const track = &mov->tracks[i];
7640 
7641  if (track->tag == MKTAG('r','t','p',' '))
7642  ff_mov_close_hinting(track);
7643  else if (track->tag == MKTAG('t','m','c','d') && mov->nb_meta_tmcd)
7644  av_freep(&track->par);
7645  av_freep(&track->cluster);
7646  av_freep(&track->cluster_written);
7647  av_freep(&track->frag_info);
7648  av_packet_free(&track->cover_image);
7649 
7650  if (track->eac3_priv) {
7651  struct eac3_info *info = track->eac3_priv;
7652  av_packet_free(&info->pkt);
7653  av_freep(&track->eac3_priv);
7654  }
7655  for (int j = 0; j < track->stsd_count; j++)
7656  av_freep(&track->extradata[j]);
7657  av_freep(&track->extradata);
7658  av_freep(&track->extradata_size);
7659 
7660  ff_mov_cenc_free(&track->cenc);
7661  ffio_free_dyn_buf(&track->mdat_buf);
7662 
7663 #if CONFIG_IAMFENC
7664  ffio_free_dyn_buf(&track->iamf_buf);
7665  if (track->iamf)
7666  ff_iamf_uninit_context(track->iamf);
7667  av_freep(&track->iamf);
7668 #endif
7669  ff_isom_close_apvc(&track->apv);
7670 
7672  }
7673 
7674  av_freep(&mov->tracks);
7675  ffio_free_dyn_buf(&mov->mdat_buf);
7676 }
7677 
7678 static uint32_t rgb_to_yuv(uint32_t rgb)
7679 {
7680  uint8_t r, g, b;
7681  int y, cb, cr;
7682 
7683  r = (rgb >> 16) & 0xFF;
7684  g = (rgb >> 8) & 0xFF;
7685  b = (rgb ) & 0xFF;
7686 
7687  y = av_clip_uint8(( 16000 + 257 * r + 504 * g + 98 * b)/1000);
7688  cb = av_clip_uint8((128000 - 148 * r - 291 * g + 439 * b)/1000);
7689  cr = av_clip_uint8((128000 + 439 * r - 368 * g - 71 * b)/1000);
7690 
7691  return (y << 16) | (cr << 8) | cb;
7692 }
7693 
7695  AVStream *st)
7696 {
7697  int i, width = 720, height = 480;
7698  int have_palette = 0, have_size = 0;
7699  uint32_t palette[16];
7700  char *cur = track->extradata[track->last_stsd_index];
7701 
7702  while (cur && *cur) {
7703  if (strncmp("palette:", cur, 8) == 0) {
7704  int i, count;
7705  count = sscanf(cur + 8,
7706  "%06"PRIx32", %06"PRIx32", %06"PRIx32", %06"PRIx32", "
7707  "%06"PRIx32", %06"PRIx32", %06"PRIx32", %06"PRIx32", "
7708  "%06"PRIx32", %06"PRIx32", %06"PRIx32", %06"PRIx32", "
7709  "%06"PRIx32", %06"PRIx32", %06"PRIx32", %06"PRIx32"",
7710  &palette[ 0], &palette[ 1], &palette[ 2], &palette[ 3],
7711  &palette[ 4], &palette[ 5], &palette[ 6], &palette[ 7],
7712  &palette[ 8], &palette[ 9], &palette[10], &palette[11],
7713  &palette[12], &palette[13], &palette[14], &palette[15]);
7714 
7715  for (i = 0; i < count; i++) {
7716  palette[i] = rgb_to_yuv(palette[i]);
7717  }
7718  have_palette = 1;
7719  } else if (!strncmp("size:", cur, 5)) {
7720  sscanf(cur + 5, "%dx%d", &width, &height);
7721  have_size = 1;
7722  }
7723  if (have_palette && have_size)
7724  break;
7725  cur += strcspn(cur, "\n\r");
7726  cur += strspn(cur, "\n\r");
7727  }
7728  if (have_palette) {
7730  if (!track->extradata[track->last_stsd_index])
7731  return AVERROR(ENOMEM);
7732  for (i = 0; i < 16; i++) {
7733  AV_WB32(track->extradata[track->last_stsd_index] + i * 4, palette[i]);
7734  }
7735  memset(track->extradata[track->last_stsd_index] + 16*4, 0, AV_INPUT_BUFFER_PADDING_SIZE);
7736  track->extradata_size[track->last_stsd_index] = 16 * 4;
7737  }
7738  st->codecpar->width = width;
7739  st->codecpar->height = track->height = height;
7740 
7741  return 0;
7742 }
7743 
7744 #if CONFIG_IAMFENC
7745 static int mov_init_iamf_track(AVFormatContext *s)
7746 {
7747  MOVMuxContext *mov = s->priv_data;
7748  MOVTrack *track;
7749  IAMFContext *iamf;
7750  int first_iamf_idx = INT_MAX, last_iamf_idx = 0;
7751  int nb_audio_elements = 0, nb_mix_presentations = 0;
7752  int ret;
7753 
7754  for (int i = 0; i < s->nb_stream_groups; i++) {
7755  const AVStreamGroup *stg = s->stream_groups[i];
7756 
7758  nb_audio_elements++;
7760  nb_mix_presentations++;
7761  }
7762 
7763  if (!nb_audio_elements && !nb_mix_presentations)
7764  return 0;
7765 
7766  if (nb_audio_elements < 1 || nb_audio_elements > 2 || nb_mix_presentations < 1) {
7767  av_log(s, AV_LOG_ERROR, "There must be >= 1 and <= 2 IAMF_AUDIO_ELEMENT and at least "
7768  "one IAMF_MIX_PRESENTATION stream groups to write a IMAF track\n");
7769  return AVERROR(EINVAL);
7770  }
7771 
7772  iamf = av_mallocz(sizeof(*iamf));
7773  if (!iamf)
7774  return AVERROR(ENOMEM);
7775 
7776 
7777  for (int i = 0; i < s->nb_stream_groups; i++) {
7778  const AVStreamGroup *stg = s->stream_groups[i];
7779  switch(stg->type) {
7781  for (int j = 0; j < stg->nb_streams; j++) {
7782  first_iamf_idx = FFMIN(stg->streams[j]->index, first_iamf_idx);
7783  last_iamf_idx = FFMAX(stg->streams[j]->index, last_iamf_idx);
7784  }
7785 
7786  ret = ff_iamf_add_audio_element(iamf, stg, s);
7787  break;
7789  ret = ff_iamf_add_mix_presentation(iamf, stg, s);
7790  break;
7791  default:
7792  av_assert0(0);
7793  }
7794  if (ret < 0)
7795  return ret;
7796  }
7797 
7798  track = &mov->tracks[first_iamf_idx];
7799  track->iamf = iamf;
7800  track->first_iamf_idx = first_iamf_idx;
7801  track->last_iamf_idx = last_iamf_idx;
7802  track->tag = MKTAG('i','a','m','f');
7803 
7804  for (int i = 0; i < s->nb_stream_groups; i++) {
7805  AVStreamGroup *stg = s->stream_groups[i];
7807  continue;
7808  for (int j = 0; j < stg->nb_streams; j++)
7809  stg->streams[j]->priv_data = track;
7810  }
7811 
7812  ret = avio_open_dyn_buf(&track->iamf_buf);
7813  if (ret < 0)
7814  return ret;
7815 
7816  return 0;
7817 }
7818 #endif
7819 
7821 {
7822  MOVMuxContext *mov = s->priv_data;
7823  int has_iamf = 0;
7824  int i, ret;
7825 
7826  mov->fc = s;
7827  mov->pkt = ffformatcontext(s)->pkt;
7828 
7829  /* Default mode == MP4 */
7830  mov->mode = MODE_MP4;
7831 
7832 #define IS_MODE(muxer, config) (CONFIG_ ## config ## _MUXER && !strcmp(#muxer, s->oformat->name))
7833  if (IS_MODE(3gp, TGP)) mov->mode = MODE_3GP;
7834  else if (IS_MODE(3g2, TG2)) mov->mode = MODE_3GP|MODE_3G2;
7835  else if (IS_MODE(mov, MOV)) mov->mode = MODE_MOV;
7836  else if (IS_MODE(psp, PSP)) mov->mode = MODE_PSP;
7837  else if (IS_MODE(ipod, IPOD)) mov->mode = MODE_IPOD;
7838  else if (IS_MODE(ismv, ISMV)) mov->mode = MODE_ISM;
7839  else if (IS_MODE(f4v, F4V)) mov->mode = MODE_F4V;
7840  else if (IS_MODE(avif, AVIF)) mov->mode = MODE_AVIF;
7841 #undef IS_MODE
7842 
7843  if (mov->flags & FF_MOV_FLAG_DELAY_MOOV)
7844  mov->flags |= FF_MOV_FLAG_EMPTY_MOOV;
7845 
7846  if (mov->mode == MODE_AVIF)
7847  mov->flags |= FF_MOV_FLAG_DELAY_MOOV;
7848 
7849  /* Set the FRAGMENT flag if any of the fragmentation methods are
7850  * enabled. */
7851  if (mov->max_fragment_duration || mov->max_fragment_size ||
7852  mov->flags & (FF_MOV_FLAG_EMPTY_MOOV |
7856  mov->flags |= FF_MOV_FLAG_FRAGMENT;
7857 
7858  if (mov->flags & FF_MOV_FLAG_HYBRID_FRAGMENTED &&
7859  mov->flags & FF_MOV_FLAG_FASTSTART) {
7860  av_log(s, AV_LOG_ERROR, "Setting both hybrid_fragmented and faststart is not supported.\n");
7861  return AVERROR(EINVAL);
7862  }
7863 
7864  /* Set other implicit flags immediately */
7866  mov->flags |= FF_MOV_FLAG_FRAGMENT;
7867 
7868  if (mov->mode == MODE_ISM)
7871  if (mov->flags & FF_MOV_FLAG_DASH)
7874  if (mov->flags & FF_MOV_FLAG_CMAF)
7877 
7878  if (mov->flags & FF_MOV_FLAG_EMPTY_MOOV && s->flags & AVFMT_FLAG_AUTO_BSF) {
7879  av_log(s, AV_LOG_VERBOSE, "Empty MOOV enabled; disabling automatic bitstream filtering\n");
7880  s->flags &= ~AVFMT_FLAG_AUTO_BSF;
7881  }
7882 
7884  av_log(s, AV_LOG_WARNING, "Global SIDX enabled; Ignoring skip_sidx option\n");
7885  mov->flags &= ~FF_MOV_FLAG_SKIP_SIDX;
7886  }
7887 
7888  if (mov->flags & FF_MOV_FLAG_FASTSTART) {
7889  mov->reserved_moov_size = -1;
7890  }
7891 
7892  if (mov->use_editlist < 0) {
7893  mov->use_editlist = 1;
7894  if (mov->flags & FF_MOV_FLAG_FRAGMENT &&
7895  !(mov->flags & FF_MOV_FLAG_DELAY_MOOV)) {
7896  // If we can avoid needing an edit list by shifting the
7897  // tracks, prefer that over (trying to) write edit lists
7898  // in fragmented output.
7899  if (s->avoid_negative_ts == AVFMT_AVOID_NEG_TS_AUTO ||
7900  s->avoid_negative_ts == AVFMT_AVOID_NEG_TS_MAKE_ZERO)
7901  mov->use_editlist = 0;
7902  }
7903  }
7904  if (mov->flags & FF_MOV_FLAG_EMPTY_MOOV &&
7905  !(mov->flags & FF_MOV_FLAG_DELAY_MOOV) && mov->use_editlist)
7906  av_log(s, AV_LOG_WARNING, "No meaningful edit list will be written when using empty_moov without delay_moov\n");
7907 
7908  if (!mov->use_editlist && s->avoid_negative_ts == AVFMT_AVOID_NEG_TS_AUTO &&
7910  s->avoid_negative_ts = AVFMT_AVOID_NEG_TS_MAKE_ZERO;
7911 
7912  /* Clear the omit_tfhd_offset flag if default_base_moof is set;
7913  * if the latter is set that's enough and omit_tfhd_offset doesn't
7914  * add anything extra on top of that. */
7915  if (mov->flags & FF_MOV_FLAG_OMIT_TFHD_OFFSET &&
7918 
7919  if (mov->frag_interleave &&
7922  "Sample interleaving in fragments is mutually exclusive with "
7923  "omit_tfhd_offset and separate_moof\n");
7924  return AVERROR(EINVAL);
7925  }
7926 
7927  /* Non-seekable output is ok if using fragmentation. If ism_lookahead
7928  * is enabled, we don't support non-seekable output at all. */
7929  if (!(s->pb->seekable & AVIO_SEEKABLE_NORMAL) &&
7930  (!(mov->flags & FF_MOV_FLAG_FRAGMENT) || mov->ism_lookahead ||
7931  mov->mode == MODE_AVIF)) {
7932  av_log(s, AV_LOG_ERROR, "muxer does not support non seekable output\n");
7933  return AVERROR(EINVAL);
7934  }
7935 
7936  /* AVIF output must have at most two video streams (one for YUV and one for
7937  * alpha). */
7938  if (mov->mode == MODE_AVIF) {
7939  if (s->nb_streams > 2) {
7940  av_log(s, AV_LOG_ERROR, "AVIF output requires exactly one or two streams\n");
7941  return AVERROR(EINVAL);
7942  }
7943  if (s->streams[0]->codecpar->codec_type != AVMEDIA_TYPE_VIDEO &&
7944  (s->nb_streams > 1 && s->streams[1]->codecpar->codec_type != AVMEDIA_TYPE_VIDEO)) {
7945  av_log(s, AV_LOG_ERROR, "AVIF output supports only video streams\n");
7946  return AVERROR(EINVAL);
7947  }
7948  if (s->nb_streams > 1) {
7949  const AVPixFmtDescriptor *pixdesc =
7950  av_pix_fmt_desc_get(s->streams[1]->codecpar->format);
7951  if (pixdesc->nb_components != 1) {
7952  av_log(s, AV_LOG_ERROR, "Second stream for AVIF (alpha) output must have exactly one plane\n");
7953  return AVERROR(EINVAL);
7954  }
7955  }
7956  s->streams[0]->disposition |= AV_DISPOSITION_DEFAULT;
7957  }
7958 
7959 #if CONFIG_IAMFENC
7960  for (i = 0; i < s->nb_stream_groups; i++) {
7961  AVStreamGroup *stg = s->stream_groups[i];
7962 
7964  continue;
7965 
7966  for (int j = 0; j < stg->nb_streams; j++) {
7967  AVStream *st = stg->streams[j];
7968 
7969  if (st->priv_data) {
7970  av_log(s, AV_LOG_ERROR, "Stream %d is present in more than one Stream Group of type "
7971  "IAMF Audio Element\n", j);
7972  return AVERROR(EINVAL);
7973  }
7974  st->priv_data = st;
7975  }
7976  has_iamf = 1;
7977 
7978  if (!mov->nb_tracks) // We support one track for the entire IAMF structure
7979  mov->nb_tracks++;
7980  }
7981 #endif
7982 
7983  for (i = 0; i < s->nb_streams; i++) {
7984  AVStream *st = s->streams[i];
7985  if (st->priv_data)
7986  continue;
7987  // Don't produce a track in the output file for timed ID3 streams.
7988  if (st->codecpar->codec_id == AV_CODEC_ID_TIMED_ID3) {
7989  // Leave priv_data set to NULL for these AVStreams that don't
7990  // have a corresponding track.
7991  continue;
7992  }
7993  st->priv_data = st;
7994  mov->nb_tracks++;
7995  }
7996 
7997  mov->nb_streams = mov->nb_tracks;
7998 
7999  if (mov->mode & (MODE_MP4|MODE_MOV|MODE_IPOD) && s->nb_chapters)
8000  mov->chapter_track = mov->nb_tracks++;
8001 
8002  if (mov->flags & FF_MOV_FLAG_RTP_HINT) {
8003  for (i = 0; i < s->nb_streams; i++)
8004  if (rtp_hinting_needed(s->streams[i]))
8005  mov->nb_tracks++;
8006  }
8007 
8008  if (mov->write_btrt < 0) {
8009  mov->write_btrt = mov->mode == MODE_MP4;
8010  }
8011 
8012  if ( mov->write_tmcd == -1 && (mov->mode == MODE_MOV || mov->mode == MODE_MP4)
8013  || mov->write_tmcd == 1) {
8014  AVDictionaryEntry *global_tcr = av_dict_get(s->metadata, "timecode",
8015  NULL, 0);
8016 
8017  /* +1 tmcd track for each video stream with a timecode */
8018  for (i = 0; i < s->nb_streams; i++) {
8019  AVStream *st = s->streams[i];
8020  AVDictionaryEntry *t = global_tcr;
8021  if (st->codecpar->codec_type == AVMEDIA_TYPE_VIDEO &&
8022  (t || (t=av_dict_get(st->metadata, "timecode", NULL, 0)))) {
8023  AVTimecode tc;
8024  ret = mov_check_timecode_track(s, &tc, st, t->value);
8025  if (ret >= 0)
8026  mov->nb_meta_tmcd++;
8027  }
8028  }
8029 
8030  /* check if there is already a tmcd track to remux */
8031  if (mov->nb_meta_tmcd) {
8032  for (i = 0; i < s->nb_streams; i++) {
8033  AVStream *st = s->streams[i];
8034  if (st->codecpar->codec_tag == MKTAG('t','m','c','d')) {
8035  av_log(s, AV_LOG_WARNING, "You requested a copy of the original timecode track "
8036  "so timecode metadata are now ignored\n");
8037  mov->nb_meta_tmcd = 0;
8038  }
8039  }
8040  }
8041 
8042  mov->nb_tracks += mov->nb_meta_tmcd;
8043  }
8044 
8045  // Reserve an extra stream for chapters for the case where chapters
8046  // are written in the trailer
8047  mov->tracks = av_calloc(mov->nb_tracks + 1, sizeof(*mov->tracks));
8048  if (!mov->tracks)
8049  return AVERROR(ENOMEM);
8050 
8051  for (i = 0; i < mov->nb_tracks; i++) {
8052  MOVTrack *track = &mov->tracks[i];
8053 
8054  track->stsd_count = 1;
8055  track->extradata = av_calloc(track->stsd_count, sizeof(*track->extradata));
8056  track->extradata_size = av_calloc(track->stsd_count, sizeof(*track->extradata_size));
8057  if (!track->extradata || !track->extradata_size)
8058  return AVERROR(ENOMEM);
8059  }
8060 
8061  if (mov->encryption_scheme_str != NULL && strcmp(mov->encryption_scheme_str, "none") != 0) {
8062  if (strcmp(mov->encryption_scheme_str, "cenc-aes-ctr") == 0) {
8064 
8065  if (mov->encryption_key_len != AES_CTR_KEY_SIZE) {
8066  av_log(s, AV_LOG_ERROR, "Invalid encryption key len %d expected %d\n",
8068  return AVERROR(EINVAL);
8069  }
8070 
8071  if (mov->encryption_kid_len != CENC_KID_SIZE) {
8072  av_log(s, AV_LOG_ERROR, "Invalid encryption kid len %d expected %d\n",
8074  return AVERROR(EINVAL);
8075  }
8076  } else {
8077  av_log(s, AV_LOG_ERROR, "unsupported encryption scheme %s\n",
8078  mov->encryption_scheme_str);
8079  return AVERROR(EINVAL);
8080  }
8081  }
8082 
8083 #if CONFIG_IAMFENC
8084  ret = mov_init_iamf_track(s);
8085  if (ret < 0)
8086  return ret;
8087 #endif
8088 
8089  for (int j = 0, i = 0; j < s->nb_streams; j++) {
8090  AVStream *st = s->streams[j];
8091 
8092  if (st != st->priv_data) {
8093  if (has_iamf)
8094  i += has_iamf--;
8095  continue;
8096  }
8097  st->priv_data = &mov->tracks[i++];
8098  }
8099 
8100  for (i = 0; i < s->nb_streams; i++) {
8101  AVStream *st= s->streams[i];
8102  MOVTrack *track = st->priv_data;
8103  AVDictionaryEntry *lang = av_dict_get(st->metadata, "language", NULL,0);
8104 
8105  if (!track)
8106  continue;
8107 
8108  if (!track->st) {
8109  track->st = st;
8110  track->par = st->codecpar;
8111  }
8112  track->language = ff_mov_iso639_to_lang(lang?lang->value:"und", mov->mode!=MODE_MOV);
8113  if (track->language < 0)
8114  track->language = 32767; // Unspecified Macintosh language code
8115  track->mode = mov->mode;
8116  if (!track->tag)
8117  track->tag = mov_find_codec_tag(s, track);
8118  if (!track->tag) {
8119  av_log(s, AV_LOG_ERROR, "Could not find tag for codec %s in stream #%d, "
8120  "codec not currently supported in container\n",
8122  return AVERROR(EINVAL);
8123  }
8124  /* If hinting of this track is enabled by a later hint track,
8125  * this is updated. */
8126  track->hint_track = -1;
8127  track->start_dts = AV_NOPTS_VALUE;
8128  track->start_cts = AV_NOPTS_VALUE;
8129  track->end_pts = AV_NOPTS_VALUE;
8130  track->dts_shift = AV_NOPTS_VALUE;
8131  if (st->codecpar->codec_type == AVMEDIA_TYPE_VIDEO) {
8132  if (track->tag == MKTAG('m','x','3','p') || track->tag == MKTAG('m','x','3','n') ||
8133  track->tag == MKTAG('m','x','4','p') || track->tag == MKTAG('m','x','4','n') ||
8134  track->tag == MKTAG('m','x','5','p') || track->tag == MKTAG('m','x','5','n')) {
8135  if (st->codecpar->width != 720 || (st->codecpar->height != 608 && st->codecpar->height != 512)) {
8136  av_log(s, AV_LOG_ERROR, "D-10/IMX must use 720x608 or 720x512 video resolution\n");
8137  return AVERROR(EINVAL);
8138  }
8139  track->height = track->tag >> 24 == 'n' ? 486 : 576;
8140  }
8141  if (mov->video_track_timescale) {
8142  track->timescale = mov->video_track_timescale;
8143  if (mov->mode == MODE_ISM && mov->video_track_timescale != 10000000)
8144  av_log(s, AV_LOG_WARNING, "Warning: some tools, like mp4split, assume a timescale of 10000000 for ISMV.\n");
8145  } else {
8146  track->timescale = st->time_base.den;
8147  while(track->timescale < 10000)
8148  track->timescale *= 2;
8149  }
8150  if (st->codecpar->width > 65535 || st->codecpar->height > 65535) {
8151  av_log(s, AV_LOG_ERROR, "Resolution %dx%d too large for mov/mp4\n", st->codecpar->width, st->codecpar->height);
8152  return AVERROR(EINVAL);
8153  }
8154  if (track->mode == MODE_MOV && track->timescale > 100000)
8156  "WARNING codec timebase is very high. If duration is too long,\n"
8157  "file may not be playable by quicktime. Specify a shorter timebase\n"
8158  "or choose different container.\n");
8159  if (track->mode == MODE_MOV &&
8160  track->par->codec_id == AV_CODEC_ID_RAWVIDEO &&
8161  track->tag == MKTAG('r','a','w',' ')) {
8162  enum AVPixelFormat pix_fmt = track->par->format;
8163  if (pix_fmt == AV_PIX_FMT_NONE && track->par->bits_per_coded_sample == 1)
8165  track->is_unaligned_qt_rgb =
8168  pix_fmt == AV_PIX_FMT_PAL8 ||
8172  }
8173  if (track->par->codec_id == AV_CODEC_ID_VP9 && track->mode != MODE_MP4) {
8174  av_log(s, AV_LOG_ERROR, "%s only supported in MP4.\n", avcodec_get_name(track->par->codec_id));
8175  return AVERROR(EINVAL);
8176  } else if (track->par->codec_id == AV_CODEC_ID_AV1 &&
8177  track->mode != MODE_MP4 && track->mode != MODE_AVIF) {
8178  av_log(s, AV_LOG_ERROR, "%s only supported in MP4 and AVIF.\n", avcodec_get_name(track->par->codec_id));
8179  return AVERROR(EINVAL);
8180  } else if (track->par->codec_id == AV_CODEC_ID_VP8) {
8181  /* altref frames handling is not defined in the spec as of version v1.0,
8182  * so just forbid muxing VP8 streams altogether until a new version does */
8183  av_log(s, AV_LOG_ERROR, "VP8 muxing is currently not supported.\n");
8184  return AVERROR_PATCHWELCOME;
8185  } else if (track->par->codec_id == AV_CODEC_ID_APV) {
8186  ret = ff_isom_init_apvc(&track->apv, s);
8187  if (ret < 0)
8188  return ret;
8189  }
8190  if (is_cover_image(st)) {
8191  track->cover_image = av_packet_alloc();
8192  if (!track->cover_image)
8193  return AVERROR(ENOMEM);
8194  }
8195  } else if (st->codecpar->codec_type == AVMEDIA_TYPE_AUDIO) {
8196  track->timescale = st->codecpar->sample_rate;
8198  av_log(s, AV_LOG_WARNING, "track %d: codec frame size is not set\n", i);
8199  track->audio_vbr = 1;
8200  }else if (st->codecpar->codec_id == AV_CODEC_ID_ADPCM_MS ||
8203  if (!st->codecpar->block_align) {
8204  av_log(s, AV_LOG_ERROR, "track %d: codec block align is not set for adpcm\n", i);
8205  return AVERROR(EINVAL);
8206  }
8207  track->sample_size = st->codecpar->block_align;
8208  }else if (st->codecpar->frame_size > 1){ /* assume compressed audio */
8209  track->audio_vbr = 1;
8210  }else{
8211  track->sample_size = (av_get_bits_per_sample(st->codecpar->codec_id) >> 3) *
8213  }
8214  if (st->codecpar->codec_id == AV_CODEC_ID_ILBC ||
8216  track->audio_vbr = 1;
8217  }
8218  if (track->mode != MODE_MOV &&
8219  track->par->codec_id == AV_CODEC_ID_MP3 && track->timescale < 16000) {
8220  if (s->strict_std_compliance >= FF_COMPLIANCE_NORMAL) {
8221  av_log(s, AV_LOG_ERROR, "track %d: muxing mp3 at %dhz is not standard, to mux anyway set strict to -1\n",
8222  i, track->par->sample_rate);
8223  return AVERROR(EINVAL);
8224  } else {
8225  av_log(s, AV_LOG_WARNING, "track %d: muxing mp3 at %dhz is not standard in MP4\n",
8226  i, track->par->sample_rate);
8227  }
8228  }
8229  if (track->par->codec_id == AV_CODEC_ID_FLAC ||
8230  track->par->codec_id == AV_CODEC_ID_TRUEHD ||
8231  track->par->codec_id == AV_CODEC_ID_OPUS) {
8232  if (track->mode != MODE_MP4) {
8233  av_log(s, AV_LOG_ERROR, "%s only supported in MP4.\n", avcodec_get_name(track->par->codec_id));
8234  return AVERROR(EINVAL);
8235  }
8236  if (track->par->codec_id == AV_CODEC_ID_TRUEHD &&
8237  s->strict_std_compliance > FF_COMPLIANCE_EXPERIMENTAL) {
8239  "%s in MP4 support is experimental, add "
8240  "'-strict %d' if you want to use it.\n",
8242  return AVERROR_EXPERIMENTAL;
8243  }
8244  }
8245  } else if (st->codecpar->codec_type == AVMEDIA_TYPE_SUBTITLE) {
8246  track->timescale = st->time_base.den;
8247 
8248  if (track->par->codec_id == AV_CODEC_ID_TTML) {
8249  /* 14496-30 requires us to use a single sample per fragment
8250  for TTML, for which we define a per-track flag.
8251 
8252  We set the flag in case we are receiving TTML paragraphs
8253  from the input, in other words in case we are not doing
8254  stream copy. */
8257 
8258  if (track->mode != MODE_ISM &&
8259  track->par->codec_tag == MOV_ISMV_TTML_TAG &&
8260  s->strict_std_compliance > FF_COMPLIANCE_UNOFFICIAL) {
8262  "ISMV style TTML support with the 'dfxp' tag in "
8263  "non-ISMV formats is not officially supported. Add "
8264  "'-strict unofficial' if you want to use it.\n");
8265  return AVERROR_EXPERIMENTAL;
8266  }
8267  }
8268  } else if (st->codecpar->codec_type == AVMEDIA_TYPE_DATA) {
8269  track->timescale = st->time_base.den;
8270  } else {
8271  track->timescale = mov->movie_timescale;
8272  }
8273  if (!track->height)
8274  track->height = st->codecpar->height;
8275  /* The Protected Interoperable File Format (PIFF) standard, used by ISMV recommends but
8276  doesn't mandate a track timescale of 10,000,000. The muxer allows a custom timescale
8277  for video tracks, so if user-set, it isn't overwritten */
8278  if (mov->mode == MODE_ISM &&
8281  track->timescale = 10000000;
8282  }
8283 
8284  avpriv_set_pts_info(st, 64, 1, track->timescale);
8285 
8287  ret = ff_mov_cenc_init(&track->cenc, mov->encryption_key,
8288  (track->par->codec_id == AV_CODEC_ID_H264 || track->par->codec_id == AV_CODEC_ID_HEVC ||
8289  track->par->codec_id == AV_CODEC_ID_VVC || track->par->codec_id == AV_CODEC_ID_AV1),
8290  track->par->codec_id, s->flags & AVFMT_FLAG_BITEXACT);
8291  if (ret)
8292  return ret;
8293  }
8294  }
8295 
8296  enable_tracks(s);
8297  return 0;
8298 }
8299 
8301 {
8302  AVIOContext *pb = s->pb;
8303  MOVMuxContext *mov = s->priv_data;
8304  int ret, hint_track = 0, tmcd_track = 0, nb_tracks = mov->nb_streams;
8305 
8306  if (mov->mode & (MODE_MP4|MODE_MOV|MODE_IPOD) && s->nb_chapters)
8307  nb_tracks++;
8308 
8309  if (mov->flags & FF_MOV_FLAG_RTP_HINT) {
8310  hint_track = nb_tracks;
8311  for (int i = 0; i < mov->nb_streams; i++) {
8312  if (rtp_hinting_needed(mov->tracks[i].st))
8313  nb_tracks++;
8314  }
8315  }
8316 
8317  if (mov->nb_meta_tmcd)
8318  tmcd_track = nb_tracks;
8319 
8320  for (int i = 0; i < mov->nb_streams; i++) {
8321  MOVTrack *track = &mov->tracks[i];
8322  AVStream *st = track->st;
8323 
8324  /* copy extradata if it exists */
8325  if (st->codecpar->extradata_size) {
8328  else if (!TAG_IS_AVCI(track->tag) && st->codecpar->codec_id != AV_CODEC_ID_DNXHD) {
8329  track->extradata_size[track->last_stsd_index] = st->codecpar->extradata_size;
8330  track->extradata[track->last_stsd_index] =
8332  if (!track->extradata[track->last_stsd_index]) {
8333  return AVERROR(ENOMEM);
8334  }
8335  memcpy(track->extradata[track->last_stsd_index],
8336  st->codecpar->extradata, track->extradata_size[track->last_stsd_index]);
8337  memset(track->extradata[track->last_stsd_index] + track->extradata_size[track->last_stsd_index],
8339  }
8340  }
8341 
8342  if (st->codecpar->codec_type != AVMEDIA_TYPE_AUDIO ||
8345  continue;
8346 
8347  for (int j = 0; j < mov->nb_streams; j++) {
8348  AVStream *stj= mov->tracks[j].st;
8349  MOVTrack *trackj= &mov->tracks[j];
8350  if (j == i)
8351  continue;
8352 
8353  if (stj->codecpar->codec_type == AVMEDIA_TYPE_AUDIO &&
8354  (trackj->par->ch_layout.nb_channels != 1 ||
8357  )
8358  track->mono_as_fc = -1;
8359 
8360  if (stj->codecpar->codec_type == AVMEDIA_TYPE_AUDIO &&
8363  trackj->par->ch_layout.nb_channels == 1 && track->mono_as_fc >= 0
8364  )
8365  track->mono_as_fc++;
8366 
8367  if (stj->codecpar->codec_type != AVMEDIA_TYPE_AUDIO ||
8370  trackj->language != track->language ||
8371  trackj->tag != track->tag
8372  )
8373  continue;
8374  track->multichannel_as_mono++;
8375  }
8376  }
8377 
8378  if (!(mov->flags & FF_MOV_FLAG_DELAY_MOOV)) {
8379  if ((ret = mov_write_identification(pb, s)) < 0)
8380  return ret;
8381  }
8382 
8383  if (mov->reserved_moov_size){
8384  mov->reserved_header_pos = avio_tell(pb);
8385  if (mov->reserved_moov_size > 0)
8386  avio_skip(pb, mov->reserved_moov_size);
8387  }
8388 
8389  if (mov->flags & FF_MOV_FLAG_FRAGMENT) {
8390  /* If no fragmentation options have been set, set a default. */
8391  if (!(mov->flags & (FF_MOV_FLAG_FRAG_KEYFRAME |
8396  if (mov->flags & FF_MOV_FLAG_HYBRID_FRAGMENTED) {
8397  avio_wb32(pb, 8); // placeholder for extended size field (64 bit)
8398  ffio_wfourcc(pb, mov->mode == MODE_MOV ? "wide" : "free");
8399  mov->mdat_pos = avio_tell(pb);
8400  }
8401  } else if (mov->mode != MODE_AVIF) {
8402  if (mov->flags & FF_MOV_FLAG_FASTSTART)
8403  mov->reserved_header_pos = avio_tell(pb);
8404  mov_write_mdat_tag(pb, mov);
8405  }
8406 
8408  if (mov->time)
8409  mov->time += 0x7C25B080; // 1970 based -> 1904 based
8410 
8411  if (mov->chapter_track)
8412  if ((ret = mov_create_chapter_track(s, mov->chapter_track)) < 0)
8413  return ret;
8414 
8415  if (mov->flags & FF_MOV_FLAG_RTP_HINT) {
8416  for (int i = 0; i < mov->nb_streams; i++) {
8417  if (rtp_hinting_needed(mov->tracks[i].st)) {
8418  if ((ret = ff_mov_init_hinting(s, hint_track, i)) < 0)
8419  return ret;
8420  hint_track++;
8421  }
8422  }
8423  }
8424 
8425  if (mov->nb_meta_tmcd) {
8426  const AVDictionaryEntry *t, *global_tcr = av_dict_get(s->metadata,
8427  "timecode", NULL, 0);
8428  /* Initialize the tmcd tracks */
8429  for (int i = 0; i < mov->nb_streams; i++) {
8430  AVStream *st = mov->tracks[i].st;
8431  t = global_tcr;
8432 
8433  if (st->codecpar->codec_type == AVMEDIA_TYPE_VIDEO) {
8434  AVTimecode tc;
8435  if (!t)
8436  t = av_dict_get(st->metadata, "timecode", NULL, 0);
8437  if (!t)
8438  continue;
8439  if (mov_check_timecode_track(s, &tc, st, t->value) < 0)
8440  continue;
8441  if ((ret = mov_create_timecode_track(s, tmcd_track, i, tc)) < 0)
8442  return ret;
8443  tmcd_track++;
8444  }
8445  }
8446  }
8447 
8448  avio_flush(pb);
8449 
8450  if (mov->flags & FF_MOV_FLAG_ISML)
8451  mov_write_isml_manifest(pb, mov, s);
8452 
8453  if (mov->flags & FF_MOV_FLAG_EMPTY_MOOV &&
8454  !(mov->flags & FF_MOV_FLAG_DELAY_MOOV)) {
8455  if ((ret = mov_write_moov_tag(pb, mov, s)) < 0)
8456  return ret;
8457  mov->moov_written = 1;
8458  if (mov->flags & FF_MOV_FLAG_GLOBAL_SIDX)
8459  mov->reserved_header_pos = avio_tell(pb);
8460  }
8461 
8462  return 0;
8463 }
8464 
8466 {
8467  int ret;
8468  AVIOContext *moov_buf;
8469  MOVMuxContext *mov = s->priv_data;
8470 
8471  if ((ret = ffio_open_null_buf(&moov_buf)) < 0)
8472  return ret;
8473  if ((ret = mov_write_moov_tag(moov_buf, mov, s)) < 0)
8474  return ret;
8475  return ffio_close_null_buf(moov_buf);
8476 }
8477 
8479 {
8480  int ret;
8481  AVIOContext *buf;
8482  MOVMuxContext *mov = s->priv_data;
8483 
8484  if ((ret = ffio_open_null_buf(&buf)) < 0)
8485  return ret;
8486  mov_write_sidx_tags(buf, mov, -1, 0);
8487  return ffio_close_null_buf(buf);
8488 }
8489 
8490 /*
8491  * This function gets the moov size if moved to the top of the file: the chunk
8492  * offset table can switch between stco (32-bit entries) to co64 (64-bit
8493  * entries) when the moov is moved to the beginning, so the size of the moov
8494  * would change. It also updates the chunk offset tables.
8495  */
8497 {
8498  int i, moov_size, moov_size2;
8499  MOVMuxContext *mov = s->priv_data;
8500 
8501  moov_size = get_moov_size(s);
8502  if (moov_size < 0)
8503  return moov_size;
8504 
8505  for (i = 0; i < mov->nb_tracks; i++)
8506  mov->tracks[i].data_offset += moov_size;
8507 
8508  moov_size2 = get_moov_size(s);
8509  if (moov_size2 < 0)
8510  return moov_size2;
8511 
8512  /* if the size changed, we just switched from stco to co64 and need to
8513  * update the offsets */
8514  if (moov_size2 != moov_size)
8515  for (i = 0; i < mov->nb_tracks; i++)
8516  mov->tracks[i].data_offset += moov_size2 - moov_size;
8517 
8518  return moov_size2;
8519 }
8520 
8522 {
8523  int i, sidx_size;
8524  MOVMuxContext *mov = s->priv_data;
8525 
8526  sidx_size = get_sidx_size(s);
8527  if (sidx_size < 0)
8528  return sidx_size;
8529 
8530  for (i = 0; i < mov->nb_tracks; i++)
8531  mov->tracks[i].data_offset += sidx_size;
8532 
8533  return sidx_size;
8534 }
8535 
8537 {
8538  int moov_size;
8539  MOVMuxContext *mov = s->priv_data;
8540 
8541  if (mov->flags & FF_MOV_FLAG_FRAGMENT)
8542  moov_size = compute_sidx_size(s);
8543  else
8544  moov_size = compute_moov_size(s);
8545  if (moov_size < 0)
8546  return moov_size;
8547 
8548  return ff_format_shift_data(s, mov->reserved_header_pos, moov_size);
8549 }
8550 
8552 {
8553  MOVMuxContext *mov = s->priv_data;
8554  AVIOContext *pb = s->pb;
8555 
8556  /* Write size of mdat tag */
8557  if (mov->mdat_size + 8 <= UINT32_MAX) {
8558  avio_seek(pb, mov->mdat_pos, SEEK_SET);
8559  avio_wb32(pb, mov->mdat_size + 8);
8561  ffio_wfourcc(pb, "mdat"); // overwrite the original moov into a mdat
8562  } else {
8563  /* overwrite 'wide' placeholder atom */
8564  avio_seek(pb, mov->mdat_pos - 8, SEEK_SET);
8565  /* special value: real atom size will be 64 bit value after
8566  * tag field */
8567  avio_wb32(pb, 1);
8568  ffio_wfourcc(pb, "mdat");
8569  avio_wb64(pb, mov->mdat_size + 16);
8570  }
8571 }
8572 
8574 {
8575  MOVMuxContext *mov = s->priv_data;
8576  AVIOContext *pb = s->pb;
8577  int res = 0;
8578  int i;
8579  int64_t moov_pos;
8580 
8581  /*
8582  * Before actually writing the trailer, make sure that there are no
8583  * dangling subtitles, that need a terminating sample.
8584  */
8585  for (i = 0; i < mov->nb_tracks; i++) {
8586  MOVTrack *trk = &mov->tracks[i];
8587  if (trk->par->codec_id == AV_CODEC_ID_MOV_TEXT &&
8590  trk->last_sample_is_subtitle_end = 1;
8591  }
8592  }
8593 
8594  // Check if we have any tracks that require squashing.
8595  // In that case, we'll have to write the packet here.
8596  if ((res = mov_write_squashed_packets(s)) < 0)
8597  return res;
8598 
8599  // If there were no chapters when the header was written, but there
8600  // are chapters now, write them in the trailer. This only works
8601  // when we are not doing fragments.
8602  if (!mov->chapter_track && !(mov->flags & FF_MOV_FLAG_FRAGMENT)) {
8603  if (mov->mode & (MODE_MP4|MODE_MOV|MODE_IPOD) && s->nb_chapters) {
8604  mov->chapter_track = mov->nb_tracks++;
8605  if ((res = mov_create_chapter_track(s, mov->chapter_track)) < 0)
8606  return res;
8607  }
8608  }
8609 
8610  if (!(mov->flags & FF_MOV_FLAG_FRAGMENT) ||
8612  if (mov->flags & FF_MOV_FLAG_HYBRID_FRAGMENTED) {
8614  mov->mdat_size = avio_tell(pb) - mov->mdat_pos - 8;
8615  for (i = 0; i < mov->nb_tracks; i++) {
8616  MOVTrack *track = &mov->tracks[i];
8617  track->data_offset = 0;
8618  av_free(track->cluster);
8619  track->cluster = track->cluster_written;
8620  track->entry = track->entry_written;
8621  track->cluster_written = NULL;
8622  track->entry_written = 0;
8623  track->chunkCount = 0; // Force build_chunks to rebuild the list of chunks
8624  }
8625  // Clear the empty_moov flag, as we do want the moov to include
8626  // all the samples at this point.
8627  mov->flags &= ~FF_MOV_FLAG_EMPTY_MOOV;
8628  }
8629 
8630  moov_pos = avio_tell(pb);
8631 
8632  if (!(mov->flags & FF_MOV_FLAG_HYBRID_FRAGMENTED))
8634 
8635  avio_seek(pb, mov->reserved_moov_size > 0 ? mov->reserved_header_pos : moov_pos, SEEK_SET);
8636 
8637  if (mov->flags & FF_MOV_FLAG_FASTSTART) {
8638  av_log(s, AV_LOG_INFO, "Starting second pass: moving the moov atom to the beginning of the file\n");
8639  res = shift_data(s);
8640  if (res < 0)
8641  return res;
8642  avio_seek(pb, mov->reserved_header_pos, SEEK_SET);
8643  if ((res = mov_write_moov_tag(pb, mov, s)) < 0)
8644  return res;
8645  } else if (mov->reserved_moov_size > 0) {
8646  int64_t size;
8647  if ((res = mov_write_moov_tag(pb, mov, s)) < 0)
8648  return res;
8649  size = mov->reserved_moov_size - (avio_tell(pb) - mov->reserved_header_pos);
8650  if (size < 8){
8651  av_log(s, AV_LOG_ERROR, "reserved_moov_size is too small, needed %"PRId64" additional\n", 8-size);
8652  return AVERROR(EINVAL);
8653  }
8654  avio_wb32(pb, size);
8655  ffio_wfourcc(pb, "free");
8656  ffio_fill(pb, 0, size - 8);
8657  avio_seek(pb, moov_pos, SEEK_SET);
8658  } else {
8659  if ((res = mov_write_moov_tag(pb, mov, s)) < 0)
8660  return res;
8661  }
8662 
8663  if (mov->flags & FF_MOV_FLAG_HYBRID_FRAGMENTED) {
8664  // With hybrid fragmentation, only write the mdat size (hiding
8665  // the original moov and all the fragments within the mdat)
8666  // after we've successfully written the complete moov, to avoid
8667  // risk for an unreadable file if writing the final moov fails.
8669  }
8670 
8671  res = 0;
8672  } else {
8674  for (i = 0; i < mov->nb_tracks; i++)
8675  mov->tracks[i].data_offset = 0;
8676  if (mov->flags & FF_MOV_FLAG_GLOBAL_SIDX) {
8677  int64_t end;
8678  av_log(s, AV_LOG_INFO, "Starting second pass: inserting sidx atoms\n");
8679  res = shift_data(s);
8680  if (res < 0)
8681  return res;
8682  end = avio_tell(pb);
8683  avio_seek(pb, mov->reserved_header_pos, SEEK_SET);
8684  mov_write_sidx_tags(pb, mov, -1, 0);
8685  avio_seek(pb, end, SEEK_SET);
8686  }
8687  if (!(mov->flags & FF_MOV_FLAG_SKIP_TRAILER)) {
8689  res = mov_write_mfra_tag(pb, mov);
8690  if (res < 0)
8691  return res;
8692  }
8693  }
8694 
8695  return res;
8696 }
8697 
8699  const AVPacket *pkt)
8700 {
8701  int ret = 1;
8702 
8703  if (st->codecpar->codec_id == AV_CODEC_ID_AAC) {
8704  if (pkt->size > 2 && (AV_RB16(pkt->data) & 0xfff0) == 0xfff0)
8705  ret = ff_stream_add_bitstream_filter(st, "aac_adtstoasc", NULL);
8706  } else if (st->codecpar->codec_id == AV_CODEC_ID_VP9) {
8707  ret = ff_stream_add_bitstream_filter(st, "vp9_superframe", NULL);
8708  }
8709 
8710  return ret;
8711 }
8712 
8713 #if CONFIG_AVIF_MUXER
8714 static int avif_write_trailer(AVFormatContext *s)
8715 {
8716  AVIOContext *pb = s->pb;
8717  MOVMuxContext *mov = s->priv_data;
8718  int64_t pos_backup, extent_offsets[2];
8719  uint8_t *buf;
8720  int buf_size, moov_size;
8721 
8722  if (mov->moov_written) return 0;
8723 
8724  mov->is_animated_avif = s->streams[0]->nb_frames > 1;
8725  if (mov->is_animated_avif && mov->nb_streams > 1) {
8726  // For animated avif with alpha channel, we need to write a tref tag
8727  // with type "auxl".
8728  mov->tracks[1].tref_tag = MKTAG('a', 'u', 'x', 'l');
8729  mov->tracks[1].tref_id = 1;
8730  }
8732  mov_write_meta_tag(pb, mov, s);
8733 
8734  moov_size = get_moov_size(s);
8735  for (int i = 0; i < mov->nb_tracks; i++)
8736  mov->tracks[i].data_offset = avio_tell(pb) + moov_size + 8;
8737 
8738  if (mov->is_animated_avif) {
8739  int ret;
8740  if ((ret = mov_write_moov_tag(pb, mov, s)) < 0)
8741  return ret;
8742  }
8743 
8744  buf_size = avio_get_dyn_buf(mov->mdat_buf, &buf);
8745  avio_wb32(pb, buf_size + 8);
8746  ffio_wfourcc(pb, "mdat");
8747 
8748  // The offset for the YUV planes is the starting position of mdat.
8749  extent_offsets[0] = avio_tell(pb);
8750  // The offset for alpha plane is YUV offset + YUV size.
8751  extent_offsets[1] = extent_offsets[0] + mov->avif_extent_length[0];
8752 
8753  avio_write(pb, buf, buf_size);
8754 
8755  // write extent offsets.
8756  pos_backup = avio_tell(pb);
8757  for (int i = 0; i < mov->nb_streams; i++) {
8758  if (extent_offsets[i] != (uint32_t)extent_offsets[i]) {
8759  av_log(s, AV_LOG_ERROR, "extent offset does not fit in 32 bits\n");
8760  return AVERROR_INVALIDDATA;
8761  }
8762  avio_seek(pb, mov->avif_extent_pos[i], SEEK_SET);
8763  avio_wb32(pb, extent_offsets[i]); /* rewrite offset */
8764  }
8765  avio_seek(pb, pos_backup, SEEK_SET);
8766 
8767  return 0;
8768 }
8769 #endif
8770 
8771 #if CONFIG_TGP_MUXER || CONFIG_TG2_MUXER
8772 static const AVCodecTag codec_3gp_tags[] = {
8773  { AV_CODEC_ID_H263, MKTAG('s','2','6','3') },
8774  { AV_CODEC_ID_H264, MKTAG('a','v','c','1') },
8775  { AV_CODEC_ID_MPEG4, MKTAG('m','p','4','v') },
8776  { AV_CODEC_ID_AAC, MKTAG('m','p','4','a') },
8777  { AV_CODEC_ID_AMR_NB, MKTAG('s','a','m','r') },
8778  { AV_CODEC_ID_AMR_WB, MKTAG('s','a','w','b') },
8779  { AV_CODEC_ID_MOV_TEXT, MKTAG('t','x','3','g') },
8780  { AV_CODEC_ID_NONE, 0 },
8781 };
8782 static const AVCodecTag *const codec_3gp_tags_list[] = { codec_3gp_tags, NULL };
8783 #endif
8784 
8785 static const AVCodecTag codec_mp4_tags[] = {
8786  { AV_CODEC_ID_MPEG4, MKTAG('m', 'p', '4', 'v') },
8787  { AV_CODEC_ID_H264, MKTAG('a', 'v', 'c', '1') },
8788  { AV_CODEC_ID_H264, MKTAG('a', 'v', 'c', '3') },
8789  { AV_CODEC_ID_HEVC, MKTAG('h', 'e', 'v', '1') },
8790  { AV_CODEC_ID_HEVC, MKTAG('h', 'v', 'c', '1') },
8791  { AV_CODEC_ID_HEVC, MKTAG('d', 'v', 'h', '1') },
8792  { AV_CODEC_ID_VVC, MKTAG('v', 'v', 'c', '1') },
8793  { AV_CODEC_ID_VVC, MKTAG('v', 'v', 'i', '1') },
8794  { AV_CODEC_ID_EVC, MKTAG('e', 'v', 'c', '1') },
8795  { AV_CODEC_ID_APV, MKTAG('a', 'p', 'v', '1') },
8796  { AV_CODEC_ID_MPEG2VIDEO, MKTAG('m', 'p', '4', 'v') },
8797  { AV_CODEC_ID_MPEG1VIDEO, MKTAG('m', 'p', '4', 'v') },
8798  { AV_CODEC_ID_MJPEG, MKTAG('m', 'p', '4', 'v') },
8799  { AV_CODEC_ID_PNG, MKTAG('m', 'p', '4', 'v') },
8800  { AV_CODEC_ID_JPEG2000, MKTAG('m', 'p', '4', 'v') },
8801  { AV_CODEC_ID_VC1, MKTAG('v', 'c', '-', '1') },
8802  { AV_CODEC_ID_DIRAC, MKTAG('d', 'r', 'a', 'c') },
8803  { AV_CODEC_ID_TSCC2, MKTAG('m', 'p', '4', 'v') },
8804  { AV_CODEC_ID_VP9, MKTAG('v', 'p', '0', '9') },
8805  { AV_CODEC_ID_AV1, MKTAG('a', 'v', '0', '1') },
8806  { AV_CODEC_ID_AAC, MKTAG('m', 'p', '4', 'a') },
8807  { AV_CODEC_ID_ALAC, MKTAG('a', 'l', 'a', 'c') },
8808  { AV_CODEC_ID_MP4ALS, MKTAG('m', 'p', '4', 'a') },
8809  { AV_CODEC_ID_MP3, MKTAG('m', 'p', '4', 'a') },
8810  { AV_CODEC_ID_MP2, MKTAG('m', 'p', '4', 'a') },
8811  { AV_CODEC_ID_AC3, MKTAG('a', 'c', '-', '3') },
8812  { AV_CODEC_ID_EAC3, MKTAG('e', 'c', '-', '3') },
8813  { AV_CODEC_ID_DTS, MKTAG('m', 'p', '4', 'a') },
8814  { AV_CODEC_ID_TRUEHD, MKTAG('m', 'l', 'p', 'a') },
8815  { AV_CODEC_ID_FLAC, MKTAG('f', 'L', 'a', 'C') },
8816  { AV_CODEC_ID_OPUS, MKTAG('O', 'p', 'u', 's') },
8817  { AV_CODEC_ID_VORBIS, MKTAG('m', 'p', '4', 'a') },
8818  { AV_CODEC_ID_QCELP, MKTAG('m', 'p', '4', 'a') },
8819  { AV_CODEC_ID_EVRC, MKTAG('m', 'p', '4', 'a') },
8820  { AV_CODEC_ID_DVD_SUBTITLE, MKTAG('m', 'p', '4', 's') },
8821  { AV_CODEC_ID_MOV_TEXT, MKTAG('t', 'x', '3', 'g') },
8822  { AV_CODEC_ID_BIN_DATA, MKTAG('g', 'p', 'm', 'd') },
8823  { AV_CODEC_ID_MPEGH_3D_AUDIO, MKTAG('m', 'h', 'm', '1') },
8826  { AV_CODEC_ID_FFV1, MKTAG('F', 'F', 'V', '1') },
8827 
8828  /* ISO/IEC 23003-5 integer formats */
8835  /* ISO/IEC 23003-5 floating-point formats */
8840 
8841  { AV_CODEC_ID_AVS3, MKTAG('a', 'v', 's', '3') },
8842 
8843  { AV_CODEC_ID_NONE, 0 },
8844 };
8845 #if CONFIG_MP4_MUXER || CONFIG_PSP_MUXER
8846 static const AVCodecTag *const mp4_codec_tags_list[] = { codec_mp4_tags, NULL };
8847 #endif
8848 
8849 static const AVCodecTag codec_ism_tags[] = {
8850  { AV_CODEC_ID_WMAPRO , MKTAG('w', 'm', 'a', ' ') },
8852  { AV_CODEC_ID_NONE , 0 },
8853 };
8854 
8855 static const AVCodecTag codec_ipod_tags[] = {
8856  { AV_CODEC_ID_H264, MKTAG('a','v','c','1') },
8857  { AV_CODEC_ID_MPEG4, MKTAG('m','p','4','v') },
8858  { AV_CODEC_ID_AAC, MKTAG('m','p','4','a') },
8859  { AV_CODEC_ID_ALAC, MKTAG('a','l','a','c') },
8860  { AV_CODEC_ID_AC3, MKTAG('a','c','-','3') },
8861  { AV_CODEC_ID_MOV_TEXT, MKTAG('t','x','3','g') },
8862  { AV_CODEC_ID_MOV_TEXT, MKTAG('t','e','x','t') },
8863  { AV_CODEC_ID_NONE, 0 },
8864 };
8865 
8866 static const AVCodecTag codec_f4v_tags[] = {
8867  { AV_CODEC_ID_MP3, MKTAG('.','m','p','3') },
8868  { AV_CODEC_ID_AAC, MKTAG('m','p','4','a') },
8869  { AV_CODEC_ID_H264, MKTAG('a','v','c','1') },
8870  { AV_CODEC_ID_VP6A, MKTAG('V','P','6','A') },
8871  { AV_CODEC_ID_VP6F, MKTAG('V','P','6','F') },
8872  { AV_CODEC_ID_NONE, 0 },
8873 };
8874 
8875 #if CONFIG_AVIF_MUXER
8876 
8877 static const AVOption avif_options[] = {
8878  { "movie_timescale", "set movie timescale", offsetof(MOVMuxContext, movie_timescale), AV_OPT_TYPE_INT, {.i64 = MOV_TIMESCALE}, 1, INT_MAX, AV_OPT_FLAG_ENCODING_PARAM},
8879  { "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 },
8880  { NULL },
8881 };
8882 static const AVCodecTag codec_avif_tags[] = {
8883  { AV_CODEC_ID_AV1, MKTAG('a','v','0','1') },
8884  { AV_CODEC_ID_NONE, 0 },
8885 };
8886 static const AVCodecTag *const codec_avif_tags_list[] = { codec_avif_tags, NULL };
8887 
8888 static const AVClass mov_avif_muxer_class = {
8889  .class_name = "avif muxer",
8890  .item_name = av_default_item_name,
8891  .option = avif_options,
8892  .version = LIBAVUTIL_VERSION_INT,
8893 };
8894 #endif
8895 
8896 #if CONFIG_MOV_MUXER
8897 const FFOutputFormat ff_mov_muxer = {
8898  .p.name = "mov",
8899  .p.long_name = NULL_IF_CONFIG_SMALL("QuickTime / MOV"),
8900  .p.extensions = "mov",
8901  .priv_data_size = sizeof(MOVMuxContext),
8902  .p.audio_codec = AV_CODEC_ID_AAC,
8903  .p.video_codec = CONFIG_LIBX264_ENCODER ?
8905  .init = mov_init,
8906  .write_header = mov_write_header,
8907  .write_packet = mov_write_packet,
8908  .write_trailer = mov_write_trailer,
8909  .deinit = mov_free,
8911  .p.codec_tag = (const AVCodecTag* const []){
8913  },
8914  .check_bitstream = mov_check_bitstream,
8915  .p.priv_class = &mov_isobmff_muxer_class,
8916  .flags_internal = FF_OFMT_FLAG_ALLOW_FLUSH,
8917 };
8918 #endif
8919 #if CONFIG_TGP_MUXER
8920 const FFOutputFormat ff_tgp_muxer = {
8921  .p.name = "3gp",
8922  .p.long_name = NULL_IF_CONFIG_SMALL("3GP (3GPP file format)"),
8923  .p.extensions = "3gp",
8924  .priv_data_size = sizeof(MOVMuxContext),
8925  .p.audio_codec = AV_CODEC_ID_AMR_NB,
8926  .p.video_codec = AV_CODEC_ID_H263,
8927  .init = mov_init,
8928  .write_header = mov_write_header,
8929  .write_packet = mov_write_packet,
8930  .write_trailer = mov_write_trailer,
8931  .deinit = mov_free,
8933  .p.codec_tag = codec_3gp_tags_list,
8934  .check_bitstream = mov_check_bitstream,
8935  .p.priv_class = &mov_isobmff_muxer_class,
8936  .flags_internal = FF_OFMT_FLAG_ALLOW_FLUSH,
8937 };
8938 #endif
8939 #if CONFIG_MP4_MUXER
8940 const FFOutputFormat ff_mp4_muxer = {
8941  .p.name = "mp4",
8942  .p.long_name = NULL_IF_CONFIG_SMALL("MP4 (MPEG-4 Part 14)"),
8943  .p.mime_type = "video/mp4",
8944  .p.extensions = "mp4",
8945  .priv_data_size = sizeof(MOVMuxContext),
8946  .p.audio_codec = AV_CODEC_ID_AAC,
8947  .p.video_codec = CONFIG_LIBX264_ENCODER ?
8949  .init = mov_init,
8950  .write_header = mov_write_header,
8951  .write_packet = mov_write_packet,
8952  .write_trailer = mov_write_trailer,
8953  .deinit = mov_free,
8955  .p.codec_tag = mp4_codec_tags_list,
8956  .check_bitstream = mov_check_bitstream,
8957  .p.priv_class = &mov_isobmff_muxer_class,
8958  .flags_internal = FF_OFMT_FLAG_ALLOW_FLUSH,
8959 };
8960 #endif
8961 #if CONFIG_PSP_MUXER
8962 const FFOutputFormat ff_psp_muxer = {
8963  .p.name = "psp",
8964  .p.long_name = NULL_IF_CONFIG_SMALL("PSP MP4 (MPEG-4 Part 14)"),
8965  .p.extensions = "mp4,psp",
8966  .priv_data_size = sizeof(MOVMuxContext),
8967  .p.audio_codec = AV_CODEC_ID_AAC,
8968  .p.video_codec = CONFIG_LIBX264_ENCODER ?
8970  .init = mov_init,
8971  .write_header = mov_write_header,
8972  .write_packet = mov_write_packet,
8973  .write_trailer = mov_write_trailer,
8974  .deinit = mov_free,
8976  .p.codec_tag = mp4_codec_tags_list,
8977  .check_bitstream = mov_check_bitstream,
8978  .p.priv_class = &mov_isobmff_muxer_class,
8979  .flags_internal = FF_OFMT_FLAG_ALLOW_FLUSH,
8980 };
8981 #endif
8982 #if CONFIG_TG2_MUXER
8983 const FFOutputFormat ff_tg2_muxer = {
8984  .p.name = "3g2",
8985  .p.long_name = NULL_IF_CONFIG_SMALL("3GP2 (3GPP2 file format)"),
8986  .p.extensions = "3g2",
8987  .priv_data_size = sizeof(MOVMuxContext),
8988  .p.audio_codec = AV_CODEC_ID_AMR_NB,
8989  .p.video_codec = AV_CODEC_ID_H263,
8990  .init = mov_init,
8991  .write_header = mov_write_header,
8992  .write_packet = mov_write_packet,
8993  .write_trailer = mov_write_trailer,
8994  .deinit = mov_free,
8996  .p.codec_tag = codec_3gp_tags_list,
8997  .check_bitstream = mov_check_bitstream,
8998  .p.priv_class = &mov_isobmff_muxer_class,
8999  .flags_internal = FF_OFMT_FLAG_ALLOW_FLUSH,
9000 };
9001 #endif
9002 #if CONFIG_IPOD_MUXER
9003 const FFOutputFormat ff_ipod_muxer = {
9004  .p.name = "ipod",
9005  .p.long_name = NULL_IF_CONFIG_SMALL("iPod H.264 MP4 (MPEG-4 Part 14)"),
9006  .p.mime_type = "video/mp4",
9007  .p.extensions = "m4v,m4a,m4b",
9008  .priv_data_size = sizeof(MOVMuxContext),
9009  .p.audio_codec = AV_CODEC_ID_AAC,
9010  .p.video_codec = AV_CODEC_ID_H264,
9011  .init = mov_init,
9012  .write_header = mov_write_header,
9013  .write_packet = mov_write_packet,
9014  .write_trailer = mov_write_trailer,
9015  .deinit = mov_free,
9017  .p.codec_tag = (const AVCodecTag* const []){ codec_ipod_tags, 0 },
9018  .check_bitstream = mov_check_bitstream,
9019  .p.priv_class = &mov_isobmff_muxer_class,
9020  .flags_internal = FF_OFMT_FLAG_ALLOW_FLUSH,
9021 };
9022 #endif
9023 #if CONFIG_ISMV_MUXER
9024 const FFOutputFormat ff_ismv_muxer = {
9025  .p.name = "ismv",
9026  .p.long_name = NULL_IF_CONFIG_SMALL("ISMV/ISMA (Smooth Streaming)"),
9027  .p.mime_type = "video/mp4",
9028  .p.extensions = "ismv,isma",
9029  .priv_data_size = sizeof(MOVMuxContext),
9030  .p.audio_codec = AV_CODEC_ID_AAC,
9031  .p.video_codec = AV_CODEC_ID_H264,
9032  .init = mov_init,
9033  .write_header = mov_write_header,
9034  .write_packet = mov_write_packet,
9035  .write_trailer = mov_write_trailer,
9036  .deinit = mov_free,
9038  .p.codec_tag = (const AVCodecTag* const []){
9040  .check_bitstream = mov_check_bitstream,
9041  .p.priv_class = &mov_isobmff_muxer_class,
9042  .flags_internal = FF_OFMT_FLAG_ALLOW_FLUSH,
9043 };
9044 #endif
9045 #if CONFIG_F4V_MUXER
9046 const FFOutputFormat ff_f4v_muxer = {
9047  .p.name = "f4v",
9048  .p.long_name = NULL_IF_CONFIG_SMALL("F4V Adobe Flash Video"),
9049  .p.mime_type = "application/f4v",
9050  .p.extensions = "f4v",
9051  .priv_data_size = sizeof(MOVMuxContext),
9052  .p.audio_codec = AV_CODEC_ID_AAC,
9053  .p.video_codec = AV_CODEC_ID_H264,
9054  .init = mov_init,
9055  .write_header = mov_write_header,
9056  .write_packet = mov_write_packet,
9057  .write_trailer = mov_write_trailer,
9058  .deinit = mov_free,
9059  .p.flags = AVFMT_GLOBALHEADER,
9060  .p.codec_tag = (const AVCodecTag* const []){ codec_f4v_tags, 0 },
9061  .check_bitstream = mov_check_bitstream,
9062  .p.priv_class = &mov_isobmff_muxer_class,
9063  .flags_internal = FF_OFMT_FLAG_ALLOW_FLUSH,
9064 };
9065 #endif
9066 #if CONFIG_AVIF_MUXER
9067 const FFOutputFormat ff_avif_muxer = {
9068  .p.name = "avif",
9069  .p.long_name = NULL_IF_CONFIG_SMALL("AVIF"),
9070  .p.mime_type = "image/avif",
9071  .p.extensions = "avif",
9072  .priv_data_size = sizeof(MOVMuxContext),
9073  .p.video_codec = AV_CODEC_ID_AV1,
9074  .init = mov_init,
9075  .write_header = mov_write_header,
9076  .write_packet = mov_write_packet,
9077  .write_trailer = avif_write_trailer,
9078  .deinit = mov_free,
9079  .p.flags = AVFMT_GLOBALHEADER,
9080  .p.codec_tag = codec_avif_tags_list,
9081  .p.priv_class = &mov_avif_muxer_class,
9082  .flags_internal = FF_OFMT_FLAG_ALLOW_FLUSH,
9083 };
9084 #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:3746
codec_ism_tags
static const AVCodecTag codec_ism_tags[]
Definition: movenc.c:8849
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:5616
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:4151
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:1980
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:5120
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:2325
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:3438
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:4212
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:5885
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:4899
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:5551
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:4851
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:7095
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:5426
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:4373
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:5354
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:4232
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:3447
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:2484
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:6624
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:767
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:4320
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:3871
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:7820
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:7582
mov_write_ccst_tag
static int mov_write_ccst_tag(AVIOContext *pb)
Definition: movenc.c:2662
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:664
mov_write_mdta_hdlr_tag
static int mov_write_mdta_hdlr_tag(AVIOContext *pb, MOVMuxContext *mov, AVFormatContext *s)
Definition: movenc.c:4716
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:4813
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:539
AV_DICT_IGNORE_SUFFIX
#define AV_DICT_IGNORE_SUFFIX
Return first entry in a dictionary whose first part corresponds to the search key,...
Definition: dict.h:75
AV_CODEC_ID_AMR_NB
@ AV_CODEC_ID_AMR_NB
Definition: codec_id.h:440
MOVIentry::dts
int64_t dts
Definition: movenc.h:50
MOV_TIMESCALE
#define MOV_TIMESCALE
Definition: movenc.h:33
co64_required
static int co64_required(const MOVTrack *track)
Definition: movenc.c:164
mov_write_aux_tag
static int mov_write_aux_tag(AVIOContext *pb, const char *aux_type)
Definition: movenc.c:2681
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:4438
mov_write_header
static int mov_write_header(AVFormatContext *s)
Definition: movenc.c:8300
mov_write_sv3d_tag
static int mov_write_sv3d_tag(AVFormatContext *s, AVIOContext *pb, AVSphericalMapping *spherical_mapping)
Definition: movenc.c:2224
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:4544
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:8478
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:2132
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
MOVTrack::vc1_info
struct MOVTrack::@455 vc1_info
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:2955
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:3447
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:2070
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:4833
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:5604
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:4349
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:2298
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:3771
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:1801
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:3043
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:4514
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:4362
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:3180
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:3801
mov_write_video_tag
static int mov_write_video_tag(AVFormatContext *s, AVIOContext *pb, MOVMuxContext *mov, MOVTrack *track)
Definition: movenc.c:2691
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:1989
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:5975
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:2077
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:5081
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:6384
mov_write_iref_tag
static int mov_write_iref_tag(AVIOContext *pb, MOVMuxContext *mov, AVFormatContext *s)
Definition: movenc.c:3596
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:5008
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:1776
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:5590
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:4526
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:4264
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:1956
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:8573
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:7251
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:4873
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:5861
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:4595
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:3643
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:3548
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:6197
mov_write_tcmi_tag
static int mov_write_tcmi_tag(AVIOContext *pb, MOVTrack *track)
Definition: movenc.c:3354
build_chunks
static void build_chunks(MOVTrack *trk)
Definition: movenc.c:5045
MOV_PRFT_NONE
@ MOV_PRFT_NONE
Definition: movenc.h:195
AVCOL_PRI_UNSPECIFIED
@ AVCOL_PRI_UNSPECIFIED
Definition: pixfmt.h:639
mov_write_edts_tag
static int mov_write_edts_tag(AVIOContext *pb, MOVMuxContext *mov, MOVTrack *track)
Definition: movenc.c:4014
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:2506
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:3453
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:5345
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:4957
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:8496
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:3538
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:7521
codec_f4v_tags
static const AVCodecTag codec_f4v_tags[]
Definition: movenc.c:8866
mov_create_timecode_track
static int mov_create_timecode_track(AVFormatContext *s, int index, int src_index, AVTimecode tc)
Definition: movenc.c:7530
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:7279
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:8465
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:1944
check_pkt
static int check_pkt(AVFormatContext *s, MOVTrack *trk, AVPacket *pkt)
Definition: movenc.c:6638
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:6360
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:5658
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:2443
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:2471
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:4172
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:2605
ff_mov_get_channel_positions_from_layout
int ff_mov_get_channel_positions_from_layout(const AVChannelLayout *layout, uint8_t *position, int position_num)
Get ISO/IEC 23001-8 OutputChannelPosition from AVChannelLayout.
Definition: mov_chan.c:702
ff_codec_movvideo_tags
const AVCodecTag ff_codec_movvideo_tags[]
Definition: isom_tags.c:29
AV_PIX_FMT_YUV422P10
#define AV_PIX_FMT_YUV422P10
Definition: pixfmt.h:540
mov_get_lpcm_flags
static int mov_get_lpcm_flags(enum AVCodecID codec_id)
Compute flags for 'lpcm' tag.
Definition: movenc.c: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_write_nmhd_tag
static int mov_write_nmhd_tag(AVIOContext *pb)
Definition: movenc.c:3338
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:2015
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:3709
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:5203
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:3090
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:4454
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:733
mov_write_isml_manifest
static int mov_write_isml_manifest(AVIOContext *pb, MOVMuxContext *mov, AVFormatContext *s)
Definition: movenc.c:5221
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:7182
AVCodecParameters::sample_rate
int sample_rate
Audio only.
Definition: codec_par.h:184
mov_write_stbl_tag
static int mov_write_stbl_tag(AVFormatContext *s, AVIOContext *pb, MOVMuxContext *mov, MOVTrack *track)
Definition: movenc.c:3290
cid
uint16_t cid
Definition: mxfenc.c:2314
compute_sidx_size
static int compute_sidx_size(AVFormatContext *s)
Definition: movenc.c:8521
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:2632
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:8855
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:1763
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:2287
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:1958
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:2383
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:4731
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:4133
av_csp_approximate_trc_gamma
double av_csp_approximate_trc_gamma(enum AVColorTransferCharacteristic trc)
Determine a suitable 'gamma' value to match the supplied AVColorTransferCharacteristic.
Definition: csp.c:149
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:8785
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:4489
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:3857
mov_create_dvd_sub_decoder_specific_info
static int mov_create_dvd_sub_decoder_specific_info(MOVTrack *track, AVStream *st)
Definition: movenc.c:7694
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:3376
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:3055
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:2994
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:3783
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:1934
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:2149
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:4186
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:1682
mov_write_mdta_ilst_tag
static int mov_write_mdta_ilst_tag(AVIOContext *pb, MOVMuxContext *mov, AVFormatContext *s)
Definition: movenc.c:4760
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:4782
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:8536
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:3571
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:7624
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:4649
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:3684
interlaced
uint8_t interlaced
Definition: mxfenc.c:2315
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:6097
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:3329
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:6673
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:1810
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:4475
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:8551
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:6278
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:3979
mov_write_stsz_tag
static int mov_write_stsz_tag(AVIOContext *pb, MOVTrack *track)
Definition: movenc.c:212
profile
int profile
Definition: mxfenc.c:2278
AVCOL_SPC_UNSPECIFIED
@ AVCOL_SPC_UNSPECIFIED
Definition: pixfmt.h:693
rtpenc.h
mov_check_bitstream
static int mov_check_bitstream(AVFormatContext *s, AVStream *st, const AVPacket *pkt)
Definition: movenc.c:8698
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:750
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
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:5360
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:3131
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:5829
AV_PROFILE_DNXHD
#define AV_PROFILE_DNXHD
Definition: defs.h:80
tag
uint32_t tag
Definition: movenc.c:1957
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:1872
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:4622
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:3627
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:4122
mov_write_uuid_tag_ipod
static int mov_write_uuid_tag_ipod(AVIOContext *pb)
Write uuid atom.
Definition: movenc.c:2120
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
eac3_info::substream
struct eac3_info::@454 substream[1]
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:6416
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:3346
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:7678
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:7430
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:5934
mov_write_prft_tag
static int mov_write_prft_tag(AVIOContext *pb, MOVMuxContext *mov, int tracks)
Definition: movenc.c:5779
mov_write_fiel_tag
static int mov_write_fiel_tag(AVIOContext *pb, MOVTrack *track, int field_order)
Definition: movenc.c:2136
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:6168
mov_write_sidx_tags
static int mov_write_sidx_tags(AVIOContext *pb, MOVMuxContext *mov, int tracks, int ref_size)
Definition: movenc.c:5744
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:4676
mov_flush_fragment_interleaving
static int mov_flush_fragment_interleaving(AVFormatContext *s, MOVTrack *track)
Definition: movenc.c:6297
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:3792
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:3838
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:3615
AC3HeaderInfo::bitstream_id
uint8_t bitstream_id
Definition: ac3_parser_internal.h:41
AVMEDIA_TYPE_VIDEO
@ AVMEDIA_TYPE_VIDEO
Definition: avutil.h:200
mov_pix_fmt_tags
static const struct @453 mov_pix_fmt_tags[]
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:5213
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:4970
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:2425
mov_preroll_write_stbl_atoms
static int mov_preroll_write_stbl_atoms(AVIOContext *pb, MOVTrack *track)
Definition: movenc.c:3195
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:2194
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:4844
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:3660
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:3428
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:2975
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:6218
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:6322
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:3694
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:5208
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:2574
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:2282
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:5923
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:5502
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:5537
ff_stream_add_bitstream_filter
int ff_stream_add_bitstream_filter(AVStream *st, const char *name, const char *args)
Add a bitstream filter to a stream.
Definition: mux.c:1294
AV_PROFILE_AAC_USAC
#define AV_PROFILE_AAC_USAC
Definition: defs.h:76
AV_CODEC_ID_PCM_S24BE
@ AV_CODEC_ID_PCM_S24BE
Definition: codec_id.h:350
AC3HeaderInfo::bit_rate
uint32_t bit_rate
Definition: ac3_parser_internal.h:60
mov_find_codec_tag
static unsigned int mov_find_codec_tag(AVFormatContext *s, MOVTrack *track)
Definition: movenc.c:2097
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:5482
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:2554
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:3367
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:5683
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