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