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"
47 #include "libavutil/intfloat.h"
48 #include "libavutil/mathematics.h"
49 #include "libavutil/libm.h"
50 #include "libavutil/opt.h"
51 #include "libavutil/dict.h"
52 #include "libavutil/pixdesc.h"
53 #include "libavutil/stereo3d.h"
54 #include "libavutil/timecode.h"
55 #include "libavutil/dovi_meta.h"
56 #include "libavutil/color_utils.h"
57 #include "hevc.h"
58 #include "rtpenc.h"
59 #include "mov_chan.h"
60 #include "movenc_ttml.h"
61 #include "ttmlenc.h"
62 #include "vpcc.h"
63 
64 static const AVOption options[] = {
65  { "movflags", "MOV muxer flags", offsetof(MOVMuxContext, flags), AV_OPT_TYPE_FLAGS, {.i64 = 0}, INT_MIN, INT_MAX, AV_OPT_FLAG_ENCODING_PARAM, "movflags" },
66  { "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" },
67  { "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 },
68  { "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" },
69  { "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" },
70  { "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" },
71  { "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" },
72  { "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" },
73  { "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" },
74  { "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" },
75  { "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" },
76  { "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" },
77  { "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" },
78  { "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" },
79  { "cmaf", "Write CMAF compatible fragmented MP4", 0, AV_OPT_TYPE_CONST, {.i64 = FF_MOV_FLAG_CMAF}, INT_MIN, INT_MAX, AV_OPT_FLAG_ENCODING_PARAM, "movflags" },
80  { "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" },
81  { "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" },
82  { "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" },
83  { "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" },
84  { "write_colr", "Write colr atom even if the color info is unspecified (Experimental, may be renamed or changed, do not use from scripts)", 0, AV_OPT_TYPE_CONST, {.i64 = FF_MOV_FLAG_WRITE_COLR}, INT_MIN, INT_MAX, AV_OPT_FLAG_ENCODING_PARAM, "movflags" },
85  { "prefer_icc", "If writing colr atom prioritise usage of ICC profile if it exists in stream packet side data", 0, AV_OPT_TYPE_CONST, {.i64 = FF_MOV_FLAG_PREFER_ICC}, INT_MIN, INT_MAX, AV_OPT_FLAG_ENCODING_PARAM, "movflags" },
86  { "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" },
87  { "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" },
88  { "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" },
89  { "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" },
90  FF_RTP_FLAG_OPTS(MOVMuxContext, rtp_flags),
91  { "skip_iods", "Skip writing iods atom.", offsetof(MOVMuxContext, iods_skip), AV_OPT_TYPE_BOOL, {.i64 = 1}, 0, 1, AV_OPT_FLAG_ENCODING_PARAM},
92  { "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},
93  { "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},
94  { "frag_duration", "Maximum fragment duration", offsetof(MOVMuxContext, max_fragment_duration), AV_OPT_TYPE_INT, {.i64 = 0}, 0, INT_MAX, AV_OPT_FLAG_ENCODING_PARAM},
95  { "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},
96  { "frag_size", "Maximum fragment size", offsetof(MOVMuxContext, max_fragment_size), AV_OPT_TYPE_INT, {.i64 = 0}, 0, INT_MAX, AV_OPT_FLAG_ENCODING_PARAM},
97  { "ism_lookahead", "Number of lookahead entries for ISM files", offsetof(MOVMuxContext, ism_lookahead), AV_OPT_TYPE_INT, {.i64 = 0}, 0, 255, AV_OPT_FLAG_ENCODING_PARAM},
98  { "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},
99  { "brand", "Override major brand", offsetof(MOVMuxContext, major_brand), AV_OPT_TYPE_STRING, {.str = NULL}, .flags = AV_OPT_FLAG_ENCODING_PARAM },
100  { "use_editlist", "use edit list", offsetof(MOVMuxContext, use_editlist), AV_OPT_TYPE_BOOL, {.i64 = -1}, -1, 1, AV_OPT_FLAG_ENCODING_PARAM},
101  { "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},
102  { "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},
103  { "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 },
104  { "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 },
105  { "encryption_key", "The media encryption key (hex)", offsetof(MOVMuxContext, encryption_key), AV_OPT_TYPE_BINARY, .flags = AV_OPT_FLAG_ENCODING_PARAM },
106  { "encryption_kid", "The media encryption key identifier (hex)", offsetof(MOVMuxContext, encryption_kid), AV_OPT_TYPE_BINARY, .flags = AV_OPT_FLAG_ENCODING_PARAM },
107  { "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},
108  { "write_tmcd", "force or disable writing tmcd", offsetof(MOVMuxContext, write_tmcd), AV_OPT_TYPE_BOOL, {.i64 = -1}, -1, 1, AV_OPT_FLAG_ENCODING_PARAM},
109  { "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"},
110  { "wallclock", NULL, 0, AV_OPT_TYPE_CONST, {.i64 = MOV_PRFT_SRC_WALLCLOCK}, 0, 0, AV_OPT_FLAG_ENCODING_PARAM, "prft"},
111  { "pts", NULL, 0, AV_OPT_TYPE_CONST, {.i64 = MOV_PRFT_SRC_PTS}, 0, 0, AV_OPT_FLAG_ENCODING_PARAM, "prft"},
112  { "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},
113  { "movie_timescale", "set movie timescale", offsetof(MOVMuxContext, movie_timescale), AV_OPT_TYPE_INT, {.i64 = MOV_TIMESCALE}, 1, INT_MAX, AV_OPT_FLAG_ENCODING_PARAM},
114  { NULL },
115 };
116 
118  .class_name = "mov/mp4/tgp/psp/tg2/ipod/ismv/f4v muxer",
119  .item_name = av_default_item_name,
120  .option = options,
121  .version = LIBAVUTIL_VERSION_INT,
122 };
123 
124 static int get_moov_size(AVFormatContext *s);
126 
127 static int utf8len(const uint8_t *b)
128 {
129  int len = 0;
130  int val;
131  while (*b) {
132  GET_UTF8(val, *b++, return -1;)
133  len++;
134  }
135  return len;
136 }
137 
138 //FIXME support 64 bit variant with wide placeholders
139 static int64_t update_size(AVIOContext *pb, int64_t pos)
140 {
141  int64_t curpos = avio_tell(pb);
142  avio_seek(pb, pos, SEEK_SET);
143  avio_wb32(pb, curpos - pos); /* rewrite size */
144  avio_seek(pb, curpos, SEEK_SET);
145 
146  return curpos - pos;
147 }
148 
149 static int co64_required(const MOVTrack *track)
150 {
151  if (track->entry > 0 && track->cluster[track->entry - 1].pos + track->data_offset > UINT32_MAX)
152  return 1;
153  return 0;
154 }
155 
156 static int is_cover_image(const AVStream *st)
157 {
158  /* Eg. AV_DISPOSITION_ATTACHED_PIC | AV_DISPOSITION_TIMED_THUMBNAILS
159  * is encoded as sparse video track */
160  return st && st->disposition == AV_DISPOSITION_ATTACHED_PIC;
161 }
162 
163 static int rtp_hinting_needed(const AVStream *st)
164 {
165  /* Add hint tracks for each real audio and video stream */
166  if (is_cover_image(st))
167  return 0;
168  return st->codecpar->codec_type == AVMEDIA_TYPE_VIDEO ||
170 }
171 
172 /* Chunk offset atom */
173 static int mov_write_stco_tag(AVIOContext *pb, MOVTrack *track)
174 {
175  int i;
176  int mode64 = co64_required(track); // use 32 bit size variant if possible
177  int64_t pos = avio_tell(pb);
178  avio_wb32(pb, 0); /* size */
179  if (mode64)
180  ffio_wfourcc(pb, "co64");
181  else
182  ffio_wfourcc(pb, "stco");
183  avio_wb32(pb, 0); /* version & flags */
184  avio_wb32(pb, track->chunkCount); /* entry count */
185  for (i = 0; i < track->entry; i++) {
186  if (!track->cluster[i].chunkNum)
187  continue;
188  if (mode64 == 1)
189  avio_wb64(pb, track->cluster[i].pos + track->data_offset);
190  else
191  avio_wb32(pb, track->cluster[i].pos + track->data_offset);
192  }
193  return update_size(pb, pos);
194 }
195 
196 /* Sample size atom */
197 static int mov_write_stsz_tag(AVIOContext *pb, MOVTrack *track)
198 {
199  int equalChunks = 1;
200  int i, j, entries = 0, tst = -1, oldtst = -1;
201 
202  int64_t pos = avio_tell(pb);
203  avio_wb32(pb, 0); /* size */
204  ffio_wfourcc(pb, "stsz");
205  avio_wb32(pb, 0); /* version & flags */
206 
207  for (i = 0; i < track->entry; i++) {
208  tst = track->cluster[i].size / track->cluster[i].entries;
209  if (oldtst != -1 && tst != oldtst)
210  equalChunks = 0;
211  oldtst = tst;
212  entries += track->cluster[i].entries;
213  }
214  if (equalChunks && track->entry) {
215  int sSize = track->entry ? track->cluster[0].size / track->cluster[0].entries : 0;
216  sSize = FFMAX(1, sSize); // adpcm mono case could make sSize == 0
217  avio_wb32(pb, sSize); // sample size
218  avio_wb32(pb, entries); // sample count
219  } else {
220  avio_wb32(pb, 0); // sample size
221  avio_wb32(pb, entries); // sample count
222  for (i = 0; i < track->entry; i++) {
223  for (j = 0; j < track->cluster[i].entries; j++) {
224  avio_wb32(pb, track->cluster[i].size /
225  track->cluster[i].entries);
226  }
227  }
228  }
229  return update_size(pb, pos);
230 }
231 
232 /* Sample to chunk atom */
233 static int mov_write_stsc_tag(AVIOContext *pb, MOVTrack *track)
234 {
235  int index = 0, oldval = -1, i;
236  int64_t entryPos, curpos;
237 
238  int64_t pos = avio_tell(pb);
239  avio_wb32(pb, 0); /* size */
240  ffio_wfourcc(pb, "stsc");
241  avio_wb32(pb, 0); // version & flags
242  entryPos = avio_tell(pb);
243  avio_wb32(pb, track->chunkCount); // entry count
244  for (i = 0; i < track->entry; i++) {
245  if (oldval != track->cluster[i].samples_in_chunk && track->cluster[i].chunkNum) {
246  avio_wb32(pb, track->cluster[i].chunkNum); // first chunk
247  avio_wb32(pb, track->cluster[i].samples_in_chunk); // samples per chunk
248  avio_wb32(pb, 0x1); // sample description index
249  oldval = track->cluster[i].samples_in_chunk;
250  index++;
251  }
252  }
253  curpos = avio_tell(pb);
254  avio_seek(pb, entryPos, SEEK_SET);
255  avio_wb32(pb, index); // rewrite size
256  avio_seek(pb, curpos, SEEK_SET);
257 
258  return update_size(pb, pos);
259 }
260 
261 /* Sync sample atom */
262 static int mov_write_stss_tag(AVIOContext *pb, MOVTrack *track, uint32_t flag)
263 {
264  int64_t curpos, entryPos;
265  int i, index = 0;
266  int64_t pos = avio_tell(pb);
267  avio_wb32(pb, 0); // size
268  ffio_wfourcc(pb, flag == MOV_SYNC_SAMPLE ? "stss" : "stps");
269  avio_wb32(pb, 0); // version & flags
270  entryPos = avio_tell(pb);
271  avio_wb32(pb, track->entry); // entry count
272  for (i = 0; i < track->entry; i++) {
273  if (track->cluster[i].flags & flag) {
274  avio_wb32(pb, i + 1);
275  index++;
276  }
277  }
278  curpos = avio_tell(pb);
279  avio_seek(pb, entryPos, SEEK_SET);
280  avio_wb32(pb, index); // rewrite size
281  avio_seek(pb, curpos, SEEK_SET);
282  return update_size(pb, pos);
283 }
284 
285 /* Sample dependency atom */
286 static int mov_write_sdtp_tag(AVIOContext *pb, MOVTrack *track)
287 {
288  int i;
289  uint8_t leading, dependent, reference, redundancy;
290  int64_t pos = avio_tell(pb);
291  avio_wb32(pb, 0); // size
292  ffio_wfourcc(pb, "sdtp");
293  avio_wb32(pb, 0); // version & flags
294  for (i = 0; i < track->entry; i++) {
295  dependent = MOV_SAMPLE_DEPENDENCY_YES;
296  leading = reference = redundancy = MOV_SAMPLE_DEPENDENCY_UNKNOWN;
297  if (track->cluster[i].flags & MOV_DISPOSABLE_SAMPLE) {
298  reference = MOV_SAMPLE_DEPENDENCY_NO;
299  }
300  if (track->cluster[i].flags & MOV_SYNC_SAMPLE) {
301  dependent = MOV_SAMPLE_DEPENDENCY_NO;
302  }
303  avio_w8(pb, (leading << 6) | (dependent << 4) |
304  (reference << 2) | redundancy);
305  }
306  return update_size(pb, pos);
307 }
308 
309 static int mov_write_amr_tag(AVIOContext *pb, MOVTrack *track)
310 {
311  avio_wb32(pb, 0x11); /* size */
312  if (track->mode == MODE_MOV) ffio_wfourcc(pb, "samr");
313  else ffio_wfourcc(pb, "damr");
314  ffio_wfourcc(pb, "FFMP");
315  avio_w8(pb, 0); /* decoder version */
316 
317  avio_wb16(pb, 0x81FF); /* Mode set (all modes for AMR_NB) */
318  avio_w8(pb, 0x00); /* Mode change period (no restriction) */
319  avio_w8(pb, 0x01); /* Frames per sample */
320  return 0x11;
321 }
322 
324 {
325  GetBitContext gbc;
326  PutBitContext pbc;
327  uint8_t buf[3];
328  int fscod, bsid, bsmod, acmod, lfeon, frmsizecod;
329 
330  if (track->vos_len < 7) {
332  "Cannot write moov atom before AC3 packets."
333  " Set the delay_moov flag to fix this.\n");
334  return AVERROR(EINVAL);
335  }
336 
337  avio_wb32(pb, 11);
338  ffio_wfourcc(pb, "dac3");
339 
340  init_get_bits(&gbc, track->vos_data + 4, (track->vos_len - 4) * 8);
341  fscod = get_bits(&gbc, 2);
342  frmsizecod = get_bits(&gbc, 6);
343  bsid = get_bits(&gbc, 5);
344  bsmod = get_bits(&gbc, 3);
345  acmod = get_bits(&gbc, 3);
346  if (acmod == 2) {
347  skip_bits(&gbc, 2); // dsurmod
348  } else {
349  if ((acmod & 1) && acmod != 1)
350  skip_bits(&gbc, 2); // cmixlev
351  if (acmod & 4)
352  skip_bits(&gbc, 2); // surmixlev
353  }
354  lfeon = get_bits1(&gbc);
355 
356  init_put_bits(&pbc, buf, sizeof(buf));
357  put_bits(&pbc, 2, fscod);
358  put_bits(&pbc, 5, bsid);
359  put_bits(&pbc, 3, bsmod);
360  put_bits(&pbc, 3, acmod);
361  put_bits(&pbc, 1, lfeon);
362  put_bits(&pbc, 5, frmsizecod >> 1); // bit_rate_code
363  put_bits(&pbc, 5, 0); // reserved
364 
365  flush_put_bits(&pbc);
366  avio_write(pb, buf, sizeof(buf));
367 
368  return 11;
369 }
370 
371 struct eac3_info {
373  uint8_t ec3_done;
374  uint8_t num_blocks;
375 
376  /* Layout of the EC3SpecificBox */
377  /* maximum bitrate */
378  uint16_t data_rate;
379  /* number of independent substreams */
380  uint8_t num_ind_sub;
381  struct {
382  /* sample rate code (see ff_ac3_sample_rate_tab) 2 bits */
383  uint8_t fscod;
384  /* bit stream identification 5 bits */
385  uint8_t bsid;
386  /* one bit reserved */
387  /* audio service mixing (not supported yet) 1 bit */
388  /* bit stream mode 3 bits */
389  uint8_t bsmod;
390  /* audio coding mode 3 bits */
391  uint8_t acmod;
392  /* sub woofer on 1 bit */
393  uint8_t lfeon;
394  /* 3 bits reserved */
395  /* number of dependent substreams associated with this substream 4 bits */
396  uint8_t num_dep_sub;
397  /* channel locations of the dependent substream(s), if any, 9 bits */
398  uint16_t chan_loc;
399  /* if there is no dependent substream, then one bit reserved instead */
400  } substream[1]; /* TODO: support 8 independent substreams */
401 };
402 
403 #if CONFIG_AC3_PARSER
404 static int handle_eac3(MOVMuxContext *mov, AVPacket *pkt, MOVTrack *track)
405 {
406  AC3HeaderInfo *hdr = NULL;
407  struct eac3_info *info;
408  int num_blocks, ret;
409 
410  if (!track->eac3_priv && !(track->eac3_priv = av_mallocz(sizeof(*info))))
411  return AVERROR(ENOMEM);
412  info = track->eac3_priv;
413 
414  if (!info->pkt && !(info->pkt = av_packet_alloc()))
415  return AVERROR(ENOMEM);
416 
417  if (avpriv_ac3_parse_header(&hdr, pkt->data, pkt->size) < 0) {
418  /* drop the packets until we see a good one */
419  if (!track->entry) {
420  av_log(mov->fc, AV_LOG_WARNING, "Dropping invalid packet from start of the stream\n");
421  ret = 0;
422  } else
424  goto end;
425  }
426 
427  info->data_rate = FFMAX(info->data_rate, hdr->bit_rate / 1000);
428  num_blocks = hdr->num_blocks;
429 
430  if (!info->ec3_done) {
431  /* AC-3 substream must be the first one */
432  if (hdr->bitstream_id <= 10 && hdr->substreamid != 0) {
433  ret = AVERROR(EINVAL);
434  goto end;
435  }
436 
437  /* this should always be the case, given that our AC-3 parser
438  * concatenates dependent frames to their independent parent */
440  /* substream ids must be incremental */
441  if (hdr->substreamid > info->num_ind_sub + 1) {
442  ret = AVERROR(EINVAL);
443  goto end;
444  }
445 
446  if (hdr->substreamid == info->num_ind_sub + 1) {
447  //info->num_ind_sub++;
448  avpriv_request_sample(mov->fc, "Multiple independent substreams");
450  goto end;
451  } else if (hdr->substreamid < info->num_ind_sub ||
452  hdr->substreamid == 0 && info->substream[0].bsid) {
453  info->ec3_done = 1;
454  goto concatenate;
455  }
456  } else {
457  if (hdr->substreamid != 0) {
458  avpriv_request_sample(mov->fc, "Multiple non EAC3 independent substreams");
460  goto end;
461  }
462  }
463 
464  /* fill the info needed for the "dec3" atom */
465  info->substream[hdr->substreamid].fscod = hdr->sr_code;
466  info->substream[hdr->substreamid].bsid = hdr->bitstream_id;
467  info->substream[hdr->substreamid].bsmod = hdr->bitstream_mode;
468  info->substream[hdr->substreamid].acmod = hdr->channel_mode;
469  info->substream[hdr->substreamid].lfeon = hdr->lfe_on;
470 
471  /* Parse dependent substream(s), if any */
472  if (pkt->size != hdr->frame_size) {
473  int cumul_size = hdr->frame_size;
474  int parent = hdr->substreamid;
475 
476  while (cumul_size != pkt->size) {
477  GetBitContext gbc;
478  int i;
479  ret = avpriv_ac3_parse_header(&hdr, pkt->data + cumul_size, pkt->size - cumul_size);
480  if (ret < 0)
481  goto end;
483  ret = AVERROR(EINVAL);
484  goto end;
485  }
486  info->substream[parent].num_dep_sub++;
487  ret /= 8;
488 
489  /* header is parsed up to lfeon, but custom channel map may be needed */
490  init_get_bits8(&gbc, pkt->data + cumul_size + ret, pkt->size - cumul_size - ret);
491  /* skip bsid */
492  skip_bits(&gbc, 5);
493  /* skip volume control params */
494  for (i = 0; i < (hdr->channel_mode ? 1 : 2); i++) {
495  skip_bits(&gbc, 5); // skip dialog normalization
496  if (get_bits1(&gbc)) {
497  skip_bits(&gbc, 8); // skip compression gain word
498  }
499  }
500  /* get the dependent stream channel map, if exists */
501  if (get_bits1(&gbc))
502  info->substream[parent].chan_loc |= (get_bits(&gbc, 16) >> 5) & 0x1f;
503  else
504  info->substream[parent].chan_loc |= hdr->channel_mode;
505  cumul_size += hdr->frame_size;
506  }
507  }
508  }
509 
510 concatenate:
511  if (!info->num_blocks && num_blocks == 6) {
512  ret = pkt->size;
513  goto end;
514  }
515  else if (info->num_blocks + num_blocks > 6) {
517  goto end;
518  }
519 
520  if (!info->num_blocks) {
521  ret = av_packet_ref(info->pkt, pkt);
522  if (!ret)
523  info->num_blocks = num_blocks;
524  goto end;
525  } else {
526  if ((ret = av_grow_packet(info->pkt, pkt->size)) < 0)
527  goto end;
528  memcpy(info->pkt->data + info->pkt->size - pkt->size, pkt->data, pkt->size);
529  info->num_blocks += num_blocks;
530  info->pkt->duration += pkt->duration;
531  if (info->num_blocks != 6)
532  goto end;
534  av_packet_move_ref(pkt, info->pkt);
535  info->num_blocks = 0;
536  }
537  ret = pkt->size;
538 
539 end:
540  av_free(hdr);
541 
542  return ret;
543 }
544 #endif
545 
547 {
548  PutBitContext pbc;
549  uint8_t *buf;
550  struct eac3_info *info;
551  int size, i;
552 
553  if (!track->eac3_priv) {
555  "Cannot write moov atom before EAC3 packets parsed.\n");
556  return AVERROR(EINVAL);
557  }
558 
559  info = track->eac3_priv;
560  size = 2 + ((34 * (info->num_ind_sub + 1) + 7) >> 3);
561  buf = av_malloc(size);
562  if (!buf) {
563  return AVERROR(ENOMEM);
564  }
565 
566  init_put_bits(&pbc, buf, size);
567  put_bits(&pbc, 13, info->data_rate);
568  put_bits(&pbc, 3, info->num_ind_sub);
569  for (i = 0; i <= info->num_ind_sub; i++) {
570  put_bits(&pbc, 2, info->substream[i].fscod);
571  put_bits(&pbc, 5, info->substream[i].bsid);
572  put_bits(&pbc, 1, 0); /* reserved */
573  put_bits(&pbc, 1, 0); /* asvc */
574  put_bits(&pbc, 3, info->substream[i].bsmod);
575  put_bits(&pbc, 3, info->substream[i].acmod);
576  put_bits(&pbc, 1, info->substream[i].lfeon);
577  put_bits(&pbc, 5, 0); /* reserved */
578  put_bits(&pbc, 4, info->substream[i].num_dep_sub);
579  if (!info->substream[i].num_dep_sub) {
580  put_bits(&pbc, 1, 0); /* reserved */
581  } else {
582  put_bits(&pbc, 9, info->substream[i].chan_loc);
583  }
584  }
585  flush_put_bits(&pbc);
586  size = put_bytes_output(&pbc);
587 
588  avio_wb32(pb, size + 8);
589  ffio_wfourcc(pb, "dec3");
590  avio_write(pb, buf, size);
591 
592  av_free(buf);
593 
594  return size;
595 }
596 
597 /**
598  * This function writes extradata "as is".
599  * Extradata must be formatted like a valid atom (with size and tag).
600  */
602 {
603  avio_write(pb, track->par->extradata, track->par->extradata_size);
604  return track->par->extradata_size;
605 }
606 
608 {
609  avio_wb32(pb, 10);
610  ffio_wfourcc(pb, "enda");
611  avio_wb16(pb, 1); /* little endian */
612  return 10;
613 }
614 
616 {
617  avio_wb32(pb, 10);
618  ffio_wfourcc(pb, "enda");
619  avio_wb16(pb, 0); /* big endian */
620  return 10;
621 }
622 
623 static void put_descr(AVIOContext *pb, int tag, unsigned int size)
624 {
625  int i = 3;
626  avio_w8(pb, tag);
627  for (; i > 0; i--)
628  avio_w8(pb, (size >> (7 * i)) | 0x80);
629  avio_w8(pb, size & 0x7F);
630 }
631 
632 static unsigned compute_avg_bitrate(MOVTrack *track)
633 {
634  uint64_t size = 0;
635  int i;
636  if (!track->track_duration)
637  return 0;
638  for (i = 0; i < track->entry; i++)
639  size += track->cluster[i].size;
640  return size * 8 * track->timescale / track->track_duration;
641 }
642 
644  uint32_t buffer_size; ///< Size of the decoding buffer for the elementary stream in bytes.
645  uint32_t max_bit_rate; ///< Maximum rate in bits/second over any window of one second.
646  uint32_t avg_bit_rate; ///< Average rate in bits/second over the entire presentation.
647 };
648 
650 {
651  AVCPBProperties *props = track->st ?
654  NULL) :
655  NULL;
656  struct mpeg4_bit_rate_values bit_rates = { 0 };
657 
658  bit_rates.avg_bit_rate = compute_avg_bitrate(track);
659  if (!bit_rates.avg_bit_rate) {
660  // if the average bit rate cannot be calculated at this point, such as
661  // in the case of fragmented MP4, utilize the following values as
662  // fall-back in priority order:
663  //
664  // 1. average bit rate property
665  // 2. bit rate (usually average over the whole clip)
666  // 3. maximum bit rate property
667 
668  if (props && props->avg_bitrate) {
669  bit_rates.avg_bit_rate = props->avg_bitrate;
670  } else if (track->par->bit_rate) {
671  bit_rates.avg_bit_rate = track->par->bit_rate;
672  } else if (props && props->max_bitrate) {
673  bit_rates.avg_bit_rate = props->max_bitrate;
674  }
675  }
676 
677  // (FIXME should be max rate in any 1 sec window)
678  bit_rates.max_bit_rate = FFMAX(track->par->bit_rate,
679  bit_rates.avg_bit_rate);
680 
681  // utilize values from properties if we have them available
682  if (props) {
683  bit_rates.max_bit_rate = FFMAX(bit_rates.max_bit_rate,
684  props->max_bitrate);
685  bit_rates.buffer_size = props->buffer_size / 8;
686  }
687 
688  return bit_rates;
689 }
690 
691 static int mov_write_esds_tag(AVIOContext *pb, MOVTrack *track) // Basic
692 {
693  struct mpeg4_bit_rate_values bit_rates = calculate_mpeg4_bit_rates(track);
694  int64_t pos = avio_tell(pb);
695  int decoder_specific_info_len = track->vos_len ? 5 + track->vos_len : 0;
696 
697  avio_wb32(pb, 0); // size
698  ffio_wfourcc(pb, "esds");
699  avio_wb32(pb, 0); // Version
700 
701  // ES descriptor
702  put_descr(pb, 0x03, 3 + 5+13 + decoder_specific_info_len + 5+1);
703  avio_wb16(pb, track->track_id);
704  avio_w8(pb, 0x00); // flags (= no flags)
705 
706  // DecoderConfig descriptor
707  put_descr(pb, 0x04, 13 + decoder_specific_info_len);
708 
709  // Object type indication
710  if ((track->par->codec_id == AV_CODEC_ID_MP2 ||
711  track->par->codec_id == AV_CODEC_ID_MP3) &&
712  track->par->sample_rate > 24000)
713  avio_w8(pb, 0x6B); // 11172-3
714  else
716 
717  // the following fields is made of 6 bits to identify the streamtype (4 for video, 5 for audio)
718  // plus 1 bit to indicate upstream and 1 bit set to 1 (reserved)
719  if (track->par->codec_id == AV_CODEC_ID_DVD_SUBTITLE)
720  avio_w8(pb, (0x38 << 2) | 1); // flags (= NeroSubpicStream)
721  else if (track->par->codec_type == AVMEDIA_TYPE_AUDIO)
722  avio_w8(pb, 0x15); // flags (= Audiostream)
723  else
724  avio_w8(pb, 0x11); // flags (= Visualstream)
725 
726  avio_wb24(pb, bit_rates.buffer_size); // Buffersize DB
727  avio_wb32(pb, bit_rates.max_bit_rate); // maxbitrate
728  avio_wb32(pb, bit_rates.avg_bit_rate);
729 
730  if (track->vos_len) {
731  // DecoderSpecific info descriptor
732  put_descr(pb, 0x05, track->vos_len);
733  avio_write(pb, track->vos_data, track->vos_len);
734  }
735 
736  // SL descriptor
737  put_descr(pb, 0x06, 1);
738  avio_w8(pb, 0x02);
739  return update_size(pb, pos);
740 }
741 
743 {
744  return codec_id == AV_CODEC_ID_PCM_S24LE ||
748 }
749 
751 {
752  return codec_id == AV_CODEC_ID_PCM_S24BE ||
756 }
757 
759 {
760  int ret;
761  int64_t pos = avio_tell(pb);
762  avio_wb32(pb, 0);
763  avio_wl32(pb, track->tag); // store it byteswapped
764  track->par->codec_tag = av_bswap16(track->tag >> 16);
765  if ((ret = ff_put_wav_header(s, pb, track->par, 0)) < 0)
766  return ret;
767  return update_size(pb, pos);
768 }
769 
771 {
772  int ret;
773  int64_t pos = avio_tell(pb);
774  avio_wb32(pb, 0);
775  ffio_wfourcc(pb, "wfex");
777  return ret;
778  return update_size(pb, pos);
779 }
780 
781 static int mov_write_dfla_tag(AVIOContext *pb, MOVTrack *track)
782 {
783  int64_t pos = avio_tell(pb);
784  avio_wb32(pb, 0);
785  ffio_wfourcc(pb, "dfLa");
786  avio_w8(pb, 0); /* version */
787  avio_wb24(pb, 0); /* flags */
788 
789  /* Expect the encoder to pass a METADATA_BLOCK_TYPE_STREAMINFO. */
790  if (track->par->extradata_size != FLAC_STREAMINFO_SIZE)
791  return AVERROR_INVALIDDATA;
792 
793  /* TODO: Write other METADATA_BLOCK_TYPEs if the encoder makes them available. */
794  avio_w8(pb, 1 << 7 | FLAC_METADATA_TYPE_STREAMINFO); /* LastMetadataBlockFlag << 7 | BlockType */
795  avio_wb24(pb, track->par->extradata_size); /* Length */
796  avio_write(pb, track->par->extradata, track->par->extradata_size); /* BlockData[Length] */
797 
798  return update_size(pb, pos);
799 }
800 
802 {
803  int64_t pos = avio_tell(pb);
804  int channels, channel_map;
805  avio_wb32(pb, 0);
806  ffio_wfourcc(pb, "dOps");
807  avio_w8(pb, 0); /* Version */
808  if (track->par->extradata_size < 19) {
809  av_log(s, AV_LOG_ERROR, "invalid extradata size\n");
810  return AVERROR_INVALIDDATA;
811  }
812  /* extradata contains an Ogg OpusHead, other than byte-ordering and
813  OpusHead's preceeding magic/version, OpusSpecificBox is currently
814  identical. */
815  channels = AV_RB8(track->par->extradata + 9);
816  channel_map = AV_RB8(track->par->extradata + 18);
817 
818  avio_w8(pb, channels); /* OuputChannelCount */
819  avio_wb16(pb, AV_RL16(track->par->extradata + 10)); /* PreSkip */
820  avio_wb32(pb, AV_RL32(track->par->extradata + 12)); /* InputSampleRate */
821  avio_wb16(pb, AV_RL16(track->par->extradata + 16)); /* OutputGain */
822  avio_w8(pb, channel_map); /* ChannelMappingFamily */
823  /* Write the rest of the header out without byte-swapping. */
824  if (channel_map) {
825  if (track->par->extradata_size < 21 + channels) {
826  av_log(s, AV_LOG_ERROR, "invalid extradata size\n");
827  return AVERROR_INVALIDDATA;
828  }
829  avio_write(pb, track->par->extradata + 19, 2 + channels); /* ChannelMappingTable */
830  }
831 
832  return update_size(pb, pos);
833 }
834 
836 {
837  int64_t pos = avio_tell(pb);
838  int length;
839  avio_wb32(pb, 0);
840  ffio_wfourcc(pb, "dmlp");
841 
842  if (track->vos_len < 20) {
844  "Cannot write moov atom before TrueHD packets."
845  " Set the delay_moov flag to fix this.\n");
846  return AVERROR(EINVAL);
847  }
848 
849  length = (AV_RB16(track->vos_data) & 0xFFF) * 2;
850  if (length < 20 || length > track->vos_len)
851  return AVERROR_INVALIDDATA;
852 
853  // Only TrueHD is supported
854  if (AV_RB32(track->vos_data + 4) != 0xF8726FBA)
855  return AVERROR_INVALIDDATA;
856 
857  avio_wb32(pb, AV_RB32(track->vos_data + 8)); /* format_info */
858  avio_wb16(pb, AV_RB16(track->vos_data + 18) << 1); /* peak_data_rate */
859  avio_wb32(pb, 0); /* reserved */
860 
861  return update_size(pb, pos);
862 }
863 
865 {
866  uint32_t layout_tag, bitmap;
867  int64_t pos = avio_tell(pb);
868 
869  layout_tag = ff_mov_get_channel_layout_tag(track->par->codec_id,
870  track->par->channel_layout,
871  &bitmap);
872  if (!layout_tag) {
873  av_log(s, AV_LOG_WARNING, "not writing 'chan' tag due to "
874  "lack of channel information\n");
875  return 0;
876  }
877 
878  if (track->multichannel_as_mono)
879  return 0;
880 
881  avio_wb32(pb, 0); // Size
882  ffio_wfourcc(pb, "chan"); // Type
883  avio_w8(pb, 0); // Version
884  avio_wb24(pb, 0); // Flags
885  avio_wb32(pb, layout_tag); // mChannelLayoutTag
886  avio_wb32(pb, bitmap); // mChannelBitmap
887  avio_wb32(pb, 0); // mNumberChannelDescriptions
888 
889  return update_size(pb, pos);
890 }
891 
893 {
894  int64_t pos = avio_tell(pb);
895 
896  avio_wb32(pb, 0); /* size */
897  ffio_wfourcc(pb, "wave");
898 
899  if (track->par->codec_id != AV_CODEC_ID_QDM2) {
900  avio_wb32(pb, 12); /* size */
901  ffio_wfourcc(pb, "frma");
902  avio_wl32(pb, track->tag);
903  }
904 
905  if (track->par->codec_id == AV_CODEC_ID_AAC) {
906  /* useless atom needed by mplayer, ipod, not needed by quicktime */
907  avio_wb32(pb, 12); /* size */
908  ffio_wfourcc(pb, "mp4a");
909  avio_wb32(pb, 0);
910  mov_write_esds_tag(pb, track);
911  } else if (mov_pcm_le_gt16(track->par->codec_id)) {
912  mov_write_enda_tag(pb);
913  } else if (mov_pcm_be_gt16(track->par->codec_id)) {
915  } else if (track->par->codec_id == AV_CODEC_ID_AMR_NB) {
916  mov_write_amr_tag(pb, track);
917  } else if (track->par->codec_id == AV_CODEC_ID_AC3) {
918  mov_write_ac3_tag(s, pb, track);
919  } else if (track->par->codec_id == AV_CODEC_ID_EAC3) {
920  mov_write_eac3_tag(s, pb, track);
921  } else if (track->par->codec_id == AV_CODEC_ID_ALAC ||
922  track->par->codec_id == AV_CODEC_ID_QDM2) {
923  mov_write_extradata_tag(pb, track);
924  } else if (track->par->codec_id == AV_CODEC_ID_ADPCM_MS ||
926  mov_write_ms_tag(s, pb, track);
927  }
928 
929  avio_wb32(pb, 8); /* size */
930  avio_wb32(pb, 0); /* null tag */
931 
932  return update_size(pb, pos);
933 }
934 
935 static int mov_write_dvc1_structs(MOVTrack *track, uint8_t *buf)
936 {
937  uint8_t *unescaped;
938  const uint8_t *start, *next, *end = track->vos_data + track->vos_len;
939  int unescaped_size, seq_found = 0;
940  int level = 0, interlace = 0;
941  int packet_seq = track->vc1_info.packet_seq;
942  int packet_entry = track->vc1_info.packet_entry;
943  int slices = track->vc1_info.slices;
944  PutBitContext pbc;
945 
946  if (track->start_dts == AV_NOPTS_VALUE) {
947  /* No packets written yet, vc1_info isn't authoritative yet. */
948  /* Assume inline sequence and entry headers. */
949  packet_seq = packet_entry = 1;
951  "moov atom written before any packets, unable to write correct "
952  "dvc1 atom. Set the delay_moov flag to fix this.\n");
953  }
954 
955  unescaped = av_mallocz(track->vos_len + AV_INPUT_BUFFER_PADDING_SIZE);
956  if (!unescaped)
957  return AVERROR(ENOMEM);
958  start = find_next_marker(track->vos_data, end);
959  for (next = start; next < end; start = next) {
960  GetBitContext gb;
961  int size;
962  next = find_next_marker(start + 4, end);
963  size = next - start - 4;
964  if (size <= 0)
965  continue;
966  unescaped_size = vc1_unescape_buffer(start + 4, size, unescaped);
967  init_get_bits(&gb, unescaped, 8 * unescaped_size);
968  if (AV_RB32(start) == VC1_CODE_SEQHDR) {
969  int profile = get_bits(&gb, 2);
970  if (profile != PROFILE_ADVANCED) {
971  av_free(unescaped);
972  return AVERROR(ENOSYS);
973  }
974  seq_found = 1;
975  level = get_bits(&gb, 3);
976  /* chromaformat, frmrtq_postproc, bitrtq_postproc, postprocflag,
977  * width, height */
978  skip_bits_long(&gb, 2 + 3 + 5 + 1 + 2*12);
979  skip_bits(&gb, 1); /* broadcast */
980  interlace = get_bits1(&gb);
981  skip_bits(&gb, 4); /* tfcntrflag, finterpflag, reserved, psf */
982  }
983  }
984  if (!seq_found) {
985  av_free(unescaped);
986  return AVERROR(ENOSYS);
987  }
988 
989  init_put_bits(&pbc, buf, 7);
990  /* VC1DecSpecStruc */
991  put_bits(&pbc, 4, 12); /* profile - advanced */
992  put_bits(&pbc, 3, level);
993  put_bits(&pbc, 1, 0); /* reserved */
994  /* VC1AdvDecSpecStruc */
995  put_bits(&pbc, 3, level);
996  put_bits(&pbc, 1, 0); /* cbr */
997  put_bits(&pbc, 6, 0); /* reserved */
998  put_bits(&pbc, 1, !interlace); /* no interlace */
999  put_bits(&pbc, 1, !packet_seq); /* no multiple seq */
1000  put_bits(&pbc, 1, !packet_entry); /* no multiple entry */
1001  put_bits(&pbc, 1, !slices); /* no slice code */
1002  put_bits(&pbc, 1, 0); /* no bframe */
1003  put_bits(&pbc, 1, 0); /* reserved */
1004 
1005  /* framerate */
1006  if (track->st->avg_frame_rate.num > 0 && track->st->avg_frame_rate.den > 0)
1007  put_bits32(&pbc, track->st->avg_frame_rate.num / track->st->avg_frame_rate.den);
1008  else
1009  put_bits32(&pbc, 0xffffffff);
1010 
1011  flush_put_bits(&pbc);
1012 
1013  av_free(unescaped);
1014 
1015  return 0;
1016 }
1017 
1018 static int mov_write_dvc1_tag(AVIOContext *pb, MOVTrack *track)
1019 {
1020  uint8_t buf[7] = { 0 };
1021  int ret;
1022 
1023  if ((ret = mov_write_dvc1_structs(track, buf)) < 0)
1024  return ret;
1025 
1026  avio_wb32(pb, track->vos_len + 8 + sizeof(buf));
1027  ffio_wfourcc(pb, "dvc1");
1028  avio_write(pb, buf, sizeof(buf));
1029  avio_write(pb, track->vos_data, track->vos_len);
1030 
1031  return 0;
1032 }
1033 
1034 static int mov_write_glbl_tag(AVIOContext *pb, MOVTrack *track)
1035 {
1036  avio_wb32(pb, track->vos_len + 8);
1037  ffio_wfourcc(pb, "glbl");
1038  avio_write(pb, track->vos_data, track->vos_len);
1039  return 8 + track->vos_len;
1040 }
1041 
1042 /**
1043  * Compute flags for 'lpcm' tag.
1044  * See CoreAudioTypes and AudioStreamBasicDescription at Apple.
1045  */
1047 {
1048  switch (codec_id) {
1049  case AV_CODEC_ID_PCM_F32BE:
1050  case AV_CODEC_ID_PCM_F64BE:
1051  return 11;
1052  case AV_CODEC_ID_PCM_F32LE:
1053  case AV_CODEC_ID_PCM_F64LE:
1054  return 9;
1055  case AV_CODEC_ID_PCM_U8:
1056  return 10;
1057  case AV_CODEC_ID_PCM_S16BE:
1058  case AV_CODEC_ID_PCM_S24BE:
1059  case AV_CODEC_ID_PCM_S32BE:
1060  return 14;
1061  case AV_CODEC_ID_PCM_S8:
1062  case AV_CODEC_ID_PCM_S16LE:
1063  case AV_CODEC_ID_PCM_S24LE:
1064  case AV_CODEC_ID_PCM_S32LE:
1065  return 12;
1066  default:
1067  return 0;
1068  }
1069 }
1070 
1071 static int get_cluster_duration(MOVTrack *track, int cluster_idx)
1072 {
1073  int64_t next_dts;
1074 
1075  if (cluster_idx >= track->entry)
1076  return 0;
1077 
1078  if (cluster_idx + 1 == track->entry)
1079  next_dts = track->track_duration + track->start_dts;
1080  else
1081  next_dts = track->cluster[cluster_idx + 1].dts;
1082 
1083  next_dts -= track->cluster[cluster_idx].dts;
1084 
1085  av_assert0(next_dts >= 0);
1086  av_assert0(next_dts <= INT_MAX);
1087 
1088  return next_dts;
1089 }
1090 
1092 {
1093  int i, first_duration;
1094 
1095 // return track->par->frame_size;
1096 
1097  /* use 1 for raw PCM */
1098  if (!track->audio_vbr)
1099  return 1;
1100 
1101  /* check to see if duration is constant for all clusters */
1102  if (!track->entry)
1103  return 0;
1104  first_duration = get_cluster_duration(track, 0);
1105  for (i = 1; i < track->entry; i++) {
1106  if (get_cluster_duration(track, i) != first_duration)
1107  return 0;
1108  }
1109  return first_duration;
1110 }
1111 
1112 static int mov_write_btrt_tag(AVIOContext *pb, MOVTrack *track)
1113 {
1114  int64_t pos = avio_tell(pb);
1115  struct mpeg4_bit_rate_values bit_rates = calculate_mpeg4_bit_rates(track);
1116  if (!bit_rates.max_bit_rate && !bit_rates.avg_bit_rate &&
1117  !bit_rates.buffer_size)
1118  // no useful data to be written, skip
1119  return 0;
1120 
1121  avio_wb32(pb, 0); /* size */
1122  ffio_wfourcc(pb, "btrt");
1123 
1124  avio_wb32(pb, bit_rates.buffer_size);
1125  avio_wb32(pb, bit_rates.max_bit_rate);
1126  avio_wb32(pb, bit_rates.avg_bit_rate);
1127 
1128  return update_size(pb, pos);
1129 }
1130 
1132 {
1133  int64_t pos = avio_tell(pb);
1134  int version = 0;
1135  uint32_t tag = track->tag;
1136  int ret = 0;
1137 
1138  if (track->mode == MODE_MOV) {
1139  if (track->timescale > UINT16_MAX || !track->par->channels) {
1140  if (mov_get_lpcm_flags(track->par->codec_id))
1141  tag = AV_RL32("lpcm");
1142  version = 2;
1143  } else if (track->audio_vbr || mov_pcm_le_gt16(track->par->codec_id) ||
1144  mov_pcm_be_gt16(track->par->codec_id) ||
1145  track->par->codec_id == AV_CODEC_ID_ADPCM_MS ||
1146  track->par->codec_id == AV_CODEC_ID_ADPCM_IMA_WAV ||
1147  track->par->codec_id == AV_CODEC_ID_QDM2) {
1148  version = 1;
1149  }
1150  }
1151 
1152  avio_wb32(pb, 0); /* size */
1153  if (mov->encryption_scheme != MOV_ENC_NONE) {
1154  ffio_wfourcc(pb, "enca");
1155  } else {
1156  avio_wl32(pb, tag); // store it byteswapped
1157  }
1158  avio_wb32(pb, 0); /* Reserved */
1159  avio_wb16(pb, 0); /* Reserved */
1160  avio_wb16(pb, 1); /* Data-reference index, XXX == 1 */
1161 
1162  /* SoundDescription */
1163  avio_wb16(pb, version); /* Version */
1164  avio_wb16(pb, 0); /* Revision level */
1165  avio_wb32(pb, 0); /* Reserved */
1166 
1167  if (version == 2) {
1168  avio_wb16(pb, 3);
1169  avio_wb16(pb, 16);
1170  avio_wb16(pb, 0xfffe);
1171  avio_wb16(pb, 0);
1172  avio_wb32(pb, 0x00010000);
1173  avio_wb32(pb, 72);
1174  avio_wb64(pb, av_double2int(track->par->sample_rate));
1175  avio_wb32(pb, track->par->channels);
1176  avio_wb32(pb, 0x7F000000);
1178  avio_wb32(pb, mov_get_lpcm_flags(track->par->codec_id));
1179  avio_wb32(pb, track->sample_size);
1180  avio_wb32(pb, get_samples_per_packet(track));
1181  } else {
1182  if (track->mode == MODE_MOV) {
1183  avio_wb16(pb, track->par->channels);
1184  if (track->par->codec_id == AV_CODEC_ID_PCM_U8 ||
1185  track->par->codec_id == AV_CODEC_ID_PCM_S8)
1186  avio_wb16(pb, 8); /* bits per sample */
1187  else if (track->par->codec_id == AV_CODEC_ID_ADPCM_G726)
1188  avio_wb16(pb, track->par->bits_per_coded_sample);
1189  else
1190  avio_wb16(pb, 16);
1191  avio_wb16(pb, track->audio_vbr ? -2 : 0); /* compression ID */
1192  } else { /* reserved for mp4/3gp */
1193  if (track->par->codec_id == AV_CODEC_ID_FLAC ||
1194  track->par->codec_id == AV_CODEC_ID_ALAC ||
1195  track->par->codec_id == AV_CODEC_ID_OPUS) {
1196  avio_wb16(pb, track->par->channels);
1197  } else {
1198  avio_wb16(pb, 2);
1199  }
1200  if (track->par->codec_id == AV_CODEC_ID_FLAC ||
1201  track->par->codec_id == AV_CODEC_ID_ALAC) {
1202  avio_wb16(pb, track->par->bits_per_raw_sample);
1203  } else {
1204  avio_wb16(pb, 16);
1205  }
1206  avio_wb16(pb, 0);
1207  }
1208 
1209  avio_wb16(pb, 0); /* packet size (= 0) */
1210  if (track->par->codec_id == AV_CODEC_ID_OPUS)
1211  avio_wb16(pb, 48000);
1212  else if (track->par->codec_id == AV_CODEC_ID_TRUEHD)
1213  avio_wb32(pb, track->par->sample_rate);
1214  else
1215  avio_wb16(pb, track->par->sample_rate <= UINT16_MAX ?
1216  track->par->sample_rate : 0);
1217 
1218  if (track->par->codec_id != AV_CODEC_ID_TRUEHD)
1219  avio_wb16(pb, 0); /* Reserved */
1220  }
1221 
1222  if (version == 1) { /* SoundDescription V1 extended info */
1223  if (mov_pcm_le_gt16(track->par->codec_id) ||
1224  mov_pcm_be_gt16(track->par->codec_id))
1225  avio_wb32(pb, 1); /* must be 1 for uncompressed formats */
1226  else
1227  avio_wb32(pb, track->par->frame_size); /* Samples per packet */
1228  avio_wb32(pb, track->sample_size / track->par->channels); /* Bytes per packet */
1229  avio_wb32(pb, track->sample_size); /* Bytes per frame */
1230  avio_wb32(pb, 2); /* Bytes per sample */
1231  }
1232 
1233  if (track->mode == MODE_MOV &&
1234  (track->par->codec_id == AV_CODEC_ID_AAC ||
1235  track->par->codec_id == AV_CODEC_ID_AC3 ||
1236  track->par->codec_id == AV_CODEC_ID_EAC3 ||
1237  track->par->codec_id == AV_CODEC_ID_AMR_NB ||
1238  track->par->codec_id == AV_CODEC_ID_ALAC ||
1239  track->par->codec_id == AV_CODEC_ID_ADPCM_MS ||
1240  track->par->codec_id == AV_CODEC_ID_ADPCM_IMA_WAV ||
1241  track->par->codec_id == AV_CODEC_ID_QDM2 ||
1242  (mov_pcm_le_gt16(track->par->codec_id) && version==1) ||
1243  (mov_pcm_be_gt16(track->par->codec_id) && version==1)))
1244  ret = mov_write_wave_tag(s, pb, track);
1245  else if (track->tag == MKTAG('m','p','4','a'))
1246  ret = mov_write_esds_tag(pb, track);
1247  else if (track->par->codec_id == AV_CODEC_ID_AMR_NB)
1248  ret = mov_write_amr_tag(pb, track);
1249  else if (track->par->codec_id == AV_CODEC_ID_AC3)
1250  ret = mov_write_ac3_tag(s, pb, track);
1251  else if (track->par->codec_id == AV_CODEC_ID_EAC3)
1252  ret = mov_write_eac3_tag(s, pb, track);
1253  else if (track->par->codec_id == AV_CODEC_ID_ALAC)
1254  ret = mov_write_extradata_tag(pb, track);
1255  else if (track->par->codec_id == AV_CODEC_ID_WMAPRO)
1256  ret = mov_write_wfex_tag(s, pb, track);
1257  else if (track->par->codec_id == AV_CODEC_ID_FLAC)
1258  ret = mov_write_dfla_tag(pb, track);
1259  else if (track->par->codec_id == AV_CODEC_ID_OPUS)
1260  ret = mov_write_dops_tag(s, pb, track);
1261  else if (track->par->codec_id == AV_CODEC_ID_TRUEHD)
1262  ret = mov_write_dmlp_tag(s, pb, track);
1263  else if (track->vos_len > 0)
1264  ret = mov_write_glbl_tag(pb, track);
1265 
1266  if (ret < 0)
1267  return ret;
1268 
1269  if (track->mode == MODE_MOV && track->par->codec_type == AVMEDIA_TYPE_AUDIO
1270  && ((ret = mov_write_chan_tag(s, pb, track)) < 0)) {
1271  return ret;
1272  }
1273 
1274  if (mov->encryption_scheme != MOV_ENC_NONE
1275  && ((ret = ff_mov_cenc_write_sinf_tag(track, pb, mov->encryption_kid)) < 0)) {
1276  return ret;
1277  }
1278 
1279  if (track->mode == MODE_MP4 &&
1280  ((ret = mov_write_btrt_tag(pb, track)) < 0))
1281  return ret;
1282 
1283  ret = update_size(pb, pos);
1284  return ret;
1285 }
1286 
1288 {
1289  avio_wb32(pb, 0xf); /* size */
1290  ffio_wfourcc(pb, "d263");
1291  ffio_wfourcc(pb, "FFMP");
1292  avio_w8(pb, 0); /* decoder version */
1293  /* FIXME use AVCodecContext level/profile, when encoder will set values */
1294  avio_w8(pb, 0xa); /* level */
1295  avio_w8(pb, 0); /* profile */
1296  return 0xf;
1297 }
1298 
1299 static int mov_write_av1c_tag(AVIOContext *pb, MOVTrack *track)
1300 {
1301  int64_t pos = avio_tell(pb);
1302 
1303  avio_wb32(pb, 0);
1304  ffio_wfourcc(pb, "av1C");
1305  ff_isom_write_av1c(pb, track->vos_data, track->vos_len);
1306  return update_size(pb, pos);
1307 }
1308 
1309 static int mov_write_avcc_tag(AVIOContext *pb, MOVTrack *track)
1310 {
1311  int64_t pos = avio_tell(pb);
1312 
1313  avio_wb32(pb, 0);
1314  ffio_wfourcc(pb, "avcC");
1315  ff_isom_write_avcc(pb, track->vos_data, track->vos_len);
1316  return update_size(pb, pos);
1317 }
1318 
1320 {
1321  int64_t pos = avio_tell(pb);
1322 
1323  avio_wb32(pb, 0);
1324  ffio_wfourcc(pb, "vpcC");
1325  avio_w8(pb, 1); /* version */
1326  avio_wb24(pb, 0); /* flags */
1327  ff_isom_write_vpcc(s, pb, track->par);
1328  return update_size(pb, pos);
1329 }
1330 
1331 static int mov_write_hvcc_tag(AVIOContext *pb, MOVTrack *track)
1332 {
1333  int64_t pos = avio_tell(pb);
1334 
1335  avio_wb32(pb, 0);
1336  ffio_wfourcc(pb, "hvcC");
1337  if (track->tag == MKTAG('h','v','c','1'))
1338  ff_isom_write_hvcc(pb, track->vos_data, track->vos_len, 1);
1339  else
1340  ff_isom_write_hvcc(pb, track->vos_data, track->vos_len, 0);
1341  return update_size(pb, pos);
1342 }
1343 
1344 /* also used by all avid codecs (dv, imx, meridien) and their variants */
1345 static int mov_write_avid_tag(AVIOContext *pb, MOVTrack *track)
1346 {
1347  int interlaced;
1348  int cid;
1349  int display_width = track->par->width;
1350 
1351  if (track->vos_data && track->vos_len > 0x29) {
1352  if (ff_dnxhd_parse_header_prefix(track->vos_data) != 0) {
1353  /* looks like a DNxHD bit stream */
1354  interlaced = (track->vos_data[5] & 2);
1355  cid = AV_RB32(track->vos_data + 0x28);
1356  } else {
1357  av_log(NULL, AV_LOG_WARNING, "Could not locate DNxHD bit stream in vos_data\n");
1358  return 0;
1359  }
1360  } else {
1361  av_log(NULL, AV_LOG_WARNING, "Could not locate DNxHD bit stream, vos_data too small\n");
1362  return 0;
1363  }
1364 
1365  avio_wb32(pb, 24); /* size */
1366  ffio_wfourcc(pb, "ACLR");
1367  ffio_wfourcc(pb, "ACLR");
1368  ffio_wfourcc(pb, "0001");
1369  if (track->par->color_range == AVCOL_RANGE_MPEG || /* Legal range (16-235) */
1371  avio_wb32(pb, 1); /* Corresponds to 709 in official encoder */
1372  } else { /* Full range (0-255) */
1373  avio_wb32(pb, 2); /* Corresponds to RGB in official encoder */
1374  }
1375  avio_wb32(pb, 0); /* unknown */
1376 
1377  if (track->tag == MKTAG('A','V','d','h')) {
1378  avio_wb32(pb, 32);
1379  ffio_wfourcc(pb, "ADHR");
1380  ffio_wfourcc(pb, "0001");
1381  avio_wb32(pb, cid);
1382  avio_wb32(pb, 0); /* unknown */
1383  avio_wb32(pb, 1); /* unknown */
1384  avio_wb32(pb, 0); /* unknown */
1385  avio_wb32(pb, 0); /* unknown */
1386  return 0;
1387  }
1388 
1389  avio_wb32(pb, 24); /* size */
1390  ffio_wfourcc(pb, "APRG");
1391  ffio_wfourcc(pb, "APRG");
1392  ffio_wfourcc(pb, "0001");
1393  avio_wb32(pb, 1); /* unknown */
1394  avio_wb32(pb, 0); /* unknown */
1395 
1396  avio_wb32(pb, 120); /* size */
1397  ffio_wfourcc(pb, "ARES");
1398  ffio_wfourcc(pb, "ARES");
1399  ffio_wfourcc(pb, "0001");
1400  avio_wb32(pb, cid); /* dnxhd cid, some id ? */
1401  if ( track->par->sample_aspect_ratio.num > 0
1402  && track->par->sample_aspect_ratio.den > 0)
1403  display_width = display_width * track->par->sample_aspect_ratio.num / track->par->sample_aspect_ratio.den;
1404  avio_wb32(pb, display_width);
1405  /* values below are based on samples created with quicktime and avid codecs */
1406  if (interlaced) {
1407  avio_wb32(pb, track->par->height / 2);
1408  avio_wb32(pb, 2); /* unknown */
1409  avio_wb32(pb, 0); /* unknown */
1410  avio_wb32(pb, 4); /* unknown */
1411  } else {
1412  avio_wb32(pb, track->par->height);
1413  avio_wb32(pb, 1); /* unknown */
1414  avio_wb32(pb, 0); /* unknown */
1415  if (track->par->height == 1080)
1416  avio_wb32(pb, 5); /* unknown */
1417  else
1418  avio_wb32(pb, 6); /* unknown */
1419  }
1420  /* padding */
1421  ffio_fill(pb, 0, 10 * 8);
1422 
1423  return 0;
1424 }
1425 
1426 static int mov_write_dpxe_tag(AVIOContext *pb, MOVTrack *track)
1427 {
1428  avio_wb32(pb, 12);
1429  ffio_wfourcc(pb, "DpxE");
1430  if (track->par->extradata_size >= 12 &&
1431  !memcmp(&track->par->extradata[4], "DpxE", 4)) {
1432  avio_wb32(pb, track->par->extradata[11]);
1433  } else {
1434  avio_wb32(pb, 1);
1435  }
1436  return 0;
1437 }
1438 
1440 {
1441  int tag;
1442 
1443  if (track->par->width == 720) { /* SD */
1444  if (track->par->height == 480) { /* NTSC */
1445  if (track->par->format == AV_PIX_FMT_YUV422P) tag = MKTAG('d','v','5','n');
1446  else tag = MKTAG('d','v','c',' ');
1447  }else if (track->par->format == AV_PIX_FMT_YUV422P) tag = MKTAG('d','v','5','p');
1448  else if (track->par->format == AV_PIX_FMT_YUV420P) tag = MKTAG('d','v','c','p');
1449  else tag = MKTAG('d','v','p','p');
1450  } else if (track->par->height == 720) { /* HD 720 line */
1451  if (track->st->time_base.den == 50) tag = MKTAG('d','v','h','q');
1452  else tag = MKTAG('d','v','h','p');
1453  } else if (track->par->height == 1080) { /* HD 1080 line */
1454  if (track->st->time_base.den == 25) tag = MKTAG('d','v','h','5');
1455  else tag = MKTAG('d','v','h','6');
1456  } else {
1457  av_log(s, AV_LOG_ERROR, "unsupported height for dv codec\n");
1458  return 0;
1459  }
1460 
1461  return tag;
1462 }
1463 
1465 {
1466  AVRational rational_framerate = st->avg_frame_rate;
1467  int rate = 0;
1468  if (rational_framerate.den != 0)
1469  rate = av_q2d(rational_framerate);
1470  return rate;
1471 }
1472 
1474 {
1475  int tag = track->par->codec_tag;
1477  AVStream *st = track->st;
1478  int rate = defined_frame_rate(s, st);
1479 
1480  if (!tag)
1481  tag = MKTAG('m', '2', 'v', '1'); //fallback tag
1482 
1483  if (track->par->format == AV_PIX_FMT_YUV420P) {
1484  if (track->par->width == 1280 && track->par->height == 720) {
1485  if (!interlaced) {
1486  if (rate == 24) tag = MKTAG('x','d','v','4');
1487  else if (rate == 25) tag = MKTAG('x','d','v','5');
1488  else if (rate == 30) tag = MKTAG('x','d','v','1');
1489  else if (rate == 50) tag = MKTAG('x','d','v','a');
1490  else if (rate == 60) tag = MKTAG('x','d','v','9');
1491  }
1492  } else if (track->par->width == 1440 && track->par->height == 1080) {
1493  if (!interlaced) {
1494  if (rate == 24) tag = MKTAG('x','d','v','6');
1495  else if (rate == 25) tag = MKTAG('x','d','v','7');
1496  else if (rate == 30) tag = MKTAG('x','d','v','8');
1497  } else {
1498  if (rate == 25) tag = MKTAG('x','d','v','3');
1499  else if (rate == 30) tag = MKTAG('x','d','v','2');
1500  }
1501  } else if (track->par->width == 1920 && track->par->height == 1080) {
1502  if (!interlaced) {
1503  if (rate == 24) tag = MKTAG('x','d','v','d');
1504  else if (rate == 25) tag = MKTAG('x','d','v','e');
1505  else if (rate == 30) tag = MKTAG('x','d','v','f');
1506  } else {
1507  if (rate == 25) tag = MKTAG('x','d','v','c');
1508  else if (rate == 30) tag = MKTAG('x','d','v','b');
1509  }
1510  }
1511  } else if (track->par->format == AV_PIX_FMT_YUV422P) {
1512  if (track->par->width == 1280 && track->par->height == 720) {
1513  if (!interlaced) {
1514  if (rate == 24) tag = MKTAG('x','d','5','4');
1515  else if (rate == 25) tag = MKTAG('x','d','5','5');
1516  else if (rate == 30) tag = MKTAG('x','d','5','1');
1517  else if (rate == 50) tag = MKTAG('x','d','5','a');
1518  else if (rate == 60) tag = MKTAG('x','d','5','9');
1519  }
1520  } else if (track->par->width == 1920 && track->par->height == 1080) {
1521  if (!interlaced) {
1522  if (rate == 24) tag = MKTAG('x','d','5','d');
1523  else if (rate == 25) tag = MKTAG('x','d','5','e');
1524  else if (rate == 30) tag = MKTAG('x','d','5','f');
1525  } else {
1526  if (rate == 25) tag = MKTAG('x','d','5','c');
1527  else if (rate == 30) tag = MKTAG('x','d','5','b');
1528  }
1529  }
1530  }
1531 
1532  return tag;
1533 }
1534 
1536 {
1537  int tag = track->par->codec_tag;
1539  AVStream *st = track->st;
1540  int rate = defined_frame_rate(s, st);
1541 
1542  if (!tag)
1543  tag = MKTAG('a', 'v', 'c', 'i'); //fallback tag
1544 
1545  if (track->par->format == AV_PIX_FMT_YUV420P10) {
1546  if (track->par->width == 960 && track->par->height == 720) {
1547  if (!interlaced) {
1548  if (rate == 24) tag = MKTAG('a','i','5','p');
1549  else if (rate == 25) tag = MKTAG('a','i','5','q');
1550  else if (rate == 30) tag = MKTAG('a','i','5','p');
1551  else if (rate == 50) tag = MKTAG('a','i','5','q');
1552  else if (rate == 60) tag = MKTAG('a','i','5','p');
1553  }
1554  } else if (track->par->width == 1440 && track->par->height == 1080) {
1555  if (!interlaced) {
1556  if (rate == 24) tag = MKTAG('a','i','5','3');
1557  else if (rate == 25) tag = MKTAG('a','i','5','2');
1558  else if (rate == 30) tag = MKTAG('a','i','5','3');
1559  } else {
1560  if (rate == 50) tag = MKTAG('a','i','5','5');
1561  else if (rate == 60) tag = MKTAG('a','i','5','6');
1562  }
1563  }
1564  } else if (track->par->format == AV_PIX_FMT_YUV422P10) {
1565  if (track->par->width == 1280 && track->par->height == 720) {
1566  if (!interlaced) {
1567  if (rate == 24) tag = MKTAG('a','i','1','p');
1568  else if (rate == 25) tag = MKTAG('a','i','1','q');
1569  else if (rate == 30) tag = MKTAG('a','i','1','p');
1570  else if (rate == 50) tag = MKTAG('a','i','1','q');
1571  else if (rate == 60) tag = MKTAG('a','i','1','p');
1572  }
1573  } else if (track->par->width == 1920 && track->par->height == 1080) {
1574  if (!interlaced) {
1575  if (rate == 24) tag = MKTAG('a','i','1','3');
1576  else if (rate == 25) tag = MKTAG('a','i','1','2');
1577  else if (rate == 30) tag = MKTAG('a','i','1','3');
1578  } else {
1579  if (rate == 25) tag = MKTAG('a','i','1','5');
1580  else if (rate == 50) tag = MKTAG('a','i','1','5');
1581  else if (rate == 60) tag = MKTAG('a','i','1','6');
1582  }
1583  } else if ( track->par->width == 4096 && track->par->height == 2160
1584  || track->par->width == 3840 && track->par->height == 2160
1585  || track->par->width == 2048 && track->par->height == 1080) {
1586  tag = MKTAG('a','i','v','x');
1587  }
1588  }
1589 
1590  return tag;
1591 }
1592 
1593 static const struct {
1595  uint32_t tag;
1596  unsigned bps;
1597 } mov_pix_fmt_tags[] = {
1598  { AV_PIX_FMT_YUYV422, MKTAG('y','u','v','2'), 0 },
1599  { AV_PIX_FMT_YUYV422, MKTAG('y','u','v','s'), 0 },
1600  { AV_PIX_FMT_UYVY422, MKTAG('2','v','u','y'), 0 },
1601  { AV_PIX_FMT_RGB555BE,MKTAG('r','a','w',' '), 16 },
1602  { AV_PIX_FMT_RGB555LE,MKTAG('L','5','5','5'), 16 },
1603  { AV_PIX_FMT_RGB565LE,MKTAG('L','5','6','5'), 16 },
1604  { AV_PIX_FMT_RGB565BE,MKTAG('B','5','6','5'), 16 },
1605  { AV_PIX_FMT_GRAY16BE,MKTAG('b','1','6','g'), 16 },
1606  { AV_PIX_FMT_RGB24, MKTAG('r','a','w',' '), 24 },
1607  { AV_PIX_FMT_BGR24, MKTAG('2','4','B','G'), 24 },
1608  { AV_PIX_FMT_ARGB, MKTAG('r','a','w',' '), 32 },
1609  { AV_PIX_FMT_BGRA, MKTAG('B','G','R','A'), 32 },
1610  { AV_PIX_FMT_RGBA, MKTAG('R','G','B','A'), 32 },
1611  { AV_PIX_FMT_ABGR, MKTAG('A','B','G','R'), 32 },
1612  { AV_PIX_FMT_RGB48BE, MKTAG('b','4','8','r'), 48 },
1613 };
1614 
1616 {
1617  int tag = MKTAG('A','V','d','n');
1618  if (track->par->profile != FF_PROFILE_UNKNOWN &&
1619  track->par->profile != FF_PROFILE_DNXHD)
1620  tag = MKTAG('A','V','d','h');
1621  return tag;
1622 }
1623 
1625 {
1626  int tag = track->par->codec_tag;
1627  int i;
1628  enum AVPixelFormat pix_fmt;
1629 
1630  for (i = 0; i < FF_ARRAY_ELEMS(mov_pix_fmt_tags); i++) {
1631  if (track->par->format == mov_pix_fmt_tags[i].pix_fmt) {
1632  tag = mov_pix_fmt_tags[i].tag;
1634  if (track->par->codec_tag == mov_pix_fmt_tags[i].tag)
1635  break;
1636  }
1637  }
1638 
1640  track->par->bits_per_coded_sample);
1641  if (tag == MKTAG('r','a','w',' ') &&
1642  track->par->format != pix_fmt &&
1643  track->par->format != AV_PIX_FMT_GRAY8 &&
1644  track->par->format != AV_PIX_FMT_NONE)
1645  av_log(s, AV_LOG_ERROR, "%s rawvideo cannot be written to mov, output file will be unreadable\n",
1646  av_get_pix_fmt_name(track->par->format));
1647  return tag;
1648 }
1649 
1650 static unsigned int mov_get_codec_tag(AVFormatContext *s, MOVTrack *track)
1651 {
1652  unsigned int tag = track->par->codec_tag;
1653 
1654  // "rtp " is used to distinguish internally created RTP-hint tracks
1655  // (with rtp_ctx) from other tracks.
1656  if (tag == MKTAG('r','t','p',' '))
1657  tag = 0;
1658  if (!tag || (s->strict_std_compliance >= FF_COMPLIANCE_NORMAL &&
1659  (track->par->codec_id == AV_CODEC_ID_DVVIDEO ||
1660  track->par->codec_id == AV_CODEC_ID_RAWVIDEO ||
1661  track->par->codec_id == AV_CODEC_ID_H263 ||
1662  track->par->codec_id == AV_CODEC_ID_H264 ||
1663  track->par->codec_id == AV_CODEC_ID_DNXHD ||
1664  track->par->codec_id == AV_CODEC_ID_MPEG2VIDEO ||
1665  av_get_bits_per_sample(track->par->codec_id)))) { // pcm audio
1666  if (track->par->codec_id == AV_CODEC_ID_DVVIDEO)
1667  tag = mov_get_dv_codec_tag(s, track);
1668  else if (track->par->codec_id == AV_CODEC_ID_RAWVIDEO)
1669  tag = mov_get_rawvideo_codec_tag(s, track);
1670  else if (track->par->codec_id == AV_CODEC_ID_MPEG2VIDEO)
1672  else if (track->par->codec_id == AV_CODEC_ID_H264)
1673  tag = mov_get_h264_codec_tag(s, track);
1674  else if (track->par->codec_id == AV_CODEC_ID_DNXHD)
1675  tag = mov_get_dnxhd_codec_tag(s, track);
1676  else if (track->par->codec_type == AVMEDIA_TYPE_VIDEO) {
1678  if (!tag) { // if no mac fcc found, try with Microsoft tags
1680  if (tag)
1681  av_log(s, AV_LOG_WARNING, "Using MS style video codec tag, "
1682  "the file may be unplayable!\n");
1683  }
1684  } else if (track->par->codec_type == AVMEDIA_TYPE_AUDIO) {
1686  if (!tag) { // if no mac fcc found, try with Microsoft tags
1687  int ms_tag = ff_codec_get_tag(ff_codec_wav_tags, track->par->codec_id);
1688  if (ms_tag) {
1689  tag = MKTAG('m', 's', ((ms_tag >> 8) & 0xff), (ms_tag & 0xff));
1690  av_log(s, AV_LOG_WARNING, "Using MS style audio codec tag, "
1691  "the file may be unplayable!\n");
1692  }
1693  }
1694  } else if (track->par->codec_type == AVMEDIA_TYPE_SUBTITLE)
1696  }
1697 
1698  return tag;
1699 }
1700 
1702  { AV_CODEC_ID_MJPEG, 0xD },
1703  { AV_CODEC_ID_PNG, 0xE },
1704  { AV_CODEC_ID_BMP, 0x1B },
1705  { AV_CODEC_ID_NONE, 0 },
1706 };
1707 
1708 static unsigned int validate_codec_tag(const AVCodecTag *const *tags,
1709  unsigned int tag, int codec_id)
1710 {
1711  int i;
1712 
1713  /**
1714  * Check that tag + id is in the table
1715  */
1716  for (i = 0; tags && tags[i]; i++) {
1717  const AVCodecTag *codec_tags = tags[i];
1718  while (codec_tags->id != AV_CODEC_ID_NONE) {
1719  if (avpriv_toupper4(codec_tags->tag) == avpriv_toupper4(tag) &&
1720  codec_tags->id == codec_id)
1721  return codec_tags->tag;
1722  codec_tags++;
1723  }
1724  }
1725  return 0;
1726 }
1727 
1728 static unsigned int mov_find_codec_tag(AVFormatContext *s, MOVTrack *track)
1729 {
1730  if (is_cover_image(track->st))
1732 
1733  if (track->mode == MODE_IPOD)
1734  if (!av_match_ext(s->url, "m4a") &&
1735  !av_match_ext(s->url, "m4v") &&
1736  !av_match_ext(s->url, "m4b"))
1737  av_log(s, AV_LOG_WARNING, "Warning, extension is not .m4a nor .m4v "
1738  "Quicktime/Ipod might not play the file\n");
1739 
1740  if (track->mode == MODE_MOV) {
1741  return mov_get_codec_tag(s, track);
1742  } else
1743  return validate_codec_tag(s->oformat->codec_tag, track->par->codec_tag,
1744  track->par->codec_id);
1745 }
1746 
1747 /** Write uuid atom.
1748  * Needed to make file play in iPods running newest firmware
1749  * goes after avcC atom in moov.trak.mdia.minf.stbl.stsd.avc1
1750  */
1752 {
1753  avio_wb32(pb, 28);
1754  ffio_wfourcc(pb, "uuid");
1755  avio_wb32(pb, 0x6b6840f2);
1756  avio_wb32(pb, 0x5f244fc5);
1757  avio_wb32(pb, 0xba39a51b);
1758  avio_wb32(pb, 0xcf0323f3);
1759  avio_wb32(pb, 0x0);
1760  return 28;
1761 }
1762 
1763 static const uint16_t fiel_data[] = {
1764  0x0000, 0x0100, 0x0201, 0x0206, 0x0209, 0x020e
1765 };
1766 
1767 static int mov_write_fiel_tag(AVIOContext *pb, MOVTrack *track, int field_order)
1768 {
1769  unsigned mov_field_order = 0;
1770  if (field_order < FF_ARRAY_ELEMS(fiel_data))
1771  mov_field_order = fiel_data[field_order];
1772  else
1773  return 0;
1774  avio_wb32(pb, 10);
1775  ffio_wfourcc(pb, "fiel");
1776  avio_wb16(pb, mov_field_order);
1777  return 10;
1778 }
1779 
1781 {
1782  int ret = AVERROR_BUG;
1783  int64_t pos = avio_tell(pb);
1784  avio_wb32(pb, 0); /* size */
1785  avio_wl32(pb, track->tag); // store it byteswapped
1786  avio_wb32(pb, 0); /* Reserved */
1787  avio_wb16(pb, 0); /* Reserved */
1788  avio_wb16(pb, 1); /* Data-reference index */
1789 
1790  if (track->par->codec_id == AV_CODEC_ID_DVD_SUBTITLE)
1791  mov_write_esds_tag(pb, track);
1792  else if (track->par->codec_id == AV_CODEC_ID_TTML) {
1793  switch (track->par->codec_tag) {
1794  case MOV_ISMV_TTML_TAG:
1795  // ISMV dfxp requires no extradata.
1796  break;
1797  case MOV_MP4_TTML_TAG:
1798  // As specified in 14496-30, XMLSubtitleSampleEntry
1799  // Namespace
1800  avio_put_str(pb, "http://www.w3.org/ns/ttml");
1801  // Empty schema_location
1802  avio_w8(pb, 0);
1803  // Empty auxiliary_mime_types
1804  avio_w8(pb, 0);
1805  break;
1806  default:
1808  "Unknown codec tag '%s' utilized for TTML stream with "
1809  "index %d (track id %d)!\n",
1810  av_fourcc2str(track->par->codec_tag), track->st->index,
1811  track->track_id);
1812  return AVERROR(EINVAL);
1813  }
1814  } else if (track->par->extradata_size)
1815  avio_write(pb, track->par->extradata, track->par->extradata_size);
1816 
1817  if (track->mode == MODE_MP4 &&
1818  ((ret = mov_write_btrt_tag(pb, track)) < 0))
1819  return ret;
1820 
1821  return update_size(pb, pos);
1822 }
1823 
1825 {
1826  int8_t stereo_mode;
1827 
1828  if (stereo_3d->flags != 0) {
1829  av_log(s, AV_LOG_WARNING, "Unsupported stereo_3d flags %x. st3d not written.\n", stereo_3d->flags);
1830  return 0;
1831  }
1832 
1833  switch (stereo_3d->type) {
1834  case AV_STEREO3D_2D:
1835  stereo_mode = 0;
1836  break;
1837  case AV_STEREO3D_TOPBOTTOM:
1838  stereo_mode = 1;
1839  break;
1841  stereo_mode = 2;
1842  break;
1843  default:
1844  av_log(s, AV_LOG_WARNING, "Unsupported stereo_3d type %s. st3d not written.\n", av_stereo3d_type_name(stereo_3d->type));
1845  return 0;
1846  }
1847  avio_wb32(pb, 13); /* size */
1848  ffio_wfourcc(pb, "st3d");
1849  avio_wb32(pb, 0); /* version = 0 & flags = 0 */
1850  avio_w8(pb, stereo_mode);
1851  return 13;
1852 }
1853 
1855 {
1856  int64_t sv3d_pos, svhd_pos, proj_pos;
1857  const char* metadata_source = s->flags & AVFMT_FLAG_BITEXACT ? "Lavf" : LIBAVFORMAT_IDENT;
1858 
1859  if (spherical_mapping->projection != AV_SPHERICAL_EQUIRECTANGULAR &&
1860  spherical_mapping->projection != AV_SPHERICAL_EQUIRECTANGULAR_TILE &&
1861  spherical_mapping->projection != AV_SPHERICAL_CUBEMAP) {
1862  av_log(s, AV_LOG_WARNING, "Unsupported projection %d. sv3d not written.\n", spherical_mapping->projection);
1863  return 0;
1864  }
1865 
1866  sv3d_pos = avio_tell(pb);
1867  avio_wb32(pb, 0); /* size */
1868  ffio_wfourcc(pb, "sv3d");
1869 
1870  svhd_pos = avio_tell(pb);
1871  avio_wb32(pb, 0); /* size */
1872  ffio_wfourcc(pb, "svhd");
1873  avio_wb32(pb, 0); /* version = 0 & flags = 0 */
1874  avio_put_str(pb, metadata_source);
1875  update_size(pb, svhd_pos);
1876 
1877  proj_pos = avio_tell(pb);
1878  avio_wb32(pb, 0); /* size */
1879  ffio_wfourcc(pb, "proj");
1880 
1881  avio_wb32(pb, 24); /* size */
1882  ffio_wfourcc(pb, "prhd");
1883  avio_wb32(pb, 0); /* version = 0 & flags = 0 */
1884  avio_wb32(pb, spherical_mapping->yaw);
1885  avio_wb32(pb, spherical_mapping->pitch);
1886  avio_wb32(pb, spherical_mapping->roll);
1887 
1888  switch (spherical_mapping->projection) {
1891  avio_wb32(pb, 28); /* size */
1892  ffio_wfourcc(pb, "equi");
1893  avio_wb32(pb, 0); /* version = 0 & flags = 0 */
1894  avio_wb32(pb, spherical_mapping->bound_top);
1895  avio_wb32(pb, spherical_mapping->bound_bottom);
1896  avio_wb32(pb, spherical_mapping->bound_left);
1897  avio_wb32(pb, spherical_mapping->bound_right);
1898  break;
1899  case AV_SPHERICAL_CUBEMAP:
1900  avio_wb32(pb, 20); /* size */
1901  ffio_wfourcc(pb, "cbmp");
1902  avio_wb32(pb, 0); /* version = 0 & flags = 0 */
1903  avio_wb32(pb, 0); /* layout */
1904  avio_wb32(pb, spherical_mapping->padding); /* padding */
1905  break;
1906  }
1907  update_size(pb, proj_pos);
1908 
1909  return update_size(pb, sv3d_pos);
1910 }
1911 
1913 {
1914  avio_wb32(pb, 32); /* size = 8 + 24 */
1915  if (dovi->dv_profile > 7)
1916  ffio_wfourcc(pb, "dvvC");
1917  else
1918  ffio_wfourcc(pb, "dvcC");
1919  avio_w8(pb, dovi->dv_version_major);
1920  avio_w8(pb, dovi->dv_version_minor);
1921  avio_wb16(pb, (dovi->dv_profile << 9) | (dovi->dv_level << 3) |
1922  (dovi->rpu_present_flag << 2) | (dovi->el_present_flag << 1) |
1923  dovi->bl_present_flag);
1924  avio_wb32(pb, (dovi->dv_bl_signal_compatibility_id << 28) | 0);
1925 
1926  ffio_fill(pb, 0, 4 * 4); /* reserved */
1927  av_log(s, AV_LOG_DEBUG, "DOVI in %s box, version: %d.%d, profile: %d, level: %d, "
1928  "rpu flag: %d, el flag: %d, bl flag: %d, compatibility id: %d\n",
1929  dovi->dv_profile > 7 ? "dvvC" : "dvcC",
1930  dovi->dv_version_major, dovi->dv_version_minor,
1931  dovi->dv_profile, dovi->dv_level,
1932  dovi->rpu_present_flag,
1933  dovi->el_present_flag,
1934  dovi->bl_present_flag,
1936  return 32; /* 8 + 24 */
1937 }
1938 
1939 static int mov_write_clap_tag(AVIOContext *pb, MOVTrack *track)
1940 {
1941  avio_wb32(pb, 40);
1942  ffio_wfourcc(pb, "clap");
1943  avio_wb32(pb, track->par->width); /* apertureWidth_N */
1944  avio_wb32(pb, 1); /* apertureWidth_D (= 1) */
1945  avio_wb32(pb, track->height); /* apertureHeight_N */
1946  avio_wb32(pb, 1); /* apertureHeight_D (= 1) */
1947  avio_wb32(pb, 0); /* horizOff_N (= 0) */
1948  avio_wb32(pb, 1); /* horizOff_D (= 1) */
1949  avio_wb32(pb, 0); /* vertOff_N (= 0) */
1950  avio_wb32(pb, 1); /* vertOff_D (= 1) */
1951  return 40;
1952 }
1953 
1954 static int mov_write_pasp_tag(AVIOContext *pb, MOVTrack *track)
1955 {
1956  AVRational sar;
1957  av_reduce(&sar.num, &sar.den, track->par->sample_aspect_ratio.num,
1958  track->par->sample_aspect_ratio.den, INT_MAX);
1959 
1960  avio_wb32(pb, 16);
1961  ffio_wfourcc(pb, "pasp");
1962  avio_wb32(pb, sar.num);
1963  avio_wb32(pb, sar.den);
1964  return 16;
1965 }
1966 
1967 static int mov_write_gama_tag(AVFormatContext *s, AVIOContext *pb, MOVTrack *track, double gamma)
1968 {
1969  uint32_t gama = 0;
1970  if (gamma <= 0.0) {
1971  gamma = avpriv_get_gamma_from_trc(track->par->color_trc);
1972  }
1973  av_log(s, AV_LOG_DEBUG, "gamma value %g\n", gamma);
1974 
1975  if (gamma > 1e-6) {
1976  gama = (uint32_t)lrint((double)(1<<16) * gamma);
1977  av_log(s, AV_LOG_DEBUG, "writing gama value %"PRId32"\n", gama);
1978 
1979  av_assert0(track->mode == MODE_MOV);
1980  avio_wb32(pb, 12);
1981  ffio_wfourcc(pb, "gama");
1982  avio_wb32(pb, gama);
1983  return 12;
1984  } else {
1985  av_log(s, AV_LOG_WARNING, "gamma value unknown, unable to write gama atom\n");
1986  }
1987  return 0;
1988 }
1989 
1990 static int mov_write_colr_tag(AVIOContext *pb, MOVTrack *track, int prefer_icc)
1991 {
1992  int64_t pos = avio_tell(pb);
1993 
1994  // Ref (MOV): https://developer.apple.com/library/mac/technotes/tn2162/_index.html#//apple_ref/doc/uid/DTS40013070-CH1-TNTAG9
1995  // Ref (MP4): ISO/IEC 14496-12:2012
1996 
1997  const uint8_t *icc_profile;
1998  size_t icc_profile_size;
1999 
2000  if (prefer_icc) {
2001  icc_profile = av_stream_get_side_data(track->st, AV_PKT_DATA_ICC_PROFILE, &icc_profile_size);
2002 
2003  if (icc_profile) {
2004  avio_wb32(pb, 12 + icc_profile_size);
2005  ffio_wfourcc(pb, "colr");
2006  ffio_wfourcc(pb, "prof");
2007  avio_write(pb, icc_profile, icc_profile_size);
2008  return 12 + icc_profile_size;
2009  }
2010  else {
2011  av_log(NULL, AV_LOG_INFO, "no ICC profile found, will write nclx/nclc colour info instead\n");
2012  }
2013  }
2014 
2015  /* We should only ever be called by MOV or MP4. */
2016  av_assert0(track->mode == MODE_MOV || track->mode == MODE_MP4);
2017 
2018  avio_wb32(pb, 0); /* size */
2019  ffio_wfourcc(pb, "colr");
2020  if (track->mode == MODE_MP4)
2021  ffio_wfourcc(pb, "nclx");
2022  else
2023  ffio_wfourcc(pb, "nclc");
2024  // Do not try to guess the color info if it is AVCOL_PRI_UNSPECIFIED.
2025  // e.g., Dolby Vision for Apple devices should be set to AVCOL_PRI_UNSPECIFIED. See
2026  // https://developer.apple.com/av-foundation/High-Dynamic-Range-Metadata-for-Apple-Devices.pdf
2027  avio_wb16(pb, track->par->color_primaries);
2028  avio_wb16(pb, track->par->color_trc);
2029  avio_wb16(pb, track->par->color_space);
2030  if (track->mode == MODE_MP4) {
2031  int full_range = track->par->color_range == AVCOL_RANGE_JPEG;
2032  avio_w8(pb, full_range << 7);
2033  }
2034 
2035  return update_size(pb, pos);
2036 }
2037 
2038 static int mov_write_clli_tag(AVIOContext *pb, MOVTrack *track)
2039 {
2040  const uint8_t *side_data;
2041  const AVContentLightMetadata *content_light_metadata;
2042 
2044  if (!side_data) {
2045  return 0;
2046  }
2047  content_light_metadata = (const AVContentLightMetadata*)side_data;
2048 
2049  avio_wb32(pb, 12); // size
2050  ffio_wfourcc(pb, "clli");
2051  avio_wb16(pb, content_light_metadata->MaxCLL);
2052  avio_wb16(pb, content_light_metadata->MaxFALL);
2053  return 12;
2054 }
2055 
2056 static inline int64_t rescale_mdcv(AVRational q, int b)
2057 {
2058  return av_rescale(q.num, b, q.den);
2059 }
2060 
2061 static int mov_write_mdcv_tag(AVIOContext *pb, MOVTrack *track)
2062 {
2063  const int chroma_den = 50000;
2064  const int luma_den = 10000;
2065  const uint8_t *side_data;
2066  const AVMasteringDisplayMetadata *metadata;
2067 
2069  metadata = (const AVMasteringDisplayMetadata*)side_data;
2070  if (!metadata || !metadata->has_primaries || !metadata->has_luminance) {
2071  return 0;
2072  }
2073 
2074  avio_wb32(pb, 32); // size
2075  ffio_wfourcc(pb, "mdcv");
2076  avio_wb16(pb, rescale_mdcv(metadata->display_primaries[1][0], chroma_den));
2077  avio_wb16(pb, rescale_mdcv(metadata->display_primaries[1][1], chroma_den));
2078  avio_wb16(pb, rescale_mdcv(metadata->display_primaries[2][0], chroma_den));
2079  avio_wb16(pb, rescale_mdcv(metadata->display_primaries[2][1], chroma_den));
2080  avio_wb16(pb, rescale_mdcv(metadata->display_primaries[0][0], chroma_den));
2081  avio_wb16(pb, rescale_mdcv(metadata->display_primaries[0][1], chroma_den));
2082  avio_wb16(pb, rescale_mdcv(metadata->white_point[0], chroma_den));
2083  avio_wb16(pb, rescale_mdcv(metadata->white_point[1], chroma_den));
2084  avio_wb32(pb, rescale_mdcv(metadata->max_luminance, luma_den));
2085  avio_wb32(pb, rescale_mdcv(metadata->min_luminance, luma_den));
2086  return 32;
2087 }
2088 
2089 static void find_compressor(char * compressor_name, int len, MOVTrack *track)
2090 {
2091  AVDictionaryEntry *encoder;
2092  int xdcam_res = (track->par->width == 1280 && track->par->height == 720)
2093  || (track->par->width == 1440 && track->par->height == 1080)
2094  || (track->par->width == 1920 && track->par->height == 1080);
2095 
2096  if (track->mode == MODE_MOV &&
2097  (encoder = av_dict_get(track->st->metadata, "encoder", NULL, 0))) {
2098  av_strlcpy(compressor_name, encoder->value, 32);
2099  } else if (track->par->codec_id == AV_CODEC_ID_MPEG2VIDEO && xdcam_res) {
2101  AVStream *st = track->st;
2102  int rate = defined_frame_rate(NULL, st);
2103  av_strlcatf(compressor_name, len, "XDCAM");
2104  if (track->par->format == AV_PIX_FMT_YUV422P) {
2105  av_strlcatf(compressor_name, len, " HD422");
2106  } else if(track->par->width == 1440) {
2107  av_strlcatf(compressor_name, len, " HD");
2108  } else
2109  av_strlcatf(compressor_name, len, " EX");
2110 
2111  av_strlcatf(compressor_name, len, " %d%c", track->par->height, interlaced ? 'i' : 'p');
2112 
2113  av_strlcatf(compressor_name, len, "%d", rate * (interlaced + 1));
2114  }
2115 }
2116 
2118 {
2119  int ret = AVERROR_BUG;
2120  int64_t pos = avio_tell(pb);
2121  char compressor_name[32] = { 0 };
2122  int avid = 0;
2123 
2124  int uncompressed_ycbcr = ((track->par->codec_id == AV_CODEC_ID_RAWVIDEO && track->par->format == AV_PIX_FMT_UYVY422)
2125  || (track->par->codec_id == AV_CODEC_ID_RAWVIDEO && track->par->format == AV_PIX_FMT_YUYV422)
2126  || track->par->codec_id == AV_CODEC_ID_V308
2127  || track->par->codec_id == AV_CODEC_ID_V408
2128  || track->par->codec_id == AV_CODEC_ID_V410
2129  || track->par->codec_id == AV_CODEC_ID_V210);
2130 
2131  avio_wb32(pb, 0); /* size */
2132  if (mov->encryption_scheme != MOV_ENC_NONE) {
2133  ffio_wfourcc(pb, "encv");
2134  } else {
2135  avio_wl32(pb, track->tag); // store it byteswapped
2136  }
2137  avio_wb32(pb, 0); /* Reserved */
2138  avio_wb16(pb, 0); /* Reserved */
2139  avio_wb16(pb, 1); /* Data-reference index */
2140 
2141  if (uncompressed_ycbcr) {
2142  avio_wb16(pb, 2); /* Codec stream version */
2143  } else {
2144  avio_wb16(pb, 0); /* Codec stream version */
2145  }
2146  avio_wb16(pb, 0); /* Codec stream revision (=0) */
2147  if (track->mode == MODE_MOV) {
2148  ffio_wfourcc(pb, "FFMP"); /* Vendor */
2149  if (track->par->codec_id == AV_CODEC_ID_RAWVIDEO || uncompressed_ycbcr) {
2150  avio_wb32(pb, 0); /* Temporal Quality */
2151  avio_wb32(pb, 0x400); /* Spatial Quality = lossless*/
2152  } else {
2153  avio_wb32(pb, 0x200); /* Temporal Quality = normal */
2154  avio_wb32(pb, 0x200); /* Spatial Quality = normal */
2155  }
2156  } else {
2157  ffio_fill(pb, 0, 3 * 4); /* Reserved */
2158  }
2159  avio_wb16(pb, track->par->width); /* Video width */
2160  avio_wb16(pb, track->height); /* Video height */
2161  avio_wb32(pb, 0x00480000); /* Horizontal resolution 72dpi */
2162  avio_wb32(pb, 0x00480000); /* Vertical resolution 72dpi */
2163  avio_wb32(pb, 0); /* Data size (= 0) */
2164  avio_wb16(pb, 1); /* Frame count (= 1) */
2165 
2166  /* FIXME not sure, ISO 14496-1 draft where it shall be set to 0 */
2167  find_compressor(compressor_name, 32, track);
2168  avio_w8(pb, strlen(compressor_name));
2169  avio_write(pb, compressor_name, 31);
2170 
2171  if (track->mode == MODE_MOV &&
2172  (track->par->codec_id == AV_CODEC_ID_V410 || track->par->codec_id == AV_CODEC_ID_V210))
2173  avio_wb16(pb, 0x18);
2174  else if (track->mode == MODE_MOV && track->par->bits_per_coded_sample)
2175  avio_wb16(pb, track->par->bits_per_coded_sample |
2176  (track->par->format == AV_PIX_FMT_GRAY8 ? 0x20 : 0));
2177  else
2178  avio_wb16(pb, 0x18); /* Reserved */
2179 
2180  if (track->mode == MODE_MOV && track->par->format == AV_PIX_FMT_PAL8) {
2181  int pal_size, i;
2182  avio_wb16(pb, 0); /* Color table ID */
2183  avio_wb32(pb, 0); /* Color table seed */
2184  avio_wb16(pb, 0x8000); /* Color table flags */
2185  if (track->par->bits_per_coded_sample < 0 || track->par->bits_per_coded_sample > 8)
2186  return AVERROR(EINVAL);
2187  pal_size = 1 << track->par->bits_per_coded_sample;
2188  avio_wb16(pb, pal_size - 1); /* Color table size (zero-relative) */
2189  for (i = 0; i < pal_size; i++) {
2190  uint32_t rgb = track->palette[i];
2191  uint16_t r = (rgb >> 16) & 0xff;
2192  uint16_t g = (rgb >> 8) & 0xff;
2193  uint16_t b = rgb & 0xff;
2194  avio_wb16(pb, 0);
2195  avio_wb16(pb, (r << 8) | r);
2196  avio_wb16(pb, (g << 8) | g);
2197  avio_wb16(pb, (b << 8) | b);
2198  }
2199  } else
2200  avio_wb16(pb, 0xffff); /* Reserved */
2201 
2202  if (track->tag == MKTAG('m','p','4','v'))
2203  mov_write_esds_tag(pb, track);
2204  else if (track->par->codec_id == AV_CODEC_ID_H263)
2205  mov_write_d263_tag(pb);
2206  else if (track->par->codec_id == AV_CODEC_ID_AVUI ||
2207  track->par->codec_id == AV_CODEC_ID_SVQ3) {
2208  mov_write_extradata_tag(pb, track);
2209  avio_wb32(pb, 0);
2210  } else if (track->par->codec_id == AV_CODEC_ID_DNXHD) {
2211  mov_write_avid_tag(pb, track);
2212  avid = 1;
2213  } else if (track->par->codec_id == AV_CODEC_ID_HEVC)
2214  mov_write_hvcc_tag(pb, track);
2215  else if (track->par->codec_id == AV_CODEC_ID_H264 && !TAG_IS_AVCI(track->tag)) {
2216  mov_write_avcc_tag(pb, track);
2217  if (track->mode == MODE_IPOD)
2219  } else if (track->par->codec_id == AV_CODEC_ID_VP9) {
2220  mov_write_vpcc_tag(mov->fc, pb, track);
2221  } else if (track->par->codec_id == AV_CODEC_ID_AV1) {
2222  mov_write_av1c_tag(pb, track);
2223  } else if (track->par->codec_id == AV_CODEC_ID_VC1 && track->vos_len > 0)
2224  mov_write_dvc1_tag(pb, track);
2225  else if (track->par->codec_id == AV_CODEC_ID_VP6F ||
2226  track->par->codec_id == AV_CODEC_ID_VP6A) {
2227  /* Don't write any potential extradata here - the cropping
2228  * is signalled via the normal width/height fields. */
2229  } else if (track->par->codec_id == AV_CODEC_ID_R10K) {
2230  if (track->par->codec_tag == MKTAG('R','1','0','k'))
2231  mov_write_dpxe_tag(pb, track);
2232  } else if (track->vos_len > 0)
2233  mov_write_glbl_tag(pb, track);
2234 
2235  if (track->par->codec_id != AV_CODEC_ID_H264 &&
2236  track->par->codec_id != AV_CODEC_ID_MPEG4 &&
2237  track->par->codec_id != AV_CODEC_ID_DNXHD) {
2238  int field_order = track->par->field_order;
2239 
2240  if (field_order != AV_FIELD_UNKNOWN)
2241  mov_write_fiel_tag(pb, track, field_order);
2242  }
2243 
2244  if (mov->flags & FF_MOV_FLAG_WRITE_GAMA) {
2245  if (track->mode == MODE_MOV)
2246  mov_write_gama_tag(s, pb, track, mov->gamma);
2247  else
2248  av_log(mov->fc, AV_LOG_WARNING, "Not writing 'gama' atom. Format is not MOV.\n");
2249  }
2250  if (track->mode == MODE_MOV || track->mode == MODE_MP4) {
2251  int has_color_info = track->par->color_primaries != AVCOL_PRI_UNSPECIFIED &&
2252  track->par->color_trc != AVCOL_TRC_UNSPECIFIED &&
2254  if (has_color_info || mov->flags & FF_MOV_FLAG_WRITE_COLR ||
2256  int prefer_icc = mov->flags & FF_MOV_FLAG_PREFER_ICC || !has_color_info;
2257  mov_write_colr_tag(pb, track, prefer_icc);
2258  } else if (mov->flags & FF_MOV_FLAG_WRITE_COLR) {
2259  av_log(mov->fc, AV_LOG_WARNING, "Not writing 'colr' atom. Format is not MOV or MP4.\n");
2260  }
2261  }
2262  if (track->mode == MODE_MOV || track->mode == MODE_MP4) {
2263  mov_write_clli_tag(pb, track);
2264  mov_write_mdcv_tag(pb, track);
2265  }
2266 
2267  if (track->mode == MODE_MP4 && mov->fc->strict_std_compliance <= FF_COMPLIANCE_UNOFFICIAL) {
2272 
2273  if (stereo_3d)
2274  mov_write_st3d_tag(s, pb, stereo_3d);
2275  if (spherical_mapping)
2276  mov_write_sv3d_tag(mov->fc, pb, spherical_mapping);
2277  if (dovi)
2278  mov_write_dvcc_dvvc_tag(s, pb, dovi);
2279  }
2280 
2281  if (track->par->sample_aspect_ratio.den && track->par->sample_aspect_ratio.num) {
2282  mov_write_pasp_tag(pb, track);
2283  }
2284 
2285  if (uncompressed_ycbcr){
2286  mov_write_clap_tag(pb, track);
2287  }
2288 
2289  if (mov->encryption_scheme != MOV_ENC_NONE) {
2290  ff_mov_cenc_write_sinf_tag(track, pb, mov->encryption_kid);
2291  }
2292 
2293  if (track->mode == MODE_MP4 &&
2294  ((ret = mov_write_btrt_tag(pb, track)) < 0))
2295  return ret;
2296 
2297  /* extra padding for avid stsd */
2298  /* https://developer.apple.com/library/mac/documentation/QuickTime/QTFF/QTFFChap2/qtff2.html#//apple_ref/doc/uid/TP40000939-CH204-61112 */
2299  if (avid)
2300  avio_wb32(pb, 0);
2301 
2302  return update_size(pb, pos);
2303 }
2304 
2305 static int mov_write_rtp_tag(AVIOContext *pb, MOVTrack *track)
2306 {
2307  int64_t pos = avio_tell(pb);
2308  avio_wb32(pb, 0); /* size */
2309  ffio_wfourcc(pb, "rtp ");
2310  avio_wb32(pb, 0); /* Reserved */
2311  avio_wb16(pb, 0); /* Reserved */
2312  avio_wb16(pb, 1); /* Data-reference index */
2313 
2314  avio_wb16(pb, 1); /* Hint track version */
2315  avio_wb16(pb, 1); /* Highest compatible version */
2316  avio_wb32(pb, track->max_packet_size); /* Max packet size */
2317 
2318  avio_wb32(pb, 12); /* size */
2319  ffio_wfourcc(pb, "tims");
2320  avio_wb32(pb, track->timescale);
2321 
2322  return update_size(pb, pos);
2323 }
2324 
2325 static int mov_write_source_reference_tag(AVIOContext *pb, MOVTrack *track, const char *reel_name)
2326 {
2327  uint64_t str_size =strlen(reel_name);
2328  int64_t pos = avio_tell(pb);
2329 
2330  if (str_size >= UINT16_MAX){
2331  av_log(NULL, AV_LOG_ERROR, "reel_name length %"PRIu64" is too large\n", str_size);
2332  avio_wb16(pb, 0);
2333  return AVERROR(EINVAL);
2334  }
2335 
2336  avio_wb32(pb, 0); /* size */
2337  ffio_wfourcc(pb, "name"); /* Data format */
2338  avio_wb16(pb, str_size); /* string size */
2339  avio_wb16(pb, track->language); /* langcode */
2340  avio_write(pb, reel_name, str_size); /* reel name */
2341  return update_size(pb,pos);
2342 }
2343 
2344 static int mov_write_tmcd_tag(AVIOContext *pb, MOVTrack *track)
2345 {
2346  int64_t pos = avio_tell(pb);
2347 #if 1
2348  int frame_duration;
2349  int nb_frames;
2350  AVDictionaryEntry *t = NULL;
2351 
2352  if (!track->st->avg_frame_rate.num || !track->st->avg_frame_rate.den) {
2353  av_log(NULL, AV_LOG_ERROR, "avg_frame_rate not set for tmcd track.\n");
2354  return AVERROR(EINVAL);
2355  } else {
2356  frame_duration = av_rescale(track->timescale, track->st->avg_frame_rate.den, track->st->avg_frame_rate.num);
2357  nb_frames = ROUNDED_DIV(track->st->avg_frame_rate.num, track->st->avg_frame_rate.den);
2358  }
2359 
2360  if (nb_frames > 255) {
2361  av_log(NULL, AV_LOG_ERROR, "fps %d is too large\n", nb_frames);
2362  return AVERROR(EINVAL);
2363  }
2364 
2365  avio_wb32(pb, 0); /* size */
2366  ffio_wfourcc(pb, "tmcd"); /* Data format */
2367  avio_wb32(pb, 0); /* Reserved */
2368  avio_wb32(pb, 1); /* Data reference index */
2369  avio_wb32(pb, 0); /* Flags */
2370  avio_wb32(pb, track->timecode_flags); /* Flags (timecode) */
2371  avio_wb32(pb, track->timescale); /* Timescale */
2372  avio_wb32(pb, frame_duration); /* Frame duration */
2373  avio_w8(pb, nb_frames); /* Number of frames */
2374  avio_w8(pb, 0); /* Reserved */
2375 
2376  t = av_dict_get(track->st->metadata, "reel_name", NULL, 0);
2377  if (t && utf8len(t->value) && track->mode != MODE_MP4)
2378  mov_write_source_reference_tag(pb, track, t->value);
2379  else
2380  avio_wb16(pb, 0); /* zero size */
2381 #else
2382 
2383  avio_wb32(pb, 0); /* size */
2384  ffio_wfourcc(pb, "tmcd"); /* Data format */
2385  avio_wb32(pb, 0); /* Reserved */
2386  avio_wb32(pb, 1); /* Data reference index */
2387  if (track->par->extradata_size)
2388  avio_write(pb, track->par->extradata, track->par->extradata_size);
2389 #endif
2390  return update_size(pb, pos);
2391 }
2392 
2393 static int mov_write_gpmd_tag(AVIOContext *pb, const MOVTrack *track)
2394 {
2395  int64_t pos = avio_tell(pb);
2396  avio_wb32(pb, 0); /* size */
2397  ffio_wfourcc(pb, "gpmd");
2398  avio_wb32(pb, 0); /* Reserved */
2399  avio_wb16(pb, 0); /* Reserved */
2400  avio_wb16(pb, 1); /* Data-reference index */
2401  avio_wb32(pb, 0); /* Reserved */
2402  return update_size(pb, pos);
2403 }
2404 
2406 {
2407  int64_t pos = avio_tell(pb);
2408  int ret = 0;
2409  avio_wb32(pb, 0); /* size */
2410  ffio_wfourcc(pb, "stsd");
2411  avio_wb32(pb, 0); /* version & flags */
2412  avio_wb32(pb, 1); /* entry count */
2413  if (track->par->codec_type == AVMEDIA_TYPE_VIDEO)
2414  ret = mov_write_video_tag(s, pb, mov, track);
2415  else if (track->par->codec_type == AVMEDIA_TYPE_AUDIO)
2416  ret = mov_write_audio_tag(s, pb, mov, track);
2417  else if (track->par->codec_type == AVMEDIA_TYPE_SUBTITLE)
2418  ret = mov_write_subtitle_tag(pb, track);
2419  else if (track->par->codec_tag == MKTAG('r','t','p',' '))
2420  ret = mov_write_rtp_tag(pb, track);
2421  else if (track->par->codec_tag == MKTAG('t','m','c','d'))
2422  ret = mov_write_tmcd_tag(pb, track);
2423  else if (track->par->codec_tag == MKTAG('g','p','m','d'))
2424  ret = mov_write_gpmd_tag(pb, track);
2425 
2426  if (ret < 0)
2427  return ret;
2428 
2429  return update_size(pb, pos);
2430 }
2431 
2433 {
2434  MOVMuxContext *mov = s->priv_data;
2435  MOVStts *ctts_entries;
2436  uint32_t entries = 0;
2437  uint32_t atom_size;
2438  int i;
2439 
2440  ctts_entries = av_malloc_array((track->entry + 1), sizeof(*ctts_entries)); /* worst case */
2441  if (!ctts_entries)
2442  return AVERROR(ENOMEM);
2443  ctts_entries[0].count = 1;
2444  ctts_entries[0].duration = track->cluster[0].cts;
2445  for (i = 1; i < track->entry; i++) {
2446  if (track->cluster[i].cts == ctts_entries[entries].duration) {
2447  ctts_entries[entries].count++; /* compress */
2448  } else {
2449  entries++;
2450  ctts_entries[entries].duration = track->cluster[i].cts;
2451  ctts_entries[entries].count = 1;
2452  }
2453  }
2454  entries++; /* last one */
2455  atom_size = 16 + (entries * 8);
2456  avio_wb32(pb, atom_size); /* size */
2457  ffio_wfourcc(pb, "ctts");
2459  avio_w8(pb, 1); /* version */
2460  else
2461  avio_w8(pb, 0); /* version */
2462  avio_wb24(pb, 0); /* flags */
2463  avio_wb32(pb, entries); /* entry count */
2464  for (i = 0; i < entries; i++) {
2465  avio_wb32(pb, ctts_entries[i].count);
2466  avio_wb32(pb, ctts_entries[i].duration);
2467  }
2468  av_free(ctts_entries);
2469  return atom_size;
2470 }
2471 
2472 /* Time to sample atom */
2473 static int mov_write_stts_tag(AVIOContext *pb, MOVTrack *track)
2474 {
2475  MOVStts *stts_entries = NULL;
2476  uint32_t entries = -1;
2477  uint32_t atom_size;
2478  int i;
2479 
2480  if (track->par->codec_type == AVMEDIA_TYPE_AUDIO && !track->audio_vbr) {
2481  stts_entries = av_malloc(sizeof(*stts_entries)); /* one entry */
2482  if (!stts_entries)
2483  return AVERROR(ENOMEM);
2484  stts_entries[0].count = track->sample_count;
2485  stts_entries[0].duration = 1;
2486  entries = 1;
2487  } else {
2488  if (track->entry) {
2489  stts_entries = av_malloc_array(track->entry, sizeof(*stts_entries)); /* worst case */
2490  if (!stts_entries)
2491  return AVERROR(ENOMEM);
2492  }
2493  for (i = 0; i < track->entry; i++) {
2494  int duration = get_cluster_duration(track, i);
2495  if (i && duration == stts_entries[entries].duration) {
2496  stts_entries[entries].count++; /* compress */
2497  } else {
2498  entries++;
2499  stts_entries[entries].duration = duration;
2500  stts_entries[entries].count = 1;
2501  }
2502  }
2503  entries++; /* last one */
2504  }
2505  atom_size = 16 + (entries * 8);
2506  avio_wb32(pb, atom_size); /* size */
2507  ffio_wfourcc(pb, "stts");
2508  avio_wb32(pb, 0); /* version & flags */
2509  avio_wb32(pb, entries); /* entry count */
2510  for (i = 0; i < entries; i++) {
2511  avio_wb32(pb, stts_entries[i].count);
2512  avio_wb32(pb, stts_entries[i].duration);
2513  }
2514  av_free(stts_entries);
2515  return atom_size;
2516 }
2517 
2519 {
2520  avio_wb32(pb, 28); /* size */
2521  ffio_wfourcc(pb, "dref");
2522  avio_wb32(pb, 0); /* version & flags */
2523  avio_wb32(pb, 1); /* entry count */
2524 
2525  avio_wb32(pb, 0xc); /* size */
2526  //FIXME add the alis and rsrc atom
2527  ffio_wfourcc(pb, "url ");
2528  avio_wb32(pb, 1); /* version & flags */
2529 
2530  return 28;
2531 }
2532 
2534 {
2535  struct sgpd_entry {
2536  int count;
2537  int16_t roll_distance;
2538  int group_description_index;
2539  };
2540 
2541  struct sgpd_entry *sgpd_entries = NULL;
2542  int entries = -1;
2543  int group = 0;
2544  int i, j;
2545 
2546  const int OPUS_SEEK_PREROLL_MS = 80;
2547  int roll_samples = av_rescale_q(OPUS_SEEK_PREROLL_MS,
2548  (AVRational){1, 1000},
2549  (AVRational){1, 48000});
2550 
2551  if (!track->entry)
2552  return 0;
2553 
2554  sgpd_entries = av_malloc_array(track->entry, sizeof(*sgpd_entries));
2555  if (!sgpd_entries)
2556  return AVERROR(ENOMEM);
2557 
2559 
2560  if (track->par->codec_id == AV_CODEC_ID_OPUS) {
2561  for (i = 0; i < track->entry; i++) {
2562  int roll_samples_remaining = roll_samples;
2563  int distance = 0;
2564  for (j = i - 1; j >= 0; j--) {
2565  roll_samples_remaining -= get_cluster_duration(track, j);
2566  distance++;
2567  if (roll_samples_remaining <= 0)
2568  break;
2569  }
2570  /* We don't have enough preceeding samples to compute a valid
2571  roll_distance here, so this sample can't be independently
2572  decoded. */
2573  if (roll_samples_remaining > 0)
2574  distance = 0;
2575  /* Verify distance is a maximum of 32 (2.5ms) packets. */
2576  if (distance > 32)
2577  return AVERROR_INVALIDDATA;
2578  if (i && distance == sgpd_entries[entries].roll_distance) {
2579  sgpd_entries[entries].count++;
2580  } else {
2581  entries++;
2582  sgpd_entries[entries].count = 1;
2583  sgpd_entries[entries].roll_distance = distance;
2584  sgpd_entries[entries].group_description_index = distance ? ++group : 0;
2585  }
2586  }
2587  } else {
2588  entries++;
2589  sgpd_entries[entries].count = track->sample_count;
2590  sgpd_entries[entries].roll_distance = 1;
2591  sgpd_entries[entries].group_description_index = ++group;
2592  }
2593  entries++;
2594 
2595  if (!group) {
2596  av_free(sgpd_entries);
2597  return 0;
2598  }
2599 
2600  /* Write sgpd tag */
2601  avio_wb32(pb, 24 + (group * 2)); /* size */
2602  ffio_wfourcc(pb, "sgpd");
2603  avio_wb32(pb, 1 << 24); /* fullbox */
2604  ffio_wfourcc(pb, "roll");
2605  avio_wb32(pb, 2); /* default_length */
2606  avio_wb32(pb, group); /* entry_count */
2607  for (i = 0; i < entries; i++) {
2608  if (sgpd_entries[i].group_description_index) {
2609  avio_wb16(pb, -sgpd_entries[i].roll_distance); /* roll_distance */
2610  }
2611  }
2612 
2613  /* Write sbgp tag */
2614  avio_wb32(pb, 20 + (entries * 8)); /* size */
2615  ffio_wfourcc(pb, "sbgp");
2616  avio_wb32(pb, 0); /* fullbox */
2617  ffio_wfourcc(pb, "roll");
2618  avio_wb32(pb, entries); /* entry_count */
2619  for (i = 0; i < entries; i++) {
2620  avio_wb32(pb, sgpd_entries[i].count); /* sample_count */
2621  avio_wb32(pb, sgpd_entries[i].group_description_index); /* group_description_index */
2622  }
2623 
2624  av_free(sgpd_entries);
2625  return 0;
2626 }
2627 
2629 {
2630  int64_t pos = avio_tell(pb);
2631  int ret = 0;
2632 
2633  avio_wb32(pb, 0); /* size */
2634  ffio_wfourcc(pb, "stbl");
2635  if ((ret = mov_write_stsd_tag(s, pb, mov, track)) < 0)
2636  return ret;
2637  mov_write_stts_tag(pb, track);
2638  if ((track->par->codec_type == AVMEDIA_TYPE_VIDEO ||
2639  track->par->codec_id == AV_CODEC_ID_TRUEHD ||
2641  track->par->codec_tag == MKTAG('r','t','p',' ')) &&
2642  track->has_keyframes && track->has_keyframes < track->entry)
2643  mov_write_stss_tag(pb, track, MOV_SYNC_SAMPLE);
2644  if (track->par->codec_type == AVMEDIA_TYPE_VIDEO && track->has_disposable)
2645  mov_write_sdtp_tag(pb, track);
2646  if (track->mode == MODE_MOV && track->flags & MOV_TRACK_STPS)
2648  if (track->par->codec_type == AVMEDIA_TYPE_VIDEO &&
2649  track->flags & MOV_TRACK_CTTS && track->entry) {
2650 
2651  if ((ret = mov_write_ctts_tag(s, pb, track)) < 0)
2652  return ret;
2653  }
2654  mov_write_stsc_tag(pb, track);
2655  mov_write_stsz_tag(pb, track);
2656  mov_write_stco_tag(pb, track);
2657  if (track->cenc.aes_ctr) {
2658  ff_mov_cenc_write_stbl_atoms(&track->cenc, pb);
2659  }
2660  if (track->par->codec_id == AV_CODEC_ID_OPUS || track->par->codec_id == AV_CODEC_ID_AAC) {
2661  mov_preroll_write_stbl_atoms(pb, track);
2662  }
2663  return update_size(pb, pos);
2664 }
2665 
2667 {
2668  int64_t pos = avio_tell(pb);
2669  avio_wb32(pb, 0); /* size */
2670  ffio_wfourcc(pb, "dinf");
2671  mov_write_dref_tag(pb);
2672  return update_size(pb, pos);
2673 }
2674 
2676 {
2677  avio_wb32(pb, 12);
2678  ffio_wfourcc(pb, "nmhd");
2679  avio_wb32(pb, 0);
2680  return 12;
2681 }
2682 
2684 {
2685  avio_wb32(pb, 12);
2686  ffio_wfourcc(pb, "sthd");
2687  avio_wb32(pb, 0);
2688  return 12;
2689 }
2690 
2691 static int mov_write_tcmi_tag(AVIOContext *pb, MOVTrack *track)
2692 {
2693  int64_t pos = avio_tell(pb);
2694  const char *font = "Lucida Grande";
2695  avio_wb32(pb, 0); /* size */
2696  ffio_wfourcc(pb, "tcmi"); /* timecode media information atom */
2697  avio_wb32(pb, 0); /* version & flags */
2698  avio_wb16(pb, 0); /* text font */
2699  avio_wb16(pb, 0); /* text face */
2700  avio_wb16(pb, 12); /* text size */
2701  avio_wb16(pb, 0); /* (unknown, not in the QT specs...) */
2702  avio_wb16(pb, 0x0000); /* text color (red) */
2703  avio_wb16(pb, 0x0000); /* text color (green) */
2704  avio_wb16(pb, 0x0000); /* text color (blue) */
2705  avio_wb16(pb, 0xffff); /* background color (red) */
2706  avio_wb16(pb, 0xffff); /* background color (green) */
2707  avio_wb16(pb, 0xffff); /* background color (blue) */
2708  avio_w8(pb, strlen(font)); /* font len (part of the pascal string) */
2709  avio_write(pb, font, strlen(font)); /* font name */
2710  return update_size(pb, pos);
2711 }
2712 
2713 static int mov_write_gmhd_tag(AVIOContext *pb, MOVTrack *track)
2714 {
2715  int64_t pos = avio_tell(pb);
2716  avio_wb32(pb, 0); /* size */
2717  ffio_wfourcc(pb, "gmhd");
2718  avio_wb32(pb, 0x18); /* gmin size */
2719  ffio_wfourcc(pb, "gmin");/* generic media info */
2720  avio_wb32(pb, 0); /* version & flags */
2721  avio_wb16(pb, 0x40); /* graphics mode = */
2722  avio_wb16(pb, 0x8000); /* opColor (r?) */
2723  avio_wb16(pb, 0x8000); /* opColor (g?) */
2724  avio_wb16(pb, 0x8000); /* opColor (b?) */
2725  avio_wb16(pb, 0); /* balance */
2726  avio_wb16(pb, 0); /* reserved */
2727 
2728  /*
2729  * This special text atom is required for
2730  * Apple Quicktime chapters. The contents
2731  * don't appear to be documented, so the
2732  * bytes are copied verbatim.
2733  */
2734  if (track->tag != MKTAG('c','6','0','8')) {
2735  avio_wb32(pb, 0x2C); /* size */
2736  ffio_wfourcc(pb, "text");
2737  avio_wb16(pb, 0x01);
2738  avio_wb32(pb, 0x00);
2739  avio_wb32(pb, 0x00);
2740  avio_wb32(pb, 0x00);
2741  avio_wb32(pb, 0x01);
2742  avio_wb32(pb, 0x00);
2743  avio_wb32(pb, 0x00);
2744  avio_wb32(pb, 0x00);
2745  avio_wb32(pb, 0x00004000);
2746  avio_wb16(pb, 0x0000);
2747  }
2748 
2749  if (track->par->codec_tag == MKTAG('t','m','c','d')) {
2750  int64_t tmcd_pos = avio_tell(pb);
2751  avio_wb32(pb, 0); /* size */
2752  ffio_wfourcc(pb, "tmcd");
2753  mov_write_tcmi_tag(pb, track);
2754  update_size(pb, tmcd_pos);
2755  } else if (track->par->codec_tag == MKTAG('g','p','m','d')) {
2756  int64_t gpmd_pos = avio_tell(pb);
2757  avio_wb32(pb, 0); /* size */
2758  ffio_wfourcc(pb, "gpmd");
2759  avio_wb32(pb, 0); /* version */
2760  update_size(pb, gpmd_pos);
2761  }
2762  return update_size(pb, pos);
2763 }
2764 
2766 {
2767  avio_wb32(pb, 16); /* size */
2768  ffio_wfourcc(pb, "smhd");
2769  avio_wb32(pb, 0); /* version & flags */
2770  avio_wb16(pb, 0); /* reserved (balance, normally = 0) */
2771  avio_wb16(pb, 0); /* reserved */
2772  return 16;
2773 }
2774 
2776 {
2777  avio_wb32(pb, 0x14); /* size (always 0x14) */
2778  ffio_wfourcc(pb, "vmhd");
2779  avio_wb32(pb, 0x01); /* version & flags */
2780  avio_wb64(pb, 0); /* reserved (graphics mode = copy) */
2781  return 0x14;
2782 }
2783 
2784 static int is_clcp_track(MOVTrack *track)
2785 {
2786  return track->tag == MKTAG('c','7','0','8') ||
2787  track->tag == MKTAG('c','6','0','8');
2788 }
2789 
2791 {
2792  MOVMuxContext *mov = s->priv_data;
2793  const char *hdlr, *descr = NULL, *hdlr_type = NULL;
2794  int64_t pos = avio_tell(pb);
2795  size_t descr_len;
2796 
2797  hdlr = "dhlr";
2798  hdlr_type = "url ";
2799  descr = "DataHandler";
2800 
2801  if (track) {
2802  hdlr = (track->mode == MODE_MOV) ? "mhlr" : "\0\0\0\0";
2803  if (track->par->codec_type == AVMEDIA_TYPE_VIDEO) {
2804  hdlr_type = "vide";
2805  descr = "VideoHandler";
2806  } else if (track->par->codec_type == AVMEDIA_TYPE_AUDIO) {
2807  hdlr_type = "soun";
2808  descr = "SoundHandler";
2809  } else if (track->par->codec_type == AVMEDIA_TYPE_SUBTITLE) {
2810  if (is_clcp_track(track)) {
2811  hdlr_type = "clcp";
2812  descr = "ClosedCaptionHandler";
2813  } else {
2814  if (track->tag == MKTAG('t','x','3','g')) {
2815  hdlr_type = "sbtl";
2816  } else if (track->tag == MKTAG('m','p','4','s')) {
2817  hdlr_type = "subp";
2818  } else if (track->tag == MOV_MP4_TTML_TAG) {
2819  hdlr_type = "subt";
2820  } else {
2821  hdlr_type = "text";
2822  }
2823  descr = "SubtitleHandler";
2824  }
2825  } else if (track->par->codec_tag == MKTAG('r','t','p',' ')) {
2826  hdlr_type = "hint";
2827  descr = "HintHandler";
2828  } else if (track->par->codec_tag == MKTAG('t','m','c','d')) {
2829  hdlr_type = "tmcd";
2830  descr = "TimeCodeHandler";
2831  } else if (track->par->codec_tag == MKTAG('g','p','m','d')) {
2832  hdlr_type = "meta";
2833  descr = "GoPro MET"; // GoPro Metadata
2834  } else {
2836  "Unknown hdlr_type for %s, writing dummy values\n",
2837  av_fourcc2str(track->par->codec_tag));
2838  }
2839  if (track->st) {
2840  // hdlr.name is used by some players to identify the content title
2841  // of the track. So if an alternate handler description is
2842  // specified, use it.
2843  AVDictionaryEntry *t;
2844  t = av_dict_get(track->st->metadata, "handler_name", NULL, 0);
2845  if (t && utf8len(t->value))
2846  descr = t->value;
2847  }
2848  }
2849 
2850  if (mov->empty_hdlr_name) /* expressly allowed by QTFF and not prohibited in ISO 14496-12 8.4.3.3 */
2851  descr = "";
2852 
2853  avio_wb32(pb, 0); /* size */
2854  ffio_wfourcc(pb, "hdlr");
2855  avio_wb32(pb, 0); /* Version & flags */
2856  avio_write(pb, hdlr, 4); /* handler */
2857  ffio_wfourcc(pb, hdlr_type); /* handler type */
2858  avio_wb32(pb, 0); /* reserved */
2859  avio_wb32(pb, 0); /* reserved */
2860  avio_wb32(pb, 0); /* reserved */
2861  descr_len = strlen(descr);
2862  if (!track || track->mode == MODE_MOV)
2863  avio_w8(pb, descr_len); /* pascal string */
2864  avio_write(pb, descr, descr_len); /* handler description */
2865  if (track && track->mode != MODE_MOV)
2866  avio_w8(pb, 0); /* c string */
2867  return update_size(pb, pos);
2868 }
2869 
2871 {
2872  /* This atom must be present, but leaving the values at zero
2873  * seems harmless. */
2874  avio_wb32(pb, 28); /* size */
2875  ffio_wfourcc(pb, "hmhd");
2876  avio_wb32(pb, 0); /* version, flags */
2877  avio_wb16(pb, 0); /* maxPDUsize */
2878  avio_wb16(pb, 0); /* avgPDUsize */
2879  avio_wb32(pb, 0); /* maxbitrate */
2880  avio_wb32(pb, 0); /* avgbitrate */
2881  avio_wb32(pb, 0); /* reserved */
2882  return 28;
2883 }
2884 
2886 {
2887  int64_t pos = avio_tell(pb);
2888  int ret;
2889 
2890  avio_wb32(pb, 0); /* size */
2891  ffio_wfourcc(pb, "minf");
2892  if (track->par->codec_type == AVMEDIA_TYPE_VIDEO)
2893  mov_write_vmhd_tag(pb);
2894  else if (track->par->codec_type == AVMEDIA_TYPE_AUDIO)
2895  mov_write_smhd_tag(pb);
2896  else if (track->par->codec_type == AVMEDIA_TYPE_SUBTITLE) {
2897  if (track->tag == MKTAG('t','e','x','t') || is_clcp_track(track)) {
2898  mov_write_gmhd_tag(pb, track);
2899  } else if (track->tag == MOV_MP4_TTML_TAG) {
2900  mov_write_sthd_tag(pb);
2901  } else {
2902  mov_write_nmhd_tag(pb);
2903  }
2904  } else if (track->tag == MKTAG('r','t','p',' ')) {
2905  mov_write_hmhd_tag(pb);
2906  } else if (track->tag == MKTAG('t','m','c','d')) {
2907  if (track->mode != MODE_MOV)
2908  mov_write_nmhd_tag(pb);
2909  else
2910  mov_write_gmhd_tag(pb, track);
2911  } else if (track->tag == MKTAG('g','p','m','d')) {
2912  mov_write_gmhd_tag(pb, track);
2913  }
2914  if (track->mode == MODE_MOV) /* ISO 14496-12 8.4.3.1 specifies hdlr only within mdia or meta boxes */
2915  mov_write_hdlr_tag(s, pb, NULL);
2916  mov_write_dinf_tag(pb);
2917  if ((ret = mov_write_stbl_tag(s, pb, mov, track)) < 0)
2918  return ret;
2919  return update_size(pb, pos);
2920 }
2921 
2922 static void get_pts_range(MOVMuxContext *mov, MOVTrack *track,
2923  int64_t *start, int64_t *end)
2924 {
2925  if (track->tag == MKTAG('t','m','c','d') && mov->nb_meta_tmcd) {
2926  // tmcd tracks gets track_duration set in mov_write_moov_tag from
2927  // another track's duration, while the end_pts may be left at zero.
2928  // Calculate the pts duration for that track instead.
2929  get_pts_range(mov, &mov->tracks[track->src_track], start, end);
2930  *start = av_rescale(*start, track->timescale,
2931  mov->tracks[track->src_track].timescale);
2932  *end = av_rescale(*end, track->timescale,
2933  mov->tracks[track->src_track].timescale);
2934  return;
2935  }
2936  if (track->end_pts != AV_NOPTS_VALUE &&
2937  track->start_dts != AV_NOPTS_VALUE &&
2938  track->start_cts != AV_NOPTS_VALUE) {
2939  *start = track->start_dts + track->start_cts;
2940  *end = track->end_pts;
2941  return;
2942  }
2943  *start = 0;
2944  *end = track->track_duration;
2945 }
2946 
2948 {
2949  int64_t start, end;
2950  get_pts_range(mov, track, &start, &end);
2951  return end - start;
2952 }
2953 
2954 // Calculate the actual duration of the track, after edits.
2955 // If it starts with a pts < 0, that is removed by the edit list.
2956 // If it starts with a pts > 0, the edit list adds a delay before that.
2957 // Thus, with edit lists enabled, the post-edit output of the file is
2958 // starting with pts=0.
2959 static int64_t calc_pts_duration(MOVMuxContext *mov, MOVTrack *track)
2960 {
2961  int64_t start, end;
2962  get_pts_range(mov, track, &start, &end);
2963  if (mov->use_editlist != 0)
2964  start = 0;
2965  return end - start;
2966 }
2967 
2969  MOVTrack *track)
2970 {
2971  int64_t duration = calc_pts_duration(mov, track);
2972  int version = duration < INT32_MAX ? 0 : 1;
2973 
2974  if (track->mode == MODE_ISM)
2975  version = 1;
2976 
2977  (version == 1) ? avio_wb32(pb, 44) : avio_wb32(pb, 32); /* size */
2978  ffio_wfourcc(pb, "mdhd");
2979  avio_w8(pb, version);
2980  avio_wb24(pb, 0); /* flags */
2981  if (version == 1) {
2982  avio_wb64(pb, track->time);
2983  avio_wb64(pb, track->time);
2984  } else {
2985  avio_wb32(pb, track->time); /* creation time */
2986  avio_wb32(pb, track->time); /* modification time */
2987  }
2988  avio_wb32(pb, track->timescale); /* time scale (sample rate for audio) */
2989  if (!track->entry && mov->mode == MODE_ISM)
2990  (version == 1) ? avio_wb64(pb, UINT64_C(0xffffffffffffffff)) : avio_wb32(pb, 0xffffffff);
2991  else if (!track->entry)
2992  (version == 1) ? avio_wb64(pb, 0) : avio_wb32(pb, 0);
2993  else
2994  (version == 1) ? avio_wb64(pb, duration) : avio_wb32(pb, duration); /* duration */
2995  avio_wb16(pb, track->language); /* language */
2996  avio_wb16(pb, 0); /* reserved (quality) */
2997 
2998  if (version != 0 && track->mode == MODE_MOV) {
3000  "FATAL error, file duration too long for timebase, this file will not be\n"
3001  "playable with QuickTime. Choose a different timebase with "
3002  "-video_track_timescale or a different container format\n");
3003  }
3004 
3005  return 32;
3006 }
3007 
3009  MOVMuxContext *mov, MOVTrack *track)
3010 {
3011  int64_t pos = avio_tell(pb);
3012  int ret;
3013 
3014  avio_wb32(pb, 0); /* size */
3015  ffio_wfourcc(pb, "mdia");
3016  mov_write_mdhd_tag(pb, mov, track);
3017  mov_write_hdlr_tag(s, pb, track);
3018  if ((ret = mov_write_minf_tag(s, pb, mov, track)) < 0)
3019  return ret;
3020  return update_size(pb, pos);
3021 }
3022 
3023 /* transformation matrix
3024  |a b u|
3025  |c d v|
3026  |tx ty w| */
3027 static void write_matrix(AVIOContext *pb, int16_t a, int16_t b, int16_t c,
3028  int16_t d, int16_t tx, int16_t ty)
3029 {
3030  avio_wb32(pb, a << 16); /* 16.16 format */
3031  avio_wb32(pb, b << 16); /* 16.16 format */
3032  avio_wb32(pb, 0); /* u in 2.30 format */
3033  avio_wb32(pb, c << 16); /* 16.16 format */
3034  avio_wb32(pb, d << 16); /* 16.16 format */
3035  avio_wb32(pb, 0); /* v in 2.30 format */
3036  avio_wb32(pb, tx << 16); /* 16.16 format */
3037  avio_wb32(pb, ty << 16); /* 16.16 format */
3038  avio_wb32(pb, 1 << 30); /* w in 2.30 format */
3039 }
3040 
3042  MOVTrack *track, AVStream *st)
3043 {
3044  int64_t duration = av_rescale_rnd(calc_pts_duration(mov, track),
3045  mov->movie_timescale, track->timescale,
3046  AV_ROUND_UP);
3047  int version = duration < INT32_MAX ? 0 : 1;
3049  int group = 0;
3050 
3051  uint32_t *display_matrix = NULL;
3052  size_t display_matrix_size;
3053  int i;
3054 
3055  if (st) {
3056  if (mov->per_stream_grouping)
3057  group = st->index;
3058  else
3059  group = st->codecpar->codec_type;
3060 
3061  display_matrix = (uint32_t*)av_stream_get_side_data(st, AV_PKT_DATA_DISPLAYMATRIX,
3062  &display_matrix_size);
3063  if (display_matrix && display_matrix_size < 9 * sizeof(*display_matrix))
3064  display_matrix = NULL;
3065  }
3066 
3067  if (track->flags & MOV_TRACK_ENABLED)
3069 
3070  if (track->mode == MODE_ISM)
3071  version = 1;
3072 
3073  (version == 1) ? avio_wb32(pb, 104) : avio_wb32(pb, 92); /* size */
3074  ffio_wfourcc(pb, "tkhd");
3075  avio_w8(pb, version);
3076  avio_wb24(pb, flags);
3077  if (version == 1) {
3078  avio_wb64(pb, track->time);
3079  avio_wb64(pb, track->time);
3080  } else {
3081  avio_wb32(pb, track->time); /* creation time */
3082  avio_wb32(pb, track->time); /* modification time */
3083  }
3084  avio_wb32(pb, track->track_id); /* track-id */
3085  avio_wb32(pb, 0); /* reserved */
3086  if (!track->entry && mov->mode == MODE_ISM)
3087  (version == 1) ? avio_wb64(pb, UINT64_C(0xffffffffffffffff)) : avio_wb32(pb, 0xffffffff);
3088  else if (!track->entry)
3089  (version == 1) ? avio_wb64(pb, 0) : avio_wb32(pb, 0);
3090  else
3091  (version == 1) ? avio_wb64(pb, duration) : avio_wb32(pb, duration);
3092 
3093  avio_wb32(pb, 0); /* reserved */
3094  avio_wb32(pb, 0); /* reserved */
3095  avio_wb16(pb, 0); /* layer */
3096  avio_wb16(pb, group); /* alternate group) */
3097  /* Volume, only for audio */
3098  if (track->par->codec_type == AVMEDIA_TYPE_AUDIO)
3099  avio_wb16(pb, 0x0100);
3100  else
3101  avio_wb16(pb, 0);
3102  avio_wb16(pb, 0); /* reserved */
3103 
3104  /* Matrix structure */
3105  if (display_matrix) {
3106  for (i = 0; i < 9; i++)
3107  avio_wb32(pb, display_matrix[i]);
3108  } else {
3109  write_matrix(pb, 1, 0, 0, 1, 0, 0);
3110  }
3111  /* Track width and height, for visual only */
3112  if (st && (track->par->codec_type == AVMEDIA_TYPE_VIDEO ||
3113  track->par->codec_type == AVMEDIA_TYPE_SUBTITLE)) {
3114  int64_t track_width_1616;
3115  if (track->mode == MODE_MOV) {
3116  track_width_1616 = track->par->width * 0x10000ULL;
3117  } else {
3118  track_width_1616 = av_rescale(st->sample_aspect_ratio.num,
3119  track->par->width * 0x10000LL,
3120  st->sample_aspect_ratio.den);
3121  if (!track_width_1616 ||
3122  track->height != track->par->height ||
3123  track_width_1616 > UINT32_MAX)
3124  track_width_1616 = track->par->width * 0x10000ULL;
3125  }
3126  if (track_width_1616 > UINT32_MAX) {
3127  av_log(mov->fc, AV_LOG_WARNING, "track width is too large\n");
3128  track_width_1616 = 0;
3129  }
3130  avio_wb32(pb, track_width_1616);
3131  if (track->height > 0xFFFF) {
3132  av_log(mov->fc, AV_LOG_WARNING, "track height is too large\n");
3133  avio_wb32(pb, 0);
3134  } else
3135  avio_wb32(pb, track->height * 0x10000U);
3136  } else {
3137  avio_wb32(pb, 0);
3138  avio_wb32(pb, 0);
3139  }
3140  return 0x5c;
3141 }
3142 
3143 static int mov_write_tapt_tag(AVIOContext *pb, MOVTrack *track)
3144 {
3146  track->par->sample_aspect_ratio.den);
3147 
3148  int64_t pos = avio_tell(pb);
3149 
3150  avio_wb32(pb, 0); /* size */
3151  ffio_wfourcc(pb, "tapt");
3152 
3153  avio_wb32(pb, 20);
3154  ffio_wfourcc(pb, "clef");
3155  avio_wb32(pb, 0);
3156  avio_wb32(pb, width << 16);
3157  avio_wb32(pb, track->par->height << 16);
3158 
3159  avio_wb32(pb, 20);
3160  ffio_wfourcc(pb, "prof");
3161  avio_wb32(pb, 0);
3162  avio_wb32(pb, width << 16);
3163  avio_wb32(pb, track->par->height << 16);
3164 
3165  avio_wb32(pb, 20);
3166  ffio_wfourcc(pb, "enof");
3167  avio_wb32(pb, 0);
3168  avio_wb32(pb, track->par->width << 16);
3169  avio_wb32(pb, track->par->height << 16);
3170 
3171  return update_size(pb, pos);
3172 }
3173 
3174 // This box seems important for the psp playback ... without it the movie seems to hang
3176  MOVTrack *track)
3177 {
3178  int64_t duration = av_rescale_rnd(calc_samples_pts_duration(mov, track),
3179  mov->movie_timescale, track->timescale,
3180  AV_ROUND_UP);
3181  int version = duration < INT32_MAX ? 0 : 1;
3182  int entry_size, entry_count, size;
3183  int64_t delay, start_ct = track->start_cts;
3184  int64_t start_dts = track->start_dts;
3185 
3186  if (track->entry) {
3187  if (start_dts != track->cluster[0].dts || start_ct != track->cluster[0].cts) {
3188 
3189  av_log(mov->fc, AV_LOG_DEBUG,
3190  "EDTS using dts:%"PRId64" cts:%d instead of dts:%"PRId64" cts:%"PRId64" tid:%d\n",
3191  track->cluster[0].dts, track->cluster[0].cts,
3192  start_dts, start_ct, track->track_id);
3193  start_dts = track->cluster[0].dts;
3194  start_ct = track->cluster[0].cts;
3195  }
3196  }
3197 
3198  delay = av_rescale_rnd(start_dts + start_ct, mov->movie_timescale,
3199  track->timescale, AV_ROUND_DOWN);
3200  version |= delay < INT32_MAX ? 0 : 1;
3201 
3202  entry_size = (version == 1) ? 20 : 12;
3203  entry_count = 1 + (delay > 0);
3204  size = 24 + entry_count * entry_size;
3205 
3206  /* write the atom data */
3207  avio_wb32(pb, size);
3208  ffio_wfourcc(pb, "edts");
3209  avio_wb32(pb, size - 8);
3210  ffio_wfourcc(pb, "elst");
3211  avio_w8(pb, version);
3212  avio_wb24(pb, 0); /* flags */
3213 
3214  avio_wb32(pb, entry_count);
3215  if (delay > 0) { /* add an empty edit to delay presentation */
3216  /* In the positive delay case, the delay includes the cts
3217  * offset, and the second edit list entry below trims out
3218  * the same amount from the actual content. This makes sure
3219  * that the offset last sample is included in the edit
3220  * list duration as well. */
3221  if (version == 1) {
3222  avio_wb64(pb, delay);
3223  avio_wb64(pb, -1);
3224  } else {
3225  avio_wb32(pb, delay);
3226  avio_wb32(pb, -1);
3227  }
3228  avio_wb32(pb, 0x00010000);
3229  } else {
3230  /* Avoid accidentally ending up with start_ct = -1 which has got a
3231  * special meaning. Normally start_ct should end up positive or zero
3232  * here, but use FFMIN in case dts is a small positive integer
3233  * rounded to 0 when represented in movie timescale units. */
3234  av_assert0(av_rescale_rnd(start_dts, mov->movie_timescale, track->timescale, AV_ROUND_DOWN) <= 0);
3235  start_ct = -FFMIN(start_dts, 0);
3236  /* Note, this delay is calculated from the pts of the first sample,
3237  * ensuring that we don't reduce the duration for cases with
3238  * dts<0 pts=0. */
3239  duration += delay;
3240  }
3241 
3242  /* For fragmented files, we don't know the full length yet. Setting
3243  * duration to 0 allows us to only specify the offset, including
3244  * the rest of the content (from all future fragments) without specifying
3245  * an explicit duration. */
3246  if (mov->flags & FF_MOV_FLAG_FRAGMENT)
3247  duration = 0;
3248 
3249  /* duration */
3250  if (version == 1) {
3251  avio_wb64(pb, duration);
3252  avio_wb64(pb, start_ct);
3253  } else {
3254  avio_wb32(pb, duration);
3255  avio_wb32(pb, start_ct);
3256  }
3257  avio_wb32(pb, 0x00010000);
3258  return size;
3259 }
3260 
3261 static int mov_write_tref_tag(AVIOContext *pb, MOVTrack *track)
3262 {
3263  avio_wb32(pb, 20); // size
3264  ffio_wfourcc(pb, "tref");
3265  avio_wb32(pb, 12); // size (subatom)
3266  avio_wl32(pb, track->tref_tag);
3267  avio_wb32(pb, track->tref_id);
3268  return 20;
3269 }
3270 
3271 // goes at the end of each track! ... Critical for PSP playback ("Incompatible data" without it)
3273 {
3274  avio_wb32(pb, 0x34); /* size ... reports as 28 in mp4box! */
3275  ffio_wfourcc(pb, "uuid");
3276  ffio_wfourcc(pb, "USMT");
3277  avio_wb32(pb, 0x21d24fce);
3278  avio_wb32(pb, 0xbb88695c);
3279  avio_wb32(pb, 0xfac9c740);
3280  avio_wb32(pb, 0x1c); // another size here!
3281  ffio_wfourcc(pb, "MTDT");
3282  avio_wb32(pb, 0x00010012);
3283  avio_wb32(pb, 0x0a);
3284  avio_wb32(pb, 0x55c40000);
3285  avio_wb32(pb, 0x1);
3286  avio_wb32(pb, 0x0);
3287  return 0x34;
3288 }
3289 
3290 static int mov_write_udta_sdp(AVIOContext *pb, MOVTrack *track)
3291 {
3292  AVFormatContext *ctx = track->rtp_ctx;
3293  char buf[1000] = "";
3294  int len;
3295 
3296  ff_sdp_write_media(buf, sizeof(buf), ctx->streams[0], track->src_track,
3297  NULL, NULL, 0, 0, ctx);
3298  av_strlcatf(buf, sizeof(buf), "a=control:streamid=%d\r\n", track->track_id);
3299  len = strlen(buf);
3300 
3301  avio_wb32(pb, len + 24);
3302  ffio_wfourcc(pb, "udta");
3303  avio_wb32(pb, len + 16);
3304  ffio_wfourcc(pb, "hnti");
3305  avio_wb32(pb, len + 8);
3306  ffio_wfourcc(pb, "sdp ");
3307  avio_write(pb, buf, len);
3308  return len + 24;
3309 }
3310 
3312  const char *tag, const char *str)
3313 {
3314  int64_t pos = avio_tell(pb);
3316  if (!t || !utf8len(t->value))
3317  return 0;
3318 
3319  avio_wb32(pb, 0); /* size */
3320  ffio_wfourcc(pb, tag); /* type */
3321  avio_write(pb, t->value, strlen(t->value)); /* UTF8 string value */
3322  return update_size(pb, pos);
3323 }
3324 
3325 static int mov_write_track_kind(AVIOContext *pb, const char *scheme_uri,
3326  const char *value)
3327 {
3328  int64_t pos = avio_tell(pb);
3329 
3330  /* Box|FullBox basics */
3331  avio_wb32(pb, 0); /* size placeholder */
3332  ffio_wfourcc(pb, (const unsigned char *)"kind");
3333  avio_w8(pb, 0); /* version = 0 */
3334  avio_wb24(pb, 0); /* flags = 0 */
3335 
3336  /* Required null-terminated scheme URI */
3337  avio_write(pb, (const unsigned char *)scheme_uri,
3338  strlen(scheme_uri));
3339  avio_w8(pb, 0);
3340 
3341  /* Optional value string */
3342  if (value && value[0])
3343  avio_write(pb, (const unsigned char *)value,
3344  strlen(value));
3345 
3346  avio_w8(pb, 0);
3347 
3348  return update_size(pb, pos);
3349 }
3350 
3352 {
3353  int ret = AVERROR_BUG;
3354 
3355  for (int i = 0; ff_mov_track_kind_table[i].scheme_uri; i++) {
3357 
3358  for (int j = 0; map.value_maps[j].disposition; j++) {
3359  const struct MP4TrackKindValueMapping value_map = map.value_maps[j];
3360  if (!(st->disposition & value_map.disposition))
3361  continue;
3362 
3363  if ((ret = mov_write_track_kind(pb, map.scheme_uri, value_map.value)) < 0)
3364  return ret;
3365  }
3366  }
3367 
3368  return 0;
3369 }
3370 
3372  AVStream *st)
3373 {
3374  AVIOContext *pb_buf;
3375  int ret, size;
3376  uint8_t *buf;
3377 
3378  if (!st)
3379  return 0;
3380 
3381  ret = avio_open_dyn_buf(&pb_buf);
3382  if (ret < 0)
3383  return ret;
3384 
3385  if (mov->mode & (MODE_MP4|MODE_MOV))
3386  mov_write_track_metadata(pb_buf, st, "name", "title");
3387 
3388  if (mov->mode & MODE_MP4) {
3389  if ((ret = mov_write_track_kinds(pb_buf, st)) < 0)
3390  return ret;
3391  }
3392 
3393  if ((size = avio_get_dyn_buf(pb_buf, &buf)) > 0) {
3394  avio_wb32(pb, size + 8);
3395  ffio_wfourcc(pb, "udta");
3396  avio_write(pb, buf, size);
3397  }
3398  ffio_free_dyn_buf(&pb_buf);
3399 
3400  return 0;
3401 }
3402 
3404  MOVTrack *track, AVStream *st)
3405 {
3406  int64_t pos = avio_tell(pb);
3407  int entry_backup = track->entry;
3408  int chunk_backup = track->chunkCount;
3409  int ret;
3410 
3411  /* If we want to have an empty moov, but some samples already have been
3412  * buffered (delay_moov), pretend that no samples have been written yet. */
3413  if (mov->flags & FF_MOV_FLAG_EMPTY_MOOV)
3414  track->chunkCount = track->entry = 0;
3415 
3416  avio_wb32(pb, 0); /* size */
3417  ffio_wfourcc(pb, "trak");
3418  mov_write_tkhd_tag(pb, mov, track, st);
3419 
3420  av_assert2(mov->use_editlist >= 0);
3421 
3422  if (track->start_dts != AV_NOPTS_VALUE) {
3423  if (mov->use_editlist)
3424  mov_write_edts_tag(pb, mov, track); // PSP Movies and several other cases require edts box
3425  else if ((track->entry && track->cluster[0].dts) || track->mode == MODE_PSP || is_clcp_track(track))
3426  av_log(mov->fc, AV_LOG_WARNING,
3427  "Not writing any edit list even though one would have been required\n");
3428  }
3429 
3430  if (track->tref_tag)
3431  mov_write_tref_tag(pb, track);
3432 
3433  if ((ret = mov_write_mdia_tag(s, pb, mov, track)) < 0)
3434  return ret;
3435  if (track->mode == MODE_PSP)
3436  mov_write_uuid_tag_psp(pb, track); // PSP Movies require this uuid box
3437  if (track->tag == MKTAG('r','t','p',' '))
3438  mov_write_udta_sdp(pb, track);
3439  if (track->mode == MODE_MOV) {
3440  if (track->par->codec_type == AVMEDIA_TYPE_VIDEO) {
3441  double sample_aspect_ratio = av_q2d(st->sample_aspect_ratio);
3442  if (st->sample_aspect_ratio.num && 1.0 != sample_aspect_ratio) {
3443  mov_write_tapt_tag(pb, track);
3444  }
3445  }
3446  if (is_clcp_track(track) && st->sample_aspect_ratio.num) {
3447  mov_write_tapt_tag(pb, track);
3448  }
3449  }
3450  mov_write_track_udta_tag(pb, mov, st);
3451  track->entry = entry_backup;
3452  track->chunkCount = chunk_backup;
3453  return update_size(pb, pos);
3454 }
3455 
3457 {
3458  int i, has_audio = 0, has_video = 0;
3459  int64_t pos = avio_tell(pb);
3460  int audio_profile = mov->iods_audio_profile;
3461  int video_profile = mov->iods_video_profile;
3462  for (i = 0; i < mov->nb_streams; i++) {
3463  if (mov->tracks[i].entry > 0 || mov->flags & FF_MOV_FLAG_EMPTY_MOOV) {
3464  has_audio |= mov->tracks[i].par->codec_type == AVMEDIA_TYPE_AUDIO;
3465  has_video |= mov->tracks[i].par->codec_type == AVMEDIA_TYPE_VIDEO;
3466  }
3467  }
3468  if (audio_profile < 0)
3469  audio_profile = 0xFF - has_audio;
3470  if (video_profile < 0)
3471  video_profile = 0xFF - has_video;
3472  avio_wb32(pb, 0x0); /* size */
3473  ffio_wfourcc(pb, "iods");
3474  avio_wb32(pb, 0); /* version & flags */
3475  put_descr(pb, 0x10, 7);
3476  avio_wb16(pb, 0x004f);
3477  avio_w8(pb, 0xff);
3478  avio_w8(pb, 0xff);
3479  avio_w8(pb, audio_profile);
3480  avio_w8(pb, video_profile);
3481  avio_w8(pb, 0xff);
3482  return update_size(pb, pos);
3483 }
3484 
3485 static int mov_write_trex_tag(AVIOContext *pb, MOVTrack *track)
3486 {
3487  avio_wb32(pb, 0x20); /* size */
3488  ffio_wfourcc(pb, "trex");
3489  avio_wb32(pb, 0); /* version & flags */
3490  avio_wb32(pb, track->track_id); /* track ID */
3491  avio_wb32(pb, 1); /* default sample description index */
3492  avio_wb32(pb, 0); /* default sample duration */
3493  avio_wb32(pb, 0); /* default sample size */
3494  avio_wb32(pb, 0); /* default sample flags */
3495  return 0;
3496 }
3497 
3499 {
3500  int64_t pos = avio_tell(pb);
3501  int i;
3502  avio_wb32(pb, 0x0); /* size */
3503  ffio_wfourcc(pb, "mvex");
3504  for (i = 0; i < mov->nb_streams; i++)
3505  mov_write_trex_tag(pb, &mov->tracks[i]);
3506  return update_size(pb, pos);
3507 }
3508 
3510 {
3511  int max_track_id = 1, i;
3512  int64_t max_track_len = 0;
3513  int version;
3514 
3515  for (i = 0; i < mov->nb_streams; i++) {
3516  if (mov->tracks[i].entry > 0 && mov->tracks[i].timescale) {
3517  int64_t max_track_len_temp = av_rescale_rnd(
3518  calc_pts_duration(mov, &mov->tracks[i]),
3519  mov->movie_timescale,
3520  mov->tracks[i].timescale,
3521  AV_ROUND_UP);
3522  if (max_track_len < max_track_len_temp)
3523  max_track_len = max_track_len_temp;
3524  if (max_track_id < mov->tracks[i].track_id)
3525  max_track_id = mov->tracks[i].track_id;
3526  }
3527  }
3528  /* If using delay_moov, make sure the output is the same as if no
3529  * samples had been written yet. */
3530  if (mov->flags & FF_MOV_FLAG_EMPTY_MOOV) {
3531  max_track_len = 0;
3532  max_track_id = 1;
3533  }
3534 
3535  version = max_track_len < UINT32_MAX ? 0 : 1;
3536  avio_wb32(pb, version == 1 ? 120 : 108); /* size */
3537 
3538  ffio_wfourcc(pb, "mvhd");
3539  avio_w8(pb, version);
3540  avio_wb24(pb, 0); /* flags */
3541  if (version == 1) {
3542  avio_wb64(pb, mov->time);
3543  avio_wb64(pb, mov->time);
3544  } else {
3545  avio_wb32(pb, mov->time); /* creation time */
3546  avio_wb32(pb, mov->time); /* modification time */
3547  }
3548  avio_wb32(pb, mov->movie_timescale);
3549  (version == 1) ? avio_wb64(pb, max_track_len) : avio_wb32(pb, max_track_len); /* duration of longest track */
3550 
3551  avio_wb32(pb, 0x00010000); /* reserved (preferred rate) 1.0 = normal */
3552  avio_wb16(pb, 0x0100); /* reserved (preferred volume) 1.0 = normal */
3553  ffio_fill(pb, 0, 2 + 2 * 4); /* reserved */
3554 
3555  /* Matrix structure */
3556  write_matrix(pb, 1, 0, 0, 1, 0, 0);
3557 
3558  avio_wb32(pb, 0); /* reserved (preview time) */
3559  avio_wb32(pb, 0); /* reserved (preview duration) */
3560  avio_wb32(pb, 0); /* reserved (poster time) */
3561  avio_wb32(pb, 0); /* reserved (selection time) */
3562  avio_wb32(pb, 0); /* reserved (selection duration) */
3563  avio_wb32(pb, 0); /* reserved (current time) */
3564  avio_wb32(pb, max_track_id + 1); /* Next track id */
3565  return 0x6c;
3566 }
3567 
3569  AVFormatContext *s)
3570 {
3571  avio_wb32(pb, 33); /* size */
3572  ffio_wfourcc(pb, "hdlr");
3573  avio_wb32(pb, 0);
3574  avio_wb32(pb, 0);
3575  ffio_wfourcc(pb, "mdir");
3576  ffio_wfourcc(pb, "appl");
3577  avio_wb32(pb, 0);
3578  avio_wb32(pb, 0);
3579  avio_w8(pb, 0);
3580  return 33;
3581 }
3582 
3583 /* helper function to write a data tag with the specified string as data */
3584 static int mov_write_string_data_tag(AVIOContext *pb, const char *data, int lang, int long_style)
3585 {
3586  size_t data_len = strlen(data);
3587  if (long_style) {
3588  int size = 16 + data_len;
3589  avio_wb32(pb, size); /* size */
3590  ffio_wfourcc(pb, "data");
3591  avio_wb32(pb, 1);
3592  avio_wb32(pb, 0);
3593  avio_write(pb, data, data_len);
3594  return size;
3595  } else {
3596  avio_wb16(pb, data_len); /* string length */
3597  if (!lang)
3598  lang = ff_mov_iso639_to_lang("und", 1);
3599  avio_wb16(pb, lang);
3600  avio_write(pb, data, data_len);
3601  return data_len + 4;
3602  }
3603 }
3604 
3605 static int mov_write_string_tag(AVIOContext *pb, const char *name,
3606  const char *value, int lang, int long_style)
3607 {
3608  int size = 0;
3609  if (value && value[0]) {
3610  int64_t pos = avio_tell(pb);
3611  avio_wb32(pb, 0); /* size */
3612  ffio_wfourcc(pb, name);
3613  mov_write_string_data_tag(pb, value, lang, long_style);
3614  size = update_size(pb, pos);
3615  }
3616  return size;
3617 }
3618 
3620  const char *tag, int *lang)
3621 {
3622  int l, len, len2;
3623  AVDictionaryEntry *t, *t2 = NULL;
3624  char tag2[16];
3625 
3626  *lang = 0;
3627 
3628  if (!(t = av_dict_get(s->metadata, tag, NULL, 0)))
3629  return NULL;
3630 
3631  len = strlen(t->key);
3632  snprintf(tag2, sizeof(tag2), "%s-", tag);
3633  while ((t2 = av_dict_get(s->metadata, tag2, t2, AV_DICT_IGNORE_SUFFIX))) {
3634  len2 = strlen(t2->key);
3635  if (len2 == len + 4 && !strcmp(t->value, t2->value)
3636  && (l = ff_mov_iso639_to_lang(&t2->key[len2 - 3], 1)) >= 0) {
3637  *lang = l;
3638  return t;
3639  }
3640  }
3641  return t;
3642 }
3643 
3645  const char *name, const char *tag,
3646  int long_style)
3647 {
3648  int lang;
3649  AVDictionaryEntry *t = get_metadata_lang(s, tag, &lang);
3650  if (!t)
3651  return 0;
3652  return mov_write_string_tag(pb, name, t->value, lang, long_style);
3653 }
3654 
3655 /* iTunes bpm number */
3657 {
3658  AVDictionaryEntry *t = av_dict_get(s->metadata, "tmpo", NULL, 0);
3659  int size = 0, tmpo = t ? atoi(t->value) : 0;
3660  if (tmpo) {
3661  size = 26;
3662  avio_wb32(pb, size);
3663  ffio_wfourcc(pb, "tmpo");
3664  avio_wb32(pb, size-8); /* size */
3665  ffio_wfourcc(pb, "data");
3666  avio_wb32(pb, 0x15); //type specifier
3667  avio_wb32(pb, 0);
3668  avio_wb16(pb, tmpo); // data
3669  }
3670  return size;
3671 }
3672 
3673 /* 3GPP TS 26.244 */
3675 {
3676  int lang;
3677  int64_t pos = avio_tell(pb);
3678  double latitude, longitude, altitude;
3679  int32_t latitude_fix, longitude_fix, altitude_fix;
3680  AVDictionaryEntry *t = get_metadata_lang(s, "location", &lang);
3681  const char *ptr, *place = "";
3682  char *end;
3683  static const char *astronomical_body = "earth";
3684  if (!t)
3685  return 0;
3686 
3687  ptr = t->value;
3688  longitude = strtod(ptr, &end);
3689  if (end == ptr) {
3690  av_log(s, AV_LOG_WARNING, "malformed location metadata\n");
3691  return 0;
3692  }
3693  ptr = end;
3694  latitude = strtod(ptr, &end);
3695  if (end == ptr) {
3696  av_log(s, AV_LOG_WARNING, "malformed location metadata\n");
3697  return 0;
3698  }
3699  ptr = end;
3700  altitude = strtod(ptr, &end);
3701  /* If no altitude was present, the default 0 should be fine */
3702  if (*end == '/')
3703  place = end + 1;
3704 
3705  latitude_fix = (int32_t) ((1 << 16) * latitude);
3706  longitude_fix = (int32_t) ((1 << 16) * longitude);
3707  altitude_fix = (int32_t) ((1 << 16) * altitude);
3708 
3709  avio_wb32(pb, 0); /* size */
3710  ffio_wfourcc(pb, "loci"); /* type */
3711  avio_wb32(pb, 0); /* version + flags */
3712  avio_wb16(pb, lang);
3713  avio_write(pb, place, strlen(place) + 1);
3714  avio_w8(pb, 0); /* role of place (0 == shooting location, 1 == real location, 2 == fictional location) */
3715  avio_wb32(pb, latitude_fix);
3716  avio_wb32(pb, longitude_fix);
3717  avio_wb32(pb, altitude_fix);
3718  avio_write(pb, astronomical_body, strlen(astronomical_body) + 1);
3719  avio_w8(pb, 0); /* additional notes, null terminated string */
3720 
3721  return update_size(pb, pos);
3722 }
3723 
3724 /* iTunes track or disc number */
3726  AVFormatContext *s, int disc)
3727 {
3728  AVDictionaryEntry *t = av_dict_get(s->metadata,
3729  disc ? "disc" : "track",
3730  NULL, 0);
3731  int size = 0, track = t ? atoi(t->value) : 0;
3732  if (track) {
3733  int tracks = 0;
3734  char *slash = strchr(t->value, '/');
3735  if (slash)
3736  tracks = atoi(slash + 1);
3737  avio_wb32(pb, 32); /* size */
3738  ffio_wfourcc(pb, disc ? "disk" : "trkn");
3739  avio_wb32(pb, 24); /* size */
3740  ffio_wfourcc(pb, "data");
3741  avio_wb32(pb, 0); // 8 bytes empty
3742  avio_wb32(pb, 0);
3743  avio_wb16(pb, 0); // empty
3744  avio_wb16(pb, track); // track / disc number
3745  avio_wb16(pb, tracks); // total track / disc number
3746  avio_wb16(pb, 0); // empty
3747  size = 32;
3748  }
3749  return size;
3750 }
3751 
3753  const char *name, const char *tag,
3754  int len)
3755 {
3756  AVDictionaryEntry *t = NULL;
3757  uint8_t num;
3758  int size = 24 + len;
3759 
3760  if (len != 1 && len != 4)
3761  return -1;
3762 
3763  if (!(t = av_dict_get(s->metadata, tag, NULL, 0)))
3764  return 0;
3765  num = atoi(t->value);
3766 
3767  avio_wb32(pb, size);
3768  ffio_wfourcc(pb, name);
3769  avio_wb32(pb, size - 8);
3770  ffio_wfourcc(pb, "data");
3771  avio_wb32(pb, 0x15);
3772  avio_wb32(pb, 0);
3773  if (len==4) avio_wb32(pb, num);
3774  else avio_w8 (pb, num);
3775 
3776  return size;
3777 }
3778 
3780 {
3781  MOVMuxContext *mov = s->priv_data;
3782  int64_t pos = 0;
3783  int i;
3784 
3785  for (i = 0; i < s->nb_streams; i++) {
3786  MOVTrack *trk = &mov->tracks[i];
3787 
3788  if (!is_cover_image(trk->st) || trk->cover_image->size <= 0)
3789  continue;
3790 
3791  if (!pos) {
3792  pos = avio_tell(pb);
3793  avio_wb32(pb, 0);
3794  ffio_wfourcc(pb, "covr");
3795  }
3796  avio_wb32(pb, 16 + trk->cover_image->size);
3797  ffio_wfourcc(pb, "data");
3798  avio_wb32(pb, trk->tag);
3799  avio_wb32(pb , 0);
3800  avio_write(pb, trk->cover_image->data, trk->cover_image->size);
3801  }
3802 
3803  return pos ? update_size(pb, pos) : 0;
3804 }
3805 
3806 /* iTunes meta data list */
3808  AVFormatContext *s)
3809 {
3810  int64_t pos = avio_tell(pb);
3811  avio_wb32(pb, 0); /* size */
3812  ffio_wfourcc(pb, "ilst");
3813  mov_write_string_metadata(s, pb, "\251nam", "title" , 1);
3814  mov_write_string_metadata(s, pb, "\251ART", "artist" , 1);
3815  mov_write_string_metadata(s, pb, "aART", "album_artist", 1);
3816  mov_write_string_metadata(s, pb, "\251wrt", "composer" , 1);
3817  mov_write_string_metadata(s, pb, "\251alb", "album" , 1);
3818  mov_write_string_metadata(s, pb, "\251day", "date" , 1);
3819  if (!mov_write_string_metadata(s, pb, "\251too", "encoding_tool", 1)) {
3820  if (!(s->flags & AVFMT_FLAG_BITEXACT))
3821  mov_write_string_tag(pb, "\251too", LIBAVFORMAT_IDENT, 0, 1);
3822  }
3823  mov_write_string_metadata(s, pb, "\251cmt", "comment" , 1);
3824  mov_write_string_metadata(s, pb, "\251gen", "genre" , 1);
3825  mov_write_string_metadata(s, pb, "cprt", "copyright", 1);
3826  mov_write_string_metadata(s, pb, "\251grp", "grouping" , 1);
3827  mov_write_string_metadata(s, pb, "\251lyr", "lyrics" , 1);
3828  mov_write_string_metadata(s, pb, "desc", "description",1);
3829  mov_write_string_metadata(s, pb, "ldes", "synopsis" , 1);
3830  mov_write_string_metadata(s, pb, "tvsh", "show" , 1);
3831  mov_write_string_metadata(s, pb, "tven", "episode_id",1);
3832  mov_write_string_metadata(s, pb, "tvnn", "network" , 1);
3833  mov_write_string_metadata(s, pb, "keyw", "keywords" , 1);
3834  mov_write_int8_metadata (s, pb, "tves", "episode_sort",4);
3835  mov_write_int8_metadata (s, pb, "tvsn", "season_number",4);
3836  mov_write_int8_metadata (s, pb, "stik", "media_type",1);
3837  mov_write_int8_metadata (s, pb, "hdvd", "hd_video", 1);
3838  mov_write_int8_metadata (s, pb, "pgap", "gapless_playback",1);
3839  mov_write_int8_metadata (s, pb, "cpil", "compilation", 1);
3840  mov_write_covr(pb, s);
3841  mov_write_trkn_tag(pb, mov, s, 0); // track number
3842  mov_write_trkn_tag(pb, mov, s, 1); // disc number
3843  mov_write_tmpo_tag(pb, s);
3844  return update_size(pb, pos);
3845 }
3846 
3848  AVFormatContext *s)
3849 {
3850  avio_wb32(pb, 33); /* size */
3851  ffio_wfourcc(pb, "hdlr");
3852  avio_wb32(pb, 0);
3853  avio_wb32(pb, 0);
3854  ffio_wfourcc(pb, "mdta");
3855  avio_wb32(pb, 0);
3856  avio_wb32(pb, 0);
3857  avio_wb32(pb, 0);
3858  avio_w8(pb, 0);
3859  return 33;
3860 }
3861 
3863  AVFormatContext *s)
3864 {
3865  AVDictionaryEntry *t = NULL;
3866  int64_t pos = avio_tell(pb);
3867  int64_t curpos, entry_pos;
3868  int count = 0;
3869 
3870  avio_wb32(pb, 0); /* size */
3871  ffio_wfourcc(pb, "keys");
3872  avio_wb32(pb, 0);
3873  entry_pos = avio_tell(pb);
3874  avio_wb32(pb, 0); /* entry count */
3875 
3876  while (t = av_dict_get(s->metadata, "", t, AV_DICT_IGNORE_SUFFIX)) {
3877  size_t key_len = strlen(t->key);
3878  avio_wb32(pb, key_len + 8);
3879  ffio_wfourcc(pb, "mdta");
3880  avio_write(pb, t->key, key_len);
3881  count += 1;
3882  }
3883  curpos = avio_tell(pb);
3884  avio_seek(pb, entry_pos, SEEK_SET);
3885  avio_wb32(pb, count); // rewrite entry count
3886  avio_seek(pb, curpos, SEEK_SET);
3887 
3888  return update_size(pb, pos);
3889 }
3890 
3892  AVFormatContext *s)
3893 {
3894  AVDictionaryEntry *t = NULL;
3895  int64_t pos = avio_tell(pb);
3896  int count = 1; /* keys are 1-index based */
3897 
3898  avio_wb32(pb, 0); /* size */
3899  ffio_wfourcc(pb, "ilst");
3900 
3901  while (t = av_dict_get(s->metadata, "", t, AV_DICT_IGNORE_SUFFIX)) {
3902  int64_t entry_pos = avio_tell(pb);
3903  avio_wb32(pb, 0); /* size */
3904  avio_wb32(pb, count); /* key */
3905  mov_write_string_data_tag(pb, t->value, 0, 1);
3906  update_size(pb, entry_pos);
3907  count += 1;
3908  }
3909  return update_size(pb, pos);
3910 }
3911 
3912 /* meta data tags */
3914  AVFormatContext *s)
3915 {
3916  int size = 0;
3917  int64_t pos = avio_tell(pb);
3918  avio_wb32(pb, 0); /* size */
3919  ffio_wfourcc(pb, "meta");
3920  avio_wb32(pb, 0);
3921  if (mov->flags & FF_MOV_FLAG_USE_MDTA) {
3922  mov_write_mdta_hdlr_tag(pb, mov, s);
3923  mov_write_mdta_keys_tag(pb, mov, s);
3924  mov_write_mdta_ilst_tag(pb, mov, s);
3925  }
3926  else {
3927  /* iTunes metadata tag */
3928  mov_write_itunes_hdlr_tag(pb, mov, s);
3929  mov_write_ilst_tag(pb, mov, s);
3930  }
3931  size = update_size(pb, pos);
3932  return size;
3933 }
3934 
3936  const char *name, const char *key)
3937 {
3938  int len;
3939  AVDictionaryEntry *t;
3940 
3941  if (!(t = av_dict_get(s->metadata, key, NULL, 0)))
3942  return 0;
3943 
3944  len = strlen(t->value);
3945  if (len > 0) {
3946  int size = len + 8;
3947  avio_wb32(pb, size);
3948  ffio_wfourcc(pb, name);
3949  avio_write(pb, t->value, len);
3950  return size;
3951  }
3952  return 0;
3953 }
3954 
3955 static int ascii_to_wc(AVIOContext *pb, const uint8_t *b)
3956 {
3957  int val;
3958  while (*b) {
3959  GET_UTF8(val, *b++, return -1;)
3960  avio_wb16(pb, val);
3961  }
3962  avio_wb16(pb, 0x00);
3963  return 0;
3964 }
3965 
3966 static uint16_t language_code(const char *str)
3967 {
3968  return (((str[0] - 0x60) & 0x1F) << 10) +
3969  (((str[1] - 0x60) & 0x1F) << 5) +
3970  (( str[2] - 0x60) & 0x1F);
3971 }
3972 
3974  const char *tag, const char *str)
3975 {
3976  int64_t pos = avio_tell(pb);
3977  AVDictionaryEntry *t = av_dict_get(s->metadata, str, NULL, 0);
3978  if (!t || !utf8len(t->value))
3979  return 0;
3980  avio_wb32(pb, 0); /* size */
3981  ffio_wfourcc(pb, tag); /* type */
3982  avio_wb32(pb, 0); /* version + flags */
3983  if (!strcmp(tag, "yrrc"))
3984  avio_wb16(pb, atoi(t->value));
3985  else {
3986  avio_wb16(pb, language_code("eng")); /* language */
3987  avio_write(pb, t->value, strlen(t->value) + 1); /* UTF8 string value */
3988  if (!strcmp(tag, "albm") &&
3989  (t = av_dict_get(s->metadata, "track", NULL, 0)))
3990  avio_w8(pb, atoi(t->value));
3991  }
3992  return update_size(pb, pos);
3993 }
3994 
3996 {
3997  int64_t pos = avio_tell(pb);
3998  int i, nb_chapters = FFMIN(s->nb_chapters, 255);
3999 
4000  avio_wb32(pb, 0); // size
4001  ffio_wfourcc(pb, "chpl");
4002  avio_wb32(pb, 0x01000000); // version + flags
4003  avio_wb32(pb, 0); // unknown
4004  avio_w8(pb, nb_chapters);
4005 
4006  for (i = 0; i < nb_chapters; i++) {
4007  AVChapter *c = s->chapters[i];
4008  AVDictionaryEntry *t;
4009  avio_wb64(pb, av_rescale_q(c->start, c->time_base, (AVRational){1,10000000}));
4010 
4011  if ((t = av_dict_get(c->metadata, "title", NULL, 0))) {
4012  int len = FFMIN(strlen(t->value), 255);
4013  avio_w8(pb, len);
4014  avio_write(pb, t->value, len);
4015  } else
4016  avio_w8(pb, 0);
4017  }
4018  return update_size(pb, pos);
4019 }
4020 
4022  AVFormatContext *s)
4023 {
4024  AVIOContext *pb_buf;
4025  int ret, size;
4026  uint8_t *buf;
4027 
4028  ret = avio_open_dyn_buf(&pb_buf);
4029  if (ret < 0)
4030  return ret;
4031 
4032  if (mov->mode & MODE_3GP) {
4033  mov_write_3gp_udta_tag(pb_buf, s, "perf", "artist");
4034  mov_write_3gp_udta_tag(pb_buf, s, "titl", "title");
4035  mov_write_3gp_udta_tag(pb_buf, s, "auth", "author");
4036  mov_write_3gp_udta_tag(pb_buf, s, "gnre", "genre");
4037  mov_write_3gp_udta_tag(pb_buf, s, "dscp", "comment");
4038  mov_write_3gp_udta_tag(pb_buf, s, "albm", "album");
4039  mov_write_3gp_udta_tag(pb_buf, s, "cprt", "copyright");
4040  mov_write_3gp_udta_tag(pb_buf, s, "yrrc", "date");
4041  mov_write_loci_tag(s, pb_buf);
4042  } 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
4043  mov_write_string_metadata(s, pb_buf, "\251ART", "artist", 0);
4044  mov_write_string_metadata(s, pb_buf, "\251nam", "title", 0);
4045  mov_write_string_metadata(s, pb_buf, "\251aut", "author", 0);
4046  mov_write_string_metadata(s, pb_buf, "\251alb", "album", 0);
4047  mov_write_string_metadata(s, pb_buf, "\251day", "date", 0);
4048  mov_write_string_metadata(s, pb_buf, "\251swr", "encoder", 0);
4049  // currently ignored by mov.c
4050  mov_write_string_metadata(s, pb_buf, "\251des", "comment", 0);
4051  // add support for libquicktime, this atom is also actually read by mov.c
4052  mov_write_string_metadata(s, pb_buf, "\251cmt", "comment", 0);
4053  mov_write_string_metadata(s, pb_buf, "\251gen", "genre", 0);
4054  mov_write_string_metadata(s, pb_buf, "\251cpy", "copyright", 0);
4055  mov_write_string_metadata(s, pb_buf, "\251mak", "make", 0);
4056  mov_write_string_metadata(s, pb_buf, "\251mod", "model", 0);
4057  mov_write_string_metadata(s, pb_buf, "\251xyz", "location", 0);
4058  mov_write_string_metadata(s, pb_buf, "\251key", "keywords", 0);
4059  mov_write_raw_metadata_tag(s, pb_buf, "XMP_", "xmp");
4060  } else {
4061  /* iTunes meta data */
4062  mov_write_meta_tag(pb_buf, mov, s);
4063  mov_write_loci_tag(s, pb_buf);
4064  }
4065 
4066  if (s->nb_chapters && !(mov->flags & FF_MOV_FLAG_DISABLE_CHPL))
4067  mov_write_chpl_tag(pb_buf, s);
4068 
4069  if ((size = avio_get_dyn_buf(pb_buf, &buf)) > 0) {
4070  avio_wb32(pb, size + 8);
4071  ffio_wfourcc(pb, "udta");
4072  avio_write(pb, buf, size);
4073  }
4074  ffio_free_dyn_buf(&pb_buf);
4075 
4076  return 0;
4077 }
4078 
4080  const char *str, const char *lang, int type)
4081 {
4082  int len = utf8len(str) + 1;
4083  if (len <= 0)
4084  return;
4085  avio_wb16(pb, len * 2 + 10); /* size */
4086  avio_wb32(pb, type); /* type */
4087  avio_wb16(pb, language_code(lang)); /* language */
4088  avio_wb16(pb, 0x01); /* ? */
4089  ascii_to_wc(pb, str);
4090 }
4091 
4093 {
4094  AVDictionaryEntry *title = av_dict_get(s->metadata, "title", NULL, 0);
4095  int64_t pos, pos2;
4096 
4097  if (title) {
4098  pos = avio_tell(pb);
4099  avio_wb32(pb, 0); /* size placeholder*/
4100  ffio_wfourcc(pb, "uuid");
4101  ffio_wfourcc(pb, "USMT");
4102  avio_wb32(pb, 0x21d24fce); /* 96 bit UUID */
4103  avio_wb32(pb, 0xbb88695c);
4104  avio_wb32(pb, 0xfac9c740);
4105 
4106  pos2 = avio_tell(pb);
4107  avio_wb32(pb, 0); /* size placeholder*/
4108  ffio_wfourcc(pb, "MTDT");
4109  avio_wb16(pb, 4);
4110 
4111  // ?
4112  avio_wb16(pb, 0x0C); /* size */
4113  avio_wb32(pb, 0x0B); /* type */
4114  avio_wb16(pb, language_code("und")); /* language */
4115  avio_wb16(pb, 0x0); /* ? */
4116  avio_wb16(pb, 0x021C); /* data */
4117 
4118  if (!(s->flags & AVFMT_FLAG_BITEXACT))
4119  mov_write_psp_udta_tag(pb, LIBAVCODEC_IDENT, "eng", 0x04);
4120  mov_write_psp_udta_tag(pb, title->value, "eng", 0x01);
4121  mov_write_psp_udta_tag(pb, "2006/04/01 11:11:11", "und", 0x03);
4122 
4123  update_size(pb, pos2);
4124  return update_size(pb, pos);
4125  }
4126 
4127  return 0;
4128 }
4129 
4130 static void build_chunks(MOVTrack *trk)
4131 {
4132  int i;
4133  MOVIentry *chunk = &trk->cluster[0];
4134  uint64_t chunkSize = chunk->size;
4135  chunk->chunkNum = 1;
4136  if (trk->chunkCount)
4137  return;
4138  trk->chunkCount = 1;
4139  for (i = 1; i<trk->entry; i++){
4140  if (chunk->pos + chunkSize == trk->cluster[i].pos &&
4141  chunkSize + trk->cluster[i].size < (1<<20)){
4142  chunkSize += trk->cluster[i].size;
4143  chunk->samples_in_chunk += trk->cluster[i].entries;
4144  } else {
4145  trk->cluster[i].chunkNum = chunk->chunkNum+1;
4146  chunk=&trk->cluster[i];
4147  chunkSize = chunk->size;
4148  trk->chunkCount++;
4149  }
4150  }
4151 }
4152 
4153 /**
4154  * Assign track ids. If option "use_stream_ids_as_track_ids" is set,
4155  * the stream ids are used as track ids.
4156  *
4157  * This assumes mov->tracks and s->streams are in the same order and
4158  * there are no gaps in either of them (so mov->tracks[n] refers to
4159  * s->streams[n]).
4160  *
4161  * As an exception, there can be more entries in
4162  * s->streams than in mov->tracks, in which case new track ids are
4163  * generated (starting after the largest found stream id).
4164  */
4166 {
4167  int i;
4168 
4169  if (mov->track_ids_ok)
4170  return 0;
4171 
4172  if (mov->use_stream_ids_as_track_ids) {
4173  int next_generated_track_id = 0;
4174  for (i = 0; i < s->nb_streams; i++) {
4175  if (s->streams[i]->id > next_generated_track_id)
4176  next_generated_track_id = s->streams[i]->id;
4177  }
4178 
4179  for (i = 0; i < mov->nb_streams; i++) {
4180  if (mov->tracks[i].entry <= 0 && !(mov->flags & FF_MOV_FLAG_FRAGMENT))
4181  continue;
4182 
4183  mov->tracks[i].track_id = i >= s->nb_streams ? ++next_generated_track_id : s->streams[i]->id;
4184  }
4185  } else {
4186  for (i = 0; i < mov->nb_streams; i++) {
4187  if (mov->tracks[i].entry <= 0 && !(mov->flags & FF_MOV_FLAG_FRAGMENT))
4188  continue;
4189 
4190  mov->tracks[i].track_id = i + 1;
4191  }
4192  }
4193 
4194  mov->track_ids_ok = 1;
4195 
4196  return 0;
4197 }
4198 
4200  AVFormatContext *s)
4201 {
4202  int i;
4203  int64_t pos = avio_tell(pb);
4204  avio_wb32(pb, 0); /* size placeholder*/
4205  ffio_wfourcc(pb, "moov");
4206 
4207  mov_setup_track_ids(mov, s);
4208 
4209  for (i = 0; i < mov->nb_streams; i++) {
4210  if (mov->tracks[i].entry <= 0 && !(mov->flags & FF_MOV_FLAG_FRAGMENT))
4211  continue;
4212 
4213  mov->tracks[i].time = mov->time;
4214 
4215