3 * Copyright (c) 2001 Fabrice Bellard
4 * Copyright (c) 2009 Baptiste Coudurier <baptiste dot coudurier at gmail dot com>
6 * first version by Francois Revol <revol@free.fr>
7 * seek function by Gael Chardon <gael.dev@4now.net>
9 * This file is part of FFmpeg.
11 * FFmpeg is free software; you can redistribute it and/or
12 * modify it under the terms of the GNU Lesser General Public
13 * License as published by the Free Software Foundation; either
14 * version 2.1 of the License, or (at your option) any later version.
16 * FFmpeg is distributed in the hope that it will be useful,
17 * but WITHOUT ANY WARRANTY; without even the implied warranty of
18 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
19 * Lesser General Public License for more details.
21 * You should have received a copy of the GNU Lesser General Public
22 * License along with FFmpeg; if not, write to the Free Software
23 * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
30 #include "libavutil/attributes.h"
31 #include "libavutil/channel_layout.h"
32 #include "libavutil/internal.h"
33 #include "libavutil/intreadwrite.h"
34 #include "libavutil/intfloat.h"
35 #include "libavutil/mathematics.h"
36 #include "libavutil/time_internal.h"
37 #include "libavutil/avassert.h"
38 #include "libavutil/avstring.h"
39 #include "libavutil/dict.h"
40 #include "libavutil/display.h"
41 #include "libavutil/opt.h"
42 #include "libavutil/aes.h"
43 #include "libavutil/aes_ctr.h"
44 #include "libavutil/pixdesc.h"
45 #include "libavutil/sha.h"
46 #include "libavutil/spherical.h"
47 #include "libavutil/stereo3d.h"
48 #include "libavutil/timecode.h"
49 #include "libavutil/dovi_meta.h"
50 #include "libavcodec/ac3tab.h"
51 #include "libavcodec/flac.h"
52 #include "libavcodec/mpegaudiodecheader.h"
53 #include "libavcodec/mlp_parse.h"
56 #include "avio_internal.h"
59 #include "libavcodec/get_bits.h"
62 #include "replaygain.h"
68 #include "qtpalette.h"
70 /* those functions parse an atom */
71 /* links atom IDs to parse functions */
72 typedef struct MOVParseTableEntry {
74 int (*parse)(MOVContext *ctx, AVIOContext *pb, MOVAtom atom);
77 static int mov_read_default(MOVContext *c, AVIOContext *pb, MOVAtom atom);
78 static int mov_read_mfra(MOVContext *c, AVIOContext *f);
79 static int64_t add_ctts_entry(MOVStts** ctts_data, unsigned int* ctts_count, unsigned int* allocated_size,
80 int count, int duration);
82 static int mov_metadata_track_or_disc_number(MOVContext *c, AVIOContext *pb,
83 unsigned len, const char *key)
87 short current, total = 0;
88 avio_rb16(pb); // unknown
89 current = avio_rb16(pb);
91 total = avio_rb16(pb);
93 snprintf(buf, sizeof(buf), "%d", current);
95 snprintf(buf, sizeof(buf), "%d/%d", current, total);
96 c->fc->event_flags |= AVFMT_EVENT_FLAG_METADATA_UPDATED;
97 av_dict_set(&c->fc->metadata, key, buf, 0);
102 static int mov_metadata_int8_bypass_padding(MOVContext *c, AVIOContext *pb,
103 unsigned len, const char *key)
105 /* bypass padding bytes */
110 c->fc->event_flags |= AVFMT_EVENT_FLAG_METADATA_UPDATED;
111 av_dict_set_int(&c->fc->metadata, key, avio_r8(pb), 0);
116 static int mov_metadata_int8_no_padding(MOVContext *c, AVIOContext *pb,
117 unsigned len, const char *key)
119 c->fc->event_flags |= AVFMT_EVENT_FLAG_METADATA_UPDATED;
120 av_dict_set_int(&c->fc->metadata, key, avio_r8(pb), 0);
125 static int mov_metadata_gnre(MOVContext *c, AVIOContext *pb,
126 unsigned len, const char *key)
130 avio_r8(pb); // unknown
133 if (genre < 1 || genre > ID3v1_GENRE_MAX)
135 c->fc->event_flags |= AVFMT_EVENT_FLAG_METADATA_UPDATED;
136 av_dict_set(&c->fc->metadata, key, ff_id3v1_genre_str[genre-1], 0);
141 static const uint32_t mac_to_unicode[128] = {
142 0x00C4,0x00C5,0x00C7,0x00C9,0x00D1,0x00D6,0x00DC,0x00E1,
143 0x00E0,0x00E2,0x00E4,0x00E3,0x00E5,0x00E7,0x00E9,0x00E8,
144 0x00EA,0x00EB,0x00ED,0x00EC,0x00EE,0x00EF,0x00F1,0x00F3,
145 0x00F2,0x00F4,0x00F6,0x00F5,0x00FA,0x00F9,0x00FB,0x00FC,
146 0x2020,0x00B0,0x00A2,0x00A3,0x00A7,0x2022,0x00B6,0x00DF,
147 0x00AE,0x00A9,0x2122,0x00B4,0x00A8,0x2260,0x00C6,0x00D8,
148 0x221E,0x00B1,0x2264,0x2265,0x00A5,0x00B5,0x2202,0x2211,
149 0x220F,0x03C0,0x222B,0x00AA,0x00BA,0x03A9,0x00E6,0x00F8,
150 0x00BF,0x00A1,0x00AC,0x221A,0x0192,0x2248,0x2206,0x00AB,
151 0x00BB,0x2026,0x00A0,0x00C0,0x00C3,0x00D5,0x0152,0x0153,
152 0x2013,0x2014,0x201C,0x201D,0x2018,0x2019,0x00F7,0x25CA,
153 0x00FF,0x0178,0x2044,0x20AC,0x2039,0x203A,0xFB01,0xFB02,
154 0x2021,0x00B7,0x201A,0x201E,0x2030,0x00C2,0x00CA,0x00C1,
155 0x00CB,0x00C8,0x00CD,0x00CE,0x00CF,0x00CC,0x00D3,0x00D4,
156 0xF8FF,0x00D2,0x00DA,0x00DB,0x00D9,0x0131,0x02C6,0x02DC,
157 0x00AF,0x02D8,0x02D9,0x02DA,0x00B8,0x02DD,0x02DB,0x02C7,
160 static int mov_read_mac_string(MOVContext *c, AVIOContext *pb, int len,
161 char *dst, int dstlen)
164 char *end = dst+dstlen-1;
167 for (i = 0; i < len; i++) {
168 uint8_t t, c = avio_r8(pb);
176 PUT_UTF8(mac_to_unicode[c-0x80], t, if (p < end) *p++ = t;);
182 static int mov_read_covr(MOVContext *c, AVIOContext *pb, int type, int len)
185 MOVStreamContext *sc;
190 case 0xd: id = AV_CODEC_ID_MJPEG; break;
191 case 0xe: id = AV_CODEC_ID_PNG; break;
192 case 0x1b: id = AV_CODEC_ID_BMP; break;
194 av_log(c->fc, AV_LOG_WARNING, "Unknown cover type: 0x%x.\n", type);
199 st = avformat_new_stream(c->fc, NULL);
201 return AVERROR(ENOMEM);
202 sc = av_mallocz(sizeof(*sc));
204 return AVERROR(ENOMEM);
207 ret = av_get_packet(pb, &st->attached_pic, len);
211 if (st->attached_pic.size >= 8 && id != AV_CODEC_ID_BMP) {
212 if (AV_RB64(st->attached_pic.data) == 0x89504e470d0a1a0a) {
213 id = AV_CODEC_ID_PNG;
215 id = AV_CODEC_ID_MJPEG;
219 st->disposition |= AV_DISPOSITION_ATTACHED_PIC;
221 st->attached_pic.stream_index = st->index;
222 st->attached_pic.flags |= AV_PKT_FLAG_KEY;
224 st->codecpar->codec_type = AVMEDIA_TYPE_VIDEO;
225 st->codecpar->codec_id = id;
231 static int mov_metadata_loci(MOVContext *c, AVIOContext *pb, unsigned len)
233 char language[4] = { 0 };
234 char buf[200], place[100];
235 uint16_t langcode = 0;
236 double longitude, latitude, altitude;
237 const char *key = "location";
239 if (len < 4 + 2 + 1 + 1 + 4 + 4 + 4) {
240 av_log(c->fc, AV_LOG_ERROR, "loci too short\n");
241 return AVERROR_INVALIDDATA;
244 avio_skip(pb, 4); // version+flags
245 langcode = avio_rb16(pb);
246 ff_mov_lang_to_iso639(langcode, language);
249 len -= avio_get_str(pb, len, place, sizeof(place));
251 av_log(c->fc, AV_LOG_ERROR, "place name too long\n");
252 return AVERROR_INVALIDDATA;
254 avio_skip(pb, 1); // role
258 av_log(c->fc, AV_LOG_ERROR,
259 "loci too short (%u bytes left, need at least %d)\n", len, 12);
260 return AVERROR_INVALIDDATA;
262 longitude = ((int32_t) avio_rb32(pb)) / (float) (1 << 16);
263 latitude = ((int32_t) avio_rb32(pb)) / (float) (1 << 16);
264 altitude = ((int32_t) avio_rb32(pb)) / (float) (1 << 16);
266 // Try to output in the same format as the ?xyz field
267 snprintf(buf, sizeof(buf), "%+08.4f%+09.4f", latitude, longitude);
269 av_strlcatf(buf, sizeof(buf), "%+f", altitude);
270 av_strlcatf(buf, sizeof(buf), "/%s", place);
272 if (*language && strcmp(language, "und")) {
274 snprintf(key2, sizeof(key2), "%s-%s", key, language);
275 av_dict_set(&c->fc->metadata, key2, buf, 0);
277 c->fc->event_flags |= AVFMT_EVENT_FLAG_METADATA_UPDATED;
278 return av_dict_set(&c->fc->metadata, key, buf, 0);
281 static int mov_metadata_hmmt(MOVContext *c, AVIOContext *pb, unsigned len)
287 if (c->ignore_chapters)
290 n_hmmt = avio_rb32(pb);
291 for (i = 0; i < n_hmmt && !pb->eof_reached; i++) {
292 int moment_time = avio_rb32(pb);
293 avpriv_new_chapter(c->fc, i, av_make_q(1, 1000), moment_time, AV_NOPTS_VALUE, NULL);
298 static int mov_read_udta_string(MOVContext *c, AVIOContext *pb, MOVAtom atom)
300 char tmp_key[AV_FOURCC_MAX_STRING_SIZE] = {0};
301 char key2[32], language[4] = {0};
303 const char *key = NULL;
304 uint16_t langcode = 0;
305 uint32_t data_type = 0, str_size, str_size_alloc;
306 int (*parse)(MOVContext*, AVIOContext*, unsigned, const char*) = NULL;
311 case MKTAG( '@','P','R','M'): key = "premiere_version"; raw = 1; break;
312 case MKTAG( '@','P','R','Q'): key = "quicktime_version"; raw = 1; break;
313 case MKTAG( 'X','M','P','_'):
314 if (c->export_xmp) { key = "xmp"; raw = 1; } break;
315 case MKTAG( 'a','A','R','T'): key = "album_artist"; break;
316 case MKTAG( 'a','k','I','D'): key = "account_type";
317 parse = mov_metadata_int8_no_padding; break;
318 case MKTAG( 'a','p','I','D'): key = "account_id"; break;
319 case MKTAG( 'c','a','t','g'): key = "category"; break;
320 case MKTAG( 'c','p','i','l'): key = "compilation";
321 parse = mov_metadata_int8_no_padding; break;
322 case MKTAG( 'c','p','r','t'): key = "copyright"; break;
323 case MKTAG( 'd','e','s','c'): key = "description"; break;
324 case MKTAG( 'd','i','s','k'): key = "disc";
325 parse = mov_metadata_track_or_disc_number; break;
326 case MKTAG( 'e','g','i','d'): key = "episode_uid";
327 parse = mov_metadata_int8_no_padding; break;
328 case MKTAG( 'F','I','R','M'): key = "firmware"; raw = 1; break;
329 case MKTAG( 'g','n','r','e'): key = "genre";
330 parse = mov_metadata_gnre; break;
331 case MKTAG( 'h','d','v','d'): key = "hd_video";
332 parse = mov_metadata_int8_no_padding; break;
333 case MKTAG( 'H','M','M','T'):
334 return mov_metadata_hmmt(c, pb, atom.size);
335 case MKTAG( 'k','e','y','w'): key = "keywords"; break;
336 case MKTAG( 'l','d','e','s'): key = "synopsis"; break;
337 case MKTAG( 'l','o','c','i'):
338 return mov_metadata_loci(c, pb, atom.size);
339 case MKTAG( 'm','a','n','u'): key = "make"; break;
340 case MKTAG( 'm','o','d','l'): key = "model"; break;
341 case MKTAG( 'p','c','s','t'): key = "podcast";
342 parse = mov_metadata_int8_no_padding; break;
343 case MKTAG( 'p','g','a','p'): key = "gapless_playback";
344 parse = mov_metadata_int8_no_padding; break;
345 case MKTAG( 'p','u','r','d'): key = "purchase_date"; break;
346 case MKTAG( 'r','t','n','g'): key = "rating";
347 parse = mov_metadata_int8_no_padding; break;
348 case MKTAG( 's','o','a','a'): key = "sort_album_artist"; break;
349 case MKTAG( 's','o','a','l'): key = "sort_album"; break;
350 case MKTAG( 's','o','a','r'): key = "sort_artist"; break;
351 case MKTAG( 's','o','c','o'): key = "sort_composer"; break;
352 case MKTAG( 's','o','n','m'): key = "sort_name"; break;
353 case MKTAG( 's','o','s','n'): key = "sort_show"; break;
354 case MKTAG( 's','t','i','k'): key = "media_type";
355 parse = mov_metadata_int8_no_padding; break;
356 case MKTAG( 't','r','k','n'): key = "track";
357 parse = mov_metadata_track_or_disc_number; break;
358 case MKTAG( 't','v','e','n'): key = "episode_id"; break;
359 case MKTAG( 't','v','e','s'): key = "episode_sort";
360 parse = mov_metadata_int8_bypass_padding; break;
361 case MKTAG( 't','v','n','n'): key = "network"; break;
362 case MKTAG( 't','v','s','h'): key = "show"; break;
363 case MKTAG( 't','v','s','n'): key = "season_number";
364 parse = mov_metadata_int8_bypass_padding; break;
365 case MKTAG(0xa9,'A','R','T'): key = "artist"; break;
366 case MKTAG(0xa9,'P','R','D'): key = "producer"; break;
367 case MKTAG(0xa9,'a','l','b'): key = "album"; break;
368 case MKTAG(0xa9,'a','u','t'): key = "artist"; break;
369 case MKTAG(0xa9,'c','h','p'): key = "chapter"; break;
370 case MKTAG(0xa9,'c','m','t'): key = "comment"; break;
371 case MKTAG(0xa9,'c','o','m'): key = "composer"; break;
372 case MKTAG(0xa9,'c','p','y'): key = "copyright"; break;
373 case MKTAG(0xa9,'d','a','y'): key = "date"; break;
374 case MKTAG(0xa9,'d','i','r'): key = "director"; break;
375 case MKTAG(0xa9,'d','i','s'): key = "disclaimer"; break;
376 case MKTAG(0xa9,'e','d','1'): key = "edit_date"; break;
377 case MKTAG(0xa9,'e','n','c'): key = "encoder"; break;
378 case MKTAG(0xa9,'f','m','t'): key = "original_format"; break;
379 case MKTAG(0xa9,'g','e','n'): key = "genre"; break;
380 case MKTAG(0xa9,'g','r','p'): key = "grouping"; break;
381 case MKTAG(0xa9,'h','s','t'): key = "host_computer"; break;
382 case MKTAG(0xa9,'i','n','f'): key = "comment"; break;
383 case MKTAG(0xa9,'l','y','r'): key = "lyrics"; break;
384 case MKTAG(0xa9,'m','a','k'): key = "make"; break;
385 case MKTAG(0xa9,'m','o','d'): key = "model"; break;
386 case MKTAG(0xa9,'n','a','m'): key = "title"; break;
387 case MKTAG(0xa9,'o','p','e'): key = "original_artist"; break;
388 case MKTAG(0xa9,'p','r','d'): key = "producer"; break;
389 case MKTAG(0xa9,'p','r','f'): key = "performers"; break;
390 case MKTAG(0xa9,'r','e','q'): key = "playback_requirements"; break;
391 case MKTAG(0xa9,'s','r','c'): key = "original_source"; break;
392 case MKTAG(0xa9,'s','t','3'): key = "subtitle"; break;
393 case MKTAG(0xa9,'s','w','r'): key = "encoder"; break;
394 case MKTAG(0xa9,'t','o','o'): key = "encoder"; break;
395 case MKTAG(0xa9,'t','r','k'): key = "track"; break;
396 case MKTAG(0xa9,'u','r','l'): key = "URL"; break;
397 case MKTAG(0xa9,'w','r','n'): key = "warning"; break;
398 case MKTAG(0xa9,'w','r','t'): key = "composer"; break;
399 case MKTAG(0xa9,'x','y','z'): key = "location"; break;
402 if (c->itunes_metadata && atom.size > 8) {
403 int data_size = avio_rb32(pb);
404 int tag = avio_rl32(pb);
405 if (tag == MKTAG('d','a','t','a') && data_size <= atom.size) {
406 data_type = avio_rb32(pb); // type
407 avio_rb32(pb); // unknown
408 str_size = data_size - 16;
411 if (atom.type == MKTAG('c', 'o', 'v', 'r')) {
412 int ret = mov_read_covr(c, pb, data_type, str_size);
414 av_log(c->fc, AV_LOG_ERROR, "Error parsing cover art.\n");
417 atom.size -= str_size;
421 } else if (!key && c->found_hdlr_mdta && c->meta_keys) {
422 uint32_t index = AV_RB32(&atom.type);
423 if (index < c->meta_keys_count && index > 0) {
424 key = c->meta_keys[index];
426 av_log(c->fc, AV_LOG_WARNING,
427 "The index of 'data' is out of range: %"PRId32" < 1 or >= %d.\n",
428 index, c->meta_keys_count);
432 } else if (atom.size > 4 && key && !c->itunes_metadata && !raw) {
433 str_size = avio_rb16(pb); // string length
434 if (str_size > atom.size) {
436 avio_seek(pb, -2, SEEK_CUR);
437 av_log(c->fc, AV_LOG_WARNING, "UDTA parsing failed retrying raw\n");
440 langcode = avio_rb16(pb);
441 ff_mov_lang_to_iso639(langcode, language);
444 str_size = atom.size;
446 if (c->export_all && !key) {
447 key = av_fourcc_make_string(tmp_key, atom.type);
452 if (atom.size < 0 || str_size >= INT_MAX/2)
453 return AVERROR_INVALIDDATA;
455 // Allocates enough space if data_type is a int32 or float32 number, otherwise
456 // worst-case requirement for output string in case of utf8 coded input
457 num = (data_type >= 21 && data_type <= 23);
458 str_size_alloc = (num ? 512 : (raw ? str_size : str_size * 2)) + 1;
459 str = av_mallocz(str_size_alloc);
461 return AVERROR(ENOMEM);
464 parse(c, pb, str_size, key);
466 if (!raw && (data_type == 3 || (data_type == 0 && (langcode < 0x400 || langcode == 0x7fff)))) { // MAC Encoded
467 mov_read_mac_string(c, pb, str_size, str, str_size_alloc);
468 } else if (data_type == 21) { // BE signed integer, variable size
471 val = (int8_t)avio_r8(pb);
472 else if (str_size == 2)
473 val = (int16_t)avio_rb16(pb);
474 else if (str_size == 3)
475 val = ((int32_t)(avio_rb24(pb)<<8))>>8;
476 else if (str_size == 4)
477 val = (int32_t)avio_rb32(pb);
478 if (snprintf(str, str_size_alloc, "%d", val) >= str_size_alloc) {
479 av_log(c->fc, AV_LOG_ERROR,
480 "Failed to store the number (%d) in string.\n", val);
482 return AVERROR_INVALIDDATA;
484 } else if (data_type == 22) { // BE unsigned integer, variable size
485 unsigned int val = 0;
488 else if (str_size == 2)
490 else if (str_size == 3)
492 else if (str_size == 4)
494 if (snprintf(str, str_size_alloc, "%u", val) >= str_size_alloc) {
495 av_log(c->fc, AV_LOG_ERROR,
496 "Failed to store the number (%u) in string.\n", val);
498 return AVERROR_INVALIDDATA;
500 } else if (data_type == 23 && str_size >= 4) { // BE float32
501 float val = av_int2float(avio_rb32(pb));
502 if (snprintf(str, str_size_alloc, "%f", val) >= str_size_alloc) {
503 av_log(c->fc, AV_LOG_ERROR,
504 "Failed to store the float32 number (%f) in string.\n", val);
506 return AVERROR_INVALIDDATA;
509 int ret = ffio_read_size(pb, str, str_size);
516 c->fc->event_flags |= AVFMT_EVENT_FLAG_METADATA_UPDATED;
517 av_dict_set(&c->fc->metadata, key, str, 0);
518 if (*language && strcmp(language, "und")) {
519 snprintf(key2, sizeof(key2), "%s-%s", key, language);
520 av_dict_set(&c->fc->metadata, key2, str, 0);
522 if (!strcmp(key, "encoder")) {
523 int major, minor, micro;
524 if (sscanf(str, "HandBrake %d.%d.%d", &major, &minor, µ) == 3) {
525 c->handbrake_version = 1000000*major + 1000*minor + micro;
534 static int mov_read_chpl(MOVContext *c, AVIOContext *pb, MOVAtom atom)
537 int i, nb_chapters, str_len, version;
541 if (c->ignore_chapters)
544 if ((atom.size -= 5) < 0)
547 version = avio_r8(pb);
550 avio_rb32(pb); // ???
551 nb_chapters = avio_r8(pb);
553 for (i = 0; i < nb_chapters; i++) {
557 start = avio_rb64(pb);
558 str_len = avio_r8(pb);
560 if ((atom.size -= 9+str_len) < 0)
563 ret = ffio_read_size(pb, str, str_len);
567 avpriv_new_chapter(c->fc, i, (AVRational){1,10000000}, start, AV_NOPTS_VALUE, str);
572 #define MIN_DATA_ENTRY_BOX_SIZE 12
573 static int mov_read_dref(MOVContext *c, AVIOContext *pb, MOVAtom atom)
576 MOVStreamContext *sc;
579 if (c->fc->nb_streams < 1)
581 st = c->fc->streams[c->fc->nb_streams-1];
584 avio_rb32(pb); // version + flags
585 entries = avio_rb32(pb);
587 entries > (atom.size - 1) / MIN_DATA_ENTRY_BOX_SIZE + 1 ||
588 entries >= UINT_MAX / sizeof(*sc->drefs))
589 return AVERROR_INVALIDDATA;
593 sc->drefs = av_mallocz(entries * sizeof(*sc->drefs));
595 return AVERROR(ENOMEM);
596 sc->drefs_count = entries;
598 for (i = 0; i < entries; i++) {
599 MOVDref *dref = &sc->drefs[i];
600 uint32_t size = avio_rb32(pb);
601 int64_t next = avio_tell(pb) + size - 4;
604 return AVERROR_INVALIDDATA;
606 dref->type = avio_rl32(pb);
607 avio_rb32(pb); // version + flags
609 if (dref->type == MKTAG('a','l','i','s') && size > 150) {
610 /* macintosh alias record */
611 uint16_t volume_len, len;
617 volume_len = avio_r8(pb);
618 volume_len = FFMIN(volume_len, 27);
619 ret = ffio_read_size(pb, dref->volume, 27);
622 dref->volume[volume_len] = 0;
623 av_log(c->fc, AV_LOG_DEBUG, "volume %s, len %d\n", dref->volume, volume_len);
628 len = FFMIN(len, 63);
629 ret = ffio_read_size(pb, dref->filename, 63);
632 dref->filename[len] = 0;
633 av_log(c->fc, AV_LOG_DEBUG, "filename %s, len %d\n", dref->filename, len);
637 /* read next level up_from_alias/down_to_target */
638 dref->nlvl_from = avio_rb16(pb);
639 dref->nlvl_to = avio_rb16(pb);
640 av_log(c->fc, AV_LOG_DEBUG, "nlvl from %d, nlvl to %d\n",
641 dref->nlvl_from, dref->nlvl_to);
645 for (type = 0; type != -1 && avio_tell(pb) < next; ) {
648 type = avio_rb16(pb);
650 av_log(c->fc, AV_LOG_DEBUG, "type %d, len %d\n", type, len);
653 if (type == 2) { // absolute path
655 dref->path = av_mallocz(len+1);
657 return AVERROR(ENOMEM);
659 ret = ffio_read_size(pb, dref->path, len);
661 av_freep(&dref->path);
664 if (len > volume_len && !strncmp(dref->path, dref->volume, volume_len)) {
666 memmove(dref->path, dref->path+volume_len, len);
669 // trim string of any ending zeros
670 for (j = len - 1; j >= 0; j--) {
671 if (dref->path[j] == 0)
676 for (j = 0; j < len; j++)
677 if (dref->path[j] == ':' || dref->path[j] == 0)
679 av_log(c->fc, AV_LOG_DEBUG, "path %s\n", dref->path);
680 } else if (type == 0) { // directory name
682 dref->dir = av_malloc(len+1);
684 return AVERROR(ENOMEM);
686 ret = ffio_read_size(pb, dref->dir, len);
688 av_freep(&dref->dir);
692 for (j = 0; j < len; j++)
693 if (dref->dir[j] == ':')
695 av_log(c->fc, AV_LOG_DEBUG, "dir %s\n", dref->dir);
700 av_log(c->fc, AV_LOG_DEBUG, "Unknown dref type 0x%08"PRIx32" size %"PRIu32"\n",
705 avio_seek(pb, next, SEEK_SET);
710 static int mov_read_hdlr(MOVContext *c, AVIOContext *pb, MOVAtom atom)
719 avio_r8(pb); /* version */
720 avio_rb24(pb); /* flags */
723 ctype = avio_rl32(pb);
724 type = avio_rl32(pb); /* component subtype */
726 av_log(c->fc, AV_LOG_TRACE, "ctype=%s\n", av_fourcc2str(ctype));
727 av_log(c->fc, AV_LOG_TRACE, "stype=%s\n", av_fourcc2str(type));
729 if (c->trak_index < 0) { // meta not inside a trak
730 if (type == MKTAG('m','d','t','a')) {
731 c->found_hdlr_mdta = 1;
736 st = c->fc->streams[c->fc->nb_streams-1];
738 if (type == MKTAG('v','i','d','e'))
739 st->codecpar->codec_type = AVMEDIA_TYPE_VIDEO;
740 else if (type == MKTAG('s','o','u','n'))
741 st->codecpar->codec_type = AVMEDIA_TYPE_AUDIO;
742 else if (type == MKTAG('m','1','a',' '))
743 st->codecpar->codec_id = AV_CODEC_ID_MP2;
744 else if ((type == MKTAG('s','u','b','p')) || (type == MKTAG('c','l','c','p')))
745 st->codecpar->codec_type = AVMEDIA_TYPE_SUBTITLE;
747 avio_rb32(pb); /* component manufacture */
748 avio_rb32(pb); /* component flags */
749 avio_rb32(pb); /* component flags mask */
751 title_size = atom.size - 24;
752 if (title_size > 0) {
753 if (title_size > FFMIN(INT_MAX, SIZE_MAX-1))
754 return AVERROR_INVALIDDATA;
755 title_str = av_malloc(title_size + 1); /* Add null terminator */
757 return AVERROR(ENOMEM);
759 ret = ffio_read_size(pb, title_str, title_size);
761 av_freep(&title_str);
764 title_str[title_size] = 0;
766 int off = (!c->isom && title_str[0] == title_size - 1);
767 // flag added so as to not set stream handler name if already set from mdia->hdlr
768 av_dict_set(&st->metadata, "handler_name", title_str + off, AV_DICT_DONT_OVERWRITE);
770 av_freep(&title_str);
776 static int mov_read_esds(MOVContext *c, AVIOContext *pb, MOVAtom atom)
778 return ff_mov_read_esds(c->fc, pb);
781 static int mov_read_dac3(MOVContext *c, AVIOContext *pb, MOVAtom atom)
784 enum AVAudioServiceType *ast;
785 int ac3info, acmod, lfeon, bsmod;
787 if (c->fc->nb_streams < 1)
789 st = c->fc->streams[c->fc->nb_streams-1];
791 ast = (enum AVAudioServiceType*)av_stream_new_side_data(st, AV_PKT_DATA_AUDIO_SERVICE_TYPE,
794 return AVERROR(ENOMEM);
796 ac3info = avio_rb24(pb);
797 bsmod = (ac3info >> 14) & 0x7;
798 acmod = (ac3info >> 11) & 0x7;
799 lfeon = (ac3info >> 10) & 0x1;
800 st->codecpar->channels = ((int[]){2,1,2,3,3,4,4,5})[acmod] + lfeon;
801 st->codecpar->channel_layout = avpriv_ac3_channel_layout_tab[acmod];
803 st->codecpar->channel_layout |= AV_CH_LOW_FREQUENCY;
805 if (st->codecpar->channels > 1 && bsmod == 0x7)
806 *ast = AV_AUDIO_SERVICE_TYPE_KARAOKE;
808 #if FF_API_LAVF_AVCTX
809 FF_DISABLE_DEPRECATION_WARNINGS
810 st->codec->audio_service_type = *ast;
811 FF_ENABLE_DEPRECATION_WARNINGS
817 static int mov_read_dec3(MOVContext *c, AVIOContext *pb, MOVAtom atom)
820 enum AVAudioServiceType *ast;
821 int eac3info, acmod, lfeon, bsmod;
823 if (c->fc->nb_streams < 1)
825 st = c->fc->streams[c->fc->nb_streams-1];
827 ast = (enum AVAudioServiceType*)av_stream_new_side_data(st, AV_PKT_DATA_AUDIO_SERVICE_TYPE,
830 return AVERROR(ENOMEM);
832 /* No need to parse fields for additional independent substreams and its
833 * associated dependent substreams since libavcodec's E-AC-3 decoder
834 * does not support them yet. */
835 avio_rb16(pb); /* data_rate and num_ind_sub */
836 eac3info = avio_rb24(pb);
837 bsmod = (eac3info >> 12) & 0x1f;
838 acmod = (eac3info >> 9) & 0x7;
839 lfeon = (eac3info >> 8) & 0x1;
840 st->codecpar->channel_layout = avpriv_ac3_channel_layout_tab[acmod];
842 st->codecpar->channel_layout |= AV_CH_LOW_FREQUENCY;
843 st->codecpar->channels = av_get_channel_layout_nb_channels(st->codecpar->channel_layout);
845 if (st->codecpar->channels > 1 && bsmod == 0x7)
846 *ast = AV_AUDIO_SERVICE_TYPE_KARAOKE;
848 #if FF_API_LAVF_AVCTX
849 FF_DISABLE_DEPRECATION_WARNINGS
850 st->codec->audio_service_type = *ast;
851 FF_ENABLE_DEPRECATION_WARNINGS
857 static int mov_read_ddts(MOVContext *c, AVIOContext *pb, MOVAtom atom)
860 uint8_t buf[DDTS_SIZE + AV_INPUT_BUFFER_PADDING_SIZE];
862 uint32_t frame_duration_code = 0;
863 uint32_t channel_layout_code = 0;
867 if ((ret = ffio_read_size(pb, buf, DDTS_SIZE)) < 0)
870 init_get_bits(&gb, buf, 8 * DDTS_SIZE);
872 if (c->fc->nb_streams < 1) {
875 st = c->fc->streams[c->fc->nb_streams-1];
877 st->codecpar->sample_rate = get_bits_long(&gb, 32);
878 if (st->codecpar->sample_rate <= 0) {
879 av_log(c->fc, AV_LOG_ERROR, "Invalid sample rate %d\n", st->codecpar->sample_rate);
880 return AVERROR_INVALIDDATA;
882 skip_bits_long(&gb, 32); /* max bitrate */
883 st->codecpar->bit_rate = get_bits_long(&gb, 32);
884 st->codecpar->bits_per_coded_sample = get_bits(&gb, 8);
885 frame_duration_code = get_bits(&gb, 2);
886 skip_bits(&gb, 30); /* various fields */
887 channel_layout_code = get_bits(&gb, 16);
889 st->codecpar->frame_size =
890 (frame_duration_code == 0) ? 512 :
891 (frame_duration_code == 1) ? 1024 :
892 (frame_duration_code == 2) ? 2048 :
893 (frame_duration_code == 3) ? 4096 : 0;
895 if (channel_layout_code > 0xff) {
896 av_log(c->fc, AV_LOG_WARNING, "Unsupported DTS audio channel layout\n");
898 st->codecpar->channel_layout =
899 ((channel_layout_code & 0x1) ? AV_CH_FRONT_CENTER : 0) |
900 ((channel_layout_code & 0x2) ? AV_CH_FRONT_LEFT : 0) |
901 ((channel_layout_code & 0x2) ? AV_CH_FRONT_RIGHT : 0) |
902 ((channel_layout_code & 0x4) ? AV_CH_SIDE_LEFT : 0) |
903 ((channel_layout_code & 0x4) ? AV_CH_SIDE_RIGHT : 0) |
904 ((channel_layout_code & 0x8) ? AV_CH_LOW_FREQUENCY : 0);
906 st->codecpar->channels = av_get_channel_layout_nb_channels(st->codecpar->channel_layout);
911 static int mov_read_chan(MOVContext *c, AVIOContext *pb, MOVAtom atom)
915 if (c->fc->nb_streams < 1)
917 st = c->fc->streams[c->fc->nb_streams-1];
922 /* skip version and flags */
925 ff_mov_read_chan(c->fc, pb, st, atom.size - 4);
930 static int mov_read_wfex(MOVContext *c, AVIOContext *pb, MOVAtom atom)
935 if (c->fc->nb_streams < 1)
937 st = c->fc->streams[c->fc->nb_streams-1];
939 if ((ret = ff_get_wav_header(c->fc, pb, st->codecpar, atom.size, 0)) < 0)
940 av_log(c->fc, AV_LOG_WARNING, "get_wav_header failed\n");
945 static int mov_read_pasp(MOVContext *c, AVIOContext *pb, MOVAtom atom)
947 const int num = avio_rb32(pb);
948 const int den = avio_rb32(pb);
951 if (c->fc->nb_streams < 1)
953 st = c->fc->streams[c->fc->nb_streams-1];
955 if ((st->sample_aspect_ratio.den != 1 || st->sample_aspect_ratio.num) && // default
956 (den != st->sample_aspect_ratio.den || num != st->sample_aspect_ratio.num)) {
957 av_log(c->fc, AV_LOG_WARNING,
958 "sample aspect ratio already set to %d:%d, ignoring 'pasp' atom (%d:%d)\n",
959 st->sample_aspect_ratio.num, st->sample_aspect_ratio.den,
961 } else if (den != 0) {
962 av_reduce(&st->sample_aspect_ratio.num, &st->sample_aspect_ratio.den,
968 /* this atom contains actual media data */
969 static int mov_read_mdat(MOVContext *c, AVIOContext *pb, MOVAtom atom)
971 if (atom.size == 0) /* wrong one (MP4) */
974 return 0; /* now go for moov */
977 #define DRM_BLOB_SIZE 56
979 static int mov_read_adrm(MOVContext *c, AVIOContext *pb, MOVAtom atom)
981 uint8_t intermediate_key[20];
982 uint8_t intermediate_iv[20];
985 uint8_t file_checksum[20];
986 uint8_t calculated_checksum[20];
990 uint8_t *activation_bytes = c->activation_bytes;
991 uint8_t *fixed_key = c->audible_fixed_key;
995 sha = av_sha_alloc();
997 return AVERROR(ENOMEM);
998 av_free(c->aes_decrypt);
999 c->aes_decrypt = av_aes_alloc();
1000 if (!c->aes_decrypt) {
1001 ret = AVERROR(ENOMEM);
1005 /* drm blob processing */
1006 avio_read(pb, output, 8); // go to offset 8, absolute position 0x251
1007 avio_read(pb, input, DRM_BLOB_SIZE);
1008 avio_read(pb, output, 4); // go to offset 4, absolute position 0x28d
1009 avio_read(pb, file_checksum, 20);
1011 av_log(c->fc, AV_LOG_INFO, "[aax] file checksum == "); // required by external tools
1012 for (i = 0; i < 20; i++)
1013 av_log(c->fc, AV_LOG_INFO, "%02x", file_checksum[i]);
1014 av_log(c->fc, AV_LOG_INFO, "\n");
1016 /* verify activation data */
1017 if (!activation_bytes) {
1018 av_log(c->fc, AV_LOG_WARNING, "[aax] activation_bytes option is missing!\n");
1019 ret = 0; /* allow ffprobe to continue working on .aax files */
1022 if (c->activation_bytes_size != 4) {
1023 av_log(c->fc, AV_LOG_FATAL, "[aax] activation_bytes value needs to be 4 bytes!\n");
1024 ret = AVERROR(EINVAL);
1028 /* verify fixed key */
1029 if (c->audible_fixed_key_size != 16) {
1030 av_log(c->fc, AV_LOG_FATAL, "[aax] audible_fixed_key value needs to be 16 bytes!\n");
1031 ret = AVERROR(EINVAL);
1035 /* AAX (and AAX+) key derivation */
1036 av_sha_init(sha, 160);
1037 av_sha_update(sha, fixed_key, 16);
1038 av_sha_update(sha, activation_bytes, 4);
1039 av_sha_final(sha, intermediate_key);
1040 av_sha_init(sha, 160);
1041 av_sha_update(sha, fixed_key, 16);
1042 av_sha_update(sha, intermediate_key, 20);
1043 av_sha_update(sha, activation_bytes, 4);
1044 av_sha_final(sha, intermediate_iv);
1045 av_sha_init(sha, 160);
1046 av_sha_update(sha, intermediate_key, 16);
1047 av_sha_update(sha, intermediate_iv, 16);
1048 av_sha_final(sha, calculated_checksum);
1049 if (memcmp(calculated_checksum, file_checksum, 20)) { // critical error
1050 av_log(c->fc, AV_LOG_ERROR, "[aax] mismatch in checksums!\n");
1051 ret = AVERROR_INVALIDDATA;
1054 av_aes_init(c->aes_decrypt, intermediate_key, 128, 1);
1055 av_aes_crypt(c->aes_decrypt, output, input, DRM_BLOB_SIZE >> 4, intermediate_iv, 1);
1056 for (i = 0; i < 4; i++) {
1057 // file data (in output) is stored in big-endian mode
1058 if (activation_bytes[i] != output[3 - i]) { // critical error
1059 av_log(c->fc, AV_LOG_ERROR, "[aax] error in drm blob decryption!\n");
1060 ret = AVERROR_INVALIDDATA;
1064 memcpy(c->file_key, output + 8, 16);
1065 memcpy(input, output + 26, 16);
1066 av_sha_init(sha, 160);
1067 av_sha_update(sha, input, 16);
1068 av_sha_update(sha, c->file_key, 16);
1069 av_sha_update(sha, fixed_key, 16);
1070 av_sha_final(sha, c->file_iv);
1078 // Audible AAX (and AAX+) bytestream decryption
1079 static int aax_filter(uint8_t *input, int size, MOVContext *c)
1082 unsigned char iv[16];
1084 memcpy(iv, c->file_iv, 16); // iv is overwritten
1085 blocks = size >> 4; // trailing bytes are not encrypted!
1086 av_aes_init(c->aes_decrypt, c->file_key, 128, 1);
1087 av_aes_crypt(c->aes_decrypt, input, input, blocks, iv, 1);
1092 /* read major brand, minor version and compatible brands and store them as metadata */
1093 static int mov_read_ftyp(MOVContext *c, AVIOContext *pb, MOVAtom atom)
1096 int comp_brand_size;
1097 char* comp_brands_str;
1098 uint8_t type[5] = {0};
1099 int ret = ffio_read_size(pb, type, 4);
1103 if (strcmp(type, "qt "))
1105 av_log(c->fc, AV_LOG_DEBUG, "ISO: File Type Major Brand: %.4s\n",(char *)&type);
1106 av_dict_set(&c->fc->metadata, "major_brand", type, 0);
1107 minor_ver = avio_rb32(pb); /* minor version */
1108 av_dict_set_int(&c->fc->metadata, "minor_version", minor_ver, 0);
1110 comp_brand_size = atom.size - 8;
1111 if (comp_brand_size < 0 || comp_brand_size == INT_MAX)
1112 return AVERROR_INVALIDDATA;
1113 comp_brands_str = av_malloc(comp_brand_size + 1); /* Add null terminator */
1114 if (!comp_brands_str)
1115 return AVERROR(ENOMEM);
1117 ret = ffio_read_size(pb, comp_brands_str, comp_brand_size);
1119 av_freep(&comp_brands_str);
1122 comp_brands_str[comp_brand_size] = 0;
1123 av_dict_set(&c->fc->metadata, "compatible_brands",
1124 comp_brands_str, AV_DICT_DONT_STRDUP_VAL);
1129 /* this atom should contain all header atoms */
1130 static int mov_read_moov(MOVContext *c, AVIOContext *pb, MOVAtom atom)
1134 if (c->found_moov) {
1135 av_log(c->fc, AV_LOG_WARNING, "Found duplicated MOOV Atom. Skipped it\n");
1136 avio_skip(pb, atom.size);
1140 if ((ret = mov_read_default(c, pb, atom)) < 0)
1142 /* we parsed the 'moov' atom, we can terminate the parsing as soon as we find the 'mdat' */
1143 /* so we don't parse the whole file if over a network */
1145 return 0; /* now go for mdat */
1148 static MOVFragmentStreamInfo * get_frag_stream_info(
1149 MOVFragmentIndex *frag_index,
1154 MOVFragmentIndexItem * item;
1156 if (index < 0 || index >= frag_index->nb_items)
1158 item = &frag_index->item[index];
1159 for (i = 0; i < item->nb_stream_info; i++)
1160 if (item->stream_info[i].id == id)
1161 return &item->stream_info[i];
1163 // This shouldn't happen
1167 static void set_frag_stream(MOVFragmentIndex *frag_index, int id)
1170 MOVFragmentIndexItem * item;
1172 if (frag_index->current < 0 ||
1173 frag_index->current >= frag_index->nb_items)
1176 item = &frag_index->item[frag_index->current];
1177 for (i = 0; i < item->nb_stream_info; i++)
1178 if (item->stream_info[i].id == id) {
1183 // id not found. This shouldn't happen.
1187 static MOVFragmentStreamInfo * get_current_frag_stream_info(
1188 MOVFragmentIndex *frag_index)
1190 MOVFragmentIndexItem *item;
1191 if (frag_index->current < 0 ||
1192 frag_index->current >= frag_index->nb_items)
1195 item = &frag_index->item[frag_index->current];
1196 if (item->current >= 0 && item->current < item->nb_stream_info)
1197 return &item->stream_info[item->current];
1199 // This shouldn't happen
1203 static int search_frag_moof_offset(MOVFragmentIndex *frag_index, int64_t offset)
1206 int64_t moof_offset;
1208 // Optimize for appending new entries
1209 if (!frag_index->nb_items ||
1210 frag_index->item[frag_index->nb_items - 1].moof_offset < offset)
1211 return frag_index->nb_items;
1214 b = frag_index->nb_items;
1218 moof_offset = frag_index->item[m].moof_offset;
1219 if (moof_offset >= offset)
1221 if (moof_offset <= offset)
1227 static int64_t get_stream_info_time(MOVFragmentStreamInfo * frag_stream_info)
1229 av_assert0(frag_stream_info);
1230 if (frag_stream_info->sidx_pts != AV_NOPTS_VALUE)
1231 return frag_stream_info->sidx_pts;
1232 if (frag_stream_info->first_tfra_pts != AV_NOPTS_VALUE)
1233 return frag_stream_info->first_tfra_pts;
1234 return frag_stream_info->tfdt_dts;
1237 static int64_t get_frag_time(MOVFragmentIndex *frag_index,
1238 int index, int track_id)
1240 MOVFragmentStreamInfo * frag_stream_info;
1244 if (track_id >= 0) {
1245 frag_stream_info = get_frag_stream_info(frag_index, index, track_id);
1246 return frag_stream_info->sidx_pts;
1249 for (i = 0; i < frag_index->item[index].nb_stream_info; i++) {
1250 frag_stream_info = &frag_index->item[index].stream_info[i];
1251 timestamp = get_stream_info_time(frag_stream_info);
1252 if (timestamp != AV_NOPTS_VALUE)
1255 return AV_NOPTS_VALUE;
1258 static int search_frag_timestamp(MOVFragmentIndex *frag_index,
1259 AVStream *st, int64_t timestamp)
1266 // If the stream is referenced by any sidx, limit the search
1267 // to fragments that referenced this stream in the sidx
1268 MOVStreamContext *sc = st->priv_data;
1274 b = frag_index->nb_items;
1277 m0 = m = (a + b) >> 1;
1280 (frag_time = get_frag_time(frag_index, m, id)) == AV_NOPTS_VALUE)
1283 if (m < b && frag_time <= timestamp)
1292 static int update_frag_index(MOVContext *c, int64_t offset)
1295 MOVFragmentIndexItem * item;
1296 MOVFragmentStreamInfo * frag_stream_info;
1298 // If moof_offset already exists in frag_index, return index to it
1299 index = search_frag_moof_offset(&c->frag_index, offset);
1300 if (index < c->frag_index.nb_items &&
1301 c->frag_index.item[index].moof_offset == offset)
1304 // offset is not yet in frag index.
1305 // Insert new item at index (sorted by moof offset)
1306 item = av_fast_realloc(c->frag_index.item,
1307 &c->frag_index.allocated_size,
1308 (c->frag_index.nb_items + 1) *
1309 sizeof(*c->frag_index.item));
1312 c->frag_index.item = item;
1314 frag_stream_info = av_realloc_array(NULL, c->fc->nb_streams,
1315 sizeof(*item->stream_info));
1316 if (!frag_stream_info)
1319 for (i = 0; i < c->fc->nb_streams; i++) {
1320 // Avoid building frag index if streams lack track id.
1321 if (c->fc->streams[i]->id < 0) {
1322 av_free(frag_stream_info);
1323 return AVERROR_INVALIDDATA;
1326 frag_stream_info[i].id = c->fc->streams[i]->id;
1327 frag_stream_info[i].sidx_pts = AV_NOPTS_VALUE;
1328 frag_stream_info[i].tfdt_dts = AV_NOPTS_VALUE;
1329 frag_stream_info[i].next_trun_dts = AV_NOPTS_VALUE;
1330 frag_stream_info[i].first_tfra_pts = AV_NOPTS_VALUE;
1331 frag_stream_info[i].index_entry = -1;
1332 frag_stream_info[i].encryption_index = NULL;
1335 if (index < c->frag_index.nb_items)
1336 memmove(c->frag_index.item + index + 1, c->frag_index.item + index,
1337 (c->frag_index.nb_items - index) * sizeof(*c->frag_index.item));
1339 item = &c->frag_index.item[index];
1340 item->headers_read = 0;
1342 item->nb_stream_info = c->fc->nb_streams;
1343 item->moof_offset = offset;
1344 item->stream_info = frag_stream_info;
1345 c->frag_index.nb_items++;
1350 static void fix_frag_index_entries(MOVFragmentIndex *frag_index, int index,
1351 int id, int entries)
1354 MOVFragmentStreamInfo * frag_stream_info;
1358 for (i = index; i < frag_index->nb_items; i++) {
1359 frag_stream_info = get_frag_stream_info(frag_index, i, id);
1360 if (frag_stream_info && frag_stream_info->index_entry >= 0)
1361 frag_stream_info->index_entry += entries;
1365 static int mov_read_moof(MOVContext *c, AVIOContext *pb, MOVAtom atom)
1367 // Set by mov_read_tfhd(). mov_read_trun() will reject files missing tfhd.
1368 c->fragment.found_tfhd = 0;
1370 if (!c->has_looked_for_mfra && c->use_mfra_for > 0) {
1371 c->has_looked_for_mfra = 1;
1372 if (pb->seekable & AVIO_SEEKABLE_NORMAL) {
1374 av_log(c->fc, AV_LOG_VERBOSE, "stream has moof boxes, will look "
1376 if ((ret = mov_read_mfra(c, pb)) < 0) {
1377 av_log(c->fc, AV_LOG_VERBOSE, "found a moof box but failed to "
1378 "read the mfra (may be a live ismv)\n");
1381 av_log(c->fc, AV_LOG_VERBOSE, "found a moof box but stream is not "
1382 "seekable, can not look for mfra\n");
1385 c->fragment.moof_offset = c->fragment.implicit_offset = avio_tell(pb) - 8;
1386 av_log(c->fc, AV_LOG_TRACE, "moof offset %"PRIx64"\n", c->fragment.moof_offset);
1387 c->frag_index.current = update_frag_index(c, c->fragment.moof_offset);
1388 return mov_read_default(c, pb, atom);
1391 static void mov_metadata_creation_time(AVDictionary **metadata, int64_t time, void *logctx)
1394 if (time >= 2082844800)
1395 time -= 2082844800; /* seconds between 1904-01-01 and Epoch */
1397 if ((int64_t)(time * 1000000ULL) / 1000000 != time) {
1398 av_log(logctx, AV_LOG_DEBUG, "creation_time is not representable\n");
1402 avpriv_dict_set_timestamp(metadata, "creation_time", time * 1000000);
1406 static int mov_read_mdhd(MOVContext *c, AVIOContext *pb, MOVAtom atom)
1409 MOVStreamContext *sc;
1411 char language[4] = {0};
1413 int64_t creation_time;
1415 if (c->fc->nb_streams < 1)
1417 st = c->fc->streams[c->fc->nb_streams-1];
1420 if (sc->time_scale) {
1421 av_log(c->fc, AV_LOG_ERROR, "Multiple mdhd?\n");
1422 return AVERROR_INVALIDDATA;
1425 version = avio_r8(pb);
1427 avpriv_request_sample(c->fc, "Version %d", version);
1428 return AVERROR_PATCHWELCOME;
1430 avio_rb24(pb); /* flags */
1432 creation_time = avio_rb64(pb);
1435 creation_time = avio_rb32(pb);
1436 avio_rb32(pb); /* modification time */
1438 mov_metadata_creation_time(&st->metadata, creation_time, c->fc);
1440 sc->time_scale = avio_rb32(pb);
1441 if (sc->time_scale <= 0) {
1442 av_log(c->fc, AV_LOG_ERROR, "Invalid mdhd time scale %d, defaulting to 1\n", sc->time_scale);
1445 st->duration = (version == 1) ? avio_rb64(pb) : avio_rb32(pb); /* duration */
1447 lang = avio_rb16(pb); /* language */
1448 if (ff_mov_lang_to_iso639(lang, language))
1449 av_dict_set(&st->metadata, "language", language, 0);
1450 avio_rb16(pb); /* quality */
1455 static int mov_read_mvhd(MOVContext *c, AVIOContext *pb, MOVAtom atom)
1458 int64_t creation_time;
1459 int version = avio_r8(pb); /* version */
1460 avio_rb24(pb); /* flags */
1463 creation_time = avio_rb64(pb);
1466 creation_time = avio_rb32(pb);
1467 avio_rb32(pb); /* modification time */
1469 mov_metadata_creation_time(&c->fc->metadata, creation_time, c->fc);
1470 c->time_scale = avio_rb32(pb); /* time scale */
1471 if (c->time_scale <= 0) {
1472 av_log(c->fc, AV_LOG_ERROR, "Invalid mvhd time scale %d, defaulting to 1\n", c->time_scale);
1475 av_log(c->fc, AV_LOG_TRACE, "time scale = %i\n", c->time_scale);
1477 c->duration = (version == 1) ? avio_rb64(pb) : avio_rb32(pb); /* duration */
1478 // set the AVCodecContext duration because the duration of individual tracks
1479 // may be inaccurate
1480 if (c->time_scale > 0 && !c->trex_data)
1481 c->fc->duration = av_rescale(c->duration, AV_TIME_BASE, c->time_scale);
1482 avio_rb32(pb); /* preferred scale */
1484 avio_rb16(pb); /* preferred volume */
1486 avio_skip(pb, 10); /* reserved */
1488 /* movie display matrix, store it in main context and use it later on */
1489 for (i = 0; i < 3; i++) {
1490 c->movie_display_matrix[i][0] = avio_rb32(pb); // 16.16 fixed point
1491 c->movie_display_matrix[i][1] = avio_rb32(pb); // 16.16 fixed point
1492 c->movie_display_matrix[i][2] = avio_rb32(pb); // 2.30 fixed point
1495 avio_rb32(pb); /* preview time */
1496 avio_rb32(pb); /* preview duration */
1497 avio_rb32(pb); /* poster time */
1498 avio_rb32(pb); /* selection time */
1499 avio_rb32(pb); /* selection duration */
1500 avio_rb32(pb); /* current time */
1501 avio_rb32(pb); /* next track ID */
1506 static int mov_read_enda(MOVContext *c, AVIOContext *pb, MOVAtom atom)
1511 if (c->fc->nb_streams < 1)
1513 st = c->fc->streams[c->fc->nb_streams-1];
1515 little_endian = avio_rb16(pb) & 0xFF;
1516 av_log(c->fc, AV_LOG_TRACE, "enda %d\n", little_endian);
1517 if (little_endian == 1) {
1518 switch (st->codecpar->codec_id) {
1519 case AV_CODEC_ID_PCM_S24BE:
1520 st->codecpar->codec_id = AV_CODEC_ID_PCM_S24LE;
1522 case AV_CODEC_ID_PCM_S32BE:
1523 st->codecpar->codec_id = AV_CODEC_ID_PCM_S32LE;
1525 case AV_CODEC_ID_PCM_F32BE:
1526 st->codecpar->codec_id = AV_CODEC_ID_PCM_F32LE;
1528 case AV_CODEC_ID_PCM_F64BE:
1529 st->codecpar->codec_id = AV_CODEC_ID_PCM_F64LE;
1538 static int mov_read_colr(MOVContext *c, AVIOContext *pb, MOVAtom atom)
1541 uint8_t *icc_profile;
1542 char color_parameter_type[5] = { 0 };
1543 uint16_t color_primaries, color_trc, color_matrix;
1546 if (c->fc->nb_streams < 1)
1548 st = c->fc->streams[c->fc->nb_streams - 1];
1550 ret = ffio_read_size(pb, color_parameter_type, 4);
1553 if (strncmp(color_parameter_type, "nclx", 4) &&
1554 strncmp(color_parameter_type, "nclc", 4) &&
1555 strncmp(color_parameter_type, "prof", 4)) {
1556 av_log(c->fc, AV_LOG_WARNING, "unsupported color_parameter_type %s\n",
1557 color_parameter_type);
1561 if (!strncmp(color_parameter_type, "prof", 4)) {
1562 icc_profile = av_stream_new_side_data(st, AV_PKT_DATA_ICC_PROFILE, atom.size - 4);
1564 return AVERROR(ENOMEM);
1565 ret = ffio_read_size(pb, icc_profile, atom.size - 4);
1569 color_primaries = avio_rb16(pb);
1570 color_trc = avio_rb16(pb);
1571 color_matrix = avio_rb16(pb);
1573 av_log(c->fc, AV_LOG_TRACE,
1574 "%s: pri %d trc %d matrix %d",
1575 color_parameter_type, color_primaries, color_trc, color_matrix);
1577 if (!strncmp(color_parameter_type, "nclx", 4)) {
1578 uint8_t color_range = avio_r8(pb) >> 7;
1579 av_log(c->fc, AV_LOG_TRACE, " full %"PRIu8"", color_range);
1581 st->codecpar->color_range = AVCOL_RANGE_JPEG;
1583 st->codecpar->color_range = AVCOL_RANGE_MPEG;
1586 if (!av_color_primaries_name(color_primaries))
1587 color_primaries = AVCOL_PRI_UNSPECIFIED;
1588 if (!av_color_transfer_name(color_trc))
1589 color_trc = AVCOL_TRC_UNSPECIFIED;
1590 if (!av_color_space_name(color_matrix))
1591 color_matrix = AVCOL_SPC_UNSPECIFIED;
1593 st->codecpar->color_primaries = color_primaries;
1594 st->codecpar->color_trc = color_trc;
1595 st->codecpar->color_space = color_matrix;
1596 av_log(c->fc, AV_LOG_TRACE, "\n");
1601 static int mov_read_fiel(MOVContext *c, AVIOContext *pb, MOVAtom atom)
1604 unsigned mov_field_order;
1605 enum AVFieldOrder decoded_field_order = AV_FIELD_UNKNOWN;
1607 if (c->fc->nb_streams < 1) // will happen with jp2 files
1609 st = c->fc->streams[c->fc->nb_streams-1];
1611 return AVERROR_INVALIDDATA;
1612 mov_field_order = avio_rb16(pb);
1613 if ((mov_field_order & 0xFF00) == 0x0100)
1614 decoded_field_order = AV_FIELD_PROGRESSIVE;
1615 else if ((mov_field_order & 0xFF00) == 0x0200) {
1616 switch (mov_field_order & 0xFF) {
1617 case 0x01: decoded_field_order = AV_FIELD_TT;
1619 case 0x06: decoded_field_order = AV_FIELD_BB;
1621 case 0x09: decoded_field_order = AV_FIELD_TB;
1623 case 0x0E: decoded_field_order = AV_FIELD_BT;
1627 if (decoded_field_order == AV_FIELD_UNKNOWN && mov_field_order) {
1628 av_log(c->fc, AV_LOG_ERROR, "Unknown MOV field order 0x%04x\n", mov_field_order);
1630 st->codecpar->field_order = decoded_field_order;
1635 static int mov_realloc_extradata(AVCodecParameters *par, MOVAtom atom)
1638 uint64_t size = (uint64_t)par->extradata_size + atom.size + 8 + AV_INPUT_BUFFER_PADDING_SIZE;
1639 if (size > INT_MAX || (uint64_t)atom.size > INT_MAX)
1640 return AVERROR_INVALIDDATA;
1641 if ((err = av_reallocp(&par->extradata, size)) < 0) {
1642 par->extradata_size = 0;
1645 par->extradata_size = size - AV_INPUT_BUFFER_PADDING_SIZE;
1649 /* Read a whole atom into the extradata return the size of the atom read, possibly truncated if != atom.size */
1650 static int64_t mov_read_atom_into_extradata(MOVContext *c, AVIOContext *pb, MOVAtom atom,
1651 AVCodecParameters *par, uint8_t *buf)
1653 int64_t result = atom.size;
1656 AV_WB32(buf , atom.size + 8);
1657 AV_WL32(buf + 4, atom.type);
1658 err = ffio_read_size(pb, buf + 8, atom.size);
1660 par->extradata_size -= atom.size;
1662 } else if (err < atom.size) {
1663 av_log(c->fc, AV_LOG_WARNING, "truncated extradata\n");
1664 par->extradata_size -= atom.size - err;
1667 memset(buf + 8 + err, 0, AV_INPUT_BUFFER_PADDING_SIZE);
1671 /* FIXME modify QDM2/SVQ3/H.264 decoders to take full atom as extradata */
1672 static int mov_read_extradata(MOVContext *c, AVIOContext *pb, MOVAtom atom,
1673 enum AVCodecID codec_id)
1676 uint64_t original_size;
1679 if (c->fc->nb_streams < 1) // will happen with jp2 files
1681 st = c->fc->streams[c->fc->nb_streams-1];
1683 if (st->codecpar->codec_id != codec_id)
1684 return 0; /* unexpected codec_id - don't mess with extradata */
1686 original_size = st->codecpar->extradata_size;
1687 err = mov_realloc_extradata(st->codecpar, atom);
1691 err = mov_read_atom_into_extradata(c, pb, atom, st->codecpar, st->codecpar->extradata + original_size);
1694 return 0; // Note: this is the original behavior to ignore truncation.
1697 /* wrapper functions for reading ALAC/AVS/MJPEG/MJPEG2000 extradata atoms only for those codecs */
1698 static int mov_read_alac(MOVContext *c, AVIOContext *pb, MOVAtom atom)
1700 return mov_read_extradata(c, pb, atom, AV_CODEC_ID_ALAC);
1703 static int mov_read_avss(MOVContext *c, AVIOContext *pb, MOVAtom atom)
1705 return mov_read_extradata(c, pb, atom, AV_CODEC_ID_AVS);
1708 static int mov_read_jp2h(MOVContext *c, AVIOContext *pb, MOVAtom atom)
1710 return mov_read_extradata(c, pb, atom, AV_CODEC_ID_JPEG2000);
1713 static int mov_read_dpxe(MOVContext *c, AVIOContext *pb, MOVAtom atom)
1715 return mov_read_extradata(c, pb, atom, AV_CODEC_ID_R10K);
1718 static int mov_read_avid(MOVContext *c, AVIOContext *pb, MOVAtom atom)
1720 int ret = mov_read_extradata(c, pb, atom, AV_CODEC_ID_AVUI);
1722 ret = mov_read_extradata(c, pb, atom, AV_CODEC_ID_DNXHD);
1726 static int mov_read_targa_y216(MOVContext *c, AVIOContext *pb, MOVAtom atom)
1728 int ret = mov_read_extradata(c, pb, atom, AV_CODEC_ID_TARGA_Y216);
1730 if (!ret && c->fc->nb_streams >= 1) {
1731 AVCodecParameters *par = c->fc->streams[c->fc->nb_streams-1]->codecpar;
1732 if (par->extradata_size >= 40) {
1733 par->height = AV_RB16(&par->extradata[36]);
1734 par->width = AV_RB16(&par->extradata[38]);
1740 static int mov_read_ares(MOVContext *c, AVIOContext *pb, MOVAtom atom)
1742 if (c->fc->nb_streams >= 1) {
1743 AVCodecParameters *par = c->fc->streams[c->fc->nb_streams-1]->codecpar;
1744 if (par->codec_tag == MKTAG('A', 'V', 'i', 'n') &&
1745 par->codec_id == AV_CODEC_ID_H264 &&
1749 cid = avio_rb16(pb);
1750 /* For AVID AVCI50, force width of 1440 to be able to select the correct SPS and PPS */
1751 if (cid == 0xd4d || cid == 0xd4e)
1754 } else if ((par->codec_tag == MKTAG('A', 'V', 'd', '1') ||
1755 par->codec_tag == MKTAG('A', 'V', 'j', '2') ||
1756 par->codec_tag == MKTAG('A', 'V', 'd', 'n')) &&
1760 num = avio_rb32(pb);
1761 den = avio_rb32(pb);
1762 if (num <= 0 || den <= 0)
1764 switch (avio_rb32(pb)) {
1766 if (den >= INT_MAX / 2)
1770 c->fc->streams[c->fc->nb_streams-1]->display_aspect_ratio.num = num;
1771 c->fc->streams[c->fc->nb_streams-1]->display_aspect_ratio.den = den;
1778 return mov_read_avid(c, pb, atom);
1781 static int mov_read_aclr(MOVContext *c, AVIOContext *pb, MOVAtom atom)
1785 uint64_t original_size;
1786 if (c->fc->nb_streams >= 1) {
1787 AVCodecParameters *par = c->fc->streams[c->fc->nb_streams-1]->codecpar;
1788 if (par->codec_id == AV_CODEC_ID_H264)
1790 if (atom.size == 16) {
1791 original_size = par->extradata_size;
1792 ret = mov_realloc_extradata(par, atom);
1794 length = mov_read_atom_into_extradata(c, pb, atom, par, par->extradata + original_size);
1795 if (length == atom.size) {
1796 const uint8_t range_value = par->extradata[original_size + 19];
1797 switch (range_value) {
1799 par->color_range = AVCOL_RANGE_MPEG;
1802 par->color_range = AVCOL_RANGE_JPEG;
1805 av_log(c->fc, AV_LOG_WARNING, "ignored unknown aclr value (%d)\n", range_value);
1808 ff_dlog(c->fc, "color_range: %d\n", par->color_range);
1810 /* For some reason the whole atom was not added to the extradata */
1811 av_log(c->fc, AV_LOG_ERROR, "aclr not decoded - incomplete atom\n");
1814 av_log(c->fc, AV_LOG_ERROR, "aclr not decoded - unable to add atom to extradata\n");
1817 av_log(c->fc, AV_LOG_WARNING, "aclr not decoded - unexpected size %"PRId64"\n", atom.size);
1824 static int mov_read_svq3(MOVContext *c, AVIOContext *pb, MOVAtom atom)
1826 return mov_read_extradata(c, pb, atom, AV_CODEC_ID_SVQ3);
1829 static int mov_read_wave(MOVContext *c, AVIOContext *pb, MOVAtom atom)
1834 if (c->fc->nb_streams < 1)
1836 st = c->fc->streams[c->fc->nb_streams-1];
1838 if ((uint64_t)atom.size > (1<<30))
1839 return AVERROR_INVALIDDATA;
1841 if (st->codecpar->codec_id == AV_CODEC_ID_QDM2 ||
1842 st->codecpar->codec_id == AV_CODEC_ID_QDMC ||
1843 st->codecpar->codec_id == AV_CODEC_ID_SPEEX) {
1844 // pass all frma atom to codec, needed at least for QDMC and QDM2
1845 ret = ff_get_extradata(c->fc, st->codecpar, pb, atom.size);
1848 } else if (atom.size > 8) { /* to read frma, esds atoms */
1849 if (st->codecpar->codec_id == AV_CODEC_ID_ALAC && atom.size >= 24) {
1851 ret = ffio_ensure_seekback(pb, 8);
1854 buffer = avio_rb64(pb);
1856 if ( (buffer & 0xFFFFFFFF) == MKBETAG('f','r','m','a')
1857 && buffer >> 32 <= atom.size
1858 && buffer >> 32 >= 8) {
1861 } else if (!st->codecpar->extradata_size) {
1862 #define ALAC_EXTRADATA_SIZE 36
1863 st->codecpar->extradata = av_mallocz(ALAC_EXTRADATA_SIZE + AV_INPUT_BUFFER_PADDING_SIZE);
1864 if (!st->codecpar->extradata)
1865 return AVERROR(ENOMEM);
1866 st->codecpar->extradata_size = ALAC_EXTRADATA_SIZE;
1867 AV_WB32(st->codecpar->extradata , ALAC_EXTRADATA_SIZE);
1868 AV_WB32(st->codecpar->extradata + 4, MKTAG('a','l','a','c'));
1869 AV_WB64(st->codecpar->extradata + 12, buffer);
1870 avio_read(pb, st->codecpar->extradata + 20, 16);
1871 avio_skip(pb, atom.size - 24);
1875 if ((ret = mov_read_default(c, pb, atom)) < 0)
1878 avio_skip(pb, atom.size);
1883 * This function reads atom content and puts data in extradata without tag
1884 * nor size unlike mov_read_extradata.
1886 static int mov_read_glbl(MOVContext *c, AVIOContext *pb, MOVAtom atom)
1891 if (c->fc->nb_streams < 1)
1893 st = c->fc->streams[c->fc->nb_streams-1];
1895 if ((uint64_t)atom.size > (1<<30))
1896 return AVERROR_INVALIDDATA;
1898 if (atom.size >= 10) {
1899 // Broken files created by legacy versions of libavformat will
1900 // wrap a whole fiel atom inside of a glbl atom.
1901 unsigned size = avio_rb32(pb);
1902 unsigned type = avio_rl32(pb);
1903 avio_seek(pb, -8, SEEK_CUR);
1904 if (type == MKTAG('f','i','e','l') && size == atom.size)
1905 return mov_read_default(c, pb, atom);
1907 if (st->codecpar->extradata_size > 1 && st->codecpar->extradata) {
1908 av_log(c->fc, AV_LOG_WARNING, "ignoring multiple glbl\n");
1911 ret = ff_get_extradata(c->fc, st->codecpar, pb, atom.size);
1914 if (atom.type == MKTAG('h','v','c','C') && st->codecpar->codec_tag == MKTAG('d','v','h','1'))
1915 /* HEVC-based Dolby Vision derived from hvc1.
1916 Happens to match with an identifier
1917 previously utilized for DV. Thus, if we have
1918 the hvcC extradata box available as specified,
1919 set codec to HEVC */
1920 st->codecpar->codec_id = AV_CODEC_ID_HEVC;
1925 static int mov_read_dvc1(MOVContext *c, AVIOContext *pb, MOVAtom atom)
1928 uint8_t profile_level;
1931 if (c->fc->nb_streams < 1)
1933 st = c->fc->streams[c->fc->nb_streams-1];
1935 if (atom.size >= (1<<28) || atom.size < 7)
1936 return AVERROR_INVALIDDATA;
1938 profile_level = avio_r8(pb);
1939 if ((profile_level & 0xf0) != 0xc0)
1942 avio_seek(pb, 6, SEEK_CUR);
1943 ret = ff_get_extradata(c->fc, st->codecpar, pb, atom.size - 7);
1951 * An strf atom is a BITMAPINFOHEADER struct. This struct is 40 bytes itself,
1952 * but can have extradata appended at the end after the 40 bytes belonging
1955 static int mov_read_strf(MOVContext *c, AVIOContext *pb, MOVAtom atom)
1960 if (c->fc->nb_streams < 1)
1962 if (atom.size <= 40)
1964 st = c->fc->streams[c->fc->nb_streams-1];
1966 if ((uint64_t)atom.size > (1<<30))
1967 return AVERROR_INVALIDDATA;
1970 ret = ff_get_extradata(c->fc, st->codecpar, pb, atom.size - 40);
1977 static int mov_read_stco(MOVContext *c, AVIOContext *pb, MOVAtom atom)
1980 MOVStreamContext *sc;
1981 unsigned int i, entries;
1983 if (c->trak_index < 0) {
1984 av_log(c->fc, AV_LOG_WARNING, "STCO outside TRAK\n");
1987 if (c->fc->nb_streams < 1)
1989 st = c->fc->streams[c->fc->nb_streams-1];
1992 avio_r8(pb); /* version */
1993 avio_rb24(pb); /* flags */
1995 entries = avio_rb32(pb);
2000 if (sc->chunk_offsets)
2001 av_log(c->fc, AV_LOG_WARNING, "Duplicated STCO atom\n");
2002 av_free(sc->chunk_offsets);
2003 sc->chunk_count = 0;
2004 sc->chunk_offsets = av_malloc_array(entries, sizeof(*sc->chunk_offsets));
2005 if (!sc->chunk_offsets)
2006 return AVERROR(ENOMEM);
2007 sc->chunk_count = entries;
2009 if (atom.type == MKTAG('s','t','c','o'))
2010 for (i = 0; i < entries && !pb->eof_reached; i++)
2011 sc->chunk_offsets[i] = avio_rb32(pb);
2012 else if (atom.type == MKTAG('c','o','6','4'))
2013 for (i = 0; i < entries && !pb->eof_reached; i++)
2014 sc->chunk_offsets[i] = avio_rb64(pb);
2016 return AVERROR_INVALIDDATA;
2018 sc->chunk_count = i;
2020 if (pb->eof_reached) {
2021 av_log(c->fc, AV_LOG_WARNING, "reached eof, corrupted STCO atom\n");
2028 static int mov_codec_id(AVStream *st, uint32_t format)
2030 int id = ff_codec_get_id(ff_codec_movaudio_tags, format);
2033 ((format & 0xFFFF) == 'm' + ('s' << 8) ||
2034 (format & 0xFFFF) == 'T' + ('S' << 8)))
2035 id = ff_codec_get_id(ff_codec_wav_tags, av_bswap32(format) & 0xFFFF);
2037 if (st->codecpar->codec_type != AVMEDIA_TYPE_VIDEO && id > 0) {
2038 st->codecpar->codec_type = AVMEDIA_TYPE_AUDIO;
2039 } else if (st->codecpar->codec_type != AVMEDIA_TYPE_AUDIO &&
2040 /* skip old ASF MPEG-4 tag */
2041 format && format != MKTAG('m','p','4','s')) {
2042 id = ff_codec_get_id(ff_codec_movvideo_tags, format);
2044 id = ff_codec_get_id(ff_codec_bmp_tags, format);
2046 st->codecpar->codec_type = AVMEDIA_TYPE_VIDEO;
2047 else if (st->codecpar->codec_type == AVMEDIA_TYPE_DATA ||
2048 (st->codecpar->codec_type == AVMEDIA_TYPE_SUBTITLE &&
2049 st->codecpar->codec_id == AV_CODEC_ID_NONE)) {
2050 id = ff_codec_get_id(ff_codec_movsubtitle_tags, format);
2052 st->codecpar->codec_type = AVMEDIA_TYPE_SUBTITLE;
2054 id = ff_codec_get_id(ff_codec_movdata_tags, format);
2058 st->codecpar->codec_tag = format;
2063 static void mov_parse_stsd_video(MOVContext *c, AVIOContext *pb,
2064 AVStream *st, MOVStreamContext *sc)
2066 uint8_t codec_name[32] = { 0 };
2070 /* The first 16 bytes of the video sample description are already
2071 * read in ff_mov_read_stsd_entries() */
2072 stsd_start = avio_tell(pb) - 16;
2074 avio_rb16(pb); /* version */
2075 avio_rb16(pb); /* revision level */
2076 avio_rb32(pb); /* vendor */
2077 avio_rb32(pb); /* temporal quality */
2078 avio_rb32(pb); /* spatial quality */
2080 st->codecpar->width = avio_rb16(pb); /* width */
2081 st->codecpar->height = avio_rb16(pb); /* height */
2083 avio_rb32(pb); /* horiz resolution */
2084 avio_rb32(pb); /* vert resolution */
2085 avio_rb32(pb); /* data size, always 0 */
2086 avio_rb16(pb); /* frames per samples */
2088 len = avio_r8(pb); /* codec name, pascal string */
2091 mov_read_mac_string(c, pb, len, codec_name, sizeof(codec_name));
2093 avio_skip(pb, 31 - len);
2096 av_dict_set(&st->metadata, "encoder", codec_name, 0);
2098 /* codec_tag YV12 triggers an UV swap in rawdec.c */
2099 if (!strncmp(codec_name, "Planar Y'CbCr 8-bit 4:2:0", 25)) {
2100 st->codecpar->codec_tag = MKTAG('I', '4', '2', '0');
2101 st->codecpar->width &= ~1;
2102 st->codecpar->height &= ~1;
2104 /* Flash Media Server uses tag H.263 with Sorenson Spark */
2105 if (st->codecpar->codec_tag == MKTAG('H','2','6','3') &&
2106 !strncmp(codec_name, "Sorenson H263", 13))
2107 st->codecpar->codec_id = AV_CODEC_ID_FLV1;
2109 st->codecpar->bits_per_coded_sample = avio_rb16(pb); /* depth */
2111 avio_seek(pb, stsd_start, SEEK_SET);
2113 if (ff_get_qtpalette(st->codecpar->codec_id, pb, sc->palette)) {
2114 st->codecpar->bits_per_coded_sample &= 0x1F;
2115 sc->has_palette = 1;
2119 static void mov_parse_stsd_audio(MOVContext *c, AVIOContext *pb,
2120 AVStream *st, MOVStreamContext *sc)
2122 int bits_per_sample, flags;
2123 uint16_t version = avio_rb16(pb);
2124 AVDictionaryEntry *compatible_brands = av_dict_get(c->fc->metadata, "compatible_brands", NULL, AV_DICT_MATCH_CASE);
2126 avio_rb16(pb); /* revision level */
2127 avio_rb32(pb); /* vendor */
2129 st->codecpar->channels = avio_rb16(pb); /* channel count */
2130 st->codecpar->bits_per_coded_sample = avio_rb16(pb); /* sample size */
2131 av_log(c->fc, AV_LOG_TRACE, "audio channels %d\n", st->codecpar->channels);
2133 sc->audio_cid = avio_rb16(pb);
2134 avio_rb16(pb); /* packet size = 0 */
2136 st->codecpar->sample_rate = ((avio_rb32(pb) >> 16));
2138 // Read QT version 1 fields. In version 0 these do not exist.
2139 av_log(c->fc, AV_LOG_TRACE, "version =%d, isom =%d\n", version, c->isom);
2141 (compatible_brands && strstr(compatible_brands->value, "qt ")) ||
2142 (sc->stsd_version == 0 && version > 0)) {
2144 sc->samples_per_frame = avio_rb32(pb);
2145 avio_rb32(pb); /* bytes per packet */
2146 sc->bytes_per_frame = avio_rb32(pb);
2147 avio_rb32(pb); /* bytes per sample */
2148 } else if (version == 2) {
2149 avio_rb32(pb); /* sizeof struct only */
2150 st->codecpar->sample_rate = av_int2double(avio_rb64(pb));
2151 st->codecpar->channels = avio_rb32(pb);
2152 avio_rb32(pb); /* always 0x7F000000 */
2153 st->codecpar->bits_per_coded_sample = avio_rb32(pb);
2155 flags = avio_rb32(pb); /* lpcm format specific flag */
2156 sc->bytes_per_frame = avio_rb32(pb);
2157 sc->samples_per_frame = avio_rb32(pb);
2158 if (st->codecpar->codec_tag == MKTAG('l','p','c','m'))
2159 st->codecpar->codec_id =
2160 ff_mov_get_lpcm_codec_id(st->codecpar->bits_per_coded_sample,
2163 if (version == 0 || (version == 1 && sc->audio_cid != -2)) {
2164 /* can't correctly handle variable sized packet as audio unit */
2165 switch (st->codecpar->codec_id) {
2166 case AV_CODEC_ID_MP2:
2167 case AV_CODEC_ID_MP3:
2168 st->need_parsing = AVSTREAM_PARSE_FULL;
2174 if (sc->format == 0) {
2175 if (st->codecpar->bits_per_coded_sample == 8)
2176 st->codecpar->codec_id = mov_codec_id(st, MKTAG('r','a','w',' '));
2177 else if (st->codecpar->bits_per_coded_sample == 16)
2178 st->codecpar->codec_id = mov_codec_id(st, MKTAG('t','w','o','s'));
2181 switch (st->codecpar->codec_id) {
2182 case AV_CODEC_ID_PCM_S8:
2183 case AV_CODEC_ID_PCM_U8:
2184 if (st->codecpar->bits_per_coded_sample == 16)
2185 st->codecpar->codec_id = AV_CODEC_ID_PCM_S16BE;
2187 case AV_CODEC_ID_PCM_S16LE:
2188 case AV_CODEC_ID_PCM_S16BE:
2189 if (st->codecpar->bits_per_coded_sample == 8)
2190 st->codecpar->codec_id = AV_CODEC_ID_PCM_S8;
2191 else if (st->codecpar->bits_per_coded_sample == 24)
2192 st->codecpar->codec_id =
2193 st->codecpar->codec_id == AV_CODEC_ID_PCM_S16BE ?
2194 AV_CODEC_ID_PCM_S24BE : AV_CODEC_ID_PCM_S24LE;
2195 else if (st->codecpar->bits_per_coded_sample == 32)
2196 st->codecpar->codec_id =
2197 st->codecpar->codec_id == AV_CODEC_ID_PCM_S16BE ?
2198 AV_CODEC_ID_PCM_S32BE : AV_CODEC_ID_PCM_S32LE;
2200 /* set values for old format before stsd version 1 appeared */
2201 case AV_CODEC_ID_MACE3:
2202 sc->samples_per_frame = 6;
2203 sc->bytes_per_frame = 2 * st->codecpar->channels;
2205 case AV_CODEC_ID_MACE6:
2206 sc->samples_per_frame = 6;
2207 sc->bytes_per_frame = 1 * st->codecpar->channels;
2209 case AV_CODEC_ID_ADPCM_IMA_QT:
2210 sc->samples_per_frame = 64;
2211 sc->bytes_per_frame = 34 * st->codecpar->channels;
2213 case AV_CODEC_ID_GSM:
2214 sc->samples_per_frame = 160;
2215 sc->bytes_per_frame = 33;
2221 bits_per_sample = av_get_bits_per_sample(st->codecpar->codec_id);
2222 if (bits_per_sample) {
2223 st->codecpar->bits_per_coded_sample = bits_per_sample;
2224 sc->sample_size = (bits_per_sample >> 3) * st->codecpar->channels;
2228 static void mov_parse_stsd_subtitle(MOVContext *c, AVIOContext *pb,
2229 AVStream *st, MOVStreamContext *sc,
2232 // ttxt stsd contains display flags, justification, background
2233 // color, fonts, and default styles, so fake an atom to read it
2234 MOVAtom fake_atom = { .size = size };
2235 // mp4s contains a regular esds atom
2236 if (st->codecpar->codec_tag != AV_RL32("mp4s"))
2237 mov_read_glbl(c, pb, fake_atom);
2238 st->codecpar->width = sc->width;
2239 st->codecpar->height = sc->height;
2242 static uint32_t yuv_to_rgba(uint32_t ycbcr)
2247 y = (ycbcr >> 16) & 0xFF;
2248 cr = (ycbcr >> 8) & 0xFF;
2251 b = av_clip_uint8((1164 * (y - 16) + 2018 * (cb - 128)) / 1000);
2252 g = av_clip_uint8((1164 * (y - 16) - 813 * (cr - 128) - 391 * (cb - 128)) / 1000);
2253 r = av_clip_uint8((1164 * (y - 16) + 1596 * (cr - 128) ) / 1000);
2255 return (r << 16) | (g << 8) | b;
2258 static int mov_rewrite_dvd_sub_extradata(AVStream *st)
2260 char buf[256] = {0};
2261 uint8_t *src = st->codecpar->extradata;
2264 if (st->codecpar->extradata_size != 64)
2267 if (st->codecpar->width > 0 && st->codecpar->height > 0)
2268 snprintf(buf, sizeof(buf), "size: %dx%d\n",
2269 st->codecpar->width, st->codecpar->height);
2270 av_strlcat(buf, "palette: ", sizeof(buf));
2272 for (i = 0; i < 16; i++) {
2273 uint32_t yuv = AV_RB32(src + i * 4);
2274 uint32_t rgba = yuv_to_rgba(yuv);
2276 av_strlcatf(buf, sizeof(buf), "%06"PRIx32"%s", rgba, i != 15 ? ", " : "");
2279 if (av_strlcat(buf, "\n", sizeof(buf)) >= sizeof(buf))
2282 ret = ff_alloc_extradata(st->codecpar, strlen(buf));
2285 memcpy(st->codecpar->extradata, buf, st->codecpar->extradata_size);
2290 static int mov_parse_stsd_data(MOVContext *c, AVIOContext *pb,
2291 AVStream *st, MOVStreamContext *sc,
2296 if (st->codecpar->codec_tag == MKTAG('t','m','c','d')) {
2297 if ((int)size != size)
2298 return AVERROR(ENOMEM);
2300 ret = ff_get_extradata(c->fc, st->codecpar, pb, size);
2304 MOVStreamContext *tmcd_ctx = st->priv_data;
2306 val = AV_RB32(st->codecpar->extradata + 4);
2307 tmcd_ctx->tmcd_flags = val;
2308 st->avg_frame_rate.num = AV_RB32(st->codecpar->extradata + 8); /* timescale */
2309 st->avg_frame_rate.den = AV_RB32(st->codecpar->extradata + 12); /* frameDuration */
2310 #if FF_API_LAVF_AVCTX
2311 FF_DISABLE_DEPRECATION_WARNINGS
2312 st->codec->time_base = av_inv_q(st->avg_frame_rate);
2313 FF_ENABLE_DEPRECATION_WARNINGS
2315 /* adjust for per frame dur in counter mode */
2316 if (tmcd_ctx->tmcd_flags & 0x0008) {
2317 int timescale = AV_RB32(st->codecpar->extradata + 8);
2318 int framedur = AV_RB32(st->codecpar->extradata + 12);
2319 st->avg_frame_rate.num *= timescale;
2320 st->avg_frame_rate.den *= framedur;
2321 #if FF_API_LAVF_AVCTX
2322 FF_DISABLE_DEPRECATION_WARNINGS
2323 st->codec->time_base.den *= timescale;
2324 st->codec->time_base.num *= framedur;
2325 FF_ENABLE_DEPRECATION_WARNINGS
2329 uint32_t len = AV_RB32(st->codecpar->extradata + 18); /* name atom length */
2330 uint32_t format = AV_RB32(st->codecpar->extradata + 22);
2331 if (format == AV_RB32("name") && (int64_t)size >= (int64_t)len + 18) {
2332 uint16_t str_size = AV_RB16(st->codecpar->extradata + 26); /* string length */
2333 if (str_size > 0 && size >= (int)str_size + 30 &&
2334 st->codecpar->extradata[30] /* Don't add empty string */) {
2335 char *reel_name = av_malloc(str_size + 1);
2337 return AVERROR(ENOMEM);
2338 memcpy(reel_name, st->codecpar->extradata + 30, str_size);
2339 reel_name[str_size] = 0; /* Add null terminator */
2340 av_dict_set(&st->metadata, "reel_name", reel_name,
2341 AV_DICT_DONT_STRDUP_VAL);
2347 /* other codec type, just skip (rtp, mp4s ...) */
2348 avio_skip(pb, size);
2353 static int mov_finalize_stsd_codec(MOVContext *c, AVIOContext *pb,
2354 AVStream *st, MOVStreamContext *sc)
2356 if (st->codecpar->codec_type == AVMEDIA_TYPE_AUDIO &&
2357 !st->codecpar->sample_rate && sc->time_scale > 1)
2358 st->codecpar->sample_rate = sc->time_scale;
2360 /* special codec parameters handling */
2361 switch (st->codecpar->codec_id) {
2362 #if CONFIG_DV_DEMUXER
2363 case AV_CODEC_ID_DVAUDIO:
2364 c->dv_fctx = avformat_alloc_context();
2366 av_log(c->fc, AV_LOG_ERROR, "dv demux context alloc error\n");
2367 return AVERROR(ENOMEM);
2369 c->dv_demux = avpriv_dv_init_demux(c->dv_fctx);
2371 av_log(c->fc, AV_LOG_ERROR, "dv demux context init error\n");
2372 return AVERROR(ENOMEM);
2374 sc->dv_audio_container = 1;
2375 st->codecpar->codec_id = AV_CODEC_ID_PCM_S16LE;
2378 /* no ifdef since parameters are always those */
2379 case AV_CODEC_ID_QCELP:
2380 st->codecpar->channels = 1;
2381 // force sample rate for qcelp when not stored in mov
2382 if (st->codecpar->codec_tag != MKTAG('Q','c','l','p'))
2383 st->codecpar->sample_rate = 8000;
2384 // FIXME: Why is the following needed for some files?
2385 sc->samples_per_frame = 160;
2386 if (!sc->bytes_per_frame)
2387 sc->bytes_per_frame = 35;
2389 case AV_CODEC_ID_AMR_NB:
2390 st->codecpar->channels = 1;
2391 /* force sample rate for amr, stsd in 3gp does not store sample rate */
2392 st->codecpar->sample_rate = 8000;
2394 case AV_CODEC_ID_AMR_WB:
2395 st->codecpar->channels = 1;
2396 st->codecpar->sample_rate = 16000;
2398 case AV_CODEC_ID_MP2:
2399 case AV_CODEC_ID_MP3:
2400 /* force type after stsd for m1a hdlr */
2401 st->codecpar->codec_type = AVMEDIA_TYPE_AUDIO;
2403 case AV_CODEC_ID_GSM:
2404 case AV_CODEC_ID_ADPCM_MS:
2405 case AV_CODEC_ID_ADPCM_IMA_WAV:
2406 case AV_CODEC_ID_ILBC:
2407 case AV_CODEC_ID_MACE3:
2408 case AV_CODEC_ID_MACE6:
2409 case AV_CODEC_ID_QDM2:
2410 st->codecpar->block_align = sc->bytes_per_frame;
2412 case AV_CODEC_ID_ALAC:
2413 if (st->codecpar->extradata_size == 36) {
2414 st->codecpar->channels = AV_RB8 (st->codecpar->extradata + 21);
2415 st->codecpar->sample_rate = AV_RB32(st->codecpar->extradata + 32);
2418 case AV_CODEC_ID_AC3:
2419 case AV_CODEC_ID_EAC3:
2420 case AV_CODEC_ID_MPEG1VIDEO:
2421 case AV_CODEC_ID_VC1:
2422 case AV_CODEC_ID_VP8:
2423 case AV_CODEC_ID_VP9:
2424 st->need_parsing = AVSTREAM_PARSE_FULL;
2426 case AV_CODEC_ID_AV1:
2427 st->need_parsing = AVSTREAM_PARSE_HEADERS;
2435 static int mov_skip_multiple_stsd(MOVContext *c, AVIOContext *pb,
2436 int codec_tag, int format,
2439 int video_codec_id = ff_codec_get_id(ff_codec_movvideo_tags, format);
2442 (codec_tag != format &&
2443 // AVID 1:1 samples with differing data format and codec tag exist
2444 (codec_tag != AV_RL32("AV1x") || format != AV_RL32("AVup")) &&
2445 // prores is allowed to have differing data format and codec tag
2446 codec_tag != AV_RL32("apcn") && codec_tag != AV_RL32("apch") &&
2448 codec_tag != AV_RL32("dvpp") && codec_tag != AV_RL32("dvcp") &&
2449 (c->fc->video_codec_id ? video_codec_id != c->fc->video_codec_id
2450 : codec_tag != MKTAG('j','p','e','g')))) {
2451 /* Multiple fourcc, we skip JPEG. This is not correct, we should
2452 * export it as a separate AVStream but this needs a few changes
2453 * in the MOV demuxer, patch welcome. */
2455 av_log(c->fc, AV_LOG_WARNING, "multiple fourcc not supported\n");
2456 avio_skip(pb, size);
2463 int ff_mov_read_stsd_entries(MOVContext *c, AVIOContext *pb, int entries)
2466 MOVStreamContext *sc;
2467 int pseudo_stream_id;
2469 av_assert0 (c->fc->nb_streams >= 1);
2470 st = c->fc->streams[c->fc->nb_streams-1];
2473 for (pseudo_stream_id = 0;
2474 pseudo_stream_id < entries && !pb->eof_reached;
2475 pseudo_stream_id++) {
2476 //Parsing Sample description table
2478 int ret, dref_id = 1;
2479 MOVAtom a = { AV_RL32("stsd") };
2480 int64_t start_pos = avio_tell(pb);
2481 int64_t size = avio_rb32(pb); /* size */
2482 uint32_t format = avio_rl32(pb); /* data format */
2485 avio_rb32(pb); /* reserved */
2486 avio_rb16(pb); /* reserved */
2487 dref_id = avio_rb16(pb);
2488 } else if (size <= 7) {
2489 av_log(c->fc, AV_LOG_ERROR,
2490 "invalid size %"PRId64" in stsd\n", size);
2491 return AVERROR_INVALIDDATA;
2494 if (mov_skip_multiple_stsd(c, pb, st->codecpar->codec_tag, format,
2495 size - (avio_tell(pb) - start_pos))) {
2500 sc->pseudo_stream_id = st->codecpar->codec_tag ? -1 : pseudo_stream_id;
2501 sc->dref_id= dref_id;
2502 sc->format = format;
2504 id = mov_codec_id(st, format);
2506 av_log(c->fc, AV_LOG_TRACE,
2507 "size=%"PRId64" 4CC=%s codec_type=%d\n", size,
2508 av_fourcc2str(format), st->codecpar->codec_type);
2510 st->codecpar->codec_id = id;
2511 if (st->codecpar->codec_type==AVMEDIA_TYPE_VIDEO) {
2512 mov_parse_stsd_video(c, pb, st, sc);
2513 } else if (st->codecpar->codec_type==AVMEDIA_TYPE_AUDIO) {
2514 mov_parse_stsd_audio(c, pb, st, sc);
2515 if (st->codecpar->sample_rate < 0) {
2516 av_log(c->fc, AV_LOG_ERROR, "Invalid sample rate %d\n", st->codecpar->sample_rate);
2517 return AVERROR_INVALIDDATA;
2519 } else if (st->codecpar->codec_type==AVMEDIA_TYPE_SUBTITLE){
2520 mov_parse_stsd_subtitle(c, pb, st, sc,
2521 size - (avio_tell(pb) - start_pos));
2523 ret = mov_parse_stsd_data(c, pb, st, sc,
2524 size - (avio_tell(pb) - start_pos));
2528 /* this will read extra atoms at the end (wave, alac, damr, avcC, hvcC, SMI ...) */
2529 a.size = size - (avio_tell(pb) - start_pos);
2531 if ((ret = mov_read_default(c, pb, a)) < 0)
2533 } else if (a.size > 0)
2534 avio_skip(pb, a.size);
2536 if (sc->extradata && st->codecpar->extradata) {
2537 int extra_size = st->codecpar->extradata_size;
2539 /* Move the current stream extradata to the stream context one. */
2540 sc->extradata_size[pseudo_stream_id] = extra_size;
2541 sc->extradata[pseudo_stream_id] = st->codecpar->extradata;
2542 st->codecpar->extradata = NULL;
2543 st->codecpar->extradata_size = 0;
2548 if (pb->eof_reached) {
2549 av_log(c->fc, AV_LOG_WARNING, "reached eof, corrupted STSD atom\n");
2556 static int mov_read_stsd(MOVContext *c, AVIOContext *pb, MOVAtom atom)
2559 MOVStreamContext *sc;
2562 if (c->fc->nb_streams < 1)
2564 st = c->fc->streams[c->fc->nb_streams - 1];
2567 sc->stsd_version = avio_r8(pb);
2568 avio_rb24(pb); /* flags */
2569 entries = avio_rb32(pb);
2571 /* Each entry contains a size (4 bytes) and format (4 bytes). */
2572 if (entries <= 0 || entries > atom.size / 8) {
2573 av_log(c->fc, AV_LOG_ERROR, "invalid STSD entries %d\n", entries);
2574 return AVERROR_INVALIDDATA;
2577 if (sc->extradata) {
2578 av_log(c->fc, AV_LOG_ERROR,
2579 "Duplicate stsd found in this track.\n");
2580 return AVERROR_INVALIDDATA;
2583 /* Prepare space for hosting multiple extradata. */
2584 sc->extradata = av_mallocz_array(entries, sizeof(*sc->extradata));
2586 return AVERROR(ENOMEM);
2588 sc->extradata_size = av_mallocz_array(entries, sizeof(*sc->extradata_size));
2589 if (!sc->extradata_size) {
2590 ret = AVERROR(ENOMEM);
2594 ret = ff_mov_read_stsd_entries(c, pb, entries);
2598 /* Restore back the primary extradata. */
2599 av_freep(&st->codecpar->extradata);
2600 st->codecpar->extradata_size = sc->extradata_size[0];
2601 if (sc->extradata_size[0]) {
2602 st->codecpar->extradata = av_mallocz(sc->extradata_size[0] + AV_INPUT_BUFFER_PADDING_SIZE);
2603 if (!st->codecpar->extradata)
2604 return AVERROR(ENOMEM);
2605 memcpy(st->codecpar->extradata, sc->extradata[0], sc->extradata_size[0]);
2608 return mov_finalize_stsd_codec(c, pb, st, sc);
2610 if (sc->extradata) {
2612 for (j = 0; j < sc->stsd_count; j++)
2613 av_freep(&sc->extradata[j]);
2616 av_freep(&sc->extradata);
2617 av_freep(&sc->extradata_size);
2621 static int mov_read_stsc(MOVContext *c, AVIOContext *pb, MOVAtom atom)
2624 MOVStreamContext *sc;
2625 unsigned int i, entries;
2627 if (c->fc->nb_streams < 1)
2629 st = c->fc->streams[c->fc->nb_streams-1];
2632 avio_r8(pb); /* version */
2633 avio_rb24(pb); /* flags */
2635 entries = avio_rb32(pb);
2636 if ((uint64_t)entries * 12 + 4 > atom.size)
2637 return AVERROR_INVALIDDATA;
2639 av_log(c->fc, AV_LOG_TRACE, "track[%u].stsc.entries = %u\n", c->fc->nb_streams - 1, entries);
2644 av_log(c->fc, AV_LOG_WARNING, "Duplicated STSC atom\n");
2645 av_free(sc->stsc_data);
2647 sc->stsc_data = av_malloc_array(entries, sizeof(*sc->stsc_data));
2649 return AVERROR(ENOMEM);
2651 for (i = 0; i < entries && !pb->eof_reached; i++) {
2652 sc->stsc_data[i].first = avio_rb32(pb);
2653 sc->stsc_data[i].count = avio_rb32(pb);
2654 sc->stsc_data[i].id = avio_rb32(pb);
2658 for (i = sc->stsc_count - 1; i < UINT_MAX; i--) {
2659 int64_t first_min = i + 1;
2660 if ((i+1 < sc->stsc_count && sc->stsc_data[i].first >= sc->stsc_data[i+1].first) ||
2661 (i > 0 && sc->stsc_data[i].first <= sc->stsc_data[i-1].first) ||
2662 sc->stsc_data[i].first < first_min ||
2663 sc->stsc_data[i].count < 1 ||
2664 sc->stsc_data[i].id < 1) {
2665 av_log(c->fc, AV_LOG_WARNING, "STSC entry %d is invalid (first=%d count=%d id=%d)\n", i, sc->stsc_data[i].first, sc->stsc_data[i].count, sc->stsc_data[i].id);
2666 if (i+1 >= sc->stsc_count) {
2667 if (sc->stsc_data[i].count == 0 && i > 0) {
2671 sc->stsc_data[i].first = FFMAX(sc->stsc_data[i].first, first_min);
2672 if (i > 0 && sc->stsc_data[i].first <= sc->stsc_data[i-1].first)
2673 sc->stsc_data[i].first = FFMIN(sc->stsc_data[i-1].first + 1LL, INT_MAX);
2674 sc->stsc_data[i].count = FFMAX(sc->stsc_data[i].count, 1);
2675 sc->stsc_data[i].id = FFMAX(sc->stsc_data[i].id, 1);
2678 av_assert0(sc->stsc_data[i+1].first >= 2);
2679 // We replace this entry by the next valid
2680 sc->stsc_data[i].first = sc->stsc_data[i+1].first - 1;
2681 sc->stsc_data[i].count = sc->stsc_data[i+1].count;
2682 sc->stsc_data[i].id = sc->stsc_data[i+1].id;
2686 if (pb->eof_reached) {
2687 av_log(c->fc, AV_LOG_WARNING, "reached eof, corrupted STSC atom\n");
2694 static inline int mov_stsc_index_valid(unsigned int index, unsigned int count)
2696 return index < count - 1;
2699 /* Compute the samples value for the stsc entry at the given index. */
2700 static inline int64_t mov_get_stsc_samples(MOVStreamContext *sc, unsigned int index)
2704 if (mov_stsc_index_valid(index, sc->stsc_count))
2705 chunk_count = sc->stsc_data[index + 1].first - sc->stsc_data[index].first;
2707 // Validation for stsc / stco happens earlier in mov_read_stsc + mov_read_trak.
2708 av_assert0(sc->stsc_data[index].first <= sc->chunk_count);
2709 chunk_count = sc->chunk_count - (sc->stsc_data[index].first - 1);
2712 return sc->stsc_data[index].count * (int64_t)chunk_count;
2715 static int mov_read_stps(MOVContext *c, AVIOContext *pb, MOVAtom atom)
2718 MOVStreamContext *sc;
2719 unsigned i, entries;
2721 if (c->fc->nb_streams < 1)
2723 st = c->fc->streams[c->fc->nb_streams-1];
2726 avio_rb32(pb); // version + flags
2728 entries = avio_rb32(pb);
2730 av_log(c->fc, AV_LOG_WARNING, "Duplicated STPS atom\n");
2731 av_free(sc->stps_data);
2733 sc->stps_data = av_malloc_array(entries, sizeof(*sc->stps_data));
2735 return AVERROR(ENOMEM);
2737 for (i = 0; i < entries && !pb->eof_reached; i++) {
2738 sc->stps_data[i] = avio_rb32(pb);
2743 if (pb->eof_reached) {
2744 av_log(c->fc, AV_LOG_WARNING, "reached eof, corrupted STPS atom\n");
2751 static int mov_read_stss(MOVContext *c, AVIOContext *pb, MOVAtom atom)
2754 MOVStreamContext *sc;
2755 unsigned int i, entries;
2757 if (c->fc->nb_streams < 1)
2759 st = c->fc->streams[c->fc->nb_streams-1];
2762 avio_r8(pb); /* version */
2763 avio_rb24(pb); /* flags */
2765 entries = avio_rb32(pb);
2767 av_log(c->fc, AV_LOG_TRACE, "keyframe_count = %u\n", entries);
2770 sc->keyframe_absent = 1;
2771 if (!st->need_parsing && st->codecpar->codec_type == AVMEDIA_TYPE_VIDEO)
2772 st->need_parsing = AVSTREAM_PARSE_HEADERS;
2776 av_log(c->fc, AV_LOG_WARNING, "Duplicated STSS atom\n");
2777 if (entries >= UINT_MAX / sizeof(int))
2778 return AVERROR_INVALIDDATA;
2779 av_freep(&sc->keyframes);
2780 sc->keyframe_count = 0;
2781 sc->keyframes = av_malloc_array(entries, sizeof(*sc->keyframes));
2783 return AVERROR(ENOMEM);
2785 for (i = 0; i < entries && !pb->eof_reached; i++) {
2786 sc->keyframes[i] = avio_rb32(pb);
2789 sc->keyframe_count = i;
2791 if (pb->eof_reached) {
2792 av_log(c->fc, AV_LOG_WARNING, "reached eof, corrupted STSS atom\n");
2799 static int mov_read_stsz(MOVContext *c, AVIOContext *pb, MOVAtom atom)
2802 MOVStreamContext *sc;
2803 unsigned int i, entries, sample_size, field_size, num_bytes;
2808 if (c->fc->nb_streams < 1)
2810 st = c->fc->streams[c->fc->nb_streams-1];
2813 avio_r8(pb); /* version */
2814 avio_rb24(pb); /* flags */
2816 if (atom.type == MKTAG('s','t','s','z')) {
2817 sample_size = avio_rb32(pb);
2818 if (!sc->sample_size) /* do not overwrite value computed in stsd */
2819 sc->sample_size = sample_size;
2820 sc->stsz_sample_size = sample_size;
2824 avio_rb24(pb); /* reserved */
2825 field_size = avio_r8(pb);
2827 entries = avio_rb32(pb);
2829 av_log(c->fc, AV_LOG_TRACE, "sample_size = %u sample_count = %u\n", sc->sample_size, entries);
2831 sc->sample_count = entries;
2835 if (field_size != 4 && field_size != 8 && field_size != 16 && field_size != 32) {
2836 av_log(c->fc, AV_LOG_ERROR, "Invalid sample field size %u\n", field_size);
2837 return AVERROR_INVALIDDATA;
2842 if (entries >= (UINT_MAX - 4) / field_size)
2843 return AVERROR_INVALIDDATA;
2844 if (sc->sample_sizes)
2845 av_log(c->fc, AV_LOG_WARNING, "Duplicated STSZ atom\n");
2846 av_free(sc->sample_sizes);
2847 sc->sample_count = 0;
2848 sc->sample_sizes = av_malloc_array(entries, sizeof(*sc->sample_sizes));
2849 if (!sc->sample_sizes)
2850 return AVERROR(ENOMEM);
2852 num_bytes = (entries*field_size+4)>>3;
2854 buf = av_malloc(num_bytes+AV_INPUT_BUFFER_PADDING_SIZE);
2856 av_freep(&sc->sample_sizes);
2857 return AVERROR(ENOMEM);
2860 ret = ffio_read_size(pb, buf, num_bytes);
2862 av_freep(&sc->sample_sizes);
2864 av_log(c->fc, AV_LOG_WARNING, "STSZ atom truncated\n");
2868 init_get_bits(&gb, buf, 8*num_bytes);
2870 for (i = 0; i < entries && !pb->eof_reached; i++) {
2871 sc->sample_sizes[i] = get_bits_long(&gb, field_size);
2872 if (sc->sample_sizes[i] < 0) {
2874 av_log(c->fc, AV_LOG_ERROR, "Invalid sample size %d\n", sc->sample_sizes[i]);
2875 return AVERROR_INVALIDDATA;
2877 sc->data_size += sc->sample_sizes[i];
2880 sc->sample_count = i;
2884 if (pb->eof_reached) {
2885 av_log(c->fc, AV_LOG_WARNING, "reached eof, corrupted STSZ atom\n");
2892 static int mov_read_stts(MOVContext *c, AVIOContext *pb, MOVAtom atom)
2895 MOVStreamContext *sc;
2896 unsigned int i, entries, alloc_size = 0;
2897 int64_t duration = 0;
2898 int64_t total_sample_count = 0;
2900 if (c->fc->nb_streams < 1)
2902 st = c->fc->streams[c->fc->nb_streams-1];
2905 avio_r8(pb); /* version */
2906 avio_rb24(pb); /* flags */
2907 entries = avio_rb32(pb);
2909 av_log(c->fc, AV_LOG_TRACE, "track[%u].stts.entries = %u\n",
2910 c->fc->nb_streams-1, entries);
2913 av_log(c->fc, AV_LOG_WARNING, "Duplicated STTS atom\n");
2914 av_freep(&sc->stts_data);
2916 if (entries >= INT_MAX / sizeof(*sc->stts_data))
2917 return AVERROR(ENOMEM);
2919 for (i = 0; i < entries && !pb->eof_reached; i++) {
2920 int sample_duration;
2921 unsigned int sample_count;
2922 unsigned int min_entries = FFMIN(FFMAX(i + 1, 1024 * 1024), entries);
2923 MOVStts *stts_data = av_fast_realloc(sc->stts_data, &alloc_size,
2924 min_entries * sizeof(*sc->stts_data));
2926 av_freep(&sc->stts_data);
2928 return AVERROR(ENOMEM);
2930 sc->stts_count = min_entries;
2931 sc->stts_data = stts_data;
2933 sample_count = avio_rb32(pb);
2934 sample_duration = avio_rb32(pb);
2936 sc->stts_data[i].count= sample_count;
2937 sc->stts_data[i].duration= sample_duration;
2939 av_log(c->fc, AV_LOG_TRACE, "sample_count=%d, sample_duration=%d\n",
2940 sample_count, sample_duration);
2942 duration+=(int64_t)sample_duration*(uint64_t)sample_count;
2943 total_sample_count+=sample_count;
2949 duration <= INT64_MAX - sc->duration_for_fps &&
2950 total_sample_count <= INT_MAX - sc->nb_frames_for_fps) {
2951 sc->duration_for_fps += duration;
2952 sc->nb_frames_for_fps += total_sample_count;
2955 if (pb->eof_reached) {
2956 av_log(c->fc, AV_LOG_WARNING, "reached eof, corrupted STTS atom\n");
2960 st->nb_frames= total_sample_count;
2962 st->duration= FFMIN(st->duration, duration);
2963 sc->track_end = duration;
2967 static int mov_read_sdtp(MOVContext *c, AVIOContext *pb, MOVAtom atom)
2970 MOVStreamContext *sc;
2973 if (c->fc->nb_streams < 1)
2975 st = c->fc->streams[c->fc->nb_streams - 1];
2978 avio_r8(pb); /* version */
2979 avio_rb24(pb); /* flags */
2980 entries = atom.size - 4;
2982 av_log(c->fc, AV_LOG_TRACE, "track[%u].sdtp.entries = %" PRId64 "\n",
2983 c->fc->nb_streams - 1, entries);
2986 av_log(c->fc, AV_LOG_WARNING, "Duplicated SDTP atom\n");
2987 av_freep(&sc->sdtp_data);
2990 sc->sdtp_data = av_mallocz(entries);
2992 return AVERROR(ENOMEM);
2994 for (i = 0; i < entries && !pb->eof_reached; i++)
2995 sc->sdtp_data[i] = avio_r8(pb);
3001 static void mov_update_dts_shift(MOVStreamContext *sc, int duration, void *logctx)
3004 if (duration == INT_MIN) {
3005 av_log(logctx, AV_LOG_WARNING, "mov_update_dts_shift(): dts_shift set to %d\n", INT_MAX);
3008 sc->dts_shift = FFMAX(sc->dts_shift, -duration);
3012 static int mov_read_ctts(MOVContext *c, AVIOContext *pb, MOVAtom atom)
3015 MOVStreamContext *sc;
3016 unsigned int i, entries, ctts_count = 0;
3018 if (c->fc->nb_streams < 1)
3020 st = c->fc->streams[c->fc->nb_streams-1];
3023 avio_r8(pb); /* version */
3024 avio_rb24(pb); /* flags */
3025 entries = avio_rb32(pb);
3027 av_log(c->fc, AV_LOG_TRACE, "track[%u].ctts.entries = %u\n", c->fc->nb_streams - 1, entries);
3031 if (entries >= UINT_MAX / sizeof(*sc->ctts_data))
3032 return AVERROR_INVALIDDATA;
3033 av_freep(&sc->ctts_data);
3034 sc->ctts_data = av_fast_realloc(NULL, &sc->ctts_allocated_size, entries * sizeof(*sc->ctts_data));
3036 return AVERROR(ENOMEM);
3038 for (i = 0; i < entries && !pb->eof_reached; i++) {
3039 int count = avio_rb32(pb);
3040 int duration = avio_rb32(pb);
3043 av_log(c->fc, AV_LOG_TRACE,
3044 "ignoring CTTS entry with count=%d duration=%d\n",
3049 add_ctts_entry(&sc->ctts_data, &ctts_count, &sc->ctts_allocated_size,
3052 av_log(c->fc, AV_LOG_TRACE, "count=%d, duration=%d\n",
3055 if (FFNABS(duration) < -(1<<28) && i+2<entries) {
3056 av_log(c->fc, AV_LOG_WARNING, "CTTS invalid\n");
3057 av_freep(&sc->ctts_data);
3063 mov_update_dts_shift(sc, duration, c->fc);
3066 sc->ctts_count = ctts_count;
3068 if (pb->eof_reached) {
3069 av_log(c->fc, AV_LOG_WARNING, "reached eof, corrupted CTTS atom\n");
3073 av_log(c->fc, AV_LOG_TRACE, "dts shift %d\n", sc->dts_shift);
3078 static int mov_read_sbgp(MOVContext *c, AVIOContext *pb, MOVAtom atom)
3081 MOVStreamContext *sc;
3082 unsigned int i, entries;
3084 uint32_t grouping_type;
3086 if (c->fc->nb_streams < 1)
3088 st = c->fc->streams[c->fc->nb_streams-1];
3091 version = avio_r8(pb); /* version */
3092 avio_rb24(pb); /* flags */
3093 grouping_type = avio_rl32(pb);
3094 if (grouping_type != MKTAG( 'r','a','p',' '))
3095 return 0; /* only support 'rap ' grouping */
3097 avio_rb32(pb); /* grouping_type_parameter */
3099 entries = avio_rb32(pb);
3103 av_log(c->fc, AV_LOG_WARNING, "Duplicated SBGP atom\n");
3104 av_free(sc->rap_group);
3105 sc->rap_group_count = 0;
3106 sc->rap_group = av_malloc_array(entries, sizeof(*sc->rap_group));
3108 return AVERROR(ENOMEM);
3110 for (i = 0; i < entries && !pb->eof_reached; i++) {
3111 sc->rap_group[i].count = avio_rb32(pb); /* sample_count */
3112 sc->rap_group[i].index = avio_rb32(pb); /* group_description_index */
3115 sc->rap_group_count = i;
3117 if (pb->eof_reached) {
3118 av_log(c->fc, AV_LOG_WARNING, "reached eof, corrupted SBGP atom\n");
3126 * Get ith edit list entry (media time, duration).
3128 static int get_edit_list_entry(MOVContext *mov,
3129 const MOVStreamContext *msc,
3130 unsigned int edit_list_index,
3131 int64_t *edit_list_media_time,
3132 int64_t *edit_list_duration,
3133 int64_t global_timescale)
3135 if (edit_list_index == msc->elst_count) {
3138 *edit_list_media_time = msc->elst_data[edit_list_index].time;
3139 *edit_list_duration = msc->elst_data[edit_list_index].duration;
3141 /* duration is in global timescale units;convert to msc timescale */
3142 if (global_timescale == 0) {
3143 avpriv_request_sample(mov->fc, "Support for mvhd.timescale = 0 with editlists");
3146 *edit_list_duration = av_rescale(*edit_list_duration, msc->time_scale,
3152 * Find the closest previous frame to the timestamp_pts, in e_old index
3153 * entries. Searching for just any frame / just key frames can be controlled by
3154 * last argument 'flag'.
3155 * Note that if ctts_data is not NULL, we will always search for a key frame
3156 * irrespective of the value of 'flag'. If we don't find any keyframe, we will
3157 * return the first frame of the video.
3159 * Here the timestamp_pts is considered to be a presentation timestamp and
3160 * the timestamp of index entries are considered to be decoding timestamps.
3162 * Returns 0 if successful in finding a frame, else returns -1.
3163 * Places the found index corresponding output arg.
3165 * If ctts_old is not NULL, then refines the searched entry by searching
3166 * backwards from the found timestamp, to find the frame with correct PTS.
3168 * Places the found ctts_index and ctts_sample in corresponding output args.
3170 static int find_prev_closest_index(AVStream *st,
3171 AVIndexEntry *e_old,
3175 int64_t timestamp_pts,
3178 int64_t* ctts_index,
3179 int64_t* ctts_sample)
3181 MOVStreamContext *msc = st->priv_data;
3182 AVIndexEntry *e_keep = st->index_entries;
3183 int nb_keep = st->nb_index_entries;
3185 int64_t index_ctts_count;
3189 // If dts_shift > 0, then all the index timestamps will have to be offset by
3190 // at least dts_shift amount to obtain PTS.
3191 // Hence we decrement the searched timestamp_pts by dts_shift to find the closest index element.
3192 if (msc->dts_shift > 0) {
3193 timestamp_pts -= msc->dts_shift;
3196 st->index_entries = e_old;
3197 st->nb_index_entries = nb_old;
3198 *index = av_index_search_timestamp(st, timestamp_pts, flag | AVSEEK_FLAG_BACKWARD);
3200 // Keep going backwards in the index entries until the timestamp is the same.
3202 for (i = *index; i > 0 && e_old[i].timestamp == e_old[i - 1].timestamp;
3204 if ((flag & AVSEEK_FLAG_ANY) ||
3205 (e_old[i - 1].flags & AVINDEX_KEYFRAME)) {
3211 // If we have CTTS then refine the search, by searching backwards over PTS
3212 // computed by adding corresponding CTTS durations to index timestamps.
3213 if (ctts_data && *index >= 0) {
3214 av_assert0(ctts_index);
3215 av_assert0(ctts_sample);
3216 // Find out the ctts_index for the found frame.
3219 for (index_ctts_count = 0; index_ctts_count < *index; index_ctts_count++) {
3220 if (*ctts_index < ctts_count) {
3222 if (ctts_data[*ctts_index].count == *ctts_sample) {
3229 while (*index >= 0 && (*ctts_index) >= 0 && (*ctts_index) < ctts_count) {
3230 // Find a "key frame" with PTS <= timestamp_pts (So that we can decode B-frames correctly).
3231 // No need to add dts_shift to the timestamp here becase timestamp_pts has already been
3232 // compensated by dts_shift above.
3233 if ((e_old[*index].timestamp + ctts_data[*ctts_index].duration) <= timestamp_pts &&
3234 (e_old[*index].flags & AVINDEX_KEYFRAME)) {
3239 if (*ctts_sample == 0) {
3241 if (*ctts_index >= 0)
3242 *ctts_sample = ctts_data[*ctts_index].count - 1;
3249 /* restore AVStream state*/
3250 st->index_entries = e_keep;
3251 st->nb_index_entries = nb_keep;
3252 return *index >= 0 ? 0 : -1;
3256 * Add index entry with the given values, to the end of st->index_entries.
3257 * Returns the new size st->index_entries if successful, else returns -1.
3259 * This function is similar to ff_add_index_entry in libavformat/utils.c
3260 * except that here we are always unconditionally adding an index entry to
3261 * the end, instead of searching the entries list and skipping the add if
3262 * there is an existing entry with the same timestamp.
3263 * This is needed because the mov_fix_index calls this func with the same
3264 * unincremented timestamp for successive discarded frames.
3266 static int64_t add_index_entry(AVStream *st, int64_t pos, int64_t timestamp,
3267 int size, int distance, int flags)
3269 AVIndexEntry *entries, *ie;
3271 const size_t min_size_needed = (st->nb_index_entries + 1) * sizeof(AVIndexEntry);
3273 // Double the allocation each time, to lower memory fragmentation.
3274 // Another difference from ff_add_index_entry function.
3275 const size_t requested_size =
3276 min_size_needed > st->index_entries_allocated_size ?
3277 FFMAX(min_size_needed, 2 * st->index_entries_allocated_size) :
3280 if (st->nb_index_entries + 1U >= UINT_MAX / sizeof(AVIndexEntry))
3283 entries = av_fast_realloc(st->index_entries,
3284 &st->index_entries_allocated_size,
3289 st->index_entries= entries;
3291 index= st->nb_index_entries++;
3292 ie= &entries[index];
3295 ie->timestamp = timestamp;
3296 ie->min_distance= distance;
3303 * Rewrite timestamps of index entries in the range [end_index - frame_duration_buffer_size, end_index)
3304 * by subtracting end_ts successively by the amounts given in frame_duration_buffer.
3306 static void fix_index_entry_timestamps(AVStream* st, int end_index, int64_t end_ts,
3307 int64_t* frame_duration_buffer,
3308 int frame_duration_buffer_size) {
3310 av_assert0(end_index >= 0 && end_index <= st->nb_index_entries);
3311 for (i = 0; i < frame_duration_buffer_size; i++) {
3312 end_ts -= frame_duration_buffer[frame_duration_buffer_size - 1 - i];
3313 st->index_entries[end_index - 1 - i].timestamp = end_ts;
3318 * Append a new ctts entry to ctts_data.
3319 * Returns the new ctts_count if successful, else returns -1.
3321 static int64_t add_ctts_entry(MOVStts** ctts_data, unsigned int* ctts_count, unsigned int* allocated_size,
3322 int count, int duration)
3324 MOVStts *ctts_buf_new;
3325 const size_t min_size_needed = (*ctts_count + 1) * sizeof(MOVStts);
3326 const size_t requested_size =
3327 min_size_needed > *allocated_size ?
3328 FFMAX(min_size_needed, 2 * (*allocated_size)) :
3331 if ((unsigned)(*ctts_count) >= UINT_MAX / sizeof(MOVStts) - 1)
3334 ctts_buf_new = av_fast_realloc(*ctts_data, allocated_size, requested_size);
3339 *ctts_data = ctts_buf_new;
3341 ctts_buf_new[*ctts_count].count = count;
3342 ctts_buf_new[*ctts_count].duration = duration;
3344 *ctts_count = (*ctts_count) + 1;
3348 #define MAX_REORDER_DELAY 16
3349 static void mov_estimate_video_delay(MOVContext *c, AVStream* st)
3351 MOVStreamContext *msc = st->priv_data;
3354 int ctts_sample = 0;
3355 int64_t pts_buf[MAX_REORDER_DELAY + 1]; // Circular buffer to sort pts.
3357 int j, r, num_swaps;
3359 for (j = 0; j < MAX_REORDER_DELAY + 1; j++)
3360 pts_buf[j] = INT64_MIN;
3362 if (st->codecpar->video_delay <= 0 && msc->ctts_data &&
3363 st->codecpar->codec_id == AV_CODEC_ID_H264) {
3364 st->codecpar->video_delay = 0;
3365 for (ind = 0; ind < st->nb_index_entries && ctts_ind < msc->ctts_count; ++ind) {
3366 // Point j to the last elem of the buffer and insert the current pts there.
3368 buf_start = (buf_start + 1);
3369 if (buf_start == MAX_REORDER_DELAY + 1)
3372 pts_buf[j] = st->index_entries[ind].timestamp + msc->ctts_data[ctts_ind].duration;
3374 // The timestamps that are already in the sorted buffer, and are greater than the
3375 // current pts, are exactly the timestamps that need to be buffered to output PTS
3376 // in correct sorted order.
3377 // Hence the video delay (which is the buffer size used to sort DTS and output PTS),
3378 // can be computed as the maximum no. of swaps any particular timestamp needs to
3379 // go through, to keep this buffer in sorted order.
3381 while (j != buf_start) {
3383 if (r < 0) r = MAX_REORDER_DELAY;
3384 if (pts_buf[j] < pts_buf[r]) {
3385 FFSWAP(int64_t, pts_buf[j], pts_buf[r]);
3392 st->codecpar->video_delay = FFMAX(st->codecpar->video_delay, num_swaps);
3395 if (ctts_sample == msc->ctts_data[ctts_ind].count) {
3400 av_log(c->fc, AV_LOG_DEBUG, "Setting codecpar->delay to %d for stream st: %d\n",
3401 st->codecpar->video_delay, st->index);
3405 static void mov_current_sample_inc(MOVStreamContext *sc)
3407 sc->current_sample++;
3408 sc->current_index++;
3409 if (sc->index_ranges &&
3410 sc->current_index >= sc->current_index_range->end &&
3411 sc->current_index_range->end) {
3412 sc->current_index_range++;
3413 sc->current_index = sc->current_index_range->start;
3417 static void mov_current_sample_dec(MOVStreamContext *sc)
3419 sc->current_sample--;
3420 sc->current_index--;
3421 if (sc->index_ranges &&
3422 sc->current_index < sc->current_index_range->start &&
3423 sc->current_index_range > sc->index_ranges) {
3424 sc->current_index_range--;
3425 sc->current_index = sc->current_index_range->end - 1;
3429 static void mov_current_sample_set(MOVStreamContext *sc, int current_sample)
3433 sc->current_sample = current_sample;
3434 sc->current_index = current_sample;
3435 if (!sc->index_ranges) {
3439 for (sc->current_index_range = sc->index_ranges;
3440 sc->current_index_range->end;
3441 sc->current_index_range++) {
3442 range_size = sc->current_index_range->end - sc->current_index_range->start;
3443 if (range_size > current_sample) {
3444 sc->current_index = sc->current_index_range->start + current_sample;
3447 current_sample -= range_size;
3452 * Fix st->index_entries, so that it contains only the entries (and the entries
3453 * which are needed to decode them) that fall in the edit list time ranges.
3454 * Also fixes the timestamps of the index entries to match the timeline
3455 * specified the edit lists.
3457 static void mov_fix_index(MOVContext *mov, AVStream *st)
3459 MOVStreamContext *msc = st->priv_data;
3460 AVIndexEntry *e_old = st->index_entries;
3461 int nb_old = st->nb_index_entries;
3462 const AVIndexEntry *e_old_end = e_old + nb_old;
3463 const AVIndexEntry *current = NULL;
3464 MOVStts *ctts_data_old = msc->ctts_data;
3465 int64_t ctts_index_old = 0;
3466 int64_t ctts_sample_old = 0;
3467 int64_t ctts_count_old = msc->ctts_count;
3468 int64_t edit_list_media_time = 0;
3469 int64_t edit_list_duration = 0;
3470 int64_t frame_duration = 0;
3471 int64_t edit_list_dts_counter = 0;
3472 int64_t edit_list_dts_entry_end = 0;
3473 int64_t edit_list_start_ctts_sample = 0;
3475 int64_t curr_ctts = 0;
3476 int64_t empty_edits_sum_duration = 0;
3477 int64_t edit_list_index = 0;
3480 int64_t start_dts = 0;
3481 int64_t edit_list_start_encountered = 0;
3482 int64_t search_timestamp = 0;
3483 int64_t* frame_duration_buffer = NULL;
3484 int num_discarded_begin = 0;
3485 int first_non_zero_audio_edit = -1;
3486 int packet_skip_samples = 0;
3487 MOVIndexRange *current_index_range;
3489 int found_keyframe_after_edit = 0;
3490 int found_non_empty_edit = 0;
3492 if (!msc->elst_data || msc->elst_count <= 0 || nb_old <= 0) {
3496 // allocate the index ranges array
3497 msc->index_ranges = av_malloc((msc->elst_count + 1) * sizeof(msc->index_ranges[0]));
3498 if (!msc->index_ranges) {
3499 av_log(mov->fc, AV_LOG_ERROR, "Cannot allocate index ranges buffer\n");
3502 msc->current_index_range = msc->index_ranges;
3503 current_index_range = msc->index_ranges - 1;
3505 // Clean AVStream from traces of old index
3506 st->index_entries = NULL;
3507 st->index_entries_allocated_size = 0;
3508 st->nb_index_entries = 0;
3510 // Clean ctts fields of MOVStreamContext
3511 msc->ctts_data = NULL;
3512 msc->ctts_count = 0;
3513 msc->ctts_index = 0;
3514 msc->ctts_sample = 0;
3515 msc->ctts_allocated_size = 0;
3517 // Reinitialize min_corrected_pts so that it can be computed again.
3518 msc->min_corrected_pts = -1;
3520 // If the dts_shift is positive (in case of negative ctts values in mov),
3521 // then negate the DTS by dts_shift
3522 if (msc->dts_shift > 0) {
3523 edit_list_dts_entry_end -= msc->dts_shift;
3524 av_log(mov->fc, AV_LOG_DEBUG, "Shifting DTS by %d because of negative CTTS.\n", msc->dts_shift);
3527 start_dts = edit_list_dts_entry_end;
3529 while (get_edit_list_entry(mov, msc, edit_list_index, &edit_list_media_time,
3530 &edit_list_duration, mov->time_scale)) {
3531 av_log(mov->fc, AV_LOG_DEBUG, "Processing st: %d, edit list %"PRId64" - media time: %"PRId64", duration: %"PRId64"\n",
3532 st->index, edit_list_index, edit_list_media_time, edit_list_duration);
3534 edit_list_dts_counter = edit_list_dts_entry_end;
3535 edit_list_dts_entry_end += edit_list_duration;
3536 num_discarded_begin = 0;
3537 if (!found_non_empty_edit && edit_list_media_time == -1) {
3538 empty_edits_sum_duration += edit_list_duration;
3541 found_non_empty_edit = 1;
3543 // If we encounter a non-negative edit list reset the skip_samples/start_pad fields and set them
3544 // according to the edit list below.
3545 if (st->codecpar->codec_type == AVMEDIA_TYPE_AUDIO) {
3546 if (first_non_zero_audio_edit < 0) {
3547 first_non_zero_audio_edit = 1;
3549 first_non_zero_audio_edit = 0;
3552 if (first_non_zero_audio_edit > 0)
3553 st->skip_samples = msc->start_pad = 0;
3556 // While reordering frame index according to edit list we must handle properly
3557 // the scenario when edit list entry starts from none key frame.
3558 // We find closest previous key frame and preserve it and consequent frames in index.
3559 // All frames which are outside edit list entry time boundaries will be dropped after decoding.
3560 search_timestamp = edit_list_media_time;
3561 if (st->codecpar->codec_type == AVMEDIA_TYPE_AUDIO) {
3562 // Audio decoders like AAC need need a decoder delay samples previous to the current sample,
3563 // to correctly decode this frame. Hence for audio we seek to a frame 1 sec. before the
3564 // edit_list_media_time to cover the decoder delay.
3565 search_timestamp = FFMAX(search_timestamp - msc->time_scale, e_old[0].timestamp);
3568 if (find_prev_closest_index(st, e_old, nb_old, ctts_data_old, ctts_count_old, search_timestamp, 0,
3569 &index, &ctts_index_old, &ctts_sample_old) < 0) {
3570 av_log(mov->fc, AV_LOG_WARNING,
3571 "st: %d edit list: %"PRId64" Missing key frame while searching for timestamp: %"PRId64"\n",
3572 st->index, edit_list_index, search_timestamp);
3573 if (find_prev_closest_index(st, e_old, nb_old, ctts_data_old, ctts_count_old, search_timestamp, AVSEEK_FLAG_ANY,
3574 &index, &ctts_index_old, &ctts_sample_old) < 0) {
3575 av_log(mov->fc, AV_LOG_WARNING,
3576 "st: %d edit list %"PRId64" Cannot find an index entry before timestamp: %"PRId64".\n",
3577 st->index, edit_list_index, search_timestamp);
3580 ctts_sample_old = 0;
3583 current = e_old + index;
3584 edit_list_start_ctts_sample = ctts_sample_old;
3586 // Iterate over index and arrange it according to edit list
3587 edit_list_start_encountered = 0;
3588 found_keyframe_after_edit = 0;
3589 for (; current < e_old_end; current++, index++) {
3590 // check if frame outside edit list mark it for discard
3591 frame_duration = (current + 1 < e_old_end) ?
3592 ((current + 1)->timestamp - current->timestamp) : edit_list_duration;
3594 flags = current->flags;
3596 // frames (pts) before or after edit list
3597 curr_cts = current->timestamp + msc->dts_shift;
3600 if (ctts_data_old && ctts_index_old < ctts_count_old) {
3601 curr_ctts = ctts_data_old[ctts_index_old].duration;
3602 av_log(mov->fc, AV_LOG_DEBUG, "stts: %"PRId64" ctts: %"PRId64", ctts_index: %"PRId64", ctts_count: %"PRId64"\n",
3603 curr_cts, curr_ctts, ctts_index_old, ctts_count_old);
3604 curr_cts += curr_ctts;
3606 if (ctts_sample_old == ctts_data_old[ctts_index_old].count) {
3607 if (add_ctts_entry(&msc->ctts_data, &msc->ctts_count,
3608 &msc->ctts_allocated_size,
3609 ctts_data_old[ctts_index_old].count - edit_list_start_ctts_sample,
3610 ctts_data_old[ctts_index_old].duration) == -1) {
3611 av_log(mov->fc, AV_LOG_ERROR, "Cannot add CTTS entry %"PRId64" - {%"PRId64", %d}\n",
3613 ctts_data_old[ctts_index_old].count - edit_list_start_ctts_sample,
3614 ctts_data_old[ctts_index_old].duration);
3618 ctts_sample_old = 0;
3619 edit_list_start_ctts_sample = 0;
3623 if (curr_cts < edit_list_media_time || curr_cts >= (edit_list_duration + edit_list_media_time)) {
3624 if (st->codecpar->codec_type == AVMEDIA_TYPE_AUDIO && st->codecpar->codec_id != AV_CODEC_ID_VORBIS &&
3625 curr_cts < edit_list_media_time && curr_cts + frame_duration > edit_list_media_time &&
3626 first_non_zero_audio_edit > 0) {
3627 packet_skip_samples = edit_list_media_time - curr_cts;
3628 st->skip_samples += packet_skip_samples;
3630 // Shift the index entry timestamp by packet_skip_samples to be correct.
3631 edit_list_dts_counter -= packet_skip_samples;
3632 if (edit_list_start_encountered == 0) {
3633 edit_list_start_encountered = 1;
3634 // Make timestamps strictly monotonically increasing for audio, by rewriting timestamps for
3635 // discarded packets.
3636 if (frame_duration_buffer) {
3637 fix_index_entry_timestamps(st, st->nb_index_entries, edit_list_dts_counter,
3638 frame_duration_buffer, num_discarded_begin);
3639 av_freep(&frame_duration_buffer);
3643 av_log(mov->fc, AV_LOG_DEBUG, "skip %d audio samples from curr_cts: %"PRId64"\n", packet_skip_samples, curr_cts);
3645 flags |= AVINDEX_DISCARD_FRAME;
3646 av_log(mov->fc, AV_LOG_DEBUG, "drop a frame at curr_cts: %"PRId64" @ %"PRId64"\n", curr_cts, index);
3648 if (edit_list_start_encountered == 0) {
3649 num_discarded_begin++;
3650 frame_duration_buffer = av_realloc(frame_duration_buffer,
3651 num_discarded_begin * sizeof(int64_t));
3652 if (!frame_duration_buffer) {
3653 av_log(mov->fc, AV_LOG_ERROR, "Cannot reallocate frame duration buffer\n");
3656 frame_duration_buffer[num_discarded_begin - 1] = frame_duration;
3658 // Increment skip_samples for the first non-zero audio edit list
3659 if (st->codecpar->codec_type == AVMEDIA_TYPE_AUDIO &&
3660 first_non_zero_audio_edit > 0 && st->codecpar->codec_id != AV_CODEC_ID_VORBIS) {
3661 st->skip_samples += frame_duration;
3666 if (msc->min_corrected_pts < 0) {
3667 msc->min_corrected_pts = edit_list_dts_counter + curr_ctts + msc->dts_shift;
3669 msc->min_corrected_pts = FFMIN(msc->min_corrected_pts, edit_list_dts_counter + curr_ctts + msc->dts_shift);
3671 if (edit_list_start_encountered == 0) {
3672 edit_list_start_encountered = 1;
3673 // Make timestamps strictly monotonically increasing by rewriting timestamps for
3674 // discarded packets.
3675 if (frame_duration_buffer) {
3676 fix_index_entry_timestamps(st, st->nb_index_entries, edit_list_dts_counter,
3677 frame_duration_buffer, num_discarded_begin);
3678 av_freep(&frame_duration_buffer);
3683 if (add_index_entry(st, current->pos, edit_list_dts_counter, current->size,
3684 current->min_distance, flags) == -1) {
3685 av_log(mov->fc, AV_LOG_ERROR, "Cannot add index entry\n");
3689 // Update the index ranges array
3690 if (current_index_range < msc->index_ranges || index != current_index_range->end) {
3691 current_index_range++;
3692 current_index_range->start = index;
3694 current_index_range->end = index + 1;
3696 // Only start incrementing DTS in frame_duration amounts, when we encounter a frame in edit list.
3697 if (edit_list_start_encountered > 0) {
3698 edit_list_dts_counter = edit_list_dts_counter + frame_duration;
3701 // Break when found first key frame after edit entry completion
3702 if ((curr_cts + frame_duration >= (edit_list_duration + edit_list_media_time)) &&
3703 ((flags & AVINDEX_KEYFRAME) || ((st->codecpar->codec_type == AVMEDIA_TYPE_AUDIO)))) {
3704 if (ctts_data_old) {
3705 // If we have CTTS and this is the first keyframe after edit elist,
3706 // wait for one more, because there might be trailing B-frames after this I-frame
3707 // that do belong to the edit.
3708 if (st->codecpar->codec_type != AVMEDIA_TYPE_AUDIO && found_keyframe_after_edit == 0) {
3709 found_keyframe_after_edit = 1;
3712 if (ctts_sample_old != 0) {
3713 if (add_ctts_entry(&msc->ctts_data, &msc->ctts_count,
3714 &msc->ctts_allocated_size,
3715 ctts_sample_old - edit_list_start_ctts_sample,
3716 ctts_data_old[ctts_index_old].duration) == -1) {
3717 av_log(mov->fc, AV_LOG_ERROR, "Cannot add CTTS entry %"PRId64" - {%"PRId64", %d}\n",
3718 ctts_index_old, ctts_sample_old - edit_list_start_ctts_sample,
3719 ctts_data_old[ctts_index_old].duration);
3728 // If there are empty edits, then msc->min_corrected_pts might be positive
3729 // intentionally. So we subtract the sum duration of emtpy edits here.
3730 msc->min_corrected_pts -= empty_edits_sum_duration;
3732 // If the minimum pts turns out to be greater than zero after fixing the index, then we subtract the
3733 // dts by that amount to make the first pts zero.
3734 if (st->codecpar->codec_type == AVMEDIA_TYPE_VIDEO) {
3735 if (msc->min_corrected_pts > 0) {
3736 av_log(mov->fc, AV_LOG_DEBUG, "Offset DTS by %"PRId64" to make first pts zero.\n", msc->min_corrected_pts);
3737 for (i = 0; i < st->nb_index_entries; ++i) {
3738 st->index_entries[i].timestamp -= msc->min_corrected_pts;
3742 // Start time should be equal to zero or the duration of any empty edits.
3743 st->start_time = empty_edits_sum_duration;
3745 // Update av stream length, if it ends up shorter than the track's media duration
3746 st->duration = FFMIN(st->duration, edit_list_dts_entry_end - start_dts);
3747 msc->start_pad = st->skip_samples;
3749 // Free the old index and the old CTTS structures
3751 av_free(ctts_data_old);
3752 av_freep(&frame_duration_buffer);
3754 // Null terminate the index ranges array
3755 current_index_range++;
3756 current_index_range->start = 0;
3757 current_index_range->end = 0;
3758 msc->current_index = msc->index_ranges[0].start;
3761 static void mov_build_index(MOVContext *mov, AVStream *st)
3763 MOVStreamContext *sc = st->priv_data;
3764 int64_t current_offset;
3765 int64_t current_dts = 0;
3766 unsigned int stts_index = 0;
3767 unsigned int stsc_index = 0;
3768 unsigned int stss_index = 0;
3769 unsigned int stps_index = 0;
3771 uint64_t stream_size = 0;
3772 MOVStts *ctts_data_old = sc->ctts_data;
3773 unsigned int ctts_count_old = sc->ctts_count;
3775 if (sc->elst_count) {
3776 int i, edit_start_index = 0, multiple_edits = 0;
3777 int64_t empty_duration = 0; // empty duration of the first edit list entry
3778 int64_t start_time = 0; // start time of the media
3780 for (i = 0; i < sc->elst_count; i++) {
3781 const MOVElst *e = &sc->elst_data[i];
3782 if (i == 0 && e->time == -1) {
3783 /* if empty, the first entry is the start time of the stream
3784 * relative to the presentation itself */
3785 empty_duration = e->duration;
3786 edit_start_index = 1;
3787 } else if (i == edit_start_index && e->time >= 0) {
3788 start_time = e->time;
3794 if (multiple_edits && !mov->advanced_editlist)
3795 av_log(mov->fc, AV_LOG_WARNING, "multiple edit list entries, "
3796 "Use -advanced_editlist to correctly decode otherwise "
3797 "a/v desync might occur\n");
3799 /* adjust first dts according to edit list */
3800 if ((empty_duration || start_time) && mov->time_scale > 0) {
3802 empty_duration = av_rescale(empty_duration, sc->time_scale, mov->time_scale);
3803 sc->time_offset = start_time - empty_duration;
3804 sc->min_corrected_pts = start_time;
3805 if (!mov->advanced_editlist)
3806 current_dts = -sc->time_offset;
3809 if (!multiple_edits && !mov->advanced_editlist &&
3810 st->codecpar->codec_id == AV_CODEC_ID_AAC && start_time > 0)
3811 sc->start_pad = start_time;
3814 /* only use old uncompressed audio chunk demuxing when stts specifies it */
3815 if (!(st->codecpar->codec_type == AVMEDIA_TYPE_AUDIO &&
3816 sc->stts_count == 1 && sc->stts_data[0].duration == 1)) {
3817 unsigned int current_sample = 0;
3818 unsigned int stts_sample = 0;
3819 unsigned int sample_size;
3820 unsigned int distance = 0;
3821 unsigned int rap_group_index = 0;
3822 unsigned int rap_group_sample = 0;
3823 int64_t last_dts = 0;
3824 int64_t dts_correction = 0;
3825 int rap_group_present = sc->rap_group_count && sc->rap_group;
3826 int key_off = (sc->keyframe_count && sc->keyframes[0] > 0) || (sc->stps_count && sc->stps_data[0] > 0);
3828 current_dts -= sc->dts_shift;
3829 last_dts = current_dts;
3831 if (!sc->sample_count || st->nb_index_entries)
3833 if (sc->sample_count >= UINT_MAX / sizeof(*st->index_entries) - st->nb_index_entries)
3835 if (av_reallocp_array(&st->index_entries,
3836 st->nb_index_entries + sc->sample_count,
3837 sizeof(*st->index_entries)) < 0) {
3838 st->nb_index_entries = 0;
3841 st->index_entries_allocated_size = (st->nb_index_entries + sc->sample_count) * sizeof(*st->index_entries);
3843 if (ctts_data_old) {
3844 // Expand ctts entries such that we have a 1-1 mapping with samples
3845 if (sc->sample_count >= UINT_MAX / sizeof(*sc->ctts_data))
3848 sc->ctts_allocated_size = 0;
3849 sc->ctts_data = av_fast_realloc(NULL, &sc->ctts_allocated_size,
3850 sc->sample_count * sizeof(*sc->ctts_data));
3851 if (!sc->ctts_data) {
3852 av_free(ctts_data_old);
3856 memset((uint8_t*)(sc->ctts_data), 0, sc->ctts_allocated_size);
3858 for (i = 0; i < ctts_count_old &&
3859 sc->ctts_count < sc->sample_count; i++)
3860 for (j = 0; j < ctts_data_old[i].count &&
3861 sc->ctts_count < sc->sample_count; j++)
3862 add_ctts_entry(&sc->ctts_data, &sc->ctts_count,
3863 &sc->ctts_allocated_size, 1,
3864 ctts_data_old[i].duration);
3865 av_free(ctts_data_old);
3868 for (i = 0; i < sc->chunk_count; i++) {
3869 int64_t next_offset = i+1 < sc->chunk_count ? sc->chunk_offsets[i+1] : INT64_MAX;
3870 current_offset = sc->chunk_offsets[i];
3871 while (mov_stsc_index_valid(stsc_index, sc->stsc_count) &&
3872 i + 1 == sc->stsc_data[stsc_index + 1].first)
3875 if (next_offset > current_offset && sc->sample_size>0 && sc->sample_size < sc->stsz_sample_size &&
3876 sc->stsc_data[stsc_index].count * (int64_t)sc->stsz_sample_size > next_offset - current_offset) {
3877 av_log(mov->fc, AV_LOG_WARNING, "STSZ sample size %d invalid (too large), ignoring\n", sc->stsz_sample_size);
3878 sc->stsz_sample_size = sc->sample_size;
3880 if (sc->stsz_sample_size>0 && sc->stsz_sample_size < sc->sample_size) {
3881 av_log(mov->fc, AV_LOG_WARNING, "STSZ sample size %d invalid (too small), ignoring\n", sc->stsz_sample_size);
3882 sc->stsz_sample_size = sc->sample_size;
3885 for (j = 0; j < sc->stsc_data[stsc_index].count; j++) {
3887 if (current_sample >= sc->sample_count) {
3888 av_log(mov->fc, AV_LOG_ERROR, "wrong sample count\n");
3892 if (!sc->keyframe_absent && (!sc->keyframe_count || current_sample+key_off == sc->keyframes[stss_index])) {
3894 if (stss_index + 1 < sc->keyframe_count)
3896 } else if (sc->stps_count && current_sample+key_off == sc->stps_data[stps_index]) {
3898 if (stps_index + 1 < sc->stps_count)
3901 if (rap_group_present && rap_group_index < sc->rap_group_count) {
3902 if (sc->rap_group[rap_group_index].index > 0)
3904 if (++rap_group_sample == sc->rap_group[rap_group_index].count) {
3905 rap_group_sample = 0;
3909 if (sc->keyframe_absent
3911 && !rap_group_present
3912 && (st->codecpar->codec_type == AVMEDIA_TYPE_AUDIO || (i==0 && j==0)))
3916 sample_size = sc->stsz_sample_size > 0 ? sc->stsz_sample_size : sc->sample_sizes[current_sample];
3917 if (sc->pseudo_stream_id == -1 ||
3918 sc->stsc_data[stsc_index].id - 1 == sc->pseudo_stream_id) {
3920 if (sample_size > 0x3FFFFFFF) {
3921 av_log(mov->fc, AV_LOG_ERROR, "Sample size %u is too large\n", sample_size);
3924 e = &st->index_entries[st->nb_index_entries++];
3925 e->pos = current_offset;
3926 e->timestamp = current_dts;
3927 e->size = sample_size;
3928 e->min_distance = distance;
3929 e->flags = keyframe ? AVINDEX_KEYFRAME : 0;
3930 av_log(mov->fc, AV_LOG_TRACE, "AVIndex stream %d, sample %u, offset %"PRIx64", dts %"PRId64", "
3931 "size %u, distance %u, keyframe %d\n", st->index, current_sample,
3932 current_offset, current_dts, sample_size, distance, keyframe);
3933 if (st->codecpar->codec_type == AVMEDIA_TYPE_VIDEO && st->nb_index_entries < 100)
3934 ff_rfps_add_frame(mov->fc, st, current_dts);
3937 current_offset += sample_size;
3938 stream_size += sample_size;
3940 /* A negative sample duration is invalid based on the spec,
3941 * but some samples need it to correct the DTS. */
3942 if (sc->stts_data[stts_index].duration < 0) {
3943 av_log(mov->fc, AV_LOG_WARNING,
3944 "Invalid SampleDelta %d in STTS, at %d st:%d\n",
3945 sc->stts_data[stts_index].duration, stts_index,
3947 dts_correction += sc->stts_data[stts_index].duration - 1;
3948 sc->stts_data[stts_index].duration = 1;
3950 current_dts += sc->stts_data[stts_index].duration;
3951 if (!dts_correction || current_dts + dts_correction > last_dts) {
3952 current_dts += dts_correction;
3955 /* Avoid creating non-monotonous DTS */
3956 dts_correction += current_dts - last_dts - 1;
3957 current_dts = last_dts + 1;
3959 last_dts = current_dts;
3963 if (stts_index + 1 < sc->stts_count && stts_sample == sc->stts_data[stts_index].count) {
3969 if (st->duration > 0)
3970 st->codecpar->bit_rate = stream_size*8*sc->time_scale/st->duration;
3972 unsigned chunk_samples, total = 0;
3974 if (!sc->chunk_count)
3977 // compute total chunk count
3978 for (i = 0; i < sc->stsc_count; i++) {
3979 unsigned count, chunk_count;
3981 chunk_samples = sc->stsc_data[i].count;
3982 if (i != sc->stsc_count - 1 &&
3983 sc->samples_per_frame && chunk_samples % sc->samples_per_frame) {
3984 av_log(mov->fc, AV_LOG_ERROR, "error unaligned chunk\n");
3988 if (sc->samples_per_frame >= 160) { // gsm
3989 count = chunk_samples / sc->samples_per_frame;
3990 } else if (sc->samples_per_frame > 1) {
3991 unsigned samples = (1024/sc->samples_per_frame)*sc->samples_per_frame;
3992 count = (chunk_samples+samples-1) / samples;
3994 count = (chunk_samples+1023) / 1024;
3997 if (mov_stsc_index_valid(i, sc->stsc_count))
3998 chunk_count = sc->stsc_data[i+1].first - sc->stsc_data[i].first;
4000 chunk_count = sc->chunk_count - (sc->stsc_data[i].first - 1);
4001 total += chunk_count * count;
4004 av_log(mov->fc, AV_LOG_TRACE, "chunk count %u\n", total);
4005 if (total >= UINT_MAX / sizeof(*st->index_entries) - st->nb_index_entries)
4007 if (av_reallocp_array(&st->index_entries,
4008 st->nb_index_entries + total,
4009 sizeof(*st->index_entries)) < 0) {
4010 st->nb_index_entries = 0;
4013 st->index_entries_allocated_size = (st->nb_index_entries + total) * sizeof(*st->index_entries);
4016 for (i = 0; i < sc->chunk_count; i++) {
4017 current_offset = sc->chunk_offsets[i];
4018 if (mov_stsc_index_valid(stsc_index, sc->stsc_count) &&
4019 i + 1 == sc->stsc_data[stsc_index + 1].first)
4021 chunk_samples = sc->stsc_data[stsc_index].count;
4023 while (chunk_samples > 0) {
4025 unsigned size, samples;
4027 if (sc->samples_per_frame > 1 && !sc->bytes_per_frame) {
4028 avpriv_request_sample(mov->fc,
4029 "Zero bytes per frame, but %d samples per frame",
4030 sc->samples_per_frame);
4034 if (sc->samples_per_frame >= 160) { // gsm
4035 samples = sc->samples_per_frame;
4036 size = sc->bytes_per_frame;
4038 if (sc->samples_per_frame > 1) {
4039 samples = FFMIN((1024 / sc->samples_per_frame)*
4040 sc->samples_per_frame, chunk_samples);
4041 size = (samples / sc->samples_per_frame) * sc->bytes_per_frame;
4043 samples = FFMIN(1024, chunk_samples);
4044 size = samples * sc->sample_size;
4048 if (st->nb_index_entries >= total) {
4049 av_log(mov->fc, AV_LOG_ERROR, "wrong chunk count %u\n", total);
4052 if (size > 0x3FFFFFFF) {
4053 av_log(mov->fc, AV_LOG_ERROR, "Sample size %u is too large\n", size);
4056 e = &st->index_entries[st->nb_index_entries++];
4057 e->pos = current_offset;
4058 e->timestamp = current_dts;
4060 e->min_distance = 0;
4061 e->flags = AVINDEX_KEYFRAME;
4062 av_log(mov->fc, AV_LOG_TRACE, "AVIndex stream %d, chunk %u, offset %"PRIx64", dts %"PRId64", "
4063 "size %u, duration %u\n", st->index, i, current_offset, current_dts,
4066 current_offset += size;
4067 current_dts += samples;
4068 chunk_samples -= samples;
4073 if (!mov->ignore_editlist && mov->advanced_editlist) {
4074 // Fix index according to edit lists.
4075 mov_fix_index(mov, st);
4078 // Update start time of the stream.
4079 if (st->start_time == AV_NOPTS_VALUE && st->codecpar->codec_type == AVMEDIA_TYPE_VIDEO && st->nb_index_entries > 0) {
4080 st->start_time = st->index_entries[0].timestamp + sc->dts_shift;
4081 if (sc->ctts_data) {
4082 st->start_time += sc->ctts_data[0].duration;
4086 mov_estimate_video_delay(mov, st);
4089 static int test_same_origin(const char *src, const char *ref) {
4099 av_url_split(src_proto, sizeof(src_proto), src_auth, sizeof(src_auth), src_host, sizeof(src_host), &src_port, NULL, 0, src);
4100 av_url_split(ref_proto, sizeof(ref_proto), ref_auth, sizeof(ref_auth), ref_host, sizeof(ref_host), &ref_port, NULL, 0, ref);
4102 if (strlen(src) == 0) {
4104 } else if (strlen(src_auth) + 1 >= sizeof(src_auth) ||
4105 strlen(ref_auth) + 1 >= sizeof(ref_auth) ||
4106 strlen(src_host) + 1 >= sizeof(src_host) ||
4107 strlen(ref_host) + 1 >= sizeof(ref_host)) {
4109 } else if (strcmp(src_proto, ref_proto) ||
4110 strcmp(src_auth, ref_auth) ||
4111 strcmp(src_host, ref_host) ||
4112 src_port != ref_port) {
4118 static int mov_open_dref(MOVContext *c, AVIOContext **pb, const char *src, MOVDref *ref)
4120 /* try relative path, we do not try the absolute because it can leak information about our
4121 system to an attacker */
4122 if (ref->nlvl_to > 0 && ref->nlvl_from > 0) {
4123 char filename[1025];
4124 const char *src_path;
4127 /* find a source dir */
4128 src_path = strrchr(src, '/');
4134 /* find a next level down to target */
4135 for (i = 0, l = strlen(ref->path) - 1; l >= 0; l--)
4136 if (ref->path[l] == '/') {
4137 if (i == ref->nlvl_to - 1)
4143 /* compose filename if next level down to target was found */
4144 if (i == ref->nlvl_to - 1 && src_path - src < sizeof(filename)) {
4145 memcpy(filename, src, src_path - src);
4146 filename[src_path - src] = 0;
4148 for (i = 1; i < ref->nlvl_from; i++)
4149 av_strlcat(filename, "../", sizeof(filename));
4151 av_strlcat(filename, ref->path + l + 1, sizeof(filename));
4152 if (!c->use_absolute_path) {
4153 int same_origin = test_same_origin(src, filename);
4156 av_log(c->fc, AV_LOG_ERROR,
4157 "Reference with mismatching origin, %s not tried for security reasons, "
4158 "set demuxer option use_absolute_path to allow it anyway\n",
4160 return AVERROR(ENOENT);
4163 if (strstr(ref->path + l + 1, "..") ||
4164 strstr(ref->path + l + 1, ":") ||
4165 (ref->nlvl_from > 1 && same_origin < 0) ||
4166 (filename[0] == '/' && src_path == src))
4167 return AVERROR(ENOENT);
4170 if (strlen(filename) + 1 == sizeof(filename))
4171 return AVERROR(ENOENT);
4172 if (!c->fc->io_open(c->fc, pb, filename, AVIO_FLAG_READ, NULL))
4175 } else if (c->use_absolute_path) {
4176 av_log(c->fc, AV_LOG_WARNING, "Using absolute path on user request, "
4177 "this is a possible security issue\n");
4178 if (!c->fc->io_open(c->fc, pb, ref->path, AVIO_FLAG_READ, NULL))
4181 av_log(c->fc, AV_LOG_ERROR,
4182 "Absolute path %s not tried for security reasons, "
4183 "set demuxer option use_absolute_path to allow absolute paths\n",
4187 return AVERROR(ENOENT);
4190 static void fix_timescale(MOVContext *c, MOVStreamContext *sc)
4192 if (sc->time_scale <= 0) {
4193 av_log(c->fc, AV_LOG_WARNING, "stream %d, timescale not set\n", sc->ffindex);
4194 sc->time_scale = c->time_scale;
4195 if (sc->time_scale <= 0)
4200 static int mov_read_trak(MOVContext *c, AVIOContext *pb, MOVAtom atom)
4203 MOVStreamContext *sc;
4206 st = avformat_new_stream(c->fc, NULL);
4207 if (!st) return AVERROR(ENOMEM);
4209 sc = av_mallocz(sizeof(MOVStreamContext));
4210 if (!sc) return AVERROR(ENOMEM);
4213 st->codecpar->codec_type = AVMEDIA_TYPE_DATA;
4214 sc->ffindex = st->index;
4215 c->trak_index = st->index;
4217 if ((ret = mov_read_default(c, pb, atom)) < 0)
4222 // Here stsc refers to a chunk not described in stco. This is technically invalid,
4223 // but we can overlook it (clearing stsc) whenever stts_count == 0 (indicating no samples).
4224 if (!sc->chunk_count && !sc->stts_count && sc->stsc_count) {
4226 av_freep(&sc->stsc_data);
4230 if ((sc->chunk_count && (!sc->stts_count || !sc->stsc_count ||
4231 (!sc->sample_size && !sc->sample_count))) ||
4232 (!sc->chunk_count && sc->sample_count)) {
4233 av_log(c->fc, AV_LOG_ERROR, "stream %d, missing mandatory atoms, broken header\n",
4237 if (sc->stsc_count && sc->stsc_data[ sc->stsc_count - 1 ].first > sc->chunk_count) {
4238 av_log(c->fc, AV_LOG_ERROR, "stream %d, contradictionary STSC and STCO\n",
4240 return AVERROR_INVALIDDATA;
4243 fix_timescale(c, sc);
4245 avpriv_set_pts_info(st, 64, 1, sc->time_scale);
4247 mov_build_index(c, st);
4249 if (sc->dref_id-1 < sc->drefs_count && sc->drefs[sc->dref_id-1].path) {
4250 MOVDref *dref = &sc->drefs[sc->dref_id - 1];
4251 if (c->enable_drefs) {
4252 if (mov_open_dref(c, &sc->pb, c->fc->url, dref) < 0)
4253 av_log(c->fc, AV_LOG_ERROR,
4254 "stream %d, error opening alias: path='%s', dir='%s', "
4255 "filename='%s', volume='%s', nlvl_from=%d, nlvl_to=%d\n",
4256 st->index, dref->path, dref->dir, dref->filename,
4257 dref->volume, dref->nlvl_from, dref->nlvl_to);
4259 av_log(c->fc, AV_LOG_WARNING,
4260 "Skipped opening external track: "
4261 "stream %d, alias: path='%s', dir='%s', "
4262 "filename='%s', volume='%s', nlvl_from=%d, nlvl_to=%d."
4263 "Set enable_drefs to allow this.\n",
4264 st->index, dref->path, dref->dir, dref->filename,
4265 dref->volume, dref->nlvl_from, dref->nlvl_to);
4269 sc->pb_is_copied = 1;
4272 if (st->codecpar->codec_type == AVMEDIA_TYPE_VIDEO) {
4273 if (!st->sample_aspect_ratio.num && st->codecpar->width && st->codecpar->height &&
4274 sc->height && sc->width &&
4275 (st->codecpar->width != sc->width || st->codecpar->height != sc->height)) {
4276 st->sample_aspect_ratio = av_d2q(((double)st->codecpar->height * sc->width) /
4277 ((double)st->codecpar->width * sc->height), INT_MAX);
4280 #if FF_API_R_FRAME_RATE
4281 if (sc->stts_count == 1 || (sc->stts_count == 2 && sc->stts_data[1].count == 1))
4282 av_reduce(&st->r_frame_rate.num, &st->r_frame_rate.den,
4283 sc->time_scale, sc->stts_data[0].duration, INT_MAX);
4287 // done for ai5q, ai52, ai55, ai1q, ai12 and ai15.
4288 if (!st->codecpar->extradata_size && st->codecpar->codec_id == AV_CODEC_ID_H264 &&
4289 TAG_IS_AVCI(st->codecpar->codec_tag)) {
4290 ret = ff_generate_avci_extradata(st);
4295 switch (st->codecpar->codec_id) {
4296 #if CONFIG_H261_DECODER
4297 case AV_CODEC_ID_H261:
4299 #if CONFIG_H263_DECODER
4300 case AV_CODEC_ID_H263:
4302 #if CONFIG_MPEG4_DECODER
4303 case AV_CODEC_ID_MPEG4:
4305 st->codecpar->width = 0; /* let decoder init width/height */
4306 st->codecpar->height= 0;
4310 // If the duration of the mp3 packets is not constant, then they could need a parser
4311 if (st->codecpar->codec_id == AV_CODEC_ID_MP3
4312 && sc->stts_count > 3
4313 && sc->stts_count*10 > st->nb_frames
4314 && sc->time_scale == st->codecpar->sample_rate) {
4315 st->need_parsing = AVSTREAM_PARSE_FULL;
4317 /* Do not need those anymore. */
4318 av_freep(&sc->chunk_offsets);
4319 av_freep(&sc->sample_sizes);
4320 av_freep(&sc->keyframes);
4321 av_freep(&sc->stts_data);
4322 av_freep(&sc->stps_data);
4323 av_freep(&sc->elst_data);
4324 av_freep(&sc->rap_group);
4329 static int mov_read_ilst(MOVContext *c, AVIOContext *pb, MOVAtom atom)
4332 c->itunes_metadata = 1;
4333 ret = mov_read_default(c, pb, atom);
4334 c->itunes_metadata = 0;
4338 static int mov_read_keys(MOVContext *c, AVIOContext *pb, MOVAtom atom)
4347 count = avio_rb32(pb);
4348 if (count > UINT_MAX / sizeof(*c->meta_keys) - 1) {
4349 av_log(c->fc, AV_LOG_ERROR,
4350 "The 'keys' atom with the invalid key count: %"PRIu32"\n", count);
4351 return AVERROR_INVALIDDATA;
4354 c->meta_keys_count = count + 1;
4355 c->meta_keys = av_mallocz(c->meta_keys_count * sizeof(*c->meta_keys));
4357 return AVERROR(ENOMEM);
4359 for (i = 1; i <= count; ++i) {
4360 uint32_t key_size = avio_rb32(pb);
4361 uint32_t type = avio_rl32(pb);
4363 av_log(c->fc, AV_LOG_ERROR,
4364 "The key# %"PRIu32" in meta has invalid size:"
4365 "%"PRIu32"\n", i, key_size);
4366 return AVERROR_INVALIDDATA;
4369 if (type != MKTAG('m','d','t','a')) {
4370 avio_skip(pb, key_size);
4372 c->meta_keys[i] = av_mallocz(key_size + 1);
4373 if (!c->meta_keys[i])
4374 return AVERROR(ENOMEM);
4375 avio_read(pb, c->meta_keys[i], key_size);
4381 static int mov_read_custom(MOVContext *c, AVIOContext *pb, MOVAtom atom)
4383 int64_t end = avio_tell(pb) + atom.size;
4384 uint8_t *key = NULL, *val = NULL, *mean = NULL;
4388 MOVStreamContext *sc;
4390 if (c->fc->nb_streams < 1)
4392 st = c->fc->streams[c->fc->nb_streams-1];
4395 for (i = 0; i < 3; i++) {
4399 if (end - avio_tell(pb) <= 12)
4402 len = avio_rb32(pb);
4403 tag = avio_rl32(pb);
4404 avio_skip(pb, 4); // flags
4406 if (len < 12 || len - 12 > end - avio_tell(pb))
4410 if (tag == MKTAG('m', 'e', 'a', 'n'))
4412 else if (tag == MKTAG('n', 'a', 'm', 'e'))
4414 else if (tag == MKTAG('d', 'a', 't', 'a') && len > 4) {
4424 *p = av_malloc(len + 1);
4426 ret = AVERROR(ENOMEM);
4429 ret = ffio_read_size(pb, *p, len);
4437 if (mean && key && val) {
4438 if (strcmp(key, "iTunSMPB") == 0) {
4439 int priming, remainder, samples;
4440 if(sscanf(val, "%*X %X %X %X", &priming, &remainder, &samples) == 3){
4441 if(priming>0 && priming<16384)
4442 sc->start_pad = priming;
4445 if (strcmp(key, "cdec") != 0) {
4446 av_dict_set(&c->fc->metadata, key, val,
4447 AV_DICT_DONT_STRDUP_KEY | AV_DICT_DONT_STRDUP_VAL);
4451 av_log(c->fc, AV_LOG_VERBOSE,
4452 "Unhandled or malformed custom metadata of size %"PRId64"\n", atom.size);
4455 avio_seek(pb, end, SEEK_SET);
4462 static int mov_read_meta(MOVContext *c, AVIOContext *pb, MOVAtom atom)
4464 while (atom.size > 8) {
4468 tag = avio_rl32(pb);
4470 if (tag == MKTAG('h','d','l','r')) {
4471 avio_seek(pb, -8, SEEK_CUR);
4473 return mov_read_default(c, pb, atom);
4479 // return 1 when matrix is identity, 0 otherwise
4480 #define IS_MATRIX_IDENT(matrix) \
4481 ( (matrix)[0][0] == (1 << 16) && \
4482 (matrix)[1][1] == (1 << 16) && \
4483 (matrix)[2][2] == (1 << 30) && \
4484 !(matrix)[0][1] && !(matrix)[0][2] && \
4485 !(matrix)[1][0] && !(matrix)[1][2] && \
4486 !(matrix)[2][0] && !(matrix)[2][1])
4488 static int mov_read_tkhd(MOVContext *c, AVIOContext *pb, MOVAtom atom)
4493 int display_matrix[3][3];
4494 int res_display_matrix[3][3] = { { 0 } };
4496 MOVStreamContext *sc;
4500 if (c->fc->nb_streams < 1)
4502 st = c->fc->streams[c->fc->nb_streams-1];
4505 // Each stream (trak) should have exactly 1 tkhd. This catches bad files and
4506 // avoids corrupting AVStreams mapped to an earlier tkhd.
4508 return AVERROR_INVALIDDATA;
4510 version = avio_r8(pb);
4511 flags = avio_rb24(pb);
4512 st->disposition |= (flags & MOV_TKHD_FLAG_ENABLED) ? AV_DISPOSITION_DEFAULT : 0;
4518 avio_rb32(pb); /* creation time */
4519 avio_rb32(pb); /* modification time */
4521 st->id = (int)avio_rb32(pb); /* track id (NOT 0 !)*/
4522 avio_rb32(pb); /* reserved */
4524 /* highlevel (considering edits) duration in movie timebase */
4525 (version == 1) ? avio_rb64(pb) : avio_rb32(pb);
4526 avio_rb32(pb); /* reserved */
4527 avio_rb32(pb); /* reserved */
4529 avio_rb16(pb); /* layer */
4530 avio_rb16(pb); /* alternate group */
4531 avio_rb16(pb); /* volume */
4532 avio_rb16(pb); /* reserved */
4534 //read in the display matrix (outlined in ISO 14496-12, Section 6.2.2)
4535 // they're kept in fixed point format through all calculations
4536 // save u,v,z to store the whole matrix in the AV_PKT_DATA_DISPLAYMATRIX
4537 // side data, but the scale factor is not needed to calculate aspect ratio
4538 for (i = 0; i < 3; i++) {
4539 display_matrix[i][0] = avio_rb32(pb); // 16.16 fixed point
4540 display_matrix[i][1] = avio_rb32(pb); // 16.16 fixed point
4541 display_matrix[i][2] = avio_rb32(pb); // 2.30 fixed point
4544 width = avio_rb32(pb); // 16.16 fixed point track width
4545 height = avio_rb32(pb); // 16.16 fixed point track height
4546 sc->width = width >> 16;
4547 sc->height = height >> 16;
4549 // apply the moov display matrix (after the tkhd one)
4550 for (i = 0; i < 3; i++) {
4551 const int sh[3] = { 16, 16, 30 };
4552 for (j = 0; j < 3; j++) {
4553 for (e = 0; e < 3; e++) {
4554 res_display_matrix[i][j] +=
4555 ((int64_t) display_matrix[i][e] *
4556 c->movie_display_matrix[e][j]) >> sh[e];
4561 // save the matrix when it is not the default identity
4562 if (!IS_MATRIX_IDENT(res_display_matrix)) {
4565 av_freep(&sc->display_matrix);
4566 sc->display_matrix = av_malloc(sizeof(int32_t) * 9);
4567 if (!sc->display_matrix)
4568 return AVERROR(ENOMEM);
4570 for (i = 0; i < 3; i++)
4571 for (j = 0; j < 3; j++)
4572 sc->display_matrix[i * 3 + j] = res_display_matrix[i][j];
4574 #if FF_API_OLD_ROTATE_API
4575 rotate = av_display_rotation_get(sc->display_matrix);
4576 if (!isnan(rotate)) {
4577 char rotate_buf[64];
4579 if (rotate < 0) // for backward compatibility
4581 snprintf(rotate_buf, sizeof(rotate_buf), "%g", rotate);
4582 av_dict_set(&st->metadata, "rotate", rotate_buf, 0);
4587 // transform the display width/height according to the matrix
4588 // to keep the same scale, use [width height 1<<16]
4589 if (width && height && sc->display_matrix) {
4590 double disp_transform[2];
4592 for (i = 0; i < 2; i++)
4593 disp_transform[i] = hypot(sc->display_matrix[0 + i],
4594 sc->display_matrix[3 + i]);
4596 if (disp_transform[0] > 0 && disp_transform[1] > 0 &&
4597 disp_transform[0] < (1<<24) && disp_transform[1] < (1<<24) &&
4598 fabs((disp_transform[0] / disp_transform[1]) - 1.0) > 0.01)
4599 st->sample_aspect_ratio = av_d2q(
4600 disp_transform[0] / disp_transform[1],
4606 static int mov_read_tfhd(MOVContext *c, AVIOContext *pb, MOVAtom atom)
4608 MOVFragment *frag = &c->fragment;
4609 MOVTrackExt *trex = NULL;
4610 int flags, track_id, i;
4611 MOVFragmentStreamInfo * frag_stream_info;
4613 avio_r8(pb); /* version */
4614 flags = avio_rb24(pb);
4616 track_id = avio_rb32(pb);
4618 return AVERROR_INVALIDDATA;
4619 for (i = 0; i < c->trex_count; i++)
4620 if (c->trex_data[i].track_id == track_id) {
4621 trex = &c->trex_data[i];
4625 av_log(c->fc, AV_LOG_WARNING, "could not find corresponding trex (id %u)\n", track_id);
4628 c->fragment.found_tfhd = 1;
4629 frag->track_id = track_id;
4630 set_frag_stream(&c->frag_index, track_id);
4632 frag->base_data_offset = flags & MOV_TFHD_BASE_DATA_OFFSET ?
4633 avio_rb64(pb) : flags & MOV_TFHD_DEFAULT_BASE_IS_MOOF ?
4634 frag->moof_offset : frag->implicit_offset;
4635 frag->stsd_id = flags & MOV_TFHD_STSD_ID ? avio_rb32(pb) : trex->stsd_id;
4637 frag->duration = flags & MOV_TFHD_DEFAULT_DURATION ?
4638 avio_rb32(pb) : trex->duration;
4639 frag->size = flags & MOV_TFHD_DEFAULT_SIZE ?
4640 avio_rb32(pb) : trex->size;
4641 frag->flags = flags & MOV_TFHD_DEFAULT_FLAGS ?
4642 avio_rb32(pb) : trex->flags;
4643 av_log(c->fc, AV_LOG_TRACE, "frag flags 0x%x\n", frag->flags);
4645 frag_stream_info = get_current_frag_stream_info(&c->frag_index);
4646 if (frag_stream_info)
4647 frag_stream_info->next_trun_dts = AV_NOPTS_VALUE;
4652 static int mov_read_chap(MOVContext *c, AVIOContext *pb, MOVAtom atom)
4657 num = atom.size / 4;
4658 if (!(new_tracks = av_malloc_array(num, sizeof(int))))
4659 return AVERROR(ENOMEM);
4661 av_free(c->chapter_tracks);
4662 c->chapter_tracks = new_tracks;
4663 c->nb_chapter_tracks = num;
4665 for (i = 0; i < num && !pb->eof_reached; i++)
4666 c->chapter_tracks[i] = avio_rb32(pb);
4671 static int mov_read_trex(MOVContext *c, AVIOContext *pb, MOVAtom atom)
4676 if ((uint64_t)c->trex_count+1 >= UINT_MAX / sizeof(*c->trex_data))
4677 return AVERROR_INVALIDDATA;
4678 if ((err = av_reallocp_array(&c->trex_data, c->trex_count + 1,
4679 sizeof(*c->trex_data))) < 0) {
4684 c->fc->duration = AV_NOPTS_VALUE; // the duration from mvhd is not representing the whole file when fragments are used.
4686 trex = &c->trex_data[c->trex_count++];
4687 avio_r8(pb); /* version */
4688 avio_rb24(pb); /* flags */
4689 trex->track_id = avio_rb32(pb);
4690 trex->stsd_id = avio_rb32(pb);
4691 trex->duration = avio_rb32(pb);
4692 trex->size = avio_rb32(pb);
4693 trex->flags = avio_rb32(pb);
4697 static int mov_read_tfdt(MOVContext *c, AVIOContext *pb, MOVAtom atom)
4699 MOVFragment *frag = &c->fragment;
4700 AVStream *st = NULL;
4701 MOVStreamContext *sc;
4703 MOVFragmentStreamInfo * frag_stream_info;
4704 int64_t base_media_decode_time;
4706 for (i = 0; i < c->fc->nb_streams; i++) {
4707 if (c->fc->streams[i]->id == frag->track_id) {
4708 st = c->fc->streams[i];
4713 av_log(c->fc, AV_LOG_WARNING, "could not find corresponding track id %u\n", frag->track_id);
4717 if (sc->pseudo_stream_id + 1 != frag->stsd_id && sc->pseudo_stream_id != -1)
4719 version = avio_r8(pb);
4720 avio_rb24(pb); /* flags */
4722 base_media_decode_time = avio_rb64(pb);
4724 base_media_decode_time = avio_rb32(pb);
4727 frag_stream_info = get_current_frag_stream_info(&c->frag_index);
4728 if (frag_stream_info)
4729 frag_stream_info->tfdt_dts = base_media_decode_time;
4730 sc->track_end = base_media_decode_time;
4735 static int mov_read_trun(MOVContext *c, AVIOContext *pb, MOVAtom atom)
4737 MOVFragment *frag = &c->fragment;
4738 AVStream *st = NULL;
4739 MOVStreamContext *sc;
4742 int64_t dts, pts = AV_NOPTS_VALUE;
4743 int data_offset = 0;
4744 unsigned entries, first_sample_flags = frag->flags;
4745 int flags, distance, i;
4746 int64_t prev_dts = AV_NOPTS_VALUE;
4747 int next_frag_index = -1, index_entry_pos;
4748 size_t requested_size;
4749 size_t old_ctts_allocated_size;
4750 AVIndexEntry *new_entries;
4751 MOVFragmentStreamInfo * frag_stream_info;
4753 if (!frag->found_tfhd) {
4754 av_log(c->fc, AV_LOG_ERROR, "trun track id unknown, no tfhd was found\n");
4755 return AVERROR_INVALIDDATA;
4758 for (i = 0; i < c->fc->nb_streams; i++) {
4759 if (c->fc->streams[i]->id == frag->track_id) {
4760 st = c->fc->streams[i];
4765 av_log(c->fc, AV_LOG_WARNING, "could not find corresponding track id %u\n", frag->track_id);
4769 if (sc->pseudo_stream_id+1 != frag->stsd_id && sc->pseudo_stream_id != -1)
4772 // Find the next frag_index index that has a valid index_entry for
4773 // the current track_id.
4775 // A valid index_entry means the trun for the fragment was read
4776 // and it's samples are in index_entries at the given position.
4777 // New index entries will be inserted before the index_entry found.
4778 index_entry_pos = st->nb_index_entries;
4779 for (i = c->frag_index.current + 1; i < c->frag_index.nb_items; i++) {
4780 frag_stream_info = get_frag_stream_info(&c->frag_index, i, frag->track_id);
4781 if (frag_stream_info && frag_stream_info->index_entry >= 0) {
4782 next_frag_index = i;
4783 index_entry_pos = frag_stream_info->index_entry;
4787 av_assert0(index_entry_pos <= st->nb_index_entries);
4789 avio_r8(pb); /* version */
4790 flags = avio_rb24(pb);
4791 entries = avio_rb32(pb);
4792 av_log(c->fc, AV_LOG_TRACE, "flags 0x%x entries %u\n", flags, entries);
4794 if ((uint64_t)entries+sc->ctts_count >= UINT_MAX/sizeof(*sc->ctts_data))
4795 return AVERROR_INVALIDDATA;
4796 if (flags & MOV_TRUN_DATA_OFFSET) data_offset = avio_rb32(pb);
4797 if (flags & MOV_TRUN_FIRST_SAMPLE_FLAGS) first_sample_flags = avio_rb32(pb);
4799 frag_stream_info = get_current_frag_stream_info(&c->frag_index);
4800 if (frag_stream_info) {
4801 if (frag_stream_info->next_trun_dts != AV_NOPTS_VALUE) {
4802 dts = frag_stream_info->next_trun_dts - sc->time_offset;
4803 } else if (frag_stream_info->first_tfra_pts != AV_NOPTS_VALUE &&
4804 c->use_mfra_for == FF_MOV_FLAG_MFRA_PTS) {
4805 pts = frag_stream_info->first_tfra_pts;
4806 av_log(c->fc, AV_LOG_DEBUG, "found mfra time %"PRId64
4807 ", using it for pts\n", pts);
4808 } else if (frag_stream_info->first_tfra_pts != AV_NOPTS_VALUE &&
4809 c->use_mfra_for == FF_MOV_FLAG_MFRA_DTS) {
4810 dts = frag_stream_info->first_tfra_pts;
4811 av_log(c->fc, AV_LOG_DEBUG, "found mfra time %"PRId64
4812 ", using it for dts\n", pts);
4813 } else if (frag_stream_info->sidx_pts != AV_NOPTS_VALUE) {
4814 // FIXME: sidx earliest_presentation_time is *PTS*, s.b.
4815 // pts = frag_stream_info->sidx_pts;
4816 dts = frag_stream_info->sidx_pts - sc->time_offset;
4817 av_log(c->fc, AV_LOG_DEBUG, "found sidx time %"PRId64
4818 ", using it for pts\n", pts);
4819 } else if (frag_stream_info->tfdt_dts != AV_NOPTS_VALUE) {
4820 dts = frag_stream_info->tfdt_dts - sc->time_offset;
4821 av_log(c->fc, AV_LOG_DEBUG, "found tfdt time %"PRId64
4822 ", using it for dts\n", dts);
4824 dts = sc->track_end - sc->time_offset;
4825 av_log(c->fc, AV_LOG_DEBUG, "found track end time %"PRId64
4826 ", using it for dts\n", dts);
4829 dts = sc->track_end - sc->time_offset;
4830 av_log(c->fc, AV_LOG_DEBUG, "found track end time %"PRId64
4831 ", using it for dts\n", dts);
4833 offset = frag->base_data_offset + data_offset;
4835 av_log(c->fc, AV_LOG_TRACE, "first sample flags 0x%x\n", first_sample_flags);
4837 // realloc space for new index entries
4838 if((uint64_t)st->nb_index_entries + entries >= UINT_MAX / sizeof(AVIndexEntry)) {
4839 entries = UINT_MAX / sizeof(AVIndexEntry) - st->nb_index_entries;
4840 av_log(c->fc, AV_LOG_ERROR, "Failed to add index entry\n");
4845 requested_size = (st->nb_index_entries + entries) * sizeof(AVIndexEntry);
4846 new_entries = av_fast_realloc(st->index_entries,
4847 &st->index_entries_allocated_size,
4850 return AVERROR(ENOMEM);
4851 st->index_entries= new_entries;
4853 requested_size = (st->nb_index_entries + entries) * sizeof(*sc->ctts_data);
4854 old_ctts_allocated_size = sc->ctts_allocated_size;
4855 ctts_data = av_fast_realloc(sc->ctts_data, &sc->ctts_allocated_size,
4858 return AVERROR(ENOMEM);
4859 sc->ctts_data = ctts_data;
4861 // In case there were samples without ctts entries, ensure they get
4862 // zero valued entries. This ensures clips which mix boxes with and
4863 // without ctts entries don't pickup uninitialized data.
4864 memset((uint8_t*)(sc->ctts_data) + old_ctts_allocated_size, 0,
4865 sc->ctts_allocated_size - old_ctts_allocated_size);
4867 if (index_entry_pos < st->nb_index_entries) {
4868 // Make hole in index_entries and ctts_data for new samples
4869 memmove(st->index_entries + index_entry_pos + entries,
4870 st->index_entries + index_entry_pos,
4871 sizeof(*st->index_entries) *
4872 (st->nb_index_entries - index_entry_pos));
4873 memmove(sc->ctts_data + index_entry_pos + entries,
4874 sc->ctts_data + index_entry_pos,
4875 sizeof(*sc->ctts_data) * (sc->ctts_count - index_entry_pos));
4876 if (index_entry_pos < sc->current_sample) {
4877 sc->current_sample += entries;
4881 st->nb_index_entries += entries;
4882 sc->ctts_count = st->nb_index_entries;
4884 // Record the index_entry position in frag_index of this fragment
4885 if (frag_stream_info)
4886 frag_stream_info->index_entry = index_entry_pos;
4888 if (index_entry_pos > 0)
4889 prev_dts = st->index_entries[index_entry_pos-1].timestamp;
4891 for (i = 0; i < entries && !pb->eof_reached; i++) {
4892 unsigned sample_size = frag->size;
4893 int sample_flags = i ? frag->flags : first_sample_flags;
4894 unsigned sample_duration = frag->duration;
4895 unsigned ctts_duration = 0;
4897 int index_entry_flags = 0;
4899 if (flags & MOV_TRUN_SAMPLE_DURATION) sample_duration = avio_rb32(pb);
4900 if (flags & MOV_TRUN_SAMPLE_SIZE) sample_size = avio_rb32(pb);
4901 if (flags & MOV_TRUN_SAMPLE_FLAGS) sample_flags = avio_rb32(pb);
4902 if (flags & MOV_TRUN_SAMPLE_CTS) ctts_duration = avio_rb32(pb);
4904 mov_update_dts_shift(sc, ctts_duration, c->fc);
4905 if (pts != AV_NOPTS_VALUE) {
4906 dts = pts - sc->dts_shift;
4907 if (flags & MOV_TRUN_SAMPLE_CTS) {
4908 dts -= ctts_duration;
4910 dts -= sc->time_offset;
4912 av_log(c->fc, AV_LOG_DEBUG,
4913 "pts %"PRId64" calculated dts %"PRId64
4914 " sc->dts_shift %d ctts.duration %d"
4915 " sc->time_offset %"PRId64
4916 " flags & MOV_TRUN_SAMPLE_CTS %d\n",
4918 sc->dts_shift, ctts_duration,
4919 sc->time_offset, flags & MOV_TRUN_SAMPLE_CTS);
4920 pts = AV_NOPTS_VALUE;
4923 if (st->codecpar->codec_type == AVMEDIA_TYPE_AUDIO)
4927 !(sample_flags & (MOV_FRAG_SAMPLE_FLAG_IS_NON_SYNC |
4928 MOV_FRAG_SAMPLE_FLAG_DEPENDS_YES));
4931 index_entry_flags |= AVINDEX_KEYFRAME;
4933 // Fragments can overlap in time. Discard overlapping frames after
4935 if (prev_dts >= dts)
4936 index_entry_flags |= AVINDEX_DISCARD_FRAME;
4938 st->index_entries[index_entry_pos].pos = offset;
4939 st->index_entries[index_entry_pos].timestamp = dts;
4940 st->index_entries[index_entry_pos].size= sample_size;
4941 st->index_entries[index_entry_pos].min_distance= distance;
4942 st->index_entries[index_entry_pos].flags = index_entry_flags;
4944 sc->ctts_data[index_entry_pos].count = 1;
4945 sc->ctts_data[index_entry_pos].duration = ctts_duration;
4948 av_log(c->fc, AV_LOG_TRACE, "AVIndex stream %d, sample %d, offset %"PRIx64", dts %"PRId64", "
4949 "size %u, distance %d, keyframe %d\n", st->index,
4950 index_entry_pos, offset, dts, sample_size, distance, keyframe);
4952 dts += sample_duration;
4953 offset += sample_size;
4954 sc->data_size += sample_size;
4956 if (sample_duration <= INT64_MAX - sc->duration_for_fps &&
4957 1 <= INT_MAX - sc->nb_frames_for_fps
4959 sc->duration_for_fps += sample_duration;
4960 sc->nb_frames_for_fps ++;
4963 if (frag_stream_info)
4964 frag_stream_info->next_trun_dts = dts + sc->time_offset;
4966 // EOF found before reading all entries. Fix the hole this would
4967 // leave in index_entries and ctts_data
4968 int gap = entries - i;
4969 memmove(st->index_entries + index_entry_pos,
4970 st->index_entries + index_entry_pos + gap,
4971 sizeof(*st->index_entries) *
4972 (st->nb_index_entries - (index_entry_pos + gap)));
4973 memmove(sc->ctts_data + index_entry_pos,
4974 sc->ctts_data + index_entry_pos + gap,
4975 sizeof(*sc->ctts_data) *
4976 (sc->ctts_count - (index_entry_pos + gap)));
4978 st->nb_index_entries -= gap;
4979 sc->ctts_count -= gap;
4980 if (index_entry_pos < sc->current_sample) {
4981 sc->current_sample -= gap;
4986 // The end of this new fragment may overlap in time with the start
4987 // of the next fragment in index_entries. Mark the samples in the next
4988 // fragment that overlap with AVINDEX_DISCARD_FRAME
4989 prev_dts = AV_NOPTS_VALUE;
4990 if (index_entry_pos > 0)
4991 prev_dts = st->index_entries[index_entry_pos-1].timestamp;
4992 for (i = index_entry_pos; i < st->nb_index_entries; i++) {
4993 if (prev_dts < st->index_entries[i].timestamp)
4995 st->index_entries[i].flags |= AVINDEX_DISCARD_FRAME;
4998 // If a hole was created to insert the new index_entries into,
4999 // the index_entry recorded for all subsequent moof must
5000 // be incremented by the number of entries inserted.
5001 fix_frag_index_entries(&c->frag_index, next_frag_index,
5002 frag->track_id, entries);
5004 if (pb->eof_reached) {
5005 av_log(c->fc, AV_LOG_WARNING, "reached eof, corrupted TRUN atom\n");
5009 frag->implicit_offset = offset;
5011 sc->track_end = dts + sc->time_offset;
5012 if (st->duration < sc->track_end)
5013 st->duration = sc->track_end;
5018 static int mov_read_sidx(MOVContext *c, AVIOContext *pb, MOVAtom atom)
5020 int64_t stream_size = avio_size(pb);
5021 int64_t offset = avio_tell(pb) + atom.size, pts, timestamp;
5022 uint8_t version, is_complete;
5023 unsigned i, j, track_id, item_count;
5024 AVStream *st = NULL;
5025 AVStream *ref_st = NULL;
5026 MOVStreamContext *sc, *ref_sc = NULL;
5027 AVRational timescale;
5029 version = avio_r8(pb);
5031 avpriv_request_sample(c->fc, "sidx version %u", version);
5035 avio_rb24(pb); // flags
5037 track_id = avio_rb32(pb); // Reference ID
5038 for (i = 0; i < c->fc->nb_streams; i++) {
5039 if (c->fc->streams[i]->id == track_id) {
5040 st = c->fc->streams[i];
5045 av_log(c->fc, AV_LOG_WARNING, "could not find corresponding track id %d\n", track_id);
5051 timescale = av_make_q(1, avio_rb32(pb));
5053 if (timescale.den <= 0) {
5054 av_log(c->fc, AV_LOG_ERROR, "Invalid sidx timescale 1/%d\n", timescale.den);
5055 return AVERROR_INVALIDDATA;
5059 pts = avio_rb32(pb);
5060 offset += avio_rb32(pb);
5062 pts = avio_rb64(pb);
5063 offset += avio_rb64(pb);
5066 avio_rb16(pb); // reserved
5068 item_count = avio_rb16(pb);
5070 for (i = 0; i < item_count; i++) {
5072 MOVFragmentStreamInfo * frag_stream_info;
5073 uint32_t size = avio_rb32(pb);
5074 uint32_t duration = avio_rb32(pb);
5075 if (size & 0x80000000) {
5076 avpriv_request_sample(c->fc, "sidx reference_type 1");
5077 return AVERROR_PATCHWELCOME;
5079 avio_rb32(pb); // sap_flags
5080 timestamp = av_rescale_q(pts, timescale, st->time_base);
5082 index = update_frag_index(c, offset);
5083 frag_stream_info = get_frag_stream_info(&c->frag_index, index, track_id);
5084 if (frag_stream_info)
5085 frag_stream_info->sidx_pts = timestamp;
5091 st->duration = sc->track_end = pts;
5095 // See if the remaining bytes are just an mfra which we can ignore.
5096 is_complete = offset == stream_size;
5099 int64_t original_pos = avio_tell(pb);
5101 if ((ret = avio_seek(pb, stream_size - 4, SEEK_SET)) < 0)
5103 mfra_size = avio_rb32(pb);
5104 if (offset + mfra_size == stream_size)
5106 if ((ret = avio_seek(pb, original_pos, SEEK_SET)) < 0)
5111 // Find first entry in fragment index that came from an sidx.
5112 // This will pretty much always be the first entry.
5113 for (i = 0; i < c->frag_index.nb_items; i++) {
5114 MOVFragmentIndexItem * item = &c->frag_index.item[i];
5115 for (j = 0; ref_st == NULL && j < item->nb_stream_info; j++) {
5116 MOVFragmentStreamInfo * si;
5117 si = &item->stream_info[j];
5118 if (si->sidx_pts != AV_NOPTS_VALUE) {
5119 ref_st = c->fc->streams[j];
5120 ref_sc = ref_st->priv_data;
5125 if (ref_st) for (i = 0; i < c->fc->nb_streams; i++) {
5126 st = c->fc->streams[i];
5128 if (!sc->has_sidx) {
5129 st->duration = sc->track_end = av_rescale(ref_st->duration, sc->time_scale, ref_sc->time_scale);
5133 c->frag_index.complete = 1;
5139 /* this atom should be null (from specs), but some buggy files put the 'moov' atom inside it... */
5140 /* like the files created with Adobe Premiere 5.0, for samples see */
5141 /* http://graphics.tudelft.nl/~wouter/publications/soundtests/ */
5142 static int mov_read_wide(MOVContext *c, AVIOContext *pb, MOVAtom atom)
5147 return 0; /* continue */
5148 if (avio_rb32(pb) != 0) { /* 0 sized mdat atom... use the 'wide' atom size */
5149 avio_skip(pb, atom.size - 4);
5152 atom.type = avio_rl32(pb);
5154 if (atom.type != MKTAG('m','d','a','t')) {
5155 avio_skip(pb, atom.size);
5158 err = mov_read_mdat(c, pb, atom);
5162 static int mov_read_cmov(MOVContext *c, AVIOContext *pb, MOVAtom atom)
5167 uint8_t *moov_data; /* uncompressed data */
5168 long cmov_len, moov_len;
5171 avio_rb32(pb); /* dcom atom */
5172 if (avio_rl32(pb) != MKTAG('d','c','o','m'))
5173 return AVERROR_INVALIDDATA;
5174 if (avio_rl32(pb) != MKTAG('z','l','i','b')) {
5175 av_log(c->fc, AV_LOG_ERROR, "unknown compression for cmov atom !\n");
5176 return AVERROR_INVALIDDATA;
5178 avio_rb32(pb); /* cmvd atom */
5179 if (avio_rl32(pb) != MKTAG('c','m','v','d'))
5180 return AVERROR_INVALIDDATA;
5181 moov_len = avio_rb32(pb); /* uncompressed size */
5182 cmov_len = atom.size - 6 * 4;
5184 cmov_data = av_malloc(cmov_len);
5186 return AVERROR(ENOMEM);
5187 moov_data = av_malloc(moov_len);
5190 return AVERROR(ENOMEM);
5192 ret = ffio_read_size(pb, cmov_data, cmov_len);
5194 goto free_and_return;
5196 ret = AVERROR_INVALIDDATA;
5197 if (uncompress (moov_data, (uLongf *) &moov_len, (const Bytef *)cmov_data, cmov_len) != Z_OK)
5198 goto free_and_return;
5199 if (ffio_init_context(&ctx, moov_data, moov_len, 0, NULL, NULL, NULL, NULL) != 0)
5200 goto free_and_return;
5201 ctx.seekable = AVIO_SEEKABLE_NORMAL;
5202 atom.type = MKTAG('m','o','o','v');
5203 atom.size = moov_len;
5204 ret = mov_read_default(c, &ctx, atom);
5210 av_log(c->fc, AV_LOG_ERROR, "this file requires zlib support compiled in\n");
5211 return AVERROR(ENOSYS);
5215 /* edit list atom */
5216 static int mov_read_elst(MOVContext *c, AVIOContext *pb, MOVAtom atom)
5218 MOVStreamContext *sc;
5219 int i, edit_count, version;
5220 int64_t elst_entry_size;
5222 if (c->fc->nb_streams < 1 || c->ignore_editlist)
5224 sc = c->fc->streams[c->fc->nb_streams-1]->priv_data;
5226 version = avio_r8(pb); /* version */
5227 avio_rb24(pb); /* flags */
5228 edit_count = avio_rb32(pb); /* entries */
5231 elst_entry_size = version == 1 ? 20 : 12;
5232 if (atom.size != edit_count * elst_entry_size) {
5233 if (c->fc->strict_std_compliance >= FF_COMPLIANCE_STRICT) {
5234 av_log(c->fc, AV_LOG_ERROR, "Invalid edit list entry_count: %d for elst atom of size: %"PRId64" bytes.\n",
5235 edit_count, atom.size + 8);
5236 return AVERROR_INVALIDDATA;
5238 edit_count = atom.size / elst_entry_size;
5239 if (edit_count * elst_entry_size != atom.size) {
5240 av_log(c->fc, AV_LOG_WARNING, "ELST atom of %"PRId64" bytes, bigger than %d entries.\n", atom.size, edit_count);
5248 av_log(c->fc, AV_LOG_WARNING, "Duplicated ELST atom\n");
5249 av_free(sc->elst_data);
5251 sc->elst_data = av_malloc_array(edit_count, sizeof(*sc->elst_data));
5253 return AVERROR(ENOMEM);
5255 av_log(c->fc, AV_LOG_TRACE, "track[%u].edit_count = %i\n", c->fc->nb_streams - 1, edit_count);
5256 for (i = 0; i < edit_count && atom.size > 0 && !pb->eof_reached; i++) {
5257 MOVElst *e = &sc->elst_data[i];
5260 e->duration = avio_rb64(pb);
5261 e->time = avio_rb64(pb);
5264 e->duration = avio_rb32(pb); /* segment duration */
5265 e->time = (int32_t)avio_rb32(pb); /* media time */
5268 e->rate = avio_rb32(pb) / 65536.0;
5270 av_log(c->fc, AV_LOG_TRACE, "duration=%"PRId64" time=%"PRId64" rate=%f\n",
5271 e->duration, e->time, e->rate);
5273 if (e->time < 0 && e->time != -1 &&
5274 c->fc->strict_std_compliance >= FF_COMPLIANCE_STRICT) {
5275 av_log(c->fc, AV_LOG_ERROR, "Track %d, edit %d: Invalid edit list media time=%"PRId64"\n",
5276 c->fc->nb_streams-1, i, e->time);
5277 return AVERROR_INVALIDDATA;
5285 static int mov_read_tmcd(MOVContext *c, AVIOContext *pb, MOVAtom atom)
5287 MOVStreamContext *sc;
5289 if (c->fc->nb_streams < 1)
5290 return AVERROR_INVALIDDATA;
5291 sc = c->fc->streams[c->fc->nb_streams - 1]->priv_data;
5292 sc->timecode_track = avio_rb32(pb);
5296 static int mov_read_av1c(MOVContext *c, AVIOContext *pb, MOVAtom atom)
5301 if (c->fc->nb_streams < 1)
5303 st = c->fc->streams[c->fc->nb_streams - 1];
5305 if (atom.size < 4) {
5306 av_log(c->fc, AV_LOG_ERROR, "Empty AV1 Codec Configuration Box\n");
5307 return AVERROR_INVALIDDATA;
5310 /* For now, propagate only the OBUs, if any. Once libavcodec is
5311 updated to handle isobmff style extradata this can be removed. */
5317 ret = ff_get_extradata(c->fc, st->codecpar, pb, atom.size - 4);
5324 static int mov_read_vpcc(MOVContext *c, AVIOContext *pb, MOVAtom atom)
5327 int version, color_range, color_primaries, color_trc, color_space;
5329 if (c->fc->nb_streams < 1)
5331 st = c->fc->streams[c->fc->nb_streams - 1];
5333 if (atom.size < 5) {
5334 av_log(c->fc, AV_LOG_ERROR, "Empty VP Codec Configuration box\n");
5335 return AVERROR_INVALIDDATA;
5338 version = avio_r8(pb);
5340 av_log(c->fc, AV_LOG_WARNING, "Unsupported VP Codec Configuration box version %d\n", version);
5343 avio_skip(pb, 3); /* flags */
5345 avio_skip(pb, 2); /* profile + level */
5346 color_range = avio_r8(pb); /* bitDepth, chromaSubsampling, videoFullRangeFlag */
5347 color_primaries = avio_r8(pb);
5348 color_trc = avio_r8(pb);
5349 color_space = avio_r8(pb);
5350 if (avio_rb16(pb)) /* codecIntializationDataSize */
5351 return AVERROR_INVALIDDATA;
5353 if (!av_color_primaries_name(color_primaries))
5354 color_primaries = AVCOL_PRI_UNSPECIFIED;
5355 if (!av_color_transfer_name(color_trc))
5356 color_trc = AVCOL_TRC_UNSPECIFIED;
5357 if (!av_color_space_name(color_space))
5358 color_space = AVCOL_SPC_UNSPECIFIED;
5360 st->codecpar->color_range = (color_range & 1) ? AVCOL_RANGE_JPEG : AVCOL_RANGE_MPEG;
5361 st->codecpar->color_primaries = color_primaries;
5362 st->codecpar->color_trc = color_trc;
5363 st->codecpar->color_space = color_space;
5368 static int mov_read_smdm(MOVContext *c, AVIOContext *pb, MOVAtom atom)
5370 MOVStreamContext *sc;
5373 if (c->fc->nb_streams < 1)
5374 return AVERROR_INVALIDDATA;
5376 sc = c->fc->streams[c->fc->nb_streams - 1]->priv_data;
5378 if (atom.size < 5) {
5379 av_log(c->fc, AV_LOG_ERROR, "Empty Mastering Display Metadata box\n");
5380 return AVERROR_INVALIDDATA;
5383 version = avio_r8(pb);
5385 av_log(c->fc, AV_LOG_WARNING, "Unsupported Mastering Display Metadata box version %d\n", version);
5388 avio_skip(pb, 3); /* flags */
5390 sc->mastering = av_mastering_display_metadata_alloc();
5392 return AVERROR(ENOMEM);
5394 for (i = 0; i < 3; i++) {
5395 sc->mastering->display_primaries[i][0] = av_make_q(avio_rb16(pb), 1 << 16);
5396 sc->mastering->display_primaries[i][1] = av_make_q(avio_rb16(pb), 1 << 16);
5398 sc->mastering->white_point[0] = av_make_q(avio_rb16(pb), 1 << 16);
5399 sc->mastering->white_point[1] = av_make_q(avio_rb16(pb), 1 << 16);
5401 sc->mastering->max_luminance = av_make_q(avio_rb32(pb), 1 << 8);
5402 sc->mastering->min_luminance = av_make_q(avio_rb32(pb), 1 << 14);
5404 sc->mastering->has_primaries = 1;
5405 sc->mastering->has_luminance = 1;
5410 static int mov_read_mdcv(MOVContext *c, AVIOContext *pb, MOVAtom atom)
5412 MOVStreamContext *sc;
5413 const int mapping[3] = {1, 2, 0};
5414 const int chroma_den = 50000;
5415 const int luma_den = 10000;
5418 if (c->fc->nb_streams < 1)
5419 return AVERROR_INVALIDDATA;
5421 sc = c->fc->streams[c->fc->nb_streams - 1]->priv_data;
5423 if (atom.size < 24) {
5424 av_log(c->fc, AV_LOG_ERROR, "Invalid Mastering Display Color Volume box\n");
5425 return AVERROR_INVALIDDATA;
5428 sc->mastering = av_mastering_display_metadata_alloc();
5430 return AVERROR(ENOMEM);
5432 for (i = 0; i < 3; i++) {
5433 const int j = mapping[i];
5434 sc->mastering->display_primaries[j][0] = av_make_q(avio_rb16(pb), chroma_den);
5435 sc->mastering->display_primaries[j][1] = av_make_q(avio_rb16(pb), chroma_den);
5437 sc->mastering->white_point[0] = av_make_q(avio_rb16(pb), chroma_den);
5438 sc->mastering->white_point[1] = av_make_q(avio_rb16(pb), chroma_den);
5440 sc->mastering->max_luminance = av_make_q(avio_rb32(pb), luma_den);
5441 sc->mastering->min_luminance = av_make_q(avio_rb32(pb), luma_den);
5443 sc->mastering->has_luminance = 1;
5444 sc->mastering->has_primaries = 1;
5449 static int mov_read_coll(MOVContext *c, AVIOContext *pb, MOVAtom atom)
5451 MOVStreamContext *sc;
5454 if (c->fc->nb_streams < 1)
5455 return AVERROR_INVALIDDATA;
5457 sc = c->fc->streams[c->fc->nb_streams - 1]->priv_data;
5459 if (atom.size < 5) {
5460 av_log(c->fc, AV_LOG_ERROR, "Empty Content Light Level box\n");
5461 return AVERROR_INVALIDDATA;
5464 version = avio_r8(pb);
5466 av_log(c->fc, AV_LOG_WARNING, "Unsupported Content Light Level box version %d\n", version);
5469 avio_skip(pb, 3); /* flags */
5471 sc->coll = av_content_light_metadata_alloc(&sc->coll_size);
5473 return AVERROR(ENOMEM);
5475 sc->coll->MaxCLL = avio_rb16(pb);
5476 sc->coll->MaxFALL = avio_rb16(pb);
5481 static int mov_read_clli(MOVContext *c, AVIOContext *pb, MOVAtom atom)
5483 MOVStreamContext *sc;
5485 if (c->fc->nb_streams < 1)
5486 return AVERROR_INVALIDDATA;
5488 sc = c->fc->streams[c->fc->nb_streams - 1]->priv_data;
5490 if (atom.size < 4) {
5491 av_log(c->fc, AV_LOG_ERROR, "Empty Content Light Level Info box\n");
5492 return AVERROR_INVALIDDATA;
5495 sc->coll = av_content_light_metadata_alloc(&sc->coll_size);
5497 return AVERROR(ENOMEM);
5499 sc->coll->MaxCLL = avio_rb16(pb);
5500 sc->coll->MaxFALL = avio_rb16(pb);
5505 static int mov_read_st3d(MOVContext *c, AVIOContext *pb, MOVAtom atom)
5508 MOVStreamContext *sc;
5509 enum AVStereo3DType type;
5512 if (c->fc->nb_streams < 1)
5515 st = c->fc->streams[c->fc->nb_streams - 1];
5518 if (atom.size < 5) {
5519 av_log(c->fc, AV_LOG_ERROR, "Empty stereoscopic video box\n");
5520 return AVERROR_INVALIDDATA;
5522 avio_skip(pb, 4); /* version + flags */
5527 type = AV_STEREO3D_2D;
5530 type = AV_STEREO3D_TOPBOTTOM;
5533 type = AV_STEREO3D_SIDEBYSIDE;
5536 av_log(c->fc, AV_LOG_WARNING, "Unknown st3d mode value %d\n", mode);
5540 sc->stereo3d = av_stereo3d_alloc();
5542 return AVERROR(ENOMEM);
5544 sc->stereo3d->type = type;
5548 static int mov_read_sv3d(MOVContext *c, AVIOContext *pb, MOVAtom atom)
5551 MOVStreamContext *sc;
5552 int size, version, layout;
5553 int32_t yaw, pitch, roll;
5554 uint32_t l = 0, t = 0, r = 0, b = 0;
5555 uint32_t tag, padding = 0;
5556 enum AVSphericalProjection projection;
5558 if (c->fc->nb_streams < 1)
5561 st = c->fc->streams[c->fc->nb_streams - 1];
5564 if (atom.size < 8) {
5565 av_log(c->fc, AV_LOG_ERROR, "Empty spherical video box\n");
5566 return AVERROR_INVALIDDATA;
5569 size = avio_rb32(pb);
5570 if (size <= 12 || size > atom.size)
5571 return AVERROR_INVALIDDATA;
5573 tag = avio_rl32(pb);
5574 if (tag != MKTAG('s','v','h','d')) {
5575 av_log(c->fc, AV_LOG_ERROR, "Missing spherical video header\n");
5578 version = avio_r8(pb);
5580 av_log(c->fc, AV_LOG_WARNING, "Unknown spherical version %d\n",
5584 avio_skip(pb, 3); /* flags */
5585 avio_skip(pb, size - 12); /* metadata_source */
5587 size = avio_rb32(pb);
5588 if (size > atom.size)
5589 return AVERROR_INVALIDDATA;
5591 tag = avio_rl32(pb);
5592 if (tag != MKTAG('p','r','o','j')) {
5593 av_log(c->fc, AV_LOG_ERROR, "Missing projection box\n");
5597 size = avio_rb32(pb);
5598 if (size > atom.size)
5599 return AVERROR_INVALIDDATA;
5601 tag = avio_rl32(pb);
5602 if (tag != MKTAG('p','r','h','d')) {
5603 av_log(c->fc, AV_LOG_ERROR, "Missing projection header box\n");
5606 version = avio_r8(pb);
5608 av_log(c->fc, AV_LOG_WARNING, "Unknown spherical version %d\n",
5612 avio_skip(pb, 3); /* flags */
5614 /* 16.16 fixed point */
5615 yaw = avio_rb32(pb);
5616 pitch = avio_rb32(pb);
5617 roll = avio_rb32(pb);
5619 size = avio_rb32(pb);
5620 if (size > atom.size)
5621 return AVERROR_INVALIDDATA;
5623 tag = avio_rl32(pb);
5624 version = avio_r8(pb);
5626 av_log(c->fc, AV_LOG_WARNING, "Unknown spherical version %d\n",
5630 avio_skip(pb, 3); /* flags */
5632 case MKTAG('c','b','m','p'):
5633 layout = avio_rb32(pb);
5635 av_log(c->fc, AV_LOG_WARNING,
5636 "Unsupported cubemap layout %d\n", layout);
5639 projection = AV_SPHERICAL_CUBEMAP;
5640 padding = avio_rb32(pb);
5642 case MKTAG('e','q','u','i'):
5648 if (b >= UINT_MAX - t || r >= UINT_MAX - l) {
5649 av_log(c->fc, AV_LOG_ERROR,
5650 "Invalid bounding rectangle coordinates "
5651 "%"PRIu32",%"PRIu32",%"PRIu32",%"PRIu32"\n", l, t, r, b);
5652 return AVERROR_INVALIDDATA;
5655 if (l || t || r || b)
5656 projection = AV_SPHERICAL_EQUIRECTANGULAR_TILE;
5658 projection = AV_SPHERICAL_EQUIRECTANGULAR;
5661 av_log(c->fc, AV_LOG_ERROR, "Unknown projection type: %s\n", av_fourcc2str(tag));
5665 sc->spherical = av_spherical_alloc(&sc->spherical_size);
5667 return AVERROR(ENOMEM);
5669 sc->spherical->projection = projection;
5671 sc->spherical->yaw = yaw;
5672 sc->spherical->pitch = pitch;
5673 sc->spherical->roll = roll;
5675 sc->spherical->padding = padding;
5677 sc->spherical->bound_left = l;
5678 sc->spherical->bound_top = t;
5679 sc->spherical->bound_right = r;
5680 sc->spherical->bound_bottom = b;
5685 static int mov_parse_uuid_spherical(MOVStreamContext *sc, AVIOContext *pb, size_t len)
5688 uint8_t *buffer = av_malloc(len + 1);
5692 return AVERROR(ENOMEM);
5695 ret = ffio_read_size(pb, buffer, len);
5699 /* Check for mandatory keys and values, try to support XML as best-effort */
5700 if (!sc->spherical &&
5701 av_stristr(buffer, "<GSpherical:StitchingSoftware>") &&
5702 (val = av_stristr(buffer, "<GSpherical:Spherical>")) &&
5703 av_stristr(val, "true") &&
5704 (val = av_stristr(buffer, "<GSpherical:Stitched>")) &&
5705 av_stristr(val, "true") &&
5706 (val = av_stristr(buffer, "<GSpherical:ProjectionType>")) &&
5707 av_stristr(val, "equirectangular")) {
5708 sc->spherical = av_spherical_alloc(&sc->spherical_size);
5712 sc->spherical->projection = AV_SPHERICAL_EQUIRECTANGULAR;
5714 if (av_stristr(buffer, "<GSpherical:StereoMode>") && !sc->stereo3d) {
5715 enum AVStereo3DType mode;
5717 if (av_stristr(buffer, "left-right"))
5718 mode = AV_STEREO3D_SIDEBYSIDE;
5719 else if (av_stristr(buffer, "top-bottom"))
5720 mode = AV_STEREO3D_TOPBOTTOM;
5722 mode = AV_STEREO3D_2D;
5724 sc->stereo3d = av_stereo3d_alloc();
5728 sc->stereo3d->type = mode;
5732 val = av_stristr(buffer, "<GSpherical:InitialViewHeadingDegrees>");
5734 sc->spherical->yaw = strtol(val, NULL, 10) * (1 << 16);
5735 val = av_stristr(buffer, "<GSpherical:InitialViewPitchDegrees>");
5737 sc->spherical->pitch = strtol(val, NULL, 10) * (1 << 16);
5738 val = av_stristr(buffer, "<GSpherical:InitialViewRollDegrees>");
5740 sc->spherical->roll = strtol(val, NULL, 10) * (1 << 16);
5748 static int mov_read_uuid(MOVContext *c, AVIOContext *pb, MOVAtom atom)
5751 MOVStreamContext *sc;
5754 static const uint8_t uuid_isml_manifest[] = {
5755 0xa5, 0xd4, 0x0b, 0x30, 0xe8, 0x14, 0x11, 0xdd,
5756 0xba, 0x2f, 0x08, 0x00, 0x20, 0x0c, 0x9a, 0x66
5758 static const uint8_t uuid_xmp[] = {
5759 0xbe, 0x7a, 0xcf, 0xcb, 0x97, 0xa9, 0x42, 0xe8,
5760 0x9c, 0x71, 0x99, 0x94, 0x91, 0xe3, 0xaf, 0xac
5762 static const uint8_t uuid_spherical[] = {
5763 0xff, 0xcc, 0x82, 0x63, 0xf8, 0x55, 0x4a, 0x93,
5764 0x88, 0x14, 0x58, 0x7a, 0x02, 0x52, 0x1f, 0xdd,
5767 if (atom.size < sizeof(uuid) || atom.size >= FFMIN(INT_MAX, SIZE_MAX))
5768 return AVERROR_INVALIDDATA;
5770 if (c->fc->nb_streams < 1)
5772 st = c->fc->streams[c->fc->nb_streams - 1];
5775 ret = ffio_read_size(pb, uuid, sizeof(uuid));
5778 if (!memcmp(uuid, uuid_isml_manifest, sizeof(uuid))) {
5779 uint8_t *buffer, *ptr;
5781 size_t len = atom.size - sizeof(uuid);
5784 return AVERROR_INVALIDDATA;
5786 ret = avio_skip(pb, 4); // zeroes
5789 buffer = av_mallocz(len + 1);
5791 return AVERROR(ENOMEM);
5793 ret = ffio_read_size(pb, buffer, len);
5800 while ((ptr = av_stristr(ptr, "systemBitrate=\""))) {
5801 ptr += sizeof("systemBitrate=\"") - 1;
5802 c->bitrates_count++;
5803 c->bitrates = av_realloc_f(c->bitrates, c->bitrates_count, sizeof(*c->bitrates));
5805 c->bitrates_count = 0;
5807 return AVERROR(ENOMEM);
5810 ret = strtol(ptr, &endptr, 10);
5811 if (ret < 0 || errno || *endptr != '"') {
5812 c->bitrates[c->bitrates_count - 1] = 0;
5814 c->bitrates[c->bitrates_count - 1] = ret;
5819 } else if (!memcmp(uuid, uuid_xmp, sizeof(uuid))) {
5821 size_t len = atom.size - sizeof(uuid);
5822 if (c->export_xmp) {
5823 buffer = av_mallocz(len + 1);
5825 return AVERROR(ENOMEM);
5827 ret = ffio_read_size(pb, buffer, len);
5833 av_dict_set(&c->fc->metadata, "xmp",
5834 buffer, AV_DICT_DONT_STRDUP_VAL);
5836 // skip all uuid atom, which makes it fast for long uuid-xmp file
5837 ret = avio_skip(pb, len);
5841 } else if (!memcmp(uuid, uuid_spherical, sizeof(uuid))) {
5842 size_t len = atom.size - sizeof(uuid);
5843 ret = mov_parse_uuid_spherical(sc, pb, len);
5847 av_log(c->fc, AV_LOG_WARNING, "Invalid spherical metadata found\n");
5853 static int mov_read_free(MOVContext *c, AVIOContext *pb, MOVAtom atom)
5856 uint8_t content[16];
5861 ret = avio_read(pb, content, FFMIN(sizeof(content), atom.size));
5867 && !memcmp(content, "Anevia\x1A\x1A", 8)
5868 && c->use_mfra_for == FF_MOV_FLAG_MFRA_AUTO) {
5869 c->use_mfra_for = FF_MOV_FLAG_MFRA_PTS;
5875 static int mov_read_frma(MOVContext *c, AVIOContext *pb, MOVAtom atom)
5877 uint32_t format = avio_rl32(pb);
5878 MOVStreamContext *sc;
5882 if (c->fc->nb_streams < 1)
5884 st = c->fc->streams[c->fc->nb_streams - 1];
5889 case MKTAG('e','n','c','v'): // encrypted video
5890 case MKTAG('e','n','c','a'): // encrypted audio
5891 id = mov_codec_id(st, format);
5892 if (st->codecpar->codec_id != AV_CODEC_ID_NONE &&
5893 st->codecpar->codec_id != id) {
5894 av_log(c->fc, AV_LOG_WARNING,
5895 "ignoring 'frma' atom of '%.4s', stream has codec id %d\n",
5896 (char*)&format, st->codecpar->codec_id);
5900 st->codecpar->codec_id = id;
5901 sc->format = format;
5905 if (format != sc->format) {
5906 av_log(c->fc, AV_LOG_WARNING,
5907 "ignoring 'frma' atom of '%.4s', stream format is '%.4s'\n",
5908 (char*)&format, (char*)&sc->format);
5917 * Gets the current encryption info and associated current stream context. If
5918 * we are parsing a track fragment, this will return the specific encryption
5919 * info for this fragment; otherwise this will return the global encryption
5920 * info for the current stream.
5922 static int get_current_encryption_info(MOVContext *c, MOVEncryptionIndex **encryption_index, MOVStreamContext **sc)
5924 MOVFragmentStreamInfo *frag_stream_info;
5928 frag_stream_info = get_current_frag_stream_info(&c->frag_index);
5929 if (frag_stream_info) {
5930 for (i = 0; i < c->fc->nb_streams; i++) {
5931 if (c->fc->streams[i]->id == frag_stream_info->id) {
5932 st = c->fc->streams[i];
5936 if (i == c->fc->nb_streams)
5938 *sc = st->priv_data;
5940 if (!frag_stream_info->encryption_index) {
5941 // If this stream isn't encrypted, don't create the index.
5942 if (!(*sc)->cenc.default_encrypted_sample)
5944 frag_stream_info->encryption_index = av_mallocz(sizeof(*frag_stream_info->encryption_index));
5945 if (!frag_stream_info->encryption_index)
5946 return AVERROR(ENOMEM);
5948 *encryption_index = frag_stream_info->encryption_index;
5951 // No current track fragment, using stream level encryption info.
5953 if (c->fc->nb_streams < 1)
5955 st = c->fc->streams[c->fc->nb_streams - 1];
5956 *sc = st->priv_data;
5958 if (!(*sc)->cenc.encryption_index) {
5959 // If this stream isn't encrypted, don't create the index.
5960 if (!(*sc)->cenc.default_encrypted_sample)
5962 (*sc)->cenc.encryption_index = av_mallocz(sizeof(*frag_stream_info->encryption_index));
5963 if (!(*sc)->cenc.encryption_index)
5964 return AVERROR(ENOMEM);
5967 *encryption_index = (*sc)->cenc.encryption_index;
5972 static int mov_read_sample_encryption_info(MOVContext *c, AVIOContext *pb, MOVStreamContext *sc, AVEncryptionInfo **sample, int use_subsamples)
5975 unsigned int subsample_count;
5976 AVSubsampleEncryptionInfo *subsamples;
5978 if (!sc->cenc.default_encrypted_sample) {
5979 av_log(c->fc, AV_LOG_ERROR, "Missing schm or tenc\n");
5980 return AVERROR_INVALIDDATA;
5983 *sample = av_encryption_info_clone(sc->cenc.default_encrypted_sample);
5985 return AVERROR(ENOMEM);
5987 if (sc->cenc.per_sample_iv_size != 0) {
5988 if ((ret = ffio_read_size(pb, (*sample)->iv, sc->cenc.per_sample_iv_size)) < 0) {
5989 av_log(c->fc, AV_LOG_ERROR, "failed to read the initialization vector\n");
5990 av_encryption_info_free(*sample);
5996 if (use_subsamples) {
5997 subsample_count = avio_rb16(pb);
5998 av_free((*sample)->subsamples);
5999 (*sample)->subsamples = av_mallocz_array(subsample_count, sizeof(*subsamples));
6000 if (!(*sample)->subsamples) {
6001 av_encryption_info_free(*sample);
6003 return AVERROR(ENOMEM);
6006 for (i = 0; i < subsample_count && !pb->eof_reached; i++) {
6007 (*sample)->subsamples[i].bytes_of_clear_data = avio_rb16(pb);
6008 (*sample)->subsamples[i].bytes_of_protected_data = avio_rb32(pb);
6011 if (pb->eof_reached) {
6012 av_log(c->fc, AV_LOG_ERROR, "hit EOF while reading sub-sample encryption info\n");
6013 av_encryption_info_free(*sample);
6015 return AVERROR_INVALIDDATA;
6017 (*sample)->subsample_count = subsample_count;
6023 static int mov_read_senc(MOVContext *c, AVIOContext *pb, MOVAtom atom)
6025 AVEncryptionInfo **encrypted_samples;
6026 MOVEncryptionIndex *encryption_index;
6027 MOVStreamContext *sc;
6028 int use_subsamples, ret;
6029 unsigned int sample_count, i, alloc_size = 0;
6031 ret = get_current_encryption_info(c, &encryption_index, &sc);
6035 if (encryption_index->nb_encrypted_samples) {
6036 // This can happen if we have both saio/saiz and senc atoms.
6037 av_log(c->fc, AV_LOG_DEBUG, "Ignoring duplicate encryption info in senc\n");
6041 avio_r8(pb); /* version */
6042 use_subsamples = avio_rb24(pb) & 0x02; /* flags */
6044 sample_count = avio_rb32(pb);
6045 if (sample_count >= INT_MAX / sizeof(*encrypted_samples))
6046 return AVERROR(ENOMEM);
6048 for (i = 0; i < sample_count; i++) {
6049 unsigned int min_samples = FFMIN(FFMAX(i + 1, 1024 * 1024), sample_count);
6050 encrypted_samples = av_fast_realloc(encryption_index->encrypted_samples, &alloc_size,
6051 min_samples * sizeof(*encrypted_samples));
6052 if (encrypted_samples) {
6053 encryption_index->encrypted_samples = encrypted_samples;
6055 ret = mov_read_sample_encryption_info(
6056 c, pb, sc, &encryption_index->encrypted_samples[i], use_subsamples);
6058 ret = AVERROR(ENOMEM);
6060 if (pb->eof_reached) {
6061 av_log(c->fc, AV_LOG_ERROR, "Hit EOF while reading senc\n");
6062 ret = AVERROR_INVALIDDATA;
6067 av_encryption_info_free(encryption_index->encrypted_samples[i - 1]);
6068 av_freep(&encryption_index->encrypted_samples);
6072 encryption_index->nb_encrypted_samples = sample_count;
6077 static int mov_parse_auxiliary_info(MOVContext *c, MOVStreamContext *sc, AVIOContext *pb, MOVEncryptionIndex *encryption_index)
6079 AVEncryptionInfo **sample, **encrypted_samples;
6081 size_t sample_count, sample_info_size, i;
6083 unsigned int alloc_size = 0;
6085 if (encryption_index->nb_encrypted_samples)
6087 sample_count = encryption_index->auxiliary_info_sample_count;
6088 if (encryption_index->auxiliary_offsets_count != 1) {
6089 av_log(c->fc, AV_LOG_ERROR, "Multiple auxiliary info chunks are not supported\n");
6090 return AVERROR_PATCHWELCOME;
6092 if (sample_count >= INT_MAX / sizeof(*encrypted_samples))
6093 return AVERROR(ENOMEM);
6095 prev_pos = avio_tell(pb);
6096 if (!(pb->seekable & AVIO_SEEKABLE_NORMAL) ||
6097 avio_seek(pb, encryption_index->auxiliary_offsets[0], SEEK_SET) != encryption_index->auxiliary_offsets[0]) {
6098 av_log(c->fc, AV_LOG_INFO, "Failed to seek for auxiliary info, will only parse senc atoms for encryption info\n");
6102 for (i = 0; i < sample_count && !pb->eof_reached; i++) {
6103 unsigned int min_samples = FFMIN(FFMAX(i + 1, 1024 * 1024), sample_count);
6104 encrypted_samples = av_fast_realloc(encryption_index->encrypted_samples, &alloc_size,
6105 min_samples * sizeof(*encrypted_samples));
6106 if (!encrypted_samples) {
6107 ret = AVERROR(ENOMEM);
6110 encryption_index->encrypted_samples = encrypted_samples;
6112 sample = &encryption_index->encrypted_samples[i];
6113 sample_info_size = encryption_index->auxiliary_info_default_size
6114 ? encryption_index->auxiliary_info_default_size
6115 : encryption_index->auxiliary_info_sizes[i];
6117 ret = mov_read_sample_encryption_info(c, pb, sc, sample, sample_info_size > sc->cenc.per_sample_iv_size);
6121 if (pb->eof_reached) {
6122 av_log(c->fc, AV_LOG_ERROR, "Hit EOF while reading auxiliary info\n");
6123 ret = AVERROR_INVALIDDATA;
6125 encryption_index->nb_encrypted_samples = sample_count;
6129 avio_seek(pb, prev_pos, SEEK_SET);
6131 for (; i > 0; i--) {
6132 av_encryption_info_free(encryption_index->encrypted_samples[i - 1]);
6134 av_freep(&encryption_index->encrypted_samples);
6140 * Tries to read the given number of bytes from the stream and puts it in a
6141 * newly allocated buffer. This reads in small chunks to avoid allocating large
6142 * memory if the file contains an invalid/malicious size value.
6144 static int mov_try_read_block(AVIOContext *pb, size_t size, uint8_t **data)
6146 const unsigned int block_size = 1024 * 1024;
6147 uint8_t *buffer = NULL;
6148 unsigned int alloc_size = 0, offset = 0;
6149 while (offset < size) {
6150 unsigned int new_size =
6151 alloc_size >= INT_MAX - block_size ? INT_MAX : alloc_size + block_size;
6152 uint8_t *new_buffer = av_fast_realloc(buffer, &alloc_size, new_size);
6153 unsigned int to_read = FFMIN(size, alloc_size) - offset;
6156 return AVERROR(ENOMEM);
6158 buffer = new_buffer;
6160 if (avio_read(pb, buffer + offset, to_read) != to_read) {
6162 return AVERROR_INVALIDDATA;
6171 static int mov_read_saiz(MOVContext *c, AVIOContext *pb, MOVAtom atom)
6173 MOVEncryptionIndex *encryption_index;
6174 MOVStreamContext *sc;
6176 unsigned int sample_count, aux_info_type, aux_info_param;
6178 ret = get_current_encryption_info(c, &encryption_index, &sc);
6182 if (encryption_index->nb_encrypted_samples) {
6183 // This can happen if we have both saio/saiz and senc atoms.
6184 av_log(c->fc, AV_LOG_DEBUG, "Ignoring duplicate encryption info in saiz\n");
6188 if (encryption_index->auxiliary_info_sample_count) {
6189 av_log(c->fc, AV_LOG_ERROR, "Duplicate saiz atom\n");
6190 return AVERROR_INVALIDDATA;
6193 avio_r8(pb); /* version */
6194 if (avio_rb24(pb) & 0x01) { /* flags */
6195 aux_info_type = avio_rb32(pb);
6196 aux_info_param = avio_rb32(pb);
6197 if (sc->cenc.default_encrypted_sample) {
6198 if (aux_info_type != sc->cenc.default_encrypted_sample->scheme) {
6199 av_log(c->fc, AV_LOG_DEBUG, "Ignoring saiz box with non-zero aux_info_type\n");
6202 if (aux_info_param != 0) {
6203 av_log(c->fc, AV_LOG_DEBUG, "Ignoring saiz box with non-zero aux_info_type_parameter\n");
6207 // Didn't see 'schm' or 'tenc', so this isn't encrypted.
6208 if ((aux_info_type == MKBETAG('c','e','n','c') ||
6209 aux_info_type == MKBETAG('c','e','n','s') ||
6210 aux_info_type == MKBETAG('c','b','c','1') ||
6211 aux_info_type == MKBETAG('c','b','c','s')) &&
6212 aux_info_param == 0) {
6213 av_log(c->fc, AV_LOG_ERROR, "Saw encrypted saiz without schm/tenc\n");
6214 return AVERROR_INVALIDDATA;
6219 } else if (!sc->cenc.default_encrypted_sample) {
6220 // Didn't see 'schm' or 'tenc', so this isn't encrypted.
6224 encryption_index->auxiliary_info_default_size = avio_r8(pb);
6225 sample_count = avio_rb32(pb);
6226 encryption_index->auxiliary_info_sample_count = sample_count;
6228 if (encryption_index->auxiliary_info_default_size == 0) {
6229 ret = mov_try_read_block(pb, sample_count, &encryption_index->auxiliary_info_sizes);
6231 av_log(c->fc, AV_LOG_ERROR, "Failed to read the auxiliary info\n");
6236 if (encryption_index->auxiliary_offsets_count) {
6237 return mov_parse_auxiliary_info(c, sc, pb, encryption_index);
6243 static int mov_read_saio(MOVContext *c, AVIOContext *pb, MOVAtom atom)
6245 uint64_t *auxiliary_offsets;
6246 MOVEncryptionIndex *encryption_index;
6247 MOVStreamContext *sc;
6249 unsigned int version, entry_count, aux_info_type, aux_info_param;
6250 unsigned int alloc_size = 0;
6252 ret = get_current_encryption_info(c, &encryption_index, &sc);
6256 if (encryption_index->nb_encrypted_samples) {
6257 // This can happen if we have both saio/saiz and senc atoms.
6258 av_log(c->fc, AV_LOG_DEBUG, "Ignoring duplicate encryption info in saio\n");
6262 if (encryption_index->auxiliary_offsets_count) {
6263 av_log(c->fc, AV_LOG_ERROR, "Duplicate saio atom\n");
6264 return AVERROR_INVALIDDATA;
6267 version = avio_r8(pb); /* version */
6268 if (avio_rb24(pb) & 0x01) { /* flags */
6269 aux_info_type = avio_rb32(pb);
6270 aux_info_param = avio_rb32(pb);
6271 if (sc->cenc.default_encrypted_sample) {
6272 if (aux_info_type != sc->cenc.default_encrypted_sample->scheme) {
6273 av_log(c->fc, AV_LOG_DEBUG, "Ignoring saio box with non-zero aux_info_type\n");
6276 if (aux_info_param != 0) {
6277 av_log(c->fc, AV_LOG_DEBUG, "Ignoring saio box with non-zero aux_info_type_parameter\n");
6281 // Didn't see 'schm' or 'tenc', so this isn't encrypted.
6282 if ((aux_info_type == MKBETAG('c','e','n','c') ||
6283 aux_info_type == MKBETAG('c','e','n','s') ||
6284 aux_info_type == MKBETAG('c','b','c','1') ||
6285 aux_info_type == MKBETAG('c','b','c','s')) &&
6286 aux_info_param == 0) {
6287 av_log(c->fc, AV_LOG_ERROR, "Saw encrypted saio without schm/tenc\n");
6288 return AVERROR_INVALIDDATA;
6293 } else if (!sc->cenc.default_encrypted_sample) {
6294 // Didn't see 'schm' or 'tenc', so this isn't encrypted.
6298 entry_count = avio_rb32(pb);
6299 if (entry_count >= INT_MAX / sizeof(*auxiliary_offsets))
6300 return AVERROR(ENOMEM);
6302 for (i = 0; i < entry_count && !pb->eof_reached; i++) {
6303 unsigned int min_offsets = FFMIN(FFMAX(i + 1, 1024), entry_count);
6304 auxiliary_offsets = av_fast_realloc(
6305 encryption_index->auxiliary_offsets, &alloc_size,
6306 min_offsets * sizeof(*auxiliary_offsets));
6307 if (!auxiliary_offsets) {
6308 av_freep(&encryption_index->auxiliary_offsets);
6309 return AVERROR(ENOMEM);
6311 encryption_index->auxiliary_offsets = auxiliary_offsets;
6314 encryption_index->auxiliary_offsets[i] = avio_rb32(pb);
6316 encryption_index->auxiliary_offsets[i] = avio_rb64(pb);
6318 if (c->frag_index.current >= 0) {
6319 encryption_index->auxiliary_offsets[i] += c->fragment.base_data_offset;
6323 if (pb->eof_reached) {
6324 av_log(c->fc, AV_LOG_ERROR, "Hit EOF while reading saio\n");
6325 av_freep(&encryption_index->auxiliary_offsets);
6326 return AVERROR_INVALIDDATA;
6329 encryption_index->auxiliary_offsets_count = entry_count;
6331 if (encryption_index->auxiliary_info_sample_count) {
6332 return mov_parse_auxiliary_info(c, sc, pb, encryption_index);
6338 static int mov_read_pssh(MOVContext *c, AVIOContext *pb, MOVAtom atom)
6340 AVEncryptionInitInfo *info, *old_init_info;
6343 uint8_t *side_data, *extra_data, *old_side_data;
6344 size_t side_data_size;
6345 int ret = 0, old_side_data_size;
6346 unsigned int version, kid_count, extra_data_size, alloc_size = 0;
6348 if (c->fc->nb_streams < 1)
6350 st = c->fc->streams[c->fc->nb_streams-1];
6352 version = avio_r8(pb); /* version */
6353 avio_rb24(pb); /* flags */
6355 info = av_encryption_init_info_alloc(/* system_id_size */ 16, /* num_key_ids */ 0,
6356 /* key_id_size */ 16, /* data_size */ 0);
6358 return AVERROR(ENOMEM);
6360 if ((ret = ffio_read_size(pb, info->system_id, 16)) < 0) {
6361 av_log(c->fc, AV_LOG_ERROR, "Failed to read the system id\n");
6366 kid_count = avio_rb32(pb);
6367 if (kid_count >= INT_MAX / sizeof(*key_ids)) {
6368 ret = AVERROR(ENOMEM);
6372 for (unsigned int i = 0; i < kid_count && !pb->eof_reached; i++) {
6373 unsigned int min_kid_count = FFMIN(FFMAX(i + 1, 1024), kid_count);
6374 key_ids = av_fast_realloc(info->key_ids, &alloc_size,
6375 min_kid_count * sizeof(*key_ids));
6377 ret = AVERROR(ENOMEM);
6380 info->key_ids = key_ids;
6382 info->key_ids[i] = av_mallocz(16);
6383 if (!info->key_ids[i]) {
6384 ret = AVERROR(ENOMEM);
6387 info->num_key_ids = i + 1;
6389 if ((ret = ffio_read_size(pb, info->key_ids[i], 16)) < 0) {
6390 av_log(c->fc, AV_LOG_ERROR, "Failed to read the key id\n");
6395 if (pb->eof_reached) {
6396 av_log(c->fc, AV_LOG_ERROR, "Hit EOF while reading pssh\n");
6397 ret = AVERROR_INVALIDDATA;
6402 extra_data_size = avio_rb32(pb);
6403 ret = mov_try_read_block(pb, extra_data_size, &extra_data);
6407 av_freep(&info->data); // malloc(0) may still allocate something.
6408 info->data = extra_data;
6409 info->data_size = extra_data_size;
6411 // If there is existing initialization data, append to the list.
6412 old_side_data = av_stream_get_side_data(st, AV_PKT_DATA_ENCRYPTION_INIT_INFO, &old_side_data_size);
6413 if (old_side_data) {
6414 old_init_info = av_encryption_init_info_get_side_data(old_side_data, old_side_data_size);
6415 if (old_init_info) {
6416 // Append to the end of the list.
6417 for (AVEncryptionInitInfo *cur = old_init_info;; cur = cur->next) {
6423 info = old_init_info;
6425 // Assume existing side-data will be valid, so the only error we could get is OOM.
6426 ret = AVERROR(ENOMEM);
6431 side_data = av_encryption_init_info_add_side_data(info, &side_data_size);
6433 ret = AVERROR(ENOMEM);
6436 ret = av_stream_add_side_data(st, AV_PKT_DATA_ENCRYPTION_INIT_INFO,
6437 side_data, side_data_size);
6442 av_encryption_init_info_free(info);
6446 static int mov_read_schm(MOVContext *c, AVIOContext *pb, MOVAtom atom)
6449 MOVStreamContext *sc;
6451 if (c->fc->nb_streams < 1)
6453 st = c->fc->streams[c->fc->nb_streams-1];
6456 if (sc->pseudo_stream_id != 0) {
6457 av_log(c->fc, AV_LOG_ERROR, "schm boxes are only supported in first sample descriptor\n");
6458 return AVERROR_PATCHWELCOME;
6462 return AVERROR_INVALIDDATA;
6464 avio_rb32(pb); /* version and flags */
6466 if (!sc->cenc.default_encrypted_sample) {
6467 sc->cenc.default_encrypted_sample = av_encryption_info_alloc(0, 16, 16);
6468 if (!sc->cenc.default_encrypted_sample) {
6469 return AVERROR(ENOMEM);
6473 sc->cenc.default_encrypted_sample->scheme = avio_rb32(pb);
6477 static int mov_read_tenc(MOVContext *c, AVIOContext *pb, MOVAtom atom)
6480 MOVStreamContext *sc;
6481 unsigned int version, pattern, is_protected, iv_size;
6483 if (c->fc->nb_streams < 1)
6485 st = c->fc->streams[c->fc->nb_streams-1];
6488 if (sc->pseudo_stream_id != 0) {
6489 av_log(c->fc, AV_LOG_ERROR, "tenc atom are only supported in first sample descriptor\n");
6490 return AVERROR_PATCHWELCOME;
6493 if (!sc->cenc.default_encrypted_sample) {
6494 sc->cenc.default_encrypted_sample = av_encryption_info_alloc(0, 16, 16);
6495 if (!sc->cenc.default_encrypted_sample) {
6496 return AVERROR(ENOMEM);
6501 return AVERROR_INVALIDDATA;
6503 version = avio_r8(pb); /* version */
6504 avio_rb24(pb); /* flags */
6506 avio_r8(pb); /* reserved */
6507 pattern = avio_r8(pb);
6510 sc->cenc.default_encrypted_sample->crypt_byte_block = pattern >> 4;
6511 sc->cenc.default_encrypted_sample->skip_byte_block = pattern & 0xf;
6514 is_protected = avio_r8(pb);
6515 if (is_protected && !sc->cenc.encryption_index) {
6516 // The whole stream should be by-default encrypted.
6517 sc->cenc.encryption_index = av_mallocz(sizeof(MOVEncryptionIndex));
6518 if (!sc->cenc.encryption_index)
6519 return AVERROR(ENOMEM);
6521 sc->cenc.per_sample_iv_size = avio_r8(pb);
6522 if (sc->cenc.per_sample_iv_size != 0 && sc->cenc.per_sample_iv_size != 8 &&
6523 sc->cenc.per_sample_iv_size != 16) {
6524 av_log(c->fc, AV_LOG_ERROR, "invalid per-sample IV size value\n");
6525 return AVERROR_INVALIDDATA;
6527 if (avio_read(pb, sc->cenc.default_encrypted_sample->key_id, 16) != 16) {
6528 av_log(c->fc, AV_LOG_ERROR, "failed to read the default key ID\n");
6529 return AVERROR_INVALIDDATA;
6532 if (is_protected && !sc->cenc.per_sample_iv_size) {
6533 iv_size = avio_r8(pb);
6534 if (iv_size != 8 && iv_size != 16) {
6535 av_log(c->fc, AV_LOG_ERROR, "invalid default_constant_IV_size in tenc atom\n");
6536 return AVERROR_INVALIDDATA;
6539 if (avio_read(pb, sc->cenc.default_encrypted_sample->iv, iv_size) != iv_size) {
6540 av_log(c->fc, AV_LOG_ERROR, "failed to read the default IV\n");
6541 return AVERROR_INVALIDDATA;
6548 static int mov_read_dfla(MOVContext *c, AVIOContext *pb, MOVAtom atom)
6551 int last, type, size, ret;
6554 if (c->fc->nb_streams < 1)
6556 st = c->fc->streams[c->fc->nb_streams-1];
6558 if ((uint64_t)atom.size > (1<<30) || atom.size < 42)
6559 return AVERROR_INVALIDDATA;
6561 /* Check FlacSpecificBox version. */
6562 if (avio_r8(pb) != 0)
6563 return AVERROR_INVALIDDATA;
6565 avio_rb24(pb); /* Flags */
6567 avio_read(pb, buf, sizeof(buf));
6568 flac_parse_block_header(buf, &last, &type, &size);
6570 if (type != FLAC_METADATA_TYPE_STREAMINFO || size != FLAC_STREAMINFO_SIZE) {
6571 av_log(c->fc, AV_LOG_ERROR, "STREAMINFO must be first FLACMetadataBlock\n");
6572 return AVERROR_INVALIDDATA;
6575 ret = ff_get_extradata(c->fc, st->codecpar, pb, size);
6580 av_log(c->fc, AV_LOG_WARNING, "non-STREAMINFO FLACMetadataBlock(s) ignored\n");
6585 static int cenc_decrypt(MOVContext *c, MOVStreamContext *sc, AVEncryptionInfo *sample, uint8_t *input, int size)
6589 if (sample->scheme != MKBETAG('c','e','n','c') || sample->crypt_byte_block != 0 || sample->skip_byte_block != 0) {
6590 av_log(c->fc, AV_LOG_ERROR, "Only the 'cenc' encryption scheme is supported\n");
6591 return AVERROR_PATCHWELCOME;
6594 if (!sc->cenc.aes_ctr) {
6595 /* initialize the cipher */
6596 sc->cenc.aes_ctr = av_aes_ctr_alloc();
6597 if (!sc->cenc.aes_ctr) {
6598 return AVERROR(ENOMEM);
6601 ret = av_aes_ctr_init(sc->cenc.aes_ctr, c->decryption_key);
6607 av_aes_ctr_set_full_iv(sc->cenc.aes_ctr, sample->iv);
6609 if (!sample->subsample_count) {
6610 /* decrypt the whole packet */
6611 av_aes_ctr_crypt(sc->cenc.aes_ctr, input, input, size);
6615 for (i = 0; i < sample->subsample_count; i++) {
6616 if (sample->subsamples[i].bytes_of_clear_data + sample->subsamples[i].bytes_of_protected_data > size) {
6617 av_log(c->fc, AV_LOG_ERROR, "subsample size exceeds the packet size left\n");
6618 return AVERROR_INVALIDDATA;
6621 /* skip the clear bytes */
6622 input += sample->subsamples[i].bytes_of_clear_data;
6623 size -= sample->subsamples[i].bytes_of_clear_data;
6625 /* decrypt the encrypted bytes */
6626 av_aes_ctr_crypt(sc->cenc.aes_ctr, input, input, sample->subsamples[i].bytes_of_protected_data);
6627 input += sample->subsamples[i].bytes_of_protected_data;
6628 size -= sample->subsamples[i].bytes_of_protected_data;
6632 av_log(c->fc, AV_LOG_ERROR, "leftover packet bytes after subsample processing\n");
6633 return AVERROR_INVALIDDATA;
6639 static int cenc_filter(MOVContext *mov, AVStream* st, MOVStreamContext *sc, AVPacket *pkt, int current_index)
6641 MOVFragmentStreamInfo *frag_stream_info;
6642 MOVEncryptionIndex *encryption_index;
6643 AVEncryptionInfo *encrypted_sample;
6644 int encrypted_index, ret;
6646 frag_stream_info = get_frag_stream_info(&mov->frag_index, mov->frag_index.current, st->id);
6647 encrypted_index = current_index;
6648 encryption_index = NULL;
6649 if (frag_stream_info) {
6650 // Note this only supports encryption info in the first sample descriptor.
6651 if (mov->fragment.stsd_id == 1) {
6652 if (frag_stream_info->encryption_index) {
6653 encrypted_index = current_index - frag_stream_info->index_entry;
6654 encryption_index = frag_stream_info->encryption_index;
6656 encryption_index = sc->cenc.encryption_index;
6660 encryption_index = sc->cenc.encryption_index;
6663 if (encryption_index) {
6664 if (encryption_index->auxiliary_info_sample_count &&
6665 !encryption_index->nb_encrypted_samples) {
6666 av_log(mov->fc, AV_LOG_ERROR, "saiz atom found without saio\n");
6667 return AVERROR_INVALIDDATA;
6669 if (encryption_index->auxiliary_offsets_count &&
6670 !encryption_index->nb_encrypted_samples) {
6671 av_log(mov->fc, AV_LOG_ERROR, "saio atom found without saiz\n");
6672 return AVERROR_INVALIDDATA;
6675 if (!encryption_index->nb_encrypted_samples) {
6676 // Full-sample encryption with default settings.
6677 encrypted_sample = sc->cenc.default_encrypted_sample;
6678 } else if (encrypted_index >= 0 && encrypted_index < encryption_index->nb_encrypted_samples) {
6679 // Per-sample setting override.
6680 encrypted_sample = encryption_index->encrypted_samples[encrypted_index];
6682 av_log(mov->fc, AV_LOG_ERROR, "Incorrect number of samples in encryption info\n");
6683 return AVERROR_INVALIDDATA;
6686 if (mov->decryption_key) {
6687 return cenc_decrypt(mov, sc, encrypted_sample, pkt->data, pkt->size);
6690 uint8_t *side_data = av_encryption_info_add_side_data(encrypted_sample, &size);
6692 return AVERROR(ENOMEM);
6693 ret = av_packet_add_side_data(pkt, AV_PKT_DATA_ENCRYPTION_INFO, side_data, size);
6703 static int mov_read_dops(MOVContext *c, AVIOContext *pb, MOVAtom atom)
6705 const int OPUS_SEEK_PREROLL_MS = 80;
6711 if (c->fc->nb_streams < 1)
6713 st = c->fc->streams[c->fc->nb_streams-1];
6715 if ((uint64_t)atom.size > (1<<30) || atom.size < 11)
6716 return AVERROR_INVALIDDATA;
6718 /* Check OpusSpecificBox version. */
6719 if (avio_r8(pb) != 0) {
6720 av_log(c->fc, AV_LOG_ERROR, "unsupported OpusSpecificBox version\n");
6721 return AVERROR_INVALIDDATA;
6724 /* OpusSpecificBox size plus magic for Ogg OpusHead header. */
6725 size = atom.size + 8;
6727 if ((ret = ff_alloc_extradata(st->codecpar, size)) < 0)
6730 AV_WL32(st->codecpar->extradata, MKTAG('O','p','u','s'));
6731 AV_WL32(st->codecpar->extradata + 4, MKTAG('H','e','a','d'));
6732 AV_WB8(st->codecpar->extradata + 8, 1); /* OpusHead version */
6733 avio_read(pb, st->codecpar->extradata + 9, size - 9);
6735 /* OpusSpecificBox is stored in big-endian, but OpusHead is
6736 little-endian; aside from the preceeding magic and version they're
6737 otherwise currently identical. Data after output gain at offset 16
6738 doesn't need to be bytewapped. */
6739 pre_skip = AV_RB16(st->codecpar->extradata + 10);
6740 AV_WL16(st->codecpar->extradata + 10, pre_skip);
6741 AV_WL32(st->codecpar->extradata + 12, AV_RB32(st->codecpar->extradata + 12));
6742 AV_WL16(st->codecpar->extradata + 16, AV_RB16(st->codecpar->extradata + 16));
6744 st->codecpar->initial_padding = pre_skip;
6745 st->codecpar->seek_preroll = av_rescale_q(OPUS_SEEK_PREROLL_MS,
6746 (AVRational){1, 1000},
6747 (AVRational){1, 48000});
6752 static int mov_read_dmlp(MOVContext *c, AVIOContext *pb, MOVAtom atom)
6755 unsigned format_info;
6756 int channel_assignment, channel_assignment1, channel_assignment2;
6759 if (c->fc->nb_streams < 1)
6761 st = c->fc->streams[c->fc->nb_streams-1];
6764 return AVERROR_INVALIDDATA;
6766 format_info = avio_rb32(pb);
6768 ratebits = (format_info >> 28) & 0xF;
6769 channel_assignment1 = (format_info >> 15) & 0x1F;
6770 channel_assignment2 = format_info & 0x1FFF;
6771 if (channel_assignment2)
6772 channel_assignment = channel_assignment2;
6774 channel_assignment = channel_assignment1;
6776 st->codecpar->frame_size = 40 << (ratebits & 0x7);
6777 st->codecpar->sample_rate = mlp_samplerate(ratebits);
6778 st->codecpar->channels = truehd_channels(channel_assignment);
6779 st->codecpar->channel_layout = truehd_layout(channel_assignment);
6784 static int mov_read_dvcc_dvvc(MOVContext *c, AVIOContext *pb, MOVAtom atom)
6788 AVDOVIDecoderConfigurationRecord *dovi;
6792 if (c->fc->nb_streams < 1)
6794 st = c->fc->streams[c->fc->nb_streams-1];
6796 if ((uint64_t)atom.size > (1<<30) || atom.size < 4)
6797 return AVERROR_INVALIDDATA;
6799 dovi = av_dovi_alloc(&dovi_size);
6801 return AVERROR(ENOMEM);
6803 dovi->dv_version_major = avio_r8(pb);
6804 dovi->dv_version_minor = avio_r8(pb);
6806 buf = avio_rb16(pb);
6807 dovi->dv_profile = (buf >> 9) & 0x7f; // 7 bits
6808 dovi->dv_level = (buf >> 3) & 0x3f; // 6 bits
6809 dovi->rpu_present_flag = (buf >> 2) & 0x01; // 1 bit
6810 dovi->el_present_flag = (buf >> 1) & 0x01; // 1 bit
6811 dovi->bl_present_flag = buf & 0x01; // 1 bit
6812 if (atom.size >= 24) { // 4 + 4 + 4 * 4
6814 dovi->dv_bl_signal_compatibility_id = (buf >> 4) & 0x0f; // 4 bits
6816 // 0 stands for None
6817 // Dolby Vision V1.2.93 profiles and levels
6818 dovi->dv_bl_signal_compatibility_id = 0;
6821 ret = av_stream_add_side_data(st, AV_PKT_DATA_DOVI_CONF,
6822 (uint8_t *)dovi, dovi_size);
6828 av_log(c, AV_LOG_TRACE, "DOVI in dvcC/dvvC box, version: %d.%d, profile: %d, level: %d, "
6829 "rpu flag: %d, el flag: %d, bl flag: %d, compatibility id: %d\n",
6830 dovi->dv_version_major, dovi->dv_version_minor,
6831 dovi->dv_profile, dovi->dv_level,
6832 dovi->rpu_present_flag,
6833 dovi->el_present_flag,
6834 dovi->bl_present_flag,
6835 dovi->dv_bl_signal_compatibility_id
6841 static const MOVParseTableEntry mov_default_parse_table[] = {
6842 { MKTAG('A','C','L','R'), mov_read_aclr },
6843 { MKTAG('A','P','R','G'), mov_read_avid },
6844 { MKTAG('A','A','L','P'), mov_read_avid },
6845 { MKTAG('A','R','E','S'), mov_read_ares },
6846 { MKTAG('a','v','s','s'), mov_read_avss },
6847 { MKTAG('a','v','1','C'), mov_read_av1c },
6848 { MKTAG('c','h','p','l'), mov_read_chpl },
6849 { MKTAG('c','o','6','4'), mov_read_stco },
6850 { MKTAG('c','o','l','r'), mov_read_colr },
6851 { MKTAG('c','t','t','s'), mov_read_ctts }, /* composition time to sample */
6852 { MKTAG('d','i','n','f'), mov_read_default },
6853 { MKTAG('D','p','x','E'), mov_read_dpxe },
6854 { MKTAG('d','r','e','f'), mov_read_dref },
6855 { MKTAG('e','d','t','s'), mov_read_default },
6856 { MKTAG('e','l','s','t'), mov_read_elst },
6857 { MKTAG('e','n','d','a'), mov_read_enda },
6858 { MKTAG('f','i','e','l'), mov_read_fiel },
6859 { MKTAG('a','d','r','m'), mov_read_adrm },
6860 { MKTAG('f','t','y','p'), mov_read_ftyp },
6861 { MKTAG('g','l','b','l'), mov_read_glbl },
6862 { MKTAG('h','d','l','r'), mov_read_hdlr },
6863 { MKTAG('i','l','s','t'), mov_read_ilst },
6864 { MKTAG('j','p','2','h'), mov_read_jp2h },
6865 { MKTAG('m','d','a','t'), mov_read_mdat },
6866 { MKTAG('m','d','h','d'), mov_read_mdhd },
6867 { MKTAG('m','d','i','a'), mov_read_default },
6868 { MKTAG('m','e','t','a'), mov_read_meta },
6869 { MKTAG('m','i','n','f'), mov_read_default },
6870 { MKTAG('m','o','o','f'), mov_read_moof },
6871 { MKTAG('m','o','o','v'), mov_read_moov },
6872 { MKTAG('m','v','e','x'), mov_read_default },
6873 { MKTAG('m','v','h','d'), mov_read_mvhd },
6874 { MKTAG('S','M','I',' '), mov_read_svq3 },
6875 { MKTAG('a','l','a','c'), mov_read_alac }, /* alac specific atom */
6876 { MKTAG('a','v','c','C'), mov_read_glbl },
6877 { MKTAG('p','a','s','p'), mov_read_pasp },
6878 { MKTAG('s','i','d','x'), mov_read_sidx },
6879 { MKTAG('s','t','b','l'), mov_read_default },
6880 { MKTAG('s','t','c','o'), mov_read_stco },
6881 { MKTAG('s','t','p','s'), mov_read_stps },
6882 { MKTAG('s','t','r','f'), mov_read_strf },
6883 { MKTAG('s','t','s','c'), mov_read_stsc },
6884 { MKTAG('s','t','s','d'), mov_read_stsd }, /* sample description */
6885 { MKTAG('s','t','s','s'), mov_read_stss }, /* sync sample */
6886 { MKTAG('s','t','s','z'), mov_read_stsz }, /* sample size */
6887 { MKTAG('s','t','t','s'), mov_read_stts },
6888 { MKTAG('s','t','z','2'), mov_read_stsz }, /* compact sample size */
6889 { MKTAG('s','d','t','p'), mov_read_sdtp }, /* independent and disposable samples */
6890 { MKTAG('t','k','h','d'), mov_read_tkhd }, /* track header */
6891 { MKTAG('t','f','d','t'), mov_read_tfdt },
6892 { MKTAG('t','f','h','d'), mov_read_tfhd }, /* track fragment header */
6893 { MKTAG('t','r','a','k'), mov_read_trak },
6894 { MKTAG('t','r','a','f'), mov_read_default },
6895 { MKTAG('t','r','e','f'), mov_read_default },
6896 { MKTAG('t','m','c','d'), mov_read_tmcd },
6897 { MKTAG('c','h','a','p'), mov_read_chap },
6898 { MKTAG('t','r','e','x'), mov_read_trex },
6899 { MKTAG('t','r','u','n'), mov_read_trun },
6900 { MKTAG('u','d','t','a'), mov_read_default },
6901 { MKTAG('w','a','v','e'), mov_read_wave },
6902 { MKTAG('e','s','d','s'), mov_read_esds },
6903 { MKTAG('d','a','c','3'), mov_read_dac3 }, /* AC-3 info */
6904 { MKTAG('d','e','c','3'), mov_read_dec3 }, /* EAC-3 info */
6905 { MKTAG('d','d','t','s'), mov_read_ddts }, /* DTS audio descriptor */
6906 { MKTAG('w','i','d','e'), mov_read_wide }, /* place holder */
6907 { MKTAG('w','f','e','x'), mov_read_wfex },
6908 { MKTAG('c','m','o','v'), mov_read_cmov },
6909 { MKTAG('c','h','a','n'), mov_read_chan }, /* channel layout */
6910 { MKTAG('d','v','c','1'), mov_read_dvc1 },
6911 { MKTAG('s','b','g','p'), mov_read_sbgp },
6912 { MKTAG('h','v','c','C'), mov_read_glbl },
6913 { MKTAG('u','u','i','d'), mov_read_uuid },
6914 { MKTAG('C','i','n', 0x8e), mov_read_targa_y216 },
6915 { MKTAG('f','r','e','e'), mov_read_free },
6916 { MKTAG('-','-','-','-'), mov_read_custom },
6917 { MKTAG('s','i','n','f'), mov_read_default },
6918 { MKTAG('f','r','m','a'), mov_read_frma },
6919 { MKTAG('s','e','n','c'), mov_read_senc },
6920 { MKTAG('s','a','i','z'), mov_read_saiz },
6921 { MKTAG('s','a','i','o'), mov_read_saio },
6922 { MKTAG('p','s','s','h'), mov_read_pssh },
6923 { MKTAG('s','c','h','m'), mov_read_schm },
6924 { MKTAG('s','c','h','i'), mov_read_default },
6925 { MKTAG('t','e','n','c'), mov_read_tenc },
6926 { MKTAG('d','f','L','a'), mov_read_dfla },
6927 { MKTAG('s','t','3','d'), mov_read_st3d }, /* stereoscopic 3D video box */
6928 { MKTAG('s','v','3','d'), mov_read_sv3d }, /* spherical video box */
6929 { MKTAG('d','O','p','s'), mov_read_dops },
6930 { MKTAG('d','m','l','p'), mov_read_dmlp },
6931 { MKTAG('S','m','D','m'), mov_read_smdm },
6932 { MKTAG('C','o','L','L'), mov_read_coll },
6933 { MKTAG('v','p','c','C'), mov_read_vpcc },
6934 { MKTAG('m','d','c','v'), mov_read_mdcv },
6935 { MKTAG('c','l','l','i'), mov_read_clli },
6936 { MKTAG('d','v','c','C'), mov_read_dvcc_dvvc },
6937 { MKTAG('d','v','v','C'), mov_read_dvcc_dvvc },
6941 static int mov_read_default(MOVContext *c, AVIOContext *pb, MOVAtom atom)
6943 int64_t total_size = 0;
6947 if (c->atom_depth > 10) {
6948 av_log(c->fc, AV_LOG_ERROR, "Atoms too deeply nested\n");
6949 return AVERROR_INVALIDDATA;
6954 atom.size = INT64_MAX;
6955 while (total_size <= atom.size - 8 && !avio_feof(pb)) {
6956 int (*parse)(MOVContext*, AVIOContext*, MOVAtom) = NULL;
6959 if (atom.size >= 8) {
6960 a.size = avio_rb32(pb);
6961 a.type = avio_rl32(pb);
6962 if (((a.type == MKTAG('f','r','e','e') && c->moov_retry) ||
6963 a.type == MKTAG('h','o','o','v')) &&
6965 c->fc->strict_std_compliance < FF_COMPLIANCE_STRICT) {
6968 type = avio_rl32(pb);
6969 avio_seek(pb, -8, SEEK_CUR);
6970 if (type == MKTAG('m','v','h','d') ||
6971 type == MKTAG('c','m','o','v')) {
6972 av_log(c->fc, AV_LOG_ERROR, "Detected moov in a free or hoov atom.\n");
6973 a.type = MKTAG('m','o','o','v');
6976 if (atom.type != MKTAG('r','o','o','t') &&
6977 atom.type != MKTAG('m','o','o','v')) {
6978 if (a.type == MKTAG('t','r','a','k') ||
6979 a.type == MKTAG('m','d','a','t')) {
6980 av_log(c->fc, AV_LOG_ERROR, "Broken file, trak/mdat not at top-level\n");
6987 if (a.size == 1 && total_size + 8 <= atom.size) { /* 64 bit extended size */
6988 a.size = avio_rb64(pb) - 8;
6992 av_log(c->fc, AV_LOG_TRACE, "type:'%s' parent:'%s' sz: %"PRId64" %"PRId64" %"PRId64"\n",
6993 av_fourcc2str(a.type), av_fourcc2str(atom.type), a.size, total_size, atom.size);
6995 a.size = atom.size - total_size + 8;
7000 a.size = FFMIN(a.size, atom.size - total_size);
7002 for (i = 0; mov_default_parse_table[i].type; i++)
7003 if (mov_default_parse_table[i].type == a.type) {
7004 parse = mov_default_parse_table[i].parse;
7008 // container is user data
7009 if (!parse && (atom.type == MKTAG('u','d','t','a') ||
7010 atom.type == MKTAG('i','l','s','t')))
7011 parse = mov_read_udta_string;
7013 // Supports parsing the QuickTime Metadata Keys.
7014 // https://developer.apple.com/library/mac/documentation/QuickTime/QTFF/Metadata/Metadata.html
7015 if (!parse && c->found_hdlr_mdta &&
7016 atom.type == MKTAG('m','e','t','a') &&
7017 a.type == MKTAG('k','e','y','s') &&
7018 c->meta_keys_count == 0) {
7019 parse = mov_read_keys;
7022 if (!parse) { /* skip leaf atoms data */
7023 avio_skip(pb, a.size);
7025 int64_t start_pos = avio_tell(pb);
7027 int err = parse(c, pb, a);
7032 if (c->found_moov && c->found_mdat &&
7033 ((!(pb->seekable & AVIO_SEEKABLE_NORMAL) || c->fc->flags & AVFMT_FLAG_IGNIDX || c->frag_index.complete) ||
7034 start_pos + a.size == avio_size(pb))) {
7035 if (!(pb->seekable & AVIO_SEEKABLE_NORMAL) || c->fc->flags & AVFMT_FLAG_IGNIDX || c->frag_index.complete)
7036 c->next_root_atom = start_pos + a.size;
7040 left = a.size - avio_tell(pb) + start_pos;
7041 if (left > 0) /* skip garbage at atom end */
7042 avio_skip(pb, left);
7043 else if (left < 0) {
7044 av_log(c->fc, AV_LOG_WARNING,
7045 "overread end of atom '%s' by %"PRId64" bytes\n",
7046 av_fourcc2str(a.type), -left);
7047 avio_seek(pb, left, SEEK_CUR);
7051 total_size += a.size;
7054 if (total_size < atom.size && atom.size < 0x7ffff)
7055 avio_skip(pb, atom.size - total_size);
7061 static int mov_probe(const AVProbeData *p)
7066 int moov_offset = -1;
7068 /* check file header */
7071 /* ignore invalid offset */
7072 if ((offset + 8) > (unsigned int)p->buf_size)
7074 tag = AV_RL32(p->buf + offset + 4);
7076 /* check for obvious tags */
7077 case MKTAG('m','o','o','v'):
7078 moov_offset = offset + 4;
7079 case MKTAG('m','d','a','t'):
7080 case MKTAG('p','n','o','t'): /* detect movs with preview pics like ew.mov and april.mov */
7081 case MKTAG('u','d','t','a'): /* Packet Video PVAuthor adds this and a lot of more junk */
7082 case MKTAG('f','t','y','p'):
7083 if (AV_RB32(p->buf+offset) < 8 &&
7084 (AV_RB32(p->buf+offset) != 1 ||
7085 offset + 12 > (unsigned int)p->buf_size ||
7086 AV_RB64(p->buf+offset + 8) == 0)) {
7087 score = FFMAX(score, AVPROBE_SCORE_EXTENSION);
7088 } else if (tag == MKTAG('f','t','y','p') &&
7089 ( AV_RL32(p->buf + offset + 8) == MKTAG('j','p','2',' ')
7090 || AV_RL32(p->buf + offset + 8) == MKTAG('j','p','x',' ')
7092 score = FFMAX(score, 5);
7094 score = AVPROBE_SCORE_MAX;
7096 offset = FFMAX(4, AV_RB32(p->buf+offset)) + offset;
7098 /* those are more common words, so rate then a bit less */
7099 case MKTAG('e','d','i','w'): /* xdcam files have reverted first tags */
7100 case MKTAG('w','i','d','e'):
7101 case MKTAG('f','r','e','e'):
7102 case MKTAG('j','u','n','k'):
7103 case MKTAG('p','i','c','t'):
7104 score = FFMAX(score, AVPROBE_SCORE_MAX - 5);
7105 offset = FFMAX(4, AV_RB32(p->buf+offset)) + offset;
7107 case MKTAG(0x82,0x82,0x7f,0x7d):
7108 case MKTAG('s','k','i','p'):
7109 case MKTAG('u','u','i','d'):
7110 case MKTAG('p','r','f','l'):
7111 /* if we only find those cause probedata is too small at least rate them */
7112 score = FFMAX(score, AVPROBE_SCORE_EXTENSION);
7113 offset = FFMAX(4, AV_RB32(p->buf+offset)) + offset;
7116 offset = FFMAX(4, AV_RB32(p->buf+offset)) + offset;
7119 if (score > AVPROBE_SCORE_MAX - 50 && moov_offset != -1) {
7120 /* moov atom in the header - we should make sure that this is not a
7121 * MOV-packed MPEG-PS */
7122 offset = moov_offset;
7124 while (offset < (p->buf_size - 16)) { /* Sufficient space */
7125 /* We found an actual hdlr atom */
7126 if (AV_RL32(p->buf + offset ) == MKTAG('h','d','l','r') &&
7127 AV_RL32(p->buf + offset + 8) == MKTAG('m','h','l','r') &&
7128 AV_RL32(p->buf + offset + 12) == MKTAG('M','P','E','G')) {
7129 av_log(NULL, AV_LOG_WARNING, "Found media data tag MPEG indicating this is a MOV-packed MPEG-PS.\n");
7130 /* We found a media handler reference atom describing an
7131 * MPEG-PS-in-MOV, return a
7132 * low score to force expanding the probe window until
7133 * mpegps_probe finds what it needs */
7145 // must be done after parsing all trak because there's no order requirement
7146 static void mov_read_chapters(AVFormatContext *s)
7148 MOVContext *mov = s->priv_data;
7150 MOVStreamContext *sc;
7155 for (j = 0; j < mov->nb_chapter_tracks; j++) {
7156 chapter_track = mov->chapter_tracks[j];
7158 for (i = 0; i < s->nb_streams; i++)
7159 if (s->streams[i]->id == chapter_track) {
7164 av_log(s, AV_LOG_ERROR, "Referenced QT chapter track not found\n");
7169 cur_pos = avio_tell(sc->pb);
7171 if (st->codecpar->codec_type == AVMEDIA_TYPE_VIDEO) {
7172 st->disposition |= AV_DISPOSITION_ATTACHED_PIC | AV_DISPOSITION_TIMED_THUMBNAILS;
7173 if (st->nb_index_entries) {
7174 // Retrieve the first frame, if possible
7175 AVIndexEntry *sample = &st->index_entries[0];
7176 if (avio_seek(sc->pb, sample->pos, SEEK_SET) != sample->pos) {
7177 av_log(s, AV_LOG_ERROR, "Failed to retrieve first frame\n");
7181 if (av_get_packet(sc->pb, &st->attached_pic, sample->size) < 0)
7184 st->attached_pic.stream_index = st->index;
7185 st->attached_pic.flags |= AV_PKT_FLAG_KEY;
7188 st->codecpar->codec_type = AVMEDIA_TYPE_DATA;
7189 st->codecpar->codec_id = AV_CODEC_ID_BIN_DATA;
7190 st->discard = AVDISCARD_ALL;
7191 for (i = 0; i < st->nb_index_entries; i++) {
7192 AVIndexEntry *sample = &st->index_entries[i];
7193 int64_t end = i+1 < st->nb_index_entries ? st->index_entries[i+1].timestamp : st->duration;
7198 if (end < sample->timestamp) {
7199 av_log(s, AV_LOG_WARNING, "ignoring stream duration which is shorter than chapters\n");
7200 end = AV_NOPTS_VALUE;
7203 if (avio_seek(sc->pb, sample->pos, SEEK_SET) != sample->pos) {
7204 av_log(s, AV_LOG_ERROR, "Chapter %d not found in file\n", i);
7208 // the first two bytes are the length of the title
7209 len = avio_rb16(sc->pb);
7210 if (len > sample->size-2)
7212 title_len = 2*len + 1;
7213 if (!(title = av_mallocz(title_len)))
7216 // The samples could theoretically be in any encoding if there's an encd
7217 // atom following, but in practice are only utf-8 or utf-16, distinguished
7218 // instead by the presence of a BOM
7222 ch = avio_rb16(sc->pb);
7224 avio_get_str16be(sc->pb, len, title, title_len);
7225 else if (ch == 0xfffe)
7226 avio_get_str16le(sc->pb, len, title, title_len);
7229 if (len == 1 || len == 2)
7232 avio_get_str(sc->pb, INT_MAX, title + 2, len - 1);
7236 avpriv_new_chapter(s, i, st->time_base, sample->timestamp, end, title);
7241 avio_seek(sc->pb, cur_pos, SEEK_SET);
7245 static int parse_timecode_in_framenum_format(AVFormatContext *s, AVStream *st,
7246 uint32_t value, int flags)
7249 char buf[AV_TIMECODE_STR_SIZE];
7250 AVRational rate = st->avg_frame_rate;
7251 int ret = av_timecode_init(&tc, rate, flags, 0, s);
7254 av_dict_set(&st->metadata, "timecode",
7255 av_timecode_make_string(&tc, buf, value), 0);
7259 static int mov_read_rtmd_track(AVFormatContext *s, AVStream *st)
7261 MOVStreamContext *sc = st->priv_data;
7262 char buf[AV_TIMECODE_STR_SIZE];
7263 int64_t cur_pos = avio_tell(sc->pb);
7264 int hh, mm, ss, ff, drop;
7266 if (!st->nb_index_entries)
7269 avio_seek(sc->pb, st->index_entries->pos, SEEK_SET);
7270 avio_skip(s->pb, 13);
7271 hh = avio_r8(s->pb);
7272 mm = avio_r8(s->pb);
7273 ss = avio_r8(s->pb);
7274 drop = avio_r8(s->pb);
7275 ff = avio_r8(s->pb);
7276 snprintf(buf, AV_TIMECODE_STR_SIZE, "%02d:%02d:%02d%c%02d",
7277 hh, mm, ss, drop ? ';' : ':', ff);
7278 av_dict_set(&st->metadata, "timecode", buf, 0);
7280 avio_seek(sc->pb, cur_pos, SEEK_SET);
7284 static int mov_read_timecode_track(AVFormatContext *s, AVStream *st)
7286 MOVStreamContext *sc = st->priv_data;
7288 int64_t cur_pos = avio_tell(sc->pb);
7291 if (!st->nb_index_entries)
7294 avio_seek(sc->pb, st->index_entries->pos, SEEK_SET);
7295 value = avio_rb32(s->pb);
7297 if (sc->tmcd_flags & 0x0001) flags |= AV_TIMECODE_FLAG_DROPFRAME;
7298 if (sc->tmcd_flags & 0x0002) flags |= AV_TIMECODE_FLAG_24HOURSMAX;
7299 if (sc->tmcd_flags & 0x0004) flags |= AV_TIMECODE_FLAG_ALLOWNEGATIVE;
7301 /* Assume Counter flag is set to 1 in tmcd track (even though it is likely
7302 * not the case) and thus assume "frame number format" instead of QT one.
7303 * No sample with tmcd track can be found with a QT timecode at the moment,
7304 * despite what the tmcd track "suggests" (Counter flag set to 0 means QT
7306 parse_timecode_in_framenum_format(s, st, value, flags);
7308 avio_seek(sc->pb, cur_pos, SEEK_SET);
7312 static void mov_free_encryption_index(MOVEncryptionIndex **index) {
7314 if (!index || !*index) return;
7315 for (i = 0; i < (*index)->nb_encrypted_samples; i++) {
7316 av_encryption_info_free((*index)->encrypted_samples[i]);
7318 av_freep(&(*index)->encrypted_samples);
7319 av_freep(&(*index)->auxiliary_info_sizes);
7320 av_freep(&(*index)->auxiliary_offsets);
7324 static int mov_read_close(AVFormatContext *s)
7326 MOVContext *mov = s->priv_data;
7329 for (i = 0; i < s->nb_streams; i++) {
7330 AVStream *st = s->streams[i];
7331 MOVStreamContext *sc = st->priv_data;
7336 av_freep(&sc->ctts_data);
7337 for (j = 0; j < sc->drefs_count; j++) {
7338 av_freep(&sc->drefs[j].path);
7339 av_freep(&sc->drefs[j].dir);
7341 av_freep(&sc->drefs);
7343 sc->drefs_count = 0;
7345 if (!sc->pb_is_copied)
7346 ff_format_io_close(s, &sc->pb);
7349 av_freep(&sc->chunk_offsets);
7350 av_freep(&sc->stsc_data);
7351 av_freep(&sc->sample_sizes);
7352 av_freep(&sc->keyframes);
7353 av_freep(&sc->stts_data);
7354 av_freep(&sc->sdtp_data);
7355 av_freep(&sc->stps_data);
7356 av_freep(&sc->elst_data);
7357 av_freep(&sc->rap_group);
7358 av_freep(&sc->display_matrix);
7359 av_freep(&sc->index_ranges);
7362 for (j = 0; j < sc->stsd_count; j++)
7363 av_free(sc->extradata[j]);
7364 av_freep(&sc->extradata);
7365 av_freep(&sc->extradata_size);
7367 mov_free_encryption_index(&sc->cenc.encryption_index);
7368 av_encryption_info_free(sc->cenc.default_encrypted_sample);
7369 av_aes_ctr_free(sc->cenc.aes_ctr);
7371 av_freep(&sc->stereo3d);
7372 av_freep(&sc->spherical);
7373 av_freep(&sc->mastering);
7374 av_freep(&sc->coll);
7377 av_freep(&mov->dv_demux);
7378 avformat_free_context(mov->dv_fctx);
7379 mov->dv_fctx = NULL;
7381 if (mov->meta_keys) {
7382 for (i = 1; i < mov->meta_keys_count; i++) {
7383 av_freep(&mov->meta_keys[i]);
7385 av_freep(&mov->meta_keys);
7388 av_freep(&mov->trex_data);
7389 av_freep(&mov->bitrates);
7391 for (i = 0; i < mov->frag_index.nb_items; i++) {
7392 MOVFragmentStreamInfo *frag = mov->frag_index.item[i].stream_info;
7393 for (j = 0; j < mov->frag_index.item[i].nb_stream_info; j++) {
7394 mov_free_encryption_index(&frag[j].encryption_index);
7396 av_freep(&mov->frag_index.item[i].stream_info);
7398 av_freep(&mov->frag_index.item);
7400 av_freep(&mov->aes_decrypt);
7401 av_freep(&mov->chapter_tracks);
7406 static int tmcd_is_referenced(AVFormatContext *s, int tmcd_id)
7410 for (i = 0; i < s->nb_streams; i++) {
7411 AVStream *st = s->streams[i];
7412 MOVStreamContext *sc = st->priv_data;
7414 if (st->codecpar->codec_type == AVMEDIA_TYPE_VIDEO &&
7415 sc->timecode_track == tmcd_id)
7421 /* look for a tmcd track not referenced by any video track, and export it globally */
7422 static void export_orphan_timecode(AVFormatContext *s)
7426 for (i = 0; i < s->nb_streams; i++) {
7427 AVStream *st = s->streams[i];
7429 if (st->codecpar->codec_tag == MKTAG('t','m','c','d') &&
7430 !tmcd_is_referenced(s, i + 1)) {
7431 AVDictionaryEntry *tcr = av_dict_get(st->metadata, "timecode", NULL, 0);
7433 av_dict_set(&s->metadata, "timecode", tcr->value, 0);
7440 static int read_tfra(MOVContext *mov, AVIOContext *f)
7442 int version, fieldlength, i, j;
7443 int64_t pos = avio_tell(f);
7444 uint32_t size = avio_rb32(f);
7445 unsigned track_id, item_count;
7447 if (avio_rb32(f) != MKBETAG('t', 'f', 'r', 'a')) {
7450 av_log(mov->fc, AV_LOG_VERBOSE, "found tfra\n");
7452 version = avio_r8(f);
7454 track_id = avio_rb32(f);
7455 fieldlength = avio_rb32(f);
7456 item_count = avio_rb32(f);
7457 for (i = 0; i < item_count; i++) {
7458 int64_t time, offset;
7460 MOVFragmentStreamInfo * frag_stream_info;
7463 return AVERROR_INVALIDDATA;
7467 time = avio_rb64(f);
7468 offset = avio_rb64(f);
7470 time = avio_rb32(f);
7471 offset = avio_rb32(f);
7474 // The first sample of each stream in a fragment is always a random
7475 // access sample. So it's entry in the tfra can be used as the
7476 // initial PTS of the fragment.
7477 index = update_frag_index(mov, offset);
7478 frag_stream_info = get_frag_stream_info(&mov->frag_index, index, track_id);
7479 if (frag_stream_info &&
7480 frag_stream_info->first_tfra_pts == AV_NOPTS_VALUE)
7481 frag_stream_info->first_tfra_pts = time;
7483 for (j = 0; j < ((fieldlength >> 4) & 3) + 1; j++)
7485 for (j = 0; j < ((fieldlength >> 2) & 3) + 1; j++)
7487 for (j = 0; j < ((fieldlength >> 0) & 3) + 1; j++)
7491 avio_seek(f, pos + size, SEEK_SET);
7495 static int mov_read_mfra(MOVContext *c, AVIOContext *f)
7497 int64_t stream_size = avio_size(f);
7498 int64_t original_pos = avio_tell(f);
7502 if ((seek_ret = avio_seek(f, stream_size - 4, SEEK_SET)) < 0) {
7506 mfra_size = avio_rb32(f);
7507 if (mfra_size < 0 || mfra_size > stream_size) {
7508 av_log(c->fc, AV_LOG_DEBUG, "doesn't look like mfra (unreasonable size)\n");
7511 if ((seek_ret = avio_seek(f, -mfra_size, SEEK_CUR)) < 0) {
7515 if (avio_rb32(f) != mfra_size) {
7516 av_log(c->fc, AV_LOG_DEBUG, "doesn't look like mfra (size mismatch)\n");
7519 if (avio_rb32(f) != MKBETAG('m', 'f', 'r', 'a')) {
7520 av_log(c->fc, AV_LOG_DEBUG, "doesn't look like mfra (tag mismatch)\n");
7523 av_log(c->fc, AV_LOG_VERBOSE, "stream has mfra\n");
7525 ret = read_tfra(c, f);
7531 seek_ret = avio_seek(f, original_pos, SEEK_SET);
7533 av_log(c->fc, AV_LOG_ERROR,
7534 "failed to seek back after looking for mfra\n");
7540 static int mov_read_header(AVFormatContext *s)
7542 MOVContext *mov = s->priv_data;
7543 AVIOContext *pb = s->pb;
7545 MOVAtom atom = { AV_RL32("root") };
7548 if (mov->decryption_key_len != 0 && mov->decryption_key_len != AES_CTR_KEY_SIZE) {
7549 av_log(s, AV_LOG_ERROR, "Invalid decryption key len %d expected %d\n",
7550 mov->decryption_key_len, AES_CTR_KEY_SIZE);
7551 return AVERROR(EINVAL);
7555 mov->trak_index = -1;
7556 /* .mov and .mp4 aren't streamable anyway (only progressive download if moov is before mdat) */
7557 if (pb->seekable & AVIO_SEEKABLE_NORMAL)
7558 atom.size = avio_size(pb);
7560 atom.size = INT64_MAX;
7562 /* check MOV header */
7564 if (mov->moov_retry)
7565 avio_seek(pb, 0, SEEK_SET);
7566 if ((err = mov_read_default(mov, pb, atom)) < 0) {
7567 av_log(s, AV_LOG_ERROR, "error reading header\n");
7570 } while ((pb->seekable & AVIO_SEEKABLE_NORMAL) && !mov->found_moov && !mov->moov_retry++);
7571 if (!mov->found_moov) {
7572 av_log(s, AV_LOG_ERROR, "moov atom not found\n");
7573 err = AVERROR_INVALIDDATA;
7576 av_log(mov->fc, AV_LOG_TRACE, "on_parse_exit_offset=%"PRId64"\n", avio_tell(pb));
7578 if (pb->seekable & AVIO_SEEKABLE_NORMAL) {
7579 if (mov->nb_chapter_tracks > 0 && !mov->ignore_chapters)
7580 mov_read_chapters(s);
7581 for (i = 0; i < s->nb_streams; i++)
7582 if (s->streams[i]->codecpar->codec_tag == AV_RL32("tmcd")) {
7583 mov_read_timecode_track(s, s->streams[i]);
7584 } else if (s->streams[i]->codecpar->codec_tag == AV_RL32("rtmd")) {
7585 mov_read_rtmd_track(s, s->streams[i]);
7589 /* copy timecode metadata from tmcd tracks to the related video streams */
7590 for (i = 0; i < s->nb_streams; i++) {
7591 AVStream *st = s->streams[i];
7592 MOVStreamContext *sc = st->priv_data;
7593 if (sc->timecode_track > 0) {
7594 AVDictionaryEntry *tcr;
7595 int tmcd_st_id = -1;
7597 for (j = 0; j < s->nb_streams; j++)
7598 if (s->streams[j]->id == sc->timecode_track)
7601 if (tmcd_st_id < 0 || tmcd_st_id == i)
7603 tcr = av_dict_get(s->streams[tmcd_st_id]->metadata, "timecode", NULL, 0);
7605 av_dict_set(&st->metadata, "timecode", tcr->value, 0);
7608 export_orphan_timecode(s);
7610 for (i = 0; i < s->nb_streams; i++) {
7611 AVStream *st = s->streams[i];
7612 MOVStreamContext *sc = st->priv_data;
7613 fix_timescale(mov, sc);
7614 if (st->codecpar->codec_type == AVMEDIA_TYPE_AUDIO &&
7615 st->codecpar->codec_id == AV_CODEC_ID_AAC) {
7616 st->skip_samples = sc->start_pad;
7618 if (st->codecpar->codec_type == AVMEDIA_TYPE_VIDEO && sc->nb_frames_for_fps > 0 && sc->duration_for_fps > 0)
7619 av_reduce(&st->avg_frame_rate.num, &st->avg_frame_rate.den,
7620 sc->time_scale*(int64_t)sc->nb_frames_for_fps, sc->duration_for_fps, INT_MAX);
7621 if (st->codecpar->codec_type == AVMEDIA_TYPE_SUBTITLE) {
7622 if (st->codecpar->width <= 0 || st->codecpar->height <= 0) {
7623 st->codecpar->width = sc->width;
7624 st->codecpar->height = sc->height;
7626 if (st->codecpar->codec_id == AV_CODEC_ID_DVD_SUBTITLE) {
7627 if ((err = mov_rewrite_dvd_sub_extradata(st)) < 0)
7631 if (mov->handbrake_version &&
7632 mov->handbrake_version <= 1000000*0 + 1000*10 + 2 && // 0.10.2
7633 st->codecpar->codec_id == AV_CODEC_ID_MP3) {
7634 av_log(s, AV_LOG_VERBOSE, "Forcing full parsing for mp3 stream\n");
7635 st->need_parsing = AVSTREAM_PARSE_FULL;
7639 if (mov->trex_data) {
7640 for (i = 0; i < s->nb_streams; i++) {
7641 AVStream *st = s->streams[i];
7642 MOVStreamContext *sc = st->priv_data;
7643 if (st->duration > 0) {
7644 if (sc->data_size > INT64_MAX / sc->time_scale / 8) {
7645 av_log(s, AV_LOG_ERROR, "Overflow during bit rate calculation %"PRId64" * 8 * %d\n",
7646 sc->data_size, sc->time_scale);
7647 err = AVERROR_INVALIDDATA;
7650 st->codecpar->bit_rate = sc->data_size * 8 * sc->time_scale / st->duration;
7655 if (mov->use_mfra_for > 0) {
7656 for (i = 0; i < s->nb_streams; i++) {
7657 AVStream *st = s->streams[i];
7658 MOVStreamContext *sc = st->priv_data;
7659 if (sc->duration_for_fps > 0) {
7660 if (sc->data_size > INT64_MAX / sc->time_scale / 8) {
7661 av_log(s, AV_LOG_ERROR, "Overflow during bit rate calculation %"PRId64" * 8 * %d\n",
7662 sc->data_size, sc->time_scale);
7663 err = AVERROR_INVALIDDATA;
7666 st->codecpar->bit_rate = sc->data_size * 8 * sc->time_scale /
7667 sc->duration_for_fps;
7672 for (i = 0; i < mov->bitrates_count && i < s->nb_streams; i++) {
7673 if (mov->bitrates[i]) {
7674 s->streams[i]->codecpar->bit_rate = mov->bitrates[i];
7678 ff_rfps_calculate(s);
7680 for (i = 0; i < s->nb_streams; i++) {
7681 AVStream *st = s->streams[i];
7682 MOVStreamContext *sc = st->priv_data;
7684 switch (st->codecpar->codec_type) {
7685 case AVMEDIA_TYPE_AUDIO:
7686 err = ff_replaygain_export(st, s->metadata);
7690 case AVMEDIA_TYPE_VIDEO:
7691 if (sc->display_matrix) {
7692 err = av_stream_add_side_data(st, AV_PKT_DATA_DISPLAYMATRIX, (uint8_t*)sc->display_matrix,
7693 sizeof(int32_t) * 9);
7697 sc->display_matrix = NULL;
7700 err = av_stream_add_side_data(st, AV_PKT_DATA_STEREO3D,
7701 (uint8_t *)sc->stereo3d,
7702 sizeof(*sc->stereo3d));
7706 sc->stereo3d = NULL;
7708 if (sc->spherical) {
7709 err = av_stream_add_side_data(st, AV_PKT_DATA_SPHERICAL,
7710 (uint8_t *)sc->spherical,
7711 sc->spherical_size);
7715 sc->spherical = NULL;
7717 if (sc->mastering) {
7718 err = av_stream_add_side_data(st, AV_PKT_DATA_MASTERING_DISPLAY_METADATA,
7719 (uint8_t *)sc->mastering,
7720 sizeof(*sc->mastering));
7724 sc->mastering = NULL;
7727 err = av_stream_add_side_data(st, AV_PKT_DATA_CONTENT_LIGHT_LEVEL,
7728 (uint8_t *)sc->coll,
7738 ff_configure_buffers_for_index(s, AV_TIME_BASE);
7740 for (i = 0; i < mov->frag_index.nb_items; i++)
7741 if (mov->frag_index.item[i].moof_offset <= mov->fragment.moof_offset)
7742 mov->frag_index.item[i].headers_read = 1;
7750 static AVIndexEntry *mov_find_next_sample(AVFormatContext *s, AVStream **st)
7752 AVIndexEntry *sample = NULL;
7753 int64_t best_dts = INT64_MAX;
7755 for (i = 0; i < s->nb_streams; i++) {
7756 AVStream *avst = s->streams[i];
7757 MOVStreamContext *msc = avst->priv_data;
7758 if (msc->pb && msc->current_sample < avst->nb_index_entries) {
7759 AVIndexEntry *current_sample = &avst->index_entries[msc->current_sample];
7760 int64_t dts = av_rescale(current_sample->timestamp, AV_TIME_BASE, msc->time_scale);
7761 av_log(s, AV_LOG_TRACE, "stream %d, sample %d, dts %"PRId64"\n", i, msc->current_sample, dts);
7762 if (!sample || (!(s->pb->seekable & AVIO_SEEKABLE_NORMAL) && current_sample->pos < sample->pos) ||
7763 ((s->pb->seekable & AVIO_SEEKABLE_NORMAL) &&
7764 ((msc->pb != s->pb && dts < best_dts) || (msc->pb == s->pb && dts != AV_NOPTS_VALUE &&
7765 ((FFABS(best_dts - dts) <= AV_TIME_BASE && current_sample->pos < sample->pos) ||
7766 (FFABS(best_dts - dts) > AV_TIME_BASE && dts < best_dts)))))) {
7767 sample = current_sample;
7776 static int should_retry(AVIOContext *pb, int error_code) {
7777 if (error_code == AVERROR_EOF || avio_feof(pb))
7783 static int mov_switch_root(AVFormatContext *s, int64_t target, int index)
7786 MOVContext *mov = s->priv_data;
7788 if (index >= 0 && index < mov->frag_index.nb_items)
7789 target = mov->frag_index.item[index].moof_offset;
7790 if (avio_seek(s->pb, target, SEEK_SET) != target) {
7791 av_log(mov->fc, AV_LOG_ERROR, "root atom offset 0x%"PRIx64": partial file\n", target);
7792 return AVERROR_INVALIDDATA;
7795 mov->next_root_atom = 0;
7796 if (index < 0 || index >= mov->frag_index.nb_items)
7797 index = search_frag_moof_offset(&mov->frag_index, target);
7798 if (index < mov->frag_index.nb_items &&
7799 mov->frag_index.item[index].moof_offset == target) {
7800 if (index + 1 < mov->frag_index.nb_items)
7801 mov->next_root_atom = mov->frag_index.item[index + 1].moof_offset;
7802 if (mov->frag_index.item[index].headers_read)
7804 mov->frag_index.item[index].headers_read = 1;
7807 mov->found_mdat = 0;
7809 ret = mov_read_default(mov, s->pb, (MOVAtom){ AV_RL32("root"), INT64_MAX });
7812 if (avio_feof(s->pb))
7814 av_log(s, AV_LOG_TRACE, "read fragments, offset 0x%"PRIx64"\n", avio_tell(s->pb));
7819 static int mov_change_extradata(MOVStreamContext *sc, AVPacket *pkt)
7821 uint8_t *side, *extradata;
7824 /* Save the current index. */
7825 sc->last_stsd_index = sc->stsc_data[sc->stsc_index].id - 1;
7827 /* Notify the decoder that extradata changed. */
7828 extradata_size = sc->extradata_size[sc->last_stsd_index];
7829 extradata = sc->extradata[sc->last_stsd_index];
7830 if (extradata_size > 0 && extradata) {
7831 side = av_packet_new_side_data(pkt,
7832 AV_PKT_DATA_NEW_EXTRADATA,
7835 return AVERROR(ENOMEM);
7836 memcpy(side, extradata, extradata_size);
7842 static int get_eia608_packet(AVIOContext *pb, AVPacket *pkt, int size)
7847 return AVERROR_INVALIDDATA;
7848 new_size = ((size - 8) / 2) * 3;
7849 ret = av_new_packet(pkt, new_size);
7854 for (int j = 0; j < new_size; j += 3) {
7855 pkt->data[j] = 0xFC;
7856 pkt->data[j+1] = avio_r8(pb);
7857 pkt->data[j+2] = avio_r8(pb);
7863 static int mov_read_packet(AVFormatContext *s, AVPacket *pkt)
7865 MOVContext *mov = s->priv_data;
7866 MOVStreamContext *sc;
7867 AVIndexEntry *sample;
7868 AVStream *st = NULL;
7869 int64_t current_index;
7873 sample = mov_find_next_sample(s, &st);
7874 if (!sample || (mov->next_root_atom && sample->pos > mov->next_root_atom)) {
7875 if (!mov->next_root_atom)
7877 if ((ret = mov_switch_root(s, mov->next_root_atom, -1)) < 0)
7882 /* must be done just before reading, to avoid infinite loop on sample */
7883 current_index = sc->current_index;
7884 mov_current_sample_inc(sc);
7886 if (mov->next_root_atom) {
7887 sample->pos = FFMIN(sample->pos, mov->next_root_atom);
7888 sample->size = FFMIN(sample->size, (mov->next_root_atom - sample->pos));
7891 if (st->discard != AVDISCARD_ALL) {
7892 int64_t ret64 = avio_seek(sc->pb, sample->pos, SEEK_SET);
7893 if (ret64 != sample->pos) {
7894 av_log(mov->fc, AV_LOG_ERROR, "stream %d, offset 0x%"PRIx64": partial file\n",
7895 sc->ffindex, sample->pos);
7896 if (should_retry(sc->pb, ret64)) {
7897 mov_current_sample_dec(sc);
7899 return AVERROR_INVALIDDATA;
7902 if (st->discard == AVDISCARD_NONKEY && !(sample->flags & AVINDEX_KEYFRAME)) {
7903 av_log(mov->fc, AV_LOG_DEBUG, "Nonkey frame from stream %d discarded due to AVDISCARD_NONKEY\n", sc->ffindex);
7907 if (st->codecpar->codec_id == AV_CODEC_ID_EIA_608 && sample->size > 8)
7908 ret = get_eia608_packet(sc->pb, pkt, sample->size);
7910 ret = av_get_packet(sc->pb, pkt, sample->size);
7912 if (should_retry(sc->pb, ret)) {
7913 mov_current_sample_dec(sc);
7917 #if CONFIG_DV_DEMUXER
7918 if (mov->dv_demux && sc->dv_audio_container) {
7919 AVBufferRef *buf = pkt->buf;
7920 ret = avpriv_dv_produce_packet(mov->dv_demux, pkt, pkt->data, pkt->size, pkt->pos);
7922 av_packet_unref(pkt);
7925 ret = avpriv_dv_get_packet(mov->dv_demux, pkt);
7930 if (sc->has_palette) {
7933 pal = av_packet_new_side_data(pkt, AV_PKT_DATA_PALETTE, AVPALETTE_SIZE);
7935 av_log(mov->fc, AV_LOG_ERROR, "Cannot append palette to packet\n");
7937 memcpy(pal, sc->palette, AVPALETTE_SIZE);
7938 sc->has_palette = 0;
7941 if (st->codecpar->codec_id == AV_CODEC_ID_MP3 && !st->need_parsing && pkt->size > 4) {
7942 if (ff_mpa_check_header(AV_RB32(pkt->data)) < 0)
7943 st->need_parsing = AVSTREAM_PARSE_FULL;
7947 pkt->stream_index = sc->ffindex;
7948 pkt->dts = sample->timestamp;
7949 if (sample->flags & AVINDEX_DISCARD_FRAME) {
7950 pkt->flags |= AV_PKT_FLAG_DISCARD;
7952 if (sc->ctts_data && sc->ctts_index < sc->ctts_count) {
7953 pkt->pts = pkt->dts + sc->dts_shift + sc->ctts_data[sc->ctts_index].duration;
7954 /* update ctts context */
7956 if (sc->ctts_index < sc->ctts_count &&
7957 sc->ctts_data[sc->ctts_index].count == sc->ctts_sample) {
7959 sc->ctts_sample = 0;
7962 int64_t next_dts = (sc->current_sample < st->nb_index_entries) ?
7963 st->index_entries[sc->current_sample].timestamp : st->duration;
7965 if (next_dts >= pkt->dts)
7966 pkt->duration = next_dts - pkt->dts;
7967 pkt->pts = pkt->dts;
7969 if (st->discard == AVDISCARD_ALL)
7971 if (sc->sdtp_data && sc->current_sample <= sc->sdtp_count) {
7972 uint8_t sample_flags = sc->sdtp_data[sc->current_sample - 1];
7973 uint8_t sample_is_depended_on = (sample_flags >> 2) & 0x3;
7974 pkt->flags |= sample_is_depended_on == MOV_SAMPLE_DEPENDENCY_NO ? AV_PKT_FLAG_DISPOSABLE : 0;
7976 pkt->flags |= sample->flags & AVINDEX_KEYFRAME ? AV_PKT_FLAG_KEY : 0;
7977 pkt->pos = sample->pos;
7979 /* Multiple stsd handling. */
7980 if (sc->stsc_data) {
7981 /* Keep track of the stsc index for the given sample, then check
7982 * if the stsd index is different from the last used one. */
7984 if (mov_stsc_index_valid(sc->stsc_index, sc->stsc_count) &&
7985 mov_get_stsc_samples(sc, sc->stsc_index) == sc->stsc_sample) {
7987 sc->stsc_sample = 0;
7988 /* Do not check indexes after a switch. */
7989 } else if (sc->stsc_data[sc->stsc_index].id > 0 &&
7990 sc->stsc_data[sc->stsc_index].id - 1 < sc->stsd_count &&
7991 sc->stsc_data[sc->stsc_index].id - 1 != sc->last_stsd_index) {
7992 ret = mov_change_extradata(sc, pkt);
7999 aax_filter(pkt->data, pkt->size, mov);
8001 ret = cenc_filter(mov, st, sc, pkt, current_index);
8009 static int mov_seek_fragment(AVFormatContext *s, AVStream *st, int64_t timestamp)
8011 MOVContext *mov = s->priv_data;
8014 if (!mov->frag_index.complete)
8017 index = search_frag_timestamp(&mov->frag_index, st, timestamp);
8020 if (!mov->frag_index.item[index].headers_read)
8021 return mov_switch_root(s, -1, index);
8022 if (index + 1 < mov->frag_index.nb_items)
8023 mov->next_root_atom = mov->frag_index.item[index + 1].moof_offset;
8028 static int mov_seek_stream(AVFormatContext *s, AVStream *st, int64_t timestamp, int flags)
8030 MOVStreamContext *sc = st->priv_data;
8031 int sample, time_sample, ret;
8034 // Here we consider timestamp to be PTS, hence try to offset it so that we
8035 // can search over the DTS timeline.
8036 timestamp -= (sc->min_corrected_pts + sc->dts_shift);
8038 ret = mov_seek_fragment(s, st, timestamp);
8042 sample = av_index_search_timestamp(st, timestamp, flags);
8043 av_log(s, AV_LOG_TRACE, "stream %d, timestamp %"PRId64", sample %d\n", st->index, timestamp, sample);
8044 if (sample < 0 && st->nb_index_entries && timestamp < st->index_entries[0].timestamp)
8046 if (sample < 0) /* not sure what to do */
8047 return AVERROR_INVALIDDATA;
8048 mov_current_sample_set(sc, sample);
8049 av_log(s, AV_LOG_TRACE, "stream %d, found sample %d\n", st->index, sc->current_sample);
8050 /* adjust ctts index */
8051 if (sc->ctts_data) {
8053 for (i = 0; i < sc->ctts_count; i++) {
8054 int next = time_sample + sc->ctts_data[i].count;
8055 if (next > sc->current_sample) {
8057 sc->ctts_sample = sc->current_sample - time_sample;
8064 /* adjust stsd index */
8065 if (sc->chunk_count) {
8067 for (i = 0; i < sc->stsc_count; i++) {
8068 int64_t next = time_sample + mov_get_stsc_samples(sc, i);
8069 if (next > sc->current_sample) {
8071 sc->stsc_sample = sc->current_sample - time_sample;
8074 av_assert0(next == (int)next);
8082 static int mov_read_seek(AVFormatContext *s, int stream_index, int64_t sample_time, int flags)
8084 MOVContext *mc = s->priv_data;
8089 if (stream_index >= s->nb_streams)
8090 return AVERROR_INVALIDDATA;
8092 st = s->streams[stream_index];
8093 sample = mov_seek_stream(s, st, sample_time, flags);
8097 if (mc->seek_individually) {
8098 /* adjust seek timestamp to found sample timestamp */
8099 int64_t seek_timestamp = st->index_entries[sample].timestamp;
8101 for (i = 0; i < s->nb_streams; i++) {
8103 MOVStreamContext *sc = s->streams[i]->priv_data;
8105 st->skip_samples = (sample_time <= 0) ? sc->start_pad : 0;
8107 if (stream_index == i)
8110 timestamp = av_rescale_q(seek_timestamp, s->streams[stream_index]->time_base, st->time_base);
8111 mov_seek_stream(s, st, timestamp, flags);
8114 for (i = 0; i < s->nb_streams; i++) {
8115 MOVStreamContext *sc;
8118 mov_current_sample_set(sc, 0);
8121 MOVStreamContext *sc;
8122 AVIndexEntry *entry = mov_find_next_sample(s, &st);
8124 return AVERROR_INVALIDDATA;
8126 if (sc->ffindex == stream_index && sc->current_sample == sample)
8128 mov_current_sample_inc(sc);
8134 #define OFFSET(x) offsetof(MOVContext, x)
8135 #define FLAGS AV_OPT_FLAG_VIDEO_PARAM | AV_OPT_FLAG_DECODING_PARAM
8136 static const AVOption mov_options[] = {
8137 {"use_absolute_path",
8138 "allow using absolute path when opening alias, this is a possible security issue",
8139 OFFSET(use_absolute_path), AV_OPT_TYPE_BOOL, {.i64 = 0},
8141 {"seek_streams_individually",
8142 "Seek each stream individually to the closest point",
8143 OFFSET(seek_individually), AV_OPT_TYPE_BOOL, { .i64 = 1 },
8145 {"ignore_editlist", "Ignore the edit list atom.", OFFSET(ignore_editlist), AV_OPT_TYPE_BOOL, {.i64 = 0},
8147 {"advanced_editlist",
8148 "Modify the AVIndex according to the editlists. Use this option to decode in the order specified by the edits.",
8149 OFFSET(advanced_editlist), AV_OPT_TYPE_BOOL, {.i64 = 1},
8151 {"ignore_chapters", "", OFFSET(ignore_chapters), AV_OPT_TYPE_BOOL, {.i64 = 0},
8154 "use mfra for fragment timestamps",
8155 OFFSET(use_mfra_for), AV_OPT_TYPE_INT, {.i64 = FF_MOV_FLAG_MFRA_AUTO},
8156 -1, FF_MOV_FLAG_MFRA_PTS, FLAGS,
8158 {"auto", "auto", 0, AV_OPT_TYPE_CONST, {.i64 = FF_MOV_FLAG_MFRA_AUTO}, 0, 0,
8159 FLAGS, "use_mfra_for" },
8160 {"dts", "dts", 0, AV_OPT_TYPE_CONST, {.i64 = FF_MOV_FLAG_MFRA_DTS}, 0, 0,
8161 FLAGS, "use_mfra_for" },
8162 {"pts", "pts", 0, AV_OPT_TYPE_CONST, {.i64 = FF_MOV_FLAG_MFRA_PTS}, 0, 0,
8163 FLAGS, "use_mfra_for" },
8164 { "export_all", "Export unrecognized metadata entries", OFFSET(export_all),
8165 AV_OPT_TYPE_BOOL, { .i64 = 0 }, 0, 1, .flags = FLAGS },
8166 { "export_xmp", "Export full XMP metadata", OFFSET(export_xmp),
8167 AV_OPT_TYPE_BOOL, { .i64 = 0 }, 0, 1, .flags = FLAGS },
8168 { "activation_bytes", "Secret bytes for Audible AAX files", OFFSET(activation_bytes),
8169 AV_OPT_TYPE_BINARY, .flags = AV_OPT_FLAG_DECODING_PARAM },
8170 { "audible_fixed_key", // extracted from libAAX_SDK.so and AAXSDKWin.dll files!
8171 "Fixed key used for handling Audible AAX files", OFFSET(audible_fixed_key),
8172 AV_OPT_TYPE_BINARY, {.str="77214d4b196a87cd520045fd20a51d67"},
8173 .flags = AV_OPT_FLAG_DECODING_PARAM },
8174 { "decryption_key", "The media decryption key (hex)", OFFSET(decryption_key), AV_OPT_TYPE_BINARY, .flags = AV_OPT_FLAG_DECODING_PARAM },
8175 { "enable_drefs", "Enable external track support.", OFFSET(enable_drefs), AV_OPT_TYPE_BOOL,
8176 {.i64 = 0}, 0, 1, FLAGS },
8181 static const AVClass mov_class = {
8182 .class_name = "mov,mp4,m4a,3gp,3g2,mj2",
8183 .item_name = av_default_item_name,
8184 .option = mov_options,
8185 .version = LIBAVUTIL_VERSION_INT,
8188 AVInputFormat ff_mov_demuxer = {
8189 .name = "mov,mp4,m4a,3gp,3g2,mj2",
8190 .long_name = NULL_IF_CONFIG_SMALL("QuickTime / MOV"),
8191 .priv_class = &mov_class,
8192 .priv_data_size = sizeof(MOVContext),
8193 .extensions = "mov,mp4,m4a,3gp,3g2,mj2,psp,m4b,ism,ismv,isma,f4v",
8194 .read_probe = mov_probe,
8195 .read_header = mov_read_header,
8196 .read_packet = mov_read_packet,
8197 .read_close = mov_read_close,
8198 .read_seek = mov_read_seek,
8199 .flags = AVFMT_NO_BYTE_SEEK | AVFMT_SEEK_TO_PTS,