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