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