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