FFmpeg
movenc.c
Go to the documentation of this file.
1 /*
2  * MOV, 3GP, MP4 muxer
3  * Copyright (c) 2003 Thomas Raivio
4  * Copyright (c) 2004 Gildas Bazin <gbazin at videolan dot org>
5  * Copyright (c) 2009 Baptiste Coudurier <baptiste dot coudurier at gmail dot com>
6  *
7  * This file is part of FFmpeg.
8  *
9  * FFmpeg is free software; you can redistribute it and/or
10  * modify it under the terms of the GNU Lesser General Public
11  * License as published by the Free Software Foundation; either
12  * version 2.1 of the License, or (at your option) any later version.
13  *
14  * FFmpeg is distributed in the hope that it will be useful,
15  * but WITHOUT ANY WARRANTY; without even the implied warranty of
16  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
17  * Lesser General Public License for more details.
18  *
19  * You should have received a copy of the GNU Lesser General Public
20  * License along with FFmpeg; if not, write to the Free Software
21  * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
22  */
23 
24 #include <stdint.h>
25 #include <inttypes.h>
26 
27 #include "movenc.h"
28 #include "avformat.h"
29 #include "avio_internal.h"
30 #include "riff.h"
31 #include "avio.h"
32 #include "isom.h"
33 #include "av1.h"
34 #include "avc.h"
36 #include "libavcodec/dnxhddata.h"
37 #include "libavcodec/flac.h"
38 #include "libavcodec/get_bits.h"
39 
40 #include "libavcodec/internal.h"
41 #include "libavcodec/put_bits.h"
42 #include "libavcodec/vc1_common.h"
43 #include "libavcodec/raw.h"
44 #include "internal.h"
45 #include "libavutil/avstring.h"
46 #include "libavutil/intfloat.h"
47 #include "libavutil/mathematics.h"
48 #include "libavutil/libm.h"
49 #include "libavutil/opt.h"
50 #include "libavutil/dict.h"
51 #include "libavutil/pixdesc.h"
52 #include "libavutil/stereo3d.h"
53 #include "libavutil/timecode.h"
54 #include "libavutil/dovi_meta.h"
55 #include "libavutil/color_utils.h"
56 #include "hevc.h"
57 #include "rtpenc.h"
58 #include "mov_chan.h"
59 #include "vpcc.h"
60 
61 static const AVOption options[] = {
62  { "movflags", "MOV muxer flags", offsetof(MOVMuxContext, flags), AV_OPT_TYPE_FLAGS, {.i64 = 0}, INT_MIN, INT_MAX, AV_OPT_FLAG_ENCODING_PARAM, "movflags" },
63  { "rtphint", "Add RTP hint tracks", 0, AV_OPT_TYPE_CONST, {.i64 = FF_MOV_FLAG_RTP_HINT}, INT_MIN, INT_MAX, AV_OPT_FLAG_ENCODING_PARAM, "movflags" },
64  { "moov_size", "maximum moov size so it can be placed at the begin", offsetof(MOVMuxContext, reserved_moov_size), AV_OPT_TYPE_INT, {.i64 = 0}, 0, INT_MAX, AV_OPT_FLAG_ENCODING_PARAM, 0 },
65  { "empty_moov", "Make the initial moov atom empty", 0, AV_OPT_TYPE_CONST, {.i64 = FF_MOV_FLAG_EMPTY_MOOV}, INT_MIN, INT_MAX, AV_OPT_FLAG_ENCODING_PARAM, "movflags" },
66  { "frag_keyframe", "Fragment at video keyframes", 0, AV_OPT_TYPE_CONST, {.i64 = FF_MOV_FLAG_FRAG_KEYFRAME}, INT_MIN, INT_MAX, AV_OPT_FLAG_ENCODING_PARAM, "movflags" },
67  { "frag_every_frame", "Fragment at every frame", 0, AV_OPT_TYPE_CONST, {.i64 = FF_MOV_FLAG_FRAG_EVERY_FRAME}, INT_MIN, INT_MAX, AV_OPT_FLAG_ENCODING_PARAM, "movflags" },
68  { "separate_moof", "Write separate moof/mdat atoms for each track", 0, AV_OPT_TYPE_CONST, {.i64 = FF_MOV_FLAG_SEPARATE_MOOF}, INT_MIN, INT_MAX, AV_OPT_FLAG_ENCODING_PARAM, "movflags" },
69  { "frag_custom", "Flush fragments on caller requests", 0, AV_OPT_TYPE_CONST, {.i64 = FF_MOV_FLAG_FRAG_CUSTOM}, INT_MIN, INT_MAX, AV_OPT_FLAG_ENCODING_PARAM, "movflags" },
70  { "isml", "Create a live smooth streaming feed (for pushing to a publishing point)", 0, AV_OPT_TYPE_CONST, {.i64 = FF_MOV_FLAG_ISML}, INT_MIN, INT_MAX, AV_OPT_FLAG_ENCODING_PARAM, "movflags" },
71  { "faststart", "Run a second pass to put the index (moov atom) at the beginning of the file", 0, AV_OPT_TYPE_CONST, {.i64 = FF_MOV_FLAG_FASTSTART}, INT_MIN, INT_MAX, AV_OPT_FLAG_ENCODING_PARAM, "movflags" },
72  { "omit_tfhd_offset", "Omit the base data offset in tfhd atoms", 0, AV_OPT_TYPE_CONST, {.i64 = FF_MOV_FLAG_OMIT_TFHD_OFFSET}, INT_MIN, INT_MAX, AV_OPT_FLAG_ENCODING_PARAM, "movflags" },
73  { "disable_chpl", "Disable Nero chapter atom", 0, AV_OPT_TYPE_CONST, {.i64 = FF_MOV_FLAG_DISABLE_CHPL}, INT_MIN, INT_MAX, AV_OPT_FLAG_ENCODING_PARAM, "movflags" },
74  { "default_base_moof", "Set the default-base-is-moof flag in tfhd atoms", 0, AV_OPT_TYPE_CONST, {.i64 = FF_MOV_FLAG_DEFAULT_BASE_MOOF}, INT_MIN, INT_MAX, AV_OPT_FLAG_ENCODING_PARAM, "movflags" },
75  { "dash", "Write DASH compatible fragmented MP4", 0, AV_OPT_TYPE_CONST, {.i64 = FF_MOV_FLAG_DASH}, INT_MIN, INT_MAX, AV_OPT_FLAG_ENCODING_PARAM, "movflags" },
76  { "cmaf", "Write CMAF compatible fragmented MP4", 0, AV_OPT_TYPE_CONST, {.i64 = FF_MOV_FLAG_CMAF}, INT_MIN, INT_MAX, AV_OPT_FLAG_ENCODING_PARAM, "movflags" },
77  { "frag_discont", "Signal that the next fragment is discontinuous from earlier ones", 0, AV_OPT_TYPE_CONST, {.i64 = FF_MOV_FLAG_FRAG_DISCONT}, INT_MIN, INT_MAX, AV_OPT_FLAG_ENCODING_PARAM, "movflags" },
78  { "delay_moov", "Delay writing the initial moov until the first fragment is cut, or until the first fragment flush", 0, AV_OPT_TYPE_CONST, {.i64 = FF_MOV_FLAG_DELAY_MOOV}, INT_MIN, INT_MAX, AV_OPT_FLAG_ENCODING_PARAM, "movflags" },
79  { "global_sidx", "Write a global sidx index at the start of the file", 0, AV_OPT_TYPE_CONST, {.i64 = FF_MOV_FLAG_GLOBAL_SIDX}, INT_MIN, INT_MAX, AV_OPT_FLAG_ENCODING_PARAM, "movflags" },
80  { "skip_sidx", "Skip writing of sidx atom", 0, AV_OPT_TYPE_CONST, {.i64 = FF_MOV_FLAG_SKIP_SIDX}, INT_MIN, INT_MAX, AV_OPT_FLAG_ENCODING_PARAM, "movflags" },
81  { "write_colr", "Write colr atom (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  // "rtp " is used to distinguish internally created RTP-hint tracks
1592  // (with rtp_ctx) from other tracks.
1593  if (tag == MKTAG('r','t','p',' '))
1594  tag = 0;
1595  if (!tag || (s->strict_std_compliance >= FF_COMPLIANCE_NORMAL &&
1596  (track->par->codec_id == AV_CODEC_ID_DVVIDEO ||
1597  track->par->codec_id == AV_CODEC_ID_RAWVIDEO ||
1598  track->par->codec_id == AV_CODEC_ID_H263 ||
1599  track->par->codec_id == AV_CODEC_ID_H264 ||
1600  track->par->codec_id == AV_CODEC_ID_DNXHD ||
1601  track->par->codec_id == AV_CODEC_ID_MPEG2VIDEO ||
1602  av_get_bits_per_sample(track->par->codec_id)))) { // pcm audio
1603  if (track->par->codec_id == AV_CODEC_ID_DVVIDEO)
1604  tag = mov_get_dv_codec_tag(s, track);
1605  else if (track->par->codec_id == AV_CODEC_ID_RAWVIDEO)
1606  tag = mov_get_rawvideo_codec_tag(s, track);
1607  else if (track->par->codec_id == AV_CODEC_ID_MPEG2VIDEO)
1609  else if (track->par->codec_id == AV_CODEC_ID_H264)
1610  tag = mov_get_h264_codec_tag(s, track);
1611  else if (track->par->codec_id == AV_CODEC_ID_DNXHD)
1612  tag = mov_get_dnxhd_codec_tag(s, track);
1613  else if (track->par->codec_type == AVMEDIA_TYPE_VIDEO) {
1615  if (!tag) { // if no mac fcc found, try with Microsoft tags
1617  if (tag)
1618  av_log(s, AV_LOG_WARNING, "Using MS style video codec tag, "
1619  "the file may be unplayable!\n");
1620  }
1621  } else if (track->par->codec_type == AVMEDIA_TYPE_AUDIO) {
1623  if (!tag) { // if no mac fcc found, try with Microsoft tags
1624  int ms_tag = ff_codec_get_tag(ff_codec_wav_tags, track->par->codec_id);
1625  if (ms_tag) {
1626  tag = MKTAG('m', 's', ((ms_tag >> 8) & 0xff), (ms_tag & 0xff));
1627  av_log(s, AV_LOG_WARNING, "Using MS style audio codec tag, "
1628  "the file may be unplayable!\n");
1629  }
1630  }
1631  } else if (track->par->codec_type == AVMEDIA_TYPE_SUBTITLE)
1633  }
1634 
1635  return tag;
1636 }
1637 
1639  { AV_CODEC_ID_MJPEG, 0xD },
1640  { AV_CODEC_ID_PNG, 0xE },
1641  { AV_CODEC_ID_BMP, 0x1B },
1642  { AV_CODEC_ID_NONE, 0 },
1643 };
1644 
1645 static unsigned int validate_codec_tag(const AVCodecTag *const *tags,
1646  unsigned int tag, int codec_id)
1647 {
1648  int i;
1649 
1650  /**
1651  * Check that tag + id is in the table
1652  */
1653  for (i = 0; tags && tags[i]; i++) {
1654  const AVCodecTag *codec_tags = tags[i];
1655  while (codec_tags->id != AV_CODEC_ID_NONE) {
1656  if (avpriv_toupper4(codec_tags->tag) == avpriv_toupper4(tag) &&
1657  codec_tags->id == codec_id)
1658  return codec_tags->tag;
1659  codec_tags++;
1660  }
1661  }
1662  return 0;
1663 }
1664 
1665 static unsigned int mov_find_codec_tag(AVFormatContext *s, MOVTrack *track)
1666 {
1667  if (is_cover_image(track->st))
1669 
1670  if (track->mode == MODE_IPOD)
1671  if (!av_match_ext(s->url, "m4a") &&
1672  !av_match_ext(s->url, "m4v") &&
1673  !av_match_ext(s->url, "m4b"))
1674  av_log(s, AV_LOG_WARNING, "Warning, extension is not .m4a nor .m4v "
1675  "Quicktime/Ipod might not play the file\n");
1676 
1677  if (track->mode == MODE_MOV) {
1678  return mov_get_codec_tag(s, track);
1679  } else
1680  return validate_codec_tag(s->oformat->codec_tag, track->par->codec_tag,
1681  track->par->codec_id);
1682 }
1683 
1684 /** Write uuid atom.
1685  * Needed to make file play in iPods running newest firmware
1686  * goes after avcC atom in moov.trak.mdia.minf.stbl.stsd.avc1
1687  */
1689 {
1690  avio_wb32(pb, 28);
1691  ffio_wfourcc(pb, "uuid");
1692  avio_wb32(pb, 0x6b6840f2);
1693  avio_wb32(pb, 0x5f244fc5);
1694  avio_wb32(pb, 0xba39a51b);
1695  avio_wb32(pb, 0xcf0323f3);
1696  avio_wb32(pb, 0x0);
1697  return 28;
1698 }
1699 
1700 static const uint16_t fiel_data[] = {
1701  0x0000, 0x0100, 0x0201, 0x0206, 0x0209, 0x020e
1702 };
1703 
1704 static int mov_write_fiel_tag(AVIOContext *pb, MOVTrack *track, int field_order)
1705 {
1706  unsigned mov_field_order = 0;
1707  if (field_order < FF_ARRAY_ELEMS(fiel_data))
1708  mov_field_order = fiel_data[field_order];
1709  else
1710  return 0;
1711  avio_wb32(pb, 10);
1712  ffio_wfourcc(pb, "fiel");
1713  avio_wb16(pb, mov_field_order);
1714  return 10;
1715 }
1716 
1718 {
1719  int64_t pos = avio_tell(pb);
1720  avio_wb32(pb, 0); /* size */
1721  avio_wl32(pb, track->tag); // store it byteswapped
1722  avio_wb32(pb, 0); /* Reserved */
1723  avio_wb16(pb, 0); /* Reserved */
1724  avio_wb16(pb, 1); /* Data-reference index */
1725 
1726  if (track->par->codec_id == AV_CODEC_ID_DVD_SUBTITLE)
1727  mov_write_esds_tag(pb, track);
1728  else if (track->par->extradata_size)
1729  avio_write(pb, track->par->extradata, track->par->extradata_size);
1730 
1731  return update_size(pb, pos);
1732 }
1733 
1735 {
1736  int8_t stereo_mode;
1737 
1738  if (stereo_3d->flags != 0) {
1739  av_log(s, AV_LOG_WARNING, "Unsupported stereo_3d flags %x. st3d not written.\n", stereo_3d->flags);
1740  return 0;
1741  }
1742 
1743  switch (stereo_3d->type) {
1744  case AV_STEREO3D_2D:
1745  stereo_mode = 0;
1746  break;
1747  case AV_STEREO3D_TOPBOTTOM:
1748  stereo_mode = 1;
1749  break;
1751  stereo_mode = 2;
1752  break;
1753  default:
1754  av_log(s, AV_LOG_WARNING, "Unsupported stereo_3d type %s. st3d not written.\n", av_stereo3d_type_name(stereo_3d->type));
1755  return 0;
1756  }
1757  avio_wb32(pb, 13); /* size */
1758  ffio_wfourcc(pb, "st3d");
1759  avio_wb32(pb, 0); /* version = 0 & flags = 0 */
1760  avio_w8(pb, stereo_mode);
1761  return 13;
1762 }
1763 
1765 {
1766  int64_t sv3d_pos, svhd_pos, proj_pos;
1767  const char* metadata_source = s->flags & AVFMT_FLAG_BITEXACT ? "Lavf" : LIBAVFORMAT_IDENT;
1768 
1769  if (spherical_mapping->projection != AV_SPHERICAL_EQUIRECTANGULAR &&
1770  spherical_mapping->projection != AV_SPHERICAL_EQUIRECTANGULAR_TILE &&
1771  spherical_mapping->projection != AV_SPHERICAL_CUBEMAP) {
1772  av_log(s, AV_LOG_WARNING, "Unsupported projection %d. sv3d not written.\n", spherical_mapping->projection);
1773  return 0;
1774  }
1775 
1776  sv3d_pos = avio_tell(pb);
1777  avio_wb32(pb, 0); /* size */
1778  ffio_wfourcc(pb, "sv3d");
1779 
1780  svhd_pos = avio_tell(pb);
1781  avio_wb32(pb, 0); /* size */
1782  ffio_wfourcc(pb, "svhd");
1783  avio_wb32(pb, 0); /* version = 0 & flags = 0 */
1784  avio_put_str(pb, metadata_source);
1785  update_size(pb, svhd_pos);
1786 
1787  proj_pos = avio_tell(pb);
1788  avio_wb32(pb, 0); /* size */
1789  ffio_wfourcc(pb, "proj");
1790 
1791  avio_wb32(pb, 24); /* size */
1792  ffio_wfourcc(pb, "prhd");
1793  avio_wb32(pb, 0); /* version = 0 & flags = 0 */
1794  avio_wb32(pb, spherical_mapping->yaw);
1795  avio_wb32(pb, spherical_mapping->pitch);
1796  avio_wb32(pb, spherical_mapping->roll);
1797 
1798  switch (spherical_mapping->projection) {
1801  avio_wb32(pb, 28); /* size */
1802  ffio_wfourcc(pb, "equi");
1803  avio_wb32(pb, 0); /* version = 0 & flags = 0 */
1804  avio_wb32(pb, spherical_mapping->bound_top);
1805  avio_wb32(pb, spherical_mapping->bound_bottom);
1806  avio_wb32(pb, spherical_mapping->bound_left);
1807  avio_wb32(pb, spherical_mapping->bound_right);
1808  break;
1809  case AV_SPHERICAL_CUBEMAP:
1810  avio_wb32(pb, 20); /* size */
1811  ffio_wfourcc(pb, "cbmp");
1812  avio_wb32(pb, 0); /* version = 0 & flags = 0 */
1813  avio_wb32(pb, 0); /* layout */
1814  avio_wb32(pb, spherical_mapping->padding); /* padding */
1815  break;
1816  }
1817  update_size(pb, proj_pos);
1818 
1819  return update_size(pb, sv3d_pos);
1820 }
1821 
1823 {
1824  avio_wb32(pb, 32); /* size = 8 + 24 */
1825  if (dovi->dv_profile > 7)
1826  ffio_wfourcc(pb, "dvvC");
1827  else
1828  ffio_wfourcc(pb, "dvcC");
1829  avio_w8(pb, dovi->dv_version_major);
1830  avio_w8(pb, dovi->dv_version_minor);
1831  avio_wb16(pb, (dovi->dv_profile << 9) | (dovi->dv_level << 3) |
1832  (dovi->rpu_present_flag << 2) | (dovi->el_present_flag << 1) |
1833  dovi->bl_present_flag);
1834  avio_wb32(pb, (dovi->dv_bl_signal_compatibility_id << 28) | 0);
1835 
1836  avio_wb32(pb, 0); /* reserved */
1837  avio_wb32(pb, 0); /* reserved */
1838  avio_wb32(pb, 0); /* reserved */
1839  avio_wb32(pb, 0); /* reserved */
1840  av_log(s, AV_LOG_DEBUG, "DOVI in %s box, version: %d.%d, profile: %d, level: %d, "
1841  "rpu flag: %d, el flag: %d, bl flag: %d, compatibility id: %d\n",
1842  dovi->dv_profile > 7 ? "dvvC" : "dvcC",
1843  dovi->dv_version_major, dovi->dv_version_minor,
1844  dovi->dv_profile, dovi->dv_level,
1845  dovi->rpu_present_flag,
1846  dovi->el_present_flag,
1847  dovi->bl_present_flag,
1849  return 32; /* 8 + 24 */
1850 }
1851 
1852 static int mov_write_clap_tag(AVIOContext *pb, MOVTrack *track)
1853 {
1854  avio_wb32(pb, 40);
1855  ffio_wfourcc(pb, "clap");
1856  avio_wb32(pb, track->par->width); /* apertureWidth_N */
1857  avio_wb32(pb, 1); /* apertureWidth_D (= 1) */
1858  avio_wb32(pb, track->height); /* apertureHeight_N */
1859  avio_wb32(pb, 1); /* apertureHeight_D (= 1) */
1860  avio_wb32(pb, 0); /* horizOff_N (= 0) */
1861  avio_wb32(pb, 1); /* horizOff_D (= 1) */
1862  avio_wb32(pb, 0); /* vertOff_N (= 0) */
1863  avio_wb32(pb, 1); /* vertOff_D (= 1) */
1864  return 40;
1865 }
1866 
1867 static int mov_write_pasp_tag(AVIOContext *pb, MOVTrack *track)
1868 {
1869  AVRational sar;
1870  av_reduce(&sar.num, &sar.den, track->par->sample_aspect_ratio.num,
1871  track->par->sample_aspect_ratio.den, INT_MAX);
1872 
1873  avio_wb32(pb, 16);
1874  ffio_wfourcc(pb, "pasp");
1875  avio_wb32(pb, sar.num);
1876  avio_wb32(pb, sar.den);
1877  return 16;
1878 }
1879 
1880 static int mov_write_gama_tag(AVFormatContext *s, AVIOContext *pb, MOVTrack *track, double gamma)
1881 {
1882  uint32_t gama = 0;
1883  if (gamma <= 0.0) {
1884  gamma = avpriv_get_gamma_from_trc(track->par->color_trc);
1885  }
1886  av_log(s, AV_LOG_DEBUG, "gamma value %g\n", gamma);
1887 
1888  if (gamma > 1e-6) {
1889  gama = (uint32_t)lrint((double)(1<<16) * gamma);
1890  av_log(s, AV_LOG_DEBUG, "writing gama value %"PRId32"\n", gama);
1891 
1892  av_assert0(track->mode == MODE_MOV);
1893  avio_wb32(pb, 12);
1894  ffio_wfourcc(pb, "gama");
1895  avio_wb32(pb, gama);
1896  return 12;
1897  } else {
1898  av_log(s, AV_LOG_WARNING, "gamma value unknown, unable to write gama atom\n");
1899  }
1900  return 0;
1901 }
1902 
1903 static int mov_write_colr_tag(AVIOContext *pb, MOVTrack *track, int prefer_icc)
1904 {
1905  int64_t pos = avio_tell(pb);
1906 
1907  // Ref (MOV): https://developer.apple.com/library/mac/technotes/tn2162/_index.html#//apple_ref/doc/uid/DTS40013070-CH1-TNTAG9
1908  // Ref (MP4): ISO/IEC 14496-12:2012
1909 
1910  const uint8_t *icc_profile;
1911  int icc_profile_size;
1912 
1913  if (prefer_icc) {
1914  icc_profile = av_stream_get_side_data(track->st, AV_PKT_DATA_ICC_PROFILE, &icc_profile_size);
1915 
1916  if (icc_profile) {
1917  avio_wb32(pb, 12 + icc_profile_size);
1918  ffio_wfourcc(pb, "colr");
1919  ffio_wfourcc(pb, "prof");
1920  avio_write(pb, icc_profile, icc_profile_size);
1921  return 12 + icc_profile_size;
1922  }
1923  else {
1924  av_log(NULL, AV_LOG_INFO, "no ICC profile found, will write nclx/nclc colour info instead\n");
1925  }
1926  }
1927 
1928  /* We should only ever be called by MOV or MP4. */
1929  av_assert0(track->mode == MODE_MOV || track->mode == MODE_MP4);
1930 
1931  avio_wb32(pb, 0); /* size */
1932  ffio_wfourcc(pb, "colr");
1933  if (track->mode == MODE_MP4)
1934  ffio_wfourcc(pb, "nclx");
1935  else
1936  ffio_wfourcc(pb, "nclc");
1937  // Do not try to guess the color info if it is AVCOL_PRI_UNSPECIFIED.
1938  // e.g., Dolby Vision for Apple devices should be set to AVCOL_PRI_UNSPECIFIED. See
1939  // https://developer.apple.com/av-foundation/High-Dynamic-Range-Metadata-for-Apple-Devices.pdf
1940  avio_wb16(pb, track->par->color_primaries);
1941  avio_wb16(pb, track->par->color_trc);
1942  avio_wb16(pb, track->par->color_space);
1943  if (track->mode == MODE_MP4) {
1944  int full_range = track->par->color_range == AVCOL_RANGE_JPEG;
1945  avio_w8(pb, full_range << 7);
1946  }
1947 
1948  return update_size(pb, pos);
1949 }
1950 
1951 static int mov_write_clli_tag(AVIOContext *pb, MOVTrack *track)
1952 {
1953  const uint8_t *side_data;
1954  const AVContentLightMetadata *content_light_metadata;
1955 
1957  if (!side_data) {
1958  av_log(NULL, AV_LOG_VERBOSE, "Not writing 'clli' atom. No content light level info.\n");
1959  return 0;
1960  }
1961  content_light_metadata = (const AVContentLightMetadata*)side_data;
1962 
1963  avio_wb32(pb, 12); // size
1964  ffio_wfourcc(pb, "clli");
1965  avio_wb16(pb, content_light_metadata->MaxCLL);
1966  avio_wb16(pb, content_light_metadata->MaxFALL);
1967  return 12;
1968 }
1969 
1970 static inline int64_t rescale_mdcv(AVRational q, int b)
1971 {
1972  return av_rescale(q.num, b, q.den);
1973 }
1974 
1975 static int mov_write_mdcv_tag(AVIOContext *pb, MOVTrack *track)
1976 {
1977  const int chroma_den = 50000;
1978  const int luma_den = 10000;
1979  const uint8_t *side_data;
1980  const AVMasteringDisplayMetadata *metadata;
1981 
1983  metadata = (const AVMasteringDisplayMetadata*)side_data;
1984  if (!metadata || !metadata->has_primaries || !metadata->has_luminance) {
1985  av_log(NULL, AV_LOG_VERBOSE, "Not writing 'mdcv' atom. Missing mastering metadata.\n");
1986  return 0;
1987  }
1988 
1989  avio_wb32(pb, 32); // size
1990  ffio_wfourcc(pb, "mdcv");
1991  avio_wb16(pb, rescale_mdcv(metadata->display_primaries[1][0], chroma_den));
1992  avio_wb16(pb, rescale_mdcv(metadata->display_primaries[1][1], chroma_den));
1993  avio_wb16(pb, rescale_mdcv(metadata->display_primaries[2][0], chroma_den));
1994  avio_wb16(pb, rescale_mdcv(metadata->display_primaries[2][1], chroma_den));
1995  avio_wb16(pb, rescale_mdcv(metadata->display_primaries[0][0], chroma_den));
1996  avio_wb16(pb, rescale_mdcv(metadata->display_primaries[0][1], chroma_den));
1997  avio_wb16(pb, rescale_mdcv(metadata->white_point[0], chroma_den));
1998  avio_wb16(pb, rescale_mdcv(metadata->white_point[1], chroma_den));
1999  avio_wb32(pb, rescale_mdcv(metadata->max_luminance, luma_den));
2000  avio_wb32(pb, rescale_mdcv(metadata->min_luminance, luma_den));
2001  return 32;
2002 }
2003 
2004 static void find_compressor(char * compressor_name, int len, MOVTrack *track)
2005 {
2006  AVDictionaryEntry *encoder;
2007  int xdcam_res = (track->par->width == 1280 && track->par->height == 720)
2008  || (track->par->width == 1440 && track->par->height == 1080)
2009  || (track->par->width == 1920 && track->par->height == 1080);
2010 
2011  if (track->mode == MODE_MOV &&
2012  (encoder = av_dict_get(track->st->metadata, "encoder", NULL, 0))) {
2013  av_strlcpy(compressor_name, encoder->value, 32);
2014  } else if (track->par->codec_id == AV_CODEC_ID_MPEG2VIDEO && xdcam_res) {
2016  AVStream *st = track->st;
2017  int rate = defined_frame_rate(NULL, st);
2018  av_strlcatf(compressor_name, len, "XDCAM");
2019  if (track->par->format == AV_PIX_FMT_YUV422P) {
2020  av_strlcatf(compressor_name, len, " HD422");
2021  } else if(track->par->width == 1440) {
2022  av_strlcatf(compressor_name, len, " HD");
2023  } else
2024  av_strlcatf(compressor_name, len, " EX");
2025 
2026  av_strlcatf(compressor_name, len, " %d%c", track->par->height, interlaced ? 'i' : 'p');
2027 
2028  av_strlcatf(compressor_name, len, "%d", rate * (interlaced + 1));
2029  }
2030 }
2031 
2033 {
2034  int64_t pos = avio_tell(pb);
2035  char compressor_name[32] = { 0 };
2036  int avid = 0;
2037 
2038  int uncompressed_ycbcr = ((track->par->codec_id == AV_CODEC_ID_RAWVIDEO && track->par->format == AV_PIX_FMT_UYVY422)
2039  || (track->par->codec_id == AV_CODEC_ID_RAWVIDEO && track->par->format == AV_PIX_FMT_YUYV422)
2040  || track->par->codec_id == AV_CODEC_ID_V308
2041  || track->par->codec_id == AV_CODEC_ID_V408
2042  || track->par->codec_id == AV_CODEC_ID_V410
2043  || track->par->codec_id == AV_CODEC_ID_V210);
2044 
2045  avio_wb32(pb, 0); /* size */
2046  if (mov->encryption_scheme != MOV_ENC_NONE) {
2047  ffio_wfourcc(pb, "encv");
2048  } else {
2049  avio_wl32(pb, track->tag); // store it byteswapped
2050  }
2051  avio_wb32(pb, 0); /* Reserved */
2052  avio_wb16(pb, 0); /* Reserved */
2053  avio_wb16(pb, 1); /* Data-reference index */
2054 
2055  if (uncompressed_ycbcr) {
2056  avio_wb16(pb, 2); /* Codec stream version */
2057  } else {
2058  avio_wb16(pb, 0); /* Codec stream version */
2059  }
2060  avio_wb16(pb, 0); /* Codec stream revision (=0) */
2061  if (track->mode == MODE_MOV) {
2062  ffio_wfourcc(pb, "FFMP"); /* Vendor */
2063  if (track->par->codec_id == AV_CODEC_ID_RAWVIDEO || uncompressed_ycbcr) {
2064  avio_wb32(pb, 0); /* Temporal Quality */
2065  avio_wb32(pb, 0x400); /* Spatial Quality = lossless*/
2066  } else {
2067  avio_wb32(pb, 0x200); /* Temporal Quality = normal */
2068  avio_wb32(pb, 0x200); /* Spatial Quality = normal */
2069  }
2070  } else {
2071  avio_wb32(pb, 0); /* Reserved */
2072  avio_wb32(pb, 0); /* Reserved */
2073  avio_wb32(pb, 0); /* Reserved */
2074  }
2075  avio_wb16(pb, track->par->width); /* Video width */
2076  avio_wb16(pb, track->height); /* Video height */
2077  avio_wb32(pb, 0x00480000); /* Horizontal resolution 72dpi */
2078  avio_wb32(pb, 0x00480000); /* Vertical resolution 72dpi */
2079  avio_wb32(pb, 0); /* Data size (= 0) */
2080  avio_wb16(pb, 1); /* Frame count (= 1) */
2081 
2082  /* FIXME not sure, ISO 14496-1 draft where it shall be set to 0 */
2083  find_compressor(compressor_name, 32, track);
2084  avio_w8(pb, strlen(compressor_name));
2085  avio_write(pb, compressor_name, 31);
2086 
2087  if (track->mode == MODE_MOV &&
2088  (track->par->codec_id == AV_CODEC_ID_V410 || track->par->codec_id == AV_CODEC_ID_V210))
2089  avio_wb16(pb, 0x18);
2090  else if (track->mode == MODE_MOV && track->par->bits_per_coded_sample)
2091  avio_wb16(pb, track->par->bits_per_coded_sample |
2092  (track->par->format == AV_PIX_FMT_GRAY8 ? 0x20 : 0));
2093  else
2094  avio_wb16(pb, 0x18); /* Reserved */
2095 
2096  if (track->mode == MODE_MOV && track->par->format == AV_PIX_FMT_PAL8) {
2097  int pal_size, i;
2098  avio_wb16(pb, 0); /* Color table ID */
2099  avio_wb32(pb, 0); /* Color table seed */
2100  avio_wb16(pb, 0x8000); /* Color table flags */
2101  if (track->par->bits_per_coded_sample < 0 || track->par->bits_per_coded_sample > 8)
2102  return AVERROR(EINVAL);
2103  pal_size = 1 << track->par->bits_per_coded_sample;
2104  avio_wb16(pb, pal_size - 1); /* Color table size (zero-relative) */
2105  for (i = 0; i < pal_size; i++) {
2106  uint32_t rgb = track->palette[i];
2107  uint16_t r = (rgb >> 16) & 0xff;
2108  uint16_t g = (rgb >> 8) & 0xff;
2109  uint16_t b = rgb & 0xff;
2110  avio_wb16(pb, 0);
2111  avio_wb16(pb, (r << 8) | r);
2112  avio_wb16(pb, (g << 8) | g);
2113  avio_wb16(pb, (b << 8) | b);
2114  }
2115  } else
2116  avio_wb16(pb, 0xffff); /* Reserved */
2117 
2118  if (track->tag == MKTAG('m','p','4','v'))
2119  mov_write_esds_tag(pb, track);
2120  else if (track->par->codec_id == AV_CODEC_ID_H263)
2121  mov_write_d263_tag(pb);
2122  else if (track->par->codec_id == AV_CODEC_ID_AVUI ||
2123  track->par->codec_id == AV_CODEC_ID_SVQ3) {
2124  mov_write_extradata_tag(pb, track);
2125  avio_wb32(pb, 0);
2126  } else if (track->par->codec_id == AV_CODEC_ID_DNXHD) {
2127  mov_write_avid_tag(pb, track);
2128  avid = 1;
2129  } else if (track->par->codec_id == AV_CODEC_ID_HEVC)
2130  mov_write_hvcc_tag(pb, track);
2131  else if (track->par->codec_id == AV_CODEC_ID_H264 && !TAG_IS_AVCI(track->tag)) {
2132  mov_write_avcc_tag(pb, track);
2133  if (track->mode == MODE_IPOD)
2135  } else if (track->par->codec_id == AV_CODEC_ID_VP9) {
2136  mov_write_vpcc_tag(mov->fc, pb, track);
2137  } else if (track->par->codec_id == AV_CODEC_ID_AV1) {
2138  mov_write_av1c_tag(pb, track);
2139  } else if (track->par->codec_id == AV_CODEC_ID_VC1 && track->vos_len > 0)
2140  mov_write_dvc1_tag(pb, track);
2141  else if (track->par->codec_id == AV_CODEC_ID_VP6F ||
2142  track->par->codec_id == AV_CODEC_ID_VP6A) {
2143  /* Don't write any potential extradata here - the cropping
2144  * is signalled via the normal width/height fields. */
2145  } else if (track->par->codec_id == AV_CODEC_ID_R10K) {
2146  if (track->par->codec_tag == MKTAG('R','1','0','k'))
2147  mov_write_dpxe_tag(pb, track);
2148  } else if (track->vos_len > 0)
2149  mov_write_glbl_tag(pb, track);
2150 
2151  if (track->par->codec_id != AV_CODEC_ID_H264 &&
2152  track->par->codec_id != AV_CODEC_ID_MPEG4 &&
2153  track->par->codec_id != AV_CODEC_ID_DNXHD) {
2154  int field_order = track->par->field_order;
2155 
2156 #if FF_API_LAVF_AVCTX
2158  if (field_order != track->st->codec->field_order && track->st->codec->field_order != AV_FIELD_UNKNOWN)
2159  field_order = track->st->codec->field_order;
2161 #endif
2162 
2163  if (field_order != AV_FIELD_UNKNOWN)
2164  mov_write_fiel_tag(pb, track, field_order);
2165  }
2166 
2167  if (mov->flags & FF_MOV_FLAG_WRITE_GAMA) {
2168  if (track->mode == MODE_MOV)
2169  mov_write_gama_tag(s, pb, track, mov->gamma);
2170  else
2171  av_log(mov->fc, AV_LOG_WARNING, "Not writing 'gama' atom. Format is not MOV.\n");
2172  }
2173  if (mov->flags & FF_MOV_FLAG_WRITE_COLR) {
2174  if (track->mode == MODE_MOV || track->mode == MODE_MP4)
2175  mov_write_colr_tag(pb, track, mov->flags & FF_MOV_FLAG_PREFER_ICC);
2176  else
2177  av_log(mov->fc, AV_LOG_WARNING, "Not writing 'colr' atom. Format is not MOV or MP4.\n");
2178  }
2179  if (track->mode == MODE_MOV || track->mode == MODE_MP4) {
2180  mov_write_clli_tag(pb, track);
2181  mov_write_mdcv_tag(pb, track);
2182  }
2183 
2184  if (track->mode == MODE_MP4 && mov->fc->strict_std_compliance <= FF_COMPLIANCE_UNOFFICIAL) {
2189 
2190  if (stereo_3d)
2191  mov_write_st3d_tag(s, pb, stereo_3d);
2192  if (spherical_mapping)
2193  mov_write_sv3d_tag(mov->fc, pb, spherical_mapping);
2194  if (dovi)
2195  mov_write_dvcc_dvvc_tag(s, pb, dovi);
2196  }
2197 
2198  if (track->par->sample_aspect_ratio.den && track->par->sample_aspect_ratio.num) {
2199  mov_write_pasp_tag(pb, track);
2200  }
2201 
2202  if (uncompressed_ycbcr){
2203  mov_write_clap_tag(pb, track);
2204  }
2205 
2206  if (mov->encryption_scheme != MOV_ENC_NONE) {
2207  ff_mov_cenc_write_sinf_tag(track, pb, mov->encryption_kid);
2208  }
2209 
2210  /* extra padding for avid stsd */
2211  /* https://developer.apple.com/library/mac/documentation/QuickTime/QTFF/QTFFChap2/qtff2.html#//apple_ref/doc/uid/TP40000939-CH204-61112 */
2212  if (avid)
2213  avio_wb32(pb, 0);
2214 
2215  return update_size(pb, pos);
2216 }
2217 
2218 static int mov_write_rtp_tag(AVIOContext *pb, MOVTrack *track)
2219 {
2220  int64_t pos = avio_tell(pb);
2221  avio_wb32(pb, 0); /* size */
2222  ffio_wfourcc(pb, "rtp ");
2223  avio_wb32(pb, 0); /* Reserved */
2224  avio_wb16(pb, 0); /* Reserved */
2225  avio_wb16(pb, 1); /* Data-reference index */
2226 
2227  avio_wb16(pb, 1); /* Hint track version */
2228  avio_wb16(pb, 1); /* Highest compatible version */
2229  avio_wb32(pb, track->max_packet_size); /* Max packet size */
2230 
2231  avio_wb32(pb, 12); /* size */
2232  ffio_wfourcc(pb, "tims");
2233  avio_wb32(pb, track->timescale);
2234 
2235  return update_size(pb, pos);
2236 }
2237 
2238 static int mov_write_source_reference_tag(AVIOContext *pb, MOVTrack *track, const char *reel_name)
2239 {
2240  uint64_t str_size =strlen(reel_name);
2241  int64_t pos = avio_tell(pb);
2242 
2243  if (str_size >= UINT16_MAX){
2244  av_log(NULL, AV_LOG_ERROR, "reel_name length %"PRIu64" is too large\n", str_size);
2245  avio_wb16(pb, 0);
2246  return AVERROR(EINVAL);
2247  }
2248 
2249  avio_wb32(pb, 0); /* size */
2250  ffio_wfourcc(pb, "name"); /* Data format */
2251  avio_wb16(pb, str_size); /* string size */
2252  avio_wb16(pb, track->language); /* langcode */
2253  avio_write(pb, reel_name, str_size); /* reel name */
2254  return update_size(pb,pos);
2255 }
2256 
2257 static int mov_write_tmcd_tag(AVIOContext *pb, MOVTrack *track)
2258 {
2259  int64_t pos = avio_tell(pb);
2260 #if 1
2261  int frame_duration;
2262  int nb_frames;
2263  AVDictionaryEntry *t = NULL;
2264 
2265  if (!track->st->avg_frame_rate.num || !track->st->avg_frame_rate.den) {
2266 #if FF_API_LAVF_AVCTX
2268  frame_duration = av_rescale(track->timescale, track->st->codec->time_base.num, track->st->codec->time_base.den);
2269  nb_frames = ROUNDED_DIV(track->st->codec->time_base.den, track->st->codec->time_base.num);
2271 #else
2272  av_log(NULL, AV_LOG_ERROR, "avg_frame_rate not set for tmcd track.\n");
2273  return AVERROR(EINVAL);
2274 #endif
2275  } else {
2276  frame_duration = av_rescale(track->timescale, track->st->avg_frame_rate.num, track->st->avg_frame_rate.den);
2277  nb_frames = ROUNDED_DIV(track->st->avg_frame_rate.den, track->st->avg_frame_rate.num);
2278  }
2279 
2280  if (nb_frames > 255) {
2281  av_log(NULL, AV_LOG_ERROR, "fps %d is too large\n", nb_frames);
2282  return AVERROR(EINVAL);
2283  }
2284 
2285  avio_wb32(pb, 0); /* size */
2286  ffio_wfourcc(pb, "tmcd"); /* Data format */
2287  avio_wb32(pb, 0); /* Reserved */
2288  avio_wb32(pb, 1); /* Data reference index */
2289  avio_wb32(pb, 0); /* Flags */
2290  avio_wb32(pb, track->timecode_flags); /* Flags (timecode) */
2291  avio_wb32(pb, track->timescale); /* Timescale */
2292  avio_wb32(pb, frame_duration); /* Frame duration */
2293  avio_w8(pb, nb_frames); /* Number of frames */
2294  avio_w8(pb, 0); /* Reserved */
2295 
2296  t = av_dict_get(track->st->metadata, "reel_name", NULL, 0);
2297  if (t && utf8len(t->value) && track->mode != MODE_MP4)
2298  mov_write_source_reference_tag(pb, track, t->value);
2299  else
2300  avio_wb16(pb, 0); /* zero size */
2301 #else
2302 
2303  avio_wb32(pb, 0); /* size */
2304  ffio_wfourcc(pb, "tmcd"); /* Data format */
2305  avio_wb32(pb, 0); /* Reserved */
2306  avio_wb32(pb, 1); /* Data reference index */
2307  if (track->par->extradata_size)
2308  avio_write(pb, track->par->extradata, track->par->extradata_size);
2309 #endif
2310  return update_size(pb, pos);
2311 }
2312 
2313 static int mov_write_gpmd_tag(AVIOContext *pb, const MOVTrack *track)
2314 {
2315  int64_t pos = avio_tell(pb);
2316  avio_wb32(pb, 0); /* size */
2317  ffio_wfourcc(pb, "gpmd");
2318  avio_wb32(pb, 0); /* Reserved */
2319  avio_wb16(pb, 0); /* Reserved */
2320  avio_wb16(pb, 1); /* Data-reference index */
2321  avio_wb32(pb, 0); /* Reserved */
2322  return update_size(pb, pos);
2323 }
2324 
2326 {
2327  int64_t pos = avio_tell(pb);
2328  int ret = 0;
2329  avio_wb32(pb, 0); /* size */
2330  ffio_wfourcc(pb, "stsd");
2331  avio_wb32(pb, 0); /* version & flags */
2332  avio_wb32(pb, 1); /* entry count */
2333  if (track->par->codec_type == AVMEDIA_TYPE_VIDEO)
2334  ret = mov_write_video_tag(s, pb, mov, track);
2335  else if (track->par->codec_type == AVMEDIA_TYPE_AUDIO)
2336  ret = mov_write_audio_tag(s, pb, mov, track);
2337  else if (track->par->codec_type == AVMEDIA_TYPE_SUBTITLE)
2338  ret = mov_write_subtitle_tag(pb, track);
2339  else if (track->par->codec_tag == MKTAG('r','t','p',' '))
2340  ret = mov_write_rtp_tag(pb, track);
2341  else if (track->par->codec_tag == MKTAG('t','m','c','d'))
2342  ret = mov_write_tmcd_tag(pb, track);
2343  else if (track->par->codec_tag == MKTAG('g','p','m','d'))
2344  ret = mov_write_gpmd_tag(pb, track);
2345 
2346  if (ret < 0)
2347  return ret;
2348 
2349  return update_size(pb, pos);
2350 }
2351 
2353 {
2354  MOVMuxContext *mov = s->priv_data;
2355  MOVStts *ctts_entries;
2356  uint32_t entries = 0;
2357  uint32_t atom_size;
2358  int i;
2359 
2360  ctts_entries = av_malloc_array((track->entry + 1), sizeof(*ctts_entries)); /* worst case */
2361  if (!ctts_entries)
2362  return AVERROR(ENOMEM);
2363  ctts_entries[0].count = 1;
2364  ctts_entries[0].duration = track->cluster[0].cts;
2365  for (i = 1; i < track->entry; i++) {
2366  if (track->cluster[i].cts == ctts_entries[entries].duration) {
2367  ctts_entries[entries].count++; /* compress */
2368  } else {
2369  entries++;
2370  ctts_entries[entries].duration = track->cluster[i].cts;
2371  ctts_entries[entries].count = 1;
2372  }
2373  }
2374  entries++; /* last one */
2375  atom_size = 16 + (entries * 8);
2376  avio_wb32(pb, atom_size); /* size */
2377  ffio_wfourcc(pb, "ctts");
2379  avio_w8(pb, 1); /* version */
2380  else
2381  avio_w8(pb, 0); /* version */
2382  avio_wb24(pb, 0); /* flags */
2383  avio_wb32(pb, entries); /* entry count */
2384  for (i = 0; i < entries; i++) {
2385  avio_wb32(pb, ctts_entries[i].count);
2386  avio_wb32(pb, ctts_entries[i].duration);
2387  }
2388  av_free(ctts_entries);
2389  return atom_size;
2390 }
2391 
2392 /* Time to sample atom */
2393 static int mov_write_stts_tag(AVIOContext *pb, MOVTrack *track)
2394 {
2395  MOVStts *stts_entries = NULL;
2396  uint32_t entries = -1;
2397  uint32_t atom_size;
2398  int i;
2399 
2400  if (track->par->codec_type == AVMEDIA_TYPE_AUDIO && !track->audio_vbr) {
2401  stts_entries = av_malloc(sizeof(*stts_entries)); /* one entry */
2402  if (!stts_entries)
2403  return AVERROR(ENOMEM);
2404  stts_entries[0].count = track->sample_count;
2405  stts_entries[0].duration = 1;
2406  entries = 1;
2407  } else {
2408  if (track->entry) {
2409  stts_entries = av_malloc_array(track->entry, sizeof(*stts_entries)); /* worst case */
2410  if (!stts_entries)
2411  return AVERROR(ENOMEM);
2412  }
2413  for (i = 0; i < track->entry; i++) {
2414  int duration = get_cluster_duration(track, i);
2415  if (i && duration == stts_entries[entries].duration) {
2416  stts_entries[entries].count++; /* compress */
2417  } else {
2418  entries++;
2419  stts_entries[entries].duration = duration;
2420  stts_entries[entries].count = 1;
2421  }
2422  }
2423  entries++; /* last one */
2424  }
2425  atom_size = 16 + (entries * 8);
2426  avio_wb32(pb, atom_size); /* size */
2427  ffio_wfourcc(pb, "stts");
2428  avio_wb32(pb, 0); /* version & flags */
2429  avio_wb32(pb, entries); /* entry count */
2430  for (i = 0; i < entries; i++) {
2431  avio_wb32(pb, stts_entries[i].count);
2432  avio_wb32(pb, stts_entries[i].duration);
2433  }
2434  av_free(stts_entries);
2435  return atom_size;
2436 }
2437 
2439 {
2440  avio_wb32(pb, 28); /* size */
2441  ffio_wfourcc(pb, "dref");
2442  avio_wb32(pb, 0); /* version & flags */
2443  avio_wb32(pb, 1); /* entry count */
2444 
2445  avio_wb32(pb, 0xc); /* size */
2446  //FIXME add the alis and rsrc atom
2447  ffio_wfourcc(pb, "url ");
2448  avio_wb32(pb, 1); /* version & flags */
2449 
2450  return 28;
2451 }
2452 
2454 {
2455  struct sgpd_entry {
2456  int count;
2457  int16_t roll_distance;
2458  int group_description_index;
2459  };
2460 
2461  struct sgpd_entry *sgpd_entries = NULL;
2462  int entries = -1;
2463  int group = 0;
2464  int i, j;
2465 
2466  const int OPUS_SEEK_PREROLL_MS = 80;
2467  int roll_samples = av_rescale_q(OPUS_SEEK_PREROLL_MS,
2468  (AVRational){1, 1000},
2469  (AVRational){1, 48000});
2470 
2471  if (!track->entry)
2472  return 0;
2473 
2474  sgpd_entries = av_malloc_array(track->entry, sizeof(*sgpd_entries));
2475  if (!sgpd_entries)
2476  return AVERROR(ENOMEM);
2477 
2479 
2480  if (track->par->codec_id == AV_CODEC_ID_OPUS) {
2481  for (i = 0; i < track->entry; i++) {
2482  int roll_samples_remaining = roll_samples;
2483  int distance = 0;
2484  for (j = i - 1; j >= 0; j--) {
2485  roll_samples_remaining -= get_cluster_duration(track, j);
2486  distance++;
2487  if (roll_samples_remaining <= 0)
2488  break;
2489  }
2490  /* We don't have enough preceeding samples to compute a valid
2491  roll_distance here, so this sample can't be independently
2492  decoded. */
2493  if (roll_samples_remaining > 0)
2494  distance = 0;
2495  /* Verify distance is a maximum of 32 (2.5ms) packets. */
2496  if (distance > 32)
2497  return AVERROR_INVALIDDATA;
2498  if (i && distance == sgpd_entries[entries].roll_distance) {
2499  sgpd_entries[entries].count++;
2500  } else {
2501  entries++;
2502  sgpd_entries[entries].count = 1;
2503  sgpd_entries[entries].roll_distance = distance;
2504  sgpd_entries[entries].group_description_index = distance ? ++group : 0;
2505  }
2506  }
2507  } else {
2508  entries++;
2509  sgpd_entries[entries].count = track->sample_count;
2510  sgpd_entries[entries].roll_distance = 1;
2511  sgpd_entries[entries].group_description_index = ++group;
2512  }
2513  entries++;
2514 
2515  if (!group) {
2516  av_free(sgpd_entries);
2517  return 0;
2518  }
2519 
2520  /* Write sgpd tag */
2521  avio_wb32(pb, 24 + (group * 2)); /* size */
2522  ffio_wfourcc(pb, "sgpd");
2523  avio_wb32(pb, 1 << 24); /* fullbox */
2524  ffio_wfourcc(pb, "roll");
2525  avio_wb32(pb, 2); /* default_length */
2526  avio_wb32(pb, group); /* entry_count */
2527  for (i = 0; i < entries; i++) {
2528  if (sgpd_entries[i].group_description_index) {
2529  avio_wb16(pb, -sgpd_entries[i].roll_distance); /* roll_distance */
2530  }
2531  }
2532 
2533  /* Write sbgp tag */
2534  avio_wb32(pb, 20 + (entries * 8)); /* size */
2535  ffio_wfourcc(pb, "sbgp");
2536  avio_wb32(pb, 0); /* fullbox */
2537  ffio_wfourcc(pb, "roll");
2538  avio_wb32(pb, entries); /* entry_count */
2539  for (i = 0; i < entries; i++) {
2540  avio_wb32(pb, sgpd_entries[i].count); /* sample_count */
2541  avio_wb32(pb, sgpd_entries[i].group_description_index); /* group_description_index */
2542  }
2543 
2544  av_free(sgpd_entries);
2545  return 0;
2546 }
2547 
2549 {
2550  int64_t pos = avio_tell(pb);
2551  int ret = 0;
2552 
2553  avio_wb32(pb, 0); /* size */
2554  ffio_wfourcc(pb, "stbl");
2555  if ((ret = mov_write_stsd_tag(s, pb, mov, track)) < 0)
2556  return ret;
2557  mov_write_stts_tag(pb, track);
2558  if ((track->par->codec_type == AVMEDIA_TYPE_VIDEO ||
2559  track->par->codec_id == AV_CODEC_ID_TRUEHD ||
2561  track->par->codec_tag == MKTAG('r','t','p',' ')) &&
2562  track->has_keyframes && track->has_keyframes < track->entry)
2563  mov_write_stss_tag(pb, track, MOV_SYNC_SAMPLE);
2564  if (track->par->codec_type == AVMEDIA_TYPE_VIDEO && track->has_disposable)
2565  mov_write_sdtp_tag(pb, track);
2566  if (track->mode == MODE_MOV && track->flags & MOV_TRACK_STPS)
2568  if (track->par->codec_type == AVMEDIA_TYPE_VIDEO &&
2569  track->flags & MOV_TRACK_CTTS && track->entry) {
2570 
2571  if ((ret = mov_write_ctts_tag(s, pb, track)) < 0)
2572  return ret;
2573  }
2574  mov_write_stsc_tag(pb, track);
2575  mov_write_stsz_tag(pb, track);
2576  mov_write_stco_tag(pb, track);
2577  if (track->cenc.aes_ctr) {
2578  ff_mov_cenc_write_stbl_atoms(&track->cenc, pb);
2579  }
2580  if (track->par->codec_id == AV_CODEC_ID_OPUS || track->par->codec_id == AV_CODEC_ID_AAC) {
2581  mov_preroll_write_stbl_atoms(pb, track);
2582  }
2583  return update_size(pb, pos);
2584 }
2585 
2587 {
2588  int64_t pos = avio_tell(pb);
2589  avio_wb32(pb, 0); /* size */
2590  ffio_wfourcc(pb, "dinf");
2591  mov_write_dref_tag(pb);
2592  return update_size(pb, pos);
2593 }
2594 
2596 {
2597  avio_wb32(pb, 12);
2598  ffio_wfourcc(pb, "nmhd");
2599  avio_wb32(pb, 0);
2600  return 12;
2601 }
2602 
2603 static int mov_write_tcmi_tag(AVIOContext *pb, MOVTrack *track)
2604 {
2605  int64_t pos = avio_tell(pb);
2606  const char *font = "Lucida Grande";
2607  avio_wb32(pb, 0); /* size */
2608  ffio_wfourcc(pb, "tcmi"); /* timecode media information atom */
2609  avio_wb32(pb, 0); /* version & flags */
2610  avio_wb16(pb, 0); /* text font */
2611  avio_wb16(pb, 0); /* text face */
2612  avio_wb16(pb, 12); /* text size */
2613  avio_wb16(pb, 0); /* (unknown, not in the QT specs...) */
2614  avio_wb16(pb, 0x0000); /* text color (red) */
2615  avio_wb16(pb, 0x0000); /* text color (green) */
2616  avio_wb16(pb, 0x0000); /* text color (blue) */
2617  avio_wb16(pb, 0xffff); /* background color (red) */
2618  avio_wb16(pb, 0xffff); /* background color (green) */
2619  avio_wb16(pb, 0xffff); /* background color (blue) */
2620  avio_w8(pb, strlen(font)); /* font len (part of the pascal string) */
2621  avio_write(pb, font, strlen(font)); /* font name */
2622  return update_size(pb, pos);
2623 }
2624 
2625 static int mov_write_gmhd_tag(AVIOContext *pb, MOVTrack *track)
2626 {
2627  int64_t pos = avio_tell(pb);
2628  avio_wb32(pb, 0); /* size */
2629  ffio_wfourcc(pb, "gmhd");
2630  avio_wb32(pb, 0x18); /* gmin size */
2631  ffio_wfourcc(pb, "gmin");/* generic media info */
2632  avio_wb32(pb, 0); /* version & flags */
2633  avio_wb16(pb, 0x40); /* graphics mode = */
2634  avio_wb16(pb, 0x8000); /* opColor (r?) */
2635  avio_wb16(pb, 0x8000); /* opColor (g?) */
2636  avio_wb16(pb, 0x8000); /* opColor (b?) */
2637  avio_wb16(pb, 0); /* balance */
2638  avio_wb16(pb, 0); /* reserved */
2639 
2640  /*
2641  * This special text atom is required for
2642  * Apple Quicktime chapters. The contents
2643  * don't appear to be documented, so the
2644  * bytes are copied verbatim.
2645  */
2646  if (track->tag != MKTAG('c','6','0','8')) {
2647  avio_wb32(pb, 0x2C); /* size */
2648  ffio_wfourcc(pb, "text");
2649  avio_wb16(pb, 0x01);
2650  avio_wb32(pb, 0x00);
2651  avio_wb32(pb, 0x00);
2652  avio_wb32(pb, 0x00);
2653  avio_wb32(pb, 0x01);
2654  avio_wb32(pb, 0x00);
2655  avio_wb32(pb, 0x00);
2656  avio_wb32(pb, 0x00);
2657  avio_wb32(pb, 0x00004000);
2658  avio_wb16(pb, 0x0000);
2659  }
2660 
2661  if (track->par->codec_tag == MKTAG('t','m','c','d')) {
2662  int64_t tmcd_pos = avio_tell(pb);
2663  avio_wb32(pb, 0); /* size */
2664  ffio_wfourcc(pb, "tmcd");
2665  mov_write_tcmi_tag(pb, track);
2666  update_size(pb, tmcd_pos);
2667  } else if (track->par->codec_tag == MKTAG('g','p','m','d')) {
2668  int64_t gpmd_pos = avio_tell(pb);
2669  avio_wb32(pb, 0); /* size */
2670  ffio_wfourcc(pb, "gpmd");
2671  avio_wb32(pb, 0); /* version */
2672  update_size(pb, gpmd_pos);
2673  }
2674  return update_size(pb, pos);
2675 }
2676 
2678 {
2679  avio_wb32(pb, 16); /* size */
2680  ffio_wfourcc(pb, "smhd");
2681  avio_wb32(pb, 0); /* version & flags */
2682  avio_wb16(pb, 0); /* reserved (balance, normally = 0) */
2683  avio_wb16(pb, 0); /* reserved */
2684  return 16;
2685 }
2686 
2688 {
2689  avio_wb32(pb, 0x14); /* size (always 0x14) */
2690  ffio_wfourcc(pb, "vmhd");
2691  avio_wb32(pb, 0x01); /* version & flags */
2692  avio_wb64(pb, 0); /* reserved (graphics mode = copy) */
2693  return 0x14;
2694 }
2695 
2696 static int is_clcp_track(MOVTrack *track)
2697 {
2698  return track->tag == MKTAG('c','7','0','8') ||
2699  track->tag == MKTAG('c','6','0','8');
2700 }
2701 
2703 {
2704  MOVMuxContext *mov = s->priv_data;
2705  const char *hdlr, *descr = NULL, *hdlr_type = NULL;
2706  int64_t pos = avio_tell(pb);
2707 
2708  hdlr = "dhlr";
2709  hdlr_type = "url ";
2710  descr = "DataHandler";
2711 
2712  if (track) {
2713  hdlr = (track->mode == MODE_MOV) ? "mhlr" : "\0\0\0\0";
2714  if (track->par->codec_type == AVMEDIA_TYPE_VIDEO) {
2715  hdlr_type = "vide";
2716  descr = "VideoHandler";
2717  } else if (track->par->codec_type == AVMEDIA_TYPE_AUDIO) {
2718  hdlr_type = "soun";
2719  descr = "SoundHandler";
2720  } else if (track->par->codec_type == AVMEDIA_TYPE_SUBTITLE) {
2721  if (is_clcp_track(track)) {
2722  hdlr_type = "clcp";
2723  descr = "ClosedCaptionHandler";
2724  } else {
2725  if (track->tag == MKTAG('t','x','3','g')) {
2726  hdlr_type = "sbtl";
2727  } else if (track->tag == MKTAG('m','p','4','s')) {
2728  hdlr_type = "subp";
2729  } else {
2730  hdlr_type = "text";
2731  }
2732  descr = "SubtitleHandler";
2733  }
2734  } else if (track->par->codec_tag == MKTAG('r','t','p',' ')) {
2735  hdlr_type = "hint";
2736  descr = "HintHandler";
2737  } else if (track->par->codec_tag == MKTAG('t','m','c','d')) {
2738  hdlr_type = "tmcd";
2739  descr = "TimeCodeHandler";
2740  } else if (track->par->codec_tag == MKTAG('g','p','m','d')) {
2741  hdlr_type = "meta";
2742  descr = "GoPro MET"; // GoPro Metadata
2743  } else {
2745  "Unknown hldr_type for %s, writing dummy values\n",
2746  av_fourcc2str(track->par->codec_tag));
2747  }
2748  if (track->st) {
2749  // hdlr.name is used by some players to identify the content title
2750  // of the track. So if an alternate handler description is
2751  // specified, use it.
2752  AVDictionaryEntry *t;
2753  t = av_dict_get(track->st->metadata, "handler_name", NULL, 0);
2754  if (t && utf8len(t->value))
2755  descr = t->value;
2756  }
2757  }
2758 
2759  if (mov->empty_hdlr_name) /* expressly allowed by QTFF and not prohibited in ISO 14496-12 8.4.3.3 */
2760  descr = "";
2761 
2762  avio_wb32(pb, 0); /* size */
2763  ffio_wfourcc(pb, "hdlr");
2764  avio_wb32(pb, 0); /* Version & flags */
2765  avio_write(pb, hdlr, 4); /* handler */
2766  ffio_wfourcc(pb, hdlr_type); /* handler type */
2767  avio_wb32(pb, 0); /* reserved */
2768  avio_wb32(pb, 0); /* reserved */
2769  avio_wb32(pb, 0); /* reserved */
2770  if (!track || track->mode == MODE_MOV)
2771  avio_w8(pb, strlen(descr)); /* pascal string */
2772  avio_write(pb, descr, strlen(descr)); /* handler description */
2773  if (track && track->mode != MODE_MOV)
2774  avio_w8(pb, 0); /* c string */
2775  return update_size(pb, pos);
2776 }
2777 
2779 {
2780  /* This atom must be present, but leaving the values at zero
2781  * seems harmless. */
2782  avio_wb32(pb, 28); /* size */
2783  ffio_wfourcc(pb, "hmhd");
2784  avio_wb32(pb, 0); /* version, flags */
2785  avio_wb16(pb, 0); /* maxPDUsize */
2786  avio_wb16(pb, 0); /* avgPDUsize */
2787  avio_wb32(pb, 0); /* maxbitrate */
2788  avio_wb32(pb, 0); /* avgbitrate */
2789  avio_wb32(pb, 0); /* reserved */
2790  return 28;
2791 }
2792 
2794 {
2795  int64_t pos = avio_tell(pb);
2796  int ret;
2797 
2798  avio_wb32(pb, 0); /* size */
2799  ffio_wfourcc(pb, "minf");
2800  if (track->par->codec_type == AVMEDIA_TYPE_VIDEO)
2801  mov_write_vmhd_tag(pb);
2802  else if (track->par->codec_type == AVMEDIA_TYPE_AUDIO)
2803  mov_write_smhd_tag(pb);
2804  else if (track->par->codec_type == AVMEDIA_TYPE_SUBTITLE) {
2805  if (track->tag == MKTAG('t','e','x','t') || is_clcp_track(track)) {
2806  mov_write_gmhd_tag(pb, track);
2807  } else {
2808  mov_write_nmhd_tag(pb);
2809  }
2810  } else if (track->tag == MKTAG('r','t','p',' ')) {
2811  mov_write_hmhd_tag(pb);
2812  } else if (track->tag == MKTAG('t','m','c','d')) {
2813  if (track->mode != MODE_MOV)
2814  mov_write_nmhd_tag(pb);
2815  else
2816  mov_write_gmhd_tag(pb, track);
2817  } else if (track->tag == MKTAG('g','p','m','d')) {
2818  mov_write_gmhd_tag(pb, track);
2819  }
2820  if (track->mode == MODE_MOV) /* ISO 14496-12 8.4.3.1 specifies hdlr only within mdia or meta boxes */
2821  mov_write_hdlr_tag(s, pb, NULL);
2822  mov_write_dinf_tag(pb);
2823  if ((ret = mov_write_stbl_tag(s, pb, mov, track)) < 0)
2824  return ret;
2825  return update_size(pb, pos);
2826 }
2827 
2828 static int64_t calc_pts_duration(MOVMuxContext *mov, MOVTrack *track)
2829 {
2830  if (track->tag == MKTAG('t','m','c','d') && mov->nb_meta_tmcd) {
2831  // tmcd tracks gets track_duration set in mov_write_moov_tag from
2832  // another track's duration, while the end_pts may be left at zero.
2833  // Calculate the pts duration for that track instead.
2834  return av_rescale(calc_pts_duration(mov, &mov->tracks[track->src_track]),
2835  track->timescale, mov->tracks[track->src_track].timescale);
2836  }
2837  if (track->end_pts != AV_NOPTS_VALUE &&
2838  track->start_dts != AV_NOPTS_VALUE &&
2839  track->start_cts != AV_NOPTS_VALUE) {
2840  return track->end_pts - (track->start_dts + track->start_cts);
2841  }
2842  return track->track_duration;
2843 }
2844 
2846  MOVTrack *track)
2847 {
2848  int64_t duration = calc_pts_duration(mov, track);
2849  int version = duration < INT32_MAX ? 0 : 1;
2850 
2851  if (track->mode == MODE_ISM)
2852  version = 1;
2853 
2854  (version == 1) ? avio_wb32(pb, 44) : avio_wb32(pb, 32); /* size */
2855  ffio_wfourcc(pb, "mdhd");
2856  avio_w8(pb, version);
2857  avio_wb24(pb, 0); /* flags */
2858  if (version == 1) {
2859  avio_wb64(pb, track->time);
2860  avio_wb64(pb, track->time);
2861  } else {
2862  avio_wb32(pb, track->time); /* creation time */
2863  avio_wb32(pb, track->time); /* modification time */
2864  }
2865  avio_wb32(pb, track->timescale); /* time scale (sample rate for audio) */
2866  if (!track->entry && mov->mode == MODE_ISM)
2867  (version == 1) ? avio_wb64(pb, UINT64_C(0xffffffffffffffff)) : avio_wb32(pb, 0xffffffff);
2868  else if (!track->entry)
2869  (version == 1) ? avio_wb64(pb, 0) : avio_wb32(pb, 0);
2870  else
2871  (version == 1) ? avio_wb64(pb, duration) : avio_wb32(pb, duration); /* duration */
2872  avio_wb16(pb, track->language); /* language */
2873  avio_wb16(pb, 0); /* reserved (quality) */
2874 
2875  if (version != 0 && track->mode == MODE_MOV) {
2877  "FATAL error, file duration too long for timebase, this file will not be\n"
2878  "playable with QuickTime. Choose a different timebase with "
2879  "-video_track_timescale or a different container format\n");
2880  }
2881 
2882  return 32;
2883 }
2884 
2886  MOVMuxContext *mov, MOVTrack *track)
2887 {
2888  int64_t pos = avio_tell(pb);
2889  int ret;
2890 
2891  avio_wb32(pb, 0); /* size */
2892  ffio_wfourcc(pb, "mdia");
2893  mov_write_mdhd_tag(pb, mov, track);
2894  mov_write_hdlr_tag(s, pb, track);
2895  if ((ret = mov_write_minf_tag(s, pb, mov, track)) < 0)
2896  return ret;
2897  return update_size(pb, pos);
2898 }
2899 
2900 /* transformation matrix
2901  |a b u|
2902  |c d v|
2903  |tx ty w| */
2904 static void write_matrix(AVIOContext *pb, int16_t a, int16_t b, int16_t c,
2905  int16_t d, int16_t tx, int16_t ty)
2906 {
2907  avio_wb32(pb, a << 16); /* 16.16 format */
2908  avio_wb32(pb, b << 16); /* 16.16 format */
2909  avio_wb32(pb, 0); /* u in 2.30 format */
2910  avio_wb32(pb, c << 16); /* 16.16 format */
2911  avio_wb32(pb, d << 16); /* 16.16 format */
2912  avio_wb32(pb, 0); /* v in 2.30 format */
2913  avio_wb32(pb, tx << 16); /* 16.16 format */
2914  avio_wb32(pb, ty << 16); /* 16.16 format */
2915  avio_wb32(pb, 1 << 30); /* w in 2.30 format */
2916 }
2917 
2919  MOVTrack *track, AVStream *st)
2920 {
2921  int64_t duration = av_rescale_rnd(calc_pts_duration(mov, track),
2922  MOV_TIMESCALE, track->timescale,
2923  AV_ROUND_UP);
2924  int version = duration < INT32_MAX ? 0 : 1;
2926  int rotation = 0;
2927  int group = 0;
2928 
2929  uint32_t *display_matrix = NULL;
2930  int display_matrix_size, i;
2931 
2932  if (st) {
2933  if (mov->per_stream_grouping)
2934  group = st->index;
2935  else
2936  group = st->codecpar->codec_type;
2937 
2938  display_matrix = (uint32_t*)av_stream_get_side_data(st, AV_PKT_DATA_DISPLAYMATRIX,
2939  &display_matrix_size);
2940  if (display_matrix && display_matrix_size < 9 * sizeof(*display_matrix))
2941  display_matrix = NULL;
2942  }
2943 
2944  if (track->flags & MOV_TRACK_ENABLED)
2946 
2947  if (track->mode == MODE_ISM)
2948  version = 1;
2949 
2950  (version == 1) ? avio_wb32(pb, 104) : avio_wb32(pb, 92); /* size */
2951  ffio_wfourcc(pb, "tkhd");
2952  avio_w8(pb, version);
2953  avio_wb24(pb, flags);
2954  if (version == 1) {
2955  avio_wb64(pb, track->time);
2956  avio_wb64(pb, track->time);
2957  } else {
2958  avio_wb32(pb, track->time); /* creation time */
2959  avio_wb32(pb, track->time); /* modification time */
2960  }
2961  avio_wb32(pb, track->track_id); /* track-id */
2962  avio_wb32(pb, 0); /* reserved */
2963  if (!track->entry && mov->mode == MODE_ISM)
2964  (version == 1) ? avio_wb64(pb, UINT64_C(0xffffffffffffffff)) : avio_wb32(pb, 0xffffffff);
2965  else if (!track->entry)
2966  (version == 1) ? avio_wb64(pb, 0) : avio_wb32(pb, 0);
2967  else
2968  (version == 1) ? avio_wb64(pb, duration) : avio_wb32(pb, duration);
2969 
2970  avio_wb32(pb, 0); /* reserved */
2971  avio_wb32(pb, 0); /* reserved */
2972  avio_wb16(pb, 0); /* layer */
2973  avio_wb16(pb, group); /* alternate group) */
2974  /* Volume, only for audio */
2975  if (track->par->codec_type == AVMEDIA_TYPE_AUDIO)
2976  avio_wb16(pb, 0x0100);
2977  else
2978  avio_wb16(pb, 0);
2979  avio_wb16(pb, 0); /* reserved */
2980 
2981  /* Matrix structure */
2982 #if FF_API_OLD_ROTATE_API
2983  if (st && st->metadata) {
2984  AVDictionaryEntry *rot = av_dict_get(st->metadata, "rotate", NULL, 0);
2985  rotation = (rot && rot->value) ? atoi(rot->value) : 0;
2986  }
2987 #endif
2988  if (display_matrix) {
2989  for (i = 0; i < 9; i++)
2990  avio_wb32(pb, display_matrix[i]);
2991 #if FF_API_OLD_ROTATE_API
2992  } else if (rotation == 90) {
2993  write_matrix(pb, 0, 1, -1, 0, track->par->height, 0);
2994  } else if (rotation == 180) {
2995  write_matrix(pb, -1, 0, 0, -1, track->par->width, track->par->height);
2996  } else if (rotation == 270) {
2997  write_matrix(pb, 0, -1, 1, 0, 0, track->par->width);
2998 #endif
2999  } else {
3000  write_matrix(pb, 1, 0, 0, 1, 0, 0);
3001  }
3002  /* Track width and height, for visual only */
3003  if (st && (track->par->codec_type == AVMEDIA_TYPE_VIDEO ||
3004  track->par->codec_type == AVMEDIA_TYPE_SUBTITLE)) {
3005  int64_t track_width_1616;
3006  if (track->mode == MODE_MOV) {
3007  track_width_1616 = track->par->width * 0x10000ULL;
3008  } else {
3009  track_width_1616 = av_rescale(st->sample_aspect_ratio.num,
3010  track->par->width * 0x10000LL,
3011  st->sample_aspect_ratio.den);
3012  if (!track_width_1616 ||
3013  track->height != track->par->height ||
3014  track_width_1616 > UINT32_MAX)
3015  track_width_1616 = track->par->width * 0x10000ULL;
3016  }
3017  if (track_width_1616 > UINT32_MAX) {
3018  av_log(mov->fc, AV_LOG_WARNING, "track width is too large\n");
3019  track_width_1616 = 0;
3020  }
3021  avio_wb32(pb, track_width_1616);
3022  if (track->height > 0xFFFF) {
3023  av_log(mov->fc, AV_LOG_WARNING, "track height is too large\n");
3024  avio_wb32(pb, 0);
3025  } else
3026  avio_wb32(pb, track->height * 0x10000U);
3027  } else {
3028  avio_wb32(pb, 0);
3029  avio_wb32(pb, 0);
3030  }
3031  return 0x5c;
3032 }
3033 
3034 static int mov_write_tapt_tag(AVIOContext *pb, MOVTrack *track)
3035 {
3037  track->par->sample_aspect_ratio.den);
3038 
3039  int64_t pos = avio_tell(pb);
3040 
3041  avio_wb32(pb, 0); /* size */
3042  ffio_wfourcc(pb, "tapt");
3043 
3044  avio_wb32(pb, 20);
3045  ffio_wfourcc(pb, "clef");
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, "prof");
3052  avio_wb32(pb, 0);
3053  avio_wb32(pb, width << 16);
3054  avio_wb32(pb, track->par->height << 16);
3055 
3056  avio_wb32(pb, 20);
3057  ffio_wfourcc(pb, "enof");
3058  avio_wb32(pb, 0);
3059  avio_wb32(pb, track->par->width << 16);
3060  avio_wb32(pb, track->par->height << 16);
3061 
3062  return update_size(pb, pos);
3063 }
3064 
3065 // This box seems important for the psp playback ... without it the movie seems to hang
3067  MOVTrack *track)
3068 {
3069  int64_t duration = av_rescale_rnd(calc_pts_duration(mov, track),
3070  MOV_TIMESCALE, track->timescale,
3071  AV_ROUND_UP);
3072  int version = duration < INT32_MAX ? 0 : 1;
3073  int entry_size, entry_count, size;
3074  int64_t delay, start_ct = track->start_cts;
3075  int64_t start_dts = track->start_dts;
3076 
3077  if (track->entry) {
3078  if (start_dts != track->cluster[0].dts || start_ct != track->cluster[0].cts) {
3079 
3080  av_log(mov->fc, AV_LOG_DEBUG,
3081  "EDTS using dts:%"PRId64" cts:%d instead of dts:%"PRId64" cts:%"PRId64" tid:%d\n",
3082  track->cluster[0].dts, track->cluster[0].cts,
3083  start_dts, start_ct, track->track_id);
3084  start_dts = track->cluster[0].dts;
3085  start_ct = track->cluster[0].cts;
3086  }
3087  }
3088 
3089  delay = av_rescale_rnd(start_dts + start_ct, MOV_TIMESCALE,
3090  track->timescale, AV_ROUND_DOWN);
3091  version |= delay < INT32_MAX ? 0 : 1;
3092 
3093  entry_size = (version == 1) ? 20 : 12;
3094  entry_count = 1 + (delay > 0);
3095  size = 24 + entry_count * entry_size;
3096 
3097  /* write the atom data */
3098  avio_wb32(pb, size);
3099  ffio_wfourcc(pb, "edts");
3100  avio_wb32(pb, size - 8);
3101  ffio_wfourcc(pb, "elst");
3102  avio_w8(pb, version);
3103  avio_wb24(pb, 0); /* flags */
3104 
3105  avio_wb32(pb, entry_count);
3106  if (delay > 0) { /* add an empty edit to delay presentation */
3107  /* In the positive delay case, the delay includes the cts
3108  * offset, and the second edit list entry below trims out
3109  * the same amount from the actual content. This makes sure
3110  * that the offset last sample is included in the edit
3111  * list duration as well. */
3112  if (version == 1) {
3113  avio_wb64(pb, delay);
3114  avio_wb64(pb, -1);
3115  } else {
3116  avio_wb32(pb, delay);
3117  avio_wb32(pb, -1);
3118  }
3119  avio_wb32(pb, 0x00010000);
3120  } else {
3121  /* Avoid accidentally ending up with start_ct = -1 which has got a
3122  * special meaning. Normally start_ct should end up positive or zero
3123  * here, but use FFMIN in case dts is a small positive integer
3124  * rounded to 0 when represented in MOV_TIMESCALE units. */
3125  av_assert0(av_rescale_rnd(start_dts, MOV_TIMESCALE, track->timescale, AV_ROUND_DOWN) <= 0);
3126  start_ct = -FFMIN(start_dts, 0);
3127  /* Note, this delay is calculated from the pts of the first sample,
3128  * ensuring that we don't reduce the duration for cases with
3129  * dts<0 pts=0. */
3130  duration += delay;
3131  }
3132 
3133  /* For fragmented files, we don't know the full length yet. Setting
3134  * duration to 0 allows us to only specify the offset, including
3135  * the rest of the content (from all future fragments) without specifying
3136  * an explicit duration. */
3137  if (mov->flags & FF_MOV_FLAG_FRAGMENT)
3138  duration = 0;
3139 
3140  /* duration */
3141  if (version == 1) {
3142  avio_wb64(pb, duration);
3143  avio_wb64(pb, start_ct);
3144  } else {
3145  avio_wb32(pb, duration);
3146  avio_wb32(pb, start_ct);
3147  }
3148  avio_wb32(pb, 0x00010000);
3149  return size;
3150 }
3151 
3152 static int mov_write_tref_tag(AVIOContext *pb, MOVTrack *track)
3153 {
3154  avio_wb32(pb, 20); // size
3155  ffio_wfourcc(pb, "tref");
3156  avio_wb32(pb, 12); // size (subatom)
3157  avio_wl32(pb, track->tref_tag);
3158  avio_wb32(pb, track->tref_id);
3159  return 20;
3160 }
3161 
3162 // goes at the end of each track! ... Critical for PSP playback ("Incompatible data" without it)
3164 {
3165  avio_wb32(pb, 0x34); /* size ... reports as 28 in mp4box! */
3166  ffio_wfourcc(pb, "uuid");
3167  ffio_wfourcc(pb, "USMT");
3168  avio_wb32(pb, 0x21d24fce);
3169  avio_wb32(pb, 0xbb88695c);
3170  avio_wb32(pb, 0xfac9c740);
3171  avio_wb32(pb, 0x1c); // another size here!
3172  ffio_wfourcc(pb, "MTDT");
3173  avio_wb32(pb, 0x00010012);
3174  avio_wb32(pb, 0x0a);
3175  avio_wb32(pb, 0x55c40000);
3176  avio_wb32(pb, 0x1);
3177  avio_wb32(pb, 0x0);
3178  return 0x34;
3179 }
3180 
3181 static int mov_write_udta_sdp(AVIOContext *pb, MOVTrack *track)
3182 {
3183  AVFormatContext *ctx = track->rtp_ctx;
3184  char buf[1000] = "";
3185  int len;
3186 
3187  ff_sdp_write_media(buf, sizeof(buf), ctx->streams[0], track->src_track,
3188  NULL, NULL, 0, 0, ctx);
3189  av_strlcatf(buf, sizeof(buf), "a=control:streamid=%d\r\n", track->track_id);
3190  len = strlen(buf);
3191 
3192  avio_wb32(pb, len + 24);
3193  ffio_wfourcc(pb, "udta");
3194  avio_wb32(pb, len + 16);
3195  ffio_wfourcc(pb, "hnti");
3196  avio_wb32(pb, len + 8);
3197  ffio_wfourcc(pb, "sdp ");
3198  avio_write(pb, buf, len);
3199  return len + 24;
3200 }
3201 
3203  const char *tag, const char *str)
3204 {
3205  int64_t pos = avio_tell(pb);
3207  if (!t || !utf8len(t->value))
3208  return 0;
3209 
3210  avio_wb32(pb, 0); /* size */
3211  ffio_wfourcc(pb, tag); /* type */
3212  avio_write(pb, t->value, strlen(t->value)); /* UTF8 string value */
3213  return update_size(pb, pos);
3214 }
3215 
3217  AVStream *st)
3218 {
3219  AVIOContext *pb_buf;
3220  int ret, size;
3221  uint8_t *buf;
3222 
3223  if (!st)
3224  return 0;
3225 
3226  ret = avio_open_dyn_buf(&pb_buf);
3227  if (ret < 0)
3228  return ret;
3229 
3230  if (mov->mode & (MODE_MP4|MODE_MOV))
3231  mov_write_track_metadata(pb_buf, st, "name", "title");
3232 
3233  if ((size = avio_get_dyn_buf(pb_buf, &buf)) > 0) {
3234  avio_wb32(pb, size + 8);
3235  ffio_wfourcc(pb, "udta");
3236  avio_write(pb, buf, size);
3237  }
3238  ffio_free_dyn_buf(&pb_buf);
3239 
3240  return 0;
3241 }
3242 
3244  MOVTrack *track, AVStream *st)
3245 {
3246  int64_t pos = avio_tell(pb);
3247  int entry_backup = track->entry;
3248  int chunk_backup = track->chunkCount;
3249  int ret;
3250 
3251  /* If we want to have an empty moov, but some samples already have been
3252  * buffered (delay_moov), pretend that no samples have been written yet. */
3253  if (mov->flags & FF_MOV_FLAG_EMPTY_MOOV)
3254  track->chunkCount = track->entry = 0;
3255 
3256  avio_wb32(pb, 0); /* size */
3257  ffio_wfourcc(pb, "trak");
3258  mov_write_tkhd_tag(pb, mov, track, st);
3259 
3260  av_assert2(mov->use_editlist >= 0);
3261 
3262  if (track->start_dts != AV_NOPTS_VALUE) {
3263  if (mov->use_editlist)
3264  mov_write_edts_tag(pb, mov, track); // PSP Movies and several other cases require edts box
3265  else if ((track->entry && track->cluster[0].dts) || track->mode == MODE_PSP || is_clcp_track(track))
3266  av_log(mov->fc, AV_LOG_WARNING,
3267  "Not writing any edit list even though one would have been required\n");
3268  }
3269 
3270  if (track->tref_tag)
3271  mov_write_tref_tag(pb, track);
3272 
3273  if ((ret = mov_write_mdia_tag(s, pb, mov, track)) < 0)
3274  return ret;
3275  if (track->mode == MODE_PSP)
3276  mov_write_uuid_tag_psp(pb, track); // PSP Movies require this uuid box
3277  if (track->tag == MKTAG('r','t','p',' '))
3278  mov_write_udta_sdp(pb, track);
3279  if (track->mode == MODE_MOV) {
3280  if (track->par->codec_type == AVMEDIA_TYPE_VIDEO) {
3281  double sample_aspect_ratio = av_q2d(st->sample_aspect_ratio);
3282  if (st->sample_aspect_ratio.num && 1.0 != sample_aspect_ratio) {
3283  mov_write_tapt_tag(pb, track);
3284  }
3285  }
3286  if (is_clcp_track(track) && st->sample_aspect_ratio.num) {
3287  mov_write_tapt_tag(pb, track);
3288  }
3289  }
3290  mov_write_track_udta_tag(pb, mov, st);
3291  track->entry = entry_backup;
3292  track->chunkCount = chunk_backup;
3293  return update_size(pb, pos);
3294 }
3295 
3297 {
3298  int i, has_audio = 0, has_video = 0;
3299  int64_t pos = avio_tell(pb);
3300  int audio_profile = mov->iods_audio_profile;
3301  int video_profile = mov->iods_video_profile;
3302  for (i = 0; i < mov->nb_streams; i++) {
3303  if (mov->tracks[i].entry > 0 || mov->flags & FF_MOV_FLAG_EMPTY_MOOV) {
3304  has_audio |= mov->tracks[i].par->codec_type == AVMEDIA_TYPE_AUDIO;
3305  has_video |= mov->tracks[i].par->codec_type == AVMEDIA_TYPE_VIDEO;
3306  }
3307  }
3308  if (audio_profile < 0)
3309  audio_profile = 0xFF - has_audio;
3310  if (video_profile < 0)
3311  video_profile = 0xFF - has_video;
3312  avio_wb32(pb, 0x0); /* size */
3313  ffio_wfourcc(pb, "iods");
3314  avio_wb32(pb, 0); /* version & flags */
3315  put_descr(pb, 0x10, 7);
3316  avio_wb16(pb, 0x004f);
3317  avio_w8(pb, 0xff);
3318  avio_w8(pb, 0xff);
3319  avio_w8(pb, audio_profile);
3320  avio_w8(pb, video_profile);
3321  avio_w8(pb, 0xff);
3322  return update_size(pb, pos);
3323 }
3324 
3325 static int mov_write_trex_tag(AVIOContext *pb, MOVTrack *track)
3326 {
3327  avio_wb32(pb, 0x20); /* size */
3328  ffio_wfourcc(pb, "trex");
3329  avio_wb32(pb, 0); /* version & flags */
3330  avio_wb32(pb, track->track_id); /* track ID */
3331  avio_wb32(pb, 1); /* default sample description index */
3332  avio_wb32(pb, 0); /* default sample duration */
3333  avio_wb32(pb, 0); /* default sample size */
3334  avio_wb32(pb, 0); /* default sample flags */
3335  return 0;
3336 }
3337 
3339 {
3340  int64_t pos = avio_tell(pb);
3341  int i;
3342  avio_wb32(pb, 0x0); /* size */
3343  ffio_wfourcc(pb, "mvex");
3344  for (i = 0; i < mov->nb_streams; i++)
3345  mov_write_trex_tag(pb, &mov->tracks[i]);
3346  return update_size(pb, pos);
3347 }
3348 
3350 {
3351  int max_track_id = 1, i;
3352  int64_t max_track_len = 0;
3353  int version;
3354 
3355  for (i = 0; i < mov->nb_streams; i++) {
3356  if (mov->tracks[i].entry > 0 && mov->tracks[i].timescale) {
3357  int64_t max_track_len_temp = av_rescale_rnd(
3358  calc_pts_duration(mov, &mov->tracks[i]),
3359  MOV_TIMESCALE,
3360  mov->tracks[i].timescale,
3361  AV_ROUND_UP);
3362  if (max_track_len < max_track_len_temp)
3363  max_track_len = max_track_len_temp;
3364  if (max_track_id < mov->tracks[i].track_id)
3365  max_track_id = mov->tracks[i].track_id;
3366  }
3367  }
3368  /* If using delay_moov, make sure the output is the same as if no
3369  * samples had been written yet. */
3370  if (mov->flags & FF_MOV_FLAG_EMPTY_MOOV) {
3371  max_track_len = 0;
3372  max_track_id = 1;
3373  }
3374 
3375  version = max_track_len < UINT32_MAX ? 0 : 1;
3376  avio_wb32(pb, version == 1 ? 120 : 108); /* size */
3377 
3378  ffio_wfourcc(pb, "mvhd");
3379  avio_w8(pb, version);
3380  avio_wb24(pb, 0); /* flags */
3381  if (version == 1) {
3382  avio_wb64(pb, mov->time);
3383  avio_wb64(pb, mov->time);
3384  } else {
3385  avio_wb32(pb, mov->time); /* creation time */
3386  avio_wb32(pb, mov->time); /* modification time */
3387  }
3388  avio_wb32(pb, MOV_TIMESCALE);
3389  (version == 1) ? avio_wb64(pb, max_track_len) : avio_wb32(pb, max_track_len); /* duration of longest track */
3390 
3391  avio_wb32(pb, 0x00010000); /* reserved (preferred rate) 1.0 = normal */
3392  avio_wb16(pb, 0x0100); /* reserved (preferred volume) 1.0 = normal */
3393  avio_wb16(pb, 0); /* reserved */
3394  avio_wb32(pb, 0); /* reserved */
3395  avio_wb32(pb, 0); /* reserved */
3396 
3397  /* Matrix structure */
3398  write_matrix(pb, 1, 0, 0, 1, 0, 0);
3399 
3400  avio_wb32(pb, 0); /* reserved (preview time) */
3401  avio_wb32(pb, 0); /* reserved (preview duration) */
3402  avio_wb32(pb, 0); /* reserved (poster time) */
3403  avio_wb32(pb, 0); /* reserved (selection time) */
3404  avio_wb32(pb, 0); /* reserved (selection duration) */
3405  avio_wb32(pb, 0); /* reserved (current time) */
3406  avio_wb32(pb, max_track_id + 1); /* Next track id */
3407  return 0x6c;
3408 }
3409 
3411  AVFormatContext *s)
3412 {
3413  avio_wb32(pb, 33); /* size */
3414  ffio_wfourcc(pb, "hdlr");
3415  avio_wb32(pb, 0);
3416  avio_wb32(pb, 0);
3417  ffio_wfourcc(pb, "mdir");
3418  ffio_wfourcc(pb, "appl");
3419  avio_wb32(pb, 0);
3420  avio_wb32(pb, 0);
3421  avio_w8(pb, 0);
3422  return 33;
3423 }
3424 
3425 /* helper function to write a data tag with the specified string as data */
3426 static int mov_write_string_data_tag(AVIOContext *pb, const char *data, int lang, int long_style)
3427 {
3428  if (long_style) {
3429  int size = 16 + strlen(data);
3430  avio_wb32(pb, size); /* size */
3431  ffio_wfourcc(pb, "data");
3432  avio_wb32(pb, 1);
3433  avio_wb32(pb, 0);
3434  avio_write(pb, data, strlen(data));
3435  return size;
3436  } else {
3437  if (!lang)
3438  lang = ff_mov_iso639_to_lang("und", 1);
3439  avio_wb16(pb, strlen(data)); /* string length */
3440  avio_wb16(pb, lang);
3441  avio_write(pb, data, strlen(data));
3442  return strlen(data) + 4;
3443  }
3444 }
3445 
3446 static int mov_write_string_tag(AVIOContext *pb, const char *name,
3447  const char *value, int lang, int long_style)
3448 {
3449  int size = 0;
3450  if (value && value[0]) {
3451  int64_t pos = avio_tell(pb);
3452  avio_wb32(pb, 0); /* size */
3453  ffio_wfourcc(pb, name);
3454  mov_write_string_data_tag(pb, value, lang, long_style);
3455  size = update_size(pb, pos);
3456  }
3457  return size;
3458 }
3459 
3461  const char *tag, int *lang)
3462 {
3463  int l, len, len2;
3464  AVDictionaryEntry *t, *t2 = NULL;
3465  char tag2[16];
3466 
3467  *lang = 0;
3468 
3469  if (!(t = av_dict_get(s->metadata, tag, NULL, 0)))
3470  return NULL;
3471 
3472  len = strlen(t->key);
3473  snprintf(tag2, sizeof(tag2), "%s-", tag);
3474  while ((t2 = av_dict_get(s->metadata, tag2, t2, AV_DICT_IGNORE_SUFFIX))) {
3475  len2 = strlen(t2->key);
3476  if (len2 == len + 4 && !strcmp(t->value, t2->value)
3477  && (l = ff_mov_iso639_to_lang(&t2->key[len2 - 3], 1)) >= 0) {
3478  *lang = l;
3479  return t;
3480  }
3481  }
3482  return t;
3483 }
3484 
3486  const char *name, const char *tag,
3487  int long_style)
3488 {
3489  int lang;
3490  AVDictionaryEntry *t = get_metadata_lang(s, tag, &lang);
3491  if (!t)
3492  return 0;
3493  return mov_write_string_tag(pb, name, t->value, lang, long_style);
3494 }
3495 
3496 /* iTunes bpm number */
3498 {
3499  AVDictionaryEntry *t = av_dict_get(s->metadata, "tmpo", NULL, 0);
3500  int size = 0, tmpo = t ? atoi(t->value) : 0;
3501  if (tmpo) {
3502  size = 26;
3503  avio_wb32(pb, size);
3504  ffio_wfourcc(pb, "tmpo");
3505  avio_wb32(pb, size-8); /* size */
3506  ffio_wfourcc(pb, "data");
3507  avio_wb32(pb, 0x15); //type specifier
3508  avio_wb32(pb, 0);
3509  avio_wb16(pb, tmpo); // data
3510  }
3511  return size;
3512 }
3513 
3514 /* 3GPP TS 26.244 */
3516 {
3517  int lang;
3518  int64_t pos = avio_tell(pb);
3519  double latitude, longitude, altitude;
3520  int32_t latitude_fix, longitude_fix, altitude_fix;
3521  AVDictionaryEntry *t = get_metadata_lang(s, "location", &lang);
3522  const char *ptr, *place = "";
3523  char *end;
3524  static const char *astronomical_body = "earth";
3525  if (!t)
3526  return 0;
3527 
3528  ptr = t->value;
3529  longitude = 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  latitude = strtod(ptr, &end);
3536  if (end == ptr) {
3537  av_log(s, AV_LOG_WARNING, "malformed location metadata\n");
3538  return 0;
3539  }
3540  ptr = end;
3541  altitude = strtod(ptr, &end);
3542  /* If no altitude was present, the default 0 should be fine */
3543  if (*end == '/')
3544  place = end + 1;
3545 
3546  latitude_fix = (int32_t) ((1 << 16) * latitude);
3547  longitude_fix = (int32_t) ((1 << 16) * longitude);
3548  altitude_fix = (int32_t) ((1 << 16) * altitude);
3549 
3550  avio_wb32(pb, 0); /* size */
3551  ffio_wfourcc(pb, "loci"); /* type */
3552  avio_wb32(pb, 0); /* version + flags */
3553  avio_wb16(pb, lang);
3554  avio_write(pb, place, strlen(place) + 1);
3555  avio_w8(pb, 0); /* role of place (0 == shooting location, 1 == real location, 2 == fictional location) */
3556  avio_wb32(pb, latitude_fix);
3557  avio_wb32(pb, longitude_fix);
3558  avio_wb32(pb, altitude_fix);
3559  avio_write(pb, astronomical_body, strlen(astronomical_body) + 1);
3560  avio_w8(pb, 0); /* additional notes, null terminated string */
3561 
3562  return update_size(pb, pos);
3563 }
3564 
3565 /* iTunes track or disc number */
3567  AVFormatContext *s, int disc)
3568 {
3569  AVDictionaryEntry *t = av_dict_get(s->metadata,
3570  disc ? "disc" : "track",
3571  NULL, 0);
3572  int size = 0, track = t ? atoi(t->value) : 0;
3573  if (track) {
3574  int tracks = 0;
3575  char *slash = strchr(t->value, '/');
3576  if (slash)
3577  tracks = atoi(slash + 1);
3578  avio_wb32(pb, 32); /* size */
3579  ffio_wfourcc(pb, disc ? "disk" : "trkn");
3580  avio_wb32(pb, 24); /* size */
3581  ffio_wfourcc(pb, "data");
3582  avio_wb32(pb, 0); // 8 bytes empty
3583  avio_wb32(pb, 0);
3584  avio_wb16(pb, 0); // empty
3585  avio_wb16(pb, track); // track / disc number
3586  avio_wb16(pb, tracks); // total track / disc number
3587  avio_wb16(pb, 0); // empty
3588  size = 32;
3589  }
3590  return size;
3591 }
3592 
3594  const char *name, const char *tag,
3595  int len)
3596 {
3597  AVDictionaryEntry *t = NULL;
3598  uint8_t num;
3599  int size = 24 + len;
3600 
3601  if (len != 1 && len != 4)
3602  return -1;
3603 
3604  if (!(t = av_dict_get(s->metadata, tag, NULL, 0)))
3605  return 0;
3606  num = atoi(t->value);
3607 
3608  avio_wb32(pb, size);
3609  ffio_wfourcc(pb, name);
3610  avio_wb32(pb, size - 8);
3611  ffio_wfourcc(pb, "data");
3612  avio_wb32(pb, 0x15);
3613  avio_wb32(pb, 0);
3614  if (len==4) avio_wb32(pb, num);
3615  else avio_w8 (pb, num);
3616 
3617  return size;
3618 }
3619 
3621 {
3622  MOVMuxContext *mov = s->priv_data;
3623  int64_t pos = 0;
3624  int i;
3625 
3626  for (i = 0; i < s->nb_streams; i++) {
3627  MOVTrack *trk = &mov->tracks[i];
3628 
3629  if (!is_cover_image(trk->st) || trk->cover_image.size <= 0)
3630  continue;
3631 
3632  if (!pos) {
3633  pos = avio_tell(pb);
3634  avio_wb32(pb, 0);
3635  ffio_wfourcc(pb, "covr");
3636  }
3637  avio_wb32(pb, 16 + trk->cover_image.size);
3638  ffio_wfourcc(pb, "data");
3639  avio_wb32(pb, trk->tag);
3640  avio_wb32(pb , 0);
3641  avio_write(pb, trk->cover_image.data, trk->cover_image.size);
3642  }
3643 
3644  return pos ? update_size(pb, pos) : 0;
3645 }
3646 
3647 /* iTunes meta data list */
3649  AVFormatContext *s)
3650 {
3651  int64_t pos = avio_tell(pb);
3652  avio_wb32(pb, 0); /* size */
3653  ffio_wfourcc(pb, "ilst");
3654  mov_write_string_metadata(s, pb, "\251nam", "title" , 1);
3655  mov_write_string_metadata(s, pb, "\251ART", "artist" , 1);
3656  mov_write_string_metadata(s, pb, "aART", "album_artist", 1);
3657  mov_write_string_metadata(s, pb, "\251wrt", "composer" , 1);
3658  mov_write_string_metadata(s, pb, "\251alb", "album" , 1);
3659  mov_write_string_metadata(s, pb, "\251day", "date" , 1);
3660  if (!mov_write_string_metadata(s, pb, "\251too", "encoding_tool", 1)) {
3661  if (!(s->flags & AVFMT_FLAG_BITEXACT))
3662  mov_write_string_tag(pb, "\251too", LIBAVFORMAT_IDENT, 0, 1);
3663  }
3664  mov_write_string_metadata(s, pb, "\251cmt", "comment" , 1);
3665  mov_write_string_metadata(s, pb, "\251gen", "genre" , 1);
3666  mov_write_string_metadata(s, pb, "cprt", "copyright", 1);
3667  mov_write_string_metadata(s, pb, "\251grp", "grouping" , 1);
3668  mov_write_string_metadata(s, pb, "\251lyr", "lyrics" , 1);
3669  mov_write_string_metadata(s, pb, "desc", "description",1);
3670  mov_write_string_metadata(s, pb, "ldes", "synopsis" , 1);
3671  mov_write_string_metadata(s, pb, "tvsh", "show" , 1);
3672  mov_write_string_metadata(s, pb, "tven", "episode_id",1);
3673  mov_write_string_metadata(s, pb, "tvnn", "network" , 1);
3674  mov_write_string_metadata(s, pb, "keyw", "keywords" , 1);
3675  mov_write_int8_metadata (s, pb, "tves", "episode_sort",4);
3676  mov_write_int8_metadata (s, pb, "tvsn", "season_number",4);
3677  mov_write_int8_metadata (s, pb, "stik", "media_type",1);
3678  mov_write_int8_metadata (s, pb, "hdvd", "hd_video", 1);
3679  mov_write_int8_metadata (s, pb, "pgap", "gapless_playback",1);
3680  mov_write_int8_metadata (s, pb, "cpil", "compilation", 1);
3681  mov_write_covr(pb, s);
3682  mov_write_trkn_tag(pb, mov, s, 0); // track number
3683  mov_write_trkn_tag(pb, mov, s, 1); // disc number
3684  mov_write_tmpo_tag(pb, s);
3685  return update_size(pb, pos);
3686 }
3687 
3689  AVFormatContext *s)
3690 {
3691  avio_wb32(pb, 33); /* size */
3692  ffio_wfourcc(pb, "hdlr");
3693  avio_wb32(pb, 0);
3694  avio_wb32(pb, 0);
3695  ffio_wfourcc(pb, "mdta");
3696  avio_wb32(pb, 0);
3697  avio_wb32(pb, 0);
3698  avio_wb32(pb, 0);
3699  avio_w8(pb, 0);
3700  return 33;
3701 }
3702 
3704  AVFormatContext *s)
3705 {
3706  AVDictionaryEntry *t = NULL;
3707  int64_t pos = avio_tell(pb);
3708  int64_t curpos, entry_pos;
3709  int count = 0;
3710 
3711  avio_wb32(pb, 0); /* size */
3712  ffio_wfourcc(pb, "keys");
3713  avio_wb32(pb, 0);
3714  entry_pos = avio_tell(pb);
3715  avio_wb32(pb, 0); /* entry count */
3716 
3717  while (t = av_dict_get(s->metadata, "", t, AV_DICT_IGNORE_SUFFIX)) {
3718  avio_wb32(pb, strlen(t->key) + 8);
3719  ffio_wfourcc(pb, "mdta");
3720  avio_write(pb, t->key, strlen(t->key));
3721  count += 1;
3722  }
3723  curpos = avio_tell(pb);
3724  avio_seek(pb, entry_pos, SEEK_SET);
3725  avio_wb32(pb, count); // rewrite entry count
3726  avio_seek(pb, curpos, SEEK_SET);
3727 
3728  return update_size(pb, pos);
3729 }
3730 
3732  AVFormatContext *s)
3733 {
3734  AVDictionaryEntry *t = NULL;
3735  int64_t pos = avio_tell(pb);
3736  int count = 1; /* keys are 1-index based */
3737 
3738  avio_wb32(pb, 0); /* size */
3739  ffio_wfourcc(pb, "ilst");
3740 
3741  while (t = av_dict_get(s->metadata, "", t, AV_DICT_IGNORE_SUFFIX)) {
3742  int64_t entry_pos = avio_tell(pb);
3743  avio_wb32(pb, 0); /* size */
3744  avio_wb32(pb, count); /* key */
3745  mov_write_string_data_tag(pb, t->value, 0, 1);
3746  update_size(pb, entry_pos);
3747  count += 1;
3748  }
3749  return update_size(pb, pos);
3750 }
3751 
3752 /* meta data tags */
3754  AVFormatContext *s)
3755 {
3756  int size = 0;
3757  int64_t pos = avio_tell(pb);
3758  avio_wb32(pb, 0); /* size */
3759  ffio_wfourcc(pb, "meta");
3760  avio_wb32(pb, 0);
3761  if (mov->flags & FF_MOV_FLAG_USE_MDTA) {
3762  mov_write_mdta_hdlr_tag(pb, mov, s);
3763  mov_write_mdta_keys_tag(pb, mov, s);
3764  mov_write_mdta_ilst_tag(pb, mov, s);
3765  }
3766  else {
3767  /* iTunes metadata tag */
3768  mov_write_itunes_hdlr_tag(pb, mov, s);
3769  mov_write_ilst_tag(pb, mov, s);
3770  }
3771  size = update_size(pb, pos);
3772  return size;
3773 }
3774 
3776  const char *name, const char *key)
3777 {
3778  int len;
3779  AVDictionaryEntry *t;
3780 
3781  if (!(t = av_dict_get(s->metadata, key, NULL, 0)))
3782  return 0;
3783 
3784  len = strlen(t->value);
3785  if (len > 0) {
3786  int size = len + 8;
3787  avio_wb32(pb, size);
3788  ffio_wfourcc(pb, name);
3789  avio_write(pb, t->value, len);
3790  return size;
3791  }
3792  return 0;
3793 }
3794 
3795 static int ascii_to_wc(AVIOContext *pb, const uint8_t *b)
3796 {
3797  int val;
3798  while (*b) {
3799  GET_UTF8(val, *b++, return -1;)
3800  avio_wb16(pb, val);
3801  }
3802  avio_wb16(pb, 0x00);
3803  return 0;
3804 }
3805 
3806 static uint16_t language_code(const char *str)
3807 {
3808  return (((str[0] - 0x60) & 0x1F) << 10) +
3809  (((str[1] - 0x60) & 0x1F) << 5) +
3810  (( str[2] - 0x60) & 0x1F);
3811 }
3812 
3814  const char *tag, const char *str)
3815 {
3816  int64_t pos = avio_tell(pb);
3817  AVDictionaryEntry *t = av_dict_get(s->metadata, str, NULL, 0);
3818  if (!t || !utf8len(t->value))
3819  return 0;
3820  avio_wb32(pb, 0); /* size */
3821  ffio_wfourcc(pb, tag); /* type */
3822  avio_wb32(pb, 0); /* version + flags */
3823  if (!strcmp(tag, "yrrc"))
3824  avio_wb16(pb, atoi(t->value));
3825  else {
3826  avio_wb16(pb, language_code("eng")); /* language */
3827  avio_write(pb, t->value, strlen(t->value) + 1); /* UTF8 string value */
3828  if (!strcmp(tag, "albm") &&
3829  (t = av_dict_get(s->metadata, "track", NULL, 0)))
3830  avio_w8(pb, atoi(t->value));
3831  }
3832  return update_size(pb, pos);
3833 }
3834 
3836 {
3837  int64_t pos = avio_tell(pb);
3838  int i, nb_chapters = FFMIN(s->nb_chapters, 255);
3839 
3840  avio_wb32(pb, 0); // size
3841  ffio_wfourcc(pb, "chpl");
3842  avio_wb32(pb, 0x01000000); // version + flags
3843  avio_wb32(pb, 0); // unknown
3844  avio_w8(pb, nb_chapters);
3845 
3846  for (i = 0; i < nb_chapters; i++) {
3847  AVChapter *c = s->chapters[i];
3848  AVDictionaryEntry *t;
3849  avio_wb64(pb, av_rescale_q(c->start, c->time_base, (AVRational){1,10000000}));
3850 
3851  if ((t = av_dict_get(c->metadata, "title", NULL, 0))) {
3852  int len = FFMIN(strlen(t->value), 255);
3853  avio_w8(pb, len);
3854  avio_write(pb, t->value, len);
3855  } else
3856  avio_w8(pb, 0);
3857  }
3858  return update_size(pb, pos);
3859 }
3860 
3862  AVFormatContext *s)
3863 {
3864  AVIOContext *pb_buf;
3865  int ret, size;
3866  uint8_t *buf;
3867 
3868  ret = avio_open_dyn_buf(&pb_buf);
3869  if (ret < 0)
3870  return ret;
3871 
3872  if (mov->mode & MODE_3GP) {
3873  mov_write_3gp_udta_tag(pb_buf, s, "perf", "artist");
3874  mov_write_3gp_udta_tag(pb_buf, s, "titl", "title");
3875  mov_write_3gp_udta_tag(pb_buf, s, "auth", "author");
3876  mov_write_3gp_udta_tag(pb_buf, s, "gnre", "genre");
3877  mov_write_3gp_udta_tag(pb_buf, s, "dscp", "comment");
3878  mov_write_3gp_udta_tag(pb_buf, s, "albm", "album");
3879  mov_write_3gp_udta_tag(pb_buf, s, "cprt", "copyright");
3880  mov_write_3gp_udta_tag(pb_buf, s, "yrrc", "date");
3881  mov_write_loci_tag(s, pb_buf);
3882  } 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
3883  mov_write_string_metadata(s, pb_buf, "\251ART", "artist", 0);
3884  mov_write_string_metadata(s, pb_buf, "\251nam", "title", 0);
3885  mov_write_string_metadata(s, pb_buf, "\251aut", "author", 0);
3886  mov_write_string_metadata(s, pb_buf, "\251alb", "album", 0);
3887  mov_write_string_metadata(s, pb_buf, "\251day", "date", 0);
3888  mov_write_string_metadata(s, pb_buf, "\251swr", "encoder", 0);
3889  // currently ignored by mov.c
3890  mov_write_string_metadata(s, pb_buf, "\251des", "comment", 0);
3891  // add support for libquicktime, this atom is also actually read by mov.c
3892  mov_write_string_metadata(s, pb_buf, "\251cmt", "comment", 0);
3893  mov_write_string_metadata(s, pb_buf, "\251gen", "genre", 0);
3894  mov_write_string_metadata(s, pb_buf, "\251cpy", "copyright", 0);
3895  mov_write_string_metadata(s, pb_buf, "\251mak", "make", 0);
3896  mov_write_string_metadata(s, pb_buf, "\251mod", "model", 0);
3897  mov_write_string_metadata(s, pb_buf, "\251xyz", "location", 0);
3898  mov_write_string_metadata(s, pb_buf, "\251key", "keywords", 0);
3899  mov_write_raw_metadata_tag(s, pb_buf, "XMP_", "xmp");
3900  } else {
3901  /* iTunes meta data */
3902  mov_write_meta_tag(pb_buf, mov, s);
3903  mov_write_loci_tag(s, pb_buf);
3904  }
3905 
3906  if (s->nb_chapters && !(mov->flags & FF_MOV_FLAG_DISABLE_CHPL))
3907  mov_write_chpl_tag(pb_buf, s);
3908 
3909  if ((size = avio_get_dyn_buf(pb_buf, &buf)) > 0) {
3910  avio_wb32(pb, size + 8);
3911  ffio_wfourcc(pb, "udta");
3912  avio_write(pb, buf, size);
3913  }
3914  ffio_free_dyn_buf(&pb_buf);
3915 
3916  return 0;
3917 }
3918 
3920  const char *str, const char *lang, int type)
3921 {
3922  int len = utf8len(str) + 1;
3923  if (len <= 0)
3924  return;
3925  avio_wb16(pb, len * 2 + 10); /* size */
3926  avio_wb32(pb, type); /* type */
3927  avio_wb16(pb, language_code(lang)); /* language */
3928  avio_wb16(pb, 0x01); /* ? */
3929  ascii_to_wc(pb, str);
3930 }
3931 
3933 {
3934  AVDictionaryEntry *title = av_dict_get(s->metadata, "title", NULL, 0);
3935  int64_t pos, pos2;
3936 
3937  if (title) {
3938  pos = avio_tell(pb);
3939  avio_wb32(pb, 0); /* size placeholder*/
3940  ffio_wfourcc(pb, "uuid");
3941  ffio_wfourcc(pb, "USMT");
3942  avio_wb32(pb, 0x21d24fce); /* 96 bit UUID */
3943  avio_wb32(pb, 0xbb88695c);
3944  avio_wb32(pb, 0xfac9c740);
3945 
3946  pos2 = avio_tell(pb);
3947  avio_wb32(pb, 0); /* size placeholder*/
3948  ffio_wfourcc(pb, "MTDT");
3949  avio_wb16(pb, 4);
3950 
3951  // ?
3952  avio_wb16(pb, 0x0C); /* size */
3953  avio_wb32(pb, 0x0B); /* type */
3954  avio_wb16(pb, language_code("und")); /* language */
3955  avio_wb16(pb, 0x0); /* ? */
3956  avio_wb16(pb, 0x021C); /* data */
3957 
3958  if (!(s->flags & AVFMT_FLAG_BITEXACT))
3959  mov_write_psp_udta_tag(pb, LIBAVCODEC_IDENT, "eng", 0x04);
3960  mov_write_psp_udta_tag(pb, title->value, "eng", 0x01);
3961  mov_write_psp_udta_tag(pb, "2006/04/01 11:11:11", "und", 0x03);
3962 
3963  update_size(pb, pos2);
3964  return update_size(pb, pos);
3965  }
3966 
3967  return 0;
3968 }
3969 
3970 static void build_chunks(MOVTrack *trk)
3971 {
3972  int i;
3973  MOVIentry *chunk = &trk->cluster[0];
3974  uint64_t chunkSize = chunk->size;
3975  chunk->chunkNum = 1;
3976  if (trk->chunkCount)
3977  return;
3978  trk->chunkCount = 1;
3979  for (i = 1; i<trk->entry; i++){
3980  if (chunk->pos + chunkSize == trk->cluster[i].pos &&
3981  chunkSize + trk->cluster[i].size < (1<<20)){
3982  chunkSize += trk->cluster[i].size;
3983  chunk->samples_in_chunk += trk->cluster[i].entries;
3984  } else {
3985  trk->cluster[i].chunkNum = chunk->chunkNum+1;
3986  chunk=&trk->cluster[i];
3987  chunkSize = chunk->size;
3988  trk->chunkCount++;
3989  }
3990  }
3991 }
3992 
3993 /**
3994  * Assign track ids. If option "use_stream_ids_as_track_ids" is set,
3995  * the stream ids are used as track ids.
3996  *
3997  * This assumes mov->tracks and s->streams are in the same order and
3998  * there are no gaps in either of them (so mov->tracks[n] refers to
3999  * s->streams[n]).
4000  *
4001  * As an exception, there can be more entries in
4002  * s->streams than in mov->tracks, in which case new track ids are
4003  * generated (starting after the largest found stream id).
4004  */
4006 {
4007  int i;
4008 
4009  if (mov->track_ids_ok)
4010  return 0;
4011 
4012  if (mov->use_stream_ids_as_track_ids) {
4013  int next_generated_track_id = 0;
4014  for (i = 0; i < s->nb_streams; i++) {
4015  if (s->streams[i]->id > next_generated_track_id)
4016  next_generated_track_id = s->streams[i]->id;
4017  }
4018 
4019  for (i = 0; i < mov->nb_streams; i++) {
4020  if (mov->tracks[i].entry <= 0 && !(mov->flags & FF_MOV_FLAG_FRAGMENT))
4021  continue;
4022 
4023  mov->tracks[i].track_id = i >= s->nb_streams ? ++next_generated_track_id : s->streams[i]->id;
4024  }
4025  } else {
4026  for (i = 0; i < mov->nb_streams; i++) {
4027  if (mov->tracks[i].entry <= 0 && !(mov->flags & FF_MOV_FLAG_FRAGMENT))
4028  continue;
4029 
4030  mov->tracks[i].track_id = i + 1;
4031  }
4032  }
4033 
4034  mov->track_ids_ok = 1;
4035 
4036  return 0;
4037 }
4038 
4040  AVFormatContext *s)
4041 {
4042  int i;
4043  int64_t pos = avio_tell(pb);
4044  avio_wb32(pb, 0); /* size placeholder*/
4045  ffio_wfourcc(pb, "moov");
4046 
4047  mov_setup_track_ids(mov, s);
4048 
4049  for (i = 0; i < mov->nb_streams; i++) {
4050  if (mov->tracks[i].entry <= 0 && !(mov->flags & FF_MOV_FLAG_FRAGMENT))
4051  continue;
4052 
4053  mov->tracks[i].time = mov->time;
4054 
4055  if (mov->tracks[i].entry)
4056  build_chunks(&mov->tracks[i]);
4057  }
4058 
4059  if (mov->chapter_track)
4060  for (i = 0; i < s->nb_streams; i++) {
4061  mov->tracks[i].tref_tag = MKTAG('c','h','a','p');
4062  mov->tracks[i].tref_id = mov->tracks[mov->chapter_track].track_id;
4063  }
4064  for (i = 0; i < mov->nb_streams; i++) {
4065  MOVTrack *track = &mov->tracks[i];
4066  if (track->tag == MKTAG('r','t','p',' ')) {
4067  track->tref_tag = MKTAG('h','i','n','t');
4068  track->tref_id = mov->tracks[track->src_track].track_id;
4069  } else if (track->par->codec_type == AVMEDIA_TYPE_AUDIO) {
4070  int * fallback, size;
4071  fallback = (int*)av_stream_get_side_data(track->st,
4073  &size);
4074  if (fallback != NULL && size == sizeof(int)) {
4075  if (*fallback >= 0 && *fallback < mov->nb_streams) {
4076  track->tref_tag = MKTAG('f','a','l','l');
4077  track->tref_id = mov->tracks[*fallback].track_id;
4078  }
4079  }
4080  }
4081  }
4082  for (i = 0; i < mov->nb_streams; i++) {
4083  if (mov->tracks[i].tag == MKTAG('t','m','c','d')) {
4084  int src_trk = mov->tracks[i].src_track;
4085  mov->tracks[src_trk].tref_tag = mov->tracks[i].tag;
4086  mov->tracks[src_trk].tref_id = mov->tracks[i].track_id;
4087  //src_trk may have a different timescale than the tmcd track
4088  mov->tracks[i].track_duration = av_rescale(mov->tracks[src_trk].track_duration,
4089  mov->tracks[i].timescale,
4090  mov->tracks[src_trk].timescale);
4091  }
4092  }
4093 
4094  mov_write_mvhd_tag(pb, mov);
4095  if (mov->mode != MODE_MOV && !mov->iods_skip)
4096  mov_write_iods_tag(pb, mov);
4097  for (i = 0; i < mov->nb_streams; i++) {
4098  if (mov->tracks[i].entry > 0 || mov->flags & FF_MOV_FLAG_FRAGMENT) {
4099  int ret = mov_write_trak_tag(s, pb, mov, &(mov->tracks[i]), i < s->nb_streams ? s->streams[i] : NULL);
4100  if (ret < 0)
4101  return ret;
4102  }
4103  }
4104  if (mov->flags & FF_MOV_FLAG_FRAGMENT)
4105  mov_write_mvex_tag(pb, mov); /* QuickTime requires trak to precede this */
4106 
4107  if (mov->mode == MODE_PSP)
4109  else
4110  mov_write_udta_tag(pb, mov, s);
4111 
4112  return update_size(pb, pos);
4113 }
4114 
4115 static void param_write_int(AVIOContext *pb, const char *name, int value)
4116 {
4117  avio_printf(pb, "<param name=\"%s\" value=\"%d\" valuetype=\"data\"/>\n", name, value);
4118 }
4119 
4120 static void param_write_string(AVIOContext *pb, const char *name, const char *value)
4121 {
4122  avio_printf(pb, "<param name=\"%s\" value=\"%s\" valuetype=\"data\"/>\n", name, value);
4123 }
4124 
4125 static void param_write_hex(AVIOContext *pb, const char *name, const uint8_t *value, int len)
4126 {
4127  char buf[150];
4128  len = FFMIN(sizeof(buf) / 2 - 1, len);
4129  ff_data_to_hex(buf, value, len, 0);
4130  buf[2 * len] = '\0';
4131  avio_printf(pb, "<param name=\"%s\" value=\"%s\" valuetype=\"data\"/>\n", name, buf);
4132 }
4133 
4135 {
4136  int64_t pos = avio_tell(pb);
4137  int i;
4138  int64_t manifest_bit_rate = 0;
4139  AVCPBProperties *props = NULL;
4140 
4141  static const uint8_t uuid[] = {
4142  0xa5, 0xd4, 0x0b, 0x30, 0xe8, 0x14, 0x11, 0xdd,
4143  0xba, 0x2f, 0x08, 0x00, 0x20, 0x0c, 0x9a, 0x66
4144  };
4145 
4146  avio_wb32(pb, 0);
4147  ffio_wfourcc(pb, "uuid");
4148  avio_write(pb, uuid, sizeof(uuid));
4149  avio_wb32(pb, 0);
4150 
4151  avio_printf(pb, "<?xml version=\"1.0\" encoding=\"utf-8\"?>\n");
4152  avio_printf(pb, "<smil xmlns=\"http://www.w3.org/2001/SMIL20/Language\">\n");
4153  avio_printf(pb, "<head>\n");
4154  if (!(mov->fc->flags & AVFMT_FLAG_BITEXACT))
4155  avio_printf(pb, "<meta name=\"creator\" content=\"%s\" />\n",
4157  avio_printf(pb, "</head>\n");
4158  avio_printf(pb, "<body>\n");
4159  avio_printf(pb, "<switch>\n");
4160 
4161  mov_setup_track_ids(mov, s);
4162 
4163  for (i = 0; i < mov->nb_streams; i++) {
4164  MOVTrack *track = &mov->tracks[i];
4165  const char *type;
4166  int track_id = track->track_id;
4167  char track_name_buf[32] = { 0 };
4168 
4169  AVStream *st = track->st;
4170  AVDictionaryEntry *lang = av_dict_get(st->metadata, "language", NULL,0);
4171 
4172  if (track->par->codec_type == AVMEDIA_TYPE_VIDEO && !is_cover_image(st)) {
4173  type = "video";
4174  } else if (track->par->codec_type == AVMEDIA_TYPE_AUDIO) {
4175  type = "audio";
4176  } else {
4177  continue;
4178  }
4179 
4181 
4182  if (track->par->bit_rate) {
4183  manifest_bit_rate = track->par->bit_rate;
4184  } else if (props) {
4185  manifest_bit_rate = props->max_bitrate;
4186  }
4187 
4188  avio_printf(pb, "<%s systemBitrate=\"%"PRId64"\">\n", type,
4189  manifest_bit_rate);
4190  param_write_int(pb, "systemBitrate", manifest_bit_rate);
4191  param_write_int(pb, "trackID", track_id);
4192  param_write_string(pb, "systemLanguage", lang ? lang->value : "und");
4193 
4194  /* Build track name piece by piece: */
4195  /* 1. track type */
4196  av_strlcat(track_name_buf, type, sizeof(track_name_buf));
4197  /* 2. track language, if available */
4198  if (lang)
4199  av_strlcatf(track_name_buf, sizeof(track_name_buf),
4200  "_%s", lang->value);
4201  /* 3. special type suffix */
4202  /* "_cc" = closed captions, "_ad" = audio_description */
4204  av_strlcat(track_name_buf, "_cc", sizeof(track_name_buf));
4206  av_strlcat(track_name_buf, "_ad", sizeof(track_name_buf));
4207 
4208  param_write_string(pb, "trackName", track_name_buf);
4209 
4210  if (track->par->codec_type == AVMEDIA_TYPE_VIDEO) {
4211  if (track->par->codec_id == AV_CODEC_ID_H264) {
4212  uint8_t *ptr;
4213  int size = track->par->extradata_size;
4214  if (!ff_avc_write_annexb_extradata(track->par->extradata, &ptr,
4215  &size)) {
4216  param_write_hex(pb, "CodecPrivateData",
4217  ptr ? ptr : track->par->extradata,
4218  size);
4219  av_free(ptr);
4220  }
4221  param_write_string(pb, "FourCC", "H264");
4222  } else if (track->par->codec_id == AV_CODEC_ID_VC1) {
4223  param_write_string(pb, "FourCC", "WVC1");
4224  param_write_hex(pb, "CodecPrivateData", track->par->extradata,
4225  track->par->extradata_size);
4226  }
4227  param_write_int(pb, "MaxWidth", track->par->width);
4228  param_write_int(pb, "MaxHeight", track->par->height);
4229  param_write_int(pb, "DisplayWidth", track->par->width);
4230  param_write_int(pb, "DisplayHeight", track->par->height);
4231  } else {
4232  if (track->par->codec_id == AV_CODEC_ID_AAC) {
4233  switch (track->par->profile)
4234  {
4235  case FF_PROFILE_AAC_HE_V2:
4236  param_write_string(pb, "FourCC", "AACP");
4237  break;
4238  case FF_PROFILE_AAC_HE:
4239  param_write_string(pb, "FourCC", "AACH");
4240  break;
4241  default:
4242  param_write_string(pb, "FourCC", "AACL");
4243  }
4244  } else if (track->par->codec_id == AV_CODEC_ID_WMAPRO) {
4245  param_write_string(pb, "FourCC", "WMAP");
4246  }
4247  param_write_hex(pb, "CodecPrivateData", track->par->extradata,
4248  track->par->extradata_size);
4250  track->par->codec_id));
4251  param_write_int(pb, "Channels", track->par->channels);
4252  param_write_int(pb, "SamplingRate", track->par->sample_rate);
4253  param_write_int(pb, "BitsPerSample", 16);
4254  param_write_int(pb, "PacketSize", track->par->block_align ?
4255  track->par->block_align : 4);
4256  }
4257  avio_printf(pb, "</%s>\n", type);
4258  }
4259  avio_printf(pb, "</switch>\n");
4260  avio_printf(pb, "</body>\n");
4261  avio_printf(pb, "</smil>\n");
4262 
4263  return update_size(pb, pos);
4264 }
4265 
4267 {
4268  avio_wb32(pb, 16);
4269  ffio_wfourcc(pb, "mfhd");
4270  avio_wb32(pb, 0);
4271  avio_wb32(pb, mov->fragments);
4272  return 0;
4273 }
4274 
4275 static uint32_t get_sample_flags(MOVTrack *track, MOVIentry *entry)
4276 {
4279 }
4280 
4282  MOVTrack *track, int64_t moof_offset)
4283 {
4284  int64_t pos = avio_tell(pb);
4287  if (!track->entry) {
4289  } else {
4291  }
4294  if (mov->flags & FF_MOV_FLAG_DEFAULT_BASE_MOOF) {
4297  }
4298  /* CMAF requires all values to be explicit in tfhd atoms */
4299  if (mov->flags & FF_MOV_FLAG_CMAF)
4301 
4302  /* Don't set a default sample size, the silverlight player refuses
4303  * to play files with that set. Don't set a default sample duration,
4304  * WMP freaks out if it is set. Don't set a base data offset, PIFF
4305  * file format says it MUST NOT be set. */
4306  if (track->mode == MODE_ISM)
4309 
4310  avio_wb32(pb, 0); /* size placeholder */
4311  ffio_wfourcc(pb, "tfhd");
4312  avio_w8(pb, 0); /* version */
4313  avio_wb24(pb, flags);
4314 
4315  avio_wb32(pb, track->track_id); /* track-id */
4317  avio_wb64(pb, moof_offset);
4318  if (flags & MOV_TFHD_STSD_ID) {
4319  avio_wb32(pb, 1);
4320  }
4322  track->default_duration = get_cluster_duration(track, 0);
4323  avio_wb32(pb, track->default_duration);
4324  }
4325  if (flags & MOV_TFHD_DEFAULT_SIZE) {
4326  track->default_size = track->entry ? track->cluster[0].size : 1;
4327  avio_wb32(pb, track->default_size);
4328  } else
4329  track->default_size = -1;
4330 
4331  if (flags & MOV_TFHD_DEFAULT_FLAGS) {
4332  /* Set the default flags based on the second sample, if available.
4333  * If the first sample is different, that can be signaled via a separate field. */
4334  if (track->entry > 1)
4335  track->default_sample_flags = get_sample_flags(track, &track->cluster[1]);
4336  else
4337  track->default_sample_flags =
4338  track->par->codec_type == AVMEDIA_TYPE_VIDEO ?
4341  avio_wb32(pb, track->default_sample_flags);
4342  }
4343 
4344  return update_size(pb, pos);
4345 }
4346 
4348  MOVTrack *track, int moof_size,
4349  int first, int end)
4350 {
4351  int64_t pos = avio_tell(pb);
4352  uint32_t flags = MOV_TRUN_DATA_OFFSET;
4353  int i;
4354 
4355  for (i = first; i < end; i++) {
4356  if (get_cluster_duration(track, i) != track->default_duration)
4358  if (track->cluster[i].size != track->default_size)
4360  if (i > first && get_sample_flags(track, &track->cluster[i]) != track->default_sample_flags)
4362  }
4363  if (!(flags & MOV_TRUN_SAMPLE_FLAGS) && track->entry > 0 &&
4364  get_sample_flags(track, &track->cluster[0]) != track->default_sample_flags)
4366  if (track->flags & MOV_TRACK_CTTS)
4368 
4369  avio_wb32(pb, 0); /* size placeholder */
4370  ffio_wfourcc(pb, "trun");
4372  avio_w8(pb, 1); /* version */
4373  else
4374  avio_w8(pb, 0); /* version */
4375  avio_wb24(pb, flags);
4376 
4377  avio_wb32(pb, end - first); /* sample count */
4378  if (mov->flags & FF_MOV_FLAG_OMIT_TFHD_OFFSET &&
4380  !mov->first_trun)
4381  avio_wb32(pb, 0); /* Later tracks follow immediately after the previous one */
4382  else
4383  avio_wb32(pb, moof_size + 8 + track->data_offset +
4384  track->cluster[first].pos); /* data offset */
4386  avio_wb32(pb, get_sample_flags(track, &track->cluster[first]));
4387 
4388  for (i = first; i < end; i++) {
4390  avio_wb32(pb, get_cluster_duration(track, i));
4392  avio_wb32(pb, track->cluster[i].size);
4394  avio_wb32(pb, get_sample_flags(track, &track->cluster[i]));
4395  if (flags & MOV_TRUN_SAMPLE_CTS)
4396  avio_wb32(pb, track->cluster[i].cts);
4397  }
4398 
4399  mov->first_trun = 0;
4400  return update_size(pb, pos);
4401 }
4402 
4403 static int mov_write_tfxd_tag(AVIOContext *pb, MOVTrack *track)
4404 {
4405  int64_t pos = avio_tell(pb);
4406  static const uint8_t uuid[] = {
4407  0x6d, 0x1d, 0x9b, 0x05, 0x42, 0xd5, 0x44, 0xe6,
4408  0x80, 0xe2, 0x14, 0x1d, 0xaf, 0xf7, 0x57, 0xb2
4409  };
4410 
4411  avio_wb32(pb, 0); /* size placeholder */
4412  ffio_wfourcc(pb, "uuid");
4413  avio_write(pb, uuid, sizeof(uuid));
4414  avio_w8(pb, 1);
4415  avio_wb24(pb, 0);
4416  avio_wb64(pb, track->start_dts + track->frag_start +
4417  track->cluster[0].cts);
4418  avio_wb64(pb, track->end_pts -
4419  (track->cluster[0].dts + track->cluster[0].cts));
4420 
4421  return update_size(pb, pos);
4422 }
4423 
4425  MOVTrack *track, int entry)
4426 {
4427  int n = track->nb_frag_info - 1 - entry, i;
4428  int size = 8 + 16 + 4 + 1 + 16*n;
4429  static const uint8_t uuid[] = {
4430  0xd4, 0x80, 0x7e, 0xf2, 0xca, 0x39, 0x46, 0x95,
4431  0x8e, 0x54, 0x26, 0xcb, 0x9e, 0x46, 0xa7, 0x9f
4432  };
4433 
4434  if (entry < 0)
4435  return 0;
4436 
4437  avio_seek(pb, track->frag_info[entry].tfrf_offset, SEEK_SET);
4438  avio_wb32(pb, size);
4439  ffio_wfourcc(pb, "uuid");
4440  avio_write(pb, uuid, sizeof(uuid));
4441  avio_w8(pb, 1);
4442  avio_wb24(pb, 0);
4443  avio_w8(pb, n);
4444  for (i = 0; i < n; i++) {
4445  int index = entry + 1 + i;
4446  avio_wb64(pb, track->frag_info[index].time);
4447  avio_wb64(pb, track->frag_info[index].duration);
4448  }
4449  if (n < mov->ism_lookahead) {
4450  int free_size = 16 * (mov->ism_lookahead - n);
4451  avio_wb32(pb, free_size);
4452  ffio_wfourcc(pb, "free");
4453  ffio_fill(pb, 0, free_size - 8);
4454  }
4455 
4456  return 0;
4457 }
4458 
4460  MOVTrack *track)
4461 {
4462  int64_t pos = avio_tell(pb);
4463  int i;
4464  for (i = 0; i < mov->ism_lookahead; i++) {
4465  /* Update the tfrf tag for the last ism_lookahead fragments,
4466  * nb_frag_info - 1 is the next fragment to be written. */
4467  mov_write_tfrf_tag(pb, mov, track, track->nb_frag_info - 2 - i);
4468  }
4469  avio_seek(pb, pos, SEEK_SET);
4470  return 0;
4471 }
4472 
4473 static int mov_add_tfra_entries(AVIOContext *pb, MOVMuxContext *mov, int tracks,
4474  int size)
4475 {
4476  int i;
4477  for (i = 0; i < mov->nb_streams; i++) {
4478  MOVTrack *track = &mov->tracks[i];
4480  if ((tracks >= 0 && i != tracks) || !track->entry)
4481  continue;
4482  track->nb_frag_info++;
4483  if (track->nb_frag_info >= track->frag_info_capacity) {
4484  unsigned new_capacity = track->nb_frag_info + MOV_FRAG_INFO_ALLOC_INCREMENT;
4485  if (av_reallocp_array(&track->frag_info,
4486  new_capacity,
4487  sizeof(*track->frag_info)))
4488  return AVERROR(ENOMEM);
4489  track->frag_info_capacity = new_capacity;
4490  }
4491  info = &track->frag_info[track->nb_frag_info - 1];
4492  info->offset = avio_tell(pb);
4493  info->size = size;
4494  // Try to recreate the original pts for the first packet
4495  // from the fields we have stored
4496  info->time = track->start_dts + track->frag_start +
4497  track->cluster[0].cts;
4498  info->duration = track->end_pts -
4499  (track->cluster[0].dts + track->cluster[0].cts);
4500  // If the pts is less than zero, we will have trimmed
4501  // away parts of the media track using an edit list,
4502  // and the corresponding start presentation time is zero.
4503  if (info->time < 0) {
4504  info->duration += info->time;
4505  info->time = 0;
4506  }
4507  info->tfrf_offset = 0;
4508  mov_write_tfrf_tags(pb, mov, track);
4509  }
4510  return 0;
4511 }
4512 
4513 static void mov_prune_frag_info(MOVMuxContext *mov, int tracks, int max)
4514 {
4515  int i;
4516  for (i = 0; i < mov->nb_streams; i++) {
4517  MOVTrack *track = &mov->tracks[i];
4518  if ((tracks >= 0 && i != tracks) || !track->entry)
4519  continue;
4520  if (track->nb_frag_info > max) {
4521  memmove(track->frag_info, track->frag_info + (track->nb_frag_info - max), max * sizeof(*track->frag_info));
4522  track->nb_frag_info = max;
4523  }
4524  }
4525 }
4526 
4527 static int mov_write_tfdt_tag(AVIOContext *pb, MOVTrack *track)
4528 {
4529  int64_t pos = avio_tell(pb);
4530 
4531  avio_wb32(pb, 0); /* size */
4532  ffio_wfourcc(pb, "tfdt");
4533  avio_w8(pb, 1); /* version */
4534  avio_wb24(pb, 0);
4535  avio_wb64(pb, track->frag_start);
4536  return update_size(pb, pos);
4537 }
4538 
4540  MOVTrack *track, int64_t moof_offset,
4541  int moof_size)
4542 {
4543  int64_t pos = avio_tell(pb);
4544  int i, start = 0;
4545  avio_wb32(pb, 0); /* size placeholder */
4546  ffio_wfourcc(pb, "traf");
4547 
4548  mov_write_tfhd_tag(pb, mov, track, moof_offset);
4549  if (mov->mode != MODE_ISM)
4550  mov_write_tfdt_tag(pb, track);
4551  for (i = 1; i < track->entry; i++) {
4552  if (track->cluster[i].pos != track->cluster[i - 1].pos + track->cluster[i - 1].size) {
4553  mov_write_trun_tag(pb, mov, track, moof_size, start, i);
4554  start = i;
4555  }
4556  }
4557  mov_write_trun_tag(pb, mov, track, moof_size, start, track->entry);
4558  if (mov->mode == MODE_ISM) {
4559  mov_write_tfxd_tag(pb, track);
4560 
4561  if (mov->ism_lookahead) {
4562  int i, size = 16 + 4 + 1 + 16 * mov->ism_lookahead;
4563 
4564  if (track->nb_frag_info > 0) {
4565  MOVFragmentInfo *info = &track->frag_info[track->nb_frag_info - 1];
4566  if (!info->tfrf_offset)
4567  info->tfrf_offset = avio_tell(pb);
4568  }
4569  avio_wb32(pb, 8 + size);
4570  ffio_wfourcc(pb, "free");
4571  for (i = 0; i < size; i++)
4572  avio_w8(pb, 0);
4573  }
4574  }
4575 
4576  return update_size(pb, pos);
4577 }
4578 
4580  int tracks, int moof_size)
4581 {
4582  int64_t pos = avio_tell(pb);
4583  int i;
4584 
4585  avio_wb32(pb, 0); /* size placeholder */
4586  ffio_wfourcc(pb, "moof");
4587  mov->first_trun = 1;
4588 
4589  mov_write_mfhd_tag(pb, mov);
4590  for (i = 0; i < mov->nb_streams; i++) {
4591  MOVTrack *track = &mov->tracks[i];
4592  if (tracks >= 0 && i != tracks)
4593  continue;
4594  if (!track->entry)
4595  continue;
4596  mov_write_traf_tag(pb, mov, track, pos, moof_size);
4597  }
4598 
4599  return update_size(pb, pos);
4600 }
4601 
4603  MOVTrack *track, int ref_size, int total_sidx_size)
4604 {
4605  int64_t pos = avio_tell(pb), offset_pos, end_pos;
4606  int64_t presentation_time, duration, offset;
4607  unsigned starts_with_SAP;
4608  int i, entries;
4609 
4610  if (track->entry) {
4611  entries = 1;
4612  presentation_time = track->start_dts + track->frag_start +
4613  track->cluster[0].cts;
4614  duration = track->end_pts -
4615  (track->cluster[0].dts + track->cluster[0].cts);
4616  starts_with_SAP = track->cluster[0].flags & MOV_SYNC_SAMPLE;
4617 
4618  // pts<0 should be cut away using edts
4619  if (presentation_time < 0) {
4620  duration += presentation_time;
4621  presentation_time = 0;
4622  }
4623  } else {
4624  entries = track->nb_frag_info;
4625  if (entries <= 0)
4626  return 0;
4627  presentation_time = track->frag_info[0].time;
4628  }
4629 
4630  avio_wb32(pb, 0); /* size */
4631  ffio_wfourcc(pb, "sidx");
4632  avio_w8(pb, 1); /* version */
4633  avio_wb24(pb, 0);
4634  avio_wb32(pb, track->track_id); /* reference_ID */
4635  avio_wb32(pb, track->timescale); /* timescale */
4636  avio_wb64(pb, presentation_time); /* earliest_presentation_time */
4637  offset_pos = avio_tell(pb);
4638  avio_wb64(pb, 0); /* first_offset (offset to referenced moof) */
4639  avio_wb16(pb, 0); /* reserved */
4640 
4641  avio_wb16(pb, entries); /* reference_count */
4642  for (i = 0; i < entries; i++) {
4643  if (!track->entry) {
4644  if (i > 1 && track->frag_info[i].offset != track->frag_info[i - 1].offset + track->frag_info[i - 1].size) {
4645  av_log(NULL, AV_LOG_ERROR, "Non-consecutive fragments, writing incorrect sidx\n");
4646  }
4647  duration = track->frag_info[i].duration;
4648  ref_size = track->frag_info[i].size;
4649  starts_with_SAP = 1;
4650  }
4651  avio_wb32(pb, (0 << 31) | (ref_size & 0x7fffffff)); /* reference_type (0 = media) | referenced_size */
4652  avio_wb32(pb, duration); /* subsegment_duration */
4653  avio_wb32(pb, (starts_with_SAP << 31) | (0 << 28) | 0); /* starts_with_SAP | SAP_type | SAP_delta_time */
4654  }
4655 
4656  end_pos = avio_tell(pb);
4657  offset = pos + total_sidx_size - end_pos;
4658  avio_seek(pb, offset_pos, SEEK_SET);
4659  avio_wb64(pb, offset);
4660  avio_seek(pb, end_pos, SEEK_SET);
4661  return update_size(pb, pos);
4662 }
4663 
4665  int tracks, int ref_size)
4666 {
4667  int i, round, ret;
4668  AVIOContext *avio_buf;
4669  int total_size = 0;
4670  for (round = 0; round < 2; round++) {
4671  // First run one round to calculate the total size of all
4672  // sidx atoms.
4673  // This would be much simpler if we'd only write one sidx
4674  // atom, for the first track in the moof.
4675  if (round == 0) {
4676  if ((ret = ffio_open_null_buf(&avio_buf)) < 0)
4677  return ret;
4678  } else {
4679  avio_buf = pb;
4680  }
4681  for (i = 0; i < mov->nb_streams; i++) {
4682  MOVTrack *track = &mov->tracks[i];
4683  if (tracks >= 0 && i != tracks)
4684  continue;
4685  // When writing a sidx for the full file, entry is 0, but
4686  // we want to include all tracks. ref_size is 0 in this case,
4687  // since we read it from frag_info instead.
4688  if (!track->entry && ref_size > 0)
4689  continue;
4690  total_size -= mov_write_sidx_tag(avio_buf, track, ref_size,
4691  total_size);
4692  }
4693  if (round == 0)
4694  total_size = ffio_close_null_buf(avio_buf);
4695  }
4696  return 0;
4697 }
4698 
4699 static int mov_write_prft_tag(AVIOContext *pb, MOVMuxContext *mov, int tracks)
4700 {
4701  int64_t pos = avio_tell(pb), pts_us, ntp_ts;
4702  MOVTrack *first_track;
4703  int flags = 24;
4704 
4705  /* PRFT should be associated with at most one track. So, choosing only the
4706  * first track. */
4707  if (tracks > 0)
4708  return 0;
4709  first_track = &(mov->tracks[0]);
4710 
4711  if (!first_track->entry) {
4712  av_log(mov->fc, AV_LOG_WARNING, "Unable to write PRFT, no entries in the track\n");
4713  return 0;
4714  }
4715 
4716  if (first_track->cluster[0].pts == AV_NOPTS_VALUE) {
4717  av_log(mov->fc, AV_LOG_WARNING, "Unable to write PRFT, first PTS is invalid\n");
4718  return 0;
4719  }
4720 
4721  if (mov->write_prft == MOV_PRFT_SRC_WALLCLOCK) {
4722  if (first_track->cluster[0].prft.wallclock) {
4723  /* Round the NTP time to whole milliseconds. */
4724  ntp_ts = ff_get_formatted_ntp_time((first_track->cluster[0].prft.wallclock / 1000) * 1000 +
4725  NTP_OFFSET_US);
4726  flags = first_track->cluster[0].prft.flags;
4727  } else
4729  } else if (mov->write_prft == MOV_PRFT_SRC_PTS) {
4730  pts_us = av_rescale_q(first_track->cluster[0].pts,
4731  first_track->st->time_base, AV_TIME_BASE_Q);
4732  ntp_ts = ff_get_formatted_ntp_time(pts_us + NTP_OFFSET_US);
4733  } else {
4734  av_log(mov->fc, AV_LOG_WARNING, "Unsupported PRFT box configuration: %d\n",
4735  mov->write_prft);
4736  return 0;
4737  }
4738 
4739  avio_wb32(pb, 0); // Size place holder
4740  ffio_wfourcc(pb, "prft"); // Type
4741  avio_w8(pb, 1); // Version
4742  avio_wb24(pb, flags); // Flags
4743  avio_wb32(pb, first_track->track_id); // reference track ID
4744  avio_wb64(pb, ntp_ts); // NTP time stamp
4745  avio_wb64(pb, first_track->cluster[0].pts); //media time
4746  return update_size(pb, pos);
4747 }
4748 
4749 static int mov_write_moof_tag(AVIOContext *pb, MOVMuxContext *mov, int tracks,
4750  int64_t mdat_size)
4751 {
4752  AVIOContext *avio_buf;
4753  int ret, moof_size;
4754 
4755  if ((ret = ffio_open_null_buf(&avio_buf)) < 0)
4756  return ret;
4757  mov_write_moof_tag_internal(avio_buf, mov, tracks, 0);
4758  moof_size = ffio_close_null_buf(avio_buf);
4759 
4760  if (mov->flags & FF_MOV_FLAG_DASH &&
4762  mov_write_sidx_tags(pb, mov, tracks, moof_size + 8 + mdat_size);
4763 
4764  if (mov->write_prft > MOV_PRFT_NONE && mov->write_prft < MOV_PRFT_NB)
4765  mov_write_prft_tag(pb, mov, tracks);
4766 
4767  if (mov->flags & FF_MOV_FLAG_GLOBAL_SIDX ||
4768  !(mov->flags & FF_MOV_FLAG_SKIP_TRAILER) ||
4769  mov->ism_lookahead) {
4770  if ((ret = mov_add_tfra_entries(pb, mov, tracks, moof_size + 8 + mdat_size)) < 0)
4771  return ret;
4772  if (!(mov->flags & FF_MOV_FLAG_GLOBAL_SIDX) &&
4774  mov_prune_frag_info(mov, tracks, mov->ism_lookahead + 1);
4775  }
4776  }
4777 
4778  return mov_write_moof_tag_internal(pb, mov, tracks, moof_size);
4779 }
4780 
4781 static int mov_write_tfra_tag(AVIOContext *pb, MOVTrack *track)
4782 {
4783  int64_t pos = avio_tell(pb);
4784  int i;
4785 
4786  avio_wb32(pb, 0); /* size placeholder */
4787  ffio_wfourcc(pb, "tfra");
4788  avio_w8(pb, 1); /* version */
4789  avio_wb24(pb, 0);
4790 
4791  avio_wb32(pb, track->track_id);
4792  avio_wb32(pb, 0); /* length of traf/trun/sample num */
4793  avio_wb32(pb, track->nb_frag_info);
4794  for (i = 0; i < track->nb_frag_info; i++) {
4795  avio_wb64(pb, track->frag_info[i].time);
4796  avio_wb64(pb, track->frag_info[i].offset + track->data_offset);
4797  avio_w8(pb, 1); /* traf number */
4798  avio_w8(pb, 1); /* trun number */
4799  avio_w8(pb, 1); /* sample number */
4800  }
4801 
4802  return update_size(pb, pos);
4803 }
4804 
4806 {
4807  int64_t pos = avio_tell(pb);
4808  int i;
4809 
4810  avio_wb32(pb, 0); /* size placeholder */
4811  ffio_wfourcc(pb, "mfra");
4812  /* An empty mfra atom is enough to indicate to the publishing point that
4813  * the stream has ended. */
4814  if (mov->flags & FF_MOV_FLAG_ISML)
4815  return update_size(pb, pos);
4816 
4817  for (i = 0; i < mov->nb_streams; i++) {
4818  MOVTrack *track = &mov->tracks[i];
4819  if (track->nb_frag_info)
4820  mov_write_tfra_tag(pb, track);
4821  }
4822 
4823  avio_wb32(pb, 16);
4824  ffio_wfourcc(pb, "mfro");
4825  avio_wb32(pb, 0); /* version + flags */
4826  avio_wb32(pb, avio_tell(pb) + 4 - pos);
4827 
4828  return update_size(pb, pos);
4829 }
4830 
4832 {
4833  avio_wb32(pb, 8); // placeholder for extended size field (64 bit)
4834  ffio_wfourcc(pb, mov->mode == MODE_MOV ? "wide" : "free");
4835 
4836  mov->mdat_pos = avio_tell(pb);
4837  avio_wb32(pb, 0); /* size placeholder*/
4838  ffio_wfourcc(pb, "mdat");
4839  return 0;
4840 }
4841 
4843  int has_h264, int has_video, int write_minor)
4844 {
4845  MOVMuxContext *mov = s->priv_data;
4846  int minor = 0x200;
4847 
4848  if (mov->major_brand && strlen(mov->major_brand) >= 4)
4849  ffio_wfourcc(pb, mov->major_brand);
4850  else if (mov->mode == MODE_3GP) {
4851  ffio_wfourcc(pb, has_h264 ? "3gp6" : "3gp4");
4852  minor = has_h264 ? 0x100 : 0x200;
4853  } else if (mov->mode & MODE_3G2) {
4854  ffio_wfourcc(pb, has_h264 ? "3g2b" : "3g2a");
4855  minor = has_h264 ? 0x20000 : 0x10000;
4856  } else if (mov->mode == MODE_PSP)
4857  ffio_wfourcc(pb, "MSNV");
4858  else if (mov->mode == MODE_MP4 && mov->flags & FF_MOV_FLAG_FRAGMENT &&
4860  ffio_wfourcc(pb, "iso6"); // Required when using signed CTS offsets in trun boxes
4861  else if (mov->mode == MODE_MP4 && mov->flags & FF_MOV_FLAG_DEFAULT_BASE_MOOF)
4862  ffio_wfourcc(pb, "iso5"); // Required when using default-base-is-moof
4863  else if (mov->mode == MODE_MP4 && mov->flags & FF_MOV_FLAG_NEGATIVE_CTS_OFFSETS)
4864  ffio_wfourcc(pb, "iso4");
4865  else if (mov->mode == MODE_MP4)
4866  ffio_wfourcc(pb, "isom");
4867  else if (mov->mode == MODE_IPOD)
4868  ffio_wfourcc(pb, has_video ? "M4V ":"M4A ");
4869  else if (mov->mode == MODE_ISM)
4870  ffio_wfourcc(pb, "isml");
4871  else if (mov->mode == MODE_F4V)
4872  ffio_wfourcc(pb, "f4v ");
4873  else
4874  ffio_wfourcc(pb, "qt ");
4875 
4876  if (write_minor)
4877  avio_wb32(pb, minor);
4878 }
4879 
4881 {
4882  MOVMuxContext *mov = s->priv_data;
4883  int64_t pos = avio_tell(pb);
4884  int has_h264 = 0, has_video = 0;
4885  int i;
4886 
4887  for (i = 0; i < s->nb_streams; i++) {
4888  AVStream *st = s->streams[i];
4889  if (is_cover_image(st))
4890  continue;
4892  has_video = 1;
4893  if (st->codecpar->codec_id == AV_CODEC_ID_H264)
4894  has_h264 = 1;
4895  }
4896 
4897  avio_wb32(pb, 0); /* size */
4898  ffio_wfourcc(pb, "ftyp");
4899 
4900  // Write major brand
4901  mov_write_ftyp_tag_internal(pb, s, has_h264, has_video, 1);
4902  // Write the major brand as the first compatible brand as well
4903  mov_write_ftyp_tag_internal(pb, s, has_h264, has_video, 0);
4904 
4905  // Write compatible brands, ensuring that we don't write the major brand as a
4906  // compatible brand a second time.
4907  if (mov->mode == MODE_ISM) {
4908  ffio_wfourcc(pb, "piff");
4909  } else if (mov->mode != MODE_MOV) {
4910  // We add tfdt atoms when fragmenting, signal this with the iso6 compatible
4911  // brand, if not already the major brand. This is compatible with users that
4912  // don't understand tfdt.
4913  if (mov->mode == MODE_MP4) {
4914  if (mov->flags & FF_MOV_FLAG_CMAF)
4915  ffio_wfourcc(pb, "cmfc");
4917  ffio_wfourcc(pb, "iso6");
4918  } else {
4919  if (mov->flags & FF_MOV_FLAG_FRAGMENT)
4920  ffio_wfourcc(pb, "iso6");
4922  ffio_wfourcc(pb, "iso5");
4923  else if (mov->flags & FF_MOV_FLAG_NEGATIVE_CTS_OFFSETS)
4924  ffio_wfourcc(pb, "iso4");
4925  }
4926  // Brands prior to iso5 can't be signaled when using default-base-is-moof
4927  if (!(mov->flags & FF_MOV_FLAG_DEFAULT_BASE_MOOF)) {
4928  // write isom for mp4 only if it it's not the major brand already.
4929  if (mov->mode != MODE_MP4 || mov->flags & FF_MOV_FLAG_NEGATIVE_CTS_OFFSETS)
4930  ffio_wfourcc(pb, "isom");
4931  ffio_wfourcc(pb, "iso2");
4932  if (has_h264)
4933  ffio_wfourcc(pb, "avc1");
4934  }
4935  }
4936 
4937  if (mov->mode == MODE_MP4)
4938  ffio_wfourcc(pb, "mp41");
4939 
4940  if (mov->flags & FF_MOV_FLAG_DASH && mov->flags & FF_MOV_FLAG_GLOBAL_SIDX)
4941  ffio_wfourcc(pb, "dash");
4942 
4943  return update_size(pb, pos);
4944 }
4945 
4947 {
4948  AVStream *video_st = s->streams[0];
4949  AVCodecParameters *video_par = s->streams[0]->codecpar;
4950  AVCodecParameters *audio_par = s->streams[1]->codecpar;
4951  int audio_rate = audio_par->sample_rate;
4952  int64_t frame_rate = video_st->avg_frame_rate.den ?
4954  0;
4955  int audio_kbitrate = audio_par->bit_rate / 1000;
4956  int video_kbitrate = FFMIN(video_par->bit_rate / 1000, 800 - audio_kbitrate);
4957 
4958  if (frame_rate < 0 || frame_rate > INT32_MAX) {
4959  av_log(s, AV_LOG_ERROR, "Frame rate %f outside supported range\n", frame_rate / (double)0x10000);
4960  return AVERROR(EINVAL);
4961  }
4962 
4963  avio_wb32(pb, 0x94); /* size */
4964  ffio_wfourcc(pb, "uuid");
4965  ffio_wfourcc(pb, "PROF");
4966 
4967  avio_wb32(pb, 0x21d24fce); /* 96 bit UUID */
4968  avio_wb32(pb, 0xbb88695c);
4969  avio_wb32(pb, 0xfac9c740);
4970 
4971  avio_wb32(pb, 0x0); /* ? */
4972  avio_wb32(pb, 0x3); /* 3 sections ? */
4973 
4974  avio_wb32(pb, 0x14); /* size */
4975  ffio_wfourcc(pb, "FPRF");
4976  avio_wb32(pb, 0x0); /* ? */
4977  avio_wb32(pb, 0x0); /* ? */
4978  avio_wb32(pb, 0x0); /* ? */
4979 
4980  avio_wb32(pb, 0x2c); /* size */
4981  ffio_wfourcc(pb, "APRF"); /* audio */
4982  avio_wb32(pb, 0x0);
4983  avio_wb32(pb, 0x2); /* TrackID */
4984  ffio_wfourcc(pb, "mp4a");
4985  avio_wb32(pb, 0x20f);
4986  avio_wb32(pb, 0x0);
4987  avio_wb32(pb, audio_kbitrate);
4988  avio_wb32(pb, audio_kbitrate);
4989  avio_wb32(pb, audio_rate);
4990  avio_wb32(pb, audio_par->channels);
4991 
4992  avio_wb32(pb, 0x34); /* size */
4993  ffio_wfourcc(pb, "VPRF"); /* video */
4994  avio_wb32(pb, 0x0);
4995  avio_wb32(pb, 0x1); /* TrackID */
4996  if (video_par->codec_id == AV_CODEC_ID_H264) {
4997  ffio_wfourcc(pb, "avc1");
4998  avio_wb16(pb, 0x014D);
4999  avio_wb16(pb, 0x0015);
5000  } else {
5001  ffio_wfourcc(pb, "mp4v");
5002  avio_wb16(pb, 0x0000);
5003  avio_wb16(pb, 0x0103);
5004  }
5005  avio_wb32(pb, 0x0);
5006  avio_wb32(pb, video_kbitrate);
5007  avio_wb32(pb, video_kbitrate);
5008  avio_wb32(pb, frame_rate);
5009  avio_wb32(pb, frame_rate);
5010  avio_wb16(pb, video_par->width);
5011  avio_wb16(pb, video_par->height);
5012  avio_wb32(pb, 0x010001); /* ? */
5013 
5014  return 0;
5015 }
5016 
5018 {
5019  MOVMuxContext *mov = s->priv_data;
5020  int i;
5021 
5022  mov_write_ftyp_tag(pb,s);
5023  if (mov->mode == MODE_PSP) {
5024  int video_streams_nb = 0, audio_streams_nb = 0, other_streams_nb = 0;
5025  for (i = 0; i < s->nb_streams; i++) {
5026  AVStream *st = s->streams[i];
5027  if (is_cover_image(st))
5028  continue;
5030  video_streams_nb++;
5031  else if (st->codecpar->codec_type == AVMEDIA_TYPE_AUDIO)
5032  audio_streams_nb++;
5033  else
5034  other_streams_nb++;
5035  }
5036 
5037  if (video_streams_nb != 1 || audio_streams_nb != 1 || other_streams_nb) {
5038  av_log(s, AV_LOG_ERROR, "PSP mode need one video and one audio stream\n");
5039  return AVERROR(EINVAL);
5040  }
5041  return mov_write_uuidprof_tag(pb, s);
5042  }
5043  return 0;
5044 }
5045 
5046 static int mov_parse_mpeg2_frame(AVPacket *pkt, uint32_t *flags)
5047 {
5048  uint32_t c = -1;
5049  int i, closed_gop = 0;
5050 
5051  for (i = 0; i < pkt->size - 4; i++) {
5052  c = (c << 8) + pkt->data[i];
5053  if (c == 0x1b8) { // gop
5054  closed_gop = pkt->data[i + 4] >> 6 & 0x01;
5055  } else if (c == 0x100) { // pic
5056  int temp_ref = (pkt->data[i + 1] << 2) | (pkt->data[i + 2] >> 6);
5057  if (!temp_ref || closed_gop) // I picture is not reordered
5059  else
5061  break;
5062  }
5063  }
5064  return 0;
5065 }
5066 
5068 {
5069  const uint8_t *start, *next, *end = pkt->data + pkt->size;
5070  int seq = 0, entry = 0;
5071  int key = pkt->flags & AV_PKT_FLAG_KEY;
5072  start = find_next_marker(pkt->data, end);
5073  for (next = start; next < end; start = next) {
5074  next = find_next_marker(start + 4, end);
5075  switch (AV_RB32(start)) {
5076  case VC1_CODE_SEQHDR:
5077  seq = 1;
5078  break;
5079  case VC1_CODE_ENTRYPOINT:
5080  entry = 1;
5081  break;
5082  case VC1_CODE_SLICE:
5083  trk->vc1_info.slices = 1;
5084  break;
5085  }
5086  }
5087  if (!trk->entry && trk->vc1_info.first_packet_seen)
5088  trk->vc1_info.first_frag_written = 1;
5089  if (!trk->entry && !trk->vc1_info.first_frag_written) {
5090  /* First packet in first fragment */
5091  trk->vc1_info.first_packet_seq = seq;
5092  trk->vc1_info.first_packet_entry = entry;
5093  trk->vc1_info.first_packet_seen = 1;
5094  } else if ((seq && !trk->vc1_info.packet_seq) ||
5095  (entry && !trk->vc1_info.packet_entry)) {
5096  int i;
5097  for (i = 0; i < trk->entry; i++)
5098  trk->cluster[i].flags &= ~MOV_SYNC_SAMPLE;
5099  trk->has_keyframes = 0;
5100  if (seq)
5101  trk->vc1_info.packet_seq = 1;
5102  if (entry)
5103  trk->vc1_info.packet_entry = 1;
5104  if (!trk->vc1_info.first_frag_written) {
5105  /* First fragment */
5106  if ((!seq || trk->vc1_info.first_packet_seq) &&
5107  (!entry || trk->vc1_info.first_packet_entry)) {
5108  /* First packet had the same headers as this one, readd the
5109  * sync sample flag. */
5110  trk->cluster[0].flags |= MOV_SYNC_SAMPLE;
5111  trk->has_keyframes = 1;
5112  }
5113  }
5114  }
5115  if (trk->vc1_info.packet_seq && trk->vc1_info.packet_entry)
5116  key = seq && entry;
5117  else if (trk->vc1_info.packet_seq)
5118  key = seq;
5119  else if (trk->vc1_info.packet_entry)
5120  key = entry;
5121  if (key) {
5122  trk->cluster[trk->entry].flags |= MOV_SYNC_SAMPLE;
5123  trk->has_keyframes++;
5124  }
5125 }
5126 
5128 {
5129  int length;
5130 
5131  if (pkt->size < 8)
5132  return;
5133 
5134  length = (AV_RB16(pkt->data) & 0xFFF) * 2;
5135  if (length < 8 || length > pkt->size)
5136  return;
5137 
5138  if (AV_RB32(pkt->data + 4) == 0xF8726FBA) {
5139  trk->cluster[trk->entry].flags |= MOV_SYNC_SAMPLE;
5140  trk->has_keyframes++;
5141  }
5142 
5143  return;
5144 }
5145 
5147 {
5148  MOVMuxContext *mov = s->priv_data;
5149  int ret, buf_size;
5150  uint8_t *buf;
5151  int i, offset;
5152 
5153  if (!track->mdat_buf)
5154  return 0;
5155  if (!mov->mdat_buf) {
5156  if ((ret = avio_open_dyn_buf(&mov->mdat_buf)) < 0)
5157  return ret;
5158  }
5159  buf_size = avio_get_dyn_buf(track->mdat_buf, &buf);
5160 
5161  offset = avio_tell(mov->mdat_buf);
5162  avio_write(mov->mdat_buf, buf, buf_size);
5163  ffio_free_dyn_buf(&track->mdat_buf);
5164 
5165  for (i = track->entries_flushed; i < track->entry; i++)
5166  track->cluster[i].pos += offset;
5167  track->entries_flushed = track->entry;
5168  return 0;
5169 }
5170 
5171 static int mov_flush_fragment(AVFormatContext *s, int force)
5172 {
5173  MOVMuxContext *mov = s->priv_data;
5174  int i, first_track = -1;
5175  int64_t mdat_size = 0;
5176  int ret;
5177  int has_video = 0, starts_with_key = 0, first_video_track = 1;
5178 
5179  if (!(mov->flags & FF_MOV_FLAG_FRAGMENT))
5180  return 0;
5181 
5182  // Try to fill in the duration of the last packet in each stream
5183  // from queued packets in the interleave queues. If the flushing
5184  // of fragments was triggered automatically by an AVPacket, we
5185  // already have reliable info for the end of that track, but other
5186  // tracks may need to be filled in.
5187  for (i = 0; i < s->nb_streams; i++) {
5188  MOVTrack *track = &mov->tracks[i];
5189  if (!track->end_reliable) {
5190  AVPacket pkt;
5191  if (!ff_interleaved_peek(s, i, &pkt, 1)) {
5192  if (track->dts_shift != AV_NOPTS_VALUE)
5193  pkt.dts += track->dts_shift;
5194  track->track_duration = pkt.dts - track->start_dts;
5195  if (pkt.pts != AV_NOPTS_VALUE)
5196  track->end_pts = pkt.pts;
5197  else
5198  track->end_pts = pkt.dts;
5199  }
5200  }
5201  }
5202 
5203  for (i = 0; i < mov->nb_streams; i++) {
5204  MOVTrack *track = &mov->tracks[i];
5205  if (track->entry <= 1)
5206  continue;
5207  // Sample durations are calculated as the diff of dts values,
5208  // but for the last sample in a fragment, we don't know the dts
5209  // of the first sample in the next fragment, so we have to rely
5210  // on what was set as duration in the AVPacket. Not all callers
5211  // set this though, so we might want to replace it with an
5212  // estimate if it currently is zero.
5213  if (get_cluster_duration(track, track->entry - 1) != 0)
5214  continue;
5215  // Use the duration (i.e. dts diff) of the second last sample for
5216  // the last one. This is a wild guess (and fatal if it turns out
5217  // to be too long), but probably the best we can do - having a zero
5218  // duration is bad as well.
5219  track->track_duration += get_cluster_duration(track, track->entry - 2);
5220  track->end_pts += get_cluster_duration(track, track->entry - 2);
5221  if (!mov->missing_duration_warned) {
5223  "Estimating the duration of the last packet in a "
5224  "fragment, consider setting the duration field in "
5225  "AVPacket instead.\n");
5226  mov->missing_duration_warned = 1;
5227  }
5228  }
5229 
5230  if (!mov->moov_written) {
5231  int64_t pos = avio_tell(s->pb);
5232  uint8_t *buf;
5233  int buf_size, moov_size;
5234 
5235  for (i = 0; i < mov->nb_streams; i++)
5236  if (!mov->tracks[i].entry && !is_cover_image(mov->tracks[i].st))
5237  break;
5238  /* Don't write the initial moov unless all tracks have data */
5239  if (i < mov->nb_streams && !force)
5240  return 0;
5241 
5242  moov_size = get_moov_size(s);
5243  for (i = 0; i < mov->nb_streams; i++)
5244  mov->tracks[i].data_offset = pos + moov_size + 8;
5245 
5247  if (mov->flags & FF_MOV_FLAG_DELAY_MOOV)
5249  if ((ret = mov_write_moov_tag(s->pb, mov, s)) < 0)
5250  return ret;
5251 
5252  if (mov->flags & FF_MOV_FLAG_DELAY_MOOV) {
5253  if (mov->flags & FF_MOV_FLAG_GLOBAL_SIDX)
5254  mov->reserved_header_pos = avio_tell(s->pb);
5256  mov->moov_written = 1;
5257  return 0;
5258  }
5259 
5260  buf_size = avio_get_dyn_buf(mov->mdat_buf, &buf);
5261  avio_wb32(s->pb, buf_size + 8);
5262  ffio_wfourcc(s->pb, "mdat");
5263  avio_write(s->pb, buf, buf_size);
5264  ffio_free_dyn_buf(&mov->mdat_buf);
5265 
5266  if (mov->flags & FF_MOV_FLAG_GLOBAL_SIDX)
5267  mov->reserved_header_pos = avio_tell(s->pb);
5268 
5269  mov->moov_written = 1;
5270  mov->mdat_size = 0;
5271  for (i = 0; i < mov->nb_streams; i++) {
5272  if (mov->tracks[i].entry)
5273  mov->tracks[i].frag_start += mov->tracks[i].start_dts +
5274  mov->tracks[i].track_duration -
5275  mov->tracks[i].cluster[0].dts;
5276  mov->tracks[i].entry = 0;
5277  mov->tracks[i].end_reliable = 0;
5278  }
5280  return 0;
5281  }
5282 
5283  if (mov->frag_interleave) {
5284  for (i = 0; i < mov->nb_streams; i++) {
5285  MOVTrack *track = &mov->tracks[i];
5286  int ret;
5287  if ((ret = mov_flush_fragment_interleaving(s, track)) < 0)
5288  return ret;
5289  }
5290 
5291  if (!mov->mdat_buf)
5292  return 0;
5293  mdat_size = avio_tell(mov->mdat_buf);
5294  }
5295 
5296  for (i = 0; i < mov->nb_streams; i++) {
5297  MOVTrack *track = &mov->tracks[i];
5298  if (mov->flags & FF_MOV_FLAG_SEPARATE_MOOF || mov->frag_interleave)
5299  track->data_offset = 0;
5300  else
5301  track->data_offset = mdat_size;
5302  if (track->par->codec_type == AVMEDIA_TYPE_VIDEO) {
5303  has_video = 1;
5304  if (first_video_track) {
5305  if (track->entry)
5306  starts_with_key = track->cluster[0].flags & MOV_SYNC_SAMPLE;
5307  first_video_track = 0;
5308  }
5309  }
5310  if (!track->entry)
5311  continue;
5312  if (track->mdat_buf)
5313  mdat_size += avio_tell(track->mdat_buf);
5314  if (first_track < 0)
5315  first_track = i;
5316  }
5317 
5318  if (!mdat_size)
5319  return 0;
5320 
5321  avio_write_marker(s->pb,
5322  av_rescale(mov->tracks[first_track].cluster[0].dts, AV_TIME_BASE, mov->tracks[first_track].timescale),
5323  (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);
5324 
5325  for (i = 0; i < mov->nb_streams; i++) {
5326  MOVTrack *track = &mov->tracks[i];
5327  int buf_size, write_moof = 1, moof_tracks = -1;
5328  uint8_t *buf;
5329  int64_t duration = 0;
5330 
5331  if (track->entry)
5332  duration = track->start_dts + track->track_duration -
5333  track->cluster[0].dts;
5334  if (mov->flags & FF_MOV_FLAG_SEPARATE_MOOF) {
5335  if (!track->mdat_buf)
5336  continue;
5337  mdat_size = avio_tell(track->mdat_buf);
5338  moof_tracks = i;
5339  } else {
5340  write_moof = i == first_track;
5341  }
5342 
5343  if (write_moof) {
5345 
5346  mov_write_moof_tag(s->pb, mov, moof_tracks, mdat_size);
5347  mov->fragments++;
5348 
5349  avio_wb32(s->pb, mdat_size + 8);
5350  ffio_wfourcc(s->pb, "mdat");
5351  }
5352 
5353  if (track->entry)
5354  track->frag_start += duration;
5355  track->entry = 0;
5356  track->entries_flushed = 0;
5357  track->end_reliable = 0;
5358  if (!mov->frag_interleave) {
5359  if (!track->mdat_buf)
5360  continue;
5361  buf_size = avio_close_dyn_buf(track->mdat_buf, &buf);
5362  track->mdat_buf = NULL;
5363  } else {
5364  if (!mov->mdat_buf)
5365  continue;
5366  buf_size = avio_close_dyn_buf(mov->mdat_buf, &buf);
5367  mov->mdat_buf = NULL;
5368  }
5369 
5370  avio_write(s->pb, buf, buf_size);
5371  av_free(buf);
5372  }
5373 
5374  mov->mdat_size = 0;
5375 
5377  return 0;
5378 }
5379 
5381 {
5382  MOVMuxContext *mov = s->priv_data;
5383  int had_moov = mov->moov_written;
5384  int ret = mov_flush_fragment(s, force);
5385  if (ret < 0)
5386  return ret;
5387  // If using delay_moov, the first flush only wrote the moov,
5388  // not the actual moof+mdat pair, thus flush once again.
5389  if (!had_moov && mov->flags & FF_MOV_FLAG_DELAY_MOOV)
5390  ret = mov_flush_fragment(s, force);
5391  return ret;
5392 }
5393 
5395 {
5396  MOVMuxContext *mov = s->priv_data;
5397  MOVTrack *trk = &mov->tracks[pkt->stream_index];
5398  int64_t ref;
5399  uint64_t duration;
5400 
5401  if (trk->entry) {
5402  ref = trk->cluster[trk->entry - 1].dts;
5403  } else if ( trk->start_dts != AV_NOPTS_VALUE
5404  && !trk->frag_discont) {
5405  ref = trk->start_dts + trk->track_duration;
5406  } else
5407  ref = pkt->dts; // Skip tests for the first packet
5408 
5409  if (trk->dts_shift != AV_NOPTS_VALUE) {
5410  /* With negative CTS offsets we have set an offset to the DTS,
5411  * reverse this for the check. */
5412  ref -= trk->dts_shift;
5413  }
5414 
5415  duration = pkt->dts - ref;
5416  if (pkt->dts < ref || duration >= INT_MAX) {
5417  av_log(s, AV_LOG_ERROR, "Application provided duration: %"PRId64" / timestamp: %"PRId64" is out of range for mov/mp4 format\n",
5418  duration, pkt->dts
5419  );
5420 
5421  pkt->dts = ref + 1;
5422  pkt->pts = AV_NOPTS_VALUE;
5423  }
5424 
5425  if (pkt->duration < 0 || pkt->duration > INT_MAX) {
5426  av_log(s, AV_LOG_ERROR, "Application provided duration: %"PRId64" is invalid\n", pkt->duration);
5427  return AVERROR(EINVAL);
5428  }
5429  return 0;
5430 }
5431 
5433 {
5434  MOVMuxContext *mov = s->priv_data;
5435  AVIOContext *pb = s->pb;
5436  MOVTrack *trk = &mov->tracks[pkt->stream_index];
5437  AVCodecParameters *par = trk->par;
5439  unsigned int samples_in_chunk = 0;
5440  int size = pkt->size, ret = 0, offset = 0;
5441  int prft_size;
5442  uint8_t *reformatted_data = NULL;
5443 
5444  ret = check_pkt(s, pkt);
5445  if (ret < 0)
5446  return ret;
5447 
5448  if (mov->flags & FF_MOV_FLAG_FRAGMENT) {
5449  int ret;
5450  if (mov->moov_written || mov->flags & FF_MOV_FLAG_EMPTY_MOOV) {
5451  if (mov->frag_interleave && mov->fragments > 0) {
5452  if (trk->entry - trk->entries_flushed >= mov->frag_interleave) {
5453  if ((ret = mov_flush_fragment_interleaving(s, trk)) < 0)
5454  return ret;
5455  }
5456  }
5457 
5458  if (!trk->mdat_buf) {
5459  if ((ret = avio_open_dyn_buf(&trk->mdat_buf)) < 0)
5460  return ret;
5461  }
5462  pb = trk->mdat_buf;
5463  } else {
5464  if (!mov->mdat_buf) {
5465  if ((ret = avio_open_dyn_buf(&mov->mdat_buf)) < 0)
5466  return ret;
5467  }
5468  pb = mov->mdat_buf;
5469  }
5470  }
5471 
5472  if (par->codec_id == AV_CODEC_ID_AMR_NB) {
5473  /* We must find out how many AMR blocks there are in one packet */
5474  static const uint16_t packed_size[16] =
5475  {13, 14, 16, 18, 20, 21, 27, 32, 6, 0, 0, 0, 0, 0, 0, 1};
5476  int len = 0;
5477 
5478  while (len < size && samples_in_chunk < 100) {
5479  len += packed_size[(pkt->data[len] >> 3) & 0x0F];
5480  samples_in_chunk++;
5481  }
5482  if (samples_in_chunk > 1) {
5483  av_log(s, AV_LOG_ERROR, "fatal error, input is not a single packet, implement a AVParser for it\n");
5484  return -1;
5485  }
5486  } else if (par->codec_id == AV_CODEC_ID_ADPCM_MS ||
5488  samples_in_chunk = trk->par->frame_size;
5489  } else if (trk->sample_size)
5490  samples_in_chunk = size / trk->sample_size;
5491  else
5492  samples_in_chunk = 1;
5493 
5494  if (samples_in_chunk < 1) {
5495  av_log(s, AV_LOG_ERROR, "fatal error, input packet contains no samples\n");
5496  return AVERROR_PATCHWELCOME;
5497  }
5498 
5499  /* copy extradata if it exists */
5500  if (trk->vos_len == 0 && par->extradata_size > 0 &&
5501  !TAG_IS_AVCI(trk->tag) &&
5502  (par->codec_id != AV_CODEC_ID_DNXHD)) {
5503  trk->vos_len = par->extradata_size;
5505  if (!trk->vos_data) {
5506  ret = AVERROR(ENOMEM);
5507  goto err;
5508  }
5509  memcpy(trk->vos_data, par->extradata, trk->vos_len);
5510  memset(trk->vos_data + trk->vos_len, 0, AV_INPUT_BUFFER_PADDING_SIZE);
5511  }
5512 
5513  if ((par->codec_id == AV_CODEC_ID_DNXHD ||
5514  par->codec_id == AV_CODEC_ID_H264 ||
5515  par->codec_id == AV_CODEC_ID_HEVC ||
5516  par->codec_id == AV_CODEC_ID_TRUEHD ||
5517  par->codec_id == AV_CODEC_ID_AC3) && !trk->vos_len &&
5518  !TAG_IS_AVCI(trk->tag)) {
5519  /* copy frame to create needed atoms */
5520  trk->vos_len = size;
5522  if (!trk->vos_data) {
5523  ret = AVERROR(ENOMEM);
5524  goto err;
5525  }
5526  memcpy(trk->vos_data, pkt->data, size);
5527  memset(trk->vos_data + size, 0, AV_INPUT_BUFFER_PADDING_SIZE);
5528  }
5529 
5530  if (par->codec_id == AV_CODEC_ID_AAC && pkt->size > 2 &&
5531  (AV_RB16(pkt->data) & 0xfff0) == 0xfff0) {
5532  if (!s->streams[pkt->stream_index]->nb_frames) {
5533  av_log(s, AV_LOG_ERROR, "Malformed AAC bitstream detected: "
5534  "use the audio bitstream filter 'aac_adtstoasc' to fix it "
5535  "('-bsf:a aac_adtstoasc' option with ffmpeg)\n");
5536  return -1;
5537  }
5538  av_log(s, AV_LOG_WARNING, "aac bitstream error\n");
5539  }
5540  if (par->codec_id == AV_CODEC_ID_H264 && trk->vos_len > 0 && *(uint8_t *)trk->vos_data != 1 && !TAG_IS_AVCI(trk->tag)) {
5541  /* from x264 or from bytestream H.264 */
5542  /* NAL reformatting needed */
5543  if (trk->hint_track >= 0 && trk->hint_track < mov->nb_streams) {
5544  ret = ff_avc_parse_nal_units_buf(pkt->data, &reformatted_data,
5545  &size);
5546  if (ret < 0)
5547  return ret;
5548  avio_write(pb, reformatted_data, size);
5549  } else {
5550  if (trk->cenc.aes_ctr) {
5552  if (size < 0) {
5553  ret = size;
5554  goto err;
5555  }
5556  } else {
5558  }
5559  }
5560  } else if (par->codec_id == AV_CODEC_ID_HEVC && trk->vos_len > 6 &&
5561  (AV_RB24(trk->vos_data) == 1 || AV_RB32(trk->vos_data) == 1)) {
5562  /* extradata is Annex B, assume the bitstream is too and convert it */
5563  if (trk->hint_track >= 0 && trk->hint_track < mov->nb_streams) {
5564  ret = ff_hevc_annexb2mp4_buf(pkt->data, &reformatted_data,
5565  &size, 0, NULL);
5566  if (ret < 0)
5567  return ret;
5568  avio_write(pb, reformatted_data, size);
5569  } else {
5570  size = ff_hevc_annexb2mp4(pb, pkt->data, pkt->size, 0, NULL);
5571  }
5572  } else if (par->codec_id == AV_CODEC_ID_AV1) {
5573  if (trk->hint_track >= 0 && trk->hint_track < mov->nb_streams) {
5574  ret = ff_av1_filter_obus_buf(pkt->data, &reformatted_data,
5575  &size, &offset);
5576  if (ret < 0)
5577  return ret;
5578  avio_write(pb, reformatted_data, size);
5579  } else {
5580  size = ff_av1_filter_obus(pb, pkt->data, pkt->size);
5581  }
5582 #if CONFIG_AC3_PARSER
5583  } else if (par->codec_id == AV_CODEC_ID_EAC3) {
5584  size = handle_eac3(mov, pkt, trk);
5585  if (size < 0)
5586  return size;
5587  else if (!size)
5588  goto end;
5589  avio_write(pb, pkt->data, size);
5590 #endif
5591  } else {
5592  if (trk->cenc.aes_ctr) {
5593  if (par->codec_id == AV_CODEC_ID_H264 && par->extradata_size > 4) {
5594  int nal_size_length = (par->extradata[4] & 0x3) + 1;
5595  ret = ff_mov_cenc_avc_write_nal_units(s, &trk->cenc, nal_size_length, pb, pkt->data, size);
5596  } else {
5597  ret = ff_mov_cenc_write_packet(&trk->cenc, pb, pkt->data, size);
5598  }
5599 
5600  if (ret) {
5601  goto err;
5602  }
5603  } else {
5604  avio_write(pb, pkt->data, size);
5605  }
5606  }
5607 
5608  if (trk->entry >= trk->cluster_capacity) {
5609  unsigned new_capacity = trk->entry + MOV_INDEX_CLUSTER_SIZE;
5610  void *cluster = av_realloc_array(trk->cluster, new_capacity, sizeof(*trk->cluster));
5611  if (!cluster) {
5612  ret = AVERROR(ENOMEM);
5613  goto err;
5614  }
5615  trk->cluster = cluster;
5616  trk->cluster_capacity = new_capacity;
5617  }
5618 
5619  trk->cluster[trk->entry].pos = avio_tell(pb) - size;
5620  trk->cluster[trk->entry].samples_in_chunk = samples_in_chunk;
5621  trk->cluster[trk->entry].chunkNum = 0;
5622  trk->cluster[trk->entry].size = size;
5623  trk->cluster[trk->entry].entries = samples_in_chunk;
5624  trk->cluster[trk->entry].dts = pkt->dts;
5625  trk->cluster[trk->entry].pts = pkt->pts;
5626  if (!trk->entry && trk->start_dts != AV_NOPTS_VALUE) {
5627  if (!trk->frag_discont) {
5628  /* First packet of a new fragment. We already wrote the duration
5629  * of the last packet of the previous fragment based on track_duration,
5630  * which might not exactly match our dts. Therefore adjust the dts
5631  * of this packet to be what the previous packets duration implies. */
5632  trk->cluster[trk->entry].dts = trk->start_dts + trk->track_duration;
5633  /* We also may have written the pts and the corresponding duration
5634  * in sidx/tfrf/tfxd tags; make sure the sidx pts and duration match up with
5635  * the next fragment. This means the cts of the first sample must
5636  * be the same in all fragments, unless end_pts was updated by
5637  * the packet causing the fragment to be written. */
5638  if ((mov->flags & FF_MOV_FLAG_DASH &&
5640  mov->mode == MODE_ISM)
5641  pkt->pts = pkt->dts + trk->end_pts - trk->cluster[trk->entry].dts;
5642  } else {
5643  /* New fragment, but discontinuous from previous fragments.
5644  * Pretend the duration sum of the earlier fragments is
5645  * pkt->dts - trk->start_dts. */
5646  trk->frag_start = pkt->dts - trk->start_dts;
5647  trk->end_pts = AV_NOPTS_VALUE;
5648  trk->frag_discont = 0;
5649  }
5650  }
5651 
5652  if (!trk->entry && trk->start_dts == AV_NOPTS_VALUE && !mov->use_editlist &&
5653  s->avoid_negative_ts == AVFMT_AVOID_NEG_TS_MAKE_ZERO) {
5654  /* Not using edit lists and shifting the first track to start from zero.
5655  * If the other streams start from a later timestamp, we won't be able
5656  * to signal the difference in starting time without an edit list.
5657  * Thus move the timestamp for this first sample to 0, increasing
5658  * its duration instead. */
5659  trk->cluster[trk->entry].dts = trk->start_dts = 0;
5660  }
5661  if (trk->start_dts == AV_NOPTS_VALUE) {
5662  trk->start_dts = pkt->dts;
5663  if (trk->frag_discont) {
5664  if (mov->use_editlist) {
5665  /* Pretend the whole stream started at pts=0, with earlier fragments
5666  * already written. If the stream started at pts=0, the duration sum
5667  * of earlier fragments would have been pkt->pts. */
5668  trk->frag_start = pkt->pts;
5669  trk->start_dts = pkt->dts - pkt->pts;
5670  } else {
5671  /* Pretend the whole stream started at dts=0, with earlier fragments
5672  * already written, with a duration summing up to pkt->dts. */
5673  trk->frag_start = pkt->dts;
5674  trk->start_dts = 0;
5675  }
5676  trk->frag_discont = 0;
5677  } else if (pkt->dts && mov->moov_written)
5679  "Track %d starts with a nonzero dts %"PRId64", while the moov "
5680  "already has been written. Set the delay_moov flag to handle "
5681  "this case.\n",
5682  pkt->stream_index, pkt->dts);
5683  }
5684  trk->track_duration = pkt->dts - trk->start_dts + pkt->duration;
5685  trk->last_sample_is_subtitle_end = 0;
5686 
5687  if (pkt->pts == AV_NOPTS_VALUE) {
5688  av_log(s, AV_LOG_WARNING, "pts has no value\n");
5689  pkt->pts = pkt->dts;
5690  }
5691  if (pkt->dts != pkt->pts)
5692  trk->flags |= MOV_TRACK_CTTS;
5693  trk->cluster[trk->entry].cts = pkt->pts - pkt->dts;
5694  trk->cluster[trk->entry].flags = 0;
5695  if (trk->start_cts == AV_NOPTS_VALUE)
5696  trk->start_cts = pkt->pts - pkt->dts;
5697  if (trk->end_pts == AV_NOPTS_VALUE)
5698  trk->end_pts = trk->cluster[trk->entry].dts +
5699  trk->cluster[trk->entry].cts + pkt->duration;
5700  else
5701  trk->end_pts = FFMAX(trk->end_pts, trk->cluster[trk->entry].dts +
5702  trk->cluster[trk->entry].cts +
5703  pkt->duration);
5704 
5705  if (par->codec_id == AV_CODEC_ID_VC1) {
5706  mov_parse_vc1_frame(pkt, trk);
5707  } else if (par->codec_id == AV_CODEC_ID_TRUEHD) {
5709  } else if (pkt->flags & AV_PKT_FLAG_KEY) {
5710  if (mov->mode == MODE_MOV && par->codec_id == AV_CODEC_ID_MPEG2VIDEO &&
5711  trk->entry > 0) { // force sync sample for the first key frame
5713  if (trk->cluster[trk->entry].flags & MOV_PARTIAL_SYNC_SAMPLE)
5714  trk->flags |= MOV_TRACK_STPS;
5715  } else {
5716  trk->cluster[trk->entry].flags = MOV_SYNC_SAMPLE;
5717  }
5718  if (trk->cluster[trk->entry].flags & MOV_SYNC_SAMPLE)
5719  trk->has_keyframes++;
5720  }
5721  if (pkt->flags & AV_PKT_FLAG_DISPOSABLE) {
5722  trk->cluster[trk->entry].flags |= MOV_DISPOSABLE_SAMPLE;
5723  trk->has_disposable++;
5724  }
5725 
5727  if (prft && prft_size == sizeof(AVProducerReferenceTime))
5728  memcpy(&trk->cluster[trk->entry].prft, prft, prft_size);
5729  else
5730  memset(&trk->cluster[trk->entry].prft, 0, sizeof(AVProducerReferenceTime));
5731 
5732  trk->entry++;
5733  trk->sample_count += samples_in_chunk;
5734  mov->mdat_size += size;
5735 
5736  if (trk->hint_track >= 0 && trk->hint_track < mov->nb_streams)
5738  reformatted_data ? reformatted_data + offset
5739  : NULL, size);
5740 
5741 end:
5742 err:
5743 
5744  if (pkt->data != reformatted_data)
5745  av_free(reformatted_data);
5746  return ret;
5747 }
5748 
5750 {
5751  MOVMuxContext *mov = s->priv_data;
5752  MOVTrack *trk = &mov->tracks[pkt->stream_index];
5753  AVCodecParameters *par = trk->par;
5754  int64_t frag_duration = 0;
5755  int size = pkt->size;
5756 
5757  int ret = check_pkt(s, pkt);
5758  if (ret < 0)
5759  return ret;
5760 
5761  if (mov->flags & FF_MOV_FLAG_FRAG_DISCONT) {
5762  int i;
5763  for (i = 0; i < s->nb_streams; i++)
5764  mov->tracks[i].frag_discont = 1;
5766  }
5767 
5769  if (trk->dts_shift == AV_NOPTS_VALUE)
5770  trk->dts_shift = pkt->pts - pkt->dts;
5771  pkt->dts += trk->dts_shift;
5772  }
5773 
5774  if (trk->par->codec_id == AV_CODEC_ID_MP4ALS ||
5775  trk->par->codec_id == AV_CODEC_ID_AAC ||
5776  trk->par->codec_id == AV_CODEC_ID_AV1 ||
5777  trk->par->codec_id == AV_CODEC_ID_FLAC) {
5778  int side_size = 0;
5780  if (side && side_size > 0 && (side_size != par->extradata_size || memcmp(side, par->extradata, side_size))) {
5781  void *newextra = av_mallocz(side_size + AV_INPUT_BUFFER_PADDING_SIZE);
5782  if (!newextra)
5783  return AVERROR(ENOMEM);
5784  av_free(par->extradata);
5785  par->extradata = newextra;
5786  memcpy(par->extradata, side, side_size);
5787  par->extradata_size = side_size;
5788  if (!pkt->size) // Flush packet
5789  mov->need_rewrite_extradata = 1;
5790  }
5791  }
5792 
5793  if (!pkt->size) {
5794  if (trk->start_dts == AV_NOPTS_VALUE && trk->frag_discont) {
5795  trk->start_dts = pkt->dts;
5796  if (pkt->pts != AV_NOPTS_VALUE)
5797  trk->start_cts = pkt->pts - pkt->dts;
5798  else
5799  trk->start_cts = 0;
5800  }
5801 
5802  return 0; /* Discard 0 sized packets */
5803  }
5804 
5805  if (trk->entry && pkt->stream_index < s->nb_streams)
5806  frag_duration = av_rescale_q(pkt->dts - trk->cluster[0].dts,
5807  s->streams[pkt->stream_index]->time_base,
5808  AV_TIME_BASE_Q);
5809  if ((mov->max_fragment_duration &&
5810  frag_duration >= mov->max_fragment_duration) ||
5811  (mov->max_fragment_size && mov->mdat_size + size >= mov->max_fragment_size) ||
5812  (mov->flags & FF_MOV_FLAG_FRAG_KEYFRAME &&
5813  par->codec_type == AVMEDIA_TYPE_VIDEO &&
5814  trk->entry && pkt->flags & AV_PKT_FLAG_KEY) ||
5816  if (frag_duration >= mov->min_fragment_duration) {
5817  // Set the duration of this track to line up with the next
5818  // sample in this track. This avoids relying on AVPacket
5819  // duration, but only helps for this particular track, not
5820  // for the other ones that are flushed at the same time.
5821  trk->track_duration = pkt->dts - trk->start_dts;
5822  if (pkt->pts != AV_NOPTS_VALUE)
5823  trk->end_pts = pkt->pts;
5824  else
5825  trk->end_pts = pkt->dts;
5826  trk->end_reliable = 1;
5828  }
5829  }
5830 
5831  return ff_mov_write_packet(s, pkt);
5832 }
5833 
5835  int stream_index,
5836  int64_t dts) {
5837  AVPacket end;
5838  uint8_t data[2] = {0};
5839  int ret;
5840 
5841  av_init_packet(&end);
5842  end.size = sizeof(data);
5843  end.data = data;
5844  end.pts = dts;
5845  end.dts = dts;
5846  end.duration = 0;
5847  end.stream_index = stream_index;
5848 
5850  av_packet_unref(&end);
5851 
5852  return ret;
5853 }
5854 
5856 {
5857  MOVMuxContext *mov = s->priv_data;
5858  MOVTrack *trk;
5859 
5860  if (!pkt) {
5861  mov_flush_fragment(s, 1);
5862  return 1;
5863  }
5864 
5865  trk = &mov->tracks[pkt->stream_index];
5866 
5867  if (is_cover_image(trk->st)) {
5868  int ret;
5869 
5870  if (trk->st->nb_frames >= 1) {
5871  if (trk->st->nb_frames == 1)
5872  av_log(s, AV_LOG_WARNING, "Got more than one picture in stream %d,"
5873  " ignoring.\n", pkt->stream_index);
5874  return 0;
5875  }
5876 
5877  if ((ret = av_packet_ref(&trk->cover_image, pkt)) < 0)
5878  return ret;
5879 
5880  return 0;
5881  } else {
5882  int i;
5883 
5884  if (!pkt->size)
5885  return mov_write_single_packet(s, pkt); /* Passthrough. */
5886 
5887  /*
5888  * Subtitles require special handling.
5889  *
5890  * 1) For full complaince, every track must have a sample at
5891  * dts == 0, which is rarely true for subtitles. So, as soon
5892  * as we see any packet with dts > 0, write an empty subtitle
5893  * at dts == 0 for any subtitle track with no samples in it.
5894  *
5895  * 2) For each subtitle track, check if the current packet's
5896  * dts is past the duration of the last subtitle sample. If
5897  * so, we now need to write an end sample for that subtitle.
5898  *
5899  * This must be done conditionally to allow for subtitles that
5900  * immediately replace each other, in which case an end sample
5901  * is not needed, and is, in fact, actively harmful.
5902  *
5903  * 3) See mov_write_trailer for how the final end sample is
5904  * handled.
5905  */
5906  for (i = 0; i < mov->nb_streams; i++) {
5907  MOVTrack *trk = &mov->tracks[i];
5908  int ret;
5909 
5910  if (trk->par->codec_id == AV_CODEC_ID_MOV_TEXT &&
5911  trk->track_duration < pkt->dts &&
5912  (trk->entry == 0 || !trk->last_sample_is_subtitle_end)) {
5914  if (ret < 0) return ret;
5915  trk->last_sample_is_subtitle_end = 1;
5916  }
5917  }
5918 
5919  if (trk->mode == MODE_MOV && trk->par->codec_type == AVMEDIA_TYPE_VIDEO) {
5920  AVPacket *opkt = pkt;
5921  int reshuffle_ret, ret;
5922  if (trk->is_unaligned_qt_rgb) {
5923  int64_t bpc = trk->par->bits_per_coded_sample != 15 ? trk->par->bits_per_coded_sample : 16;
5924  int expected_stride = ((trk->par->width * bpc + 15) >> 4)*2;
5925  reshuffle_ret = ff_reshuffle_raw_rgb(s, &pkt, trk->par, expected_stride);
5926  if (reshuffle_ret < 0)
5927  return reshuffle_ret;
5928  } else
5929  reshuffle_ret = 0;
5930  if (trk->par->format == AV_PIX_FMT_PAL8 && !trk->pal_done) {
5931  ret = ff_get_packet_palette(s, opkt, reshuffle_ret, trk->palette);
5932  if (ret < 0)
5933  goto fail;
5934  if (ret)
5935  trk->pal_done++;
5936  } else if (trk->par->codec_id == AV_CODEC_ID_RAWVIDEO &&
5937  (trk->par->format == AV_PIX_FMT_GRAY8 ||
5938  trk->par->format == AV_PIX_FMT_MONOBLACK)) {
5939  for (i = 0; i < pkt->size; i++)
5940  pkt->data[i] = ~pkt->data[i];
5941  }
5942  if (reshuffle_ret) {
5944 fail:
5945  if (reshuffle_ret)
5946  av_packet_free(&pkt);
5947  return ret;
5948  }
5949  }
5950 
5951  return mov_write_single_packet(s, pkt);
5952  }
5953 }
5954 
5955 // QuickTime chapters involve an additional text track with the chapter names
5956 // as samples, and a tref pointing from the other tracks to the chapter one.
5957 static int mov_create_chapter_track(AVFormatContext *s, int tracknum)
5958 {
5959  AVIOContext *pb;
5960 
5961  MOVMuxContext *mov = s->priv_data;
5962  MOVTrack *track = &mov->tracks[tracknum];
5963  AVPacket pkt = { .stream_index = tracknum, .flags = AV_PKT_FLAG_KEY };
5964  int i, len;
5965 
5966  track->mode = mov->mode;
5967  track->tag = MKTAG('t','e','x','t');
5968  track->timescale = MOV_TIMESCALE;
5969  track->par = avcodec_parameters_alloc();
5970  if (!track->par)
5971  return AVERROR(ENOMEM);
5973 #if 0
5974  // These properties are required to make QT recognize the chapter track
5975  uint8_t chapter_properties[43] = { 0, 0, 0, 0, 0, 0, 0, 1, };
5976  if (ff_alloc_extradata(track->par, sizeof(chapter_properties)))
5977  return AVERROR(ENOMEM);
5978  memcpy(track->par->extradata, chapter_properties, sizeof(chapter_properties));
5979 #else
5980  if (avio_open_dyn_buf(&pb) >= 0) {
5981  int size;
5982  uint8_t *buf;
5983 
5984  /* Stub header (usually for Quicktime chapter track) */
5985  // TextSampleEntry
5986  avio_wb32(pb, 0x01); // displayFlags
5987  avio_w8(pb, 0x00); // horizontal justification
5988  avio_w8(pb, 0x00); // vertical justification
5989  avio_w8(pb, 0x00); // bgColourRed
5990  avio_w8(pb, 0x00); // bgColourGreen
5991  avio_w8(pb, 0x00); // bgColourBlue
5992  avio_w8(pb, 0x00); // bgColourAlpha
5993  // BoxRecord
5994  avio_wb16(pb, 0x00); // defTextBoxTop
5995  avio_wb16(pb, 0x00); // defTextBoxLeft
5996  avio_wb16(pb, 0x00); // defTextBoxBottom
5997  avio_wb16(pb, 0x00); // defTextBoxRight
5998  // StyleRecord
5999  avio_wb16(pb, 0x00); // startChar
6000  avio_wb16(pb, 0x00); // endChar
6001  avio_wb16(pb, 0x01); // fontID
6002  avio_w8(pb, 0x00); // fontStyleFlags
6003  avio_w8(pb, 0x00); // fontSize
6004  avio_w8(pb, 0x00); // fgColourRed
6005  avio_w8(pb, 0x00); // fgColourGreen
6006  avio_w8(pb, 0x00); // fgColourBlue
6007  avio_w8(pb, 0x00); // fgColourAlpha
6008  // FontTableBox
6009  avio_wb32(pb, 0x0D); // box size
6010  ffio_wfourcc(pb, "ftab"); // box atom name
6011  avio_wb16(pb, 0x01); // entry count
6012  // FontRecord
6013  avio_wb16(pb, 0x01); // font ID
6014  avio_w8(pb, 0x00); // font name length
6015 
6016  if ((size = avio_close_dyn_buf(pb, &buf)) > 0) {
6017  track->par->extradata = buf;
6018  track->par->extradata_size = size;
6019  } else {
6020  av_freep(&buf);
6021  }
6022  }
6023 #endif
6024 
6025  for (i = 0; i < s->nb_chapters; i++) {
6026  AVChapter *c = s->chapters[i];
6027  AVDictionaryEntry *t;
6028 
6029  int64_t end = av_rescale_q(c->end, c->time_base, (AVRational){1,MOV_TIMESCALE});
6030  pkt.pts = pkt.dts = av_rescale_q(c->start, c->time_base, (AVRational){1,MOV_TIMESCALE});
6031  pkt.duration = end - pkt.dts;
6032 
6033  if ((t = av_dict_get(c->metadata, "title", NULL, 0))) {
6034  static const char encd[12] = {
6035  0x00, 0x00, 0x00, 0x0C,
6036  'e', 'n', 'c', 'd',
6037  0x00, 0x00, 0x01, 0x00 };
6038  len = strlen(t->value);
6039  pkt.size = len + 2 + 12;
6040  pkt.data = av_malloc(pkt.size);
6041  if (!pkt.data)
6042  return AVERROR(ENOMEM);
6043  AV_WB16(pkt.data, len);
6044  memcpy(pkt.data + 2, t->value, len);
6045  memcpy(pkt.data + len + 2, encd, sizeof(encd));
6047  av_freep(&pkt.data);
6048  }
6049  }
6050 
6051  return 0;
6052 }
6053 
6054 
6055 static int mov_check_timecode_track(AVFormatContext *s, AVTimecode *tc, int src_index, const char *tcstr)
6056 {
6057  int ret;
6058 
6059  /* compute the frame number */
6060  ret = av_timecode_init_from_string(tc, find_fps(s, s->streams[src_index]), tcstr, s);
6061  return ret;
6062 }
6063 
6065 {
6066  int ret;
6067  MOVMuxContext *mov = s->priv_data;
6068  MOVTrack *track = &mov->tracks[index];
6069  AVStream *src_st = s->streams[src_index];
6070  AVPacket pkt = {.stream_index = index, .flags = AV_PKT_FLAG_KEY, .size = 4};
6071  AVRational rate = find_fps(s, src_st);
6072 
6073  /* tmcd track based on video stream */
6074  track->mode = mov->mode;
6075  track->tag = MKTAG('t','m','c','d');
6076  track->src_track = src_index;
6077  track->timescale = mov->tracks[src_index].timescale;
6078  if (tc.flags & AV_TIMECODE_FLAG_DROPFRAME)
6080 
6081  /* set st to src_st for metadata access*/
6082  track->st = src_st;
6083 
6084  /* encode context: tmcd data stream */
6085  track->par = avcodec_parameters_alloc();
6086  if (!track->par)
6087  return AVERROR(ENOMEM);
6088  track->par->codec_type = AVMEDIA_TYPE_DATA;
6089  track->par->codec_tag = track->tag;
6090  track->st->avg_frame_rate = av_inv_q(rate);
6091 
6092  /* the tmcd track just contains one packet with the frame number */
6093  pkt.data = av_malloc(pkt.size);
6094  if (!pkt.data)
6095  return AVERROR(ENOMEM);
6096  AV_WB32(pkt.data, tc.start);
6098  av_free(pkt.data);
6099  return ret;
6100 }
6101 
6102 /*
6103  * st->disposition controls the "enabled" flag in the tkhd tag.
6104  * QuickTime will not play a track if it is not enabled. So make sure
6105  * that one track of each type (audio, video, subtitle) is enabled.
6106  *
6107  * Subtitles are special. For audio and video, setting "enabled" also
6108  * makes the track "default" (i.e. it is rendered when played). For
6109  * subtitles, an "enabled" subtitle is not rendered by default, but
6110  * if no subtitle is enabled, the subtitle menu in QuickTime will be
6111  * empty!
6112  */
6114 {
6115  MOVMuxContext *mov = s->priv_data;
6116  int i;
6117  int enabled[AVMEDIA_TYPE_NB];
6118  int first[AVMEDIA_TYPE_NB];
6119 
6120  for (i = 0; i < AVMEDIA_TYPE_NB; i++) {
6121  enabled[i] = 0;
6122  first[i] = -1;
6123  }
6124 
6125  for (i = 0; i < s->nb_streams; i++) {
6126  AVStream *st = s->streams[i];
6127 
6130  is_cover_image(st))
6131  continue;
6132 
6133  if (first[st->codecpar->codec_type] < 0)
6134  first[st->codecpar->codec_type] = i;
6135  if (st->disposition & AV_DISPOSITION_DEFAULT) {
6136  mov->tracks[i].flags |= MOV_TRACK_ENABLED;
6137  enabled[st->codecpar->codec_type]++;
6138  }
6139  }
6140 
6141  for (i = 0; i < AVMEDIA_TYPE_NB; i++) {
6142  switch (i) {
6143  case AVMEDIA_TYPE_VIDEO:
6144  case AVMEDIA_TYPE_AUDIO:
6145  case AVMEDIA_TYPE_SUBTITLE:
6146  if (enabled[i] > 1)
6147  mov->per_stream_grouping = 1;
6148  if (!enabled[i] && first[i] >= 0)
6149  mov->tracks[first[i]].flags |= MOV_TRACK_ENABLED;
6150  break;
6151  }
6152  }
6153 }
6154 
6156 {
6157  MOVMuxContext *mov = s->priv_data;
6158  int i;
6159 
6160  if (!mov->tracks)
6161  return;
6162 
6163  if (mov->chapter_track) {
6164  if (mov->tracks[mov->chapter_track].par)
6165  av_freep(&mov->tracks[mov->chapter_track].par->extradata);
6166  av_freep(&mov->tracks[mov->chapter_track].par);
6167  }
6168 
6169  for (i = 0; i < mov->nb_streams; i++) {
6170  if (mov->tracks[i].tag == MKTAG('r','t','p',' '))
6171  ff_mov_close_hinting(&mov->tracks[i]);
6172  else if (mov->tracks[i].tag == MKTAG('t','m','c','d') && mov->nb_meta_tmcd)
6173  av_freep(&mov->tracks[i].par);
6174  av_freep(&mov->tracks[i].cluster);
6175  av_freep(&mov->tracks[i].frag_info);
6177 
6178  if (mov->tracks[i].eac3_priv) {
6179  struct eac3_info *info = mov->tracks[i].eac3_priv;
6180  av_packet_unref(&info->pkt);
6181  av_freep(&mov->tracks[i].eac3_priv);
6182  }
6183  if (mov->tracks[i].vos_len)
6184  av_freep(&mov->tracks[i].vos_data);
6185 
6186  ff_mov_cenc_free(&mov->tracks[i].cenc);
6188  }
6189 
6190  av_freep(&mov->tracks);
6191  ffio_free_dyn_buf(&mov->mdat_buf);
6192 }
6193 
6194 static uint32_t rgb_to_yuv(uint32_t rgb)
6195 {
6196  uint8_t r, g, b;
6197  int y, cb, cr;
6198 
6199  r = (rgb >> 16) & 0xFF;
6200  g = (rgb >> 8) & 0xFF;
6201  b = (rgb ) & 0xFF;
6202 
6203  y = av_clip_uint8(( 16000 + 257 * r + 504 * g + 98 * b)/1000);
6204  cb = av_clip_uint8((128000 - 148 * r - 291 * g + 439 * b)/1000);
6205  cr = av_clip_uint8((128000 + 439 * r - 368 * g - 71 * b)/1000);
6206 
6207  return (y << 16) | (cr << 8) | cb;
6208 }
6209 
6211  AVStream *st)
6212 {
6213  int i, width = 720, height = 480;
6214  int have_palette = 0, have_size = 0;
6215  uint32_t palette[16];
6216  char *cur = st->codecpar->extradata;
6217 
6218  while (cur && *cur) {
6219  if (strncmp("palette:", cur, 8) == 0) {
6220  int i, count;
6221  count = sscanf(cur + 8,
6222  "%06"PRIx32", %06"PRIx32", %06"PRIx32", %06"PRIx32", "
6223  "%06"PRIx32", %06"PRIx32", %06"PRIx32", %06"PRIx32", "
6224  "%06"PRIx32", %06"PRIx32", %06"PRIx32", %06"PRIx32", "
6225  "%06"PRIx32", %06"PRIx32", %06"PRIx32", %06"PRIx32"",
6226  &palette[ 0], &palette[ 1], &palette[ 2], &palette[ 3],
6227  &palette[ 4], &palette[ 5], &palette[ 6], &palette[ 7],
6228  &palette[ 8], &palette[ 9], &palette[10], &palette[11],
6229  &palette[12], &palette[13], &palette[14], &palette[15]);
6230 
6231  for (i = 0; i < count; i++) {
6232  palette[i] = rgb_to_yuv(palette[i]);
6233  }
6234  have_palette = 1;
6235  } else if (!strncmp("size:", cur, 5)) {
6236  sscanf(cur + 5, "%dx%d", &width, &height);
6237  have_size = 1;
6238  }
6239  if (have_palette && have_size)
6240  break;
6241  cur += strcspn(cur, "\n\r");
6242  cur += strspn(cur, "\n\r");
6243  }
6244  if (have_palette) {
6246  if (!track->vos_data)
6247  return AVERROR(ENOMEM);
6248  for (i = 0; i < 16; i++) {
6249  AV_WB32(track->vos_data + i * 4, palette[i]);
6250  }
6251  memset(track->vos_data + 16*4, 0, AV_INPUT_BUFFER_PADDING_SIZE);
6252  track->vos_len = 16 * 4;
6253  }
6254  st->codecpar->width = width;
6255  st->codecpar->height = track->height = height;
6256 
6257  return 0;
6258 }
6259 
6261 {
6262  MOVMuxContext *mov = s->priv_data;
6263  AVDictionaryEntry *global_tcr = av_dict_get(s->metadata, "timecode", NULL, 0);
6264  int i, ret;
6265 
6266  mov->fc = s;
6267 
6268  /* Default mode == MP4 */
6269  mov->mode = MODE_MP4;
6270 
6271  if (s->oformat) {
6272  if (!strcmp("3gp", s->oformat->name)) mov->mode = MODE_3GP;
6273  else if (!strcmp("3g2", s->oformat->name)) mov->mode = MODE_3GP|MODE_3G2;
6274  else if (!strcmp("mov", s->oformat->name)) mov->mode = MODE_MOV;
6275  else if (!strcmp("psp", s->oformat->name)) mov->mode = MODE_PSP;
6276  else if (!strcmp("ipod",s->oformat->name)) mov->mode = MODE_IPOD;
6277  else if (!strcmp("ismv",s->oformat->name)) mov->mode = MODE_ISM;
6278  else if (!strcmp("f4v", s->oformat->name)) mov->mode = MODE_F4V;
6279  }
6280 
6281  if (mov->flags & FF_MOV_FLAG_DELAY_MOOV)
6282  mov->flags |= FF_MOV_FLAG_EMPTY_MOOV;
6283 
6284  /* Set the FRAGMENT flag if any of the fragmentation methods are
6285  * enabled. */
6286  if (mov->max_fragment_duration || mov->max_fragment_size ||
6287  mov->flags & (FF_MOV_FLAG_EMPTY_MOOV |
6291  mov->flags |= FF_MOV_FLAG_FRAGMENT;
6292 
6293  /* Set other implicit flags immediately */
6294  if (mov->mode == MODE_ISM)
6297  if (mov->flags & FF_MOV_FLAG_DASH)
6300  if (mov->flags & FF_MOV_FLAG_CMAF)
6303 
6304  if (mov->flags & FF_MOV_FLAG_EMPTY_MOOV && s->flags & AVFMT_FLAG_AUTO_BSF) {
6305  av_log(s, AV_LOG_VERBOSE, "Empty MOOV enabled; disabling automatic bitstream filtering\n");
6306  s->flags &= ~AVFMT_FLAG_AUTO_BSF;
6307  }
6308 
6310  av_log(s, AV_LOG_WARNING, "Global SIDX enabled; Ignoring skip_sidx option\n");
6311  mov->flags &= ~FF_MOV_FLAG_SKIP_SIDX;
6312  }
6313 
6314  if (mov->flags & FF_MOV_FLAG_FASTSTART) {
6315  mov->reserved_moov_size = -1;
6316  }
6317 
6318  if (mov->use_editlist < 0) {
6319  mov->use_editlist = 1;
6320  if (mov->flags & FF_MOV_FLAG_FRAGMENT &&
6321  !(mov->flags & FF_MOV_FLAG_DELAY_MOOV)) {
6322  // If we can avoid needing an edit list by shifting the
6323  // tracks, prefer that over (trying to) write edit lists
6324  // in fragmented output.
6325  if (s->avoid_negative_ts == AVFMT_AVOID_NEG_TS_AUTO ||
6326  s->avoid_negative_ts == AVFMT_AVOID_NEG_TS_MAKE_ZERO)
6327  mov->use_editlist = 0;
6328  }
6329  if (mov->flags & FF_MOV_FLAG_CMAF) {
6330  // CMAF Track requires negative cts offsets without edit lists
6331  mov->use_editlist = 0;
6332  }
6333  }
6334  if (mov->flags & FF_MOV_FLAG_EMPTY_MOOV &&
6335  !(mov->flags & FF_MOV_FLAG_DELAY_MOOV) && mov->use_editlist)
6336  av_log(s, AV_LOG_WARNING, "No meaningful edit list will be written when using empty_moov without delay_moov\n");
6337 
6338  if (mov->flags & FF_MOV_FLAG_CMAF && mov->use_editlist) {
6339  av_log(s, AV_LOG_WARNING, "Edit list enabled; Assuming writing CMAF Track File\n");
6341  }
6342  if (!mov->use_editlist && s->avoid_negative_ts == AVFMT_AVOID_NEG_TS_AUTO &&
6344  s->avoid_negative_ts = AVFMT_AVOID_NEG_TS_MAKE_ZERO;
6345 
6346  /* Clear the omit_tfhd_offset flag if default_base_moof is set;
6347  * if the latter is set that's enough and omit_tfhd_offset doesn't
6348  * add anything extra on top of that. */
6349  if (mov->flags & FF_MOV_FLAG_OMIT_TFHD_OFFSET &&
6352 
6353  if (mov->frag_interleave &&
6356  "Sample interleaving in fragments is mutually exclusive with "
6357  "omit_tfhd_offset and separate_moof\n");
6358  return AVERROR(EINVAL);
6359  }
6360 
6361  /* Non-seekable output is ok if using fragmentation. If ism_lookahead
6362  * is enabled, we don't support non-seekable output at all. */
6363  if (!(s->pb->seekable & AVIO_SEEKABLE_NORMAL) &&
6364  (!(mov->flags & FF_MOV_FLAG_FRAGMENT) || mov->ism_lookahead)) {
6365  av_log(s, AV_LOG_ERROR, "muxer does not support non seekable output\n");
6366  return AVERROR(EINVAL);
6367  }
6368 
6369  mov->nb_streams = s->nb_streams;
6370  if (mov->mode & (MODE_MP4|MODE_MOV|MODE_IPOD) && s->nb_chapters)
6371  mov->chapter_track = mov->nb_streams++;
6372 
6373  if (mov->flags & FF_MOV_FLAG_RTP_HINT) {
6374  for (i = 0; i < s->nb_streams; i++)
6375  if (rtp_hinting_needed(s->streams[i]))
6376  mov->nb_streams++;
6377  }
6378 
6379  if ( mov->write_tmcd == -1 && (mov->mode == MODE_MOV || mov->mode == MODE_MP4)
6380  || mov->write_tmcd == 1) {
6381  /* +1 tmcd track for each video stream with a timecode */
6382  for (i = 0; i < s->nb_streams; i++) {
6383  AVStream *st = s->streams[i];
6384  AVDictionaryEntry *t = global_tcr;
6385  if (st->codecpar->codec_type == AVMEDIA_TYPE_VIDEO &&
6386  (t || (t=av_dict_get(st->metadata, "timecode", NULL, 0)))) {
6387  AVTimecode tc;
6388  ret = mov_check_timecode_track(s, &tc, i, t->value);
6389  if (ret >= 0)
6390  mov->nb_meta_tmcd++;
6391  }
6392  }
6393 
6394  /* check if there is already a tmcd track to remux */
6395  if (mov->nb_meta_tmcd) {
6396  for (i = 0; i < s->nb_streams; i++) {
6397  AVStream *st = s->streams[i];
6398  if (st->codecpar->codec_tag == MKTAG('t','m','c','d')) {
6399  av_log(s, AV_LOG_WARNING, "You requested a copy of the original timecode track "
6400  "so timecode metadata are now ignored\n");
6401  mov->nb_meta_tmcd = 0;
6402  }
6403  }
6404  }
6405 
6406  mov->nb_streams += mov->nb_meta_tmcd;
6407  }
6408 
6409  // Reserve an extra stream for chapters for the case where chapters
6410  // are written in the trailer
6411  mov->tracks = av_mallocz_array((mov->nb_streams + 1), sizeof(*mov->tracks));
6412  if (!mov->tracks)
6413  return AVERROR(ENOMEM);
6414 
6415  if (mov->encryption_scheme_str != NULL && strcmp(mov->encryption_scheme_str, "none") != 0) {
6416  if (strcmp(mov->encryption_scheme_str, "cenc-aes-ctr") == 0) {
6418 
6419  if (mov->encryption_key_len != AES_CTR_KEY_SIZE) {
6420  av_log(s, AV_LOG_ERROR, "Invalid encryption key len %d expected %d\n",
6422  return AVERROR(EINVAL);
6423  }
6424 
6425  if (mov->encryption_kid_len != CENC_KID_SIZE) {
6426  av_log(s, AV_LOG_ERROR, "Invalid encryption kid len %d expected %d\n",
6428  return AVERROR(EINVAL);
6429  }
6430  } else {
6431  av_log(s, AV_LOG_ERROR, "unsupported encryption scheme %s\n",
6432  mov->encryption_scheme_str);
6433  return AVERROR(EINVAL);
6434  }
6435  }
6436 
6437  for (i = 0; i < s->nb_streams; i++) {
6438  AVStream *st= s->streams[i];
6439  MOVTrack *track= &mov->tracks[i];
6440  AVDictionaryEntry *lang = av_dict_get(st->metadata, "language", NULL,0);
6441 
6442  track->st = st;
6443  track->par = st->codecpar;
6444  track->language = ff_mov_iso639_to_lang(lang?lang->value:"und", mov->mode!=MODE_MOV);
6445  if (track->language < 0)
6446  track->language = 32767; // Unspecified Macintosh language code
6447  track->mode = mov->mode;
6448  track->tag = mov_find_codec_tag(s, track);
6449  if (!track->tag) {
6450  av_log(s, AV_LOG_ERROR, "Could not find tag for codec %s in stream #%d, "
6451  "codec not currently supported in container\n",
6453  return AVERROR(EINVAL);
6454  }
6455  /* If hinting of this track is enabled by a later hint track,
6456  * this is updated. */
6457  track->hint_track = -1;
6458  track->start_dts = AV_NOPTS_VALUE;
6459  track->start_cts = AV_NOPTS_VALUE;
6460  track->end_pts = AV_NOPTS_VALUE;
6461  track->dts_shift = AV_NOPTS_VALUE;
6462  if (st->codecpar->codec_type == AVMEDIA_TYPE_VIDEO) {
6463  if (track->tag == MKTAG('m','x','3','p') || track->tag == MKTAG('m','x','3','n') ||
6464  track->tag == MKTAG('m','x','4','p') || track->tag == MKTAG('m','x','4','n') ||
6465  track->tag == MKTAG('m','x','5','p') || track->tag == MKTAG('m','x','5','n')) {
6466  if (st->codecpar->width != 720 || (st->codecpar->height != 608 && st->codecpar->height != 512)) {
6467  av_log(s, AV_LOG_ERROR, "D-10/IMX must use 720x608 or 720x512 video resolution\n");
6468  return AVERROR(EINVAL);
6469  }
6470  track->height = track->tag >> 24 == 'n' ? 486 : 576;
6471  }
6472  if (mov->video_track_timescale) {
6473  track->timescale = mov->video_track_timescale;
6474  if (mov->mode == MODE_ISM && mov->video_track_timescale != 10000000)
6475  av_log(s, AV_LOG_WARNING, "Warning: some tools, like mp4split, assume a timescale of 10000000 for ISMV.\n");
6476  } else {
6477  track->timescale = st->time_base.den;
6478  while(track->timescale < 10000)
6479  track->timescale *= 2;
6480  }
6481  if (st->codecpar->width > 65535 || st->codecpar->height > 65535) {
6482  av_log(s, AV_LOG_ERROR, "Resolution %dx%d too large for mov/mp4\n", st->codecpar->width, st->codecpar->height);
6483  return AVERROR(EINVAL);
6484  }
6485  if (track->mode == MODE_MOV && track->timescale > 100000)
6487  "WARNING codec timebase is very high. If duration is too long,\n"
6488  "file may not be playable by quicktime. Specify a shorter timebase\n"
6489  "or choose different container.\n");
6490  if (track->mode == MODE_MOV &&
6491  track->par->codec_id == AV_CODEC_ID_RAWVIDEO &&
6492  track->tag == MKTAG('r','a','w',' ')) {
6493  enum AVPixelFormat pix_fmt = track->par->format;
6494  if (pix_fmt == AV_PIX_FMT_NONE && track->par->bits_per_coded_sample == 1)
6496  track->is_unaligned_qt_rgb =
6499  pix_fmt == AV_PIX_FMT_PAL8 ||
6503  }
6504  if (track->par->codec_id == AV_CODEC_ID_VP9 ||
6505  track->par->codec_id == AV_CODEC_ID_AV1) {
6506  if (track->mode != MODE_MP4) {
6507  av_log(s, AV_LOG_ERROR, "%s only supported in MP4.\n", avcodec_get_name(track->par->codec_id));
6508  return AVERROR(EINVAL);
6509  }
6510  } else if (track->par->codec_id == AV_CODEC_ID_VP8) {
6511  /* altref frames handling is not defined in the spec as of version v1.0,
6512  * so just forbid muxing VP8 streams altogether until a new version does */
6513  av_log(s, AV_LOG_ERROR, "VP8 muxing is currently not supported.\n");
6514  return AVERROR_PATCHWELCOME;
6515  }
6516  } else if (st->codecpar->codec_type == AVMEDIA_TYPE_AUDIO) {
6517  track->timescale = st->codecpar->sample_rate;
6519  av_log(s, AV_LOG_WARNING, "track %d: codec frame size is not set\n", i);
6520  track->audio_vbr = 1;
6521  }else if (st->codecpar->codec_id == AV_CODEC_ID_ADPCM_MS ||
6524  if (!st->codecpar->block_align) {
6525  av_log(s, AV_LOG_ERROR, "track %d: codec block align is not set for adpcm\n", i);
6526  return AVERROR(EINVAL);
6527  }
6528  track->sample_size = st->codecpar->block_align;
6529  }else if (st->codecpar->frame_size > 1){ /* assume compressed audio */
6530  track->audio_vbr = 1;
6531  }else{
6533  }
6534  if (st->codecpar->codec_id == AV_CODEC_ID_ILBC ||
6536  track->audio_vbr = 1;
6537  }
6538  if (track->mode != MODE_MOV &&
6539  track->par->codec_id == AV_CODEC_ID_MP3 && track->timescale < 16000) {
6540  if (s->strict_std_compliance >= FF_COMPLIANCE_NORMAL) {
6541  av_log(s, AV_LOG_ERROR, "track %d: muxing mp3 at %dhz is not standard, to mux anyway set strict to -1\n",
6542  i, track->par->sample_rate);
6543  return AVERROR(EINVAL);
6544  } else {
6545  av_log(s, AV_LOG_WARNING, "track %d: muxing mp3 at %dhz is not standard in MP4\n",
6546  i, track->par->sample_rate);
6547  }
6548  }
6549  if (track->par->codec_id == AV_CODEC_ID_FLAC ||
6550  track->par->codec_id == AV_CODEC_ID_TRUEHD ||
6551  track->par->codec_id == AV_CODEC_ID_OPUS) {
6552  if (track->mode != MODE_MP4) {
6553  av_log(s, AV_LOG_ERROR, "%s only supported in MP4.\n", avcodec_get_name(track->par->codec_id));
6554  return AVERROR(EINVAL);
6555  }
6556  if (track->par->codec_id != AV_CODEC_ID_OPUS &&
6557  s->strict_std_compliance > FF_COMPLIANCE_EXPERIMENTAL) {
6559  "%s in MP4 support is experimental, add "
6560  "'-strict %d' if you want to use it.\n",
6562  return AVERROR_EXPERIMENTAL;
6563  }
6564  }
6565  } else if (st->codecpar->codec_type == AVMEDIA_TYPE_SUBTITLE) {
6566  track->timescale = st->time_base.den;
6567  } else if (st->codecpar->codec_type == AVMEDIA_TYPE_DATA) {
6568  track->timescale = st->time_base.den;
6569  } else {
6570  track->timescale = MOV_TIMESCALE;
6571  }
6572  if (!track->height)
6573  track->height = st->codecpar->height;
6574  /* The Protected Interoperable File Format (PIFF) standard, used by ISMV recommends but
6575  doesn't mandate a track timescale of 10,000,000. The muxer allows a custom timescale
6576  for video tracks, so if user-set, it isn't overwritten */
6577  if (mov->mode == MODE_ISM &&
6580  track->timescale = 10000000;
6581  }
6582 
6583  avpriv_set_pts_info(st, 64, 1, track->timescale);
6584 
6586  ret = ff_mov_cenc_init(&track->cenc, mov->encryption_key,
6587  track->par->codec_id == AV_CODEC_ID_H264, s->flags & AVFMT_FLAG_BITEXACT);
6588  if (ret)
6589  return ret;
6590  }
6591  }
6592 
6593  enable_tracks(s);
6594  return 0;
6595 }
6596 
6598 {
6599  AVIOContext *pb = s->pb;
6600  MOVMuxContext *mov = s->priv_data;
6601  AVDictionaryEntry *t, *global_tcr = av_dict_get(s->metadata, "timecode", NULL, 0);
6602  int i, ret, hint_track = 0, tmcd_track = 0, nb_tracks = s->nb_streams;
6603 
6604  if (mov->mode & (MODE_MP4|MODE_MOV|MODE_IPOD) && s->nb_chapters)
6605  nb_tracks++;
6606 
6607  if (mov->flags & FF_MOV_FLAG_RTP_HINT) {
6608  hint_track = nb_tracks;
6609  for (i = 0; i < s->nb_streams; i++)
6610  if (rtp_hinting_needed(s->streams[i]))
6611  nb_tracks++;
6612  }
6613 
6614  if (mov->nb_meta_tmcd)
6615  tmcd_track = nb_tracks;
6616 
6617  for (i = 0; i < s->nb_streams; i++) {
6618  int j;
6619  AVStream *st= s->streams[i];
6620  MOVTrack *track= &mov->tracks[i];
6621 
6622  /* copy extradata if it exists */
6623  if (st->codecpar->extradata_size) {
6626  else if (!TAG_IS_AVCI(track->tag) && st->codecpar->codec_id != AV_CODEC_ID_DNXHD) {
6627  track->vos_len = st->codecpar->extradata_size;
6629  if (!track->vos_data) {
6630  return AVERROR(ENOMEM);
6631  }
6632  memcpy(track->vos_data, st->codecpar->extradata, track->vos_len);
6633  memset(track->vos_data + track->vos_len, 0, AV_INPUT_BUFFER_PADDING_SIZE);
6634  }
6635  }
6636 
6637  if (st->codecpar->codec_type != AVMEDIA_TYPE_AUDIO ||
6639  continue;
6640 
6641  for (j = 0; j < s->nb_streams; j++) {
6642  AVStream *stj= s->streams[j];
6643  MOVTrack *trackj= &mov->tracks[j];
6644  if (j == i)
6645  continue;
6646 
6647  if (stj->codecpar->codec_type != AVMEDIA_TYPE_AUDIO ||
6648  trackj->par->channel_layout != AV_CH_LAYOUT_MONO ||
6649  trackj->language != track->language ||
6650  trackj->tag != track->tag
6651  )
6652  continue;
6653  track->multichannel_as_mono++;
6654  }
6655  }
6656 
6657  if (!(mov->flags & FF_MOV_FLAG_DELAY_MOOV)) {
6658  if ((ret = mov_write_identification(pb, s)) < 0)
6659  return ret;
6660  }
6661 
6662  if (mov->reserved_moov_size){
6663  mov->reserved_header_pos = avio_tell(pb);
6664  if (mov->reserved_moov_size > 0)
6665  avio_skip(pb, mov->reserved_moov_size);
6666  }
6667 
6668  if (mov->flags & FF_MOV_FLAG_FRAGMENT) {
6669  /* If no fragmentation options have been set, set a default. */
6670  if (!(mov->flags & (FF_MOV_FLAG_FRAG_KEYFRAME |
6675  } else {
6676  if (mov->flags & FF_MOV_FLAG_FASTSTART)
6677  mov->reserved_header_pos = avio_tell(pb);
6678  mov_write_mdat_tag(pb, mov);
6679  }
6680 
6682  if (mov->time)
6683  mov->time += 0x7C25B080; // 1970 based -> 1904 based
6684 
6685  if (mov->chapter_track)
6686  if ((ret = mov_create_chapter_track(s, mov->chapter_track)) < 0)
6687  return ret;
6688 
6689  if (mov->flags & FF_MOV_FLAG_RTP_HINT) {
6690  for (i = 0; i < s->nb_streams; i++) {
6691  if (rtp_hinting_needed(s->streams[i])) {
6692  if ((ret = ff_mov_init_hinting(s, hint_track, i)) < 0)
6693  return ret;
6694  hint_track++;
6695  }
6696  }
6697  }
6698 
6699  if (mov->nb_meta_tmcd) {
6700  /* Initialize the tmcd tracks */
6701  for (i = 0; i < s->nb_streams; i++) {
6702  AVStream *st = s->streams[i];
6703  t = global_tcr;
6704 
6705  if (st->codecpar->codec_type == AVMEDIA_TYPE_VIDEO) {
6706  AVTimecode tc;
6707  if (!t)
6708  t = av_dict_get(st->metadata, "timecode", NULL, 0);
6709  if (!t)
6710  continue;
6711  if (mov_check_timecode_track(s, &tc, i, t->value) < 0)
6712  continue;
6713  if ((ret = mov_create_timecode_track(s, tmcd_track, i, tc)) < 0)
6714  return ret;
6715  tmcd_track++;
6716  }
6717  }
6718  }
6719 
6720  avio_flush(pb);
6721 
6722  if (mov->flags & FF_MOV_FLAG_ISML)
6723  mov_write_isml_manifest(pb, mov, s);
6724 
6725  if (mov->flags & FF_MOV_FLAG_EMPTY_MOOV &&
6726  !(mov->flags & FF_MOV_FLAG_DELAY_MOOV)) {
6727  if ((ret = mov_write_moov_tag(pb, mov, s)) < 0)
6728  return ret;
6729  mov->moov_written = 1;
6730  if (mov->flags & FF_MOV_FLAG_GLOBAL_SIDX)
6731  mov->reserved_header_pos = avio_tell(pb);
6732  }
6733 
6734  return 0;
6735 }
6736 
6738 {
6739  int ret;
6740  AVIOContext *moov_buf;
6741  MOVMuxContext *mov = s->priv_data;
6742 
6743  if ((ret = ffio_open_null_buf(&moov_buf)) < 0)
6744  return ret;
6745  if ((ret = mov_write_moov_tag(moov_buf, mov, s)) < 0)
6746  return ret;
6747  return ffio_close_null_buf(moov_buf);
6748 }
6749 
6751 {
6752  int ret;
6753  AVIOContext *buf;
6754  MOVMuxContext *mov = s->priv_data;
6755 
6756  if ((ret = ffio_open_null_buf(&buf)) < 0)
6757  return ret;
6758  mov_write_sidx_tags(buf, mov, -1, 0);
6759  return ffio_close_null_buf(buf);
6760 }
6761 
6762 /*
6763  * This function gets the moov size if moved to the top of the file: the chunk
6764  * offset table can switch between stco (32-bit entries) to co64 (64-bit
6765  * entries) when the moov is moved to the beginning, so the size of the moov
6766  * would change. It also updates the chunk offset tables.
6767  */
6769 {
6770  int i, moov_size, moov_size2;
6771  MOVMuxContext *mov = s->priv_data;
6772 
6773  moov_size = get_moov_size(s);
6774  if (moov_size < 0)
6775  return moov_size;
6776 
6777  for (i = 0; i < mov->nb_streams; i++)
6778  mov->tracks[i].data_offset += moov_size;
6779 
6780  moov_size2 = get_moov_size(s);
6781  if (moov_size2 < 0)
6782  return moov_size2;
6783 
6784  /* if the size changed, we just switched from stco to co64 and need to
6785  * update the offsets */
6786  if (moov_size2 != moov_size)
6787  for (i = 0; i < mov->nb_streams; i++)
6788  mov->tracks[i].data_offset += moov_size2 - moov_size;
6789 
6790  return moov_size2;
6791 }
6792 
6794 {
6795  int i, sidx_size;
6796  MOVMuxContext *mov = s->priv_data;
6797 
6798  sidx_size = get_sidx_size(s);
6799  if (sidx_size < 0)
6800  return sidx_size;
6801 
6802  for (i = 0; i < mov->nb_streams; i++)
6803  mov->tracks[i].data_offset += sidx_size;
6804 
6805  return sidx_size;
6806 }
6807 
6809 {
6810  int ret = 0, moov_size;
6811  MOVMuxContext *mov = s->priv_data;
6812  int64_t pos, pos_end;
6813  uint8_t *buf, *read_buf[2];
6814  int read_buf_id = 0;
6815  int read_size[2];
6816  AVIOContext *read_pb;
6817 
6818  if (mov->flags & FF_MOV_FLAG_FRAGMENT)
6819  moov_size = compute_sidx_size(s);
6820  else
6821  moov_size = compute_moov_size(s);
6822  if (moov_size < 0)
6823  return moov_size;
6824 
6825  buf = av_malloc(moov_size * 2);
6826  if (!buf)
6827  return AVERROR(ENOMEM);
6828  read_buf[0] = buf;
6829  read_buf[1] = buf + moov_size;
6830 
6831  /* Shift the data: the AVIO context of the output can only be used for
6832  * writing, so we re-open the same output, but for reading. It also avoids
6833  * a read/seek/write/seek back and forth. */
6834  avio_flush(s->pb);
6835  ret = s->io_open(s, &read_pb, s->url, AVIO_FLAG_READ, NULL);
6836  if (ret < 0) {
6837  av_log(s, AV_LOG_ERROR, "Unable to re-open %s output file for "
6838  "the second pass (faststart)\n", s->url);
6839  goto end;
6840  }
6841 
6842  /* mark the end of the shift to up to the last data we wrote, and get ready
6843  * for writing */
6844  pos_end = avio_tell(s->pb);
6845  avio_seek(s->pb, mov->reserved_header_pos + moov_size, SEEK_SET);
6846 
6847  /* start reading at where the new moov will be placed */
6848  avio_seek(read_pb, mov->reserved_header_pos, SEEK_SET);
6849  pos = avio_tell(read_pb);
6850 
6851 #define READ_BLOCK do { \
6852  read_size[read_buf_id] = avio_read(read_pb, read_buf[read_buf_id], moov_size); \
6853  read_buf_id ^= 1; \
6854 } while (0)
6855 
6856  /* shift data by chunk of at most moov_size */
6857  READ_BLOCK;
6858  do {
6859  int n;
6860  READ_BLOCK;
6861  n = read_size[read_buf_id];
6862  if (n <= 0)
6863  break;
6864  avio_write(s->pb, read_buf[read_buf_id], n);
6865  pos += n;
6866  } while (pos < pos_end);
6867  ff_format_io_close(s, &read_pb);
6868 
6869 end:
6870  av_free(buf);
6871  return ret;
6872 }
6873 
6875 {
6876  MOVMuxContext *mov = s->priv_data;
6877  AVIOContext *pb = s->pb;
6878  int res = 0;
6879  int i;
6880  int64_t moov_pos;
6881 
6882  if (mov->need_rewrite_extradata) {
6883  for (i = 0; i < s->nb_streams; i++) {
6884  MOVTrack *track = &mov->tracks[i];
6885  AVCodecParameters *par = track->par;
6886 
6887  track->vos_len = par->extradata_size;
6888  av_freep(&track->vos_data);
6890  if (!track->vos_data)
6891  return AVERROR(ENOMEM);
6892  memcpy(track->vos_data, par->extradata, track->vos_len);
6893  memset(track->vos_data + track->vos_len, 0, AV_INPUT_BUFFER_PADDING_SIZE);
6894  }
6895  mov->need_rewrite_extradata = 0;
6896  }
6897 
6898  /*
6899  * Before actually writing the trailer, make sure that there are no
6900  * dangling subtitles, that need a terminating sample.
6901  */
6902  for (i = 0; i < mov->nb_streams; i++) {
6903  MOVTrack *trk = &mov->tracks[i];
6904  if (trk->par->codec_id == AV_CODEC_ID_MOV_TEXT &&
6907  trk->last_sample_is_subtitle_end = 1;
6908  }
6909  }
6910 
6911  // If there were no chapters when the header was written, but there
6912  // are chapters now, write them in the trailer. This only works
6913  // when we are not doing fragments.
6914  if (!mov->chapter_track && !(mov->flags & FF_MOV_FLAG_FRAGMENT)) {
6915  if (mov->mode & (MODE_MP4|MODE_MOV|MODE_IPOD) && s->nb_chapters) {
6916  mov->chapter_track = mov->nb_streams++;
6917  if ((res = mov_create_chapter_track(s, mov->chapter_track)) < 0)
6918  return res;
6919  }
6920  }
6921 
6922  if (!(mov->flags & FF_MOV_FLAG_FRAGMENT)) {
6923  moov_pos = avio_tell(pb);
6924 
6925  /* Write size of mdat tag */
6926  if (mov->mdat_size + 8 <= UINT32_MAX) {
6927  avio_seek(pb, mov->mdat_pos, SEEK_SET);
6928  avio_wb32(pb, mov->mdat_size + 8);
6929  } else {
6930  /* overwrite 'wide' placeholder atom */
6931  avio_seek(pb, mov->mdat_pos - 8, SEEK_SET);
6932  /* special value: real atom size will be 64 bit value after
6933  * tag field */
6934  avio_wb32(pb, 1);
6935  ffio_wfourcc(pb, "mdat");
6936  avio_wb64(pb, mov->mdat_size + 16);
6937  }
6938  avio_seek(pb, mov->reserved_moov_size > 0 ? mov->reserved_header_pos : moov_pos, SEEK_SET);
6939 
6940  if (mov->flags & FF_MOV_FLAG_FASTSTART) {
6941  av_log(s, AV_LOG_INFO, "Starting second pass: moving the moov atom to the beginning of the file\n");
6942  res = shift_data(s);
6943  if (res < 0)
6944  return res;
6945  avio_seek(pb, mov->reserved_header_pos, SEEK_SET);
6946  if ((res = mov_write_moov_tag(pb, mov, s)) < 0)
6947  return res;
6948  } else if (mov->reserved_moov_size > 0) {
6949  int64_t size;
6950  if ((res = mov_write_moov_tag(pb, mov, s)) < 0)
6951  return res;
6952  size = mov->reserved_moov_size - (avio_tell(pb) - mov->reserved_header_pos);
6953  if (size < 8){
6954  av_log(s, AV_LOG_ERROR, "reserved_moov_size is too small, needed %"PRId64" additional\n", 8-size);
6955  return AVERROR(EINVAL);
6956  }
6957  avio_wb32(pb, size);
6958  ffio_wfourcc(pb, "free");
6959  ffio_fill(pb, 0, size - 8);
6960  avio_seek(pb, moov_pos, SEEK_SET);
6961  } else {
6962  if ((res = mov_write_moov_tag(pb, mov, s)) < 0)
6963  return res;
6964  }
6965  res = 0;
6966  } else {
6968  for (i = 0; i < mov->nb_streams; i++)
6969  mov->tracks[i].data_offset = 0;
6970  if (mov->flags & FF_MOV_FLAG_GLOBAL_SIDX) {
6971  int64_t end;
6972  av_log(s, AV_LOG_INFO, "Starting second pass: inserting sidx atoms\n");
6973  res = shift_data(s);
6974  if (res < 0)
6975  return res;
6976  end = avio_tell(pb);
6977  avio_seek(pb, mov->reserved_header_pos, SEEK_SET);
6978  mov_write_sidx_tags(pb, mov, -1, 0);
6979  avio_seek(pb, end, SEEK_SET);
6980  }
6981  if (!(mov->flags & FF_MOV_FLAG_SKIP_TRAILER)) {
6983  mov_write_mfra_tag(pb, mov);
6984  }
6985  }
6986 
6987  return res;
6988 }
6989 
6990 static int mov_check_bitstream(struct AVFormatContext *s, const AVPacket *pkt)
6991 {
6992  int ret = 1;
6993  AVStream *st = s->streams[pkt->stream_index];
6994 
6995  if (st->codecpar->codec_id == AV_CODEC_ID_AAC) {
6996  if (pkt->size > 2 && (AV_RB16(pkt->data) & 0xfff0) == 0xfff0)
6997  ret = ff_stream_add_bitstream_filter(st, "aac_adtstoasc", NULL);
6998  } else if (st->codecpar->codec_id == AV_CODEC_ID_VP9) {
6999  ret = ff_stream_add_bitstream_filter(st, "vp9_superframe", NULL);
7000  }
7001 
7002  return ret;
7003 }
7004 
7005 static const AVCodecTag codec_3gp_tags[] = {
7006  { AV_CODEC_ID_H263, MKTAG('s','2','6','3') },
7007  { AV_CODEC_ID_H264, MKTAG('a','v','c','1') },
7008  { AV_CODEC_ID_MPEG4, MKTAG('m','p','4','v') },
7009  { AV_CODEC_ID_AAC, MKTAG('m','p','4','a') },
7010  { AV_CODEC_ID_AMR_NB, MKTAG('s','a','m','r') },
7011  { AV_CODEC_ID_AMR_WB, MKTAG('s','a','w','b') },
7012  { AV_CODEC_ID_MOV_TEXT, MKTAG('t','x','3','g') },
7013  { AV_CODEC_ID_NONE, 0 },
7014 };
7015 
7017  { AV_CODEC_ID_MPEG4, MKTAG('m', 'p', '4', 'v') },
7018  { AV_CODEC_ID_H264, MKTAG('a', 'v', 'c', '1') },
7019  { AV_CODEC_ID_H264, MKTAG('a', 'v', 'c', '3') },
7020  { AV_CODEC_ID_HEVC, MKTAG('h', 'e', 'v', '1') },
7021  { AV_CODEC_ID_HEVC, MKTAG('h', 'v', 'c', '1') },
7022  { AV_CODEC_ID_MPEG2VIDEO, MKTAG('m', 'p', '4', 'v') },
7023  { AV_CODEC_ID_MPEG1VIDEO, MKTAG('m', 'p', '4', 'v') },
7024  { AV_CODEC_ID_MJPEG, MKTAG('m', 'p', '4', 'v') },
7025  { AV_CODEC_ID_PNG, MKTAG('m', 'p', '4', 'v') },
7026  { AV_CODEC_ID_JPEG2000, MKTAG('m', 'p', '4', 'v') },
7027  { AV_CODEC_ID_VC1, MKTAG('v', 'c', '-', '1') },
7028  { AV_CODEC_ID_DIRAC, MKTAG('d', 'r', 'a', 'c') },
7029  { AV_CODEC_ID_TSCC2, MKTAG('m', 'p', '4', 'v') },
7030  { AV_CODEC_ID_VP9, MKTAG('v', 'p', '0', '9') },
7031  { AV_CODEC_ID_AV1, MKTAG('a', 'v', '0', '1') },
7032  { AV_CODEC_ID_AAC, MKTAG('m', 'p', '4', 'a') },
7033  { AV_CODEC_ID_MP4ALS, MKTAG('m', 'p', '4', 'a') },
7034  { AV_CODEC_ID_MP3, MKTAG('m', 'p', '4', 'a') },
7035  { AV_CODEC_ID_MP2, MKTAG('m', 'p', '4', 'a') },
7036  { AV_CODEC_ID_AC3, MKTAG('a', 'c', '-', '3') },
7037  { AV_CODEC_ID_EAC3, MKTAG('e', 'c', '-', '3') },
7038  { AV_CODEC_ID_DTS, MKTAG('m', 'p', '4', 'a') },
7039  { AV_CODEC_ID_TRUEHD, MKTAG('m', 'l', 'p', 'a') },
7040  { AV_CODEC_ID_FLAC, MKTAG('f', 'L', 'a', 'C') },
7041  { AV_CODEC_ID_OPUS, MKTAG('O', 'p', 'u', 's') },
7042  { AV_CODEC_ID_VORBIS, MKTAG('m', 'p', '4', 'a') },
7043  { AV_CODEC_ID_QCELP, MKTAG('m', 'p', '4', 'a') },
7044  { AV_CODEC_ID_EVRC, MKTAG('m', 'p', '4', 'a') },
7045  { AV_CODEC_ID_DVD_SUBTITLE, MKTAG('m', 'p', '4', 's') },
7046  { AV_CODEC_ID_MOV_TEXT, MKTAG('t', 'x', '3', 'g') },
7047  { AV_CODEC_ID_BIN_DATA, MKTAG('g', 'p', 'm', 'd') },
7048  { AV_CODEC_ID_MPEGH_3D_AUDIO, MKTAG('m', 'h', 'm', '1') },
7049  { AV_CODEC_ID_NONE, 0 },
7050 };
7051 
7053  { AV_CODEC_ID_WMAPRO , MKTAG('w', 'm', 'a', ' ') },
7054  { AV_CODEC_ID_NONE , 0 },
7055 };
7056 
7057 static const AVCodecTag codec_ipod_tags[] = {
7058  { AV_CODEC_ID_H264, MKTAG('a','v','c','1') },
7059  { AV_CODEC_ID_MPEG4, MKTAG('m','p','4','v') },
7060  { AV_CODEC_ID_AAC, MKTAG('m','p','4','a') },
7061  { AV_CODEC_ID_ALAC, MKTAG('a','l','a','c') },
7062  { AV_CODEC_ID_AC3, MKTAG('a','c','-','3') },
7063  { AV_CODEC_ID_MOV_TEXT, MKTAG('t','x','3','g') },
7064  { AV_CODEC_ID_MOV_TEXT, MKTAG('t','e','x','t') },
7065  { AV_CODEC_ID_NONE, 0 },
7066 };
7067 
7068 static const AVCodecTag codec_f4v_tags[] = {
7069  { AV_CODEC_ID_MP3, MKTAG('.','m','p','3') },
7070  { AV_CODEC_ID_AAC, MKTAG('m','p','4','a') },
7071  { AV_CODEC_ID_H264, MKTAG('a','v','c','1') },
7072  { AV_CODEC_ID_VP6A, MKTAG('V','P','6','A') },
7073  { AV_CODEC_ID_VP6F, MKTAG('V','P','6','F') },
7074  { AV_CODEC_ID_NONE, 0 },
7075 };
7076 
7077 #if CONFIG_MOV_MUXER
7078 MOV_CLASS(mov)
7080  .name = "mov",
7081  .long_name = NULL_IF_CONFIG_SMALL("QuickTime / MOV"),
7082  .extensions = "mov",
7083  .priv_data_size = sizeof(MOVMuxContext),
7084  .audio_codec = AV_CODEC_ID_AAC,
7085  .video_codec = CONFIG_LIBX264_ENCODER ?
7087  .init = mov_init,
7091  .deinit = mov_free,
7093  .codec_tag = (const AVCodecTag* const []){
7095  },
7096  .check_bitstream = mov_check_bitstream,
7097  .priv_class = &mov_muxer_class,
7098 };
7099 #endif
7100 #if CONFIG_TGP_MUXER
7101 MOV_CLASS(tgp)
7103  .name = "3gp",
7104  .long_name = NULL_IF_CONFIG_SMALL("3GP (3GPP file format)"),
7105  .extensions = "3gp",
7106  .priv_data_size = sizeof(MOVMuxContext),
7107  .audio_codec = AV_CODEC_ID_AMR_NB,
7108  .video_codec = AV_CODEC_ID_H263,
7109  .init = mov_init,
7113  .deinit = mov_free,
7115  .codec_tag = (const AVCodecTag* const []){ codec_3gp_tags, 0 },
7116  .check_bitstream = mov_check_bitstream,
7117  .priv_class = &tgp_muxer_class,
7118 };
7119 #endif
7120 #if CONFIG_MP4_MUXER
7121 MOV_CLASS(mp4)
7123  .name = "mp4",
7124  .long_name = NULL_IF_CONFIG_SMALL("MP4 (MPEG-4 Part 14)"),
7125  .mime_type = "video/mp4",
7126  .extensions = "mp4",
7127  .priv_data_size = sizeof(MOVMuxContext),
7128  .audio_codec = AV_CODEC_ID_AAC,
7129  .video_codec = CONFIG_LIBX264_ENCODER ?
7131  .init = mov_init,
7135  .deinit = mov_free,
7137  .codec_tag = (const AVCodecTag* const []){ codec_mp4_tags, 0 },
7138  .check_bitstream = mov_check_bitstream,
7139  .priv_class = &mp4_muxer_class,
7140 };
7141 #endif
7142 #if CONFIG_PSP_MUXER
7143 MOV_CLASS(psp)
7145  .name = "psp",
7146  .long_name = NULL_IF_CONFIG_SMALL("PSP MP4 (MPEG-4 Part 14)"),
7147  .extensions = "mp4,psp",
7148  .priv_data_size = sizeof(MOVMuxContext),
7149  .audio_codec = AV_CODEC_ID_AAC,
7150  .video_codec = CONFIG_LIBX264_ENCODER ?
7152  .init = mov_init,
7156  .deinit = mov_free,
7158  .codec_tag = (const AVCodecTag* const []){ codec_mp4_tags, 0 },
7159  .check_bitstream = mov_check_bitstream,
7160  .priv_class = &psp_muxer_class,
7161 };
7162 #endif
7163 #if CONFIG_TG2_MUXER
7164 MOV_CLASS(tg2)
7166  .name = "3g2",
7167  .long_name = NULL_IF_CONFIG_SMALL("3GP2 (3GPP2 file format)"),
7168  .extensions = "3g2",
7169  .priv_data_size = sizeof(MOVMuxContext),
7170  .audio_codec = AV_CODEC_ID_AMR_NB,
7171  .video_codec = AV_CODEC_ID_H263,
7172  .init = mov_init,
7176  .deinit = mov_free,
7178  .codec_tag = (const AVCodecTag* const []){ codec_3gp_tags, 0 },
7179  .check_bitstream = mov_check_bitstream,
7180  .priv_class = &tg2_muxer_class,
7181 };
7182 #endif
7183 #if CONFIG_IPOD_MUXER
7184 MOV_CLASS(ipod)
7186  .name = "ipod",
7187  .long_name = NULL_IF_CONFIG_SMALL("iPod H.264 MP4 (MPEG-4 Part 14)"),
7188  .mime_type = "video/mp4",
7189  .extensions = "m4v,m4a,m4b",
7190  .priv_data_size = sizeof(MOVMuxContext),
7191  .audio_codec = AV_CODEC_ID_AAC,
7192  .video_codec = AV_CODEC_ID_H264,
7193  .init = mov_init,
7197  .deinit = mov_free,
7199  .codec_tag = (const AVCodecTag* const []){ codec_ipod_tags, 0 },
7200  .check_bitstream = mov_check_bitstream,
7201  .priv_class = &ipod_muxer_class,
7202 };
7203 #endif
7204 #if CONFIG_ISMV_MUXER
7205 MOV_CLASS(ismv)
7207  .name = "ismv",
7208  .long_name = NULL_IF_CONFIG_SMALL("ISMV/ISMA (Smooth Streaming)"),
7209  .mime_type = "video/mp4",
7210  .extensions = "ismv,isma",
7211  .priv_data_size = sizeof(MOVMuxContext),
7212  .audio_codec = AV_CODEC_ID_AAC,
7213  .video_codec = AV_CODEC_ID_H264,
7214  .init = mov_init,
7218  .deinit = mov_free,
7220  .codec_tag = (const AVCodecTag* const []){
7222  .check_bitstream = mov_check_bitstream,
7223  .priv_class = &ismv_muxer_class,
7224 };
7225 #endif
7226 #if CONFIG_F4V_MUXER
7227 MOV_CLASS(f4v)
7229  .name = "f4v",
7230  .long_name = NULL_IF_CONFIG_SMALL("F4V Adobe Flash Video"),
7231  .mime_type = "application/f4v",
7232  .extensions = "f4v",
7233  .priv_data_size = sizeof(MOVMuxContext),
7234  .audio_codec = AV_CODEC_ID_AAC,
7235  .video_codec = AV_CODEC_ID_H264,
7236  .init = mov_init,
7240  .deinit = mov_free,
7242  .codec_tag = (const AVCodecTag* const []){ codec_f4v_tags, 0 },
7243  .check_bitstream = mov_check_bitstream,
7244  .priv_class = &f4v_muxer_class,
7245 };
7246 #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:7052
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:4539
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:3181
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:210
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:4039
ff_ntp_time
uint64_t ff_ntp_time(void)
Get the current time since NTP epoch in microseconds.
Definition: utils.c:4712
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:2687
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
r
const char * r
Definition: vf_curves.c:114
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:4805
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:3861
hevc.h
mov_write_clap_tag
static int mov_write_clap_tag(AVIOContext *pb, MOVTrack *track)
Definition: movenc.c:1852
libm.h
mov_add_tfra_entries
static int mov_add_tfra_entries(AVIOContext *pb, MOVMuxContext *mov, int tracks, int size)
Definition: movenc.c:4473
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:3813
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:5749
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:4347
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:3349
get_sample_flags
static uint32_t get_sample_flags(MOVTrack *track, MOVIentry *entry)
Definition: movenc.c:4275
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:3216
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:1880
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:5380
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:4717
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:92
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:1877
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:3296
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:2918
internal.h
AVPacket::data
uint8_t * data
Definition: packet.h:355
mov_init
static int mov_init(AVFormatContext *s)
Definition: movenc.c:6260
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:6113
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:3688
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:3775
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_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:5707
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)
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:3410
mov_write_header
static int mov_write_header(AVFormatContext *s)
Definition: movenc.c:6597
mov_write_sv3d_tag
static int mov_write_sv3d_tag(AVFormatContext *s, AVIOContext *pb, AVSphericalMapping *spherical_mapping)
Definition: movenc.c:1764
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:3515
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:6750
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
MOVTrack::vos_data
uint8_t * vos_data
Definition: movenc.h:112
fiel_data
static const uint16_t fiel_data[]
Definition: movenc.c:1700
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:2218
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:2696
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:1638
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:3795
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:4527
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:3325
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:2313
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:3485
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:3338
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:2438
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:2845
mov_write_video_tag
static int mov_write_video_tag(AVFormatContext *s, AVIOContext *pb, MOVMuxContext *mov, MOVTrack *track)
Definition: movenc.c:2032
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:4880
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:1645
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:4005
AV_ROUND_UP
@ AV_ROUND_UP
Round toward +infinity.
Definition: mathematics.h:83
AV_PKT_DATA_DISPLAYMATRIX
@ AV_PKT_DATA_DISPLAYMATRIX
This side data contains a 3x3 transformation matrix describing an affine transformation that needs to...
Definition: packet.h:108
MOV_SYNC_SAMPLE
#define MOV_SYNC_SAMPLE
Definition: movenc.h:55
FF_MOV_FLAG_USE_MDTA
#define FF_MOV_FLAG_USE_MDTA
Definition: movenc.h: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:4899
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
dnxhddata.h
mov_prune_frag_info
static void mov_prune_frag_info(MOVMuxContext *mov, int tracks, int max)
Definition: movenc.c:4513
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:3497
mov_write_trak_tag
static int mov_write_trak_tag(AVFormatContext *s, AVIOContext *pb, MOVMuxContext *mov, MOVTrack *track, AVStream *st)
Definition: movenc.c:3243
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:6874
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:3835
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_realloc_array
void * av_realloc_array(void *ptr, size_t nmemb, size_t size)
Definition: mem.c:198
AV_PKT_DATA_MASTERING_DISPLAY_METADATA
@ AV_PKT_DATA_MASTERING_DISPLAY_METADATA
Mastering display metadata (based on SMPTE-2086:2014).
Definition: packet.h:222
AVFormatContext::flags
int flags
Flags modifying the (de)muxer behaviour.
Definition: avformat.h: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:6055
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:5394
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:4781
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:3566
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
AV_RL16
uint64_t_TMPL AV_WL64 unsigned int_TMPL AV_WL32 unsigned int_TMPL AV_WL24 unsigned int_TMPL AV_RL16
Definition: bytestream.h:90
MOVMuxContext::frag_interleave
int frag_interleave
Definition: movenc.h:221
nb_streams
static int nb_streams
Definition: ffprobe.c:282
av_rescale_q
int64_t av_rescale_q(int64_t a, AVRational bq, AVRational cq)
Rescale a 64-bit integer by 2 rational numbers.
Definition: mathematics.c:142
MOVTrack::max_packet_size
uint32_t max_packet_size
Definition: movenc.h:130
MOVTrack::sample_size
long sample_size
Definition: movenc.h:92
codec_id
enum AVCodecID codec_id
Definition: vaapi_decode.c:369
AV_PIX_FMT_YUV420P
@ AV_PIX_FMT_YUV420P
planar YUV 4:2:0, 12bpp, (1 Cr & Cb sample per 2x2 Y samples)
Definition: pixfmt.h:66
AV_CODEC_ID_SVQ3
@ AV_CODEC_ID_SVQ3
Definition: codec_id.h:72
key
const char * key
Definition: hwcontext_opencl.c:168
AVMEDIA_TYPE_DATA
@ AVMEDIA_TYPE_DATA
Opaque data information usually continuous.
Definition: avutil.h:203
MOVIentry::pos
uint64_t pos
Definition: movenc.h:47
mov_parse_mpeg2_frame
static int mov_parse_mpeg2_frame(AVPacket *pkt, uint32_t *flags)
Definition: movenc.c:5046
mov_write_tcmi_tag
static int mov_write_tcmi_tag(AVIOContext *pb, MOVTrack *track)
Definition: movenc.c:2603
build_chunks
static void build_chunks(MOVTrack *trk)
Definition: movenc.c:3970
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:3066
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:1903
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:2702
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:477
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:4266
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:3919
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:6768
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:7068
mov_create_timecode_track
static int mov_create_timecode_track(AVFormatContext *s, int index, int src_index, AVTimecode tc)
Definition: movenc.c:6064
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:5855
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:6737
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:5579
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:4579
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:1867
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:3202
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:2595
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:2793
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:4115
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:2352
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:3426
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:4134
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:5834
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:2548
compute_sidx_size
static int compute_sidx_size(AVFormatContext *s)
Definition: movenc.c:6793
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:2004
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:1970
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:1574
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:188
codec_ipod_tags
static const AVCodecTag codec_ipod_tags[]
Definition: movenc.c:7057
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:5508
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:4948
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:3703
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:3163
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:7016
AV_RB32
uint64_t_TMPL AV_WL64 unsigned int_TMPL AV_WL32 unsigned int_TMPL AV_WL24 unsigned int_TMPL AV_WL16 uint64_t_TMPL AV_WB64 unsigned int_TMPL AV_RB32
Definition: bytestream.h:92
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:3460
codec_3gp_tags
static const AVCodecTag codec_3gp_tags[]
Definition: movenc.c:7005
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:2904
mov_create_dvd_sub_decoder_specific_info
static int mov_create_dvd_sub_decoder_specific_info(MOVTrack *track, AVStream *st)
Definition: movenc.c:6210
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:2625
mov_write_stsd_tag
static int mov_write_stsd_tag(AVFormatContext *s, AVIOContext *pb, MOVMuxContext *mov, MOVTrack *track)
Definition: movenc.c:2325
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:2257
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:2828
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:3731
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:3753
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:6808
mov_write_dvc1_structs
static int mov_write_dvc1_structs(MOVTrack *track, uint8_t *buf)
Definition: movenc.c:875
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:6155
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:702
ff_f4v_muxer
AVOutputFormat ff_f4v_muxer
mov_write_covr
static int mov_write_covr(AVIOContext *pb, AVFormatContext *s)
Definition: movenc.c:3620
flag
#define flag(name)
Definition: cbs_av1.c:557
avcodec_get_name
const char * avcodec_get_name(enum AVCodecID id)
Get the name of a codec.
Definition: utils.c:1206
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:2139
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:4946
mov_write_dinf_tag
static int mov_write_dinf_tag(AVIOContext *pb)
Definition: movenc.c:2586
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:5432
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:3446
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:668
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:5127
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
av_mallocz
void * av_mallocz(size_t size)
Allocate a memory block with alignment suitable for all memory accesses (including vectors if availab...
Definition: mem.c:237
MOVMuxContext::max_fragment_duration
int max_fragment_duration
Definition: movenc.h:201
MOVTrack::rtp_ctx
AVFormatContext * rtp_ctx
the format context for the hinting rtp muxer
Definition: movenc.h:127
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:3034
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:1717
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:4281
mov_write_stts_tag
static int mov_write_stts_tag(AVIOContext *pb, MOVTrack *track)
Definition: movenc.c:2393
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:4749
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:5733
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:3593
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:2088
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:3152
mov_write_uuid_tag_ipod
static int mov_write_uuid_tag_ipod(AVIOContext *pb)
Write uuid atom.
Definition: movenc.c:1688
pos
unsigned int pos
Definition: spdifenc.c:412
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
AV_RL32
uint64_t_TMPL AV_WL64 unsigned int_TMPL AV_RL32
Definition: bytestream.h:88
MODE_3G2
#define MODE_3G2
Definition: movenc.h:41
mov_flush_fragment
static int mov_flush_fragment(AVFormatContext *s, int force)
Definition: movenc.c:5171
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:221
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
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:6194
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:1970
mov_create_chapter_track
static int mov_create_chapter_track(AVFormatContext *s, int tracknum)
Definition: movenc.c:5957
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:4842
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:4699
mov_write_fiel_tag
static int mov_write_fiel_tag(AVIOContext *pb, MOVTrack *track, int field_order)
Definition: movenc.c:1704
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:3155
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:5017
mov_write_sidx_tags
static int mov_write_sidx_tags(AVIOContext *pb, MOVMuxContext *mov, int tracks, int ref_size)
Definition: movenc.c:4664
eac3_info::bsid
uint8_t bsid
Definition: movenc.c:381
MOVMuxContext::tracks
MOVTrack * tracks
Definition: movenc.h:190
AV_RB8
uint64_t_TMPL AV_WL64 unsigned int_TMPL AV_WL32 unsigned int_TMPL AV_WL24 unsigned int_TMPL AV_WL16 uint64_t_TMPL AV_WB64 unsigned int_TMPL AV_WB32 unsigned int_TMPL AV_WB24 unsigned int_TMPL AV_WB16 unsigned int_TMPL AV_RB8
Definition: bytestream.h:95
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:3648
mov_flush_fragment_interleaving
static int mov_flush_fragment_interleaving(AVFormatContext *s, MOVTrack *track)
Definition: movenc.c:5146
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:2885
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:6990
ff_format_io_close
void ff_format_io_close(AVFormatContext *s, AVIOContext **pb)
Definition: utils.c:5695
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:4125
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:3932
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:1822
mov_preroll_write_stbl_atoms
static int mov_preroll_write_stbl_atoms(AVIOContext *pb, MOVTrack *track)
Definition: movenc.c:2453
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:1734
MOVTrack::cluster_capacity
unsigned cluster_capacity
Definition: movenc.h:114
language_code
static uint16_t language_code(const char *str)
Definition: movenc.c:3806
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:2677
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:2238
mov_parse_vc1_frame
static void mov_parse_vc1_frame(AVPacket *pkt, MOVTrack *trk)
Definition: movenc.c:5067
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:565
mov_write_hmhd_tag
static int mov_write_hmhd_tag(AVIOContext *pb)
Definition: movenc.c:2778
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:4120
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:1975
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:4831
av1.h
mov_write_tfrf_tag
static int mov_write_tfrf_tag(AVIOContext *pb, MOVMuxContext *mov, MOVTrack *track, int entry)
Definition: movenc.c:4424
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
AV_RB24
uint64_t_TMPL AV_WL64 unsigned int_TMPL AV_WL32 unsigned int_TMPL AV_WL24 unsigned int_TMPL AV_WL16 uint64_t_TMPL AV_WB64 unsigned int_TMPL AV_WB32 unsigned int_TMPL AV_RB24
Definition: bytestream.h:93
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:4459
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:1665
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:4403
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:1951
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
AV_RB16
uint64_t_TMPL AV_WL64 unsigned int_TMPL AV_WL32 unsigned int_TMPL AV_WL24 unsigned int_TMPL AV_WL16 uint64_t_TMPL AV_WB64 unsigned int_TMPL AV_WB32 unsigned int_TMPL AV_WB24 unsigned int_TMPL AV_RB16
Definition: bytestream.h:94
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:3328
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:4602
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