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