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