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