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,
2529  if (stereo_3d)
2530  mov_write_st3d_tag(s, pb, (AVStereo3D*)stereo_3d->data);
2531  if (spherical_mapping)
2532  mov_write_sv3d_tag(mov->fc, pb, (AVSphericalMapping*)spherical_mapping->data);
2533  }
2534 
2535  if (track->mode == MODE_MP4) {
2537  track->st->codecpar->nb_coded_side_data,
2539  if (dovi && mov->fc->strict_std_compliance <= FF_COMPLIANCE_UNOFFICIAL) {
2541  } else if (dovi) {
2542  av_log(mov->fc, AV_LOG_WARNING, "Not writing 'dvcC'/'dvvC' box. Requires -strict unofficial.\n");
2543  }
2544  }
2545 
2546  if (track->par->sample_aspect_ratio.den && track->par->sample_aspect_ratio.num) {
2547  mov_write_pasp_tag(pb, track);
2548  }
2549 
2550  if (uncompressed_ycbcr){
2551  mov_write_clap_tag(pb, track);
2552  }
2553 
2554  if (mov->encryption_scheme != MOV_ENC_NONE) {
2555  ff_mov_cenc_write_sinf_tag(track, pb, mov->encryption_kid);
2556  }
2557 
2558  if (mov->write_btrt &&
2559  ((ret = mov_write_btrt_tag(pb, track)) < 0))
2560  return ret;
2561 
2562  /* extra padding for avid stsd */
2563  /* https://developer.apple.com/library/mac/documentation/QuickTime/QTFF/QTFFChap2/qtff2.html#//apple_ref/doc/uid/TP40000939-CH204-61112 */
2564  if (avid)
2565  avio_wb32(pb, 0);
2566 
2567  if (track->mode == MODE_AVIF) {
2568  mov_write_ccst_tag(pb);
2569  if (mov->nb_streams > 0 && track == &mov->tracks[1])
2570  mov_write_aux_tag(pb, "auxi");
2571  }
2572 
2573  return update_size(pb, pos);
2574 }
2575 
2576 static int mov_write_rtp_tag(AVIOContext *pb, MOVTrack *track)
2577 {
2578  int64_t pos = avio_tell(pb);
2579  avio_wb32(pb, 0); /* size */
2580  ffio_wfourcc(pb, "rtp ");
2581  avio_wb32(pb, 0); /* Reserved */
2582  avio_wb16(pb, 0); /* Reserved */
2583  avio_wb16(pb, 1); /* Data-reference index */
2584 
2585  avio_wb16(pb, 1); /* Hint track version */
2586  avio_wb16(pb, 1); /* Highest compatible version */
2587  avio_wb32(pb, track->max_packet_size); /* Max packet size */
2588 
2589  avio_wb32(pb, 12); /* size */
2590  ffio_wfourcc(pb, "tims");
2591  avio_wb32(pb, track->timescale);
2592 
2593  return update_size(pb, pos);
2594 }
2595 
2596 static int mov_write_source_reference_tag(AVIOContext *pb, MOVTrack *track, const char *reel_name)
2597 {
2598  uint64_t str_size =strlen(reel_name);
2599  int64_t pos = avio_tell(pb);
2600 
2601  if (str_size >= UINT16_MAX){
2602  av_log(NULL, AV_LOG_ERROR, "reel_name length %"PRIu64" is too large\n", str_size);
2603  avio_wb16(pb, 0);
2604  return AVERROR(EINVAL);
2605  }
2606 
2607  avio_wb32(pb, 0); /* size */
2608  ffio_wfourcc(pb, "name"); /* Data format */
2609  avio_wb16(pb, str_size); /* string size */
2610  avio_wb16(pb, track->language); /* langcode */
2611  avio_write(pb, reel_name, str_size); /* reel name */
2612  return update_size(pb,pos);
2613 }
2614 
2615 static int mov_write_tmcd_tag(AVIOContext *pb, MOVTrack *track)
2616 {
2617  int64_t pos = avio_tell(pb);
2618 #if 1
2619  int frame_duration;
2620  int nb_frames;
2621  AVDictionaryEntry *t = NULL;
2622 
2623  if (!track->st->avg_frame_rate.num || !track->st->avg_frame_rate.den) {
2624  av_log(NULL, AV_LOG_ERROR, "avg_frame_rate not set for tmcd track.\n");
2625  return AVERROR(EINVAL);
2626  } else {
2627  frame_duration = av_rescale(track->timescale, track->st->avg_frame_rate.den, track->st->avg_frame_rate.num);
2628  nb_frames = ROUNDED_DIV(track->st->avg_frame_rate.num, track->st->avg_frame_rate.den);
2629  }
2630 
2631  if (nb_frames > 255) {
2632  av_log(NULL, AV_LOG_ERROR, "fps %d is too large\n", nb_frames);
2633  return AVERROR(EINVAL);
2634  }
2635 
2636  avio_wb32(pb, 0); /* size */
2637  ffio_wfourcc(pb, "tmcd"); /* Data format */
2638  avio_wb32(pb, 0); /* Reserved */
2639  avio_wb32(pb, 1); /* Data reference index */
2640  avio_wb32(pb, 0); /* Flags */
2641  avio_wb32(pb, track->timecode_flags); /* Flags (timecode) */
2642  avio_wb32(pb, track->timescale); /* Timescale */
2643  avio_wb32(pb, frame_duration); /* Frame duration */
2644  avio_w8(pb, nb_frames); /* Number of frames */
2645  avio_w8(pb, 0); /* Reserved */
2646 
2647  t = av_dict_get(track->st->metadata, "reel_name", NULL, 0);
2648  if (t && utf8len(t->value) && track->mode != MODE_MP4)
2649  mov_write_source_reference_tag(pb, track, t->value);
2650  else
2651  avio_wb16(pb, 0); /* zero size */
2652 #else
2653 
2654  avio_wb32(pb, 0); /* size */
2655  ffio_wfourcc(pb, "tmcd"); /* Data format */
2656  avio_wb32(pb, 0); /* Reserved */
2657  avio_wb32(pb, 1); /* Data reference index */
2658  if (track->par->extradata_size)
2659  avio_write(pb, track->par->extradata, track->par->extradata_size);
2660 #endif
2661  return update_size(pb, pos);
2662 }
2663 
2664 static int mov_write_gpmd_tag(AVIOContext *pb, const MOVTrack *track)
2665 {
2666  int64_t pos = avio_tell(pb);
2667  avio_wb32(pb, 0); /* size */
2668  ffio_wfourcc(pb, "gpmd");
2669  avio_wb32(pb, 0); /* Reserved */
2670  avio_wb16(pb, 0); /* Reserved */
2671  avio_wb16(pb, 1); /* Data-reference index */
2672  avio_wb32(pb, 0); /* Reserved */
2673  return update_size(pb, pos);
2674 }
2675 
2677 {
2678  int64_t pos = avio_tell(pb);
2679  int ret = 0;
2680  avio_wb32(pb, 0); /* size */
2681  ffio_wfourcc(pb, "stsd");
2682  avio_wb32(pb, 0); /* version & flags */
2683  avio_wb32(pb, 1); /* entry count */
2684  if (track->par->codec_type == AVMEDIA_TYPE_VIDEO)
2685  ret = mov_write_video_tag(s, pb, mov, track);
2686  else if (track->par->codec_type == AVMEDIA_TYPE_AUDIO)
2687  ret = mov_write_audio_tag(s, pb, mov, track);
2688  else if (track->par->codec_type == AVMEDIA_TYPE_SUBTITLE)
2689  ret = mov_write_subtitle_tag(s, pb, track);
2690  else if (track->par->codec_tag == MKTAG('r','t','p',' '))
2691  ret = mov_write_rtp_tag(pb, track);
2692  else if (track->par->codec_tag == MKTAG('t','m','c','d'))
2693  ret = mov_write_tmcd_tag(pb, track);
2694  else if (track->par->codec_tag == MKTAG('g','p','m','d'))
2695  ret = mov_write_gpmd_tag(pb, track);
2696 
2697  if (ret < 0)
2698  return ret;
2699 
2700  return update_size(pb, pos);
2701 }
2702 
2704 {
2705  MOVMuxContext *mov = s->priv_data;
2706  MOVCtts *ctts_entries;
2707  uint32_t entries = 0;
2708  uint32_t atom_size;
2709  int i;
2710 
2711  ctts_entries = av_malloc_array((track->entry + 1), sizeof(*ctts_entries)); /* worst case */
2712  if (!ctts_entries)
2713  return AVERROR(ENOMEM);
2714  ctts_entries[0].count = 1;
2715  ctts_entries[0].duration = track->cluster[0].cts;
2716  for (i = 1; i < track->entry; i++) {
2717  if (track->cluster[i].cts == ctts_entries[entries].duration) {
2718  ctts_entries[entries].count++; /* compress */
2719  } else {
2720  entries++;
2721  ctts_entries[entries].duration = track->cluster[i].cts;
2722  ctts_entries[entries].count = 1;
2723  }
2724  }
2725  entries++; /* last one */
2726  atom_size = 16 + (entries * 8);
2727  avio_wb32(pb, atom_size); /* size */
2728  ffio_wfourcc(pb, "ctts");
2730  avio_w8(pb, 1); /* version */
2731  else
2732  avio_w8(pb, 0); /* version */
2733  avio_wb24(pb, 0); /* flags */
2734  avio_wb32(pb, entries); /* entry count */
2735  for (i = 0; i < entries; i++) {
2736  avio_wb32(pb, ctts_entries[i].count);
2737  avio_wb32(pb, ctts_entries[i].duration);
2738  }
2739  av_free(ctts_entries);
2740  return atom_size;
2741 }
2742 
2743 /* Time to sample atom */
2744 static int mov_write_stts_tag(AVIOContext *pb, MOVTrack *track)
2745 {
2746  MOVStts *stts_entries = NULL;
2747  uint32_t entries = -1;
2748  uint32_t atom_size;
2749  int i;
2750 
2751  if (track->par->codec_type == AVMEDIA_TYPE_AUDIO && !track->audio_vbr) {
2752  stts_entries = av_malloc(sizeof(*stts_entries)); /* one entry */
2753  if (!stts_entries)
2754  return AVERROR(ENOMEM);
2755  stts_entries[0].count = track->sample_count;
2756  stts_entries[0].duration = 1;
2757  entries = 1;
2758  } else {
2759  if (track->entry) {
2760  stts_entries = av_malloc_array(track->entry, sizeof(*stts_entries)); /* worst case */
2761  if (!stts_entries)
2762  return AVERROR(ENOMEM);
2763  }
2764  for (i = 0; i < track->entry; i++) {
2765  int duration = get_cluster_duration(track, i);
2766  if (i && duration == stts_entries[entries].duration) {
2767  stts_entries[entries].count++; /* compress */
2768  } else {
2769  entries++;
2770  stts_entries[entries].duration = duration;
2771  stts_entries[entries].count = 1;
2772  }
2773  }
2774  entries++; /* last one */
2775  }
2776  atom_size = 16 + (entries * 8);
2777  avio_wb32(pb, atom_size); /* size */
2778  ffio_wfourcc(pb, "stts");
2779  avio_wb32(pb, 0); /* version & flags */
2780  avio_wb32(pb, entries); /* entry count */
2781  for (i = 0; i < entries; i++) {
2782  avio_wb32(pb, stts_entries[i].count);
2783  avio_wb32(pb, stts_entries[i].duration);
2784  }
2785  av_free(stts_entries);
2786  return atom_size;
2787 }
2788 
2790 {
2791  avio_wb32(pb, 28); /* size */
2792  ffio_wfourcc(pb, "dref");
2793  avio_wb32(pb, 0); /* version & flags */
2794  avio_wb32(pb, 1); /* entry count */
2795 
2796  avio_wb32(pb, 0xc); /* size */
2797  //FIXME add the alis and rsrc atom
2798  ffio_wfourcc(pb, "url ");
2799  avio_wb32(pb, 1); /* version & flags */
2800 
2801  return 28;
2802 }
2803 
2805 {
2806  struct sgpd_entry {
2807  int count;
2808  int16_t roll_distance;
2809  int group_description_index;
2810  };
2811 
2812  struct sgpd_entry *sgpd_entries = NULL;
2813  int entries = -1;
2814  int group = 0;
2815  int i, j;
2816 
2817  const int OPUS_SEEK_PREROLL_MS = 80;
2818  int roll_samples = av_rescale_q(OPUS_SEEK_PREROLL_MS,
2819  (AVRational){1, 1000},
2820  (AVRational){1, 48000});
2821 
2822  if (!track->entry)
2823  return 0;
2824 
2825  sgpd_entries = av_malloc_array(track->entry, sizeof(*sgpd_entries));
2826  if (!sgpd_entries)
2827  return AVERROR(ENOMEM);
2828 
2830 
2831  if (track->par->codec_id == AV_CODEC_ID_OPUS) {
2832  for (i = 0; i < track->entry; i++) {
2833  int roll_samples_remaining = roll_samples;
2834  int distance = 0;
2835  for (j = i - 1; j >= 0; j--) {
2836  roll_samples_remaining -= get_cluster_duration(track, j);
2837  distance++;
2838  if (roll_samples_remaining <= 0)
2839  break;
2840  }
2841  /* We don't have enough preceeding samples to compute a valid
2842  roll_distance here, so this sample can't be independently
2843  decoded. */
2844  if (roll_samples_remaining > 0)
2845  distance = 0;
2846  /* Verify distance is a maximum of 32 (2.5ms) packets. */
2847  if (distance > 32)
2848  return AVERROR_INVALIDDATA;
2849  if (i && distance == sgpd_entries[entries].roll_distance) {
2850  sgpd_entries[entries].count++;
2851  } else {
2852  entries++;
2853  sgpd_entries[entries].count = 1;
2854  sgpd_entries[entries].roll_distance = distance;
2855  sgpd_entries[entries].group_description_index = distance ? ++group : 0;
2856  }
2857  }
2858  } else {
2859  entries++;
2860  sgpd_entries[entries].count = track->sample_count;
2861  sgpd_entries[entries].roll_distance = 1;
2862  sgpd_entries[entries].group_description_index = ++group;
2863  }
2864  entries++;
2865 
2866  if (!group) {
2867  av_free(sgpd_entries);
2868  return 0;
2869  }
2870 
2871  /* Write sgpd tag */
2872  avio_wb32(pb, 24 + (group * 2)); /* size */
2873  ffio_wfourcc(pb, "sgpd");
2874  avio_wb32(pb, 1 << 24); /* fullbox */
2875  ffio_wfourcc(pb, "roll");
2876  avio_wb32(pb, 2); /* default_length */
2877  avio_wb32(pb, group); /* entry_count */
2878  for (i = 0; i < entries; i++) {
2879  if (sgpd_entries[i].group_description_index) {
2880  avio_wb16(pb, -sgpd_entries[i].roll_distance); /* roll_distance */
2881  }
2882  }
2883 
2884  /* Write sbgp tag */
2885  avio_wb32(pb, 20 + (entries * 8)); /* size */
2886  ffio_wfourcc(pb, "sbgp");
2887  avio_wb32(pb, 0); /* fullbox */
2888  ffio_wfourcc(pb, "roll");
2889  avio_wb32(pb, entries); /* entry_count */
2890  for (i = 0; i < entries; i++) {
2891  avio_wb32(pb, sgpd_entries[i].count); /* sample_count */
2892  avio_wb32(pb, sgpd_entries[i].group_description_index); /* group_description_index */
2893  }
2894 
2895  av_free(sgpd_entries);
2896  return 0;
2897 }
2898 
2900 {
2901  int64_t pos = avio_tell(pb);
2902  int ret = 0;
2903 
2904  avio_wb32(pb, 0); /* size */
2905  ffio_wfourcc(pb, "stbl");
2906  if ((ret = mov_write_stsd_tag(s, pb, mov, track)) < 0)
2907  return ret;
2908  mov_write_stts_tag(pb, track);
2909  if ((track->par->codec_type == AVMEDIA_TYPE_VIDEO ||
2910  track->par->codec_id == AV_CODEC_ID_TRUEHD ||
2912  track->par->codec_tag == MKTAG('r','t','p',' ')) &&
2913  track->has_keyframes && track->has_keyframes < track->entry)
2914  mov_write_stss_tag(pb, track, MOV_SYNC_SAMPLE);
2915  if (track->par->codec_type == AVMEDIA_TYPE_VIDEO && track->has_disposable)
2916  mov_write_sdtp_tag(pb, track);
2917  if (track->mode == MODE_MOV && track->flags & MOV_TRACK_STPS)
2919  if (track->par->codec_type == AVMEDIA_TYPE_VIDEO &&
2920  track->flags & MOV_TRACK_CTTS && track->entry) {
2921 
2922  if ((ret = mov_write_ctts_tag(s, pb, track)) < 0)
2923  return ret;
2924  }
2925  mov_write_stsc_tag(pb, track);
2926  mov_write_stsz_tag(pb, track);
2927  mov_write_stco_tag(pb, track);
2928  if (track->cenc.aes_ctr) {
2929  ff_mov_cenc_write_stbl_atoms(&track->cenc, pb);
2930  }
2931  if (track->par->codec_id == AV_CODEC_ID_OPUS || track->par->codec_id == AV_CODEC_ID_AAC) {
2932  mov_preroll_write_stbl_atoms(pb, track);
2933  }
2934  return update_size(pb, pos);
2935 }
2936 
2938 {
2939  int64_t pos = avio_tell(pb);
2940  avio_wb32(pb, 0); /* size */
2941  ffio_wfourcc(pb, "dinf");
2942  mov_write_dref_tag(pb);
2943  return update_size(pb, pos);
2944 }
2945 
2947 {
2948  avio_wb32(pb, 12);
2949  ffio_wfourcc(pb, "nmhd");
2950  avio_wb32(pb, 0);
2951  return 12;
2952 }
2953 
2955 {
2956  avio_wb32(pb, 12);
2957  ffio_wfourcc(pb, "sthd");
2958  avio_wb32(pb, 0);
2959  return 12;
2960 }
2961 
2962 static int mov_write_tcmi_tag(AVIOContext *pb, MOVTrack *track)
2963 {
2964  int64_t pos = avio_tell(pb);
2965  const char *font = "Lucida Grande";
2966  avio_wb32(pb, 0); /* size */
2967  ffio_wfourcc(pb, "tcmi"); /* timecode media information atom */
2968  avio_wb32(pb, 0); /* version & flags */
2969  avio_wb16(pb, 0); /* text font */
2970  avio_wb16(pb, 0); /* text face */
2971  avio_wb16(pb, 12); /* text size */
2972  avio_wb16(pb, 0); /* (unknown, not in the QT specs...) */
2973  avio_wb16(pb, 0x0000); /* text color (red) */
2974  avio_wb16(pb, 0x0000); /* text color (green) */
2975  avio_wb16(pb, 0x0000); /* text color (blue) */
2976  avio_wb16(pb, 0xffff); /* background color (red) */
2977  avio_wb16(pb, 0xffff); /* background color (green) */
2978  avio_wb16(pb, 0xffff); /* background color (blue) */
2979  avio_w8(pb, strlen(font)); /* font len (part of the pascal string) */
2980  avio_write(pb, font, strlen(font)); /* font name */
2981  return update_size(pb, pos);
2982 }
2983 
2984 static int mov_write_gmhd_tag(AVIOContext *pb, MOVTrack *track)
2985 {
2986  int64_t pos = avio_tell(pb);
2987  avio_wb32(pb, 0); /* size */
2988  ffio_wfourcc(pb, "gmhd");
2989  avio_wb32(pb, 0x18); /* gmin size */
2990  ffio_wfourcc(pb, "gmin");/* generic media info */
2991  avio_wb32(pb, 0); /* version & flags */
2992  avio_wb16(pb, 0x40); /* graphics mode = */
2993  avio_wb16(pb, 0x8000); /* opColor (r?) */
2994  avio_wb16(pb, 0x8000); /* opColor (g?) */
2995  avio_wb16(pb, 0x8000); /* opColor (b?) */
2996  avio_wb16(pb, 0); /* balance */
2997  avio_wb16(pb, 0); /* reserved */
2998 
2999  /*
3000  * This special text atom is required for
3001  * Apple Quicktime chapters. The contents
3002  * don't appear to be documented, so the
3003  * bytes are copied verbatim.
3004  */
3005  if (track->tag != MKTAG('c','6','0','8')) {
3006  avio_wb32(pb, 0x2C); /* size */
3007  ffio_wfourcc(pb, "text");
3008  avio_wb16(pb, 0x01);
3009  avio_wb32(pb, 0x00);
3010  avio_wb32(pb, 0x00);
3011  avio_wb32(pb, 0x00);
3012  avio_wb32(pb, 0x01);
3013  avio_wb32(pb, 0x00);
3014  avio_wb32(pb, 0x00);
3015  avio_wb32(pb, 0x00);
3016  avio_wb32(pb, 0x00004000);
3017  avio_wb16(pb, 0x0000);
3018  }
3019 
3020  if (track->par->codec_tag == MKTAG('t','m','c','d')) {
3021  int64_t tmcd_pos = avio_tell(pb);
3022  avio_wb32(pb, 0); /* size */
3023  ffio_wfourcc(pb, "tmcd");
3024  mov_write_tcmi_tag(pb, track);
3025  update_size(pb, tmcd_pos);
3026  } else if (track->par->codec_tag == MKTAG('g','p','m','d')) {
3027  int64_t gpmd_pos = avio_tell(pb);
3028  avio_wb32(pb, 0); /* size */
3029  ffio_wfourcc(pb, "gpmd");
3030  avio_wb32(pb, 0); /* version */
3031  update_size(pb, gpmd_pos);
3032  }
3033  return update_size(pb, pos);
3034 }
3035 
3037 {
3038  avio_wb32(pb, 16); /* size */
3039  ffio_wfourcc(pb, "smhd");
3040  avio_wb32(pb, 0); /* version & flags */
3041  avio_wb16(pb, 0); /* reserved (balance, normally = 0) */
3042  avio_wb16(pb, 0); /* reserved */
3043  return 16;
3044 }
3045 
3047 {
3048  avio_wb32(pb, 0x14); /* size (always 0x14) */
3049  ffio_wfourcc(pb, "vmhd");
3050  avio_wb32(pb, 0x01); /* version & flags */
3051  avio_wb64(pb, 0); /* reserved (graphics mode = copy) */
3052  return 0x14;
3053 }
3054 
3055 static int is_clcp_track(MOVTrack *track)
3056 {
3057  return track->tag == MKTAG('c','7','0','8') ||
3058  track->tag == MKTAG('c','6','0','8');
3059 }
3060 
3062 {
3063  MOVMuxContext *mov = s->priv_data;
3064  const char *hdlr, *descr = NULL, *hdlr_type = NULL;
3065  int64_t pos = avio_tell(pb);
3066  size_t descr_len;
3067 
3068  hdlr = "dhlr";
3069  hdlr_type = "url ";
3070  descr = "DataHandler";
3071 
3072  if (track) {
3073  hdlr = (track->mode == MODE_MOV) ? "mhlr" : "\0\0\0\0";
3074  if (track->par->codec_type == AVMEDIA_TYPE_VIDEO) {
3075  if (track->mode == MODE_AVIF) {
3076  hdlr_type = (track == &mov->tracks[0]) ? "pict" : "auxv";
3077  descr = "PictureHandler";
3078  } else {
3079  hdlr_type = "vide";
3080  descr = "VideoHandler";
3081  }
3082  } else if (track->par->codec_type == AVMEDIA_TYPE_AUDIO) {
3083  hdlr_type = "soun";
3084  descr = "SoundHandler";
3085  } else if (track->par->codec_type == AVMEDIA_TYPE_SUBTITLE) {
3086  if (is_clcp_track(track)) {
3087  hdlr_type = "clcp";
3088  descr = "ClosedCaptionHandler";
3089  } else {
3090  if (track->tag == MKTAG('t','x','3','g')) {
3091  hdlr_type = "sbtl";
3092  } else if (track->tag == MKTAG('m','p','4','s')) {
3093  hdlr_type = "subp";
3094  } else if (track->tag == MOV_MP4_TTML_TAG) {
3095  hdlr_type = "subt";
3096  } else {
3097  hdlr_type = "text";
3098  }
3099  descr = "SubtitleHandler";
3100  }
3101  } else if (track->par->codec_tag == MKTAG('r','t','p',' ')) {
3102  hdlr_type = "hint";
3103  descr = "HintHandler";
3104  } else if (track->par->codec_tag == MKTAG('t','m','c','d')) {
3105  hdlr_type = "tmcd";
3106  descr = "TimeCodeHandler";
3107  } else if (track->par->codec_tag == MKTAG('g','p','m','d')) {
3108  hdlr_type = "meta";
3109  descr = "GoPro MET"; // GoPro Metadata
3110  } else {
3112  "Unknown hdlr_type for %s, writing dummy values\n",
3113  av_fourcc2str(track->par->codec_tag));
3114  }
3115  if (track->st) {
3116  // hdlr.name is used by some players to identify the content title
3117  // of the track. So if an alternate handler description is
3118  // specified, use it.
3119  AVDictionaryEntry *t;
3120  t = av_dict_get(track->st->metadata, "handler_name", NULL, 0);
3121  if (t && utf8len(t->value))
3122  descr = t->value;
3123  }
3124  }
3125 
3126  if (mov->empty_hdlr_name) /* expressly allowed by QTFF and not prohibited in ISO 14496-12 8.4.3.3 */
3127  descr = "";
3128 
3129  avio_wb32(pb, 0); /* size */
3130  ffio_wfourcc(pb, "hdlr");
3131  avio_wb32(pb, 0); /* Version & flags */
3132  avio_write(pb, hdlr, 4); /* handler */
3133  ffio_wfourcc(pb, hdlr_type); /* handler type */
3134  avio_wb32(pb, 0); /* reserved */
3135  avio_wb32(pb, 0); /* reserved */
3136  avio_wb32(pb, 0); /* reserved */
3137  descr_len = strlen(descr);
3138  if (!track || track->mode == MODE_MOV)
3139  avio_w8(pb, descr_len); /* pascal string */
3140  avio_write(pb, descr, descr_len); /* handler description */
3141  if (track && track->mode != MODE_MOV)
3142  avio_w8(pb, 0); /* c string */
3143  return update_size(pb, pos);
3144 }
3145 
3146 static int mov_write_pitm_tag(AVIOContext *pb, int item_id)
3147 {
3148  int64_t pos = avio_tell(pb);
3149  avio_wb32(pb, 0); /* size */
3150  ffio_wfourcc(pb, "pitm");
3151  avio_wb32(pb, 0); /* Version & flags */
3152  avio_wb16(pb, item_id); /* item_id */
3153  return update_size(pb, pos);
3154 }
3155 
3157 {
3158  int64_t pos = avio_tell(pb);
3159  avio_wb32(pb, 0); /* size */
3160  ffio_wfourcc(pb, "iloc");
3161  avio_wb32(pb, 0); /* Version & flags */
3162  avio_w8(pb, (4 << 4) + 4); /* offset_size(4) and length_size(4) */
3163  avio_w8(pb, 0); /* base_offset_size(4) and reserved(4) */
3164  avio_wb16(pb, mov->nb_streams); /* item_count */
3165 
3166  for (int i = 0; i < mov->nb_streams; i++) {
3167  avio_wb16(pb, i + 1); /* item_id */
3168  avio_wb16(pb, 0); /* data_reference_index */
3169  avio_wb16(pb, 1); /* extent_count */
3170  mov->avif_extent_pos[i] = avio_tell(pb);
3171  avio_wb32(pb, 0); /* extent_offset (written later) */
3172  // For animated AVIF, we simply write the first packet's size.
3173  avio_wb32(pb, mov->avif_extent_length[i]); /* extent_length */
3174  }
3175 
3176  return update_size(pb, pos);
3177 }
3178 
3180 {
3181  int64_t iinf_pos = avio_tell(pb);
3182  avio_wb32(pb, 0); /* size */
3183  ffio_wfourcc(pb, "iinf");
3184  avio_wb32(pb, 0); /* Version & flags */
3185  avio_wb16(pb, mov->nb_streams); /* entry_count */
3186 
3187  for (int i = 0; i < mov->nb_streams; i++) {
3188  int64_t infe_pos = avio_tell(pb);
3189  avio_wb32(pb, 0); /* size */
3190  ffio_wfourcc(pb, "infe");
3191  avio_w8(pb, 0x2); /* Version */
3192  avio_wb24(pb, 0); /* flags */
3193  avio_wb16(pb, i + 1); /* item_id */
3194  avio_wb16(pb, 0); /* item_protection_index */
3195  avio_write(pb, "av01", 4); /* item_type */
3196  avio_write(pb, !i ? "Color\0" : "Alpha\0", 6); /* item_name */
3197  update_size(pb, infe_pos);
3198  }
3199 
3200  return update_size(pb, iinf_pos);
3201 }
3202 
3203 
3205 {
3206  int64_t auxl_pos;
3207  int64_t iref_pos = avio_tell(pb);
3208  avio_wb32(pb, 0); /* size */
3209  ffio_wfourcc(pb, "iref");
3210  avio_wb32(pb, 0); /* Version & flags */
3211 
3212  auxl_pos = avio_tell(pb);
3213  avio_wb32(pb, 0); /* size */
3214  ffio_wfourcc(pb, "auxl");
3215  avio_wb16(pb, 2); /* from_item_ID */
3216  avio_wb16(pb, 1); /* reference_count */
3217  avio_wb16(pb, 1); /* to_item_ID */
3218  update_size(pb, auxl_pos);
3219 
3220  return update_size(pb, iref_pos);
3221 }
3222 
3224  int stream_index)
3225 {
3226  int64_t pos = avio_tell(pb);
3227  avio_wb32(pb, 0); /* size */
3228  ffio_wfourcc(pb, "ispe");
3229  avio_wb32(pb, 0); /* Version & flags */
3230  avio_wb32(pb, s->streams[stream_index]->codecpar->width); /* image_width */
3231  avio_wb32(pb, s->streams[stream_index]->codecpar->height); /* image_height */
3232  return update_size(pb, pos);
3233 }
3234 
3236  int stream_index)
3237 {
3238  int64_t pos = avio_tell(pb);
3239  const AVPixFmtDescriptor *pixdesc =
3240  av_pix_fmt_desc_get(s->streams[stream_index]->codecpar->format);
3241  avio_wb32(pb, 0); /* size */
3242  ffio_wfourcc(pb, "pixi");
3243  avio_wb32(pb, 0); /* Version & flags */
3244  avio_w8(pb, pixdesc->nb_components); /* num_channels */
3245  for (int i = 0; i < pixdesc->nb_components; ++i) {
3246  avio_w8(pb, pixdesc->comp[i].depth); /* bits_per_channel */
3247  }
3248  return update_size(pb, pos);
3249 }
3250 
3252 {
3253  int64_t pos = avio_tell(pb);
3254  avio_wb32(pb, 0); /* size */
3255  ffio_wfourcc(pb, "ipco");
3256  for (int i = 0; i < mov->nb_streams; i++) {
3257  mov_write_ispe_tag(pb, mov, s, i);
3258  mov_write_pixi_tag(pb, mov, s, i);
3259  mov_write_av1c_tag(pb, &mov->tracks[i]);
3260  if (!i)
3261  mov_write_colr_tag(pb, &mov->tracks[0], 0);
3262  else
3263  mov_write_aux_tag(pb, "auxC");
3264  }
3265  return update_size(pb, pos);
3266 }
3267 
3269 {
3270  int64_t pos = avio_tell(pb);
3271  avio_wb32(pb, 0); /* size */
3272  ffio_wfourcc(pb, "ipma");
3273  avio_wb32(pb, 0); /* Version & flags */
3274  avio_wb32(pb, mov->nb_streams); /* entry_count */
3275 
3276  for (int i = 0, index = 1; i < mov->nb_streams; i++) {
3277  avio_wb16(pb, i + 1); /* item_ID */
3278  avio_w8(pb, 4); /* association_count */
3279 
3280  // ispe association.
3281  avio_w8(pb, index++); /* essential and property_index */
3282  // pixi association.
3283  avio_w8(pb, index++); /* essential and property_index */
3284  // av1C association.
3285  avio_w8(pb, 0x80 | index++); /* essential and property_index */
3286  // colr/auxC association.
3287  avio_w8(pb, index++); /* essential and property_index */
3288  }
3289  return update_size(pb, pos);
3290 }
3291 
3293 {
3294  int64_t pos = avio_tell(pb);
3295  avio_wb32(pb, 0); /* size */
3296  ffio_wfourcc(pb, "iprp");
3297  mov_write_ipco_tag(pb, mov, s);
3298  mov_write_ipma_tag(pb, mov, s);
3299  return update_size(pb, pos);
3300 }
3301 
3303 {
3304  /* This atom must be present, but leaving the values at zero
3305  * seems harmless. */
3306  avio_wb32(pb, 28); /* size */
3307  ffio_wfourcc(pb, "hmhd");
3308  avio_wb32(pb, 0); /* version, flags */
3309  avio_wb16(pb, 0); /* maxPDUsize */
3310  avio_wb16(pb, 0); /* avgPDUsize */
3311  avio_wb32(pb, 0); /* maxbitrate */
3312  avio_wb32(pb, 0); /* avgbitrate */
3313  avio_wb32(pb, 0); /* reserved */
3314  return 28;
3315 }
3316 
3318 {
3319  int64_t pos = avio_tell(pb);
3320  int ret;
3321 
3322  avio_wb32(pb, 0); /* size */
3323  ffio_wfourcc(pb, "minf");
3324  if (track->par->codec_type == AVMEDIA_TYPE_VIDEO)
3325  mov_write_vmhd_tag(pb);
3326  else if (track->par->codec_type == AVMEDIA_TYPE_AUDIO)
3327  mov_write_smhd_tag(pb);
3328  else if (track->par->codec_type == AVMEDIA_TYPE_SUBTITLE) {
3329  if (track->tag == MKTAG('t','e','x','t') || is_clcp_track(track)) {
3330  mov_write_gmhd_tag(pb, track);
3331  } else if (track->tag == MOV_MP4_TTML_TAG) {
3332  mov_write_sthd_tag(pb);
3333  } else {
3334  mov_write_nmhd_tag(pb);
3335  }
3336  } else if (track->tag == MKTAG('r','t','p',' ')) {
3337  mov_write_hmhd_tag(pb);
3338  } else if (track->tag == MKTAG('t','m','c','d')) {
3339  if (track->mode != MODE_MOV)
3340  mov_write_nmhd_tag(pb);
3341  else
3342  mov_write_gmhd_tag(pb, track);
3343  } else if (track->tag == MKTAG('g','p','m','d')) {
3344  mov_write_gmhd_tag(pb, track);
3345  }
3346  if (track->mode == MODE_MOV) /* ISO 14496-12 8.4.3.1 specifies hdlr only within mdia or meta boxes */
3347  mov_write_hdlr_tag(s, pb, NULL);
3348  mov_write_dinf_tag(pb);
3349  if ((ret = mov_write_stbl_tag(s, pb, mov, track)) < 0)
3350  return ret;
3351  return update_size(pb, pos);
3352 }
3353 
3354 static void get_pts_range(MOVMuxContext *mov, MOVTrack *track,
3355  int64_t *start, int64_t *end)
3356 {
3357  if (track->tag == MKTAG('t','m','c','d') && mov->nb_meta_tmcd) {
3358  // tmcd tracks gets track_duration set in mov_write_moov_tag from
3359  // another track's duration, while the end_pts may be left at zero.
3360  // Calculate the pts duration for that track instead.
3361  get_pts_range(mov, &mov->tracks[track->src_track], start, end);
3362  *start = av_rescale(*start, track->timescale,
3363  mov->tracks[track->src_track].timescale);
3364  *end = av_rescale(*end, track->timescale,
3365  mov->tracks[track->src_track].timescale);
3366  return;
3367  }
3368  if (track->end_pts != AV_NOPTS_VALUE &&
3369  track->start_dts != AV_NOPTS_VALUE &&
3370  track->start_cts != AV_NOPTS_VALUE) {
3371  *start = track->start_dts + track->start_cts;
3372  *end = track->end_pts;
3373  return;
3374  }
3375  *start = 0;
3376  *end = track->track_duration;
3377 }
3378 
3380 {
3381  int64_t start, end;
3382  get_pts_range(mov, track, &start, &end);
3383  return end - start;
3384 }
3385 
3386 // Calculate the actual duration of the track, after edits.
3387 // If it starts with a pts < 0, that is removed by the edit list.
3388 // If it starts with a pts > 0, the edit list adds a delay before that.
3389 // Thus, with edit lists enabled, the post-edit output of the file is
3390 // starting with pts=0.
3391 static int64_t calc_pts_duration(MOVMuxContext *mov, MOVTrack *track)
3392 {
3393  int64_t start, end;
3394  get_pts_range(mov, track, &start, &end);
3395  if (mov->use_editlist != 0)
3396  start = 0;
3397  return end - start;
3398 }
3399 
3401 {
3402  if (track && track->mode == MODE_ISM)
3403  return 1;
3404  if (duration < INT32_MAX)
3405  return 0;
3406  return 1;
3407 }
3408 
3410  MOVTrack *track)
3411 {
3412  int64_t duration = calc_samples_pts_duration(mov, track);
3413  int version = mov_mdhd_mvhd_tkhd_version(mov, track, duration);
3414 
3415  (version == 1) ? avio_wb32(pb, 44) : avio_wb32(pb, 32); /* size */
3416  ffio_wfourcc(pb, "mdhd");
3417  avio_w8(pb, version);
3418  avio_wb24(pb, 0); /* flags */
3419  if (version == 1) {
3420  avio_wb64(pb, track->time);
3421  avio_wb64(pb, track->time);
3422  } else {
3423  avio_wb32(pb, track->time); /* creation time */
3424  avio_wb32(pb, track->time); /* modification time */
3425  }
3426  avio_wb32(pb, track->timescale); /* time scale (sample rate for audio) */
3427  if (!track->entry && mov->mode == MODE_ISM)
3428  (version == 1) ? avio_wb64(pb, UINT64_C(0xffffffffffffffff)) : avio_wb32(pb, 0xffffffff);
3429  else if (!track->entry)
3430  (version == 1) ? avio_wb64(pb, 0) : avio_wb32(pb, 0);
3431  else
3432  (version == 1) ? avio_wb64(pb, duration) : avio_wb32(pb, duration); /* duration */
3433  avio_wb16(pb, track->language); /* language */
3434  avio_wb16(pb, 0); /* reserved (quality) */
3435 
3436  if (version != 0 && track->mode == MODE_MOV) {
3438  "FATAL error, file duration too long for timebase, this file will not be\n"
3439  "playable with QuickTime. Choose a different timebase with "
3440  "-video_track_timescale or a different container format\n");
3441  }
3442 
3443  return 32;
3444 }
3445 
3447  MOVMuxContext *mov, MOVTrack *track)
3448 {
3449  int64_t pos = avio_tell(pb);
3450  int ret;
3451 
3452  avio_wb32(pb, 0); /* size */
3453  ffio_wfourcc(pb, "mdia");
3454  mov_write_mdhd_tag(pb, mov, track);
3455  mov_write_hdlr_tag(s, pb, track);
3456  if ((ret = mov_write_minf_tag(s, pb, mov, track)) < 0)
3457  return ret;
3458  return update_size(pb, pos);
3459 }
3460 
3461 /* transformation matrix
3462  |a b u|
3463  |c d v|
3464  |tx ty w| */
3465 static void write_matrix(AVIOContext *pb, int16_t a, int16_t b, int16_t c,
3466  int16_t d, int16_t tx, int16_t ty)
3467 {
3468  avio_wb32(pb, a << 16); /* 16.16 format */
3469  avio_wb32(pb, b << 16); /* 16.16 format */
3470  avio_wb32(pb, 0); /* u in 2.30 format */
3471  avio_wb32(pb, c << 16); /* 16.16 format */
3472  avio_wb32(pb, d << 16); /* 16.16 format */
3473  avio_wb32(pb, 0); /* v in 2.30 format */
3474  avio_wb32(pb, tx << 16); /* 16.16 format */
3475  avio_wb32(pb, ty << 16); /* 16.16 format */
3476  avio_wb32(pb, 1 << 30); /* w in 2.30 format */
3477 }
3478 
3480  MOVTrack *track, AVStream *st)
3481 {
3482  int64_t duration = av_rescale_rnd(calc_pts_duration(mov, track),
3483  mov->movie_timescale, track->timescale,
3484  AV_ROUND_UP);
3485  int version;
3487  int group = 0;
3488 
3489  uint32_t *display_matrix = NULL;
3490  int i;
3491 
3492  if (mov->mode == MODE_AVIF)
3493  if (!mov->avif_loop_count)
3494  duration = INT64_MAX;
3495  else
3496  duration *= mov->avif_loop_count;
3497 
3498  if (st) {
3499  const AVPacketSideData *sd;
3500  if (mov->per_stream_grouping)
3501  group = st->index;
3502  else
3503  group = st->codecpar->codec_type;
3504 
3508  if (sd && sd->size == 9 * sizeof(*display_matrix))
3509  display_matrix = (uint32_t *)sd->data;
3510  }
3511 
3512  if (track->flags & MOV_TRACK_ENABLED)
3514 
3516 
3517  (version == 1) ? avio_wb32(pb, 104) : avio_wb32(pb, 92); /* size */
3518  ffio_wfourcc(pb, "tkhd");
3519  avio_w8(pb, version);
3520  avio_wb24(pb, flags);
3521  if (version == 1) {
3522  avio_wb64(pb, track->time);
3523  avio_wb64(pb, track->time);
3524  } else {
3525  avio_wb32(pb, track->time); /* creation time */
3526  avio_wb32(pb, track->time); /* modification time */
3527  }
3528  avio_wb32(pb, track->track_id); /* track-id */
3529  avio_wb32(pb, 0); /* reserved */
3530  if (!track->entry && mov->mode == MODE_ISM)
3531  (version == 1) ? avio_wb64(pb, UINT64_C(0xffffffffffffffff)) : avio_wb32(pb, 0xffffffff);
3532  else if (!track->entry)
3533  (version == 1) ? avio_wb64(pb, 0) : avio_wb32(pb, 0);
3534  else
3535  (version == 1) ? avio_wb64(pb, duration) : avio_wb32(pb, duration);
3536 
3537  avio_wb32(pb, 0); /* reserved */
3538  avio_wb32(pb, 0); /* reserved */
3539  avio_wb16(pb, 0); /* layer */
3540  avio_wb16(pb, group); /* alternate group) */
3541  /* Volume, only for audio */
3542  if (track->par->codec_type == AVMEDIA_TYPE_AUDIO)
3543  avio_wb16(pb, 0x0100);
3544  else
3545  avio_wb16(pb, 0);
3546  avio_wb16(pb, 0); /* reserved */
3547 
3548  /* Matrix structure */
3549  if (display_matrix) {
3550  for (i = 0; i < 9; i++)
3551  avio_wb32(pb, display_matrix[i]);
3552  } else {
3553  write_matrix(pb, 1, 0, 0, 1, 0, 0);
3554  }
3555  /* Track width and height, for visual only */
3556  if (st && (track->par->codec_type == AVMEDIA_TYPE_VIDEO ||
3557  track->par->codec_type == AVMEDIA_TYPE_SUBTITLE)) {
3558  int64_t track_width_1616;
3559  if (track->mode == MODE_MOV || track->mode == MODE_AVIF) {
3560  track_width_1616 = track->par->width * 0x10000ULL;
3561  } else {
3562  track_width_1616 = av_rescale(st->sample_aspect_ratio.num,
3563  track->par->width * 0x10000LL,
3564  st->sample_aspect_ratio.den);
3565  if (!track_width_1616 ||
3566  track->height != track->par->height ||
3567  track_width_1616 > UINT32_MAX)
3568  track_width_1616 = track->par->width * 0x10000ULL;
3569  }
3570  if (track_width_1616 > UINT32_MAX) {
3571  av_log(mov->fc, AV_LOG_WARNING, "track width is too large\n");
3572  track_width_1616 = 0;
3573  }
3574  avio_wb32(pb, track_width_1616);
3575  if (track->height > 0xFFFF) {
3576  av_log(mov->fc, AV_LOG_WARNING, "track height is too large\n");
3577  avio_wb32(pb, 0);
3578  } else
3579  avio_wb32(pb, track->height * 0x10000U);
3580  } else {
3581  avio_wb32(pb, 0);
3582  avio_wb32(pb, 0);
3583  }
3584  return 0x5c;
3585 }
3586 
3587 static int mov_write_tapt_tag(AVIOContext *pb, MOVTrack *track)
3588 {
3590  track->par->sample_aspect_ratio.den);
3591 
3592  int64_t pos = avio_tell(pb);
3593 
3594  avio_wb32(pb, 0); /* size */
3595  ffio_wfourcc(pb, "tapt");
3596 
3597  avio_wb32(pb, 20);
3598  ffio_wfourcc(pb, "clef");
3599  avio_wb32(pb, 0);
3600  avio_wb32(pb, width << 16);
3601  avio_wb32(pb, track->par->height << 16);
3602 
3603  avio_wb32(pb, 20);
3604  ffio_wfourcc(pb, "prof");
3605  avio_wb32(pb, 0);
3606  avio_wb32(pb, width << 16);
3607  avio_wb32(pb, track->par->height << 16);
3608 
3609  avio_wb32(pb, 20);
3610  ffio_wfourcc(pb, "enof");
3611  avio_wb32(pb, 0);
3612  avio_wb32(pb, track->par->width << 16);
3613  avio_wb32(pb, track->par->height << 16);
3614 
3615  return update_size(pb, pos);
3616 }
3617 
3618 // This box is written in the following cases:
3619 // * Seems important for the psp playback. Without it the movie seems to hang.
3620 // * Used for specifying the looping behavior of animated AVIF (as specified
3621 // in Section 9.6 of the HEIF specification ISO/IEC 23008-12).
3623  MOVTrack *track)
3624 {
3625  int64_t duration = av_rescale_rnd(calc_samples_pts_duration(mov, track),
3626  mov->movie_timescale, track->timescale,
3627  AV_ROUND_UP);
3628  int version = duration < INT32_MAX ? 0 : 1;
3629  int entry_size, entry_count, size;
3630  int64_t delay, start_ct = track->start_cts;
3631  int64_t start_dts = track->start_dts;
3632  int flags = 0;
3633 
3634  if (track->entry) {
3635  if (start_dts != track->cluster[0].dts || start_ct != track->cluster[0].cts) {
3636 
3637  av_log(mov->fc, AV_LOG_DEBUG,
3638  "EDTS using dts:%"PRId64" cts:%d instead of dts:%"PRId64" cts:%"PRId64" tid:%d\n",
3639  track->cluster[0].dts, track->cluster[0].cts,
3640  start_dts, start_ct, track->track_id);
3641  start_dts = track->cluster[0].dts;
3642  start_ct = track->cluster[0].cts;
3643  }
3644  }
3645 
3646  delay = av_rescale_rnd(start_dts + start_ct, mov->movie_timescale,
3647  track->timescale, AV_ROUND_DOWN);
3648 
3649  if (mov->mode == MODE_AVIF) {
3650  delay = 0;
3651  // Section 9.6.3 of ISO/IEC 23008-12: flags specifies repetition of the
3652  // edit list as follows: (flags & 1) equal to 0 specifies that the edit
3653  // list is not repeated, while (flags & 1) equal to 1 specifies that the
3654  // edit list is repeated.
3655  flags = mov->avif_loop_count != 1;
3656  start_ct = 0;
3657  }
3658 
3659  version |= delay < INT32_MAX ? 0 : 1;
3660 
3661  entry_size = (version == 1) ? 20 : 12;
3662  entry_count = 1 + (delay > 0);
3663  size = 24 + entry_count * entry_size;
3664 
3665  /* write the atom data */
3666  avio_wb32(pb, size);
3667  ffio_wfourcc(pb, "edts");
3668  avio_wb32(pb, size - 8);
3669  ffio_wfourcc(pb, "elst");
3670  avio_w8(pb, version);
3671  avio_wb24(pb, flags); /* flags */
3672 
3673  avio_wb32(pb, entry_count);
3674  if (delay > 0) { /* add an empty edit to delay presentation */
3675  /* In the positive delay case, the delay includes the cts
3676  * offset, and the second edit list entry below trims out
3677  * the same amount from the actual content. This makes sure
3678  * that the offset last sample is included in the edit
3679  * list duration as well. */
3680  if (version == 1) {
3681  avio_wb64(pb, delay);
3682  avio_wb64(pb, -1);
3683  } else {
3684  avio_wb32(pb, delay);
3685  avio_wb32(pb, -1);
3686  }
3687  avio_wb32(pb, 0x00010000);
3688  } else if (mov->mode != MODE_AVIF) {
3689  /* Avoid accidentally ending up with start_ct = -1 which has got a
3690  * special meaning. Normally start_ct should end up positive or zero
3691  * here, but use FFMIN in case dts is a small positive integer
3692  * rounded to 0 when represented in movie timescale units. */
3693  av_assert0(av_rescale_rnd(start_dts, mov->movie_timescale, track->timescale, AV_ROUND_DOWN) <= 0);
3694  start_ct = -FFMIN(start_dts, 0);
3695  /* Note, this delay is calculated from the pts of the first sample,
3696  * ensuring that we don't reduce the duration for cases with
3697  * dts<0 pts=0. */
3698  duration += delay;
3699  }
3700 
3701  /* For fragmented files, we don't know the full length yet. Setting
3702  * duration to 0 allows us to only specify the offset, including
3703  * the rest of the content (from all future fragments) without specifying
3704  * an explicit duration. */
3705  if (mov->flags & FF_MOV_FLAG_FRAGMENT)
3706  duration = 0;
3707 
3708  /* duration */
3709  if (version == 1) {
3710  avio_wb64(pb, duration);
3711  avio_wb64(pb, start_ct);
3712  } else {
3713  avio_wb32(pb, duration);
3714  avio_wb32(pb, start_ct);
3715  }
3716  avio_wb32(pb, 0x00010000);
3717  return size;
3718 }
3719 
3720 static int mov_write_tref_tag(AVIOContext *pb, MOVTrack *track)
3721 {
3722  avio_wb32(pb, 20); // size
3723  ffio_wfourcc(pb, "tref");
3724  avio_wb32(pb, 12); // size (subatom)
3725  avio_wl32(pb, track->tref_tag);
3726  avio_wb32(pb, track->tref_id);
3727  return 20;
3728 }
3729 
3730 // goes at the end of each track! ... Critical for PSP playback ("Incompatible data" without it)
3732 {
3733  avio_wb32(pb, 0x34); /* size ... reports as 28 in mp4box! */
3734  ffio_wfourcc(pb, "uuid");
3735  ffio_wfourcc(pb, "USMT");
3736  avio_wb32(pb, 0x21d24fce);
3737  avio_wb32(pb, 0xbb88695c);
3738  avio_wb32(pb, 0xfac9c740);
3739  avio_wb32(pb, 0x1c); // another size here!
3740  ffio_wfourcc(pb, "MTDT");
3741  avio_wb32(pb, 0x00010012);
3742  avio_wb32(pb, 0x0a);
3743  avio_wb32(pb, 0x55c40000);
3744  avio_wb32(pb, 0x1);
3745  avio_wb32(pb, 0x0);
3746  return 0x34;
3747 }
3748 
3749 static int mov_write_udta_sdp(AVIOContext *pb, MOVTrack *track)
3750 {
3751  AVFormatContext *ctx = track->rtp_ctx;
3752  char buf[1000] = "";
3753  int len;
3754 
3755  ff_sdp_write_media(buf, sizeof(buf), ctx->streams[0], track->src_track,
3756  NULL, NULL, 0, 0, ctx);
3757  av_strlcatf(buf, sizeof(buf), "a=control:streamid=%d\r\n", track->track_id);
3758  len = strlen(buf);
3759 
3760  avio_wb32(pb, len + 24);
3761  ffio_wfourcc(pb, "udta");
3762  avio_wb32(pb, len + 16);
3763  ffio_wfourcc(pb, "hnti");
3764  avio_wb32(pb, len + 8);
3765  ffio_wfourcc(pb, "sdp ");
3766  avio_write(pb, buf, len);
3767  return len + 24;
3768 }
3769 
3771  const char *tag, const char *str)
3772 {
3773  int64_t pos = avio_tell(pb);
3774  AVDictionaryEntry *t = av_dict_get(st->metadata, str, NULL, 0);
3775  if (!t || !utf8len(t->value))
3776  return 0;
3777 
3778  avio_wb32(pb, 0); /* size */
3779  ffio_wfourcc(pb, tag); /* type */
3780  avio_write(pb, t->value, strlen(t->value)); /* UTF8 string value */
3781  return update_size(pb, pos);
3782 }
3783 
3784 static int mov_write_track_kind(AVIOContext *pb, const char *scheme_uri,
3785  const char *value)
3786 {
3787  int64_t pos = avio_tell(pb);
3788 
3789  /* Box|FullBox basics */
3790  avio_wb32(pb, 0); /* size placeholder */
3791  ffio_wfourcc(pb, (const unsigned char *)"kind");
3792  avio_w8(pb, 0); /* version = 0 */
3793  avio_wb24(pb, 0); /* flags = 0 */
3794 
3795  /* Required null-terminated scheme URI */
3796  avio_write(pb, (const unsigned char *)scheme_uri,
3797  strlen(scheme_uri));
3798  avio_w8(pb, 0);
3799 
3800  /* Optional value string */
3801  if (value && value[0])
3802  avio_write(pb, (const unsigned char *)value,
3803  strlen(value));
3804 
3805  avio_w8(pb, 0);
3806 
3807  return update_size(pb, pos);
3808 }
3809 
3811 {
3812  int ret = AVERROR_BUG;
3813 
3814  for (int i = 0; ff_mov_track_kind_table[i].scheme_uri; i++) {
3816 
3817  for (int j = 0; map.value_maps[j].disposition; j++) {
3818  const struct MP4TrackKindValueMapping value_map = map.value_maps[j];
3819  if (!(st->disposition & value_map.disposition))
3820  continue;
3821 
3822  if ((ret = mov_write_track_kind(pb, map.scheme_uri, value_map.value)) < 0)
3823  return ret;
3824  }
3825  }
3826 
3827  return 0;
3828 }
3829 
3831  AVStream *st)
3832 {
3833  AVIOContext *pb_buf;
3834  int ret, size;
3835  uint8_t *buf;
3836 
3837  if (!st)
3838  return 0;
3839 
3840  ret = avio_open_dyn_buf(&pb_buf);
3841  if (ret < 0)
3842  return ret;
3843 
3844  if (mov->mode & (MODE_MP4|MODE_MOV))
3845  mov_write_track_metadata(pb_buf, st, "name", "title");
3846 
3847  if (mov->mode & MODE_MP4) {
3848  if ((ret = mov_write_track_kinds(pb_buf, st)) < 0)
3849  return ret;
3850  }
3851 
3852  if ((size = avio_get_dyn_buf(pb_buf, &buf)) > 0) {
3853  avio_wb32(pb, size + 8);
3854  ffio_wfourcc(pb, "udta");
3855  avio_write(pb, buf, size);
3856  }
3857  ffio_free_dyn_buf(&pb_buf);
3858 
3859  return 0;
3860 }
3861 
3863  MOVTrack *track, AVStream *st)
3864 {
3865  int64_t pos = avio_tell(pb);
3866  int entry_backup = track->entry;
3867  int chunk_backup = track->chunkCount;
3868  int ret;
3869 
3870  /* If we want to have an empty moov, but some samples already have been
3871  * buffered (delay_moov), pretend that no samples have been written yet. */
3872  if (mov->flags & FF_MOV_FLAG_EMPTY_MOOV)
3873  track->chunkCount = track->entry = 0;
3874 
3875  avio_wb32(pb, 0); /* size */
3876  ffio_wfourcc(pb, "trak");
3877  mov_write_tkhd_tag(pb, mov, track, st);
3878 
3879  av_assert2(mov->use_editlist >= 0);
3880 
3881  if (track->start_dts != AV_NOPTS_VALUE) {
3882  if (mov->use_editlist)
3883  mov_write_edts_tag(pb, mov, track); // PSP Movies and several other cases require edts box
3884  else if ((track->entry && track->cluster[0].dts) || track->mode == MODE_PSP || is_clcp_track(track))
3885  av_log(mov->fc, AV_LOG_WARNING,
3886  "Not writing any edit list even though one would have been required\n");
3887  }
3888 
3889  if (mov->is_animated_avif)
3890  mov_write_edts_tag(pb, mov, track);
3891 
3892  if (track->tref_tag)
3893  mov_write_tref_tag(pb, track);
3894 
3895  if ((ret = mov_write_mdia_tag(s, pb, mov, track)) < 0)
3896  return ret;
3897  if (track->mode == MODE_PSP)
3898  mov_write_uuid_tag_psp(pb, track); // PSP Movies require this uuid box
3899  if (track->tag == MKTAG('r','t','p',' '))
3900  mov_write_udta_sdp(pb, track);
3901  if (track->mode == MODE_MOV) {
3902  if (track->par->codec_type == AVMEDIA_TYPE_VIDEO) {
3903  double sample_aspect_ratio = av_q2d(st->sample_aspect_ratio);
3904  if (st->sample_aspect_ratio.num && 1.0 != sample_aspect_ratio) {
3905  mov_write_tapt_tag(pb, track);
3906  }
3907  }
3908  if (is_clcp_track(track) && st->sample_aspect_ratio.num) {
3909  mov_write_tapt_tag(pb, track);
3910  }
3911  }
3912  mov_write_track_udta_tag(pb, mov, st);
3913  track->entry = entry_backup;
3914  track->chunkCount = chunk_backup;
3915  return update_size(pb, pos);
3916 }
3917 
3919 {
3920  int i, has_audio = 0, has_video = 0;
3921  int64_t pos = avio_tell(pb);
3922  int audio_profile = mov->iods_audio_profile;
3923  int video_profile = mov->iods_video_profile;
3924  for (i = 0; i < mov->nb_tracks; i++) {
3925  if (mov->tracks[i].entry > 0 || mov->flags & FF_MOV_FLAG_EMPTY_MOOV) {
3926  has_audio |= mov->tracks[i].par->codec_type == AVMEDIA_TYPE_AUDIO;
3927  has_video |= mov->tracks[i].par->codec_type == AVMEDIA_TYPE_VIDEO;
3928  }
3929  }
3930  if (audio_profile < 0)
3931  audio_profile = 0xFF - has_audio;
3932  if (video_profile < 0)
3933  video_profile = 0xFF - has_video;
3934  avio_wb32(pb, 0x0); /* size */
3935  ffio_wfourcc(pb, "iods");
3936  avio_wb32(pb, 0); /* version & flags */
3937  put_descr(pb, 0x10, 7);
3938  avio_wb16(pb, 0x004f);
3939  avio_w8(pb, 0xff);
3940  avio_w8(pb, 0xff);
3941  avio_w8(pb, audio_profile);
3942  avio_w8(pb, video_profile);
3943  avio_w8(pb, 0xff);
3944  return update_size(pb, pos);
3945 }
3946 
3947 static int mov_write_trex_tag(AVIOContext *pb, MOVTrack *track)
3948 {
3949  avio_wb32(pb, 0x20); /* size */
3950  ffio_wfourcc(pb, "trex");
3951  avio_wb32(pb, 0); /* version & flags */
3952  avio_wb32(pb, track->track_id); /* track ID */
3953  avio_wb32(pb, 1); /* default sample description index */
3954  avio_wb32(pb, 0); /* default sample duration */
3955  avio_wb32(pb, 0); /* default sample size */
3956  avio_wb32(pb, 0); /* default sample flags */
3957  return 0;
3958 }
3959 
3961 {
3962  int64_t pos = avio_tell(pb);
3963  int i;
3964  avio_wb32(pb, 0x0); /* size */
3965  ffio_wfourcc(pb, "mvex");
3966  for (i = 0; i < mov->nb_tracks; i++)
3967  mov_write_trex_tag(pb, &mov->tracks[i]);
3968  return update_size(pb, pos);
3969 }
3970 
3972 {
3973  int max_track_id = 1, i;
3974  int64_t max_track_len = 0;
3975  int version;
3976  int timescale;
3977 
3978  for (i = 0; i < mov->nb_tracks; i++) {
3979  if (mov->tracks[i].entry > 0 && mov->tracks[i].timescale) {
3980  int64_t max_track_len_temp = av_rescale_rnd(
3981  calc_pts_duration(mov, &mov->tracks[i]),
3982  mov->movie_timescale,
3983  mov->tracks[i].timescale,
3984  AV_ROUND_UP);
3985  if (max_track_len < max_track_len_temp)
3986  max_track_len = max_track_len_temp;
3987  if (max_track_id < mov->tracks[i].track_id)
3988  max_track_id = mov->tracks[i].track_id;
3989  }
3990  }
3991  /* If using delay_moov, make sure the output is the same as if no
3992  * samples had been written yet. */
3993  if (mov->flags & FF_MOV_FLAG_EMPTY_MOOV) {
3994  max_track_len = 0;
3995  max_track_id = 1;
3996  }
3997 
3998  version = mov_mdhd_mvhd_tkhd_version(mov, NULL, max_track_len);
3999  avio_wb32(pb, version == 1 ? 120 : 108); /* size */
4000 
4001  ffio_wfourcc(pb, "mvhd");
4002  avio_w8(pb, version);
4003  avio_wb24(pb, 0); /* flags */
4004  if (version == 1) {
4005  avio_wb64(pb, mov->time);
4006  avio_wb64(pb, mov->time);
4007  } else {
4008  avio_wb32(pb, mov->time); /* creation time */
4009  avio_wb32(pb, mov->time); /* modification time */
4010  }
4011 
4012  timescale = mov->movie_timescale;
4013  if (mov->mode == MODE_AVIF && !timescale)
4014  timescale = mov->tracks[0].timescale;
4015 
4016  avio_wb32(pb, timescale);
4017  (version == 1) ? avio_wb64(pb, max_track_len) : avio_wb32(pb, max_track_len); /* duration of longest track */
4018 
4019  avio_wb32(pb, 0x00010000); /* reserved (preferred rate) 1.0 = normal */
4020  avio_wb16(pb, 0x0100); /* reserved (preferred volume) 1.0 = normal */
4021  ffio_fill(pb, 0, 2 + 2 * 4); /* reserved */
4022 
4023  /* Matrix structure */
4024  write_matrix(pb, 1, 0, 0, 1, 0, 0);
4025 
4026  avio_wb32(pb, 0); /* reserved (preview time) */
4027  avio_wb32(pb, 0); /* reserved (preview duration) */
4028  avio_wb32(pb, 0); /* reserved (poster time) */
4029  avio_wb32(pb, 0); /* reserved (selection time) */
4030  avio_wb32(pb, 0); /* reserved (selection duration) */
4031  avio_wb32(pb, 0); /* reserved (current time) */
4032  avio_wb32(pb, max_track_id + 1); /* Next track id */
4033  return 0x6c;
4034 }
4035 
4037  AVFormatContext *s)
4038 {
4039  avio_wb32(pb, 33); /* size */
4040  ffio_wfourcc(pb, "hdlr");
4041  avio_wb32(pb, 0);
4042  avio_wb32(pb, 0);
4043  ffio_wfourcc(pb, "mdir");
4044  ffio_wfourcc(pb, "appl");
4045  avio_wb32(pb, 0);
4046  avio_wb32(pb, 0);
4047  avio_w8(pb, 0);
4048  return 33;
4049 }
4050 
4051 /* helper function to write a data tag with the specified string as data */
4052 static int mov_write_string_data_tag(AVIOContext *pb, const char *data, int lang, int long_style)
4053 {
4054  size_t data_len = strlen(data);
4055  if (long_style) {
4056  int size = 16 + data_len;
4057  avio_wb32(pb, size); /* size */
4058  ffio_wfourcc(pb, "data");
4059  avio_wb32(pb, 1);
4060  avio_wb32(pb, 0);
4061  avio_write(pb, data, data_len);
4062  return size;
4063  } else {
4064  avio_wb16(pb, data_len); /* string length */
4065  if (!lang)
4066  lang = ff_mov_iso639_to_lang("und", 1);
4067  avio_wb16(pb, lang);
4068  avio_write(pb, data, data_len);
4069  return data_len + 4;
4070  }
4071 }
4072 
4073 static int mov_write_string_tag(AVIOContext *pb, const char *name,
4074  const char *value, int lang, int long_style)
4075 {
4076  int size = 0;
4077  if (value && value[0]) {
4078  int64_t pos = avio_tell(pb);
4079  avio_wb32(pb, 0); /* size */
4080  ffio_wfourcc(pb, name);
4081  mov_write_string_data_tag(pb, value, lang, long_style);
4082  size = update_size(pb, pos);
4083  }
4084  return size;
4085 }
4086 
4088  const char *tag, int *lang)
4089 {
4090  int l, len, len2;
4091  AVDictionaryEntry *t, *t2 = NULL;
4092  char tag2[16];
4093 
4094  *lang = 0;
4095 
4096  if (!(t = av_dict_get(s->metadata, tag, NULL, 0)))
4097  return NULL;
4098 
4099  len = strlen(t->key);
4100  snprintf(tag2, sizeof(tag2), "%s-", tag);
4101  while ((t2 = av_dict_get(s->metadata, tag2, t2, AV_DICT_IGNORE_SUFFIX))) {
4102  len2 = strlen(t2->key);
4103  if (len2 == len + 4 && !strcmp(t->value, t2->value)
4104  && (l = ff_mov_iso639_to_lang(&t2->key[len2 - 3], 1)) >= 0) {
4105  *lang = l;
4106  return t;
4107  }
4108  }
4109  return t;
4110 }
4111 
4113  const char *name, const char *tag,
4114  int long_style)
4115 {
4116  int lang;
4117  AVDictionaryEntry *t = get_metadata_lang(s, tag, &lang);
4118  if (!t)
4119  return 0;
4120  return mov_write_string_tag(pb, name, t->value, lang, long_style);
4121 }
4122 
4123 /* iTunes bpm number */
4125 {
4126  AVDictionaryEntry *t = av_dict_get(s->metadata, "tmpo", NULL, 0);
4127  int size = 0, tmpo = t ? atoi(t->value) : 0;
4128  if (tmpo) {
4129  size = 26;
4130  avio_wb32(pb, size);
4131  ffio_wfourcc(pb, "tmpo");
4132  avio_wb32(pb, size-8); /* size */
4133  ffio_wfourcc(pb, "data");
4134  avio_wb32(pb, 0x15); //type specifier
4135  avio_wb32(pb, 0);
4136  avio_wb16(pb, tmpo); // data
4137  }
4138  return size;
4139 }
4140 
4141 /* 3GPP TS 26.244 */
4143 {
4144  int lang;
4145  int64_t pos = avio_tell(pb);
4146  double latitude, longitude, altitude;
4147  int32_t latitude_fix, longitude_fix, altitude_fix;
4148  AVDictionaryEntry *t = get_metadata_lang(s, "location", &lang);
4149  const char *ptr, *place = "";
4150  char *end;
4151  static const char *astronomical_body = "earth";
4152  if (!t)
4153  return 0;
4154 
4155  ptr = t->value;
4156  latitude = strtod(ptr, &end);
4157  if (end == ptr) {
4158  av_log(s, AV_LOG_WARNING, "malformed location metadata\n");
4159  return 0;
4160  }
4161  ptr = end;
4162  longitude = strtod(ptr, &end);
4163  if (end == ptr) {
4164  av_log(s, AV_LOG_WARNING, "malformed location metadata\n");
4165  return 0;
4166  }
4167  ptr = end;
4168  altitude = strtod(ptr, &end);
4169  /* If no altitude was present, the default 0 should be fine */
4170  if (*end == '/')
4171  place = end + 1;
4172 
4173  latitude_fix = (int32_t) ((1 << 16) * latitude);
4174  longitude_fix = (int32_t) ((1 << 16) * longitude);
4175  altitude_fix = (int32_t) ((1 << 16) * altitude);
4176 
4177  avio_wb32(pb, 0); /* size */
4178  ffio_wfourcc(pb, "loci"); /* type */
4179  avio_wb32(pb, 0); /* version + flags */
4180  avio_wb16(pb, lang);
4181  avio_write(pb, place, strlen(place) + 1);
4182  avio_w8(pb, 0); /* role of place (0 == shooting location, 1 == real location, 2 == fictional location) */
4183  avio_wb32(pb, longitude_fix);
4184  avio_wb32(pb, latitude_fix);
4185  avio_wb32(pb, altitude_fix);
4186  avio_write(pb, astronomical_body, strlen(astronomical_body) + 1);
4187  avio_w8(pb, 0); /* additional notes, null terminated string */
4188 
4189  return update_size(pb, pos);
4190 }
4191 
4192 /* iTunes track or disc number */
4194  AVFormatContext *s, int disc)
4195 {
4196  AVDictionaryEntry *t = av_dict_get(s->metadata,
4197  disc ? "disc" : "track",
4198  NULL, 0);
4199  int size = 0, track = t ? atoi(t->value) : 0;
4200  if (track) {
4201  int tracks = 0;
4202  char *slash = strchr(t->value, '/');
4203  if (slash)
4204  tracks = atoi(slash + 1);
4205  avio_wb32(pb, 32); /* size */
4206  ffio_wfourcc(pb, disc ? "disk" : "trkn");
4207  avio_wb32(pb, 24); /* size */
4208  ffio_wfourcc(pb, "data");
4209  avio_wb32(pb, 0); // 8 bytes empty
4210  avio_wb32(pb, 0);
4211  avio_wb16(pb, 0); // empty
4212  avio_wb16(pb, track); // track / disc number
4213  avio_wb16(pb, tracks); // total track / disc number
4214  avio_wb16(pb, 0); // empty
4215  size = 32;
4216  }
4217  return size;
4218 }
4219 
4221  const char *name, const char *tag,
4222  int len)
4223 {
4224  AVDictionaryEntry *t = NULL;
4225  uint8_t num;
4226  int size = 24 + len;
4227 
4228  if (len != 1 && len != 4)
4229  return -1;
4230 
4231  if (!(t = av_dict_get(s->metadata, tag, NULL, 0)))
4232  return 0;
4233  num = atoi(t->value);
4234 
4235  avio_wb32(pb, size);
4236  ffio_wfourcc(pb, name);
4237  avio_wb32(pb, size - 8);
4238  ffio_wfourcc(pb, "data");
4239  avio_wb32(pb, 0x15);
4240  avio_wb32(pb, 0);
4241  if (len==4) avio_wb32(pb, num);
4242  else avio_w8 (pb, num);
4243 
4244  return size;
4245 }
4246 
4248 {
4249  MOVMuxContext *mov = s->priv_data;
4250  int64_t pos = 0;
4251 
4252  for (int i = 0; i < mov->nb_streams; i++) {
4253  MOVTrack *trk = &mov->tracks[i];
4254 
4255  if (!is_cover_image(trk->st) || trk->cover_image->size <= 0)
4256  continue;
4257 
4258  if (!pos) {
4259  pos = avio_tell(pb);
4260  avio_wb32(pb, 0);
4261  ffio_wfourcc(pb, "covr");
4262  }
4263  avio_wb32(pb, 16 + trk->cover_image->size);
4264  ffio_wfourcc(pb, "data");
4265  avio_wb32(pb, trk->tag);
4266  avio_wb32(pb , 0);
4267  avio_write(pb, trk->cover_image->data, trk->cover_image->size);
4268  }
4269 
4270  return pos ? update_size(pb, pos) : 0;
4271 }
4272 
4273 /* iTunes meta data list */
4275  AVFormatContext *s)
4276 {
4277  int64_t pos = avio_tell(pb);
4278  avio_wb32(pb, 0); /* size */
4279  ffio_wfourcc(pb, "ilst");
4280  mov_write_string_metadata(s, pb, "\251nam", "title" , 1);
4281  mov_write_string_metadata(s, pb, "\251ART", "artist" , 1);
4282  mov_write_string_metadata(s, pb, "aART", "album_artist", 1);
4283  mov_write_string_metadata(s, pb, "\251wrt", "composer" , 1);
4284  mov_write_string_metadata(s, pb, "\251alb", "album" , 1);
4285  mov_write_string_metadata(s, pb, "\251day", "date" , 1);
4286  if (!mov_write_string_metadata(s, pb, "\251too", "encoding_tool", 1)) {
4287  if (!(s->flags & AVFMT_FLAG_BITEXACT))
4288  mov_write_string_tag(pb, "\251too", LIBAVFORMAT_IDENT, 0, 1);
4289  }
4290  mov_write_string_metadata(s, pb, "\251cmt", "comment" , 1);
4291  mov_write_string_metadata(s, pb, "\251gen", "genre" , 1);
4292  mov_write_string_metadata(s, pb, "cprt", "copyright", 1);
4293  mov_write_string_metadata(s, pb, "\251grp", "grouping" , 1);
4294  mov_write_string_metadata(s, pb, "\251lyr", "lyrics" , 1);
4295  mov_write_string_metadata(s, pb, "desc", "description",1);
4296  mov_write_string_metadata(s, pb, "ldes", "synopsis" , 1);
4297  mov_write_string_metadata(s, pb, "tvsh", "show" , 1);
4298  mov_write_string_metadata(s, pb, "tven", "episode_id",1);
4299  mov_write_string_metadata(s, pb, "tvnn", "network" , 1);
4300  mov_write_string_metadata(s, pb, "keyw", "keywords" , 1);
4301  mov_write_int8_metadata (s, pb, "tves", "episode_sort",4);
4302  mov_write_int8_metadata (s, pb, "tvsn", "season_number",4);
4303  mov_write_int8_metadata (s, pb, "stik", "media_type",1);
4304  mov_write_int8_metadata (s, pb, "hdvd", "hd_video", 1);
4305  mov_write_int8_metadata (s, pb, "pgap", "gapless_playback",1);
4306  mov_write_int8_metadata (s, pb, "cpil", "compilation", 1);
4307  mov_write_covr(pb, s);
4308  mov_write_trkn_tag(pb, mov, s, 0); // track number
4309  mov_write_trkn_tag(pb, mov, s, 1); // disc number
4310  mov_write_tmpo_tag(pb, s);
4311  return update_size(pb, pos);
4312 }
4313 
4315  AVFormatContext *s)
4316 {
4317  avio_wb32(pb, 33); /* size */
4318  ffio_wfourcc(pb, "hdlr");
4319  avio_wb32(pb, 0);
4320  avio_wb32(pb, 0);
4321  ffio_wfourcc(pb, "mdta");
4322  avio_wb32(pb, 0);
4323  avio_wb32(pb, 0);
4324  avio_wb32(pb, 0);
4325  avio_w8(pb, 0);
4326  return 33;
4327 }
4328 
4330  AVFormatContext *s)
4331 {
4332  const AVDictionaryEntry *t = NULL;
4333  int64_t pos = avio_tell(pb);
4334  int64_t curpos, entry_pos;
4335  int count = 0;
4336 
4337  avio_wb32(pb, 0); /* size */
4338  ffio_wfourcc(pb, "keys");
4339  avio_wb32(pb, 0);
4340  entry_pos = avio_tell(pb);
4341  avio_wb32(pb, 0); /* entry count */
4342 
4343  while (t = av_dict_iterate(s->metadata, t)) {
4344  size_t key_len = strlen(t->key);
4345  avio_wb32(pb, key_len + 8);
4346  ffio_wfourcc(pb, "mdta");
4347  avio_write(pb, t->key, key_len);
4348  count += 1;
4349  }
4350  curpos = avio_tell(pb);
4351  avio_seek(pb, entry_pos, SEEK_SET);
4352  avio_wb32(pb, count); // rewrite entry count
4353  avio_seek(pb, curpos, SEEK_SET);
4354 
4355  return update_size(pb, pos);
4356 }
4357 
4359  AVFormatContext *s)
4360 {
4361  const AVDictionaryEntry *t = NULL;
4362  int64_t pos = avio_tell(pb);
4363  int count = 1; /* keys are 1-index based */
4364 
4365  avio_wb32(pb, 0); /* size */
4366  ffio_wfourcc(pb, "ilst");
4367 
4368  while (t = av_dict_iterate(s->metadata, t)) {
4369  int64_t entry_pos = avio_tell(pb);
4370  avio_wb32(pb, 0); /* size */
4371  avio_wb32(pb, count); /* key */
4372  mov_write_string_data_tag(pb, t->value, 0, 1);
4373  update_size(pb, entry_pos);
4374  count += 1;
4375  }
4376  return update_size(pb, pos);
4377 }
4378 
4379 /* meta data tags */
4381  AVFormatContext *s)
4382 {
4383  int size = 0;
4384  int64_t pos = avio_tell(pb);
4385  avio_wb32(pb, 0); /* size */
4386  ffio_wfourcc(pb, "meta");
4387  avio_wb32(pb, 0);
4388  if (mov->flags & FF_MOV_FLAG_USE_MDTA) {
4389  mov_write_mdta_hdlr_tag(pb, mov, s);
4390  mov_write_mdta_keys_tag(pb, mov, s);
4391  mov_write_mdta_ilst_tag(pb, mov, s);
4392  } else if (mov->mode == MODE_AVIF) {
4393  mov_write_hdlr_tag(s, pb, &mov->tracks[0]);
4394  // We always write the primary item id as 1 since only one track is
4395  // supported for AVIF.
4396  mov_write_pitm_tag(pb, 1);
4397  mov_write_iloc_tag(pb, mov, s);
4398  mov_write_iinf_tag(pb, mov, s);
4399  if (mov->nb_streams > 1)
4400  mov_write_iref_tag(pb, mov, s);
4401  mov_write_iprp_tag(pb, mov, s);
4402  } else {
4403  /* iTunes metadata tag */
4404  mov_write_itunes_hdlr_tag(pb, mov, s);
4405  mov_write_ilst_tag(pb, mov, s);
4406  }
4407  size = update_size(pb, pos);
4408  return size;
4409 }
4410 
4412  const char *name, const char *key)
4413 {
4414  int len;
4415  AVDictionaryEntry *t;
4416 
4417  if (!(t = av_dict_get(s->metadata, key, NULL, 0)))
4418  return 0;
4419 
4420  len = strlen(t->value);
4421  if (len > 0) {
4422  int size = len + 8;
4423  avio_wb32(pb, size);
4424  ffio_wfourcc(pb, name);
4425  avio_write(pb, t->value, len);
4426  return size;
4427  }
4428  return 0;
4429 }
4430 
4431 static int ascii_to_wc(AVIOContext *pb, const uint8_t *b)
4432 {
4433  int val;
4434  while (*b) {
4435  GET_UTF8(val, *b++, return -1;)
4436  avio_wb16(pb, val);
4437  }
4438  avio_wb16(pb, 0x00);
4439  return 0;
4440 }
4441 
4442 static uint16_t language_code(const char *str)
4443 {
4444  return (((str[0] - 0x60) & 0x1F) << 10) +
4445  (((str[1] - 0x60) & 0x1F) << 5) +
4446  (( str[2] - 0x60) & 0x1F);
4447 }
4448 
4450  const char *tag, const char *str)
4451 {
4452  int64_t pos = avio_tell(pb);
4453  AVDictionaryEntry *t = av_dict_get(s->metadata, str, NULL, 0);
4454  if (!t || !utf8len(t->value))
4455  return 0;
4456  avio_wb32(pb, 0); /* size */
4457  ffio_wfourcc(pb, tag); /* type */
4458  avio_wb32(pb, 0); /* version + flags */
4459  if (!strcmp(tag, "yrrc"))
4460  avio_wb16(pb, atoi(t->value));
4461  else {
4462  avio_wb16(pb, language_code("eng")); /* language */
4463  avio_write(pb, t->value, strlen(t->value) + 1); /* UTF8 string value */
4464  if (!strcmp(tag, "albm") &&
4465  (t = av_dict_get(s->metadata, "track", NULL, 0)))
4466  avio_w8(pb, atoi(t->value));
4467  }
4468  return update_size(pb, pos);
4469 }
4470 
4472 {
4473  int64_t pos = avio_tell(pb);
4474  int i, nb_chapters = FFMIN(s->nb_chapters, 255);
4475 
4476  avio_wb32(pb, 0); // size
4477  ffio_wfourcc(pb, "chpl");
4478  avio_wb32(pb, 0x01000000); // version + flags
4479  avio_wb32(pb, 0); // unknown
4480  avio_w8(pb, nb_chapters);
4481 
4482  for (i = 0; i < nb_chapters; i++) {
4483  AVChapter *c = s->chapters[i];
4484  AVDictionaryEntry *t;
4485  avio_wb64(pb, av_rescale_q(c->start, c->time_base, (AVRational){1,10000000}));
4486 
4487  if ((t = av_dict_get(c->metadata, "title", NULL, 0))) {
4488  int len = FFMIN(strlen(t->value), 255);
4489  avio_w8(pb, len);
4490  avio_write(pb, t->value, len);
4491  } else
4492  avio_w8(pb, 0);
4493  }
4494  return update_size(pb, pos);
4495 }
4496 
4498  AVFormatContext *s)
4499 {
4500  AVIOContext *pb_buf;
4501  int ret, size;
4502  uint8_t *buf;
4503 
4504  ret = avio_open_dyn_buf(&pb_buf);
4505  if (ret < 0)
4506  return ret;
4507 
4508  if (mov->mode & MODE_3GP) {
4509  mov_write_3gp_udta_tag(pb_buf, s, "perf", "artist");
4510  mov_write_3gp_udta_tag(pb_buf, s, "titl", "title");
4511  mov_write_3gp_udta_tag(pb_buf, s, "auth", "author");
4512  mov_write_3gp_udta_tag(pb_buf, s, "gnre", "genre");
4513  mov_write_3gp_udta_tag(pb_buf, s, "dscp", "comment");
4514  mov_write_3gp_udta_tag(pb_buf, s, "albm", "album");
4515  mov_write_3gp_udta_tag(pb_buf, s, "cprt", "copyright");
4516  mov_write_3gp_udta_tag(pb_buf, s, "yrrc", "date");
4517  mov_write_loci_tag(s, pb_buf);
4518  } 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
4519  mov_write_string_metadata(s, pb_buf, "\251ART", "artist", 0);
4520  mov_write_string_metadata(s, pb_buf, "\251nam", "title", 0);
4521  mov_write_string_metadata(s, pb_buf, "\251aut", "author", 0);
4522  mov_write_string_metadata(s, pb_buf, "\251alb", "album", 0);
4523  mov_write_string_metadata(s, pb_buf, "\251day", "date", 0);
4524  mov_write_string_metadata(s, pb_buf, "\251swr", "encoder", 0);
4525  // currently ignored by mov.c
4526  mov_write_string_metadata(s, pb_buf, "\251des", "comment", 0);
4527  // add support for libquicktime, this atom is also actually read by mov.c
4528  mov_write_string_metadata(s, pb_buf, "\251cmt", "comment", 0);
4529  mov_write_string_metadata(s, pb_buf, "\251gen", "genre", 0);
4530  mov_write_string_metadata(s, pb_buf, "\251cpy", "copyright", 0);
4531  mov_write_string_metadata(s, pb_buf, "\251mak", "make", 0);
4532  mov_write_string_metadata(s, pb_buf, "\251mod", "model", 0);
4533  mov_write_string_metadata(s, pb_buf, "\251xyz", "location", 0);
4534  mov_write_string_metadata(s, pb_buf, "\251key", "keywords", 0);
4535  mov_write_raw_metadata_tag(s, pb_buf, "XMP_", "xmp");
4536  } else {
4537  /* iTunes meta data */
4538  mov_write_meta_tag(pb_buf, mov, s);
4539  mov_write_loci_tag(s, pb_buf);
4540  }
4541 
4542  if (s->nb_chapters && !(mov->flags & FF_MOV_FLAG_DISABLE_CHPL))
4543  mov_write_chpl_tag(pb_buf, s);
4544 
4545  if ((size = avio_get_dyn_buf(pb_buf, &buf)) > 0) {
4546  avio_wb32(pb, size + 8);
4547  ffio_wfourcc(pb, "udta");
4548  avio_write(pb, buf, size);
4549  }
4550  ffio_free_dyn_buf(&pb_buf);
4551 
4552  return 0;
4553 }
4554 
4556  const char *str, const char *lang, int type)
4557 {
4558  int len = utf8len(str) + 1;
4559  if (len <= 0)
4560  return;
4561  avio_wb16(pb, len * 2 + 10); /* size */
4562  avio_wb32(pb, type); /* type */
4563  avio_wb16(pb, language_code(lang)); /* language */
4564  avio_wb16(pb, 0x01); /* ? */
4565  ascii_to_wc(pb, str);
4566 }
4567 
4569 {
4570  AVDictionaryEntry *title = av_dict_get(s->metadata, "title", NULL, 0);
4571  int64_t pos, pos2;
4572 
4573  if (title) {
4574  pos = avio_tell(pb);
4575  avio_wb32(pb, 0); /* size placeholder*/
4576  ffio_wfourcc(pb, "uuid");
4577  ffio_wfourcc(pb, "USMT");
4578  avio_wb32(pb, 0x21d24fce); /* 96 bit UUID */
4579  avio_wb32(pb, 0xbb88695c);
4580  avio_wb32(pb, 0xfac9c740);
4581 
4582  pos2 = avio_tell(pb);
4583  avio_wb32(pb, 0); /* size placeholder*/
4584  ffio_wfourcc(pb, "MTDT");
4585  avio_wb16(pb, 4);
4586 
4587  // ?
4588  avio_wb16(pb, 0x0C); /* size */
4589  avio_wb32(pb, 0x0B); /* type */
4590  avio_wb16(pb, language_code("und")); /* language */
4591  avio_wb16(pb, 0x0); /* ? */
4592  avio_wb16(pb, 0x021C); /* data */
4593 
4594  if (!(s->flags & AVFMT_FLAG_BITEXACT))
4595  mov_write_psp_udta_tag(pb, LIBAVFORMAT_IDENT, "eng", 0x04);
4596  mov_write_psp_udta_tag(pb, title->value, "eng", 0x01);
4597  mov_write_psp_udta_tag(pb, "2006/04/01 11:11:11", "und", 0x03);
4598 
4599  update_size(pb, pos2);
4600  return update_size(pb, pos);
4601  }
4602 
4603  return 0;
4604 }
4605 
4606 static void build_chunks(MOVTrack *trk)
4607 {
4608  int i;
4609  MOVIentry *chunk = &trk->cluster[0];
4610  uint64_t chunkSize = chunk->size;
4611  chunk->chunkNum = 1;
4612  if (trk->chunkCount)
4613  return;
4614  trk->chunkCount = 1;
4615  for (i = 1; i<trk->entry; i++){
4616  if (chunk->pos + chunkSize == trk->cluster[i].pos &&
4617  chunkSize + trk->cluster[i].size < (1<<20)){
4618  chunkSize += trk->cluster[i].size;
4619  chunk->samples_in_chunk += trk->cluster[i].entries;
4620  } else {
4621  trk->cluster[i].chunkNum = chunk->chunkNum+1;
4622  chunk=&trk->cluster[i];
4623  chunkSize = chunk->size;
4624  trk->chunkCount++;
4625  }
4626  }
4627 }
4628 
4629 /**
4630  * Assign track ids. If option "use_stream_ids_as_track_ids" is set,
4631  * the stream ids are used as track ids.
4632  *
4633  * This assumes mov->tracks and s->streams are in the same order and
4634  * there are no gaps in either of them (so mov->tracks[n] refers to
4635  * s->streams[n]).
4636  *
4637  * As an exception, there can be more entries in
4638  * s->streams than in mov->tracks, in which case new track ids are
4639  * generated (starting after the largest found stream id).
4640  */
4642 {
4643  int i;
4644 
4645  if (mov->track_ids_ok)
4646  return 0;
4647 
4648  if (mov->use_stream_ids_as_track_ids) {
4649  int next_generated_track_id = 0;
4650  for (i = 0; i < mov->nb_streams; i++) {
4651  AVStream *st = mov->tracks[i].st;
4652  if (st->id > next_generated_track_id)
4653  next_generated_track_id = st->id;
4654  }
4655 
4656  for (i = 0; i < mov->nb_tracks; i++) {
4657  if (mov->tracks[i].entry <= 0 && !(mov->flags & FF_MOV_FLAG_FRAGMENT))
4658  continue;
4659 
4660  mov->tracks[i].track_id = i >= mov->nb_streams ? ++next_generated_track_id : mov->tracks[i].st->id;
4661  }
4662  } else {
4663  for (i = 0; i < mov->nb_tracks; i++) {
4664  if (mov->tracks[i].entry <= 0 && !(mov->flags & FF_MOV_FLAG_FRAGMENT))
4665  continue;
4666 
4667  mov->tracks[i].track_id = i + 1;
4668  }
4669  }
4670 
4671  mov->track_ids_ok = 1;
4672 
4673  return 0;
4674 }
4675 
4677  AVFormatContext *s)
4678 {
4679  int i;
4680  int64_t pos = avio_tell(pb);
4681  avio_wb32(pb, 0); /* size placeholder*/
4682  ffio_wfourcc(pb, "moov");
4683 
4684  mov_setup_track_ids(mov, s);
4685 
4686  for (i = 0; i < mov->nb_tracks; i++) {
4687  if (mov->tracks[i].entry <= 0 && !(mov->flags & FF_MOV_FLAG_FRAGMENT))
4688  continue;
4689 
4690  mov->tracks[i].time = mov->time;
4691 
4692  if (mov->tracks[i].entry)
4693  build_chunks(&mov->tracks[i]);
4694  }
4695 
4696  if (mov->chapter_track)
4697  for (i = 0; i < mov->nb_streams; i++) {
4698  mov->tracks[i].tref_tag = MKTAG('c','h','a','p');
4699  mov->tracks[i].tref_id = mov->tracks[mov->chapter_track].track_id;
4700  }
4701  for (i = 0; i < mov->nb_tracks; i++) {
4702  MOVTrack *track = &mov->tracks[i];
4703  if (track->tag == MKTAG('r','t','p',' ')) {
4704  track->tref_tag = MKTAG('h','i','n','t');
4705  track->tref_id = mov->tracks[track->src_track].track_id;
4706  } else if (track->par->codec_type == AVMEDIA_TYPE_AUDIO) {
4708  track->st->codecpar->nb_coded_side_data,
4710  if (sd && sd->size == sizeof(int)) {
4711  int *fallback = (int *)sd->data;
4712  if (*fallback >= 0 && *fallback < mov->nb_tracks) {
4713  track->tref_tag = MKTAG('f','a','l','l');
4714  track->tref_id = mov->tracks[*fallback].track_id;
4715  }
4716  }
4717  }
4718  }
4719  for (i = 0; i < mov->nb_tracks; i++) {
4720  if (mov->tracks[i].tag == MKTAG('t','m','c','d')) {
4721  int src_trk = mov->tracks[i].src_track;
4722  mov->tracks[src_trk].tref_tag = mov->tracks[i].tag;
4723  mov->tracks[src_trk].tref_id = mov->tracks[i].track_id;
4724  //src_trk may have a different timescale than the tmcd track
4725  mov->tracks[i].track_duration = av_rescale(mov->tracks[src_trk].track_duration,
4726  mov->tracks[i].timescale,
4727  mov->tracks[src_trk].timescale);
4728  }
4729  }
4730 
4731  mov_write_mvhd_tag(pb, mov);
4732  if (mov->mode != MODE_MOV && mov->mode != MODE_AVIF && !mov->iods_skip)
4733  mov_write_iods_tag(pb, mov);
4734  for (i = 0; i < mov->nb_tracks; i++) {
4735  if (mov->tracks[i].entry > 0 || mov->flags & FF_MOV_FLAG_FRAGMENT ||
4736  mov->mode == MODE_AVIF) {
4737  int ret = mov_write_trak_tag(s, pb, mov, &(mov->tracks[i]), i < mov->nb_streams ? mov->tracks[i].st : NULL);
4738  if (ret < 0)
4739  return ret;
4740  }
4741  }
4742  if (mov->flags & FF_MOV_FLAG_FRAGMENT)
4743  mov_write_mvex_tag(pb, mov); /* QuickTime requires trak to precede this */
4744 
4745  if (mov->mode == MODE_PSP)
4747  else if (mov->mode != MODE_AVIF)
4748  mov_write_udta_tag(pb, mov, s);
4749 
4750  return update_size(pb, pos);
4751 }
4752 
4753 static void param_write_int(AVIOContext *pb, const char *name, int value)
4754 {
4755  avio_printf(pb, "<param name=\"%s\" value=\"%d\" valuetype=\"data\"/>\n", name, value);
4756 }
4757 
4758 static void param_write_string(AVIOContext *pb, const char *name, const char *value)
4759 {
4760  avio_printf(pb, "<param name=\"%s\" value=\"%s\" valuetype=\"data\"/>\n", name, value);
4761 }
4762 
4763 static void param_write_hex(AVIOContext *pb, const char *name, const uint8_t *value, int len)
4764 {
4765  char buf[150];
4766  len = FFMIN(sizeof(buf) / 2 - 1, len);
4767  ff_data_to_hex(buf, value, len, 0);
4768  avio_printf(pb, "<param name=\"%s\" value=\"%s\" valuetype=\"data\"/>\n", name, buf);
4769 }
4770 
4772 {
4773  int64_t pos = avio_tell(pb);
4774  int i;
4775 
4776  static const AVUUID uuid = {
4777  0xa5, 0xd4, 0x0b, 0x30, 0xe8, 0x14, 0x11, 0xdd,
4778  0xba, 0x2f, 0x08, 0x00, 0x20, 0x0c, 0x9a, 0x66
4779  };
4780 
4781  avio_wb32(pb, 0);
4782  ffio_wfourcc(pb, "uuid");
4783  avio_write(pb, uuid, AV_UUID_LEN);
4784  avio_wb32(pb, 0);
4785 
4786  avio_printf(pb, "<?xml version=\"1.0\" encoding=\"utf-8\"?>\n");
4787  avio_printf(pb, "<smil xmlns=\"http://www.w3.org/2001/SMIL20/Language\">\n");
4788  avio_printf(pb, "<head>\n");
4789  if (!(mov->fc->flags & AVFMT_FLAG_BITEXACT))
4790  avio_printf(pb, "<meta name=\"creator\" content=\"%s\" />\n",
4792  avio_printf(pb, "</head>\n");
4793  avio_printf(pb, "<body>\n");
4794  avio_printf(pb, "<switch>\n");
4795 
4796  mov_setup_track_ids(mov, s);
4797 
4798  for (i = 0; i < mov->nb_tracks; i++) {
4799  MOVTrack *track = &mov->tracks[i];
4800  struct mpeg4_bit_rate_values bit_rates =
4802  const char *type;
4803  int track_id = track->track_id;
4804  char track_name_buf[32] = { 0 };
4805 
4806  AVStream *st = track->st;
4807  AVDictionaryEntry *lang = av_dict_get(st->metadata, "language", NULL,0);
4808 
4809  if (track->par->codec_type == AVMEDIA_TYPE_VIDEO && !is_cover_image(st)) {
4810  type = "video";
4811  } else if (track->par->codec_type == AVMEDIA_TYPE_AUDIO) {
4812  type = "audio";
4813  } else {
4814  continue;
4815  }
4816 
4817  avio_printf(pb, "<%s systemBitrate=\"%"PRIu32"\">\n", type,
4818  bit_rates.avg_bit_rate);
4819  param_write_int(pb, "systemBitrate", bit_rates.avg_bit_rate);
4820  param_write_int(pb, "trackID", track_id);
4821  param_write_string(pb, "systemLanguage", lang ? lang->value : "und");
4822 
4823  /* Build track name piece by piece: */
4824  /* 1. track type */
4825  av_strlcat(track_name_buf, type, sizeof(track_name_buf));
4826  /* 2. track language, if available */
4827  if (lang)
4828  av_strlcatf(track_name_buf, sizeof(track_name_buf),
4829  "_%s", lang->value);
4830  /* 3. special type suffix */
4831  /* "_cc" = closed captions, "_ad" = audio_description */
4833  av_strlcat(track_name_buf, "_cc", sizeof(track_name_buf));
4835  av_strlcat(track_name_buf, "_ad", sizeof(track_name_buf));
4836 
4837  param_write_string(pb, "trackName", track_name_buf);
4838 
4839  if (track->par->codec_type == AVMEDIA_TYPE_VIDEO) {
4840  if (track->par->codec_id == AV_CODEC_ID_H264) {
4841  uint8_t *ptr;
4842  int size = track->par->extradata_size;
4843  if (!ff_avc_write_annexb_extradata(track->par->extradata, &ptr,
4844  &size)) {
4845  param_write_hex(pb, "CodecPrivateData",
4846  ptr ? ptr : track->par->extradata,
4847  size);
4848  av_free(ptr);
4849  }
4850  param_write_string(pb, "FourCC", "H264");
4851  } else if (track->par->codec_id == AV_CODEC_ID_VC1) {
4852  param_write_string(pb, "FourCC", "WVC1");
4853  param_write_hex(pb, "CodecPrivateData", track->par->extradata,
4854  track->par->extradata_size);
4855  }
4856  param_write_int(pb, "MaxWidth", track->par->width);
4857  param_write_int(pb, "MaxHeight", track->par->height);
4858  param_write_int(pb, "DisplayWidth", track->par->width);
4859  param_write_int(pb, "DisplayHeight", track->par->height);
4860  } else {
4861  if (track->par->codec_id == AV_CODEC_ID_AAC) {
4862  switch (track->par->profile) {
4863  case AV_PROFILE_AAC_HE_V2:
4864  param_write_string(pb, "FourCC", "AACP");
4865  break;
4866  case AV_PROFILE_AAC_HE:
4867  param_write_string(pb, "FourCC", "AACH");
4868  break;
4869  default:
4870  param_write_string(pb, "FourCC", "AACL");
4871  }
4872  } else if (track->par->codec_id == AV_CODEC_ID_WMAPRO) {
4873  param_write_string(pb, "FourCC", "WMAP");
4874  }
4875  param_write_hex(pb, "CodecPrivateData", track->par->extradata,
4876  track->par->extradata_size);
4878  track->par->codec_id));
4879  param_write_int(pb, "Channels", track->par->ch_layout.nb_channels);
4880  param_write_int(pb, "SamplingRate", track->par->sample_rate);
4881  param_write_int(pb, "BitsPerSample", 16);
4882  param_write_int(pb, "PacketSize", track->par->block_align ?
4883  track->par->block_align : 4);
4884  }
4885  avio_printf(pb, "</%s>\n", type);
4886  }
4887  avio_printf(pb, "</switch>\n");
4888  avio_printf(pb, "</body>\n");
4889  avio_printf(pb, "</smil>\n");
4890 
4891  return update_size(pb, pos);
4892 }
4893 
4895 {
4896  avio_wb32(pb, 16);
4897  ffio_wfourcc(pb, "mfhd");
4898  avio_wb32(pb, 0);
4899  avio_wb32(pb, mov->fragments);
4900  return 0;
4901 }
4902 
4903 static uint32_t get_sample_flags(MOVTrack *track, MOVIentry *entry)
4904 {
4907 }
4908 
4910  MOVTrack *track, int64_t moof_offset)
4911 {
4912  int64_t pos = avio_tell(pb);
4915  if (!track->entry) {
4917  } else {
4919  }
4922  if (mov->flags & FF_MOV_FLAG_DEFAULT_BASE_MOOF) {
4925  }
4926  /* CMAF requires all values to be explicit in tfhd atoms */
4927  if (mov->flags & FF_MOV_FLAG_CMAF)
4929 
4930  /* Don't set a default sample size, the silverlight player refuses
4931  * to play files with that set. Don't set a default sample duration,
4932  * WMP freaks out if it is set. Don't set a base data offset, PIFF
4933  * file format says it MUST NOT be set. */
4934  if (track->mode == MODE_ISM)
4937 
4938  avio_wb32(pb, 0); /* size placeholder */
4939  ffio_wfourcc(pb, "tfhd");
4940  avio_w8(pb, 0); /* version */
4941  avio_wb24(pb, flags);
4942 
4943  avio_wb32(pb, track->track_id); /* track-id */
4945  avio_wb64(pb, moof_offset);
4946  if (flags & MOV_TFHD_STSD_ID) {
4947  avio_wb32(pb, 1);
4948  }
4950  track->default_duration = get_cluster_duration(track, 0);
4951  avio_wb32(pb, track->default_duration);
4952  }
4953  if (flags & MOV_TFHD_DEFAULT_SIZE) {
4954  track->default_size = track->entry ? track->cluster[0].size : 1;
4955  avio_wb32(pb, track->default_size);
4956  } else
4957  track->default_size = -1;
4958 
4959  if (flags & MOV_TFHD_DEFAULT_FLAGS) {
4960  /* Set the default flags based on the second sample, if available.
4961  * If the first sample is different, that can be signaled via a separate field. */
4962  if (track->entry > 1)
4963  track->default_sample_flags = get_sample_flags(track, &track->cluster[1]);
4964  else
4965  track->default_sample_flags =
4966  track->par->codec_type == AVMEDIA_TYPE_VIDEO ?
4969  avio_wb32(pb, track->default_sample_flags);
4970  }
4971 
4972  return update_size(pb, pos);
4973 }
4974 
4976  MOVTrack *track, int moof_size,
4977  int first, int end)
4978 {
4979  int64_t pos = avio_tell(pb);
4980  uint32_t flags = MOV_TRUN_DATA_OFFSET;
4981  int i;
4982 
4983  for (i = first; i < end; i++) {
4984  if (get_cluster_duration(track, i) != track->default_duration)
4986  if (track->cluster[i].size != track->default_size)
4988  if (i > first && get_sample_flags(track, &track->cluster[i]) != track->default_sample_flags)
4990  }
4991  if (!(flags & MOV_TRUN_SAMPLE_FLAGS) && track->entry > first &&
4992  get_sample_flags(track, &track->cluster[first]) != track->default_sample_flags)
4994  if (track->flags & MOV_TRACK_CTTS)
4996 
4997  avio_wb32(pb, 0); /* size placeholder */
4998  ffio_wfourcc(pb, "trun");
5000  avio_w8(pb, 1); /* version */
5001  else
5002  avio_w8(pb, 0); /* version */
5003  avio_wb24(pb, flags);
5004 
5005  avio_wb32(pb, end - first); /* sample count */
5006  if (mov->flags & FF_MOV_FLAG_OMIT_TFHD_OFFSET &&
5008  !mov->first_trun)
5009  avio_wb32(pb, 0); /* Later tracks follow immediately after the previous one */
5010  else
5011  avio_wb32(pb, moof_size + 8 + track->data_offset +
5012  track->cluster[first].pos); /* data offset */
5014  avio_wb32(pb, get_sample_flags(track, &track->cluster[first]));
5015 
5016  for (i = first; i < end; i++) {
5018  avio_wb32(pb, get_cluster_duration(track, i));
5020  avio_wb32(pb, track->cluster[i].size);
5022  avio_wb32(pb, get_sample_flags(track, &track->cluster[i]));
5023  if (flags & MOV_TRUN_SAMPLE_CTS)
5024  avio_wb32(pb, track->cluster[i].cts);
5025  }
5026 
5027  mov->first_trun = 0;
5028  return update_size(pb, pos);
5029 }
5030 
5031 static int mov_write_tfxd_tag(AVIOContext *pb, MOVTrack *track)
5032 {
5033  int64_t pos = avio_tell(pb);
5034  static const uint8_t uuid[] = {
5035  0x6d, 0x1d, 0x9b, 0x05, 0x42, 0xd5, 0x44, 0xe6,
5036  0x80, 0xe2, 0x14, 0x1d, 0xaf, 0xf7, 0x57, 0xb2
5037  };
5038 
5039  avio_wb32(pb, 0); /* size placeholder */
5040  ffio_wfourcc(pb, "uuid");
5041  avio_write(pb, uuid, AV_UUID_LEN);
5042  avio_w8(pb, 1);
5043  avio_wb24(pb, 0);
5044  avio_wb64(pb, track->cluster[0].dts + track->cluster[0].cts);
5045  avio_wb64(pb, track->end_pts -
5046  (track->cluster[0].dts + track->cluster[0].cts));
5047 
5048  return update_size(pb, pos);
5049 }
5050 
5052  MOVTrack *track, int entry)
5053 {
5054  int n = track->nb_frag_info - 1 - entry, i;
5055  int size = 8 + 16 + 4 + 1 + 16*n;
5056  static const uint8_t uuid[] = {
5057  0xd4, 0x80, 0x7e, 0xf2, 0xca, 0x39, 0x46, 0x95,
5058  0x8e, 0x54, 0x26, 0xcb, 0x9e, 0x46, 0xa7, 0x9f
5059  };
5060 
5061  if (entry < 0)
5062  return 0;
5063 
5064  avio_seek(pb, track->frag_info[entry].tfrf_offset, SEEK_SET);
5065  avio_wb32(pb, size);
5066  ffio_wfourcc(pb, "uuid");
5067  avio_write(pb, uuid, AV_UUID_LEN);
5068  avio_w8(pb, 1);
5069  avio_wb24(pb, 0);
5070  avio_w8(pb, n);
5071  for (i = 0; i < n; i++) {
5072  int index = entry + 1 + i;
5073  avio_wb64(pb, track->frag_info[index].time);
5074  avio_wb64(pb, track->frag_info[index].duration);
5075  }
5076  if (n < mov->ism_lookahead) {
5077  int free_size = 16 * (mov->ism_lookahead - n);
5078  avio_wb32(pb, free_size);
5079  ffio_wfourcc(pb, "free");
5080  ffio_fill(pb, 0, free_size - 8);
5081  }
5082 
5083  return 0;
5084 }
5085 
5087  MOVTrack *track)
5088 {
5089  int64_t pos = avio_tell(pb);
5090  int i;
5091  for (i = 0; i < mov->ism_lookahead; i++) {
5092  /* Update the tfrf tag for the last ism_lookahead fragments,
5093  * nb_frag_info - 1 is the next fragment to be written. */
5094  mov_write_tfrf_tag(pb, mov, track, track->nb_frag_info - 2 - i);
5095  }
5096  avio_seek(pb, pos, SEEK_SET);
5097  return 0;
5098 }
5099 
5100 static int mov_add_tfra_entries(AVIOContext *pb, MOVMuxContext *mov, int tracks,
5101  int size)
5102 {
5103  int i;
5104  for (i = 0; i < mov->nb_tracks; i++) {
5105  MOVTrack *track = &mov->tracks[i];
5107  if ((tracks >= 0 && i != tracks) || !track->entry)
5108  continue;
5109  track->nb_frag_info++;
5110  if (track->nb_frag_info >= track->frag_info_capacity) {
5111  unsigned new_capacity = track->nb_frag_info + MOV_FRAG_INFO_ALLOC_INCREMENT;
5112  if (av_reallocp_array(&track->frag_info,
5113  new_capacity,
5114  sizeof(*track->frag_info)))
5115  return AVERROR(ENOMEM);
5116  track->frag_info_capacity = new_capacity;
5117  }
5118  info = &track->frag_info[track->nb_frag_info - 1];
5119  info->offset = avio_tell(pb);
5120  info->size = size;
5121  // Try to recreate the original pts for the first packet
5122  // from the fields we have stored
5123  info->time = track->cluster[0].dts + track->cluster[0].cts;
5124  info->duration = track->end_pts -
5125  (track->cluster[0].dts + track->cluster[0].cts);
5126  // If the pts is less than zero, we will have trimmed
5127  // away parts of the media track using an edit list,
5128  // and the corresponding start presentation time is zero.
5129  if (info->time < 0) {
5130  info->duration += info->time;
5131  info->time = 0;
5132  }
5133  info->tfrf_offset = 0;
5134  mov_write_tfrf_tags(pb, mov, track);
5135  }
5136  return 0;
5137 }
5138 
5139 static void mov_prune_frag_info(MOVMuxContext *mov, int tracks, int max)
5140 {
5141  int i;
5142  for (i = 0; i < mov->nb_tracks; i++) {
5143  MOVTrack *track = &mov->tracks[i];
5144  if ((tracks >= 0 && i != tracks) || !track->entry)
5145  continue;
5146  if (track->nb_frag_info > max) {
5147  memmove(track->frag_info, track->frag_info + (track->nb_frag_info - max), max * sizeof(*track->frag_info));
5148  track->nb_frag_info = max;
5149  }
5150  }
5151 }
5152 
5153 static int mov_write_tfdt_tag(AVIOContext *pb, MOVTrack *track)
5154 {
5155  int64_t pos = avio_tell(pb);
5156 
5157  avio_wb32(pb, 0); /* size */
5158  ffio_wfourcc(pb, "tfdt");
5159  avio_w8(pb, 1); /* version */
5160  avio_wb24(pb, 0);
5161  avio_wb64(pb, track->cluster[0].dts - track->start_dts);
5162  return update_size(pb, pos);
5163 }
5164 
5166  MOVTrack *track, int64_t moof_offset,
5167  int moof_size)
5168 {
5169  int64_t pos = avio_tell(pb);
5170  int i, start = 0;
5171  avio_wb32(pb, 0); /* size placeholder */
5172  ffio_wfourcc(pb, "traf");
5173 
5174  mov_write_tfhd_tag(pb, mov, track, moof_offset);
5175  if (mov->mode != MODE_ISM)
5176  mov_write_tfdt_tag(pb, track);
5177  for (i = 1; i < track->entry; i++) {
5178  if (track->cluster[i].pos != track->cluster[i - 1].pos + track->cluster[i - 1].size) {
5179  mov_write_trun_tag(pb, mov, track, moof_size, start, i);
5180  start = i;
5181  }
5182  }
5183  mov_write_trun_tag(pb, mov, track, moof_size, start, track->entry);
5184  if (mov->mode == MODE_ISM) {
5185  mov_write_tfxd_tag(pb, track);
5186 
5187  if (mov->ism_lookahead) {
5188  int size = 16 + 4 + 1 + 16 * mov->ism_lookahead;
5189 
5190  if (track->nb_frag_info > 0) {
5191  MOVFragmentInfo *info = &track->frag_info[track->nb_frag_info - 1];
5192  if (!info->tfrf_offset)
5193  info->tfrf_offset = avio_tell(pb);
5194  }
5195  avio_wb32(pb, 8 + size);
5196  ffio_wfourcc(pb, "free");
5197  ffio_fill(pb, 0, size);
5198  }
5199  }
5200 
5201  return update_size(pb, pos);
5202 }
5203 
5205  int tracks, int moof_size)
5206 {
5207  int64_t pos = avio_tell(pb);
5208  int i;
5209 
5210  avio_wb32(pb, 0); /* size placeholder */
5211  ffio_wfourcc(pb, "moof");
5212  mov->first_trun = 1;
5213 
5214  mov_write_mfhd_tag(pb, mov);
5215  for (i = 0; i < mov->nb_tracks; i++) {
5216  MOVTrack *track = &mov->tracks[i];
5217  if (tracks >= 0 && i != tracks)
5218  continue;
5219  if (!track->entry)
5220  continue;
5221  mov_write_traf_tag(pb, mov, track, pos, moof_size);
5222  }
5223 
5224  return update_size(pb, pos);
5225 }
5226 
5228  MOVTrack *track, int ref_size, int total_sidx_size)
5229 {
5230  int64_t pos = avio_tell(pb), offset_pos, end_pos;
5231  int64_t presentation_time, duration, offset;
5232  unsigned starts_with_SAP;
5233  int i, entries;
5234 
5235  if (track->entry) {
5236  entries = 1;
5237  presentation_time = track->cluster[0].dts + track->cluster[0].cts -
5238  track->start_dts - track->start_cts;
5239  duration = track->end_pts -
5240  (track->cluster[0].dts + track->cluster[0].cts);
5241  starts_with_SAP = track->cluster[0].flags & MOV_SYNC_SAMPLE;
5242 
5243  // pts<0 should be cut away using edts
5244  if (presentation_time < 0) {
5245  duration += presentation_time;
5246  presentation_time = 0;
5247  }
5248  } else {
5249  entries = track->nb_frag_info;
5250  if (entries <= 0)
5251  return 0;
5252  presentation_time = track->frag_info[0].time;
5253  /* presentation_time <= 0 is handled by mov_add_tfra_entries() */
5254  if (presentation_time > 0)
5255  presentation_time -= track->start_dts + track->start_cts;
5256  }
5257 
5258  avio_wb32(pb, 0); /* size */
5259  ffio_wfourcc(pb, "sidx");
5260  avio_w8(pb, 1); /* version */
5261  avio_wb24(pb, 0);
5262  avio_wb32(pb, track->track_id); /* reference_ID */
5263  avio_wb32(pb, track->timescale); /* timescale */
5264  avio_wb64(pb, presentation_time); /* earliest_presentation_time */
5265  offset_pos = avio_tell(pb);
5266  avio_wb64(pb, 0); /* first_offset (offset to referenced moof) */
5267  avio_wb16(pb, 0); /* reserved */
5268 
5269  avio_wb16(pb, entries); /* reference_count */
5270  for (i = 0; i < entries; i++) {
5271  if (!track->entry) {
5272  if (i > 1 && track->frag_info[i].offset != track->frag_info[i - 1].offset + track->frag_info[i - 1].size) {
5273  av_log(NULL, AV_LOG_ERROR, "Non-consecutive fragments, writing incorrect sidx\n");
5274  }
5275  duration = track->frag_info[i].duration;
5276  ref_size = track->frag_info[i].size;
5277  starts_with_SAP = 1;
5278  }
5279  avio_wb32(pb, (0 << 31) | (ref_size & 0x7fffffff)); /* reference_type (0 = media) | referenced_size */
5280  avio_wb32(pb, duration); /* subsegment_duration */
5281  avio_wb32(pb, (starts_with_SAP << 31) | (0 << 28) | 0); /* starts_with_SAP | SAP_type | SAP_delta_time */
5282  }
5283 
5284  end_pos = avio_tell(pb);
5285  offset = pos + total_sidx_size - end_pos;
5286  avio_seek(pb, offset_pos, SEEK_SET);
5287  avio_wb64(pb, offset);
5288  avio_seek(pb, end_pos, SEEK_SET);
5289  return update_size(pb, pos);
5290 }
5291 
5293  int tracks, int ref_size)
5294 {
5295  int i, round, ret;
5296  AVIOContext *avio_buf;
5297  int total_size = 0;
5298  for (round = 0; round < 2; round++) {
5299  // First run one round to calculate the total size of all
5300  // sidx atoms.
5301  // This would be much simpler if we'd only write one sidx
5302  // atom, for the first track in the moof.
5303  if (round == 0) {
5304  if ((ret = ffio_open_null_buf(&avio_buf)) < 0)
5305  return ret;
5306  } else {
5307  avio_buf = pb;
5308  }
5309  for (i = 0; i < mov->nb_tracks; i++) {
5310  MOVTrack *track = &mov->tracks[i];
5311  if (tracks >= 0 && i != tracks)
5312  continue;
5313  // When writing a sidx for the full file, entry is 0, but
5314  // we want to include all tracks. ref_size is 0 in this case,
5315  // since we read it from frag_info instead.
5316  if (!track->entry && ref_size > 0)
5317  continue;
5318  total_size -= mov_write_sidx_tag(avio_buf, track, ref_size,
5319  total_size);
5320  }
5321  if (round == 0)
5322  total_size = ffio_close_null_buf(avio_buf);
5323  }
5324  return 0;
5325 }
5326 
5327 static int mov_write_prft_tag(AVIOContext *pb, MOVMuxContext *mov, int tracks)
5328 {
5329  int64_t pos = avio_tell(pb), pts_us, ntp_ts;
5330  MOVTrack *first_track;
5331  int flags = 24;
5332 
5333  /* PRFT should be associated with at most one track. So, choosing only the
5334  * first track. */
5335  if (tracks > 0)
5336  return 0;
5337  first_track = &(mov->tracks[0]);
5338 
5339  if (!first_track->entry) {
5340  av_log(mov->fc, AV_LOG_WARNING, "Unable to write PRFT, no entries in the track\n");
5341  return 0;
5342  }
5343 
5344  if (first_track->cluster[0].pts == AV_NOPTS_VALUE) {
5345  av_log(mov->fc, AV_LOG_WARNING, "Unable to write PRFT, first PTS is invalid\n");
5346  return 0;
5347  }
5348 
5349  if (mov->write_prft == MOV_PRFT_SRC_WALLCLOCK) {
5350  if (first_track->cluster[0].prft.wallclock) {
5351  /* Round the NTP time to whole milliseconds. */
5352  ntp_ts = ff_get_formatted_ntp_time((first_track->cluster[0].prft.wallclock / 1000) * 1000 +
5353  NTP_OFFSET_US);
5354  flags = first_track->cluster[0].prft.flags;
5355  } else
5357  } else if (mov->write_prft == MOV_PRFT_SRC_PTS) {
5358  pts_us = av_rescale_q(first_track->cluster[0].pts,
5359  first_track->st->time_base, AV_TIME_BASE_Q);
5360  ntp_ts = ff_get_formatted_ntp_time(pts_us + NTP_OFFSET_US);
5361  } else {
5362  av_log(mov->fc, AV_LOG_WARNING, "Unsupported PRFT box configuration: %d\n",
5363  mov->write_prft);
5364  return 0;
5365  }
5366 
5367  avio_wb32(pb, 0); // Size place holder
5368  ffio_wfourcc(pb, "prft"); // Type
5369  avio_w8(pb, 1); // Version
5370  avio_wb24(pb, flags); // Flags
5371  avio_wb32(pb, first_track->track_id); // reference track ID
5372  avio_wb64(pb, ntp_ts); // NTP time stamp
5373  avio_wb64(pb, first_track->cluster[0].pts); //media time
5374  return update_size(pb, pos);
5375 }
5376 
5377 static int mov_write_moof_tag(AVIOContext *pb, MOVMuxContext *mov, int tracks,
5378  int64_t mdat_size)
5379 {
5380  AVIOContext *avio_buf;
5381  int ret, moof_size;
5382 
5383  if ((ret = ffio_open_null_buf(&avio_buf)) < 0)
5384  return ret;
5385  mov_write_moof_tag_internal(avio_buf, mov, tracks, 0);
5386  moof_size = ffio_close_null_buf(avio_buf);
5387 
5388  if (mov->flags & FF_MOV_FLAG_DASH &&
5390  mov_write_sidx_tags(pb, mov, tracks, moof_size + 8 + mdat_size);
5391 
5392  if (mov->write_prft > MOV_PRFT_NONE && mov->write_prft < MOV_PRFT_NB)
5393  mov_write_prft_tag(pb, mov, tracks);
5394 
5395  if (mov->flags & FF_MOV_FLAG_GLOBAL_SIDX ||
5396  !(mov->flags & FF_MOV_FLAG_SKIP_TRAILER) ||
5397  mov->ism_lookahead) {
5398  if ((ret = mov_add_tfra_entries(pb, mov, tracks, moof_size + 8 + mdat_size)) < 0)
5399  return ret;
5400  if (!(mov->flags & FF_MOV_FLAG_GLOBAL_SIDX) &&
5402  mov_prune_frag_info(mov, tracks, mov->ism_lookahead + 1);
5403  }
5404  }
5405 
5406  return mov_write_moof_tag_internal(pb, mov, tracks, moof_size);
5407 }
5408 
5409 static int mov_write_tfra_tag(AVIOContext *pb, MOVTrack *track)
5410 {
5411  int64_t pos = avio_tell(pb);
5412  int i;
5413 
5414  avio_wb32(pb, 0); /* size placeholder */
5415  ffio_wfourcc(pb, "tfra");
5416  avio_w8(pb, 1); /* version */
5417  avio_wb24(pb, 0);
5418 
5419  avio_wb32(pb, track->track_id);
5420  avio_wb32(pb, 0); /* length of traf/trun/sample num */
5421  avio_wb32(pb, track->nb_frag_info);
5422  for (i = 0; i < track->nb_frag_info; i++) {
5423  avio_wb64(pb, track->frag_info[i].time);
5424  avio_wb64(pb, track->frag_info[i].offset + track->data_offset);
5425  avio_w8(pb, 1); /* traf number */
5426  avio_w8(pb, 1); /* trun number */
5427  avio_w8(pb, 1); /* sample number */
5428  }
5429 
5430  return update_size(pb, pos);
5431 }
5432 
5434 {
5435  AVIOContext *mfra_pb;
5436  int i, ret, sz;
5437  uint8_t *buf;
5438 
5439  ret = avio_open_dyn_buf(&mfra_pb);
5440  if (ret < 0)
5441  return ret;
5442 
5443  avio_wb32(mfra_pb, 0); /* size placeholder */
5444  ffio_wfourcc(mfra_pb, "mfra");
5445  /* An empty mfra atom is enough to indicate to the publishing point that
5446  * the stream has ended. */
5447  if (mov->flags & FF_MOV_FLAG_ISML)
5448  goto done_mfra;
5449 
5450  for (i = 0; i < mov->nb_tracks; i++) {
5451  MOVTrack *track = &mov->tracks[i];
5452  if (track->nb_frag_info)
5453  mov_write_tfra_tag(mfra_pb, track);
5454  }
5455 
5456  avio_wb32(mfra_pb, 16);
5457  ffio_wfourcc(mfra_pb, "mfro");
5458  avio_wb32(mfra_pb, 0); /* version + flags */
5459  avio_wb32(mfra_pb, avio_tell(mfra_pb) + 4);
5460 
5461 done_mfra:
5462 
5463  sz = update_size(mfra_pb, 0);
5464  ret = avio_get_dyn_buf(mfra_pb, &buf);
5465  avio_write(pb, buf, ret);
5466  ffio_free_dyn_buf(&mfra_pb);
5467 
5468  return sz;
5469 }
5470 
5472 {
5473  avio_wb32(pb, 8); // placeholder for extended size field (64 bit)
5474  ffio_wfourcc(pb, mov->mode == MODE_MOV ? "wide" : "free");
5475 
5476  mov->mdat_pos = avio_tell(pb);
5477  avio_wb32(pb, 0); /* size placeholder*/
5478  ffio_wfourcc(pb, "mdat");
5479  return 0;
5480 }
5481 
5483  int has_h264, int has_video, int write_minor)
5484 {
5485  MOVMuxContext *mov = s->priv_data;
5486  int minor = 0x200;
5487 
5488  if (mov->major_brand && strlen(mov->major_brand) >= 4)
5489  ffio_wfourcc(pb, mov->major_brand);
5490  else if (mov->mode == MODE_3GP) {
5491  ffio_wfourcc(pb, has_h264 ? "3gp6" : "3gp4");
5492  minor = has_h264 ? 0x100 : 0x200;
5493  } else if (mov->mode == MODE_AVIF) {
5494  ffio_wfourcc(pb, mov->is_animated_avif ? "avis" : "avif");
5495  minor = 0;
5496  } else if (mov->mode & MODE_3G2) {
5497  ffio_wfourcc(pb, has_h264 ? "3g2b" : "3g2a");
5498  minor = has_h264 ? 0x20000 : 0x10000;
5499  } else if (mov->mode == MODE_PSP)
5500  ffio_wfourcc(pb, "MSNV");
5501  else if (mov->mode == MODE_MP4 && mov->flags & FF_MOV_FLAG_FRAGMENT &&
5503  ffio_wfourcc(pb, "iso6"); // Required when using signed CTS offsets in trun boxes
5504  else if (mov->mode == MODE_MP4 && mov->flags & FF_MOV_FLAG_DEFAULT_BASE_MOOF)
5505  ffio_wfourcc(pb, "iso5"); // Required when using default-base-is-moof
5506  else if (mov->mode == MODE_MP4 && mov->flags & FF_MOV_FLAG_NEGATIVE_CTS_OFFSETS)
5507  ffio_wfourcc(pb, "iso4");
5508  else if (mov->mode == MODE_MP4)
5509  ffio_wfourcc(pb, "isom");
5510  else if (mov->mode == MODE_IPOD)
5511  ffio_wfourcc(pb, has_video ? "M4V ":"M4A ");
5512  else if (mov->mode == MODE_ISM)
5513  ffio_wfourcc(pb, "isml");
5514  else if (mov->mode == MODE_F4V)
5515  ffio_wfourcc(pb, "f4v ");
5516  else
5517  ffio_wfourcc(pb, "qt ");
5518 
5519  if (write_minor)
5520  avio_wb32(pb, minor);
5521 }
5522 
5524 {
5525  MOVMuxContext *mov = s->priv_data;
5526  int64_t pos = avio_tell(pb);
5527  int has_h264 = 0, has_av1 = 0, has_video = 0, has_dolby = 0, has_id3 = 0;
5528  int has_iamf = 0;
5529 
5530 #if CONFIG_IAMFENC
5531  for (int i = 0; i < s->nb_stream_groups; i++) {
5532  const AVStreamGroup *stg = s->stream_groups[i];
5533 
5536  has_iamf = 1;
5537  break;
5538  }
5539  }
5540 #endif
5541  for (int i = 0; i < mov->nb_streams; i++) {
5542  AVStream *st = mov->tracks[i].st;
5543  if (is_cover_image(st))
5544  continue;
5546  has_video = 1;
5547  if (st->codecpar->codec_id == AV_CODEC_ID_H264)
5548  has_h264 = 1;
5549  if (st->codecpar->codec_id == AV_CODEC_ID_AV1)
5550  has_av1 = 1;
5551  if (st->codecpar->codec_id == AV_CODEC_ID_AC3 ||
5557  has_dolby = 1;
5559  has_id3 = 1;
5560  }
5561 
5562  avio_wb32(pb, 0); /* size */
5563  ffio_wfourcc(pb, "ftyp");
5564 
5565  // Write major brand
5566  mov_write_ftyp_tag_internal(pb, s, has_h264, has_video, 1);
5567  // Write the major brand as the first compatible brand as well
5568  mov_write_ftyp_tag_internal(pb, s, has_h264, has_video, 0);
5569 
5570  // Write compatible brands, ensuring that we don't write the major brand as a
5571  // compatible brand a second time.
5572  if (mov->mode == MODE_ISM) {
5573  ffio_wfourcc(pb, "piff");
5574  } else if (mov->mode == MODE_AVIF) {
5575  const AVPixFmtDescriptor *pix_fmt_desc =
5576  av_pix_fmt_desc_get(s->streams[0]->codecpar->format);
5577  const int depth = pix_fmt_desc->comp[0].depth;
5578  if (mov->is_animated_avif) {
5579  // For animated AVIF, major brand is "avis". Add "avif" as a
5580  // compatible brand.
5581  ffio_wfourcc(pb, "avif");
5582  ffio_wfourcc(pb, "msf1");
5583  ffio_wfourcc(pb, "iso8");
5584  }
5585  ffio_wfourcc(pb, "mif1");
5586  ffio_wfourcc(pb, "miaf");
5587  if (depth == 8 || depth == 10) {
5588  // MA1B and MA1A brands are based on AV1 profile. Short hand for
5589  // computing that is based on chroma subsampling type. 420 chroma
5590  // subsampling is MA1B. 444 chroma subsampling is MA1A.
5591  if (!pix_fmt_desc->log2_chroma_w && !pix_fmt_desc->log2_chroma_h) {
5592  // 444 chroma subsampling.
5593  ffio_wfourcc(pb, "MA1A");
5594  } else {
5595  // 420 chroma subsampling.
5596  ffio_wfourcc(pb, "MA1B");
5597  }
5598  }
5599  } else if (mov->mode != MODE_MOV) {
5600  // We add tfdt atoms when fragmenting, signal this with the iso6 compatible
5601  // brand, if not already the major brand. This is compatible with users that
5602  // don't understand tfdt.
5603  if (mov->mode == MODE_MP4) {
5604  if (mov->flags & FF_MOV_FLAG_CMAF)
5605  ffio_wfourcc(pb, "cmfc");
5607  ffio_wfourcc(pb, "iso6");
5608  if (has_av1)
5609  ffio_wfourcc(pb, "av01");
5610  if (has_dolby)
5611  ffio_wfourcc(pb, "dby1");
5612  if (has_iamf)
5613  ffio_wfourcc(pb, "iamf");
5614  } else {
5615  if (mov->flags & FF_MOV_FLAG_FRAGMENT)
5616  ffio_wfourcc(pb, "iso6");
5618  ffio_wfourcc(pb, "iso5");
5619  else if (mov->flags & FF_MOV_FLAG_NEGATIVE_CTS_OFFSETS)
5620  ffio_wfourcc(pb, "iso4");
5621  }
5622  // Brands prior to iso5 can't be signaled when using default-base-is-moof
5623  if (!(mov->flags & FF_MOV_FLAG_DEFAULT_BASE_MOOF)) {
5624  // write isom for mp4 only if it it's not the major brand already.
5625  if (mov->mode != MODE_MP4 || mov->flags & FF_MOV_FLAG_NEGATIVE_CTS_OFFSETS)
5626  ffio_wfourcc(pb, "isom");
5627  ffio_wfourcc(pb, "iso2");
5628  if (has_h264)
5629  ffio_wfourcc(pb, "avc1");
5630  }
5631  }
5632 
5633  if (mov->mode == MODE_MP4)
5634  ffio_wfourcc(pb, "mp41");
5635 
5636  if (mov->flags & FF_MOV_FLAG_DASH && mov->flags & FF_MOV_FLAG_GLOBAL_SIDX)
5637  ffio_wfourcc(pb, "dash");
5638 
5639  if (has_id3)
5640  ffio_wfourcc(pb, "aid3");
5641 
5642  return update_size(pb, pos);
5643 }
5644 
5646 {
5647  AVStream *video_st = s->streams[0];
5648  AVCodecParameters *video_par = s->streams[0]->codecpar;
5649  AVCodecParameters *audio_par = s->streams[1]->codecpar;
5650  int audio_rate = audio_par->sample_rate;
5651  int64_t frame_rate = video_st->avg_frame_rate.den ?
5653  0;
5654  int audio_kbitrate = audio_par->bit_rate / 1000;
5655  int video_kbitrate = FFMIN(video_par->bit_rate / 1000, 800 - audio_kbitrate);
5656 
5657  if (frame_rate < 0 || frame_rate > INT32_MAX) {
5658  av_log(s, AV_LOG_ERROR, "Frame rate %f outside supported range\n", frame_rate / (double)0x10000);
5659  return AVERROR(EINVAL);
5660  }
5661 
5662  avio_wb32(pb, 0x94); /* size */
5663  ffio_wfourcc(pb, "uuid");
5664  ffio_wfourcc(pb, "PROF");
5665 
5666  avio_wb32(pb, 0x21d24fce); /* 96 bit UUID */
5667  avio_wb32(pb, 0xbb88695c);
5668  avio_wb32(pb, 0xfac9c740);
5669 
5670  avio_wb32(pb, 0x0); /* ? */
5671  avio_wb32(pb, 0x3); /* 3 sections ? */
5672 
5673  avio_wb32(pb, 0x14); /* size */
5674  ffio_wfourcc(pb, "FPRF");
5675  avio_wb32(pb, 0x0); /* ? */
5676  avio_wb32(pb, 0x0); /* ? */
5677  avio_wb32(pb, 0x0); /* ? */
5678 
5679  avio_wb32(pb, 0x2c); /* size */
5680  ffio_wfourcc(pb, "APRF"); /* audio */
5681  avio_wb32(pb, 0x0);
5682  avio_wb32(pb, 0x2); /* TrackID */
5683  ffio_wfourcc(pb, "mp4a");
5684  avio_wb32(pb, 0x20f);
5685  avio_wb32(pb, 0x0);
5686  avio_wb32(pb, audio_kbitrate);
5687  avio_wb32(pb, audio_kbitrate);
5688  avio_wb32(pb, audio_rate);
5689  avio_wb32(pb, audio_par->ch_layout.nb_channels);
5690 
5691  avio_wb32(pb, 0x34); /* size */
5692  ffio_wfourcc(pb, "VPRF"); /* video */
5693  avio_wb32(pb, 0x0);
5694  avio_wb32(pb, 0x1); /* TrackID */
5695  if (video_par->codec_id == AV_CODEC_ID_H264) {
5696  ffio_wfourcc(pb, "avc1");
5697  avio_wb16(pb, 0x014D);
5698  avio_wb16(pb, 0x0015);
5699  } else {
5700  ffio_wfourcc(pb, "mp4v");
5701  avio_wb16(pb, 0x0000);
5702  avio_wb16(pb, 0x0103);
5703  }
5704  avio_wb32(pb, 0x0);
5705  avio_wb32(pb, video_kbitrate);
5706  avio_wb32(pb, video_kbitrate);
5707  avio_wb32(pb, frame_rate);
5708  avio_wb32(pb, frame_rate);
5709  avio_wb16(pb, video_par->width);
5710  avio_wb16(pb, video_par->height);
5711  avio_wb32(pb, 0x010001); /* ? */
5712 
5713  return 0;
5714 }
5715 
5717 {
5718  MOVMuxContext *mov = s->priv_data;
5719  int i;
5720 
5721  mov_write_ftyp_tag(pb,s);
5722  if (mov->mode == MODE_PSP) {
5723  int video_streams_nb = 0, audio_streams_nb = 0, other_streams_nb = 0;
5724  for (i = 0; i < mov->nb_streams; i++) {
5725  AVStream *st = mov->tracks[i].st;
5726  if (is_cover_image(st))
5727  continue;
5729  video_streams_nb++;
5730  else if (st->codecpar->codec_type == AVMEDIA_TYPE_AUDIO)
5731  audio_streams_nb++;
5732  else
5733  other_streams_nb++;
5734  }
5735 
5736  if (video_streams_nb != 1 || audio_streams_nb != 1 || other_streams_nb) {
5737  av_log(s, AV_LOG_ERROR, "PSP mode need one video and one audio stream\n");
5738  return AVERROR(EINVAL);
5739  }
5740  return mov_write_uuidprof_tag(pb, s);
5741  }
5742  return 0;
5743 }
5744 
5745 static int mov_parse_mpeg2_frame(AVPacket *pkt, uint32_t *flags)
5746 {
5747  uint32_t c = -1;
5748  int i, closed_gop = 0;
5749 
5750  for (i = 0; i < pkt->size - 4; i++) {
5751  c = (c << 8) + pkt->data[i];
5752  if (c == 0x1b8) { // gop
5753  closed_gop = pkt->data[i + 4] >> 6 & 0x01;
5754  } else if (c == 0x100) { // pic
5755  int temp_ref = (pkt->data[i + 1] << 2) | (pkt->data[i + 2] >> 6);
5756  if (!temp_ref || closed_gop) // I picture is not reordered
5758  else
5760  break;
5761  }
5762  }
5763  return 0;
5764 }
5765 
5767 {
5768  const uint8_t *start, *next, *end = pkt->data + pkt->size;
5769  int seq = 0, entry = 0;
5770  int key = pkt->flags & AV_PKT_FLAG_KEY;
5771  start = find_next_marker(pkt->data, end);
5772  for (next = start; next < end; start = next) {
5773  next = find_next_marker(start + 4, end);
5774  switch (AV_RB32(start)) {
5775  case VC1_CODE_SEQHDR:
5776  seq = 1;
5777  break;
5778  case VC1_CODE_ENTRYPOINT:
5779  entry = 1;
5780  break;
5781  case VC1_CODE_SLICE:
5782  trk->vc1_info.slices = 1;
5783  break;
5784  }
5785  }
5786  if (!trk->entry && trk->vc1_info.first_packet_seen)
5787  trk->vc1_info.first_frag_written = 1;
5788  if (!trk->entry && !trk->vc1_info.first_frag_written) {
5789  /* First packet in first fragment */
5790  trk->vc1_info.first_packet_seq = seq;
5792  trk->vc1_info.first_packet_seen = 1;
5793  } else if ((seq && !trk->vc1_info.packet_seq) ||
5794  (entry && !trk->vc1_info.packet_entry)) {
5795  int i;
5796  for (i = 0; i < trk->entry; i++)
5797  trk->cluster[i].flags &= ~MOV_SYNC_SAMPLE;
5798  trk->has_keyframes = 0;
5799  if (seq)
5800  trk->vc1_info.packet_seq = 1;
5801  if (entry)
5802  trk->vc1_info.packet_entry = 1;
5803  if (!trk->vc1_info.first_frag_written) {
5804  /* First fragment */
5805  if ((!seq || trk->vc1_info.first_packet_seq) &&
5806  (!entry || trk->vc1_info.first_packet_entry)) {
5807  /* First packet had the same headers as this one, readd the
5808  * sync sample flag. */
5809  trk->cluster[0].flags |= MOV_SYNC_SAMPLE;
5810  trk->has_keyframes = 1;
5811  }
5812  }
5813  }
5814  if (trk->vc1_info.packet_seq && trk->vc1_info.packet_entry)
5815  key = seq && entry;
5816  else if (trk->vc1_info.packet_seq)
5817  key = seq;
5818  else if (trk->vc1_info.packet_entry)
5819  key = entry;
5820  if (key) {
5821  trk->cluster[trk->entry].flags |= MOV_SYNC_SAMPLE;
5822  trk->has_keyframes++;
5823  }
5824 }
5825 
5827 {
5828  int length;
5829 
5830  if (pkt->size < 8)
5831  return;
5832 
5833  length = (AV_RB16(pkt->data) & 0xFFF) * 2;
5834  if (length < 8 || length > pkt->size)
5835  return;
5836 
5837  if (AV_RB32(pkt->data + 4) == 0xF8726FBA) {
5838  trk->cluster[trk->entry].flags |= MOV_SYNC_SAMPLE;
5839  trk->has_keyframes++;
5840  }
5841 
5842  return;
5843 }
5844 
5846 {
5847  MOVMuxContext *mov = s->priv_data;
5848  int ret, buf_size;
5849  uint8_t *buf;
5850  int i, offset;
5851 
5852  if (!track->mdat_buf)
5853  return 0;
5854  if (!mov->mdat_buf) {
5855  if ((ret = avio_open_dyn_buf(&mov->mdat_buf)) < 0)
5856  return ret;
5857  }
5858  buf_size = avio_get_dyn_buf(track->mdat_buf, &buf);
5859 
5860  offset = avio_tell(mov->mdat_buf);
5861  avio_write(mov->mdat_buf, buf, buf_size);
5862  ffio_free_dyn_buf(&track->mdat_buf);
5863 
5864  for (i = track->entries_flushed; i < track->entry; i++)
5865  track->cluster[i].pos += offset;
5866  track->entries_flushed = track->entry;
5867  return 0;
5868 }
5869 
5871 {
5872  MOVMuxContext *mov = s->priv_data;
5873  AVPacket *squashed_packet = mov->pkt;
5874  int ret = AVERROR_BUG;
5875 
5876  switch (track->st->codecpar->codec_id) {
5877  case AV_CODEC_ID_TTML: {
5878  int had_packets = !!track->squashed_packet_queue.head;
5879 
5880  if ((ret = ff_mov_generate_squashed_ttml_packet(s, track, squashed_packet)) < 0) {
5881  goto finish_squash;
5882  }
5883 
5884  // We have generated a padding packet (no actual input packets in
5885  // queue) and its duration is zero. Skipping writing it.
5886  if (!had_packets && squashed_packet->duration == 0) {
5887  goto finish_squash;
5888  }
5889 
5890  track->end_reliable = 1;
5891  break;
5892  }
5893  default:
5894  ret = AVERROR(EINVAL);
5895  goto finish_squash;
5896  }
5897 
5898  squashed_packet->stream_index = track->st->index;
5899 
5900  ret = mov_write_single_packet(s, squashed_packet);
5901 
5902 finish_squash:
5903  av_packet_unref(squashed_packet);
5904 
5905  return ret;
5906 }
5907 
5909 {
5910  MOVMuxContext *mov = s->priv_data;
5911 
5912  for (int i = 0; i < mov->nb_streams; i++) {
5913  MOVTrack *track = &mov->tracks[i];
5914  int ret = AVERROR_BUG;
5915 
5916  if (track->squash_fragment_samples_to_one && !track->entry) {
5917  if ((ret = mov_write_squashed_packet(s, track)) < 0) {
5919  "Failed to write squashed packet for %s stream with "
5920  "index %d and track id %d. Error: %s\n",
5922  track->st->index, track->track_id,
5923  av_err2str(ret));
5924  return ret;
5925  }
5926  }
5927  }
5928 
5929  return 0;
5930 }
5931 
5932 static int mov_flush_fragment(AVFormatContext *s, int force)
5933 {
5934  MOVMuxContext *mov = s->priv_data;
5935  int i, first_track = -1;
5936  int64_t mdat_size = 0;
5937  int ret;
5938  int has_video = 0, starts_with_key = 0, first_video_track = 1;
5939 
5940  if (!(mov->flags & FF_MOV_FLAG_FRAGMENT))
5941  return 0;
5942 
5943  // Check if we have any tracks that require squashing.
5944  // In that case, we'll have to write the packet here.
5945  if ((ret = mov_write_squashed_packets(s)) < 0)
5946  return ret;
5947 
5948  // Try to fill in the duration of the last packet in each stream
5949  // from queued packets in the interleave queues. If the flushing
5950  // of fragments was triggered automatically by an AVPacket, we
5951  // already have reliable info for the end of that track, but other
5952  // tracks may need to be filled in.
5953  for (i = 0; i < mov->nb_streams; i++) {
5954  MOVTrack *track = &mov->tracks[i];
5955  if (!track->end_reliable) {
5956  const AVPacket *pkt = ff_interleaved_peek(s, i);
5957  if (pkt) {
5958  int64_t offset, dts, pts;
5960  pts = pkt->pts + offset;
5961  dts = pkt->dts + offset;
5962  if (track->dts_shift != AV_NOPTS_VALUE)
5963  dts += track->dts_shift;
5964  track->track_duration = dts - track->start_dts;
5965  if (pts != AV_NOPTS_VALUE)
5966  track->end_pts = pts;
5967  else
5968  track->end_pts = dts;
5969  }
5970  }
5971  }
5972 
5973  for (i = 0; i < mov->nb_tracks; i++) {
5974  MOVTrack *track = &mov->tracks[i];
5975  if (track->entry <= 1)
5976  continue;
5977  // Sample durations are calculated as the diff of dts values,
5978  // but for the last sample in a fragment, we don't know the dts
5979  // of the first sample in the next fragment, so we have to rely
5980  // on what was set as duration in the AVPacket. Not all callers
5981  // set this though, so we might want to replace it with an
5982  // estimate if it currently is zero.
5983  if (get_cluster_duration(track, track->entry - 1) != 0)
5984  continue;
5985  // Use the duration (i.e. dts diff) of the second last sample for
5986  // the last one. This is a wild guess (and fatal if it turns out
5987  // to be too long), but probably the best we can do - having a zero
5988  // duration is bad as well.
5989  track->track_duration += get_cluster_duration(track, track->entry - 2);
5990  track->end_pts += get_cluster_duration(track, track->entry - 2);
5991  if (!mov->missing_duration_warned) {
5993  "Estimating the duration of the last packet in a "
5994  "fragment, consider setting the duration field in "
5995  "AVPacket instead.\n");
5996  mov->missing_duration_warned = 1;
5997  }
5998  }
5999 
6000  if (!mov->moov_written) {
6001  int64_t pos = avio_tell(s->pb);
6002  uint8_t *buf;
6003  int buf_size, moov_size;
6004 
6005  for (i = 0; i < mov->nb_tracks; i++)
6006  if (!mov->tracks[i].entry && !is_cover_image(mov->tracks[i].st))
6007  break;
6008  /* Don't write the initial moov unless all tracks have data */
6009  if (i < mov->nb_tracks && !force)
6010  return 0;
6011 
6012  moov_size = get_moov_size(s);
6013  for (i = 0; i < mov->nb_tracks; i++)
6014  mov->tracks[i].data_offset = pos + moov_size + 8;
6015 
6017  if (mov->flags & FF_MOV_FLAG_DELAY_MOOV)
6019  if ((ret = mov_write_moov_tag(s->pb, mov, s)) < 0)
6020  return ret;
6021 
6022  if (mov->flags & FF_MOV_FLAG_DELAY_MOOV) {
6023  if (mov->flags & FF_MOV_FLAG_GLOBAL_SIDX)
6024  mov->reserved_header_pos = avio_tell(s->pb);
6026  mov->moov_written = 1;
6027  return 0;
6028  }
6029 
6030  buf_size = avio_get_dyn_buf(mov->mdat_buf, &buf);
6031  avio_wb32(s->pb, buf_size + 8);
6032  ffio_wfourcc(s->pb, "mdat");
6033  avio_write(s->pb, buf, buf_size);
6034  ffio_free_dyn_buf(&mov->mdat_buf);
6035 
6036  if (mov->flags & FF_MOV_FLAG_GLOBAL_SIDX)
6037  mov->reserved_header_pos = avio_tell(s->pb);
6038 
6039  mov->moov_written = 1;
6040  mov->mdat_size = 0;
6041  for (i = 0; i < mov->nb_tracks; i++) {
6042  mov->tracks[i].entry = 0;
6043  mov->tracks[i].end_reliable = 0;
6044  }
6046  return 0;
6047  }
6048 
6049  if (mov->frag_interleave) {
6050  for (i = 0; i < mov->nb_tracks; i++) {
6051  MOVTrack *track = &mov->tracks[i];
6052  int ret;
6053  if ((ret = mov_flush_fragment_interleaving(s, track)) < 0)
6054  return ret;
6055  }
6056 
6057  if (!mov->mdat_buf)
6058  return 0;
6059  mdat_size = avio_tell(mov->mdat_buf);
6060  }
6061 
6062  for (i = 0; i < mov->nb_tracks; i++) {
6063  MOVTrack *track = &mov->tracks[i];
6064  if (mov->flags & FF_MOV_FLAG_SEPARATE_MOOF || mov->frag_interleave)
6065  track->data_offset = 0;
6066  else
6067  track->data_offset = mdat_size;
6068  if (track->par->codec_type == AVMEDIA_TYPE_VIDEO) {
6069  has_video = 1;
6070  if (first_video_track) {
6071  if (track->entry)
6072  starts_with_key = track->cluster[0].flags & MOV_SYNC_SAMPLE;
6073  first_video_track = 0;
6074  }
6075  }
6076  if (!track->entry)
6077  continue;
6078  if (track->mdat_buf)
6079  mdat_size += avio_tell(track->mdat_buf);
6080  if (first_track < 0)
6081  first_track = i;
6082  }
6083 
6084  if (!mdat_size)
6085  return 0;
6086 
6087  avio_write_marker(s->pb,
6088  av_rescale(mov->tracks[first_track].cluster[0].dts, AV_TIME_BASE, mov->tracks[first_track].timescale),
6089  (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);
6090 
6091  for (i = 0; i < mov->nb_tracks; i++) {
6092  MOVTrack *track = &mov->tracks[i];
6093  int buf_size, write_moof = 1, moof_tracks = -1;
6094  uint8_t *buf;
6095 
6096  if (mov->flags & FF_MOV_FLAG_SEPARATE_MOOF) {
6097  if (!track->entry)
6098  continue;
6099  mdat_size = avio_tell(track->mdat_buf);
6100  moof_tracks = i;
6101  } else {
6102  write_moof = i == first_track;
6103  }
6104 
6105  if (write_moof) {
6107 
6108  mov_write_moof_tag(s->pb, mov, moof_tracks, mdat_size);
6109  mov->fragments++;
6110 
6111  avio_wb32(s->pb, mdat_size + 8);
6112  ffio_wfourcc(s->pb, "mdat");
6113  }
6114 
6115  track->entry = 0;
6116  track->entries_flushed = 0;
6117  track->end_reliable = 0;
6118  if (!mov->frag_interleave) {
6119  if (!track->mdat_buf)
6120  continue;
6121  buf_size = avio_close_dyn_buf(track->mdat_buf, &buf);
6122  track->mdat_buf = NULL;
6123  } else {
6124  if (!mov->mdat_buf)
6125  continue;
6126  buf_size = avio_close_dyn_buf(mov->mdat_buf, &buf);
6127  mov->mdat_buf = NULL;
6128  }
6129 
6130  avio_write(s->pb, buf, buf_size);
6131  av_free(buf);
6132  }
6133 
6134  mov->mdat_size = 0;
6135 
6137  return 0;
6138 }
6139 
6141 {
6142  MOVMuxContext *mov = s->priv_data;
6143  int had_moov = mov->moov_written;
6144  int ret = mov_flush_fragment(s, force);
6145  if (ret < 0)
6146  return ret;
6147  // If using delay_moov, the first flush only wrote the moov,
6148  // not the actual moof+mdat pair, thus flush once again.
6149  if (!had_moov && mov->flags & FF_MOV_FLAG_DELAY_MOOV)
6150  ret = mov_flush_fragment(s, force);
6151  return ret;
6152 }
6153 
6155 {
6156  int64_t ref;
6157  uint64_t duration;
6158 
6159  if (trk->entry) {
6160  ref = trk->cluster[trk->entry - 1].dts;
6161  } else if ( trk->start_dts != AV_NOPTS_VALUE
6162  && !trk->frag_discont) {
6163  ref = trk->start_dts + trk->track_duration;
6164  } else
6165  ref = pkt->dts; // Skip tests for the first packet
6166 
6167  if (trk->dts_shift != AV_NOPTS_VALUE) {
6168  /* With negative CTS offsets we have set an offset to the DTS,
6169  * reverse this for the check. */
6170  ref -= trk->dts_shift;
6171  }
6172 
6173  duration = pkt->dts - ref;
6174  if (pkt->dts < ref || duration >= INT_MAX) {
6175  av_log(s, AV_LOG_WARNING, "Packet duration: %"PRId64" / dts: %"PRId64" is out of range\n",
6176  duration, pkt->dts);
6177 
6178  pkt->dts = ref + 1;
6179  pkt->pts = AV_NOPTS_VALUE;
6180  }
6181 
6182  if (pkt->duration < 0 || pkt->duration > INT_MAX) {
6183  av_log(s, AV_LOG_ERROR, "Application provided duration: %"PRId64" is invalid\n", pkt->duration);
6184  return AVERROR(EINVAL);
6185  }
6186  return 0;
6187 }
6188 
6190 {
6191  MOVMuxContext *mov = s->priv_data;
6192  AVIOContext *pb = s->pb;
6193  MOVTrack *trk;
6194  AVCodecParameters *par;
6196  unsigned int samples_in_chunk = 0;
6197  int size = pkt->size, ret = 0, offset = 0;
6198  size_t prft_size;
6199  uint8_t *reformatted_data = NULL;
6200 
6201  if (pkt->stream_index < s->nb_streams)
6202  trk = s->streams[pkt->stream_index]->priv_data;
6203  else // Timecode or chapter
6204  trk = &mov->tracks[pkt->stream_index];
6205  par = trk->par;
6206 
6207  ret = check_pkt(s, trk, pkt);
6208  if (ret < 0)
6209  return ret;
6210 
6211  if (pkt->pts != AV_NOPTS_VALUE &&
6212  (uint64_t)pkt->dts - pkt->pts != (int32_t)((uint64_t)pkt->dts - pkt->pts)) {
6213  av_log(s, AV_LOG_WARNING, "pts/dts pair unsupported\n");
6214  return AVERROR_PATCHWELCOME;
6215  }
6216 
6217  if (mov->flags & FF_MOV_FLAG_FRAGMENT || mov->mode == MODE_AVIF) {
6218  int ret;
6219  if (mov->moov_written || mov->flags & FF_MOV_FLAG_EMPTY_MOOV) {
6220  if (mov->frag_interleave && mov->fragments > 0) {
6221  if (trk->entry - trk->entries_flushed >= mov->frag_interleave) {
6222  if ((ret = mov_flush_fragment_interleaving(s, trk)) < 0)
6223  return ret;
6224  }
6225  }
6226 
6227  if (!trk->mdat_buf) {
6228  if ((ret = avio_open_dyn_buf(&trk->mdat_buf)) < 0)
6229  return ret;
6230  }
6231  pb = trk->mdat_buf;
6232  } else {
6233  if (!mov->mdat_buf) {
6234  if ((ret = avio_open_dyn_buf(&mov->mdat_buf)) < 0)
6235  return ret;
6236  }
6237  pb = mov->mdat_buf;
6238  }
6239  }
6240 
6241  if (par->codec_id == AV_CODEC_ID_AMR_NB) {
6242  /* We must find out how many AMR blocks there are in one packet */
6243  static const uint16_t packed_size[16] =
6244  {13, 14, 16, 18, 20, 21, 27, 32, 6, 0, 0, 0, 0, 0, 0, 1};
6245  int len = 0;
6246 
6247  while (len < size && samples_in_chunk < 100) {
6248  len += packed_size[(pkt->data[len] >> 3) & 0x0F];
6249  samples_in_chunk++;
6250  }
6251  if (samples_in_chunk > 1) {
6252  av_log(s, AV_LOG_ERROR, "fatal error, input is not a single packet, implement a AVParser for it\n");
6253  return -1;
6254  }
6255  } else if (par->codec_id == AV_CODEC_ID_ADPCM_MS ||
6257  samples_in_chunk = trk->par->frame_size;
6258  } else if (trk->sample_size)
6259  samples_in_chunk = size / trk->sample_size;
6260  else
6261  samples_in_chunk = 1;
6262 
6263  if (samples_in_chunk < 1) {
6264  av_log(s, AV_LOG_ERROR, "fatal error, input packet contains no samples\n");
6265  return AVERROR_PATCHWELCOME;
6266  }
6267 
6268  /* copy extradata if it exists */
6269  if (trk->vos_len == 0 && par->extradata_size > 0 &&
6270  !TAG_IS_AVCI(trk->tag) &&
6271  (par->codec_id != AV_CODEC_ID_DNXHD)) {
6272  trk->vos_len = par->extradata_size;
6274  if (!trk->vos_data) {
6275  ret = AVERROR(ENOMEM);
6276  goto err;
6277  }
6278  memcpy(trk->vos_data, par->extradata, trk->vos_len);
6279  memset(trk->vos_data + trk->vos_len, 0, AV_INPUT_BUFFER_PADDING_SIZE);
6280  }
6281 
6282  if ((par->codec_id == AV_CODEC_ID_DNXHD ||
6283  par->codec_id == AV_CODEC_ID_H264 ||
6284  par->codec_id == AV_CODEC_ID_HEVC ||
6285  par->codec_id == AV_CODEC_ID_VVC ||
6286  par->codec_id == AV_CODEC_ID_VP9 ||
6287  par->codec_id == AV_CODEC_ID_EVC ||
6288  par->codec_id == AV_CODEC_ID_TRUEHD) && !trk->vos_len &&
6289  !TAG_IS_AVCI(trk->tag)) {
6290  /* copy frame to create needed atoms */
6291  trk->vos_len = size;
6293  if (!trk->vos_data) {
6294  ret = AVERROR(ENOMEM);
6295  goto err;
6296  }
6297  memcpy(trk->vos_data, pkt->data, size);
6298  memset(trk->vos_data + size, 0, AV_INPUT_BUFFER_PADDING_SIZE);
6299  }
6300 
6301  if (par->codec_id == AV_CODEC_ID_AAC && pkt->size > 2 &&
6302  (AV_RB16(pkt->data) & 0xfff0) == 0xfff0) {
6303  if (!trk->st->nb_frames) {
6304  av_log(s, AV_LOG_ERROR, "Malformed AAC bitstream detected: "
6305  "use the audio bitstream filter 'aac_adtstoasc' to fix it "
6306  "('-bsf:a aac_adtstoasc' option with ffmpeg)\n");
6307  return -1;
6308  }
6309  av_log(s, AV_LOG_WARNING, "aac bitstream error\n");
6310  }
6311  if (par->codec_id == AV_CODEC_ID_H264 && trk->vos_len > 0 && *(uint8_t *)trk->vos_data != 1 && !TAG_IS_AVCI(trk->tag)) {
6312  /* from x264 or from bytestream H.264 */
6313  /* NAL reformatting needed */
6314  if (trk->hint_track >= 0 && trk->hint_track < mov->nb_tracks) {
6315  ret = ff_avc_parse_nal_units_buf(pkt->data, &reformatted_data,
6316  &size);
6317  if (ret < 0)
6318  return ret;
6319  avio_write(pb, reformatted_data, size);
6320  } else {
6321  if (trk->cenc.aes_ctr) {
6323  if (size < 0) {
6324  ret = size;
6325  goto err;
6326  }
6327  } else {
6329  }
6330  }
6331  } else if (par->codec_id == AV_CODEC_ID_HEVC && trk->vos_len > 6 &&
6332  (AV_RB24(trk->vos_data) == 1 || AV_RB32(trk->vos_data) == 1)) {
6333  /* extradata is Annex B, assume the bitstream is too and convert it */
6334  if (trk->hint_track >= 0 && trk->hint_track < mov->nb_tracks) {
6335  ret = ff_hevc_annexb2mp4_buf(pkt->data, &reformatted_data,
6336  &size, 0, NULL);
6337  if (ret < 0)
6338  return ret;
6339  avio_write(pb, reformatted_data, size);
6340  } else {
6341  if (trk->cenc.aes_ctr) {
6343  if (size < 0) {
6344  ret = size;
6345  goto err;
6346  }
6347  } else {
6348  size = ff_hevc_annexb2mp4(pb, pkt->data, pkt->size, 0, NULL);
6349  }
6350  }
6351  } else if (par->codec_id == AV_CODEC_ID_VVC && trk->vos_len > 6 &&
6352  (AV_RB24(trk->vos_data) == 1 || AV_RB32(trk->vos_data) == 1)) {
6353  /* extradata is Annex B, assume the bitstream is too and convert it */
6354  if (trk->hint_track >= 0 && trk->hint_track < mov->nb_tracks) {
6355  ret = ff_vvc_annexb2mp4_buf(pkt->data, &reformatted_data,
6356  &size, 0, NULL);
6357  if (ret < 0)
6358  return ret;
6359  avio_write(pb, reformatted_data, size);
6360  } else {
6361  size = ff_vvc_annexb2mp4(pb, pkt->data, pkt->size, 0, NULL);
6362  }
6363  } else if (par->codec_id == AV_CODEC_ID_AV1) {
6364  if (trk->hint_track >= 0 && trk->hint_track < mov->nb_tracks) {
6365  ret = ff_av1_filter_obus_buf(pkt->data, &reformatted_data,
6366  &size, &offset);
6367  if (ret < 0)
6368  return ret;
6369  avio_write(pb, reformatted_data, size);
6370  } else {
6371  size = ff_av1_filter_obus(pb, pkt->data, pkt->size);
6372  if (trk->mode == MODE_AVIF && !mov->avif_extent_length[pkt->stream_index]) {
6374  }
6375  }
6376 
6377  } else if (par->codec_id == AV_CODEC_ID_AC3 ||
6378  par->codec_id == AV_CODEC_ID_EAC3) {
6379  size = handle_eac3(mov, pkt, trk);
6380  if (size < 0)
6381  return size;
6382  else if (!size)
6383  goto end;
6384  avio_write(pb, pkt->data, size);
6385  } else if (par->codec_id == AV_CODEC_ID_EIA_608) {
6386  size = 8;
6387 
6388  for (int i = 0; i < pkt->size; i += 3) {
6389  if (pkt->data[i] == 0xFC) {
6390  size += 2;
6391  }
6392  }
6393  avio_wb32(pb, size);
6394  ffio_wfourcc(pb, "cdat");
6395  for (int i = 0; i < pkt->size; i += 3) {
6396  if (pkt->data[i] == 0xFC) {
6397  avio_w8(pb, pkt->data[i + 1]);
6398  avio_w8(pb, pkt->data[i + 2]);
6399  }
6400  }
6401  } else {
6402  if (trk->cenc.aes_ctr) {
6403  if (par->codec_id == AV_CODEC_ID_H264 && par->extradata_size > 4) {
6404  int nal_size_length = (par->extradata[4] & 0x3) + 1;
6405  ret = ff_mov_cenc_avc_write_nal_units(s, &trk->cenc, nal_size_length, pb, pkt->data, size);
6406  } else if(par->codec_id == AV_CODEC_ID_HEVC && par->extradata_size > 21) {
6407  int nal_size_length = (par->extradata[21] & 0x3) + 1;
6408  ret = ff_mov_cenc_avc_write_nal_units(s, &trk->cenc, nal_size_length, pb, pkt->data, size);
6409  } else if(par->codec_id == AV_CODEC_ID_VVC) {
6411  } else {
6412  ret = ff_mov_cenc_write_packet(&trk->cenc, pb, pkt->data, size);
6413  }
6414 
6415  if (ret) {
6416  goto err;
6417  }
6418  } else {
6419  avio_write(pb, pkt->data, size);
6420  }
6421  }
6422 
6423  if (trk->entry >= trk->cluster_capacity) {
6424  unsigned new_capacity = trk->entry + MOV_INDEX_CLUSTER_SIZE;
6425  void *cluster = av_realloc_array(trk->cluster, new_capacity, sizeof(*trk->cluster));
6426  if (!cluster) {
6427  ret = AVERROR(ENOMEM);
6428  goto err;
6429  }
6430  trk->cluster = cluster;
6431  trk->cluster_capacity = new_capacity;
6432  }
6433 
6434  trk->cluster[trk->entry].pos = avio_tell(pb) - size;
6435  trk->cluster[trk->entry].samples_in_chunk = samples_in_chunk;
6436  trk->cluster[trk->entry].chunkNum = 0;
6437  trk->cluster[trk->entry].size = size;
6438  trk->cluster[trk->entry].entries = samples_in_chunk;
6439  trk->cluster[trk->entry].dts = pkt->dts;
6440  trk->cluster[trk->entry].pts = pkt->pts;
6441  if (!trk->squash_fragment_samples_to_one &&
6442  !trk->entry && trk->start_dts != AV_NOPTS_VALUE) {
6443  if (!trk->frag_discont) {
6444  /* First packet of a new fragment. We already wrote the duration
6445  * of the last packet of the previous fragment based on track_duration,
6446  * which might not exactly match our dts. Therefore adjust the dts
6447  * of this packet to be what the previous packets duration implies. */
6448  trk->cluster[trk->entry].dts = trk->start_dts + trk->track_duration;
6449  /* We also may have written the pts and the corresponding duration
6450  * in sidx/tfrf/tfxd tags; make sure the sidx pts and duration match up with
6451  * the next fragment. This means the cts of the first sample must
6452  * be the same in all fragments, unless end_pts was updated by
6453  * the packet causing the fragment to be written. */
6454  if ((mov->flags & FF_MOV_FLAG_DASH &&
6456  mov->mode == MODE_ISM)
6457  pkt->pts = pkt->dts + trk->end_pts - trk->cluster[trk->entry].dts;
6458  } else {
6459  /* New fragment, but discontinuous from previous fragments.
6460  * Pretend the duration sum of the earlier fragments is
6461  * pkt->dts - trk->start_dts. */
6462  trk->end_pts = AV_NOPTS_VALUE;
6463  trk->frag_discont = 0;
6464  }
6465  }
6466 
6467  if (!trk->entry && trk->start_dts == AV_NOPTS_VALUE && !mov->use_editlist &&
6468  s->avoid_negative_ts == AVFMT_AVOID_NEG_TS_MAKE_ZERO) {
6469  /* Not using edit lists and shifting the first track to start from zero.
6470  * If the other streams start from a later timestamp, we won't be able
6471  * to signal the difference in starting time without an edit list.
6472  * Thus move the timestamp for this first sample to 0, increasing
6473  * its duration instead. */
6474  trk->cluster[trk->entry].dts = trk->start_dts = 0;
6475  }
6476  if (trk->start_dts == AV_NOPTS_VALUE) {
6477  trk->start_dts = pkt->dts;
6478  if (trk->frag_discont) {
6479  if (mov->use_editlist) {
6480  /* Pretend the whole stream started at pts=0, with earlier fragments
6481  * already written. If the stream started at pts=0, the duration sum
6482  * of earlier fragments would have been pkt->pts. */
6483  trk->start_dts = pkt->dts - pkt->pts;
6484  } else {
6485  /* Pretend the whole stream started at dts=0, with earlier fragments
6486  * already written, with a duration summing up to pkt->dts. */
6487  trk->start_dts = 0;
6488  }
6489  trk->frag_discont = 0;
6490  } else if (pkt->dts && mov->moov_written)
6492  "Track %d starts with a nonzero dts %"PRId64", while the moov "
6493  "already has been written. Set the delay_moov flag to handle "
6494  "this case.\n",
6495  pkt->stream_index, pkt->dts);
6496  }
6497  trk->track_duration = pkt->dts - trk->start_dts + pkt->duration;
6498  trk->last_sample_is_subtitle_end = 0;
6499 
6500  if (pkt->pts == AV_NOPTS_VALUE) {
6501  av_log(s, AV_LOG_WARNING, "pts has no value\n");
6502  pkt->pts = pkt->dts;
6503  }
6504  if (pkt->dts != pkt->pts)
6505  trk->flags |= MOV_TRACK_CTTS;
6506  trk->cluster[trk->entry].cts = pkt->pts - pkt->dts;
6507  trk->cluster[trk->entry].flags = 0;
6508  if (trk->start_cts == AV_NOPTS_VALUE)
6509  trk->start_cts = pkt->pts - pkt->dts;
6510  if (trk->end_pts == AV_NOPTS_VALUE)
6511  trk->end_pts = trk->cluster[trk->entry].dts +
6512  trk->cluster[trk->entry].cts + pkt->duration;
6513  else
6514  trk->end_pts = FFMAX(trk->end_pts, trk->cluster[trk->entry].dts +
6515  trk->cluster[trk->entry].cts +
6516  pkt->duration);
6517 
6518  if (par->codec_id == AV_CODEC_ID_VC1) {
6519  mov_parse_vc1_frame(pkt, trk);
6520  } else if (par->codec_id == AV_CODEC_ID_TRUEHD) {
6522  } else if (pkt->flags & AV_PKT_FLAG_KEY) {
6523  if (mov->mode == MODE_MOV && par->codec_id == AV_CODEC_ID_MPEG2VIDEO &&
6524  trk->entry > 0) { // force sync sample for the first key frame
6526  if (trk->cluster[trk->entry].flags & MOV_PARTIAL_SYNC_SAMPLE)
6527  trk->flags |= MOV_TRACK_STPS;
6528  } else {
6529  trk->cluster[trk->entry].flags = MOV_SYNC_SAMPLE;
6530  }
6531  if (trk->cluster[trk->entry].flags & MOV_SYNC_SAMPLE)
6532  trk->has_keyframes++;
6533  }
6534  if (pkt->flags & AV_PKT_FLAG_DISPOSABLE) {
6535  trk->cluster[trk->entry].flags |= MOV_DISPOSABLE_SAMPLE;
6536  trk->has_disposable++;
6537  }
6538 
6540  if (prft && prft_size == sizeof(AVProducerReferenceTime))
6541  memcpy(&trk->cluster[trk->entry].prft, prft, prft_size);
6542  else
6543  memset(&trk->cluster[trk->entry].prft, 0, sizeof(AVProducerReferenceTime));
6544 
6545  trk->entry++;
6546  trk->sample_count += samples_in_chunk;
6547  mov->mdat_size += size;
6548 
6549  if (trk->hint_track >= 0 && trk->hint_track < mov->nb_tracks)
6551  reformatted_data ? reformatted_data + offset
6552  : NULL, size);
6553 
6554 end:
6555 err:
6556 
6557  if (pkt->data != reformatted_data)
6558  av_free(reformatted_data);
6559  return ret;
6560 }
6561 
6563 {
6564  MOVMuxContext *mov = s->priv_data;
6565  MOVTrack *trk = s->streams[pkt->stream_index]->priv_data;
6566  AVCodecParameters *par = trk->par;
6567  int64_t frag_duration = 0;
6568  int size = pkt->size;
6569 
6570  int ret = check_pkt(s, trk, pkt);
6571  if (ret < 0)
6572  return ret;
6573 
6574  if (mov->flags & FF_MOV_FLAG_FRAG_DISCONT) {
6575  for (int i = 0; i < mov->nb_streams; i++)
6576  mov->tracks[i].frag_discont = 1;
6578  }
6579 
6581  if (trk->dts_shift == AV_NOPTS_VALUE)
6582  trk->dts_shift = pkt->pts - pkt->dts;
6583  pkt->dts += trk->dts_shift;
6584  }
6585 
6586  if (trk->par->codec_id == AV_CODEC_ID_MP4ALS ||
6587  trk->par->codec_id == AV_CODEC_ID_AAC ||
6588  trk->par->codec_id == AV_CODEC_ID_AV1 ||
6589  trk->par->codec_id == AV_CODEC_ID_FLAC) {
6590  size_t side_size;
6591  uint8_t *side = av_packet_get_side_data(pkt, AV_PKT_DATA_NEW_EXTRADATA, &side_size);
6592  if (side && side_size > 0 && (side_size != par->extradata_size || memcmp(side, par->extradata, side_size))) {
6593  void *newextra = av_mallocz(side_size + AV_INPUT_BUFFER_PADDING_SIZE);
6594  if (!newextra)
6595  return AVERROR(ENOMEM);
6596  av_free(par->extradata);
6597  par->extradata = newextra;
6598  memcpy(par->extradata, side, side_size);
6599  par->extradata_size = side_size;
6600  if (!pkt->size) // Flush packet
6601  mov->need_rewrite_extradata = 1;
6602  }
6603  }
6604 
6605  if (!pkt->size) {
6606  if (trk->start_dts == AV_NOPTS_VALUE && trk->frag_discont) {
6607  trk->start_dts = pkt->dts;
6608  if (pkt->pts != AV_NOPTS_VALUE)
6609  trk->start_cts = pkt->pts - pkt->dts;
6610  else
6611  trk->start_cts = 0;
6612  }
6613 
6614  return 0; /* Discard 0 sized packets */
6615  }
6616 
6617  if (trk->entry && pkt->stream_index < mov->nb_streams)
6618  frag_duration = av_rescale_q(pkt->dts - trk->cluster[0].dts,
6619  s->streams[pkt->stream_index]->time_base,
6620  AV_TIME_BASE_Q);
6621  if ((mov->max_fragment_duration &&
6622  frag_duration >= mov->max_fragment_duration) ||
6623  (mov->max_fragment_size && mov->mdat_size + size >= mov->max_fragment_size) ||
6624  (mov->flags & FF_MOV_FLAG_FRAG_KEYFRAME &&
6625  par->codec_type == AVMEDIA_TYPE_VIDEO &&
6626  trk->entry && pkt->flags & AV_PKT_FLAG_KEY) ||
6628  if (frag_duration >= mov->min_fragment_duration) {
6629  if (trk->entry) {
6630  // Set the duration of this track to line up with the next
6631  // sample in this track. This avoids relying on AVPacket
6632  // duration, but only helps for this particular track, not
6633  // for the other ones that are flushed at the same time.
6634  //
6635  // If we have trk->entry == 0, no fragment will be written
6636  // for this track, and we can't adjust the track end here.
6637  trk->track_duration = pkt->dts - trk->start_dts;
6638  if (pkt->pts != AV_NOPTS_VALUE)
6639  trk->end_pts = pkt->pts;
6640  else
6641  trk->end_pts = pkt->dts;
6642  trk->end_reliable = 1;
6643  }
6645  }
6646  }
6647 
6648  return ff_mov_write_packet(s, pkt);
6649 }
6650 
6652  int stream_index,
6653  int64_t dts) {
6654  MOVMuxContext *mov = s->priv_data;
6655  AVPacket *end = mov->pkt;
6656  uint8_t data[2] = {0};
6657  int ret;
6658 
6659  end->size = sizeof(data);
6660  end->data = data;
6661  end->pts = dts;
6662  end->dts = dts;
6663  end->duration = 0;
6664  end->stream_index = stream_index;
6665 
6666  ret = mov_write_single_packet(s, end);
6667  av_packet_unref(end);
6668 
6669  return ret;
6670 }
6671 
6672 #if CONFIG_IAMFENC
6673 static int mov_build_iamf_packet(AVFormatContext *s, MOVTrack *trk, AVPacket *pkt)
6674 {
6675  uint8_t *data;
6676  int ret;
6677 
6678  if (pkt->stream_index == trk->first_iamf_idx) {
6680  if (ret < 0)
6681  return ret;
6682  }
6683 
6685  s->streams[pkt->stream_index]->id, pkt);
6686  if (ret < 0)
6687  return ret;
6688 
6689  if (pkt->stream_index != trk->last_iamf_idx)
6690  return AVERROR(EAGAIN);
6691 
6692  ret = avio_close_dyn_buf(trk->iamf_buf, &data);
6693  trk->iamf_buf = NULL;
6694  if (!ret) {
6695  if (pkt->size) {
6696  // Either all or none of the packets for a single
6697  // IA Sample may be empty.
6698  av_log(s, AV_LOG_ERROR, "Unexpected packet from "
6699  "stream #%d\n", pkt->stream_index);
6701  }
6702  av_free(data);
6703  return ret;
6704  }
6705 
6706  av_buffer_unref(&pkt->buf);
6707  pkt->buf = av_buffer_create(data, ret, NULL, NULL, 0);
6708  if (!pkt->buf) {
6709  av_free(data);
6710  return AVERROR(ENOMEM);
6711  }
6712  pkt->data = data;
6713  pkt->size = ret;
6715 
6716  return avio_open_dyn_buf(&trk->iamf_buf);
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:3354
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:5165
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:3749
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:4676
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:3046
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:3810
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:5433
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:4497
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:5100
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:4449
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:6562
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:4975
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:3971
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:4903
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:3830
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:6140
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:3918
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:3479
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:4314
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:4411
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:4036
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:4142
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:2576
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:3055
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:4431
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:5153
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:3947
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:3379
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:2664
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:4112
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:3960
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:2789
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:3409
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:5523
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:4641
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:3204
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:5139
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:4124
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:3862
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
MOVTrack::vc1_info
struct MOVTrack::@359 vc1_info
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:4471
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
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:5409
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:4193
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:3251
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:3156
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:5745
mov_write_tcmi_tag
static int mov_write_tcmi_tag(AVIOContext *pb, MOVTrack *track)
Definition: movenc.c:2962
build_chunks
static void build_chunks(MOVTrack *trk)
Definition: movenc.c:4606
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:3622
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:3061
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:4894
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:4555
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:3146
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:6154
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:5908
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:5204
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:3770
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:2946
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:3317
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:4753
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:2703
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:4052
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:4771
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:6651
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:2899
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:4329
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:3731
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:4087
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:3465
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:2984
mov_write_stsd_tag
static int mov_write_stsd_tag(AVFormatContext *s, AVIOContext *pb, MOVMuxContext *mov, MOVTrack *track)
Definition: movenc.c:2676
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:2615
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:3391
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:3784
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:4358
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:4380
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:3179
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:4247
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:3292
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:5645
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:2937
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:6189
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::@358 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:4073
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:5826
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:3587
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:4909
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:2744
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:5377
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:4220
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:3235
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:3720
mov_write_uuid_tag_ipod
static int mov_write_uuid_tag_ipod(AVIOContext *pb)
Write uuid atom.
Definition: movenc.c:1945
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:5932
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:2954
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
mov_pix_fmt_tags
static const struct @357 mov_pix_fmt_tags[]
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:5482
mov_write_prft_tag
static int mov_write_prft_tag(AVIOContext *pb, MOVMuxContext *mov, int tracks)
Definition: movenc.c:5327
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:5716
mov_write_sidx_tags
static int mov_write_sidx_tags(AVIOContext *pb, MOVMuxContext *mov, int tracks, int ref_size)
Definition: movenc.c:5292
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:4274
mov_flush_fragment_interleaving
static int mov_flush_fragment_interleaving(AVFormatContext *s, MOVTrack *track)
Definition: movenc.c:5845
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:3400
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:3446
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
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:3223
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:4763
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:4568
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:2804
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:4442
AVCodecParameters::codec_id
enum AVCodecID codec_id
Specific type of the encoded data (the codec used).
Definition: codec_par.h:55
FLAC_METADATA_TYPE_STREAMINFO
@ FLAC_METADATA_TYPE_STREAMINFO
Definition: flac.h:46
mov_write_ipma_tag
static int mov_write_ipma_tag(AVIOContext *pb, MOVMuxContext *mov, AVFormatContext *s)
Definition: movenc.c:3268
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:3036
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:2596
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:5766
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:5870
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:3302
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:4758
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:5471
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:5051
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:5086
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:5031
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:5227
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