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