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