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