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