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