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