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 preceeding 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 preceeding 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  if (mov->flags & FF_MOV_FLAG_FRAGMENT)
5187  mov_write_mvex_tag(pb, mov); /* QuickTime requires trak to precede this */
5188 
5189  if (mov->mode == MODE_PSP)
5191  else if (mov->mode != MODE_AVIF)
5192  mov_write_udta_tag(pb, mov, s);
5193  for (i = 0; i < mov->nb_streams; i++)
5194  mov_write_pssh_tag(pb, mov->tracks[i].st);
5195 
5196  return update_size(pb, pos);
5197 }
5198 
5199 static void param_write_int(AVIOContext *pb, const char *name, int value)
5200 {
5201  avio_printf(pb, "<param name=\"%s\" value=\"%d\" valuetype=\"data\"/>\n", name, value);
5202 }
5203 
5204 static void param_write_string(AVIOContext *pb, const char *name, const char *value)
5205 {
5206  avio_printf(pb, "<param name=\"%s\" value=\"%s\" valuetype=\"data\"/>\n", name, value);
5207 }
5208 
5209 static void param_write_hex(AVIOContext *pb, const char *name, const uint8_t *value, int len)
5210 {
5211  char buf[150];
5212  len = FFMIN(sizeof(buf) / 2 - 1, len);
5213  ff_data_to_hex(buf, value, len, 0);
5214  avio_printf(pb, "<param name=\"%s\" value=\"%s\" valuetype=\"data\"/>\n", name, buf);
5215 }
5216 
5218 {
5219  int64_t pos = avio_tell(pb);
5220  int i;
5221 
5222  static const AVUUID uuid = {
5223  0xa5, 0xd4, 0x0b, 0x30, 0xe8, 0x14, 0x11, 0xdd,
5224  0xba, 0x2f, 0x08, 0x00, 0x20, 0x0c, 0x9a, 0x66
5225  };
5226 
5227  avio_wb32(pb, 0);
5228  ffio_wfourcc(pb, "uuid");
5229  avio_write(pb, uuid, AV_UUID_LEN);
5230  avio_wb32(pb, 0);
5231 
5232  avio_printf(pb, "<?xml version=\"1.0\" encoding=\"utf-8\"?>\n");
5233  avio_printf(pb, "<smil xmlns=\"http://www.w3.org/2001/SMIL20/Language\">\n");
5234  avio_printf(pb, "<head>\n");
5235  if (!(mov->fc->flags & AVFMT_FLAG_BITEXACT))
5236  avio_printf(pb, "<meta name=\"creator\" content=\"%s\" />\n",
5238  avio_printf(pb, "</head>\n");
5239  avio_printf(pb, "<body>\n");
5240  avio_printf(pb, "<switch>\n");
5241 
5242  mov_setup_track_ids(mov, s);
5243 
5244  for (i = 0; i < mov->nb_tracks; i++) {
5245  MOVTrack *track = &mov->tracks[i];
5246  struct mpeg4_bit_rate_values bit_rates =
5248  const char *type;
5249  int track_id = track->track_id;
5250  char track_name_buf[32] = { 0 };
5251 
5252  AVStream *st = track->st;
5253  AVDictionaryEntry *lang = av_dict_get(st->metadata, "language", NULL,0);
5254 
5255  if (track->par->codec_type == AVMEDIA_TYPE_VIDEO && !is_cover_image(st)) {
5256  type = "video";
5257  } else if (track->par->codec_type == AVMEDIA_TYPE_AUDIO) {
5258  type = "audio";
5259  } else {
5260  continue;
5261  }
5262 
5263  avio_printf(pb, "<%s systemBitrate=\"%"PRIu32"\">\n", type,
5264  bit_rates.avg_bit_rate);
5265  param_write_int(pb, "systemBitrate", bit_rates.avg_bit_rate);
5266  param_write_int(pb, "trackID", track_id);
5267  param_write_string(pb, "systemLanguage", lang ? lang->value : "und");
5268 
5269  /* Build track name piece by piece: */
5270  /* 1. track type */
5271  av_strlcat(track_name_buf, type, sizeof(track_name_buf));
5272  /* 2. track language, if available */
5273  if (lang)
5274  av_strlcatf(track_name_buf, sizeof(track_name_buf),
5275  "_%s", lang->value);
5276  /* 3. special type suffix */
5277  /* "_cc" = closed captions, "_ad" = audio_description */
5279  av_strlcat(track_name_buf, "_cc", sizeof(track_name_buf));
5281  av_strlcat(track_name_buf, "_ad", sizeof(track_name_buf));
5282 
5283  param_write_string(pb, "trackName", track_name_buf);
5284 
5285  if (track->par->codec_type == AVMEDIA_TYPE_VIDEO) {
5286  if (track->par->codec_id == AV_CODEC_ID_H264) {
5287  uint8_t *ptr;
5288  int size = track->extradata_size[track->last_stsd_index];
5289  if (!ff_avc_write_annexb_extradata(track->extradata[track->last_stsd_index], &ptr,
5290  &size)) {
5291  param_write_hex(pb, "CodecPrivateData",
5292  ptr ? ptr : track->extradata[track->last_stsd_index],
5293  size);
5294  av_free(ptr);
5295  }
5296  param_write_string(pb, "FourCC", "H264");
5297  } else if (track->par->codec_id == AV_CODEC_ID_VC1) {
5298  param_write_string(pb, "FourCC", "WVC1");
5299  param_write_hex(pb, "CodecPrivateData", track->extradata[track->last_stsd_index],
5300  track->extradata_size[track->last_stsd_index]);
5301  }
5302  param_write_int(pb, "MaxWidth", track->par->width);
5303  param_write_int(pb, "MaxHeight", track->par->height);
5304  param_write_int(pb, "DisplayWidth", track->par->width);
5305  param_write_int(pb, "DisplayHeight", track->par->height);
5306  } else {
5307  if (track->par->codec_id == AV_CODEC_ID_AAC) {
5308  switch (track->par->profile) {
5309  case AV_PROFILE_AAC_HE_V2:
5310  param_write_string(pb, "FourCC", "AACP");
5311  break;
5312  case AV_PROFILE_AAC_HE:
5313  param_write_string(pb, "FourCC", "AACH");
5314  break;
5315  default:
5316  param_write_string(pb, "FourCC", "AACL");
5317  }
5318  } else if (track->par->codec_id == AV_CODEC_ID_WMAPRO) {
5319  param_write_string(pb, "FourCC", "WMAP");
5320  }
5321  param_write_hex(pb, "CodecPrivateData", track->extradata[track->last_stsd_index],
5322  track->extradata_size[track->last_stsd_index]);
5324  track->par->codec_id));
5325  param_write_int(pb, "Channels", track->par->ch_layout.nb_channels);
5326  param_write_int(pb, "SamplingRate", track->tag == MKTAG('i','a','m','f') ?
5327  0 : track->par->sample_rate);
5328  param_write_int(pb, "BitsPerSample", 16);
5329  param_write_int(pb, "PacketSize", track->par->block_align ?
5330  track->par->block_align : 4);
5331  }
5332  avio_printf(pb, "</%s>\n", type);
5333  }
5334  avio_printf(pb, "</switch>\n");
5335  avio_printf(pb, "</body>\n");
5336  avio_printf(pb, "</smil>\n");
5337 
5338  return update_size(pb, pos);
5339 }
5340 
5342 {
5343  avio_wb32(pb, 16);
5344  ffio_wfourcc(pb, "mfhd");
5345  avio_wb32(pb, 0);
5346  avio_wb32(pb, mov->fragments);
5347  return 0;
5348 }
5349 
5350 static uint32_t get_sample_flags(MOVTrack *track, MOVIentry *entry)
5351 {
5354 }
5355 
5357  MOVTrack *track, int64_t moof_offset)
5358 {
5359  int64_t pos = avio_tell(pb);
5362  if (!track->entry) {
5364  } else {
5366  }
5369  if (mov->flags & FF_MOV_FLAG_DEFAULT_BASE_MOOF) {
5372  }
5373  /* CMAF requires all values to be explicit in tfhd atoms */
5374  if (mov->flags & FF_MOV_FLAG_CMAF)
5376 
5377  /* Don't set a default sample size, the silverlight player refuses
5378  * to play files with that set. Don't set a default sample duration,
5379  * WMP freaks out if it is set. Don't set a base data offset, PIFF
5380  * file format says it MUST NOT be set. */
5381  if (track->mode == MODE_ISM)
5384 
5385  avio_wb32(pb, 0); /* size placeholder */
5386  ffio_wfourcc(pb, "tfhd");
5387  avio_w8(pb, 0); /* version */
5388  avio_wb24(pb, flags);
5389 
5390  avio_wb32(pb, track->track_id); /* track-id */
5392  avio_wb64(pb, moof_offset);
5393  if (flags & MOV_TFHD_STSD_ID) {
5394  avio_wb32(pb, 1);
5395  }
5397  track->default_duration = get_cluster_duration(track, 0);
5398  avio_wb32(pb, track->default_duration);
5399  }
5400  if (flags & MOV_TFHD_DEFAULT_SIZE) {
5401  track->default_size = track->entry ? track->cluster[0].size : 1;
5402  avio_wb32(pb, track->default_size);
5403  } else
5404  track->default_size = -1;
5405 
5406  if (flags & MOV_TFHD_DEFAULT_FLAGS) {
5407  /* Set the default flags based on the second sample, if available.
5408  * If the first sample is different, that can be signaled via a separate field. */
5409  if (track->entry > 1)
5410  track->default_sample_flags = get_sample_flags(track, &track->cluster[1]);
5411  else
5412  track->default_sample_flags =
5413  track->par->codec_type == AVMEDIA_TYPE_VIDEO ?
5416  avio_wb32(pb, track->default_sample_flags);
5417  }
5418 
5419  return update_size(pb, pos);
5420 }
5421 
5423  MOVTrack *track, int moof_size,
5424  int first, int end)
5425 {
5426  int64_t pos = avio_tell(pb);
5427  uint32_t flags = MOV_TRUN_DATA_OFFSET;
5428  int i;
5429 
5430  for (i = first; i < end; i++) {
5431  if (get_cluster_duration(track, i) != track->default_duration)
5433  if (track->cluster[i].size != track->default_size)
5435  if (i > first && get_sample_flags(track, &track->cluster[i]) != track->default_sample_flags)
5437  }
5438  if (!(flags & MOV_TRUN_SAMPLE_FLAGS) && track->entry > first &&
5439  get_sample_flags(track, &track->cluster[first]) != track->default_sample_flags)
5441  if (track->flags & MOV_TRACK_CTTS)
5443 
5444  avio_wb32(pb, 0); /* size placeholder */
5445  ffio_wfourcc(pb, "trun");
5447  avio_w8(pb, 1); /* version */
5448  else
5449  avio_w8(pb, 0); /* version */
5450  avio_wb24(pb, flags);
5451 
5452  avio_wb32(pb, end - first); /* sample count */
5453  if (mov->flags & FF_MOV_FLAG_OMIT_TFHD_OFFSET &&
5455  !mov->first_trun)
5456  avio_wb32(pb, 0); /* Later tracks follow immediately after the previous one */
5457  else
5458  avio_wb32(pb, moof_size + 8 + track->data_offset +
5459  track->cluster[first].pos); /* data offset */
5461  avio_wb32(pb, get_sample_flags(track, &track->cluster[first]));
5462 
5463  for (i = first; i < end; i++) {
5465  avio_wb32(pb, get_cluster_duration(track, i));
5467  avio_wb32(pb, track->cluster[i].size);
5469  avio_wb32(pb, get_sample_flags(track, &track->cluster[i]));
5470  if (flags & MOV_TRUN_SAMPLE_CTS)
5471  avio_wb32(pb, track->cluster[i].cts);
5472  }
5473 
5474  mov->first_trun = 0;
5475  return update_size(pb, pos);
5476 }
5477 
5478 static int mov_write_tfxd_tag(AVIOContext *pb, MOVTrack *track)
5479 {
5480  int64_t pos = avio_tell(pb);
5481  static const uint8_t uuid[] = {
5482  0x6d, 0x1d, 0x9b, 0x05, 0x42, 0xd5, 0x44, 0xe6,
5483  0x80, 0xe2, 0x14, 0x1d, 0xaf, 0xf7, 0x57, 0xb2
5484  };
5485 
5486  avio_wb32(pb, 0); /* size placeholder */
5487  ffio_wfourcc(pb, "uuid");
5488  avio_write(pb, uuid, AV_UUID_LEN);
5489  avio_w8(pb, 1);
5490  avio_wb24(pb, 0);
5491  avio_wb64(pb, track->cluster[0].dts + track->cluster[0].cts);
5492  avio_wb64(pb, track->end_pts -
5493  (track->cluster[0].dts + track->cluster[0].cts));
5494 
5495  return update_size(pb, pos);
5496 }
5497 
5499  MOVTrack *track, int entry)
5500 {
5501  int n = track->nb_frag_info - 1 - entry, i;
5502  int size = 8 + 16 + 4 + 1 + 16*n;
5503  static const uint8_t uuid[] = {
5504  0xd4, 0x80, 0x7e, 0xf2, 0xca, 0x39, 0x46, 0x95,
5505  0x8e, 0x54, 0x26, 0xcb, 0x9e, 0x46, 0xa7, 0x9f
5506  };
5507 
5508  if (entry < 0)
5509  return 0;
5510 
5511  avio_seek(pb, track->frag_info[entry].tfrf_offset, SEEK_SET);
5512  avio_wb32(pb, size);
5513  ffio_wfourcc(pb, "uuid");
5514  avio_write(pb, uuid, AV_UUID_LEN);
5515  avio_w8(pb, 1);
5516  avio_wb24(pb, 0);
5517  avio_w8(pb, n);
5518  for (i = 0; i < n; i++) {
5519  int index = entry + 1 + i;
5520  avio_wb64(pb, track->frag_info[index].time);
5521  avio_wb64(pb, track->frag_info[index].duration);
5522  }
5523  if (n < mov->ism_lookahead) {
5524  int free_size = 16 * (mov->ism_lookahead - n);
5525  avio_wb32(pb, free_size);
5526  ffio_wfourcc(pb, "free");
5527  ffio_fill(pb, 0, free_size - 8);
5528  }
5529 
5530  return 0;
5531 }
5532 
5534  MOVTrack *track)
5535 {
5536  int64_t pos = avio_tell(pb);
5537  int i;
5538  for (i = 0; i < mov->ism_lookahead; i++) {
5539  /* Update the tfrf tag for the last ism_lookahead fragments,
5540  * nb_frag_info - 1 is the next fragment to be written. */
5541  mov_write_tfrf_tag(pb, mov, track, track->nb_frag_info - 2 - i);
5542  }
5543  avio_seek(pb, pos, SEEK_SET);
5544  return 0;
5545 }
5546 
5547 static int mov_add_tfra_entries(AVIOContext *pb, MOVMuxContext *mov, int tracks,
5548  int size)
5549 {
5550  int i;
5551  for (i = 0; i < mov->nb_tracks; i++) {
5552  MOVTrack *track = &mov->tracks[i];
5554  if ((tracks >= 0 && i != tracks) || !track->entry)
5555  continue;
5556  track->nb_frag_info++;
5557  if (track->nb_frag_info >= track->frag_info_capacity) {
5558  unsigned new_capacity = track->nb_frag_info + MOV_FRAG_INFO_ALLOC_INCREMENT;
5559  if (av_reallocp_array(&track->frag_info,
5560  new_capacity,
5561  sizeof(*track->frag_info)))
5562  return AVERROR(ENOMEM);
5563  track->frag_info_capacity = new_capacity;
5564  }
5565  info = &track->frag_info[track->nb_frag_info - 1];
5566  info->offset = avio_tell(pb);
5567  info->size = size;
5568  // Try to recreate the original pts for the first packet
5569  // from the fields we have stored
5570  info->time = track->cluster[0].dts + track->cluster[0].cts;
5571  info->duration = track->end_pts -
5572  (track->cluster[0].dts + track->cluster[0].cts);
5573  // If the pts is less than zero, we will have trimmed
5574  // away parts of the media track using an edit list,
5575  // and the corresponding start presentation time is zero.
5576  if (info->time < 0) {
5577  info->duration += info->time;
5578  info->time = 0;
5579  }
5580  info->tfrf_offset = 0;
5581  mov_write_tfrf_tags(pb, mov, track);
5582  }
5583  return 0;
5584 }
5585 
5586 static void mov_prune_frag_info(MOVMuxContext *mov, int tracks, int max)
5587 {
5588  int i;
5589  for (i = 0; i < mov->nb_tracks; i++) {
5590  MOVTrack *track = &mov->tracks[i];
5591  if ((tracks >= 0 && i != tracks) || !track->entry)
5592  continue;
5593  if (track->nb_frag_info > max) {
5594  memmove(track->frag_info, track->frag_info + (track->nb_frag_info - max), max * sizeof(*track->frag_info));
5595  track->nb_frag_info = max;
5596  }
5597  }
5598 }
5599 
5600 static int mov_write_tfdt_tag(AVIOContext *pb, MOVTrack *track)
5601 {
5602  int64_t pos = avio_tell(pb);
5603 
5604  avio_wb32(pb, 0); /* size */
5605  ffio_wfourcc(pb, "tfdt");
5606  avio_w8(pb, 1); /* version */
5607  avio_wb24(pb, 0);
5608  avio_wb64(pb, track->cluster[0].dts - track->start_dts);
5609  return update_size(pb, pos);
5610 }
5611 
5613  MOVTrack *track, int64_t moof_offset,
5614  int moof_size)
5615 {
5616  int64_t pos = avio_tell(pb);
5617  int i, start = 0;
5618  avio_wb32(pb, 0); /* size placeholder */
5619  ffio_wfourcc(pb, "traf");
5620 
5621  mov_write_tfhd_tag(pb, mov, track, moof_offset);
5622  if (mov->mode != MODE_ISM)
5623  mov_write_tfdt_tag(pb, track);
5624  for (i = 1; i < track->entry; i++) {
5625  if (track->cluster[i].pos != track->cluster[i - 1].pos + track->cluster[i - 1].size) {
5626  mov_write_trun_tag(pb, mov, track, moof_size, start, i);
5627  start = i;
5628  }
5629  }
5630  mov_write_trun_tag(pb, mov, track, moof_size, start, track->entry);
5631  if (mov->mode == MODE_ISM) {
5632  mov_write_tfxd_tag(pb, track);
5633 
5634  if (mov->ism_lookahead) {
5635  int size = 16 + 4 + 1 + 16 * mov->ism_lookahead;
5636 
5637  if (track->nb_frag_info > 0) {
5638  MOVFragmentInfo *info = &track->frag_info[track->nb_frag_info - 1];
5639  if (!info->tfrf_offset)
5640  info->tfrf_offset = avio_tell(pb);
5641  }
5642  avio_wb32(pb, 8 + size);
5643  ffio_wfourcc(pb, "free");
5644  ffio_fill(pb, 0, size);
5645  }
5646  }
5647 
5648  if (track->cenc.aes_ctr && (mov->flags & FF_MOV_FLAG_FRAGMENT))
5649  ff_mov_cenc_write_stbl_atoms(&track->cenc, pb, moof_offset);
5650 
5651  return update_size(pb, pos);
5652 }
5653 
5655  int tracks, int moof_size)
5656 {
5657  int64_t pos = avio_tell(pb);
5658  int i;
5659 
5660  avio_wb32(pb, 0); /* size placeholder */
5661  ffio_wfourcc(pb, "moof");
5662  mov->first_trun = 1;
5663 
5664  mov_write_mfhd_tag(pb, mov);
5665  for (i = 0; i < mov->nb_tracks; i++) {
5666  MOVTrack *track = &mov->tracks[i];
5667  if (tracks >= 0 && i != tracks)
5668  continue;
5669  if (!track->entry)
5670  continue;
5671  if (track->cenc.aes_ctr && (mov->flags & FF_MOV_FLAG_FRAGMENT))
5672  mov_write_pssh_tag(pb, track->st);
5673  mov_write_traf_tag(pb, mov, track, pos, moof_size);
5674  }
5675 
5676  return update_size(pb, pos);
5677 }
5678 
5680  MOVTrack *track, int ref_size, int total_sidx_size)
5681 {
5682  int64_t pos = avio_tell(pb), offset_pos, end_pos;
5683  int64_t presentation_time, duration, offset;
5684  unsigned starts_with_SAP;
5685  int i, entries;
5686 
5687  if (track->entry) {
5688  entries = 1;
5689  presentation_time = track->cluster[0].dts + track->cluster[0].cts -
5690  track->start_dts - track->start_cts;
5691  duration = track->end_pts -
5692  (track->cluster[0].dts + track->cluster[0].cts);
5693  starts_with_SAP = track->cluster[0].flags & MOV_SYNC_SAMPLE;
5694 
5695  // pts<0 should be cut away using edts
5696  if (presentation_time < 0) {
5697  duration += presentation_time;
5698  presentation_time = 0;
5699  }
5700  } else {
5701  entries = track->nb_frag_info;
5702  if (entries <= 0)
5703  return 0;
5704  presentation_time = track->frag_info[0].time;
5705  /* presentation_time <= 0 is handled by mov_add_tfra_entries() */
5706  if (presentation_time > 0)
5707  presentation_time -= track->start_dts + track->start_cts;
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 && !(mov->flags & FF_MOV_FLAG_EMPTY_MOOV)) {
6394  // First flush. If this was a case of not using empty moov, reset chunking.
6395  for (i = 0; i < track->entry; i++) {
6396  track->cluster[i].chunkNum = 0;
6397  track->cluster[i].samples_in_chunk = track->cluster[i].entries;
6398  }
6399  }
6400  if (av_reallocp_array(&track->cluster_written,
6401  track->entry_written + track->entry,
6402  sizeof(*track->cluster)))
6403  return AVERROR(ENOMEM);
6404  memcpy(&track->cluster_written[track->entry_written],
6405  track->cluster, track->entry * sizeof(*track->cluster));
6406  track->entry_written += track->entry;
6407  }
6408  track->entry = 0;
6409  track->entries_flushed = 0;
6410  track->end_reliable = 0;
6411  return 0;
6412 }
6413 
6414 static int mov_flush_fragment(AVFormatContext *s, int force)
6415 {
6416  MOVMuxContext *mov = s->priv_data;
6417  int i, first_track = -1;
6418  int64_t mdat_size = 0, mdat_start = 0;
6419  int ret;
6420  int has_video = 0, starts_with_key = 0, first_video_track = 1;
6421 
6422  if (!(mov->flags & FF_MOV_FLAG_FRAGMENT))
6423  return 0;
6424 
6425  // Check if we have any tracks that require squashing.
6426  // In that case, we'll have to write the packet here.
6427  if ((ret = mov_write_squashed_packets(s)) < 0)
6428  return ret;
6429 
6430  // Try to fill in the duration of the last packet in each stream
6431  // from queued packets in the interleave queues. If the flushing
6432  // of fragments was triggered automatically by an AVPacket, we
6433  // already have reliable info for the end of that track, but other
6434  // tracks may need to be filled in.
6435  for (i = 0; i < mov->nb_streams; i++) {
6436  MOVTrack *track = &mov->tracks[i];
6437  if (!track->end_reliable) {
6438  const AVPacket *pkt = ff_interleaved_peek(s, i);
6439  if (pkt) {
6440  int64_t offset, dts, pts;
6442  pts = pkt->pts + offset;
6443  dts = pkt->dts + offset;
6444  if (track->dts_shift != AV_NOPTS_VALUE)
6445  dts += track->dts_shift;
6446  track->track_duration = dts - track->start_dts;
6447  if (pts != AV_NOPTS_VALUE)
6448  track->end_pts = pts;
6449  else
6450  track->end_pts = dts;
6451  }
6452  }
6453  }
6454 
6455  for (i = 0; i < mov->nb_tracks; i++) {
6456  MOVTrack *track = &mov->tracks[i];
6457  if (track->entry <= 1)
6458  continue;
6459  // Sample durations are calculated as the diff of dts values,
6460  // but for the last sample in a fragment, we don't know the dts
6461  // of the first sample in the next fragment, so we have to rely
6462  // on what was set as duration in the AVPacket. Not all callers
6463  // set this though, so we might want to replace it with an
6464  // estimate if it currently is zero.
6465  if (get_cluster_duration(track, track->entry - 1) != 0)
6466  continue;
6467  // Use the duration (i.e. dts diff) of the second last sample for
6468  // the last one. This is a wild guess (and fatal if it turns out
6469  // to be too long), but probably the best we can do - having a zero
6470  // duration is bad as well.
6471  track->track_duration += get_cluster_duration(track, track->entry - 2);
6472  track->end_pts += get_cluster_duration(track, track->entry - 2);
6473  if (!mov->missing_duration_warned) {
6475  "Estimating the duration of the last packet in a "
6476  "fragment, consider setting the duration field in "
6477  "AVPacket instead.\n");
6478  mov->missing_duration_warned = 1;
6479  }
6480  }
6481 
6482  if (!mov->moov_written) {
6483  int64_t pos = avio_tell(s->pb);
6484  uint8_t *buf;
6485  int buf_size, moov_size;
6486 
6487  for (i = 0; i < mov->nb_tracks; i++)
6488  if (!mov->tracks[i].entry && !is_cover_image(mov->tracks[i].st))
6489  break;
6490  /* Don't write the initial moov unless all tracks have data */
6491  if (i < mov->nb_tracks && !force)
6492  return 0;
6493 
6494  moov_size = get_moov_size(s);
6495  for (i = 0; i < mov->nb_tracks; i++)
6496  mov->tracks[i].data_offset = pos + moov_size + 8;
6497 
6499  if (mov->flags & FF_MOV_FLAG_DELAY_MOOV)
6501  if ((ret = mov_write_moov_tag(s->pb, mov, s)) < 0)
6502  return ret;
6503 
6504  if (mov->flags & FF_MOV_FLAG_DELAY_MOOV) {
6505  if (mov->flags & FF_MOV_FLAG_GLOBAL_SIDX)
6506  mov->reserved_header_pos = avio_tell(s->pb);
6508  mov->moov_written = 1;
6509  return 0;
6510  }
6511 
6512  buf_size = avio_get_dyn_buf(mov->mdat_buf, &buf);
6513  avio_wb32(s->pb, buf_size + 8);
6514  ffio_wfourcc(s->pb, "mdat");
6515  avio_write(s->pb, buf, buf_size);
6516  ffio_free_dyn_buf(&mov->mdat_buf);
6517 
6518  if (mov->flags & FF_MOV_FLAG_GLOBAL_SIDX)
6519  mov->reserved_header_pos = avio_tell(s->pb);
6520 
6521  mov->moov_written = 1;
6522  mov->mdat_size = 0;
6523  for (i = 0; i < mov->nb_tracks; i++)
6524  mov_finish_fragment(mov, &mov->tracks[i], 0);
6526  return 0;
6527  }
6528 
6529  if (mov->frag_interleave) {
6530  for (i = 0; i < mov->nb_tracks; i++) {
6531  MOVTrack *track = &mov->tracks[i];
6532  int ret;
6533  if ((ret = mov_flush_fragment_interleaving(s, track)) < 0)
6534  return ret;
6535  }
6536 
6537  if (!mov->mdat_buf)
6538  return 0;
6539  mdat_size = avio_tell(mov->mdat_buf);
6540  }
6541 
6542  for (i = 0; i < mov->nb_tracks; i++) {
6543  MOVTrack *track = &mov->tracks[i];
6544  if (mov->flags & FF_MOV_FLAG_SEPARATE_MOOF || mov->frag_interleave)
6545  track->data_offset = 0;
6546  else
6547  track->data_offset = mdat_size;
6548  if (track->par->codec_type == AVMEDIA_TYPE_VIDEO) {
6549  has_video = 1;
6550  if (first_video_track) {
6551  if (track->entry)
6552  starts_with_key = track->cluster[0].flags & MOV_SYNC_SAMPLE;
6553  first_video_track = 0;
6554  }
6555  }
6556  if (!track->entry)
6557  continue;
6558  if (track->mdat_buf)
6559  mdat_size += avio_tell(track->mdat_buf);
6560  if (first_track < 0)
6561  first_track = i;
6562  }
6563 
6564  if (!mdat_size)
6565  return 0;
6566 
6567  avio_write_marker(s->pb,
6568  av_rescale(mov->tracks[first_track].cluster[0].dts, AV_TIME_BASE, mov->tracks[first_track].timescale),
6569  (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);
6570 
6571  for (i = first_track; i < mov->nb_tracks; i++) {
6572  MOVTrack *track = &mov->tracks[i];
6573  int buf_size, write_moof = 1, moof_tracks = -1;
6574  uint8_t *buf;
6575 
6576  if (!track->entry)
6577  continue;
6578  if (mov->flags & FF_MOV_FLAG_SEPARATE_MOOF) {
6579  mdat_size = avio_tell(track->mdat_buf);
6580  moof_tracks = i;
6581  } else {
6582  write_moof = i == first_track;
6583  }
6584 
6585  if (write_moof) {
6587 
6588  mov_write_moof_tag(s->pb, mov, moof_tracks, mdat_size);
6589  mov->fragments++;
6590 
6591  avio_wb32(s->pb, mdat_size + 8);
6592  ffio_wfourcc(s->pb, "mdat");
6593  mdat_start = avio_tell(s->pb);
6594  }
6595 
6596  mov_finish_fragment(mov, &mov->tracks[i], mdat_start);
6597  if (!mov->frag_interleave) {
6598  if (!track->mdat_buf)
6599  continue;
6600  buf_size = avio_close_dyn_buf(track->mdat_buf, &buf);
6601  track->mdat_buf = NULL;
6602  } else {
6603  if (!mov->mdat_buf)
6604  continue;
6605  buf_size = avio_close_dyn_buf(mov->mdat_buf, &buf);
6606  mov->mdat_buf = NULL;
6607  }
6608 
6609  avio_write(s->pb, buf, buf_size);
6610  av_free(buf);
6611  }
6612 
6613  mov->mdat_size = 0;
6614 
6616  return 0;
6617 }
6618 
6620 {
6621  MOVMuxContext *mov = s->priv_data;
6622  int had_moov = mov->moov_written;
6623  int ret = mov_flush_fragment(s, force);
6624  if (ret < 0)
6625  return ret;
6626  // If using delay_moov, the first flush only wrote the moov,
6627  // not the actual moof+mdat pair, thus flush once again.
6628  if (!had_moov && mov->flags & FF_MOV_FLAG_DELAY_MOOV)
6629  ret = mov_flush_fragment(s, force);
6630  return ret;
6631 }
6632 
6634 {
6635  int64_t ref;
6636  uint64_t duration;
6637 
6638  if (trk->entry) {
6639  ref = trk->cluster[trk->entry - 1].dts;
6640  } else if ( trk->start_dts != AV_NOPTS_VALUE
6641  && !trk->frag_discont) {
6642  ref = trk->start_dts + trk->track_duration;
6643  } else
6644  ref = pkt->dts; // Skip tests for the first packet
6645 
6646  if (trk->dts_shift != AV_NOPTS_VALUE) {
6647  /* With negative CTS offsets we have set an offset to the DTS,
6648  * reverse this for the check. */
6649  ref -= trk->dts_shift;
6650  }
6651 
6652  duration = pkt->dts - ref;
6653  if (pkt->dts < ref || duration >= INT_MAX) {
6654  av_log(s, AV_LOG_WARNING, "Packet duration: %"PRId64" / dts: %"PRId64" in stream %d is out of range\n",
6656 
6657  pkt->dts = ref + 1;
6658  pkt->pts = AV_NOPTS_VALUE;
6659  }
6660 
6661  if (pkt->duration < 0 || pkt->duration > INT_MAX) {
6662  av_log(s, AV_LOG_ERROR, "Application provided duration: %"PRId64" in stream %d is invalid\n", pkt->duration, pkt->stream_index);
6663  return AVERROR(EINVAL);
6664  }
6665  return 0;
6666 }
6667 
6669 {
6670  MOVMuxContext *mov = s->priv_data;
6671  AVIOContext *pb = s->pb;
6672  MOVTrack *trk;
6673  AVCodecParameters *par;
6675  unsigned int samples_in_chunk = 0;
6676  int size = pkt->size, ret = 0, offset = 0;
6677  size_t prft_size;
6678  uint8_t *reformatted_data = NULL;
6679 
6680  if (pkt->stream_index < s->nb_streams)
6681  trk = s->streams[pkt->stream_index]->priv_data;
6682  else // Timecode or chapter
6683  trk = &mov->tracks[pkt->stream_index];
6684  par = trk->par;
6685 
6686  ret = check_pkt(s, trk, pkt);
6687  if (ret < 0)
6688  return ret;
6689 
6690  if (pkt->pts != AV_NOPTS_VALUE &&
6691  (uint64_t)pkt->dts - pkt->pts != (int32_t)((uint64_t)pkt->dts - pkt->pts)) {
6692  av_log(s, AV_LOG_WARNING, "pts/dts pair unsupported\n");
6693  return AVERROR_PATCHWELCOME;
6694  }
6695 
6696  if (mov->flags & FF_MOV_FLAG_FRAGMENT || mov->mode == MODE_AVIF) {
6697  int ret;
6698  if (mov->moov_written || mov->flags & FF_MOV_FLAG_EMPTY_MOOV) {
6699  if (mov->frag_interleave && mov->fragments > 0) {
6700  if (trk->entry - trk->entries_flushed >= mov->frag_interleave) {
6701  if ((ret = mov_flush_fragment_interleaving(s, trk)) < 0)
6702  return ret;
6703  }
6704  }
6705 
6706  if (!trk->mdat_buf) {
6707  if ((ret = avio_open_dyn_buf(&trk->mdat_buf)) < 0)
6708  return ret;
6709  }
6710  pb = trk->mdat_buf;
6711  } else {
6712  if (!mov->mdat_buf) {
6713  if ((ret = avio_open_dyn_buf(&mov->mdat_buf)) < 0)
6714  return ret;
6715  }
6716  pb = mov->mdat_buf;
6717  }
6718  }
6719 
6720  if (par->codec_id == AV_CODEC_ID_AMR_NB) {
6721  /* We must find out how many AMR blocks there are in one packet */
6722  static const uint16_t packed_size[16] =
6723  {13, 14, 16, 18, 20, 21, 27, 32, 6, 0, 0, 0, 0, 0, 0, 1};
6724  int len = 0;
6725 
6726  while (len < size && samples_in_chunk < 100) {
6727  len += packed_size[(pkt->data[len] >> 3) & 0x0F];
6728  samples_in_chunk++;
6729  }
6730  if (samples_in_chunk > 1) {
6731  av_log(s, AV_LOG_ERROR, "fatal error, input is not a single packet, implement a AVParser for it\n");
6732  return -1;
6733  }
6734  } else if (par->codec_id == AV_CODEC_ID_ADPCM_MS ||
6736  samples_in_chunk = trk->par->frame_size;
6737  } else if (trk->sample_size)
6738  samples_in_chunk = size / trk->sample_size;
6739  else
6740  samples_in_chunk = 1;
6741 
6742  if (samples_in_chunk < 1) {
6743  av_log(s, AV_LOG_ERROR, "fatal error, input packet contains no samples\n");
6744  return AVERROR_PATCHWELCOME;
6745  }
6746 
6747  /* copy extradata if it exists */
6748  if (trk->extradata_size[0] == 0 && par->extradata_size > 0 &&
6749  !TAG_IS_AVCI(trk->tag) &&
6750  (par->codec_id != AV_CODEC_ID_DNXHD)) {
6751  trk->extradata[0] = av_memdup(par->extradata, par->extradata_size);
6752  if (!trk->extradata[0]) {
6753  ret = AVERROR(ENOMEM);
6754  goto err;
6755  }
6756  trk->extradata_size[0] = par->extradata_size;
6757  }
6758 
6759  if ((par->codec_id == AV_CODEC_ID_DNXHD ||
6760  par->codec_id == AV_CODEC_ID_H264 ||
6761  par->codec_id == AV_CODEC_ID_HEVC ||
6762  par->codec_id == AV_CODEC_ID_VVC ||
6763  par->codec_id == AV_CODEC_ID_VP9 ||
6764  par->codec_id == AV_CODEC_ID_EVC ||
6765  par->codec_id == AV_CODEC_ID_TRUEHD) && !trk->extradata_size[0] &&
6766  !TAG_IS_AVCI(trk->tag)) {
6767  /* copy frame to create needed atoms */
6768  trk->extradata_size[0] = size;
6770  if (!trk->extradata[0]) {
6771  ret = AVERROR(ENOMEM);
6772  goto err;
6773  }
6774  memcpy(trk->extradata[0], pkt->data, size);
6775  memset(trk->extradata[0] + size, 0, AV_INPUT_BUFFER_PADDING_SIZE);
6776  }
6777 
6779  if (pkt->size && sd && sd->size > 0) {
6780  int i;
6781  for (i = 0; i < trk->stsd_count; i++) {
6782  if (trk->extradata_size[i] == sd->size && !memcmp(trk->extradata[i], sd->data, sd->size))
6783  break;
6784  }
6785 
6786  if (i < trk->stsd_count)
6787  trk->last_stsd_index = i;
6788  else if (trk->stsd_count <= INT_MAX - 1) {
6789  int new_count = trk->stsd_count + 1;
6790  uint8_t **extradata = av_realloc_array(trk->extradata, new_count, sizeof(*trk->extradata));
6791  if (!extradata)
6792  return AVERROR(ENOMEM);
6793  trk->extradata = extradata;
6794 
6795  int *extradata_size = av_realloc_array(trk->extradata_size, new_count, sizeof(*trk->extradata_size));
6796  if (!extradata_size)
6797  return AVERROR(ENOMEM);
6798  trk->extradata_size = extradata_size;
6799 
6800  trk->extradata[trk->stsd_count] = av_memdup(sd->data, sd->size);
6801  if (!trk->extradata[trk->stsd_count])
6802  return AVERROR(ENOMEM);
6803 
6804  trk->extradata_size[trk->stsd_count] = sd->size;
6805  trk->last_stsd_index = trk->stsd_count;
6806  trk->stsd_count = new_count;
6807  } else
6808  return AVERROR(ENOMEM);
6809  }
6810 
6811  if (par->codec_id == AV_CODEC_ID_AAC && pkt->size > 2 &&
6812  (AV_RB16(pkt->data) & 0xfff0) == 0xfff0) {
6813  if (!trk->st->nb_frames) {
6814  av_log(s, AV_LOG_ERROR, "Malformed AAC bitstream detected: "
6815  "use the audio bitstream filter 'aac_adtstoasc' to fix it "
6816  "('-bsf:a aac_adtstoasc' option with ffmpeg)\n");
6817  return -1;
6818  }
6819  av_log(s, AV_LOG_WARNING, "aac bitstream error\n");
6820  }
6821  if (par->codec_id == AV_CODEC_ID_H264 && trk->extradata_size[trk->last_stsd_index] > 0 &&
6822  *(uint8_t *)trk->extradata[trk->last_stsd_index] != 1 && !TAG_IS_AVCI(trk->tag)) {
6823  /* from x264 or from bytestream H.264 */
6824  /* NAL reformatting needed */
6825  if (trk->hint_track >= 0 && trk->hint_track < mov->nb_tracks) {
6826  ret = ff_nal_parse_units_buf(pkt->data, &reformatted_data,
6827  &size);
6828  if (ret < 0)
6829  return ret;
6830  avio_write(pb, reformatted_data, size);
6831  } else {
6832  if (trk->cenc.aes_ctr) {
6834  if (size < 0) {
6835  ret = size;
6836  goto err;
6837  }
6838  } else {
6839  size = ff_nal_parse_units(pb, pkt->data, pkt->size);
6840  }
6841  }
6842  } else if (par->codec_id == AV_CODEC_ID_HEVC && trk->extradata_size[trk->last_stsd_index] > 6 &&
6843  (AV_RB24(trk->extradata[trk->last_stsd_index]) == 1 || AV_RB32(trk->extradata[trk->last_stsd_index]) == 1)) {
6844  /* extradata is Annex B, assume the bitstream is too and convert it */
6845  int filter_ps = (trk->tag == MKTAG('h','v','c','1'));
6846  if (trk->hint_track >= 0 && trk->hint_track < mov->nb_tracks) {
6847  ret = ff_hevc_annexb2mp4_buf(pkt->data, &reformatted_data,
6848  &size, filter_ps, NULL);
6849  if (ret < 0)
6850  return ret;
6851  avio_write(pb, reformatted_data, size);
6852  } else {
6853  if (trk->cenc.aes_ctr) {
6855  if (size < 0) {
6856  ret = size;
6857  goto err;
6858  }
6859  } else {
6860  size = ff_hevc_annexb2mp4(pb, pkt->data, pkt->size, filter_ps, NULL);
6861  }
6862  }
6863  } else if (par->codec_id == AV_CODEC_ID_VVC && trk->extradata_size[trk->last_stsd_index] > 6 &&
6864  (AV_RB24(trk->extradata[trk->last_stsd_index]) == 1 || AV_RB32(trk->extradata[trk->last_stsd_index]) == 1)) {
6865  /* extradata is Annex B, assume the bitstream is too and convert it */
6866  if (trk->hint_track >= 0 && trk->hint_track < mov->nb_tracks) {
6867  ret = ff_vvc_annexb2mp4_buf(pkt->data, &reformatted_data,
6868  &size, 0, NULL);
6869  if (ret < 0)
6870  return ret;
6871  avio_write(pb, reformatted_data, size);
6872  } else {
6873  size = ff_vvc_annexb2mp4(pb, pkt->data, pkt->size, 0, NULL);
6874  }
6875  } else if (par->codec_id == AV_CODEC_ID_AV1 && !trk->cenc.aes_ctr) {
6876  if (trk->hint_track >= 0 && trk->hint_track < mov->nb_tracks) {
6877  ret = ff_av1_filter_obus_buf(pkt->data, &reformatted_data,
6878  &size, &offset);
6879  if (ret < 0)
6880  return ret;
6881  avio_write(pb, reformatted_data, size);
6882  } else {
6883  size = ff_av1_filter_obus(pb, pkt->data, pkt->size);
6884  if (trk->mode == MODE_AVIF && !mov->avif_extent_length[pkt->stream_index]) {
6886  }
6887  }
6888 
6889  } else if (par->codec_id == AV_CODEC_ID_AC3 ||
6890  par->codec_id == AV_CODEC_ID_EAC3) {
6891  size = handle_eac3(mov, pkt, trk);
6892  if (size < 0)
6893  return size;
6894  else if (!size)
6895  goto end;
6896  avio_write(pb, pkt->data, size);
6897  } else if (par->codec_id == AV_CODEC_ID_EIA_608) {
6898  size = 8;
6899 
6900  for (int i = 0; i < pkt->size; i += 3) {
6901  if (pkt->data[i] == 0xFC) {
6902  size += 2;
6903  }
6904  }
6905  avio_wb32(pb, size);
6906  ffio_wfourcc(pb, "cdat");
6907  for (int i = 0; i < pkt->size; i += 3) {
6908  if (pkt->data[i] == 0xFC) {
6909  avio_w8(pb, pkt->data[i + 1]);
6910  avio_w8(pb, pkt->data[i + 2]);
6911  }
6912  }
6913  } else if (par->codec_id == AV_CODEC_ID_APV) {
6914  ff_isom_parse_apvc(trk->apv, pkt, s);
6915  avio_wb32(s->pb, pkt->size);
6916  size += 4;
6917 
6918  avio_write(s->pb, pkt->data, pkt->size);
6919  } else {
6920  if (trk->cenc.aes_ctr) {
6921  uint8_t *extradata = trk->extradata[trk->last_stsd_index];
6922  int extradata_size = trk->extradata_size[trk->last_stsd_index];
6923  if (par->codec_id == AV_CODEC_ID_H264 && extradata_size > 4) {
6924  int nal_size_length = (extradata[4] & 0x3) + 1;
6925  ret = ff_mov_cenc_avc_write_nal_units(s, &trk->cenc, nal_size_length, pb, pkt->data, size);
6926  } else if(par->codec_id == AV_CODEC_ID_HEVC && extradata_size > 21) {
6927  int nal_size_length = (extradata[21] & 0x3) + 1;
6928  ret = ff_mov_cenc_avc_write_nal_units(s, &trk->cenc, nal_size_length, pb, pkt->data, size);
6929  } else if(par->codec_id == AV_CODEC_ID_VVC) {
6931  } else if(par->codec_id == AV_CODEC_ID_AV1) {
6932  av_assert0(size == pkt->size);
6933  ret = ff_mov_cenc_av1_write_obus(s, &trk->cenc, pb, pkt);
6934  if (ret > 0) {
6935  size = ret;
6936  ret = 0;
6937  }
6938  } else {
6939  ret = ff_mov_cenc_write_packet(&trk->cenc, pb, pkt->data, size);
6940  }
6941 
6942  if (ret) {
6943  goto err;
6944  }
6945  } else {
6946  avio_write(pb, pkt->data, size);
6947  }
6948  }
6949 
6950  if (trk->entry >= trk->cluster_capacity) {
6951  unsigned new_capacity = trk->entry + MOV_INDEX_CLUSTER_SIZE;
6952  void *cluster = av_realloc_array(trk->cluster, new_capacity, sizeof(*trk->cluster));
6953  if (!cluster) {
6954  ret = AVERROR(ENOMEM);
6955  goto err;
6956  }
6957  trk->cluster = cluster;
6958  trk->cluster_capacity = new_capacity;
6959  }
6960 
6961  trk->cluster[trk->entry].pos = avio_tell(pb) - size;
6962  trk->cluster[trk->entry].stsd_index = trk->last_stsd_index;
6963  trk->cluster[trk->entry].samples_in_chunk = samples_in_chunk;
6964  trk->cluster[trk->entry].chunkNum = 0;
6965  trk->cluster[trk->entry].size = size;
6966  trk->cluster[trk->entry].entries = samples_in_chunk;
6967  trk->cluster[trk->entry].dts = pkt->dts;
6968  trk->cluster[trk->entry].pts = pkt->pts;
6969  if (!trk->squash_fragment_samples_to_one &&
6970  !trk->entry && trk->start_dts != AV_NOPTS_VALUE) {
6971  if (!trk->frag_discont) {
6972  /* First packet of a new fragment. We already wrote the duration
6973  * of the last packet of the previous fragment based on track_duration,
6974  * which might not exactly match our dts. Therefore adjust the dts
6975  * of this packet to be what the previous packets duration implies. */
6976  trk->cluster[trk->entry].dts = trk->start_dts + trk->track_duration;
6977  /* We also may have written the pts and the corresponding duration
6978  * in sidx/tfrf/tfxd tags; make sure the sidx pts and duration match up with
6979  * the next fragment. This means the cts of the first sample must
6980  * be the same in all fragments, unless end_pts was updated by
6981  * the packet causing the fragment to be written. */
6982  if ((mov->flags & FF_MOV_FLAG_DASH &&
6984  mov->mode == MODE_ISM)
6985  pkt->pts = pkt->dts + trk->end_pts - trk->cluster[trk->entry].dts;
6986  } else {
6987  /* New fragment, but discontinuous from previous fragments.
6988  * Pretend the duration sum of the earlier fragments is
6989  * pkt->dts - trk->start_dts. */
6990  trk->end_pts = AV_NOPTS_VALUE;
6991  trk->frag_discont = 0;
6992  }
6993  }
6994 
6995  if (!trk->entry && trk->start_dts == AV_NOPTS_VALUE && !mov->use_editlist &&
6996  s->avoid_negative_ts == AVFMT_AVOID_NEG_TS_MAKE_ZERO) {
6997  /* Not using edit lists and shifting the first track to start from zero.
6998  * If the other streams start from a later timestamp, we won't be able
6999  * to signal the difference in starting time without an edit list.
7000  * Thus move the timestamp for this first sample to 0, increasing
7001  * its duration instead. */
7002  trk->cluster[trk->entry].dts = trk->start_dts = 0;
7003  }
7004  if (trk->start_dts == AV_NOPTS_VALUE) {
7005  trk->start_dts = pkt->dts;
7006  if (trk->frag_discont) {
7007  if (mov->use_editlist) {
7008  /* Pretend the whole stream started at pts=0, with earlier fragments
7009  * already written. If the stream started at pts=0, the duration sum
7010  * of earlier fragments would have been pkt->pts. */
7011  trk->start_dts = pkt->dts - pkt->pts;
7012  } else {
7013  /* Pretend the whole stream started at dts=0, with earlier fragments
7014  * already written, with a duration summing up to pkt->dts. */
7015  trk->start_dts = 0;
7016  }
7017  trk->frag_discont = 0;
7018  } else if (pkt->dts && mov->moov_written)
7020  "Track %d starts with a nonzero dts %"PRId64", while the moov "
7021  "already has been written. Set the delay_moov flag to handle "
7022  "this case.\n",
7023  pkt->stream_index, pkt->dts);
7024  }
7025  trk->track_duration = pkt->dts - trk->start_dts + pkt->duration;
7026  trk->last_sample_is_subtitle_end = 0;
7027 
7028  if (pkt->pts == AV_NOPTS_VALUE) {
7029  av_log(s, AV_LOG_WARNING, "pts has no value\n");
7030  pkt->pts = pkt->dts;
7031  }
7032  if (pkt->dts != pkt->pts)
7033  trk->flags |= MOV_TRACK_CTTS;
7034  trk->cluster[trk->entry].cts = pkt->pts - pkt->dts;
7035  trk->cluster[trk->entry].flags = 0;
7036  if (trk->start_cts == AV_NOPTS_VALUE || (pkt->dts <= 0 && trk->start_cts > pkt->pts - pkt->dts))
7037  trk->start_cts = pkt->pts - pkt->dts;
7038  if (trk->end_pts == AV_NOPTS_VALUE)
7039  trk->end_pts = trk->cluster[trk->entry].dts +
7040  trk->cluster[trk->entry].cts + pkt->duration;
7041  else
7042  trk->end_pts = FFMAX(trk->end_pts, trk->cluster[trk->entry].dts +
7043  trk->cluster[trk->entry].cts +
7044  pkt->duration);
7045 
7046  if (par->codec_id == AV_CODEC_ID_VC1) {
7047  mov_parse_vc1_frame(pkt, trk);
7048  } else if (par->codec_id == AV_CODEC_ID_TRUEHD) {
7050  } else if (pkt->flags & AV_PKT_FLAG_KEY) {
7051  if (mov->mode == MODE_MOV && par->codec_id == AV_CODEC_ID_MPEG2VIDEO &&
7052  trk->entry > 0) { // force sync sample for the first key frame
7054  if (trk->cluster[trk->entry].flags & MOV_PARTIAL_SYNC_SAMPLE)
7055  trk->flags |= MOV_TRACK_STPS;
7056  } else {
7057  trk->cluster[trk->entry].flags = MOV_SYNC_SAMPLE;
7058  }
7059  if (trk->cluster[trk->entry].flags & MOV_SYNC_SAMPLE)
7060  trk->has_keyframes++;
7061  }
7062  if (pkt->flags & AV_PKT_FLAG_DISPOSABLE) {
7063  trk->cluster[trk->entry].flags |= MOV_DISPOSABLE_SAMPLE;
7064  trk->has_disposable++;
7065  }
7066 
7068  if (prft && prft_size == sizeof(AVProducerReferenceTime))
7069  memcpy(&trk->cluster[trk->entry].prft, prft, prft_size);
7070  else
7071  memset(&trk->cluster[trk->entry].prft, 0, sizeof(AVProducerReferenceTime));
7072 
7073  trk->entry++;
7074  trk->sample_count += samples_in_chunk;
7075  mov->mdat_size += size;
7076 
7077  if (trk->hint_track >= 0 && trk->hint_track < mov->nb_tracks)
7079  reformatted_data ? reformatted_data + offset
7080  : NULL, size);
7081 
7082 end:
7083 err:
7084 
7085  if (pkt->data != reformatted_data)
7086  av_free(reformatted_data);
7087  return ret;
7088 }
7089 
7091 {
7092  MOVMuxContext *mov = s->priv_data;
7093  MOVTrack *trk = s->streams[pkt->stream_index]->priv_data;
7094  AVCodecParameters *par = trk->par;
7095  int64_t frag_duration = 0;
7096  int size = pkt->size;
7097 
7098  int ret = check_pkt(s, trk, pkt);
7099  if (ret < 0)
7100  return ret;
7101 
7102  if (mov->flags & FF_MOV_FLAG_FRAG_DISCONT) {
7103  for (int i = 0; i < mov->nb_streams; i++)
7104  mov->tracks[i].frag_discont = 1;
7106  }
7107 
7109  if (trk->dts_shift == AV_NOPTS_VALUE)
7110  trk->dts_shift = pkt->pts - pkt->dts;
7111  pkt->dts += trk->dts_shift;
7112  }
7113 
7114  if (trk->par->codec_id == AV_CODEC_ID_MP4ALS ||
7115  trk->par->codec_id == AV_CODEC_ID_AAC ||
7116  trk->par->codec_id == AV_CODEC_ID_AV1 ||
7117  trk->par->codec_id == AV_CODEC_ID_FLAC) {
7118  size_t side_size;
7119  uint8_t *side = av_packet_get_side_data(pkt, AV_PKT_DATA_NEW_EXTRADATA, &side_size);
7120  /* Overwrite extradata only on flush packets or when no extradata was available during init */
7121  if (side_size > 0 && (!pkt->size || !trk->extradata_size[trk->last_stsd_index])) {
7122  void *newextra = av_memdup(side, side_size);
7123  if (!newextra)
7124  return AVERROR(ENOMEM);
7125  av_free(trk->extradata[trk->last_stsd_index]);
7126  trk->extradata[trk->last_stsd_index] = newextra;
7127  trk->extradata_size[trk->last_stsd_index] = side_size;
7128  }
7129  }
7130 
7131  if (!pkt->size) {
7132  if (trk->start_dts == AV_NOPTS_VALUE && trk->frag_discont) {
7133  trk->start_dts = pkt->dts;
7134  if (pkt->pts != AV_NOPTS_VALUE)
7135  trk->start_cts = pkt->pts - pkt->dts;
7136  else
7137  trk->start_cts = 0;
7138  }
7139 
7140  return 0; /* Discard 0 sized packets */
7141  }
7142 
7143  if (trk->entry && pkt->stream_index < mov->nb_streams)
7144  frag_duration = av_rescale_q(pkt->dts - trk->cluster[0].dts,
7145  s->streams[pkt->stream_index]->time_base,
7146  AV_TIME_BASE_Q);
7147  if ((mov->max_fragment_duration &&
7148  frag_duration >= mov->max_fragment_duration) ||
7149  (mov->max_fragment_size && mov->mdat_size + size >= mov->max_fragment_size) ||
7150  (mov->flags & FF_MOV_FLAG_FRAG_KEYFRAME &&
7151  par->codec_type == AVMEDIA_TYPE_VIDEO &&
7152  trk->entry && pkt->flags & AV_PKT_FLAG_KEY) ||
7154  if (frag_duration >= mov->min_fragment_duration) {
7155  if (trk->entry) {
7156  // Set the duration of this track to line up with the next
7157  // sample in this track. This avoids relying on AVPacket
7158  // duration, but only helps for this particular track, not
7159  // for the other ones that are flushed at the same time.
7160  //
7161  // If we have trk->entry == 0, no fragment will be written
7162  // for this track, and we can't adjust the track end here.
7163  trk->track_duration = pkt->dts - trk->start_dts;
7164  if (pkt->pts != AV_NOPTS_VALUE)
7165  trk->end_pts = pkt->pts;
7166  else
7167  trk->end_pts = pkt->dts;
7168  trk->end_reliable = 1;
7169  }
7171  }
7172  }
7173 
7174  return ff_mov_write_packet(s, pkt);
7175 }
7176 
7178  int stream_index,
7179  int64_t dts) {
7180  MOVMuxContext *mov = s->priv_data;
7181  AVPacket *end = mov->pkt;
7182  uint8_t data[2] = {0};
7183  int ret;
7184 
7185  end->size = sizeof(data);
7186  end->data = data;
7187  end->pts = dts;
7188  end->dts = dts;
7189  end->duration = 0;
7190  end->stream_index = stream_index;
7191 
7192  ret = mov_write_single_packet(s, end);
7193  av_packet_unref(end);
7194 
7195  return ret;
7196 }
7197 
7198 #if CONFIG_IAMFENC
7199 static int mov_build_iamf_packet(AVFormatContext *s, MOVTrack *trk, AVPacket *pkt)
7200 {
7201  uint8_t *data;
7202  int ret;
7203 
7204  if (pkt->stream_index == trk->first_iamf_idx) {
7206  if (ret < 0)
7207  return ret;
7208  }
7209 
7211  s->streams[pkt->stream_index]->id, pkt);
7212  if (ret < 0)
7213  return ret;
7214 
7215  if (pkt->stream_index != trk->last_iamf_idx)
7216  return AVERROR(EAGAIN);
7217 
7218  ret = avio_close_dyn_buf(trk->iamf_buf, &data);
7219  trk->iamf_buf = NULL;
7220  if (!ret) {
7221  if (pkt->size) {
7222  // Either all or none of the packets for a single
7223  // IA Sample may be empty.
7224  av_log(s, AV_LOG_ERROR, "Unexpected packet from "
7225  "stream #%d\n", pkt->stream_index);
7227  }
7228  av_free(data);
7229  return ret;
7230  }
7231 
7232  av_buffer_unref(&pkt->buf);
7233  pkt->buf = av_buffer_create(data, ret, NULL, NULL, 0);
7234  if (!pkt->buf) {
7235  av_free(data);
7236  return AVERROR(ENOMEM);
7237  }
7238  pkt->data = data;
7239  pkt->size = ret;
7241 
7242  return avio_open_dyn_buf(&trk->iamf_buf);
7243 }
7244 #endif
7245 
7247 {
7248  int64_t pos = avio_tell(pb);
7249  const char *scheme_id_uri = "https://aomedia.org/emsg/ID3";
7250  const char *value = "";
7251 
7252  av_assert0(st->time_base.num == 1);
7253 
7254  avio_write_marker(pb,
7257 
7258  avio_wb32(pb, 0); /* size */
7259  ffio_wfourcc(pb, "emsg");
7260  avio_w8(pb, 1); /* version */
7261  avio_wb24(pb, 0);
7262  avio_wb32(pb, st->time_base.den); /* timescale */
7263  avio_wb64(pb, pkt->pts); /* presentation_time */
7264  avio_wb32(pb, 0xFFFFFFFFU); /* event_duration */
7265  avio_wb32(pb, 0); /* id */
7266  /* null terminated UTF8 strings */
7267  avio_write(pb, scheme_id_uri, strlen(scheme_id_uri) + 1);
7268  avio_write(pb, value, strlen(value) + 1);
7269  avio_write(pb, pkt->data, pkt->size);
7270 
7271  return update_size(pb, pos);
7272 }
7273 
7275 {
7276  MOVMuxContext *mov = s->priv_data;
7277  MOVTrack *trk;
7278 
7279  if (!pkt) {
7280  mov_flush_fragment(s, 1);
7281  return 1;
7282  }
7283 
7284  if (s->streams[pkt->stream_index]->codecpar->codec_id == AV_CODEC_ID_TIMED_ID3) {
7285  mov_write_emsg_tag(s->pb, s->streams[pkt->stream_index], pkt);
7286  return 0;
7287  }
7288 
7289  trk = s->streams[pkt->stream_index]->priv_data;
7290 
7291 #if CONFIG_IAMFENC
7292  if (trk->iamf) {
7293  int ret = mov_build_iamf_packet(s, trk, pkt);
7294  if (ret < 0) {
7295  if (ret == AVERROR(EAGAIN))
7296  return 0;
7297  av_log(s, AV_LOG_ERROR, "Error assembling an IAMF packet "
7298  "for stream #%d\n", trk->st->index);
7299  return ret;
7300  }
7301  }
7302 #endif
7303 
7304  if (is_cover_image(trk->st)) {
7305  int ret;
7306 
7307  if (trk->st->nb_frames >= 1) {
7308  if (trk->st->nb_frames == 1)
7309  av_log(s, AV_LOG_WARNING, "Got more than one picture in stream %d,"
7310  " ignoring.\n", pkt->stream_index);
7311  return 0;
7312  }
7313 
7314  if ((ret = av_packet_ref(trk->cover_image, pkt)) < 0)
7315  return ret;
7316 
7317  return 0;
7318  } else {
7319  int i;
7320 
7321  if (!pkt->size)
7322  return mov_write_single_packet(s, pkt); /* Passthrough. */
7323 
7324  /*
7325  * Subtitles require special handling.
7326  *
7327  * 1) For full complaince, every track must have a sample at
7328  * dts == 0, which is rarely true for subtitles. So, as soon
7329  * as we see any packet with dts > 0, write an empty subtitle
7330  * at dts == 0 for any subtitle track with no samples in it.
7331  *
7332  * 2) For each subtitle track, check if the current packet's
7333  * dts is past the duration of the last subtitle sample. If
7334  * so, we now need to write an end sample for that subtitle.
7335  *
7336  * This must be done conditionally to allow for subtitles that
7337  * immediately replace each other, in which case an end sample
7338  * is not needed, and is, in fact, actively harmful.
7339  *
7340  * 3) See mov_write_trailer for how the final end sample is
7341  * handled.
7342  */
7343  for (i = 0; i < mov->nb_tracks; i++) {
7344  MOVTrack *trk = &mov->tracks[i];
7345  int ret;
7346 
7347  if (trk->par->codec_id == AV_CODEC_ID_MOV_TEXT &&
7348  trk->track_duration < pkt->dts &&
7349  (trk->entry == 0 || !trk->last_sample_is_subtitle_end)) {
7351  if (ret < 0) return ret;
7352  trk->last_sample_is_subtitle_end = 1;
7353  }
7354  }
7355 
7356  if (trk->squash_fragment_samples_to_one) {
7357  /*
7358  * If the track has to have its samples squashed into one sample,
7359  * we just take it into the track's queue.
7360  * This will then be utilized as the samples get written in either
7361  * mov_flush_fragment or when the mux is finalized in
7362  * mov_write_trailer.
7363  */
7364  int ret = AVERROR_BUG;
7365 
7366  if (pkt->pts == AV_NOPTS_VALUE) {
7368  "Packets without a valid presentation timestamp are "
7369  "not supported with packet squashing!\n");
7370  return AVERROR(EINVAL);
7371  }
7372 
7373  /* The following will reset pkt and is only allowed to be used
7374  * because we return immediately. afterwards. */
7376  pkt, NULL, 0)) < 0) {
7377  return ret;
7378  }
7379 
7380  return 0;
7381  }
7382 
7383 
7384  if (trk->mode == MODE_MOV && trk->par->codec_type == AVMEDIA_TYPE_VIDEO) {
7385  AVPacket *opkt = pkt;
7386  int reshuffle_ret, ret;
7387  if (trk->is_unaligned_qt_rgb) {
7388  int64_t bpc = trk->par->bits_per_coded_sample != 15 ? trk->par->bits_per_coded_sample : 16;
7389  int expected_stride = ((trk->par->width * bpc + 15) >> 4)*2;
7390  reshuffle_ret = ff_reshuffle_raw_rgb(s, &pkt, trk->par, expected_stride);
7391  if (reshuffle_ret < 0)
7392  return reshuffle_ret;
7393  } else
7394  reshuffle_ret = 0;
7395  if (trk->par->format == AV_PIX_FMT_PAL8 && !trk->pal_done) {
7396  ret = ff_get_packet_palette(s, opkt, reshuffle_ret, trk->palette);
7397  if (ret < 0)
7398  goto fail;
7399  if (ret)
7400  trk->pal_done++;
7401  } else if (trk->par->codec_id == AV_CODEC_ID_RAWVIDEO &&
7402  (trk->par->format == AV_PIX_FMT_GRAY8 ||
7403  trk->par->format == AV_PIX_FMT_MONOBLACK)) {
7405  if (ret < 0)
7406  goto fail;
7407  for (i = 0; i < pkt->size; i++)
7408  pkt->data[i] = ~pkt->data[i];
7409  }
7410  if (reshuffle_ret) {
7412 fail:
7413  if (reshuffle_ret)
7414  av_packet_free(&pkt);
7415  return ret;
7416  }
7417  }
7418 
7419  return mov_write_single_packet(s, pkt);
7420  }
7421 }
7422 
7423 // QuickTime chapters involve an additional text track with the chapter names
7424 // as samples, and a tref pointing from the other tracks to the chapter one.
7425 static int mov_create_chapter_track(AVFormatContext *s, int tracknum)
7426 {
7427  static const uint8_t stub_header[] = {
7428  // TextSampleEntry
7429  0x00, 0x00, 0x00, 0x01, // displayFlags
7430  0x00, 0x00, // horizontal + vertical justification
7431  0x00, 0x00, 0x00, 0x00, // bgColourRed/Green/Blue/Alpha
7432  // BoxRecord
7433  0x00, 0x00, 0x00, 0x00, // defTextBoxTop/Left
7434  0x00, 0x00, 0x00, 0x00, // defTextBoxBottom/Right
7435  // StyleRecord
7436  0x00, 0x00, 0x00, 0x00, // startChar + endChar
7437  0x00, 0x01, // fontID
7438  0x00, 0x00, // fontStyleFlags + fontSize
7439  0x00, 0x00, 0x00, 0x00, // fgColourRed/Green/Blue/Alpha
7440  // FontTableBox
7441  0x00, 0x00, 0x00, 0x0D, // box size
7442  'f', 't', 'a', 'b', // box atom name
7443  0x00, 0x01, // entry count
7444  // FontRecord
7445  0x00, 0x01, // font ID
7446  0x00, // font name length
7447  };
7448  MOVMuxContext *mov = s->priv_data;
7449  MOVTrack *track = &mov->tracks[tracknum];
7450  AVPacket *pkt = mov->pkt;
7451  int i, len;
7452  int ret;
7453 
7454  track->mode = mov->mode;
7455  track->tag = MKTAG('t','e','x','t');
7456  track->timescale = mov->movie_timescale;
7457  track->par = avcodec_parameters_alloc();
7458  if (!track->par)
7459  return AVERROR(ENOMEM);
7461  ret = ff_alloc_extradata(track->par, sizeof(stub_header));
7462  if (ret < 0)
7463  return ret;
7464  memcpy(track->par->extradata, stub_header, sizeof(stub_header));
7465 
7466  track->extradata[0] = av_memdup(stub_header, sizeof(stub_header));
7467  if (!track->extradata[0])
7468  return AVERROR(ENOMEM);
7469  track->extradata_size[0] = sizeof(stub_header);
7470 
7471  pkt->stream_index = tracknum;
7473 
7474  for (i = 0; i < s->nb_chapters; i++) {
7475  AVChapter *c = s->chapters[i];
7476  AVDictionaryEntry *t;
7477 
7478  int64_t end = av_rescale_q(c->end, c->time_base, (AVRational){1,mov->movie_timescale});
7479  pkt->pts = pkt->dts = av_rescale_q(c->start, c->time_base, (AVRational){1,mov->movie_timescale});
7480  pkt->duration = end - pkt->dts;
7481 
7482  if ((t = av_dict_get(c->metadata, "title", NULL, 0))) {
7483  static const char encd[12] = {
7484  0x00, 0x00, 0x00, 0x0C,
7485  'e', 'n', 'c', 'd',
7486  0x00, 0x00, 0x01, 0x00 };
7487  len = strlen(t->value);
7488  pkt->size = len + 2 + 12;
7489  pkt->data = av_malloc(pkt->size);
7490  if (!pkt->data) {
7492  return AVERROR(ENOMEM);
7493  }
7494  AV_WB16(pkt->data, len);
7495  memcpy(pkt->data + 2, t->value, len);
7496  memcpy(pkt->data + len + 2, encd, sizeof(encd));
7498  av_freep(&pkt->data);
7499  }
7500  }
7501 
7502  av_packet_unref(mov->pkt);
7503 
7504  return 0;
7505 }
7506 
7507 
7508 static int mov_check_timecode_track(AVFormatContext *s, AVTimecode *tc, AVStream *src_st, const char *tcstr)
7509 {
7510  int ret;
7511 
7512  /* compute the frame number */
7513  ret = av_timecode_init_from_string(tc, src_st->avg_frame_rate, tcstr, s);
7514  return ret;
7515 }
7516 
7517 static int mov_create_timecode_track(AVFormatContext *s, int index, int src_index, AVTimecode tc)
7518 {
7519  MOVMuxContext *mov = s->priv_data;
7520  MOVTrack *track = &mov->tracks[index];
7521  AVStream *src_st = mov->tracks[src_index].st;
7522  uint8_t data[4];
7523  AVPacket *pkt = mov->pkt;
7524  AVRational rate = src_st->avg_frame_rate;
7525  int ret;
7526 
7527  /* tmcd track based on video stream */
7528  track->mode = mov->mode;
7529  track->tag = MKTAG('t','m','c','d');
7530  track->src_track = src_index;
7531  track->timescale = mov->tracks[src_index].timescale;
7534 
7535  /* set st to src_st for metadata access*/
7536  track->st = src_st;
7537 
7538  /* encode context: tmcd data stream */
7539  track->par = avcodec_parameters_alloc();
7540  if (!track->par)
7541  return AVERROR(ENOMEM);
7542  track->par->codec_type = AVMEDIA_TYPE_DATA;
7543  track->par->codec_tag = track->tag;
7544  track->st->avg_frame_rate = rate;
7545 
7546  /* the tmcd track just contains one packet with the frame number */
7547  pkt->data = data;
7548  pkt->stream_index = index;
7550  pkt->pts = pkt->dts = av_rescale_q(tc.start, av_inv_q(rate), (AVRational){1,mov->movie_timescale});
7551  pkt->size = 4;
7552  AV_WB32(pkt->data, tc.start);
7555  return ret;
7556 }
7557 
7558 /*
7559  * st->disposition controls the "enabled" flag in the tkhd tag.
7560  * QuickTime will not play a track if it is not enabled. So make sure
7561  * that one track of each type (audio, video, subtitle) is enabled.
7562  *
7563  * Subtitles are special. For audio and video, setting "enabled" also
7564  * makes the track "default" (i.e. it is rendered when played). For
7565  * subtitles, an "enabled" subtitle is not rendered by default, but
7566  * if no subtitle is enabled, the subtitle menu in QuickTime will be
7567  * empty!
7568  */
7570 {
7571  MOVMuxContext *mov = s->priv_data;
7572  int i;
7573  int enabled[AVMEDIA_TYPE_NB];
7574  int first[AVMEDIA_TYPE_NB];
7575 
7576  for (i = 0; i < AVMEDIA_TYPE_NB; i++) {
7577  enabled[i] = 0;
7578  first[i] = -1;
7579  }
7580 
7581  for (i = 0; i < mov->nb_streams; i++) {
7582  AVStream *st = mov->tracks[i].st;
7583 
7586  is_cover_image(st))
7587  continue;
7588 
7589  if (first[st->codecpar->codec_type] < 0)
7590  first[st->codecpar->codec_type] = i;
7591  if (st->disposition & AV_DISPOSITION_DEFAULT) {
7592  mov->tracks[i].flags |= MOV_TRACK_ENABLED;
7593  enabled[st->codecpar->codec_type]++;
7594  }
7595  }
7596 
7597  for (i = 0; i < AVMEDIA_TYPE_NB; i++) {
7598  switch (i) {
7599  case AVMEDIA_TYPE_VIDEO:
7600  case AVMEDIA_TYPE_AUDIO:
7601  case AVMEDIA_TYPE_SUBTITLE:
7602  if (enabled[i] > 1)
7603  mov->per_stream_grouping = 1;
7604  if (!enabled[i] && first[i] >= 0)
7605  mov->tracks[first[i]].flags |= MOV_TRACK_ENABLED;
7606  break;
7607  }
7608  }
7609 }
7610 
7612 {
7613  MOVMuxContext *mov = s->priv_data;
7614 
7615  for (int i = 0; i < s->nb_streams; i++)
7616  s->streams[i]->priv_data = NULL;
7617 
7618  if (!mov->tracks)
7619  return;
7620 
7621  if (mov->chapter_track) {
7623  }
7624 
7625  for (int i = 0; i < mov->nb_tracks; i++) {
7626  MOVTrack *const track = &mov->tracks[i];
7627 
7628  if (track->tag == MKTAG('r','t','p',' '))
7629  ff_mov_close_hinting(track);
7630  else if (track->tag == MKTAG('t','m','c','d') && mov->nb_meta_tmcd)
7631  av_freep(&track->par);
7632  av_freep(&track->cluster);
7633  av_freep(&track->cluster_written);
7634  av_freep(&track->frag_info);
7635  av_packet_free(&track->cover_image);
7636 
7637  if (track->eac3_priv) {
7638  struct eac3_info *info = track->eac3_priv;
7639  av_packet_free(&info->pkt);
7640  av_freep(&track->eac3_priv);
7641  }
7642  for (int j = 0; j < track->stsd_count; j++)
7643  av_freep(&track->extradata[j]);
7644  av_freep(&track->extradata);
7645  av_freep(&track->extradata_size);
7646 
7647  ff_mov_cenc_free(&track->cenc);
7648  ffio_free_dyn_buf(&track->mdat_buf);
7649 
7650 #if CONFIG_IAMFENC
7651  ffio_free_dyn_buf(&track->iamf_buf);
7652  if (track->iamf)
7653  ff_iamf_uninit_context(track->iamf);
7654  av_freep(&track->iamf);
7655 #endif
7656  ff_isom_close_apvc(&track->apv);
7657 
7659  }
7660 
7661  av_freep(&mov->tracks);
7662  ffio_free_dyn_buf(&mov->mdat_buf);
7663 }
7664 
7665 static uint32_t rgb_to_yuv(uint32_t rgb)
7666 {
7667  uint8_t r, g, b;
7668  int y, cb, cr;
7669 
7670  r = (rgb >> 16) & 0xFF;
7671  g = (rgb >> 8) & 0xFF;
7672  b = (rgb ) & 0xFF;
7673 
7674  y = av_clip_uint8(( 16000 + 257 * r + 504 * g + 98 * b)/1000);
7675  cb = av_clip_uint8((128000 - 148 * r - 291 * g + 439 * b)/1000);
7676  cr = av_clip_uint8((128000 + 439 * r - 368 * g - 71 * b)/1000);
7677 
7678  return (y << 16) | (cr << 8) | cb;
7679 }
7680 
7682  AVStream *st)
7683 {
7684  int i, width = 720, height = 480;
7685  int have_palette = 0, have_size = 0;
7686  uint32_t palette[16];
7687  char *cur = track->extradata[track->last_stsd_index];
7688 
7689  while (cur && *cur) {
7690  if (strncmp("palette:", cur, 8) == 0) {
7691  int i, count;
7692  count = sscanf(cur + 8,
7693  "%06"PRIx32", %06"PRIx32", %06"PRIx32", %06"PRIx32", "
7694  "%06"PRIx32", %06"PRIx32", %06"PRIx32", %06"PRIx32", "
7695  "%06"PRIx32", %06"PRIx32", %06"PRIx32", %06"PRIx32", "
7696  "%06"PRIx32", %06"PRIx32", %06"PRIx32", %06"PRIx32"",
7697  &palette[ 0], &palette[ 1], &palette[ 2], &palette[ 3],
7698  &palette[ 4], &palette[ 5], &palette[ 6], &palette[ 7],
7699  &palette[ 8], &palette[ 9], &palette[10], &palette[11],
7700  &palette[12], &palette[13], &palette[14], &palette[15]);
7701 
7702  for (i = 0; i < count; i++) {
7703  palette[i] = rgb_to_yuv(palette[i]);
7704  }
7705  have_palette = 1;
7706  } else if (!strncmp("size:", cur, 5)) {
7707  sscanf(cur + 5, "%dx%d", &width, &height);
7708  have_size = 1;
7709  }
7710  if (have_palette && have_size)
7711  break;
7712  cur += strcspn(cur, "\n\r");
7713  cur += strspn(cur, "\n\r");
7714  }
7715  if (have_palette) {
7717  if (!track->extradata[track->last_stsd_index])
7718  return AVERROR(ENOMEM);
7719  for (i = 0; i < 16; i++) {
7720  AV_WB32(track->extradata[track->last_stsd_index] + i * 4, palette[i]);
7721  }
7722  memset(track->extradata[track->last_stsd_index] + 16*4, 0, AV_INPUT_BUFFER_PADDING_SIZE);
7723  track->extradata_size[track->last_stsd_index] = 16 * 4;
7724  }
7725  st->codecpar->width = width;
7726  st->codecpar->height = track->height = height;
7727 
7728  return 0;
7729 }
7730 
7731 #if CONFIG_IAMFENC
7732 static int mov_init_iamf_track(AVFormatContext *s)
7733 {
7734  MOVMuxContext *mov = s->priv_data;
7735  MOVTrack *track;
7736  IAMFContext *iamf;
7737  int first_iamf_idx = INT_MAX, last_iamf_idx = 0;
7738  int nb_audio_elements = 0, nb_mix_presentations = 0;
7739  int ret;
7740 
7741  for (int i = 0; i < s->nb_stream_groups; i++) {
7742  const AVStreamGroup *stg = s->stream_groups[i];
7743 
7745  nb_audio_elements++;
7747  nb_mix_presentations++;
7748  }
7749 
7750  if (!nb_audio_elements && !nb_mix_presentations)
7751  return 0;
7752 
7753  if (nb_audio_elements < 1 || nb_audio_elements > 2 || nb_mix_presentations < 1) {
7754  av_log(s, AV_LOG_ERROR, "There must be >= 1 and <= 2 IAMF_AUDIO_ELEMENT and at least "
7755  "one IAMF_MIX_PRESENTATION stream groups to write a IMAF track\n");
7756  return AVERROR(EINVAL);
7757  }
7758 
7759  iamf = av_mallocz(sizeof(*iamf));
7760  if (!iamf)
7761  return AVERROR(ENOMEM);
7762 
7763 
7764  for (int i = 0; i < s->nb_stream_groups; i++) {
7765  const AVStreamGroup *stg = s->stream_groups[i];
7766  switch(stg->type) {
7768  for (int j = 0; j < stg->nb_streams; j++) {
7769  first_iamf_idx = FFMIN(stg->streams[j]->index, first_iamf_idx);
7770  last_iamf_idx = FFMAX(stg->streams[j]->index, last_iamf_idx);
7771  }
7772 
7773  ret = ff_iamf_add_audio_element(iamf, stg, s);
7774  break;
7776  ret = ff_iamf_add_mix_presentation(iamf, stg, s);
7777  break;
7778  default:
7779  av_assert0(0);
7780  }
7781  if (ret < 0)
7782  return ret;
7783  }
7784 
7785  track = &mov->tracks[first_iamf_idx];
7786  track->iamf = iamf;
7787  track->first_iamf_idx = first_iamf_idx;
7788  track->last_iamf_idx = last_iamf_idx;
7789  track->tag = MKTAG('i','a','m','f');
7790 
7791  for (int i = 0; i < s->nb_stream_groups; i++) {
7792  AVStreamGroup *stg = s->stream_groups[i];
7794  continue;
7795  for (int j = 0; j < stg->nb_streams; j++)
7796  stg->streams[j]->priv_data = track;
7797  }
7798 
7799  ret = avio_open_dyn_buf(&track->iamf_buf);
7800  if (ret < 0)
7801  return ret;
7802 
7803  return 0;
7804 }
7805 #endif
7806 
7808 {
7809  MOVMuxContext *mov = s->priv_data;
7810  int has_iamf = 0;
7811  int i, ret;
7812 
7813  mov->fc = s;
7814  mov->pkt = ffformatcontext(s)->pkt;
7815 
7816  /* Default mode == MP4 */
7817  mov->mode = MODE_MP4;
7818 
7819 #define IS_MODE(muxer, config) (CONFIG_ ## config ## _MUXER && !strcmp(#muxer, s->oformat->name))
7820  if (IS_MODE(3gp, TGP)) mov->mode = MODE_3GP;
7821  else if (IS_MODE(3g2, TG2)) mov->mode = MODE_3GP|MODE_3G2;
7822  else if (IS_MODE(mov, MOV)) mov->mode = MODE_MOV;
7823  else if (IS_MODE(psp, PSP)) mov->mode = MODE_PSP;
7824  else if (IS_MODE(ipod, IPOD)) mov->mode = MODE_IPOD;
7825  else if (IS_MODE(ismv, ISMV)) mov->mode = MODE_ISM;
7826  else if (IS_MODE(f4v, F4V)) mov->mode = MODE_F4V;
7827  else if (IS_MODE(avif, AVIF)) mov->mode = MODE_AVIF;
7828 #undef IS_MODE
7829 
7830  if (mov->flags & FF_MOV_FLAG_DELAY_MOOV)
7831  mov->flags |= FF_MOV_FLAG_EMPTY_MOOV;
7832 
7833  if (mov->mode == MODE_AVIF)
7834  mov->flags |= FF_MOV_FLAG_DELAY_MOOV;
7835 
7836  /* Set the FRAGMENT flag if any of the fragmentation methods are
7837  * enabled. */
7838  if (mov->max_fragment_duration || mov->max_fragment_size ||
7839  mov->flags & (FF_MOV_FLAG_EMPTY_MOOV |
7843  mov->flags |= FF_MOV_FLAG_FRAGMENT;
7844 
7845  if (mov->flags & FF_MOV_FLAG_HYBRID_FRAGMENTED &&
7846  mov->flags & FF_MOV_FLAG_FASTSTART) {
7847  av_log(s, AV_LOG_ERROR, "Setting both hybrid_fragmented and faststart is not supported.\n");
7848  return AVERROR(EINVAL);
7849  }
7850 
7851  /* Set other implicit flags immediately */
7853  mov->flags |= FF_MOV_FLAG_FRAGMENT;
7854 
7855  if (mov->mode == MODE_ISM)
7858  if (mov->flags & FF_MOV_FLAG_DASH)
7861  if (mov->flags & FF_MOV_FLAG_CMAF)
7864 
7865  if (mov->flags & FF_MOV_FLAG_EMPTY_MOOV && s->flags & AVFMT_FLAG_AUTO_BSF) {
7866  av_log(s, AV_LOG_VERBOSE, "Empty MOOV enabled; disabling automatic bitstream filtering\n");
7867  s->flags &= ~AVFMT_FLAG_AUTO_BSF;
7868  }
7869 
7871  av_log(s, AV_LOG_WARNING, "Global SIDX enabled; Ignoring skip_sidx option\n");
7872  mov->flags &= ~FF_MOV_FLAG_SKIP_SIDX;
7873  }
7874 
7875  if (mov->flags & FF_MOV_FLAG_FASTSTART) {
7876  mov->reserved_moov_size = -1;
7877  }
7878 
7879  if (mov->use_editlist < 0) {
7880  mov->use_editlist = 1;
7881  if (mov->flags & FF_MOV_FLAG_FRAGMENT &&
7882  !(mov->flags & FF_MOV_FLAG_DELAY_MOOV)) {
7883  // If we can avoid needing an edit list by shifting the
7884  // tracks, prefer that over (trying to) write edit lists
7885  // in fragmented output.
7886  if (s->avoid_negative_ts == AVFMT_AVOID_NEG_TS_AUTO ||
7887  s->avoid_negative_ts == AVFMT_AVOID_NEG_TS_MAKE_ZERO)
7888  mov->use_editlist = 0;
7889  }
7890  }
7891  if (mov->flags & FF_MOV_FLAG_EMPTY_MOOV &&
7892  !(mov->flags & FF_MOV_FLAG_DELAY_MOOV) && mov->use_editlist)
7893  av_log(s, AV_LOG_WARNING, "No meaningful edit list will be written when using empty_moov without delay_moov\n");
7894 
7895  if (!mov->use_editlist && s->avoid_negative_ts == AVFMT_AVOID_NEG_TS_AUTO &&
7897  s->avoid_negative_ts = AVFMT_AVOID_NEG_TS_MAKE_ZERO;
7898 
7899  /* Clear the omit_tfhd_offset flag if default_base_moof is set;
7900  * if the latter is set that's enough and omit_tfhd_offset doesn't
7901  * add anything extra on top of that. */
7902  if (mov->flags & FF_MOV_FLAG_OMIT_TFHD_OFFSET &&
7905 
7906  if (mov->frag_interleave &&
7909  "Sample interleaving in fragments is mutually exclusive with "
7910  "omit_tfhd_offset and separate_moof\n");
7911  return AVERROR(EINVAL);
7912  }
7913 
7914  /* Non-seekable output is ok if using fragmentation. If ism_lookahead
7915  * is enabled, we don't support non-seekable output at all. */
7916  if (!(s->pb->seekable & AVIO_SEEKABLE_NORMAL) &&
7917  (!(mov->flags & FF_MOV_FLAG_FRAGMENT) || mov->ism_lookahead ||
7918  mov->mode == MODE_AVIF)) {
7919  av_log(s, AV_LOG_ERROR, "muxer does not support non seekable output\n");
7920  return AVERROR(EINVAL);
7921  }
7922 
7923  /* AVIF output must have at most two video streams (one for YUV and one for
7924  * alpha). */
7925  if (mov->mode == MODE_AVIF) {
7926  if (s->nb_streams > 2) {
7927  av_log(s, AV_LOG_ERROR, "AVIF output requires exactly one or two streams\n");
7928  return AVERROR(EINVAL);
7929  }
7930  if (s->streams[0]->codecpar->codec_type != AVMEDIA_TYPE_VIDEO &&
7931  (s->nb_streams > 1 && s->streams[1]->codecpar->codec_type != AVMEDIA_TYPE_VIDEO)) {
7932  av_log(s, AV_LOG_ERROR, "AVIF output supports only video streams\n");
7933  return AVERROR(EINVAL);
7934  }
7935  if (s->nb_streams > 1) {
7936  const AVPixFmtDescriptor *pixdesc =
7937  av_pix_fmt_desc_get(s->streams[1]->codecpar->format);
7938  if (pixdesc->nb_components != 1) {
7939  av_log(s, AV_LOG_ERROR, "Second stream for AVIF (alpha) output must have exactly one plane\n");
7940  return AVERROR(EINVAL);
7941  }
7942  }
7943  s->streams[0]->disposition |= AV_DISPOSITION_DEFAULT;
7944  }
7945 
7946 #if CONFIG_IAMFENC
7947  for (i = 0; i < s->nb_stream_groups; i++) {
7948  AVStreamGroup *stg = s->stream_groups[i];
7949 
7951  continue;
7952 
7953  for (int j = 0; j < stg->nb_streams; j++) {
7954  AVStream *st = stg->streams[j];
7955 
7956  if (st->priv_data) {
7957  av_log(s, AV_LOG_ERROR, "Stream %d is present in more than one Stream Group of type "
7958  "IAMF Audio Element\n", j);
7959  return AVERROR(EINVAL);
7960  }
7961  st->priv_data = st;
7962  }
7963  has_iamf = 1;
7964 
7965  if (!mov->nb_tracks) // We support one track for the entire IAMF structure
7966  mov->nb_tracks++;
7967  }
7968 #endif
7969 
7970  for (i = 0; i < s->nb_streams; i++) {
7971  AVStream *st = s->streams[i];
7972  if (st->priv_data)
7973  continue;
7974  // Don't produce a track in the output file for timed ID3 streams.
7975  if (st->codecpar->codec_id == AV_CODEC_ID_TIMED_ID3) {
7976  // Leave priv_data set to NULL for these AVStreams that don't
7977  // have a corresponding track.
7978  continue;
7979  }
7980  st->priv_data = st;
7981  mov->nb_tracks++;
7982  }
7983 
7984  mov->nb_streams = mov->nb_tracks;
7985 
7986  if (mov->mode & (MODE_MP4|MODE_MOV|MODE_IPOD) && s->nb_chapters)
7987  mov->chapter_track = mov->nb_tracks++;
7988 
7989  if (mov->flags & FF_MOV_FLAG_RTP_HINT) {
7990  for (i = 0; i < s->nb_streams; i++)
7991  if (rtp_hinting_needed(s->streams[i]))
7992  mov->nb_tracks++;
7993  }
7994 
7995  if (mov->write_btrt < 0) {
7996  mov->write_btrt = mov->mode == MODE_MP4;
7997  }
7998 
7999  if ( mov->write_tmcd == -1 && (mov->mode == MODE_MOV || mov->mode == MODE_MP4)
8000  || mov->write_tmcd == 1) {
8001  AVDictionaryEntry *global_tcr = av_dict_get(s->metadata, "timecode",
8002  NULL, 0);
8003 
8004  /* +1 tmcd track for each video stream with a timecode */
8005  for (i = 0; i < s->nb_streams; i++) {
8006  AVStream *st = s->streams[i];
8007  AVDictionaryEntry *t = global_tcr;
8008  if (st->codecpar->codec_type == AVMEDIA_TYPE_VIDEO &&
8009  (t || (t=av_dict_get(st->metadata, "timecode", NULL, 0)))) {
8010  AVTimecode tc;
8011  ret = mov_check_timecode_track(s, &tc, st, t->value);
8012  if (ret >= 0)
8013  mov->nb_meta_tmcd++;
8014  }
8015  }
8016 
8017  /* check if there is already a tmcd track to remux */
8018  if (mov->nb_meta_tmcd) {
8019  for (i = 0; i < s->nb_streams; i++) {
8020  AVStream *st = s->streams[i];
8021  if (st->codecpar->codec_tag == MKTAG('t','m','c','d')) {
8022  av_log(s, AV_LOG_WARNING, "You requested a copy of the original timecode track "
8023  "so timecode metadata are now ignored\n");
8024  mov->nb_meta_tmcd = 0;
8025  }
8026  }
8027  }
8028 
8029  mov->nb_tracks += mov->nb_meta_tmcd;
8030  }
8031 
8032  // Reserve an extra stream for chapters for the case where chapters
8033  // are written in the trailer
8034  mov->tracks = av_calloc(mov->nb_tracks + 1, sizeof(*mov->tracks));
8035  if (!mov->tracks)
8036  return AVERROR(ENOMEM);
8037 
8038  for (i = 0; i < mov->nb_tracks; i++) {
8039  MOVTrack *track = &mov->tracks[i];
8040 
8041  track->stsd_count = 1;
8042  track->extradata = av_calloc(track->stsd_count, sizeof(*track->extradata));
8043  track->extradata_size = av_calloc(track->stsd_count, sizeof(*track->extradata_size));
8044  if (!track->extradata || !track->extradata_size)
8045  return AVERROR(ENOMEM);
8046  }
8047 
8048  if (mov->encryption_scheme_str != NULL && strcmp(mov->encryption_scheme_str, "none") != 0) {
8049  if (strcmp(mov->encryption_scheme_str, "cenc-aes-ctr") == 0) {
8051 
8052  if (mov->encryption_key_len != AES_CTR_KEY_SIZE) {
8053  av_log(s, AV_LOG_ERROR, "Invalid encryption key len %d expected %d\n",
8055  return AVERROR(EINVAL);
8056  }
8057 
8058  if (mov->encryption_kid_len != CENC_KID_SIZE) {
8059  av_log(s, AV_LOG_ERROR, "Invalid encryption kid len %d expected %d\n",
8061  return AVERROR(EINVAL);
8062  }
8063  } else {
8064  av_log(s, AV_LOG_ERROR, "unsupported encryption scheme %s\n",
8065  mov->encryption_scheme_str);
8066  return AVERROR(EINVAL);
8067  }
8068  }
8069 
8070 #if CONFIG_IAMFENC
8071  ret = mov_init_iamf_track(s);
8072  if (ret < 0)
8073  return ret;
8074 #endif
8075 
8076  for (int j = 0, i = 0; j < s->nb_streams; j++) {
8077  AVStream *st = s->streams[j];
8078 
8079  if (st != st->priv_data) {
8080  if (has_iamf)
8081  i += has_iamf--;
8082  continue;
8083  }
8084  st->priv_data = &mov->tracks[i++];
8085  }
8086 
8087  for (i = 0; i < s->nb_streams; i++) {
8088  AVStream *st= s->streams[i];
8089  MOVTrack *track = st->priv_data;
8090  AVDictionaryEntry *lang = av_dict_get(st->metadata, "language", NULL,0);
8091 
8092  if (!track)
8093  continue;
8094 
8095  if (!track->st) {
8096  track->st = st;
8097  track->par = st->codecpar;
8098  }
8099  track->language = ff_mov_iso639_to_lang(lang?lang->value:"und", mov->mode!=MODE_MOV);
8100  if (track->language < 0)
8101  track->language = 32767; // Unspecified Macintosh language code
8102  track->mode = mov->mode;
8103  if (!track->tag)
8104  track->tag = mov_find_codec_tag(s, track);
8105  if (!track->tag) {
8106  av_log(s, AV_LOG_ERROR, "Could not find tag for codec %s in stream #%d, "
8107  "codec not currently supported in container\n",
8109  return AVERROR(EINVAL);
8110  }
8111  /* If hinting of this track is enabled by a later hint track,
8112  * this is updated. */
8113  track->hint_track = -1;
8114  track->start_dts = AV_NOPTS_VALUE;
8115  track->start_cts = AV_NOPTS_VALUE;
8116  track->end_pts = AV_NOPTS_VALUE;
8117  track->dts_shift = AV_NOPTS_VALUE;
8118  if (st->codecpar->codec_type == AVMEDIA_TYPE_VIDEO) {
8119  if (track->tag == MKTAG('m','x','3','p') || track->tag == MKTAG('m','x','3','n') ||
8120  track->tag == MKTAG('m','x','4','p') || track->tag == MKTAG('m','x','4','n') ||
8121  track->tag == MKTAG('m','x','5','p') || track->tag == MKTAG('m','x','5','n')) {
8122  if (st->codecpar->width != 720 || (st->codecpar->height != 608 && st->codecpar->height != 512)) {
8123  av_log(s, AV_LOG_ERROR, "D-10/IMX must use 720x608 or 720x512 video resolution\n");
8124  return AVERROR(EINVAL);
8125  }
8126  track->height = track->tag >> 24 == 'n' ? 486 : 576;
8127  }
8128  if (mov->video_track_timescale) {
8129  track->timescale = mov->video_track_timescale;
8130  if (mov->mode == MODE_ISM && mov->video_track_timescale != 10000000)
8131  av_log(s, AV_LOG_WARNING, "Warning: some tools, like mp4split, assume a timescale of 10000000 for ISMV.\n");
8132  } else {
8133  track->timescale = st->time_base.den;
8134  while(track->timescale < 10000)
8135  track->timescale *= 2;
8136  }
8137  if (st->codecpar->width > 65535 || st->codecpar->height > 65535) {
8138  av_log(s, AV_LOG_ERROR, "Resolution %dx%d too large for mov/mp4\n", st->codecpar->width, st->codecpar->height);
8139  return AVERROR(EINVAL);
8140  }
8141  if (track->mode == MODE_MOV && track->timescale > 100000)
8143  "WARNING codec timebase is very high. If duration is too long,\n"
8144  "file may not be playable by quicktime. Specify a shorter timebase\n"
8145  "or choose different container.\n");
8146  if (track->mode == MODE_MOV &&
8147  track->par->codec_id == AV_CODEC_ID_RAWVIDEO &&
8148  track->tag == MKTAG('r','a','w',' ')) {
8149  enum AVPixelFormat pix_fmt = track->par->format;
8150  if (pix_fmt == AV_PIX_FMT_NONE && track->par->bits_per_coded_sample == 1)
8152  track->is_unaligned_qt_rgb =
8155  pix_fmt == AV_PIX_FMT_PAL8 ||
8159  }
8160  if (track->par->codec_id == AV_CODEC_ID_VP9 && track->mode != MODE_MP4) {
8161  av_log(s, AV_LOG_ERROR, "%s only supported in MP4.\n", avcodec_get_name(track->par->codec_id));
8162  return AVERROR(EINVAL);
8163  } else if (track->par->codec_id == AV_CODEC_ID_AV1 &&
8164  track->mode != MODE_MP4 && track->mode != MODE_AVIF) {
8165  av_log(s, AV_LOG_ERROR, "%s only supported in MP4 and AVIF.\n", avcodec_get_name(track->par->codec_id));
8166  return AVERROR(EINVAL);
8167  } else if (track->par->codec_id == AV_CODEC_ID_VP8) {
8168  /* altref frames handling is not defined in the spec as of version v1.0,
8169  * so just forbid muxing VP8 streams altogether until a new version does */
8170  av_log(s, AV_LOG_ERROR, "VP8 muxing is currently not supported.\n");
8171  return AVERROR_PATCHWELCOME;
8172  } else if (track->par->codec_id == AV_CODEC_ID_APV) {
8173  ret = ff_isom_init_apvc(&track->apv, s);
8174  if (ret < 0)
8175  return ret;
8176  }
8177  if (is_cover_image(st)) {
8178  track->cover_image = av_packet_alloc();
8179  if (!track->cover_image)
8180  return AVERROR(ENOMEM);
8181  }
8182  } else if (st->codecpar->codec_type == AVMEDIA_TYPE_AUDIO) {
8183  track->timescale = st->codecpar->sample_rate;
8185  av_log(s, AV_LOG_WARNING, "track %d: codec frame size is not set\n", i);
8186  track->audio_vbr = 1;
8187  }else if (st->codecpar->codec_id == AV_CODEC_ID_ADPCM_MS ||
8190  if (!st->codecpar->block_align) {
8191  av_log(s, AV_LOG_ERROR, "track %d: codec block align is not set for adpcm\n", i);
8192  return AVERROR(EINVAL);
8193  }
8194  track->sample_size = st->codecpar->block_align;
8195  }else if (st->codecpar->frame_size > 1){ /* assume compressed audio */
8196  track->audio_vbr = 1;
8197  }else{
8198  track->sample_size = (av_get_bits_per_sample(st->codecpar->codec_id) >> 3) *
8200  }
8201  if (st->codecpar->codec_id == AV_CODEC_ID_ILBC ||
8203  track->audio_vbr = 1;
8204  }
8205  if (track->mode != MODE_MOV &&
8206  track->par->codec_id == AV_CODEC_ID_MP3 && track->timescale < 16000) {
8207  if (s->strict_std_compliance >= FF_COMPLIANCE_NORMAL) {
8208  av_log(s, AV_LOG_ERROR, "track %d: muxing mp3 at %dhz is not standard, to mux anyway set strict to -1\n",
8209  i, track->par->sample_rate);
8210  return AVERROR(EINVAL);
8211  } else {
8212  av_log(s, AV_LOG_WARNING, "track %d: muxing mp3 at %dhz is not standard in MP4\n",
8213  i, track->par->sample_rate);
8214  }
8215  }
8216  if (track->par->codec_id == AV_CODEC_ID_FLAC ||
8217  track->par->codec_id == AV_CODEC_ID_TRUEHD ||
8218  track->par->codec_id == AV_CODEC_ID_OPUS) {
8219  if (track->mode != MODE_MP4) {
8220  av_log(s, AV_LOG_ERROR, "%s only supported in MP4.\n", avcodec_get_name(track->par->codec_id));
8221  return AVERROR(EINVAL);
8222  }
8223  if (track->par->codec_id == AV_CODEC_ID_TRUEHD &&
8224  s->strict_std_compliance > FF_COMPLIANCE_EXPERIMENTAL) {
8226  "%s in MP4 support is experimental, add "
8227  "'-strict %d' if you want to use it.\n",
8229  return AVERROR_EXPERIMENTAL;
8230  }
8231  }
8232  } else if (st->codecpar->codec_type == AVMEDIA_TYPE_SUBTITLE) {
8233  track->timescale = st->time_base.den;
8234 
8235  if (track->par->codec_id == AV_CODEC_ID_TTML) {
8236  /* 14496-30 requires us to use a single sample per fragment
8237  for TTML, for which we define a per-track flag.
8238 
8239  We set the flag in case we are receiving TTML paragraphs
8240  from the input, in other words in case we are not doing
8241  stream copy. */
8244 
8245  if (mov->flags & FF_MOV_FLAG_FRAGMENT &&
8248  "Fragmentation is not currently supported for "
8249  "TTML in MP4/ISMV (track synchronization between "
8250  "subtitles and other media is not yet implemented)!\n");
8251  return AVERROR_PATCHWELCOME;
8252  }
8253 
8254  if (track->mode != MODE_ISM &&
8255  track->par->codec_tag == MOV_ISMV_TTML_TAG &&
8256  s->strict_std_compliance > FF_COMPLIANCE_UNOFFICIAL) {
8258  "ISMV style TTML support with the 'dfxp' tag in "
8259  "non-ISMV formats is not officially supported. Add "
8260  "'-strict unofficial' if you want to use it.\n");
8261  return AVERROR_EXPERIMENTAL;
8262  }
8263  }
8264  } else if (st->codecpar->codec_type == AVMEDIA_TYPE_DATA) {
8265  track->timescale = st->time_base.den;
8266  } else {
8267  track->timescale = mov->movie_timescale;
8268  }
8269  if (!track->height)
8270  track->height = st->codecpar->height;
8271  /* The Protected Interoperable File Format (PIFF) standard, used by ISMV recommends but
8272  doesn't mandate a track timescale of 10,000,000. The muxer allows a custom timescale
8273  for video tracks, so if user-set, it isn't overwritten */
8274  if (mov->mode == MODE_ISM &&
8277  track->timescale = 10000000;
8278  }
8279 
8280  avpriv_set_pts_info(st, 64, 1, track->timescale);
8281 
8283  ret = ff_mov_cenc_init(&track->cenc, mov->encryption_key,
8284  (track->par->codec_id == AV_CODEC_ID_H264 || track->par->codec_id == AV_CODEC_ID_HEVC ||
8285  track->par->codec_id == AV_CODEC_ID_VVC || track->par->codec_id == AV_CODEC_ID_AV1),
8286  track->par->codec_id, s->flags & AVFMT_FLAG_BITEXACT);
8287  if (ret)
8288  return ret;
8289  }
8290  }
8291 
8292  enable_tracks(s);
8293  return 0;
8294 }
8295 
8297 {
8298  AVIOContext *pb = s->pb;
8299  MOVMuxContext *mov = s->priv_data;
8300  int ret, hint_track = 0, tmcd_track = 0, nb_tracks = mov->nb_streams;
8301 
8302  if (mov->mode & (MODE_MP4|MODE_MOV|MODE_IPOD) && s->nb_chapters)
8303  nb_tracks++;
8304 
8305  if (mov->flags & FF_MOV_FLAG_RTP_HINT) {
8306  hint_track = nb_tracks;
8307  for (int i = 0; i < mov->nb_streams; i++) {
8308  if (rtp_hinting_needed(mov->tracks[i].st))
8309  nb_tracks++;
8310  }
8311  }
8312 
8313  if (mov->nb_meta_tmcd)
8314  tmcd_track = nb_tracks;
8315 
8316  for (int i = 0; i < mov->nb_streams; i++) {
8317  MOVTrack *track = &mov->tracks[i];
8318  AVStream *st = track->st;
8319 
8320  /* copy extradata if it exists */
8321  if (st->codecpar->extradata_size) {
8324  else if (!TAG_IS_AVCI(track->tag) && st->codecpar->codec_id != AV_CODEC_ID_DNXHD) {
8325  track->extradata_size[track->last_stsd_index] = st->codecpar->extradata_size;
8326  track->extradata[track->last_stsd_index] =
8328  if (!track->extradata[track->last_stsd_index]) {
8329  return AVERROR(ENOMEM);
8330  }
8331  memcpy(track->extradata[track->last_stsd_index],
8332  st->codecpar->extradata, track->extradata_size[track->last_stsd_index]);
8333  memset(track->extradata[track->last_stsd_index] + track->extradata_size[track->last_stsd_index],
8335  }
8336  }
8337 
8338  if (st->codecpar->codec_type != AVMEDIA_TYPE_AUDIO ||
8341  continue;
8342 
8343  for (int j = 0; j < mov->nb_streams; j++) {
8344  AVStream *stj= mov->tracks[j].st;
8345  MOVTrack *trackj= &mov->tracks[j];
8346  if (j == i)
8347  continue;
8348 
8349  if (stj->codecpar->codec_type == AVMEDIA_TYPE_AUDIO &&
8350  (trackj->par->ch_layout.nb_channels != 1 ||
8353  )
8354  track->mono_as_fc = -1;
8355 
8356  if (stj->codecpar->codec_type == AVMEDIA_TYPE_AUDIO &&
8359  trackj->par->ch_layout.nb_channels == 1 && track->mono_as_fc >= 0
8360  )
8361  track->mono_as_fc++;
8362 
8363  if (stj->codecpar->codec_type != AVMEDIA_TYPE_AUDIO ||
8366  trackj->language != track->language ||
8367  trackj->tag != track->tag
8368  )
8369  continue;
8370  track->multichannel_as_mono++;
8371  }
8372  }
8373 
8374  if (!(mov->flags & FF_MOV_FLAG_DELAY_MOOV)) {
8375  if ((ret = mov_write_identification(pb, s)) < 0)
8376  return ret;
8377  }
8378 
8379  if (mov->reserved_moov_size){
8380  mov->reserved_header_pos = avio_tell(pb);
8381  if (mov->reserved_moov_size > 0)
8382  avio_skip(pb, mov->reserved_moov_size);
8383  }
8384 
8385  if (mov->flags & FF_MOV_FLAG_FRAGMENT) {
8386  /* If no fragmentation options have been set, set a default. */
8387  if (!(mov->flags & (FF_MOV_FLAG_FRAG_KEYFRAME |
8392  if (mov->flags & FF_MOV_FLAG_HYBRID_FRAGMENTED) {
8393  avio_wb32(pb, 8); // placeholder for extended size field (64 bit)
8394  ffio_wfourcc(pb, mov->mode == MODE_MOV ? "wide" : "free");
8395  mov->mdat_pos = avio_tell(pb);
8396  }
8397  } else if (mov->mode != MODE_AVIF) {
8398  if (mov->flags & FF_MOV_FLAG_FASTSTART)
8399  mov->reserved_header_pos = avio_tell(pb);
8400  mov_write_mdat_tag(pb, mov);
8401  }
8402 
8404  if (mov->time)
8405  mov->time += 0x7C25B080; // 1970 based -> 1904 based
8406 
8407  if (mov->chapter_track)
8408  if ((ret = mov_create_chapter_track(s, mov->chapter_track)) < 0)
8409  return ret;
8410 
8411  if (mov->flags & FF_MOV_FLAG_RTP_HINT) {
8412  for (int i = 0; i < mov->nb_streams; i++) {
8413  if (rtp_hinting_needed(mov->tracks[i].st)) {
8414  if ((ret = ff_mov_init_hinting(s, hint_track, i)) < 0)
8415  return ret;
8416  hint_track++;
8417  }
8418  }
8419  }
8420 
8421  if (mov->nb_meta_tmcd) {
8422  const AVDictionaryEntry *t, *global_tcr = av_dict_get(s->metadata,
8423  "timecode", NULL, 0);
8424  /* Initialize the tmcd tracks */
8425  for (int i = 0; i < mov->nb_streams; i++) {
8426  AVStream *st = mov->tracks[i].st;
8427  t = global_tcr;
8428 
8429  if (st->codecpar->codec_type == AVMEDIA_TYPE_VIDEO) {
8430  AVTimecode tc;
8431  if (!t)
8432  t = av_dict_get(st->metadata, "timecode", NULL, 0);
8433  if (!t)
8434  continue;
8435  if (mov_check_timecode_track(s, &tc, st, t->value) < 0)
8436  continue;
8437  if ((ret = mov_create_timecode_track(s, tmcd_track, i, tc)) < 0)
8438  return ret;
8439  tmcd_track++;
8440  }
8441  }
8442  }
8443 
8444  avio_flush(pb);
8445 
8446  if (mov->flags & FF_MOV_FLAG_ISML)
8447  mov_write_isml_manifest(pb, mov, s);
8448 
8449  if (mov->flags & FF_MOV_FLAG_EMPTY_MOOV &&
8450  !(mov->flags & FF_MOV_FLAG_DELAY_MOOV)) {
8451  if ((ret = mov_write_moov_tag(pb, mov, s)) < 0)
8452  return ret;
8453  mov->moov_written = 1;
8454  if (mov->flags & FF_MOV_FLAG_GLOBAL_SIDX)
8455  mov->reserved_header_pos = avio_tell(pb);
8456  }
8457 
8458  return 0;
8459 }
8460 
8462 {
8463  int ret;
8464  AVIOContext *moov_buf;
8465  MOVMuxContext *mov = s->priv_data;
8466 
8467  if ((ret = ffio_open_null_buf(&moov_buf)) < 0)
8468  return ret;
8469  if ((ret = mov_write_moov_tag(moov_buf, mov, s)) < 0)
8470  return ret;
8471  return ffio_close_null_buf(moov_buf);
8472 }
8473 
8475 {
8476  int ret;
8477  AVIOContext *buf;
8478  MOVMuxContext *mov = s->priv_data;
8479 
8480  if ((ret = ffio_open_null_buf(&buf)) < 0)
8481  return ret;
8482  mov_write_sidx_tags(buf, mov, -1, 0);
8483  return ffio_close_null_buf(buf);
8484 }
8485 
8486 /*
8487  * This function gets the moov size if moved to the top of the file: the chunk
8488  * offset table can switch between stco (32-bit entries) to co64 (64-bit
8489  * entries) when the moov is moved to the beginning, so the size of the moov
8490  * would change. It also updates the chunk offset tables.
8491  */
8493 {
8494  int i, moov_size, moov_size2;
8495  MOVMuxContext *mov = s->priv_data;
8496 
8497  moov_size = get_moov_size(s);
8498  if (moov_size < 0)
8499  return moov_size;
8500 
8501  for (i = 0; i < mov->nb_tracks; i++)
8502  mov->tracks[i].data_offset += moov_size;
8503 
8504  moov_size2 = get_moov_size(s);
8505  if (moov_size2 < 0)
8506  return moov_size2;
8507 
8508  /* if the size changed, we just switched from stco to co64 and need to
8509  * update the offsets */
8510  if (moov_size2 != moov_size)
8511  for (i = 0; i < mov->nb_tracks; i++)
8512  mov->tracks[i].data_offset += moov_size2 - moov_size;
8513 
8514  return moov_size2;
8515 }
8516 
8518 {
8519  int i, sidx_size;
8520  MOVMuxContext *mov = s->priv_data;
8521 
8522  sidx_size = get_sidx_size(s);
8523  if (sidx_size < 0)
8524  return sidx_size;
8525 
8526  for (i = 0; i < mov->nb_tracks; i++)
8527  mov->tracks[i].data_offset += sidx_size;
8528 
8529  return sidx_size;
8530 }
8531 
8533 {
8534  int moov_size;
8535  MOVMuxContext *mov = s->priv_data;
8536 
8537  if (mov->flags & FF_MOV_FLAG_FRAGMENT)
8538  moov_size = compute_sidx_size(s);
8539  else
8540  moov_size = compute_moov_size(s);
8541  if (moov_size < 0)
8542  return moov_size;
8543 
8544  return ff_format_shift_data(s, mov->reserved_header_pos, moov_size);
8545 }
8546 
8548 {
8549  MOVMuxContext *mov = s->priv_data;
8550  AVIOContext *pb = s->pb;
8551  int res = 0;
8552  int i;
8553  int64_t moov_pos;
8554 
8555  /*
8556  * Before actually writing the trailer, make sure that there are no
8557  * dangling subtitles, that need a terminating sample.
8558  */
8559  for (i = 0; i < mov->nb_tracks; i++) {
8560  MOVTrack *trk = &mov->tracks[i];
8561  if (trk->par->codec_id == AV_CODEC_ID_MOV_TEXT &&
8564  trk->last_sample_is_subtitle_end = 1;
8565  }
8566  }
8567 
8568  // Check if we have any tracks that require squashing.
8569  // In that case, we'll have to write the packet here.
8570  if ((res = mov_write_squashed_packets(s)) < 0)
8571  return res;
8572 
8573  // If there were no chapters when the header was written, but there
8574  // are chapters now, write them in the trailer. This only works
8575  // when we are not doing fragments.
8576  if (!mov->chapter_track && !(mov->flags & FF_MOV_FLAG_FRAGMENT)) {
8577  if (mov->mode & (MODE_MP4|MODE_MOV|MODE_IPOD) && s->nb_chapters) {
8578  mov->chapter_track = mov->nb_tracks++;
8579  if ((res = mov_create_chapter_track(s, mov->chapter_track)) < 0)
8580  return res;
8581  }
8582  }
8583 
8584  if (!(mov->flags & FF_MOV_FLAG_FRAGMENT) ||
8586  if (mov->flags & FF_MOV_FLAG_HYBRID_FRAGMENTED) {
8587  mov_flush_fragment(s, 1);
8588  mov->mdat_size = avio_tell(pb) - mov->mdat_pos - 8;
8589  for (i = 0; i < mov->nb_tracks; i++) {
8590  MOVTrack *track = &mov->tracks[i];
8591  track->data_offset = 0;
8592  av_free(track->cluster);
8593  track->cluster = track->cluster_written;
8594  track->entry = track->entry_written;
8595  track->cluster_written = NULL;
8596  track->entry_written = 0;
8597  track->chunkCount = 0; // Force build_chunks to rebuild the list of chunks
8598  }
8599  // Clear the empty_moov flag, as we do want the moov to include
8600  // all the samples at this point.
8601  mov->flags &= ~FF_MOV_FLAG_EMPTY_MOOV;
8602  }
8603 
8604  moov_pos = avio_tell(pb);
8605 
8606  /* Write size of mdat tag */
8607  if (mov->mdat_size + 8 <= UINT32_MAX) {
8608  avio_seek(pb, mov->mdat_pos, SEEK_SET);
8609  avio_wb32(pb, mov->mdat_size + 8);
8611  ffio_wfourcc(pb, "mdat"); // overwrite the original moov into a mdat
8612  } else {
8613  /* overwrite 'wide' placeholder atom */
8614  avio_seek(pb, mov->mdat_pos - 8, SEEK_SET);
8615  /* special value: real atom size will be 64 bit value after
8616  * tag field */
8617  avio_wb32(pb, 1);
8618  ffio_wfourcc(pb, "mdat");
8619  avio_wb64(pb, mov->mdat_size + 16);
8620  }
8621  avio_seek(pb, mov->reserved_moov_size > 0 ? mov->reserved_header_pos : moov_pos, SEEK_SET);
8622 
8623  if (mov->flags & FF_MOV_FLAG_FASTSTART) {
8624  av_log(s, AV_LOG_INFO, "Starting second pass: moving the moov atom to the beginning of the file\n");
8625  res = shift_data(s);
8626  if (res < 0)
8627  return res;
8628  avio_seek(pb, mov->reserved_header_pos, SEEK_SET);
8629  if ((res = mov_write_moov_tag(pb, mov, s)) < 0)
8630  return res;
8631  } else if (mov->reserved_moov_size > 0) {
8632  int64_t size;
8633  if ((res = mov_write_moov_tag(pb, mov, s)) < 0)
8634  return res;
8635  size = mov->reserved_moov_size - (avio_tell(pb) - mov->reserved_header_pos);
8636  if (size < 8){
8637  av_log(s, AV_LOG_ERROR, "reserved_moov_size is too small, needed %"PRId64" additional\n", 8-size);
8638  return AVERROR(EINVAL);
8639  }
8640  avio_wb32(pb, size);
8641  ffio_wfourcc(pb, "free");
8642  ffio_fill(pb, 0, size - 8);
8643  avio_seek(pb, moov_pos, SEEK_SET);
8644  } else {
8645  if ((res = mov_write_moov_tag(pb, mov, s)) < 0)
8646  return res;
8647  }
8648  res = 0;
8649  } else {
8651  for (i = 0; i < mov->nb_tracks; i++)
8652  mov->tracks[i].data_offset = 0;
8653  if (mov->flags & FF_MOV_FLAG_GLOBAL_SIDX) {
8654  int64_t end;
8655  av_log(s, AV_LOG_INFO, "Starting second pass: inserting sidx atoms\n");
8656  res = shift_data(s);
8657  if (res < 0)
8658  return res;
8659  end = avio_tell(pb);
8660  avio_seek(pb, mov->reserved_header_pos, SEEK_SET);
8661  mov_write_sidx_tags(pb, mov, -1, 0);
8662  avio_seek(pb, end, SEEK_SET);
8663  }
8664  if (!(mov->flags & FF_MOV_FLAG_SKIP_TRAILER)) {
8666  res = mov_write_mfra_tag(pb, mov);
8667  if (res < 0)
8668  return res;
8669  }
8670  }
8671 
8672  return res;
8673 }
8674 
8676  const AVPacket *pkt)
8677 {
8678  int ret = 1;
8679 
8680  if (st->codecpar->codec_id == AV_CODEC_ID_AAC) {
8681  if (pkt->size > 2 && (AV_RB16(pkt->data) & 0xfff0) == 0xfff0)
8682  ret = ff_stream_add_bitstream_filter(st, "aac_adtstoasc", NULL);
8683  } else if (st->codecpar->codec_id == AV_CODEC_ID_VP9) {
8684  ret = ff_stream_add_bitstream_filter(st, "vp9_superframe", NULL);
8685  }
8686 
8687  return ret;
8688 }
8689 
8690 #if CONFIG_AVIF_MUXER
8691 static int avif_write_trailer(AVFormatContext *s)
8692 {
8693  AVIOContext *pb = s->pb;
8694  MOVMuxContext *mov = s->priv_data;
8695  int64_t pos_backup, extent_offsets[2];
8696  uint8_t *buf;
8697  int buf_size, moov_size;
8698 
8699  if (mov->moov_written) return 0;
8700 
8701  mov->is_animated_avif = s->streams[0]->nb_frames > 1;
8702  if (mov->is_animated_avif && mov->nb_streams > 1) {
8703  // For animated avif with alpha channel, we need to write a tref tag
8704  // with type "auxl".
8705  mov->tracks[1].tref_tag = MKTAG('a', 'u', 'x', 'l');
8706  mov->tracks[1].tref_id = 1;
8707  }
8709  mov_write_meta_tag(pb, mov, s);
8710 
8711  moov_size = get_moov_size(s);
8712  for (int i = 0; i < mov->nb_tracks; i++)
8713  mov->tracks[i].data_offset = avio_tell(pb) + moov_size + 8;
8714 
8715  if (mov->is_animated_avif) {
8716  int ret;
8717  if ((ret = mov_write_moov_tag(pb, mov, s)) < 0)
8718  return ret;
8719  }
8720 
8721  buf_size = avio_get_dyn_buf(mov->mdat_buf, &buf);
8722  avio_wb32(pb, buf_size + 8);
8723  ffio_wfourcc(pb, "mdat");
8724 
8725  // The offset for the YUV planes is the starting position of mdat.
8726  extent_offsets[0] = avio_tell(pb);
8727  // The offset for alpha plane is YUV offset + YUV size.
8728  extent_offsets[1] = extent_offsets[0] + mov->avif_extent_length[0];
8729 
8730  avio_write(pb, buf, buf_size);
8731 
8732  // write extent offsets.
8733  pos_backup = avio_tell(pb);
8734  for (int i = 0; i < mov->nb_streams; i++) {
8735  if (extent_offsets[i] != (uint32_t)extent_offsets[i]) {
8736  av_log(s, AV_LOG_ERROR, "extent offset does not fit in 32 bits\n");
8737  return AVERROR_INVALIDDATA;
8738  }
8739  avio_seek(pb, mov->avif_extent_pos[i], SEEK_SET);
8740  avio_wb32(pb, extent_offsets[i]); /* rewrite offset */
8741  }
8742  avio_seek(pb, pos_backup, SEEK_SET);
8743 
8744  return 0;
8745 }
8746 #endif
8747 
8748 #if CONFIG_TGP_MUXER || CONFIG_TG2_MUXER
8749 static const AVCodecTag codec_3gp_tags[] = {
8750  { AV_CODEC_ID_H263, MKTAG('s','2','6','3') },
8751  { AV_CODEC_ID_H264, MKTAG('a','v','c','1') },
8752  { AV_CODEC_ID_MPEG4, MKTAG('m','p','4','v') },
8753  { AV_CODEC_ID_AAC, MKTAG('m','p','4','a') },
8754  { AV_CODEC_ID_AMR_NB, MKTAG('s','a','m','r') },
8755  { AV_CODEC_ID_AMR_WB, MKTAG('s','a','w','b') },
8756  { AV_CODEC_ID_MOV_TEXT, MKTAG('t','x','3','g') },
8757  { AV_CODEC_ID_NONE, 0 },
8758 };
8759 static const AVCodecTag *const codec_3gp_tags_list[] = { codec_3gp_tags, NULL };
8760 #endif
8761 
8762 static const AVCodecTag codec_mp4_tags[] = {
8763  { AV_CODEC_ID_MPEG4, MKTAG('m', 'p', '4', 'v') },
8764  { AV_CODEC_ID_H264, MKTAG('a', 'v', 'c', '1') },
8765  { AV_CODEC_ID_H264, MKTAG('a', 'v', 'c', '3') },
8766  { AV_CODEC_ID_HEVC, MKTAG('h', 'e', 'v', '1') },
8767  { AV_CODEC_ID_HEVC, MKTAG('h', 'v', 'c', '1') },
8768  { AV_CODEC_ID_HEVC, MKTAG('d', 'v', 'h', '1') },
8769  { AV_CODEC_ID_VVC, MKTAG('v', 'v', 'c', '1') },
8770  { AV_CODEC_ID_VVC, MKTAG('v', 'v', 'i', '1') },
8771  { AV_CODEC_ID_EVC, MKTAG('e', 'v', 'c', '1') },
8772  { AV_CODEC_ID_APV, MKTAG('a', 'p', 'v', '1') },
8773  { AV_CODEC_ID_MPEG2VIDEO, MKTAG('m', 'p', '4', 'v') },
8774  { AV_CODEC_ID_MPEG1VIDEO, MKTAG('m', 'p', '4', 'v') },
8775  { AV_CODEC_ID_MJPEG, MKTAG('m', 'p', '4', 'v') },
8776  { AV_CODEC_ID_PNG, MKTAG('m', 'p', '4', 'v') },
8777  { AV_CODEC_ID_JPEG2000, MKTAG('m', 'p', '4', 'v') },
8778  { AV_CODEC_ID_VC1, MKTAG('v', 'c', '-', '1') },
8779  { AV_CODEC_ID_DIRAC, MKTAG('d', 'r', 'a', 'c') },
8780  { AV_CODEC_ID_TSCC2, MKTAG('m', 'p', '4', 'v') },
8781  { AV_CODEC_ID_VP9, MKTAG('v', 'p', '0', '9') },
8782  { AV_CODEC_ID_AV1, MKTAG('a', 'v', '0', '1') },
8783  { AV_CODEC_ID_AAC, MKTAG('m', 'p', '4', 'a') },
8784  { AV_CODEC_ID_ALAC, MKTAG('a', 'l', 'a', 'c') },
8785  { AV_CODEC_ID_MP4ALS, MKTAG('m', 'p', '4', 'a') },
8786  { AV_CODEC_ID_MP3, MKTAG('m', 'p', '4', 'a') },
8787  { AV_CODEC_ID_MP2, MKTAG('m', 'p', '4', 'a') },
8788  { AV_CODEC_ID_AC3, MKTAG('a', 'c', '-', '3') },
8789  { AV_CODEC_ID_EAC3, MKTAG('e', 'c', '-', '3') },
8790  { AV_CODEC_ID_DTS, MKTAG('m', 'p', '4', 'a') },
8791  { AV_CODEC_ID_TRUEHD, MKTAG('m', 'l', 'p', 'a') },
8792  { AV_CODEC_ID_FLAC, MKTAG('f', 'L', 'a', 'C') },
8793  { AV_CODEC_ID_OPUS, MKTAG('O', 'p', 'u', 's') },
8794  { AV_CODEC_ID_VORBIS, MKTAG('m', 'p', '4', 'a') },
8795  { AV_CODEC_ID_QCELP, MKTAG('m', 'p', '4', 'a') },
8796  { AV_CODEC_ID_EVRC, MKTAG('m', 'p', '4', 'a') },
8797  { AV_CODEC_ID_DVD_SUBTITLE, MKTAG('m', 'p', '4', 's') },
8798  { AV_CODEC_ID_MOV_TEXT, MKTAG('t', 'x', '3', 'g') },
8799  { AV_CODEC_ID_BIN_DATA, MKTAG('g', 'p', 'm', 'd') },
8800  { AV_CODEC_ID_MPEGH_3D_AUDIO, MKTAG('m', 'h', 'm', '1') },
8803  { AV_CODEC_ID_FFV1, MKTAG('F', 'F', 'V', '1') },
8804 
8805  /* ISO/IEC 23003-5 integer formats */
8812  /* ISO/IEC 23003-5 floating-point formats */
8817 
8818  { AV_CODEC_ID_AVS3, MKTAG('a', 'v', 's', '3') },
8819 
8820  { AV_CODEC_ID_NONE, 0 },
8821 };
8822 #if CONFIG_MP4_MUXER || CONFIG_PSP_MUXER
8823 static const AVCodecTag *const mp4_codec_tags_list[] = { codec_mp4_tags, NULL };
8824 #endif
8825 
8826 static const AVCodecTag codec_ism_tags[] = {
8827  { AV_CODEC_ID_WMAPRO , MKTAG('w', 'm', 'a', ' ') },
8829  { AV_CODEC_ID_NONE , 0 },
8830 };
8831 
8832 static const AVCodecTag codec_ipod_tags[] = {
8833  { AV_CODEC_ID_H264, MKTAG('a','v','c','1') },
8834  { AV_CODEC_ID_MPEG4, MKTAG('m','p','4','v') },
8835  { AV_CODEC_ID_AAC, MKTAG('m','p','4','a') },
8836  { AV_CODEC_ID_ALAC, MKTAG('a','l','a','c') },
8837  { AV_CODEC_ID_AC3, MKTAG('a','c','-','3') },
8838  { AV_CODEC_ID_MOV_TEXT, MKTAG('t','x','3','g') },
8839  { AV_CODEC_ID_MOV_TEXT, MKTAG('t','e','x','t') },
8840  { AV_CODEC_ID_NONE, 0 },
8841 };
8842 
8843 static const AVCodecTag codec_f4v_tags[] = {
8844  { AV_CODEC_ID_MP3, MKTAG('.','m','p','3') },
8845  { AV_CODEC_ID_AAC, MKTAG('m','p','4','a') },
8846  { AV_CODEC_ID_H264, MKTAG('a','v','c','1') },
8847  { AV_CODEC_ID_VP6A, MKTAG('V','P','6','A') },
8848  { AV_CODEC_ID_VP6F, MKTAG('V','P','6','F') },
8849  { AV_CODEC_ID_NONE, 0 },
8850 };
8851 
8852 #if CONFIG_AVIF_MUXER
8853 
8854 static const AVOption avif_options[] = {
8855  { "movie_timescale", "set movie timescale", offsetof(MOVMuxContext, movie_timescale), AV_OPT_TYPE_INT, {.i64 = MOV_TIMESCALE}, 1, INT_MAX, AV_OPT_FLAG_ENCODING_PARAM},
8856  { "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 },
8857  { NULL },
8858 };
8859 static const AVCodecTag codec_avif_tags[] = {
8860  { AV_CODEC_ID_AV1, MKTAG('a','v','0','1') },
8861  { AV_CODEC_ID_NONE, 0 },
8862 };
8863 static const AVCodecTag *const codec_avif_tags_list[] = { codec_avif_tags, NULL };
8864 
8865 static const AVClass mov_avif_muxer_class = {
8866  .class_name = "avif muxer",
8867  .item_name = av_default_item_name,
8868  .option = avif_options,
8869  .version = LIBAVUTIL_VERSION_INT,
8870 };
8871 #endif
8872 
8873 #if CONFIG_MOV_MUXER
8874 const FFOutputFormat ff_mov_muxer = {
8875  .p.name = "mov",
8876  .p.long_name = NULL_IF_CONFIG_SMALL("QuickTime / MOV"),
8877  .p.extensions = "mov",
8878  .priv_data_size = sizeof(MOVMuxContext),
8879  .p.audio_codec = AV_CODEC_ID_AAC,
8880  .p.video_codec = CONFIG_LIBX264_ENCODER ?
8882  .init = mov_init,
8883  .write_header = mov_write_header,
8884  .write_packet = mov_write_packet,
8885  .write_trailer = mov_write_trailer,
8886  .deinit = mov_free,
8888  .p.codec_tag = (const AVCodecTag* const []){
8890  },
8891  .check_bitstream = mov_check_bitstream,
8892  .p.priv_class = &mov_isobmff_muxer_class,
8893  .flags_internal = FF_OFMT_FLAG_ALLOW_FLUSH,
8894 };
8895 #endif
8896 #if CONFIG_TGP_MUXER
8897 const FFOutputFormat ff_tgp_muxer = {
8898  .p.name = "3gp",
8899  .p.long_name = NULL_IF_CONFIG_SMALL("3GP (3GPP file format)"),
8900  .p.extensions = "3gp",
8901  .priv_data_size = sizeof(MOVMuxContext),
8902  .p.audio_codec = AV_CODEC_ID_AMR_NB,
8903  .p.video_codec = AV_CODEC_ID_H263,
8904  .init = mov_init,
8905  .write_header = mov_write_header,
8906  .write_packet = mov_write_packet,
8907  .write_trailer = mov_write_trailer,
8908  .deinit = mov_free,
8910  .p.codec_tag = codec_3gp_tags_list,
8911  .check_bitstream = mov_check_bitstream,
8912  .p.priv_class = &mov_isobmff_muxer_class,
8913  .flags_internal = FF_OFMT_FLAG_ALLOW_FLUSH,
8914 };
8915 #endif
8916 #if CONFIG_MP4_MUXER
8917 const FFOutputFormat ff_mp4_muxer = {
8918  .p.name = "mp4",
8919  .p.long_name = NULL_IF_CONFIG_SMALL("MP4 (MPEG-4 Part 14)"),
8920  .p.mime_type = "video/mp4",
8921  .p.extensions = "mp4",
8922  .priv_data_size = sizeof(MOVMuxContext),
8923  .p.audio_codec = AV_CODEC_ID_AAC,
8924  .p.video_codec = CONFIG_LIBX264_ENCODER ?
8926  .init = mov_init,
8927  .write_header = mov_write_header,
8928  .write_packet = mov_write_packet,
8929  .write_trailer = mov_write_trailer,
8930  .deinit = mov_free,
8932  .p.codec_tag = mp4_codec_tags_list,
8933  .check_bitstream = mov_check_bitstream,
8934  .p.priv_class = &mov_isobmff_muxer_class,
8935  .flags_internal = FF_OFMT_FLAG_ALLOW_FLUSH,
8936 };
8937 #endif
8938 #if CONFIG_PSP_MUXER
8939 const FFOutputFormat ff_psp_muxer = {
8940  .p.name = "psp",
8941  .p.long_name = NULL_IF_CONFIG_SMALL("PSP MP4 (MPEG-4 Part 14)"),
8942  .p.extensions = "mp4,psp",
8943  .priv_data_size = sizeof(MOVMuxContext),
8944  .p.audio_codec = AV_CODEC_ID_AAC,
8945  .p.video_codec = CONFIG_LIBX264_ENCODER ?
8947  .init = mov_init,
8948  .write_header = mov_write_header,
8949  .write_packet = mov_write_packet,
8950  .write_trailer = mov_write_trailer,
8951  .deinit = mov_free,
8953  .p.codec_tag = mp4_codec_tags_list,
8954  .check_bitstream = mov_check_bitstream,
8955  .p.priv_class = &mov_isobmff_muxer_class,
8956  .flags_internal = FF_OFMT_FLAG_ALLOW_FLUSH,
8957 };
8958 #endif
8959 #if CONFIG_TG2_MUXER
8960 const FFOutputFormat ff_tg2_muxer = {
8961  .p.name = "3g2",
8962  .p.long_name = NULL_IF_CONFIG_SMALL("3GP2 (3GPP2 file format)"),
8963  .p.extensions = "3g2",
8964  .priv_data_size = sizeof(MOVMuxContext),
8965  .p.audio_codec = AV_CODEC_ID_AMR_NB,
8966  .p.video_codec = AV_CODEC_ID_H263,
8967  .init = mov_init,
8968  .write_header = mov_write_header,
8969  .write_packet = mov_write_packet,
8970  .write_trailer = mov_write_trailer,
8971  .deinit = mov_free,
8973  .p.codec_tag = codec_3gp_tags_list,
8974  .check_bitstream = mov_check_bitstream,
8975  .p.priv_class = &mov_isobmff_muxer_class,
8976  .flags_internal = FF_OFMT_FLAG_ALLOW_FLUSH,
8977 };
8978 #endif
8979 #if CONFIG_IPOD_MUXER
8980 const FFOutputFormat ff_ipod_muxer = {
8981  .p.name = "ipod",
8982  .p.long_name = NULL_IF_CONFIG_SMALL("iPod H.264 MP4 (MPEG-4 Part 14)"),
8983  .p.mime_type = "video/mp4",
8984  .p.extensions = "m4v,m4a,m4b",
8985  .priv_data_size = sizeof(MOVMuxContext),
8986  .p.audio_codec = AV_CODEC_ID_AAC,
8987  .p.video_codec = AV_CODEC_ID_H264,
8988  .init = mov_init,
8989  .write_header = mov_write_header,
8990  .write_packet = mov_write_packet,
8991  .write_trailer = mov_write_trailer,
8992  .deinit = mov_free,
8994  .p.codec_tag = (const AVCodecTag* const []){ codec_ipod_tags, 0 },
8995  .check_bitstream = mov_check_bitstream,
8996  .p.priv_class = &mov_isobmff_muxer_class,
8997  .flags_internal = FF_OFMT_FLAG_ALLOW_FLUSH,
8998 };
8999 #endif
9000 #if CONFIG_ISMV_MUXER
9001 const FFOutputFormat ff_ismv_muxer = {
9002  .p.name = "ismv",
9003  .p.long_name = NULL_IF_CONFIG_SMALL("ISMV/ISMA (Smooth Streaming)"),
9004  .p.mime_type = "video/mp4",
9005  .p.extensions = "ismv,isma",
9006  .priv_data_size = sizeof(MOVMuxContext),
9007  .p.audio_codec = AV_CODEC_ID_AAC,
9008  .p.video_codec = AV_CODEC_ID_H264,
9009  .init = mov_init,
9010  .write_header = mov_write_header,
9011  .write_packet = mov_write_packet,
9012  .write_trailer = mov_write_trailer,
9013  .deinit = mov_free,
9015  .p.codec_tag = (const AVCodecTag* const []){
9017  .check_bitstream = mov_check_bitstream,
9018  .p.priv_class = &mov_isobmff_muxer_class,
9019  .flags_internal = FF_OFMT_FLAG_ALLOW_FLUSH,
9020 };
9021 #endif
9022 #if CONFIG_F4V_MUXER
9023 const FFOutputFormat ff_f4v_muxer = {
9024  .p.name = "f4v",
9025  .p.long_name = NULL_IF_CONFIG_SMALL("F4V Adobe Flash Video"),
9026  .p.mime_type = "application/f4v",
9027  .p.extensions = "f4v",
9028  .priv_data_size = sizeof(MOVMuxContext),
9029  .p.audio_codec = AV_CODEC_ID_AAC,
9030  .p.video_codec = AV_CODEC_ID_H264,
9031  .init = mov_init,
9032  .write_header = mov_write_header,
9033  .write_packet = mov_write_packet,
9034  .write_trailer = mov_write_trailer,
9035  .deinit = mov_free,
9036  .p.flags = AVFMT_GLOBALHEADER,
9037  .p.codec_tag = (const AVCodecTag* const []){ codec_f4v_tags, 0 },
9038  .check_bitstream = mov_check_bitstream,
9039  .p.priv_class = &mov_isobmff_muxer_class,
9040  .flags_internal = FF_OFMT_FLAG_ALLOW_FLUSH,
9041 };
9042 #endif
9043 #if CONFIG_AVIF_MUXER
9044 const FFOutputFormat ff_avif_muxer = {
9045  .p.name = "avif",
9046  .p.long_name = NULL_IF_CONFIG_SMALL("AVIF"),
9047  .p.mime_type = "image/avif",
9048  .p.extensions = "avif",
9049  .priv_data_size = sizeof(MOVMuxContext),
9050  .p.video_codec = AV_CODEC_ID_AV1,
9051  .init = mov_init,
9052  .write_header = mov_write_header,
9053  .write_packet = mov_write_packet,
9054  .write_trailer = avif_write_trailer,
9055  .deinit = mov_free,
9056  .p.flags = AVFMT_GLOBALHEADER,
9057  .p.codec_tag = codec_avif_tags_list,
9058  .p.priv_class = &mov_avif_muxer_class,
9059  .flags_internal = FF_OFMT_FLAG_ALLOW_FLUSH,
9060 };
9061 #endif
AV_CODEC_ID_PCM_S16LE
@ AV_CODEC_ID_PCM_S16LE
Definition: codec_id.h:336
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:8826
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:5612
AV_CODEC_ID_EIA_608
@ AV_CODEC_ID_EIA_608
Definition: codec_id.h:571
AV_PKT_DATA_DISPLAYMATRIX
@ AV_PKT_DATA_DISPLAYMATRIX
This side data contains a 3x3 transformation matrix describing an affine transformation that needs to...
Definition: packet.h:105
AV_ROUND_UP
@ AV_ROUND_UP
Round toward +infinity.
Definition: mathematics.h:134
av_packet_unref
void av_packet_unref(AVPacket *pkt)
Wipe the packet.
Definition: packet.c:432
eac3_info
Definition: movenc.c: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:401
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:356
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:381
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:375
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:453
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:250
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:409
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
put_bits32
static void av_unused put_bits32(PutBitContext *s, uint32_t value)
Write exactly 32 bits into a bitstream.
Definition: put_bits.h:301
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:422
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:5547
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:7090
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:5422
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:5350
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:3441
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:210
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
metadata
Stream codec metadata
Definition: ogg-flac-chained-meta.txt:2
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:6619
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:255
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:223
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:403
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:332
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:552
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:7807
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:7569
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:466
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:431
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:8296
mov_write_sv3d_tag
static int mov_write_sv3d_tag(AVFormatContext *s, AVIOContext *pb, AVSphericalMapping *spherical_mapping)
Definition: movenc.c:2224
MP4TrackKindMapping::scheme_uri
const char * scheme_uri
Definition: isom.h:484
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:570
get_sidx_size
static int get_sidx_size(AVFormatContext *s)
Definition: movenc.c:8474
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:462
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:626
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
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:427
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:494
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:1374
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:607
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:432
AV_CODEC_ID_BIN_DATA
@ AV_CODEC_ID_BIN_DATA
Definition: codec_id.h:602
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:5600
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:541
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:461
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:405
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:337
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:413
fail
#define fail()
Definition: checkasm.h:199
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:1457
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:407
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:451
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:451
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:420
MOV_TRUN_DATA_OFFSET
#define MOV_TRUN_DATA_OFFSET
Definition: isom.h:405
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:632
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:5586
av_get_bits_per_sample
int av_get_bits_per_sample(enum AVCodecID codec_id)
Return codec bits per sample.
Definition: utils.c:547
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:1407
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:340
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:8547
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:7246
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:209
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:1362
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:386
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:403
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:487
MOV_TFHD_DEFAULT_DURATION
#define MOV_TFHD_DEFAULT_DURATION
Definition: isom.h:399
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:450
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:406
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:404
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:334
ffio_write_leb
void ffio_write_leb(AVIOContext *s, unsigned val)
Definition: aviobuf.c:944
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:279
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:5341
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:223
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:599
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
MOVTrack::vc1_info
struct MOVTrack::@449 vc1_info
AVPacket::buf
AVBufferRef * buf
A reference to the reference-counted buffer where the packet data is stored.
Definition: packet.h:535
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:8492
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
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:66
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:601
mov_check_timecode_track
static int mov_check_timecode_track(AVFormatContext *s, AVTimecode *tc, AVStream *src_st, const char *tcstr)
Definition: movenc.c:7508
codec_f4v_tags
static const AVCodecTag codec_f4v_tags[]
Definition: movenc.c:8843
mov_create_timecode_track
static int mov_create_timecode_track(AVFormatContext *s, int index, int src_index, AVTimecode tc)
Definition: movenc.c:7517
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:7274
MP4TrackKindValueMapping::disposition
int disposition
Definition: isom.h:479
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:546
AVIO_DATA_MARKER_TRAILER
@ AVIO_DATA_MARKER_TRAILER
Trailer data, which doesn't contain actual content, but only for finalizing the output file.
Definition: avio.h:139
AV_PIX_FMT_YUYV422
@ AV_PIX_FMT_YUYV422
packed YUV 4:2:2, 16bpp, Y0 Cb Y1 Cr
Definition: pixfmt.h:74
get_moov_size
static int get_moov_size(AVFormatContext *s)
Definition: movenc.c:8461
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:566
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:6633
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:1467
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:561
av_default_item_name
const char * av_default_item_name(void *ptr)
Return the context name.
Definition: log.c:240
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:5654
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:433
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:429
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:179
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:187
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:469
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:328
av_packet_ref
int av_packet_ref(AVPacket *dst, const AVPacket *src)
Setup a new reference to the data described by a given packet.
Definition: packet.c:440
AVCodecParameters::ch_layout
AVChannelLayout ch_layout
Audio only.
Definition: codec_par.h:180
mov_get_codec_tag
static unsigned int mov_get_codec_tag(AVFormatContext *s, MOVTrack *track)
Definition: movenc.c: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:489
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:5199
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:333
MOV_MP4_TTML_TAG
#define MOV_MP4_TTML_TAG
Definition: isom.h:474
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:397
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:495
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:5217
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:307
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:7177
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:2312
compute_sidx_size
static int compute_sidx_size(AVFormatContext *s)
Definition: movenc.c:8517
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:659
AV_CODEC_ID_EAC3
@ AV_CODEC_ID_EAC3
Definition: codec_id.h:490
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:419
EAC3_FRAME_TYPE_AC3_CONVERT
@ EAC3_FRAME_TYPE_AC3_CONVERT
Definition: ac3defs.h:113
mov_pix_fmt_tags
static const struct @447 mov_pix_fmt_tags[]
AV_CODEC_ID_AAC
@ AV_CODEC_ID_AAC
Definition: codec_id.h:452
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:474
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:107
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:348
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:553
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:8832
copy
static void copy(const float *p1, float *p2, const int length)
Definition: vf_vaguedenoiser.c:186
FF_OFMT_FLAG_ALLOW_FLUSH
#define FF_OFMT_FLAG_ALLOW_FLUSH
This flag indicates that the muxer stores data internally and supports flushing it.
Definition: mux.h:38
ff_isom_write_avcc
int ff_isom_write_avcc(AVIOContext *pb, const uint8_t *data, int len)
Definition: avc.c:31
height
#define height
Definition: dsp.h:89
AC3HeaderInfo::channel_map_present
uint8_t channel_map_present
Definition: ac3_parser_internal.h:49
MOVTrack::cover_image
AVPacket * cover_image
Definition: movenc.h: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:454
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:398
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:8762
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:7681
AV_CODEC_ID_OPUS
@ AV_CODEC_ID_OPUS
Definition: codec_id.h:510
eac3_info::substream
struct eac3_info::@448 substream[1]
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:551
avio_write
void avio_write(AVIOContext *s, const unsigned char *buf, int size)
Definition: aviobuf.c:201
avio_wb32
void avio_wb32(AVIOContext *s, unsigned int val)
Definition: aviobuf.c:365
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:475
avio_wl32
void avio_wl32(AVIOContext *s, unsigned int val)
Definition: aviobuf.c:357
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:558
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:621
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:476
MOV_DISPOSABLE_SAMPLE
#define MOV_DISPOSABLE_SAMPLE
Definition: movenc.h:60
shift_data
static int shift_data(AVFormatContext *s)
Definition: movenc.c:8532
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:7611
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:56
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:2313
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:545
avio_internal.h
ff_mov_write_packet
int ff_mov_write_packet(AVFormatContext *s, AVPacket *pkt)
Definition: movenc.c:6668
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:521
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:585
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
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:358
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:345
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:400
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:2276
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:8675
MOV_SAMPLE_DEPENDENCY_YES
#define MOV_SAMPLE_DEPENDENCY_YES
Definition: isom.h:428
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:478
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:5356
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:1435
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:231
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:423
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:563
MOVMuxContext::is_animated_avif
int is_animated_avif
Definition: movenc.h:264
flag
#define flag(name)
Definition: cbs_av1.c:495
AV_INPUT_BUFFER_PADDING_SIZE
#define AV_INPUT_BUFFER_PADDING_SIZE
Definition: defs.h:40
left
Tag MUST be and< 10hcoeff half pel interpolation filter coefficients, hcoeff[0] are the 2 middle coefficients[1] are the next outer ones and so on, resulting in a filter like:...eff[2], hcoeff[1], hcoeff[0], hcoeff[0], hcoeff[1], hcoeff[2] ... the sign of the coefficients is not explicitly stored but alternates after each coeff and coeff[0] is positive, so ...,+,-,+,-,+,+,-,+,-,+,... hcoeff[0] is not explicitly stored but found by subtracting the sum of all stored coefficients with signs from 32 hcoeff[0]=32 - hcoeff[1] - hcoeff[2] - ... a good choice for hcoeff and htaps is htaps=6 hcoeff={40,-10, 2} an alternative which requires more computations at both encoder and decoder side and may or may not be better is htaps=8 hcoeff={42,-14, 6,-2}ref_frames minimum of the number of available reference frames and max_ref_frames for example the first frame after a key frame always has ref_frames=1spatial_decomposition_type wavelet type 0 is a 9/7 symmetric compact integer wavelet 1 is a 5/3 symmetric compact integer wavelet others are reserved stored as delta from last, last is reset to 0 if always_reset||keyframeqlog quality(logarithmic quantizer scale) stored as delta from last, last is reset to 0 if always_reset||keyframemv_scale stored as delta from last, last is reset to 0 if always_reset||keyframe FIXME check that everything works fine if this changes between framesqbias dequantization bias stored as delta from last, last is reset to 0 if always_reset||keyframeblock_max_depth maximum depth of the block tree stored as delta from last, last is reset to 0 if always_reset||keyframequant_table quantization tableHighlevel bitstream structure:==============================--------------------------------------------|Header|--------------------------------------------|------------------------------------|||Block0||||split?||||yes no||||......... intra?||||:Block01 :yes no||||:Block02 :....... ..........||||:Block03 ::y DC ::ref index:||||:Block04 ::cb DC ::motion x :||||......... :cr DC ::motion y :||||....... ..........|||------------------------------------||------------------------------------|||Block1|||...|--------------------------------------------|------------ ------------ ------------|||Y subbands||Cb subbands||Cr subbands||||--- ---||--- ---||--- ---|||||LL0||HL0||||LL0||HL0||||LL0||HL0|||||--- ---||--- ---||--- ---||||--- ---||--- ---||--- ---|||||LH0||HH0||||LH0||HH0||||LH0||HH0|||||--- ---||--- ---||--- ---||||--- ---||--- ---||--- ---|||||HL1||LH1||||HL1||LH1||||HL1||LH1|||||--- ---||--- ---||--- ---||||--- ---||--- ---||--- ---|||||HH1||HL2||||HH1||HL2||||HH1||HL2|||||...||...||...|||------------ ------------ ------------|--------------------------------------------Decoding process:=================------------|||Subbands|------------||||------------|Intra DC||||LL0 subband prediction ------------|\ Dequantization ------------------- \||Reference frames|\ IDWT|------- -------|Motion \|||Frame 0||Frame 1||Compensation . OBMC v -------|------- -------|--------------. \------> Frame n output Frame Frame<----------------------------------/|...|------------------- Range Coder:============Binary Range Coder:------------------- The implemented range coder is an adapted version based upon "Range encoding: an algorithm for removing redundancy from a digitised message." by G. N. N. Martin. The symbols encoded by the Snow range coder are bits(0|1). The associated probabilities are not fix but change depending on the symbol mix seen so far. bit seen|new state ---------+----------------------------------------------- 0|256 - state_transition_table[256 - old_state];1|state_transition_table[old_state];state_transition_table={ 0, 0, 0, 0, 0, 0, 0, 0, 20, 21, 22, 23, 24, 25, 26, 27, 28, 29, 30, 31, 32, 33, 34, 35, 36, 37, 37, 38, 39, 40, 41, 42, 43, 44, 45, 46, 47, 48, 49, 50, 51, 52, 53, 54, 55, 56, 56, 57, 58, 59, 60, 61, 62, 63, 64, 65, 66, 67, 68, 69, 70, 71, 72, 73, 74, 75, 75, 76, 77, 78, 79, 80, 81, 82, 83, 84, 85, 86, 87, 88, 89, 90, 91, 92, 93, 94, 94, 95, 96, 97, 98, 99, 100, 101, 102, 103, 104, 105, 106, 107, 108, 109, 110, 111, 112, 113, 114, 114, 115, 116, 117, 118, 119, 120, 121, 122, 123, 124, 125, 126, 127, 128, 129, 130, 131, 132, 133, 133, 134, 135, 136, 137, 138, 139, 140, 141, 142, 143, 144, 145, 146, 147, 148, 149, 150, 151, 152, 152, 153, 154, 155, 156, 157, 158, 159, 160, 161, 162, 163, 164, 165, 166, 167, 168, 169, 170, 171, 171, 172, 173, 174, 175, 176, 177, 178, 179, 180, 181, 182, 183, 184, 185, 186, 187, 188, 189, 190, 190, 191, 192, 194, 194, 195, 196, 197, 198, 199, 200, 201, 202, 202, 204, 205, 206, 207, 208, 209, 209, 210, 211, 212, 213, 215, 215, 216, 217, 218, 219, 220, 220, 222, 223, 224, 225, 226, 227, 227, 229, 229, 230, 231, 232, 234, 234, 235, 236, 237, 238, 239, 240, 241, 242, 243, 244, 245, 246, 247, 248, 248, 0, 0, 0, 0, 0, 0, 0};FIXME Range Coding of integers:------------------------- FIXME Neighboring Blocks:===================left and top are set to the respective blocks unless they are outside of the image in which case they are set to the Null block top-left is set to the top left block unless it is outside of the image in which case it is set to the left block if this block has no larger parent block or it is at the left side of its parent block and the top right block is not outside of the image then the top right block is used for top-right else the top-left block is used Null block y, cb, cr are 128 level, ref, mx and my are 0 Motion Vector Prediction:=========================1. the motion vectors of all the neighboring blocks are scaled to compensate for the difference of reference frames scaled_mv=(mv *(256 *(current_reference+1)/(mv.reference+1))+128)> the median of the scaled left
Definition: snow.txt:386
AV_PIX_FMT_UYVY422
@ AV_PIX_FMT_UYVY422
packed YUV 4:2:2, 16bpp, Cb Y0 Cr Y1
Definition: pixfmt.h:88
AV_RL32
uint64_t_TMPL AV_WL64 unsigned int_TMPL AV_RL32
Definition: bytestream.h:92
MODE_3G2
#define MODE_3G2
Definition: movenc.h:42
mov_flush_fragment
static int mov_flush_fragment(AVFormatContext *s, int force)
Definition: movenc.c:6414
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:7665
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:7425
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:126
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:514
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
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:554
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:318
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:431
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
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:344
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:5209
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:341
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:455
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:359
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:529
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:376
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:402
AV_CODEC_ID_ILBC
@ AV_CODEC_ID_ILBC
Definition: codec_id.h:509
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:408
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:443
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:480
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:357
param_write_string
static void param_write_string(AVIOContext *pb, const char *name, const char *value)
Definition: movenc.c:5204
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:5498
AV_CODEC_ID_VORBIS
@ AV_CODEC_ID_VORBIS
Definition: codec_id.h:455
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:373
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:410
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:473
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:5533
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:349
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:5478
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:564
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:3361
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
FLAC_METADATA_TYPE_STREAMINFO
@ FLAC_METADATA_TYPE_STREAMINFO
Definition: flac.h:46
MP4TrackKindMapping
Definition: isom.h:483
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:230
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:5679
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