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