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