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