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)
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;
2432 static int mov_skip_multiple_stsd(MOVContext *c, AVIOContext *pb,
2433 int codec_tag, int format,
2436 int video_codec_id = ff_codec_get_id(ff_codec_movvideo_tags, format);
2439 (codec_tag != format &&
2440 // AVID 1:1 samples with differing data format and codec tag exist
2441 (codec_tag != AV_RL32("AV1x") || format != AV_RL32("AVup")) &&
2442 // prores is allowed to have differing data format and codec tag
2443 codec_tag != AV_RL32("apcn") && codec_tag != AV_RL32("apch") &&
2445 codec_tag != AV_RL32("dvpp") && codec_tag != AV_RL32("dvcp") &&
2446 (c->fc->video_codec_id ? video_codec_id != c->fc->video_codec_id
2447 : codec_tag != MKTAG('j','p','e','g')))) {
2448 /* Multiple fourcc, we skip JPEG. This is not correct, we should
2449 * export it as a separate AVStream but this needs a few changes
2450 * in the MOV demuxer, patch welcome. */
2452 av_log(c->fc, AV_LOG_WARNING, "multiple fourcc not supported\n");
2453 avio_skip(pb, size);
2460 int ff_mov_read_stsd_entries(MOVContext *c, AVIOContext *pb, int entries)
2463 MOVStreamContext *sc;
2464 int pseudo_stream_id;
2466 av_assert0 (c->fc->nb_streams >= 1);
2467 st = c->fc->streams[c->fc->nb_streams-1];
2470 for (pseudo_stream_id = 0;
2471 pseudo_stream_id < entries && !pb->eof_reached;
2472 pseudo_stream_id++) {
2473 //Parsing Sample description table
2475 int ret, dref_id = 1;
2476 MOVAtom a = { AV_RL32("stsd") };
2477 int64_t start_pos = avio_tell(pb);
2478 int64_t size = avio_rb32(pb); /* size */
2479 uint32_t format = avio_rl32(pb); /* data format */
2482 avio_rb32(pb); /* reserved */
2483 avio_rb16(pb); /* reserved */
2484 dref_id = avio_rb16(pb);
2485 } else if (size <= 7) {
2486 av_log(c->fc, AV_LOG_ERROR,
2487 "invalid size %"PRId64" in stsd\n", size);
2488 return AVERROR_INVALIDDATA;
2491 if (mov_skip_multiple_stsd(c, pb, st->codecpar->codec_tag, format,
2492 size - (avio_tell(pb) - start_pos))) {
2497 sc->pseudo_stream_id = st->codecpar->codec_tag ? -1 : pseudo_stream_id;
2498 sc->dref_id= dref_id;
2499 sc->format = format;
2501 id = mov_codec_id(st, format);
2503 av_log(c->fc, AV_LOG_TRACE,
2504 "size=%"PRId64" 4CC=%s codec_type=%d\n", size,
2505 av_fourcc2str(format), st->codecpar->codec_type);
2507 st->codecpar->codec_id = id;
2508 if (st->codecpar->codec_type==AVMEDIA_TYPE_VIDEO) {
2509 mov_parse_stsd_video(c, pb, st, sc);
2510 } else if (st->codecpar->codec_type==AVMEDIA_TYPE_AUDIO) {
2511 mov_parse_stsd_audio(c, pb, st, sc);
2512 if (st->codecpar->sample_rate < 0) {
2513 av_log(c->fc, AV_LOG_ERROR, "Invalid sample rate %d\n", st->codecpar->sample_rate);
2514 return AVERROR_INVALIDDATA;
2516 } else if (st->codecpar->codec_type==AVMEDIA_TYPE_SUBTITLE){
2517 mov_parse_stsd_subtitle(c, pb, st, sc,
2518 size - (avio_tell(pb) - start_pos));
2520 ret = mov_parse_stsd_data(c, pb, st, sc,
2521 size - (avio_tell(pb) - start_pos));
2525 /* this will read extra atoms at the end (wave, alac, damr, avcC, hvcC, SMI ...) */
2526 a.size = size - (avio_tell(pb) - start_pos);
2528 if ((ret = mov_read_default(c, pb, a)) < 0)
2530 } else if (a.size > 0)
2531 avio_skip(pb, a.size);
2533 if (sc->extradata && st->codecpar->extradata) {
2534 int extra_size = st->codecpar->extradata_size;
2536 /* Move the current stream extradata to the stream context one. */
2537 sc->extradata_size[pseudo_stream_id] = extra_size;
2538 sc->extradata[pseudo_stream_id] = st->codecpar->extradata;
2539 st->codecpar->extradata = NULL;
2540 st->codecpar->extradata_size = 0;
2545 if (pb->eof_reached) {
2546 av_log(c->fc, AV_LOG_WARNING, "reached eof, corrupted STSD atom\n");
2553 static int mov_read_stsd(MOVContext *c, AVIOContext *pb, MOVAtom atom)
2556 MOVStreamContext *sc;
2559 if (c->fc->nb_streams < 1)
2561 st = c->fc->streams[c->fc->nb_streams - 1];
2564 sc->stsd_version = avio_r8(pb);
2565 avio_rb24(pb); /* flags */
2566 entries = avio_rb32(pb);
2568 /* Each entry contains a size (4 bytes) and format (4 bytes). */
2569 if (entries <= 0 || entries > atom.size / 8) {
2570 av_log(c->fc, AV_LOG_ERROR, "invalid STSD entries %d\n", entries);
2571 return AVERROR_INVALIDDATA;
2574 if (sc->extradata) {
2575 av_log(c->fc, AV_LOG_ERROR,
2576 "Duplicate stsd found in this track.\n");
2577 return AVERROR_INVALIDDATA;
2580 /* Prepare space for hosting multiple extradata. */
2581 sc->extradata = av_mallocz_array(entries, sizeof(*sc->extradata));
2583 return AVERROR(ENOMEM);
2585 sc->extradata_size = av_mallocz_array(entries, sizeof(*sc->extradata_size));
2586 if (!sc->extradata_size) {
2587 ret = AVERROR(ENOMEM);
2591 ret = ff_mov_read_stsd_entries(c, pb, entries);
2595 /* Restore back the primary extradata. */
2596 av_freep(&st->codecpar->extradata);
2597 st->codecpar->extradata_size = sc->extradata_size[0];
2598 if (sc->extradata_size[0]) {
2599 st->codecpar->extradata = av_mallocz(sc->extradata_size[0] + AV_INPUT_BUFFER_PADDING_SIZE);
2600 if (!st->codecpar->extradata)
2601 return AVERROR(ENOMEM);
2602 memcpy(st->codecpar->extradata, sc->extradata[0], sc->extradata_size[0]);
2605 return mov_finalize_stsd_codec(c, pb, st, sc);
2607 if (sc->extradata) {
2609 for (j = 0; j < sc->stsd_count; j++)
2610 av_freep(&sc->extradata[j]);
2613 av_freep(&sc->extradata);
2614 av_freep(&sc->extradata_size);
2618 static int mov_read_stsc(MOVContext *c, AVIOContext *pb, MOVAtom atom)
2621 MOVStreamContext *sc;
2622 unsigned int i, entries;
2624 if (c->fc->nb_streams < 1)
2626 st = c->fc->streams[c->fc->nb_streams-1];
2629 avio_r8(pb); /* version */
2630 avio_rb24(pb); /* flags */
2632 entries = avio_rb32(pb);
2633 if ((uint64_t)entries * 12 + 4 > atom.size)
2634 return AVERROR_INVALIDDATA;
2636 av_log(c->fc, AV_LOG_TRACE, "track[%u].stsc.entries = %u\n", c->fc->nb_streams - 1, entries);
2641 av_log(c->fc, AV_LOG_WARNING, "Duplicated STSC atom\n");
2642 av_free(sc->stsc_data);
2644 sc->stsc_data = av_malloc_array(entries, sizeof(*sc->stsc_data));
2646 return AVERROR(ENOMEM);
2648 for (i = 0; i < entries && !pb->eof_reached; i++) {
2649 sc->stsc_data[i].first = avio_rb32(pb);
2650 sc->stsc_data[i].count = avio_rb32(pb);
2651 sc->stsc_data[i].id = avio_rb32(pb);
2655 for (i = sc->stsc_count - 1; i < UINT_MAX; i--) {
2656 int64_t first_min = i + 1;
2657 if ((i+1 < sc->stsc_count && sc->stsc_data[i].first >= sc->stsc_data[i+1].first) ||
2658 (i > 0 && sc->stsc_data[i].first <= sc->stsc_data[i-1].first) ||
2659 sc->stsc_data[i].first < first_min ||
2660 sc->stsc_data[i].count < 1 ||
2661 sc->stsc_data[i].id < 1) {
2662 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);
2663 if (i+1 >= sc->stsc_count) {
2664 if (sc->stsc_data[i].count == 0 && i > 0) {
2668 sc->stsc_data[i].first = FFMAX(sc->stsc_data[i].first, first_min);
2669 if (i > 0 && sc->stsc_data[i].first <= sc->stsc_data[i-1].first)
2670 sc->stsc_data[i].first = FFMIN(sc->stsc_data[i-1].first + 1LL, INT_MAX);
2671 sc->stsc_data[i].count = FFMAX(sc->stsc_data[i].count, 1);
2672 sc->stsc_data[i].id = FFMAX(sc->stsc_data[i].id, 1);
2675 av_assert0(sc->stsc_data[i+1].first >= 2);
2676 // We replace this entry by the next valid
2677 sc->stsc_data[i].first = sc->stsc_data[i+1].first - 1;
2678 sc->stsc_data[i].count = sc->stsc_data[i+1].count;
2679 sc->stsc_data[i].id = sc->stsc_data[i+1].id;
2683 if (pb->eof_reached) {
2684 av_log(c->fc, AV_LOG_WARNING, "reached eof, corrupted STSC atom\n");
2691 static inline int mov_stsc_index_valid(unsigned int index, unsigned int count)
2693 return index < count - 1;
2696 /* Compute the samples value for the stsc entry at the given index. */
2697 static inline int64_t mov_get_stsc_samples(MOVStreamContext *sc, unsigned int index)
2701 if (mov_stsc_index_valid(index, sc->stsc_count))
2702 chunk_count = sc->stsc_data[index + 1].first - sc->stsc_data[index].first;
2704 // Validation for stsc / stco happens earlier in mov_read_stsc + mov_read_trak.
2705 av_assert0(sc->stsc_data[index].first <= sc->chunk_count);
2706 chunk_count = sc->chunk_count - (sc->stsc_data[index].first - 1);
2709 return sc->stsc_data[index].count * (int64_t)chunk_count;
2712 static int mov_read_stps(MOVContext *c, AVIOContext *pb, MOVAtom atom)
2715 MOVStreamContext *sc;
2716 unsigned i, entries;
2718 if (c->fc->nb_streams < 1)
2720 st = c->fc->streams[c->fc->nb_streams-1];
2723 avio_rb32(pb); // version + flags
2725 entries = avio_rb32(pb);
2727 av_log(c->fc, AV_LOG_WARNING, "Duplicated STPS atom\n");
2728 av_free(sc->stps_data);
2730 sc->stps_data = av_malloc_array(entries, sizeof(*sc->stps_data));
2732 return AVERROR(ENOMEM);
2734 for (i = 0; i < entries && !pb->eof_reached; i++) {
2735 sc->stps_data[i] = avio_rb32(pb);
2740 if (pb->eof_reached) {
2741 av_log(c->fc, AV_LOG_WARNING, "reached eof, corrupted STPS atom\n");
2748 static int mov_read_stss(MOVContext *c, AVIOContext *pb, MOVAtom atom)
2751 MOVStreamContext *sc;
2752 unsigned int i, entries;
2754 if (c->fc->nb_streams < 1)
2756 st = c->fc->streams[c->fc->nb_streams-1];
2759 avio_r8(pb); /* version */
2760 avio_rb24(pb); /* flags */
2762 entries = avio_rb32(pb);
2764 av_log(c->fc, AV_LOG_TRACE, "keyframe_count = %u\n", entries);
2767 sc->keyframe_absent = 1;
2768 if (!st->need_parsing && st->codecpar->codec_type == AVMEDIA_TYPE_VIDEO)
2769 st->need_parsing = AVSTREAM_PARSE_HEADERS;
2773 av_log(c->fc, AV_LOG_WARNING, "Duplicated STSS atom\n");
2774 if (entries >= UINT_MAX / sizeof(int))
2775 return AVERROR_INVALIDDATA;
2776 av_freep(&sc->keyframes);
2777 sc->keyframe_count = 0;
2778 sc->keyframes = av_malloc_array(entries, sizeof(*sc->keyframes));
2780 return AVERROR(ENOMEM);
2782 for (i = 0; i < entries && !pb->eof_reached; i++) {
2783 sc->keyframes[i] = avio_rb32(pb);
2786 sc->keyframe_count = i;
2788 if (pb->eof_reached) {
2789 av_log(c->fc, AV_LOG_WARNING, "reached eof, corrupted STSS atom\n");
2796 static int mov_read_stsz(MOVContext *c, AVIOContext *pb, MOVAtom atom)
2799 MOVStreamContext *sc;
2800 unsigned int i, entries, sample_size, field_size, num_bytes;
2805 if (c->fc->nb_streams < 1)
2807 st = c->fc->streams[c->fc->nb_streams-1];
2810 avio_r8(pb); /* version */
2811 avio_rb24(pb); /* flags */
2813 if (atom.type == MKTAG('s','t','s','z')) {
2814 sample_size = avio_rb32(pb);
2815 if (!sc->sample_size) /* do not overwrite value computed in stsd */
2816 sc->sample_size = sample_size;
2817 sc->stsz_sample_size = sample_size;
2821 avio_rb24(pb); /* reserved */
2822 field_size = avio_r8(pb);
2824 entries = avio_rb32(pb);
2826 av_log(c->fc, AV_LOG_TRACE, "sample_size = %u sample_count = %u\n", sc->sample_size, entries);
2828 sc->sample_count = entries;
2832 if (field_size != 4 && field_size != 8 && field_size != 16 && field_size != 32) {
2833 av_log(c->fc, AV_LOG_ERROR, "Invalid sample field size %u\n", field_size);
2834 return AVERROR_INVALIDDATA;
2839 if (entries >= (UINT_MAX - 4) / field_size)
2840 return AVERROR_INVALIDDATA;
2841 if (sc->sample_sizes)
2842 av_log(c->fc, AV_LOG_WARNING, "Duplicated STSZ atom\n");
2843 av_free(sc->sample_sizes);
2844 sc->sample_count = 0;
2845 sc->sample_sizes = av_malloc_array(entries, sizeof(*sc->sample_sizes));
2846 if (!sc->sample_sizes)
2847 return AVERROR(ENOMEM);
2849 num_bytes = (entries*field_size+4)>>3;
2851 buf = av_malloc(num_bytes+AV_INPUT_BUFFER_PADDING_SIZE);
2853 av_freep(&sc->sample_sizes);
2854 return AVERROR(ENOMEM);
2857 ret = ffio_read_size(pb, buf, num_bytes);
2859 av_freep(&sc->sample_sizes);
2861 av_log(c->fc, AV_LOG_WARNING, "STSZ atom truncated\n");
2865 init_get_bits(&gb, buf, 8*num_bytes);
2867 for (i = 0; i < entries && !pb->eof_reached; i++) {
2868 sc->sample_sizes[i] = get_bits_long(&gb, field_size);
2869 if (sc->sample_sizes[i] < 0) {
2871 av_log(c->fc, AV_LOG_ERROR, "Invalid sample size %d\n", sc->sample_sizes[i]);
2872 return AVERROR_INVALIDDATA;
2874 sc->data_size += sc->sample_sizes[i];
2877 sc->sample_count = i;
2881 if (pb->eof_reached) {
2882 av_log(c->fc, AV_LOG_WARNING, "reached eof, corrupted STSZ atom\n");
2889 static int mov_read_stts(MOVContext *c, AVIOContext *pb, MOVAtom atom)
2892 MOVStreamContext *sc;
2893 unsigned int i, entries, alloc_size = 0;
2894 int64_t duration = 0;
2895 int64_t total_sample_count = 0;
2897 if (c->fc->nb_streams < 1)
2899 st = c->fc->streams[c->fc->nb_streams-1];
2902 avio_r8(pb); /* version */
2903 avio_rb24(pb); /* flags */
2904 entries = avio_rb32(pb);
2906 av_log(c->fc, AV_LOG_TRACE, "track[%u].stts.entries = %u\n",
2907 c->fc->nb_streams-1, entries);
2910 av_log(c->fc, AV_LOG_WARNING, "Duplicated STTS atom\n");
2911 av_freep(&sc->stts_data);
2913 if (entries >= INT_MAX / sizeof(*sc->stts_data))
2914 return AVERROR(ENOMEM);
2916 for (i = 0; i < entries && !pb->eof_reached; i++) {
2917 int sample_duration;
2918 unsigned int sample_count;
2919 unsigned int min_entries = FFMIN(FFMAX(i + 1, 1024 * 1024), entries);
2920 MOVStts *stts_data = av_fast_realloc(sc->stts_data, &alloc_size,
2921 min_entries * sizeof(*sc->stts_data));
2923 av_freep(&sc->stts_data);
2925 return AVERROR(ENOMEM);
2927 sc->stts_count = min_entries;
2928 sc->stts_data = stts_data;
2930 sample_count = avio_rb32(pb);
2931 sample_duration = avio_rb32(pb);
2933 sc->stts_data[i].count= sample_count;
2934 sc->stts_data[i].duration= sample_duration;
2936 av_log(c->fc, AV_LOG_TRACE, "sample_count=%d, sample_duration=%d\n",
2937 sample_count, sample_duration);
2939 duration+=(int64_t)sample_duration*(uint64_t)sample_count;
2940 total_sample_count+=sample_count;
2946 duration <= INT64_MAX - sc->duration_for_fps &&
2947 total_sample_count <= INT_MAX - sc->nb_frames_for_fps) {
2948 sc->duration_for_fps += duration;
2949 sc->nb_frames_for_fps += total_sample_count;
2952 if (pb->eof_reached) {
2953 av_log(c->fc, AV_LOG_WARNING, "reached eof, corrupted STTS atom\n");
2957 st->nb_frames= total_sample_count;
2959 st->duration= FFMIN(st->duration, duration);
2960 sc->track_end = duration;
2964 static int mov_read_sdtp(MOVContext *c, AVIOContext *pb, MOVAtom atom)
2967 MOVStreamContext *sc;
2970 if (c->fc->nb_streams < 1)
2972 st = c->fc->streams[c->fc->nb_streams - 1];
2975 avio_r8(pb); /* version */
2976 avio_rb24(pb); /* flags */
2977 entries = atom.size - 4;
2979 av_log(c->fc, AV_LOG_TRACE, "track[%u].sdtp.entries = %" PRId64 "\n",
2980 c->fc->nb_streams - 1, entries);
2983 av_log(c->fc, AV_LOG_WARNING, "Duplicated SDTP atom\n");
2984 av_freep(&sc->sdtp_data);
2987 sc->sdtp_data = av_mallocz(entries);
2989 return AVERROR(ENOMEM);
2991 for (i = 0; i < entries && !pb->eof_reached; i++)
2992 sc->sdtp_data[i] = avio_r8(pb);
2998 static void mov_update_dts_shift(MOVStreamContext *sc, int duration, void *logctx)
3001 if (duration == INT_MIN) {
3002 av_log(logctx, AV_LOG_WARNING, "mov_update_dts_shift(): dts_shift set to %d\n", INT_MAX);
3005 sc->dts_shift = FFMAX(sc->dts_shift, -duration);
3009 static int mov_read_ctts(MOVContext *c, AVIOContext *pb, MOVAtom atom)
3012 MOVStreamContext *sc;
3013 unsigned int i, entries, ctts_count = 0;
3015 if (c->fc->nb_streams < 1)
3017 st = c->fc->streams[c->fc->nb_streams-1];
3020 avio_r8(pb); /* version */
3021 avio_rb24(pb); /* flags */
3022 entries = avio_rb32(pb);
3024 av_log(c->fc, AV_LOG_TRACE, "track[%u].ctts.entries = %u\n", c->fc->nb_streams - 1, entries);
3028 if (entries >= UINT_MAX / sizeof(*sc->ctts_data))
3029 return AVERROR_INVALIDDATA;
3030 av_freep(&sc->ctts_data);
3031 sc->ctts_data = av_fast_realloc(NULL, &sc->ctts_allocated_size, entries * sizeof(*sc->ctts_data));
3033 return AVERROR(ENOMEM);
3035 for (i = 0; i < entries && !pb->eof_reached; i++) {
3036 int count = avio_rb32(pb);
3037 int duration = avio_rb32(pb);
3040 av_log(c->fc, AV_LOG_TRACE,
3041 "ignoring CTTS entry with count=%d duration=%d\n",
3046 add_ctts_entry(&sc->ctts_data, &ctts_count, &sc->ctts_allocated_size,
3049 av_log(c->fc, AV_LOG_TRACE, "count=%d, duration=%d\n",
3052 if (FFNABS(duration) < -(1<<28) && i+2<entries) {
3053 av_log(c->fc, AV_LOG_WARNING, "CTTS invalid\n");
3054 av_freep(&sc->ctts_data);
3060 mov_update_dts_shift(sc, duration, c->fc);
3063 sc->ctts_count = ctts_count;
3065 if (pb->eof_reached) {
3066 av_log(c->fc, AV_LOG_WARNING, "reached eof, corrupted CTTS atom\n");
3070 av_log(c->fc, AV_LOG_TRACE, "dts shift %d\n", sc->dts_shift);
3075 static int mov_read_sbgp(MOVContext *c, AVIOContext *pb, MOVAtom atom)
3078 MOVStreamContext *sc;
3079 unsigned int i, entries;
3081 uint32_t grouping_type;
3083 if (c->fc->nb_streams < 1)
3085 st = c->fc->streams[c->fc->nb_streams-1];
3088 version = avio_r8(pb); /* version */
3089 avio_rb24(pb); /* flags */
3090 grouping_type = avio_rl32(pb);
3091 if (grouping_type != MKTAG( 'r','a','p',' '))
3092 return 0; /* only support 'rap ' grouping */
3094 avio_rb32(pb); /* grouping_type_parameter */
3096 entries = avio_rb32(pb);
3100 av_log(c->fc, AV_LOG_WARNING, "Duplicated SBGP atom\n");
3101 av_free(sc->rap_group);
3102 sc->rap_group_count = 0;
3103 sc->rap_group = av_malloc_array(entries, sizeof(*sc->rap_group));
3105 return AVERROR(ENOMEM);
3107 for (i = 0; i < entries && !pb->eof_reached; i++) {
3108 sc->rap_group[i].count = avio_rb32(pb); /* sample_count */
3109 sc->rap_group[i].index = avio_rb32(pb); /* group_description_index */
3112 sc->rap_group_count = i;
3114 if (pb->eof_reached) {
3115 av_log(c->fc, AV_LOG_WARNING, "reached eof, corrupted SBGP atom\n");
3123 * Get ith edit list entry (media time, duration).
3125 static int get_edit_list_entry(MOVContext *mov,
3126 const MOVStreamContext *msc,
3127 unsigned int edit_list_index,
3128 int64_t *edit_list_media_time,
3129 int64_t *edit_list_duration,
3130 int64_t global_timescale)
3132 if (edit_list_index == msc->elst_count) {
3135 *edit_list_media_time = msc->elst_data[edit_list_index].time;
3136 *edit_list_duration = msc->elst_data[edit_list_index].duration;
3138 /* duration is in global timescale units;convert to msc timescale */
3139 if (global_timescale == 0) {
3140 avpriv_request_sample(mov->fc, "Support for mvhd.timescale = 0 with editlists");
3143 *edit_list_duration = av_rescale(*edit_list_duration, msc->time_scale,
3149 * Find the closest previous frame to the timestamp_pts, in e_old index
3150 * entries. Searching for just any frame / just key frames can be controlled by
3151 * last argument 'flag'.
3152 * Note that if ctts_data is not NULL, we will always search for a key frame
3153 * irrespective of the value of 'flag'. If we don't find any keyframe, we will
3154 * return the first frame of the video.
3156 * Here the timestamp_pts is considered to be a presentation timestamp and
3157 * the timestamp of index entries are considered to be decoding timestamps.
3159 * Returns 0 if successful in finding a frame, else returns -1.
3160 * Places the found index corresponding output arg.
3162 * If ctts_old is not NULL, then refines the searched entry by searching
3163 * backwards from the found timestamp, to find the frame with correct PTS.
3165 * Places the found ctts_index and ctts_sample in corresponding output args.
3167 static int find_prev_closest_index(AVStream *st,
3168 AVIndexEntry *e_old,
3172 int64_t timestamp_pts,
3175 int64_t* ctts_index,
3176 int64_t* ctts_sample)
3178 MOVStreamContext *msc = st->priv_data;
3179 AVIndexEntry *e_keep = st->index_entries;
3180 int nb_keep = st->nb_index_entries;
3182 int64_t index_ctts_count;
3186 // If dts_shift > 0, then all the index timestamps will have to be offset by
3187 // at least dts_shift amount to obtain PTS.
3188 // Hence we decrement the searched timestamp_pts by dts_shift to find the closest index element.
3189 if (msc->dts_shift > 0) {
3190 timestamp_pts -= msc->dts_shift;
3193 st->index_entries = e_old;
3194 st->nb_index_entries = nb_old;
3195 *index = av_index_search_timestamp(st, timestamp_pts, flag | AVSEEK_FLAG_BACKWARD);
3197 // Keep going backwards in the index entries until the timestamp is the same.
3199 for (i = *index; i > 0 && e_old[i].timestamp == e_old[i - 1].timestamp;
3201 if ((flag & AVSEEK_FLAG_ANY) ||
3202 (e_old[i - 1].flags & AVINDEX_KEYFRAME)) {
3208 // If we have CTTS then refine the search, by searching backwards over PTS
3209 // computed by adding corresponding CTTS durations to index timestamps.
3210 if (ctts_data && *index >= 0) {
3211 av_assert0(ctts_index);
3212 av_assert0(ctts_sample);
3213 // Find out the ctts_index for the found frame.
3216 for (index_ctts_count = 0; index_ctts_count < *index; index_ctts_count++) {
3217 if (*ctts_index < ctts_count) {
3219 if (ctts_data[*ctts_index].count == *ctts_sample) {
3226 while (*index >= 0 && (*ctts_index) >= 0 && (*ctts_index) < ctts_count) {
3227 // Find a "key frame" with PTS <= timestamp_pts (So that we can decode B-frames correctly).
3228 // No need to add dts_shift to the timestamp here becase timestamp_pts has already been
3229 // compensated by dts_shift above.
3230 if ((e_old[*index].timestamp + ctts_data[*ctts_index].duration) <= timestamp_pts &&
3231 (e_old[*index].flags & AVINDEX_KEYFRAME)) {
3236 if (*ctts_sample == 0) {
3238 if (*ctts_index >= 0)
3239 *ctts_sample = ctts_data[*ctts_index].count - 1;
3246 /* restore AVStream state*/
3247 st->index_entries = e_keep;
3248 st->nb_index_entries = nb_keep;
3249 return *index >= 0 ? 0 : -1;
3253 * Add index entry with the given values, to the end of st->index_entries.
3254 * Returns the new size st->index_entries if successful, else returns -1.
3256 * This function is similar to ff_add_index_entry in libavformat/utils.c
3257 * except that here we are always unconditionally adding an index entry to
3258 * the end, instead of searching the entries list and skipping the add if
3259 * there is an existing entry with the same timestamp.
3260 * This is needed because the mov_fix_index calls this func with the same
3261 * unincremented timestamp for successive discarded frames.
3263 static int64_t add_index_entry(AVStream *st, int64_t pos, int64_t timestamp,
3264 int size, int distance, int flags)
3266 AVIndexEntry *entries, *ie;
3268 const size_t min_size_needed = (st->nb_index_entries + 1) * sizeof(AVIndexEntry);
3270 // Double the allocation each time, to lower memory fragmentation.
3271 // Another difference from ff_add_index_entry function.
3272 const size_t requested_size =
3273 min_size_needed > st->index_entries_allocated_size ?
3274 FFMAX(min_size_needed, 2 * st->index_entries_allocated_size) :
3277 if (st->nb_index_entries + 1U >= UINT_MAX / sizeof(AVIndexEntry))
3280 entries = av_fast_realloc(st->index_entries,
3281 &st->index_entries_allocated_size,
3286 st->index_entries= entries;
3288 index= st->nb_index_entries++;
3289 ie= &entries[index];
3292 ie->timestamp = timestamp;
3293 ie->min_distance= distance;
3300 * Rewrite timestamps of index entries in the range [end_index - frame_duration_buffer_size, end_index)
3301 * by subtracting end_ts successively by the amounts given in frame_duration_buffer.
3303 static void fix_index_entry_timestamps(AVStream* st, int end_index, int64_t end_ts,
3304 int64_t* frame_duration_buffer,
3305 int frame_duration_buffer_size) {
3307 av_assert0(end_index >= 0 && end_index <= st->nb_index_entries);
3308 for (i = 0; i < frame_duration_buffer_size; i++) {
3309 end_ts -= frame_duration_buffer[frame_duration_buffer_size - 1 - i];
3310 st->index_entries[end_index - 1 - i].timestamp = end_ts;
3315 * Append a new ctts entry to ctts_data.
3316 * Returns the new ctts_count if successful, else returns -1.
3318 static int64_t add_ctts_entry(MOVStts** ctts_data, unsigned int* ctts_count, unsigned int* allocated_size,
3319 int count, int duration)
3321 MOVStts *ctts_buf_new;
3322 const size_t min_size_needed = (*ctts_count + 1) * sizeof(MOVStts);
3323 const size_t requested_size =
3324 min_size_needed > *allocated_size ?
3325 FFMAX(min_size_needed, 2 * (*allocated_size)) :
3328 if ((unsigned)(*ctts_count) >= UINT_MAX / sizeof(MOVStts) - 1)
3331 ctts_buf_new = av_fast_realloc(*ctts_data, allocated_size, requested_size);
3336 *ctts_data = ctts_buf_new;
3338 ctts_buf_new[*ctts_count].count = count;
3339 ctts_buf_new[*ctts_count].duration = duration;
3341 *ctts_count = (*ctts_count) + 1;
3345 #define MAX_REORDER_DELAY 16
3346 static void mov_estimate_video_delay(MOVContext *c, AVStream* st)
3348 MOVStreamContext *msc = st->priv_data;
3351 int ctts_sample = 0;
3352 int64_t pts_buf[MAX_REORDER_DELAY + 1]; // Circular buffer to sort pts.
3354 int j, r, num_swaps;
3356 for (j = 0; j < MAX_REORDER_DELAY + 1; j++)
3357 pts_buf[j] = INT64_MIN;
3359 if (st->codecpar->video_delay <= 0 && msc->ctts_data &&
3360 st->codecpar->codec_id == AV_CODEC_ID_H264) {
3361 st->codecpar->video_delay = 0;
3362 for (ind = 0; ind < st->nb_index_entries && ctts_ind < msc->ctts_count; ++ind) {
3363 // Point j to the last elem of the buffer and insert the current pts there.
3365 buf_start = (buf_start + 1);
3366 if (buf_start == MAX_REORDER_DELAY + 1)
3369 pts_buf[j] = st->index_entries[ind].timestamp + msc->ctts_data[ctts_ind].duration;
3371 // The timestamps that are already in the sorted buffer, and are greater than the
3372 // current pts, are exactly the timestamps that need to be buffered to output PTS
3373 // in correct sorted order.
3374 // Hence the video delay (which is the buffer size used to sort DTS and output PTS),
3375 // can be computed as the maximum no. of swaps any particular timestamp needs to
3376 // go through, to keep this buffer in sorted order.
3378 while (j != buf_start) {
3380 if (r < 0) r = MAX_REORDER_DELAY;
3381 if (pts_buf[j] < pts_buf[r]) {
3382 FFSWAP(int64_t, pts_buf[j], pts_buf[r]);
3389 st->codecpar->video_delay = FFMAX(st->codecpar->video_delay, num_swaps);
3392 if (ctts_sample == msc->ctts_data[ctts_ind].count) {
3397 av_log(c->fc, AV_LOG_DEBUG, "Setting codecpar->delay to %d for stream st: %d\n",
3398 st->codecpar->video_delay, st->index);
3402 static void mov_current_sample_inc(MOVStreamContext *sc)
3404 sc->current_sample++;
3405 sc->current_index++;
3406 if (sc->index_ranges &&
3407 sc->current_index >= sc->current_index_range->end &&
3408 sc->current_index_range->end) {
3409 sc->current_index_range++;
3410 sc->current_index = sc->current_index_range->start;
3414 static void mov_current_sample_dec(MOVStreamContext *sc)
3416 sc->current_sample--;
3417 sc->current_index--;
3418 if (sc->index_ranges &&
3419 sc->current_index < sc->current_index_range->start &&
3420 sc->current_index_range > sc->index_ranges) {
3421 sc->current_index_range--;
3422 sc->current_index = sc->current_index_range->end - 1;
3426 static void mov_current_sample_set(MOVStreamContext *sc, int current_sample)
3430 sc->current_sample = current_sample;
3431 sc->current_index = current_sample;
3432 if (!sc->index_ranges) {
3436 for (sc->current_index_range = sc->index_ranges;
3437 sc->current_index_range->end;
3438 sc->current_index_range++) {
3439 range_size = sc->current_index_range->end - sc->current_index_range->start;
3440 if (range_size > current_sample) {
3441 sc->current_index = sc->current_index_range->start + current_sample;
3444 current_sample -= range_size;
3449 * Fix st->index_entries, so that it contains only the entries (and the entries
3450 * which are needed to decode them) that fall in the edit list time ranges.
3451 * Also fixes the timestamps of the index entries to match the timeline
3452 * specified the edit lists.
3454 static void mov_fix_index(MOVContext *mov, AVStream *st)
3456 MOVStreamContext *msc = st->priv_data;
3457 AVIndexEntry *e_old = st->index_entries;
3458 int nb_old = st->nb_index_entries;
3459 const AVIndexEntry *e_old_end = e_old + nb_old;
3460 const AVIndexEntry *current = NULL;
3461 MOVStts *ctts_data_old = msc->ctts_data;
3462 int64_t ctts_index_old = 0;
3463 int64_t ctts_sample_old = 0;
3464 int64_t ctts_count_old = msc->ctts_count;
3465 int64_t edit_list_media_time = 0;
3466 int64_t edit_list_duration = 0;
3467 int64_t frame_duration = 0;
3468 int64_t edit_list_dts_counter = 0;
3469 int64_t edit_list_dts_entry_end = 0;
3470 int64_t edit_list_start_ctts_sample = 0;
3472 int64_t curr_ctts = 0;
3473 int64_t empty_edits_sum_duration = 0;
3474 int64_t edit_list_index = 0;
3477 int64_t start_dts = 0;
3478 int64_t edit_list_start_encountered = 0;
3479 int64_t search_timestamp = 0;
3480 int64_t* frame_duration_buffer = NULL;
3481 int num_discarded_begin = 0;
3482 int first_non_zero_audio_edit = -1;
3483 int packet_skip_samples = 0;
3484 MOVIndexRange *current_index_range;
3486 int found_keyframe_after_edit = 0;
3487 int found_non_empty_edit = 0;
3489 if (!msc->elst_data || msc->elst_count <= 0 || nb_old <= 0) {
3493 // allocate the index ranges array
3494 msc->index_ranges = av_malloc((msc->elst_count + 1) * sizeof(msc->index_ranges[0]));
3495 if (!msc->index_ranges) {
3496 av_log(mov->fc, AV_LOG_ERROR, "Cannot allocate index ranges buffer\n");
3499 msc->current_index_range = msc->index_ranges;
3500 current_index_range = msc->index_ranges - 1;
3502 // Clean AVStream from traces of old index
3503 st->index_entries = NULL;
3504 st->index_entries_allocated_size = 0;
3505 st->nb_index_entries = 0;
3507 // Clean ctts fields of MOVStreamContext
3508 msc->ctts_data = NULL;
3509 msc->ctts_count = 0;
3510 msc->ctts_index = 0;
3511 msc->ctts_sample = 0;
3512 msc->ctts_allocated_size = 0;
3514 // Reinitialize min_corrected_pts so that it can be computed again.
3515 msc->min_corrected_pts = -1;
3517 // If the dts_shift is positive (in case of negative ctts values in mov),
3518 // then negate the DTS by dts_shift
3519 if (msc->dts_shift > 0) {
3520 edit_list_dts_entry_end -= msc->dts_shift;
3521 av_log(mov->fc, AV_LOG_DEBUG, "Shifting DTS by %d because of negative CTTS.\n", msc->dts_shift);
3524 start_dts = edit_list_dts_entry_end;
3526 while (get_edit_list_entry(mov, msc, edit_list_index, &edit_list_media_time,
3527 &edit_list_duration, mov->time_scale)) {
3528 av_log(mov->fc, AV_LOG_DEBUG, "Processing st: %d, edit list %"PRId64" - media time: %"PRId64", duration: %"PRId64"\n",
3529 st->index, edit_list_index, edit_list_media_time, edit_list_duration);
3531 edit_list_dts_counter = edit_list_dts_entry_end;
3532 edit_list_dts_entry_end += edit_list_duration;
3533 num_discarded_begin = 0;
3534 if (!found_non_empty_edit && edit_list_media_time == -1) {
3535 empty_edits_sum_duration += edit_list_duration;
3538 found_non_empty_edit = 1;
3540 // If we encounter a non-negative edit list reset the skip_samples/start_pad fields and set them
3541 // according to the edit list below.
3542 if (st->codecpar->codec_type == AVMEDIA_TYPE_AUDIO) {
3543 if (first_non_zero_audio_edit < 0) {
3544 first_non_zero_audio_edit = 1;
3546 first_non_zero_audio_edit = 0;
3549 if (first_non_zero_audio_edit > 0)
3550 st->skip_samples = msc->start_pad = 0;
3553 // While reordering frame index according to edit list we must handle properly
3554 // the scenario when edit list entry starts from none key frame.
3555 // We find closest previous key frame and preserve it and consequent frames in index.
3556 // All frames which are outside edit list entry time boundaries will be dropped after decoding.
3557 search_timestamp = edit_list_media_time;
3558 if (st->codecpar->codec_type == AVMEDIA_TYPE_AUDIO) {
3559 // Audio decoders like AAC need need a decoder delay samples previous to the current sample,
3560 // to correctly decode this frame. Hence for audio we seek to a frame 1 sec. before the
3561 // edit_list_media_time to cover the decoder delay.
3562 search_timestamp = FFMAX(search_timestamp - msc->time_scale, e_old[0].timestamp);
3565 if (find_prev_closest_index(st, e_old, nb_old, ctts_data_old, ctts_count_old, search_timestamp, 0,
3566 &index, &ctts_index_old, &ctts_sample_old) < 0) {
3567 av_log(mov->fc, AV_LOG_WARNING,
3568 "st: %d edit list: %"PRId64" Missing key frame while searching for timestamp: %"PRId64"\n",
3569 st->index, edit_list_index, search_timestamp);
3570 if (find_prev_closest_index(st, e_old, nb_old, ctts_data_old, ctts_count_old, search_timestamp, AVSEEK_FLAG_ANY,
3571 &index, &ctts_index_old, &ctts_sample_old) < 0) {
3572 av_log(mov->fc, AV_LOG_WARNING,
3573 "st: %d edit list %"PRId64" Cannot find an index entry before timestamp: %"PRId64".\n",
3574 st->index, edit_list_index, search_timestamp);
3577 ctts_sample_old = 0;
3580 current = e_old + index;
3581 edit_list_start_ctts_sample = ctts_sample_old;
3583 // Iterate over index and arrange it according to edit list
3584 edit_list_start_encountered = 0;
3585 found_keyframe_after_edit = 0;
3586 for (; current < e_old_end; current++, index++) {
3587 // check if frame outside edit list mark it for discard
3588 frame_duration = (current + 1 < e_old_end) ?
3589 ((current + 1)->timestamp - current->timestamp) : edit_list_duration;
3591 flags = current->flags;
3593 // frames (pts) before or after edit list
3594 curr_cts = current->timestamp + msc->dts_shift;
3597 if (ctts_data_old && ctts_index_old < ctts_count_old) {
3598 curr_ctts = ctts_data_old[ctts_index_old].duration;
3599 av_log(mov->fc, AV_LOG_DEBUG, "stts: %"PRId64" ctts: %"PRId64", ctts_index: %"PRId64", ctts_count: %"PRId64"\n",
3600 curr_cts, curr_ctts, ctts_index_old, ctts_count_old);
3601 curr_cts += curr_ctts;
3603 if (ctts_sample_old == ctts_data_old[ctts_index_old].count) {
3604 if (add_ctts_entry(&msc->ctts_data, &msc->ctts_count,
3605 &msc->ctts_allocated_size,
3606 ctts_data_old[ctts_index_old].count - edit_list_start_ctts_sample,
3607 ctts_data_old[ctts_index_old].duration) == -1) {
3608 av_log(mov->fc, AV_LOG_ERROR, "Cannot add CTTS entry %"PRId64" - {%"PRId64", %d}\n",
3610 ctts_data_old[ctts_index_old].count - edit_list_start_ctts_sample,
3611 ctts_data_old[ctts_index_old].duration);
3615 ctts_sample_old = 0;
3616 edit_list_start_ctts_sample = 0;
3620 if (curr_cts < edit_list_media_time || curr_cts >= (edit_list_duration + edit_list_media_time)) {
3621 if (st->codecpar->codec_type == AVMEDIA_TYPE_AUDIO && st->codecpar->codec_id != AV_CODEC_ID_VORBIS &&
3622 curr_cts < edit_list_media_time && curr_cts + frame_duration > edit_list_media_time &&
3623 first_non_zero_audio_edit > 0) {
3624 packet_skip_samples = edit_list_media_time - curr_cts;
3625 st->skip_samples += packet_skip_samples;
3627 // Shift the index entry timestamp by packet_skip_samples to be correct.
3628 edit_list_dts_counter -= packet_skip_samples;
3629 if (edit_list_start_encountered == 0) {
3630 edit_list_start_encountered = 1;
3631 // Make timestamps strictly monotonically increasing for audio, by rewriting timestamps for
3632 // discarded packets.
3633 if (frame_duration_buffer) {
3634 fix_index_entry_timestamps(st, st->nb_index_entries, edit_list_dts_counter,
3635 frame_duration_buffer, num_discarded_begin);
3636 av_freep(&frame_duration_buffer);
3640 av_log(mov->fc, AV_LOG_DEBUG, "skip %d audio samples from curr_cts: %"PRId64"\n", packet_skip_samples, curr_cts);
3642 flags |= AVINDEX_DISCARD_FRAME;
3643 av_log(mov->fc, AV_LOG_DEBUG, "drop a frame at curr_cts: %"PRId64" @ %"PRId64"\n", curr_cts, index);
3645 if (edit_list_start_encountered == 0) {
3646 num_discarded_begin++;
3647 frame_duration_buffer = av_realloc(frame_duration_buffer,
3648 num_discarded_begin * sizeof(int64_t));
3649 if (!frame_duration_buffer) {
3650 av_log(mov->fc, AV_LOG_ERROR, "Cannot reallocate frame duration buffer\n");
3653 frame_duration_buffer[num_discarded_begin - 1] = frame_duration;
3655 // Increment skip_samples for the first non-zero audio edit list
3656 if (st->codecpar->codec_type == AVMEDIA_TYPE_AUDIO &&
3657 first_non_zero_audio_edit > 0 && st->codecpar->codec_id != AV_CODEC_ID_VORBIS) {
3658 st->skip_samples += frame_duration;
3663 if (msc->min_corrected_pts < 0) {
3664 msc->min_corrected_pts = edit_list_dts_counter + curr_ctts + msc->dts_shift;
3666 msc->min_corrected_pts = FFMIN(msc->min_corrected_pts, edit_list_dts_counter + curr_ctts + msc->dts_shift);
3668 if (edit_list_start_encountered == 0) {
3669 edit_list_start_encountered = 1;
3670 // Make timestamps strictly monotonically increasing by rewriting timestamps for
3671 // discarded packets.
3672 if (frame_duration_buffer) {
3673 fix_index_entry_timestamps(st, st->nb_index_entries, edit_list_dts_counter,
3674 frame_duration_buffer, num_discarded_begin);
3675 av_freep(&frame_duration_buffer);
3680 if (add_index_entry(st, current->pos, edit_list_dts_counter, current->size,
3681 current->min_distance, flags) == -1) {
3682 av_log(mov->fc, AV_LOG_ERROR, "Cannot add index entry\n");
3686 // Update the index ranges array
3687 if (current_index_range < msc->index_ranges || index != current_index_range->end) {
3688 current_index_range++;
3689 current_index_range->start = index;
3691 current_index_range->end = index + 1;
3693 // Only start incrementing DTS in frame_duration amounts, when we encounter a frame in edit list.
3694 if (edit_list_start_encountered > 0) {
3695 edit_list_dts_counter = edit_list_dts_counter + frame_duration;
3698 // Break when found first key frame after edit entry completion
3699 if ((curr_cts + frame_duration >= (edit_list_duration + edit_list_media_time)) &&
3700 ((flags & AVINDEX_KEYFRAME) || ((st->codecpar->codec_type == AVMEDIA_TYPE_AUDIO)))) {
3701 if (ctts_data_old) {
3702 // If we have CTTS and this is the first keyframe after edit elist,
3703 // wait for one more, because there might be trailing B-frames after this I-frame
3704 // that do belong to the edit.
3705 if (st->codecpar->codec_type != AVMEDIA_TYPE_AUDIO && found_keyframe_after_edit == 0) {
3706 found_keyframe_after_edit = 1;
3709 if (ctts_sample_old != 0) {
3710 if (add_ctts_entry(&msc->ctts_data, &msc->ctts_count,
3711 &msc->ctts_allocated_size,
3712 ctts_sample_old - edit_list_start_ctts_sample,
3713 ctts_data_old[ctts_index_old].duration) == -1) {
3714 av_log(mov->fc, AV_LOG_ERROR, "Cannot add CTTS entry %"PRId64" - {%"PRId64", %d}\n",
3715 ctts_index_old, ctts_sample_old - edit_list_start_ctts_sample,
3716 ctts_data_old[ctts_index_old].duration);
3725 // If there are empty edits, then msc->min_corrected_pts might be positive
3726 // intentionally. So we subtract the sum duration of emtpy edits here.
3727 msc->min_corrected_pts -= empty_edits_sum_duration;
3729 // If the minimum pts turns out to be greater than zero after fixing the index, then we subtract the
3730 // dts by that amount to make the first pts zero.
3731 if (st->codecpar->codec_type == AVMEDIA_TYPE_VIDEO) {
3732 if (msc->min_corrected_pts > 0) {
3733 av_log(mov->fc, AV_LOG_DEBUG, "Offset DTS by %"PRId64" to make first pts zero.\n", msc->min_corrected_pts);
3734 for (i = 0; i < st->nb_index_entries; ++i) {
3735 st->index_entries[i].timestamp -= msc->min_corrected_pts;
3739 // Start time should be equal to zero or the duration of any empty edits.
3740 st->start_time = empty_edits_sum_duration;
3742 // Update av stream length, if it ends up shorter than the track's media duration
3743 st->duration = FFMIN(st->duration, edit_list_dts_entry_end - start_dts);
3744 msc->start_pad = st->skip_samples;
3746 // Free the old index and the old CTTS structures
3748 av_free(ctts_data_old);
3749 av_freep(&frame_duration_buffer);
3751 // Null terminate the index ranges array
3752 current_index_range++;
3753 current_index_range->start = 0;
3754 current_index_range->end = 0;
3755 msc->current_index = msc->index_ranges[0].start;
3758 static void mov_build_index(MOVContext *mov, AVStream *st)
3760 MOVStreamContext *sc = st->priv_data;
3761 int64_t current_offset;
3762 int64_t current_dts = 0;
3763 unsigned int stts_index = 0;
3764 unsigned int stsc_index = 0;
3765 unsigned int stss_index = 0;
3766 unsigned int stps_index = 0;
3768 uint64_t stream_size = 0;
3769 MOVStts *ctts_data_old = sc->ctts_data;
3770 unsigned int ctts_count_old = sc->ctts_count;
3772 if (sc->elst_count) {
3773 int i, edit_start_index = 0, multiple_edits = 0;
3774 int64_t empty_duration = 0; // empty duration of the first edit list entry
3775 int64_t start_time = 0; // start time of the media
3777 for (i = 0; i < sc->elst_count; i++) {
3778 const MOVElst *e = &sc->elst_data[i];
3779 if (i == 0 && e->time == -1) {
3780 /* if empty, the first entry is the start time of the stream
3781 * relative to the presentation itself */
3782 empty_duration = e->duration;
3783 edit_start_index = 1;
3784 } else if (i == edit_start_index && e->time >= 0) {
3785 start_time = e->time;
3791 if (multiple_edits && !mov->advanced_editlist)
3792 av_log(mov->fc, AV_LOG_WARNING, "multiple edit list entries, "
3793 "Use -advanced_editlist to correctly decode otherwise "
3794 "a/v desync might occur\n");
3796 /* adjust first dts according to edit list */
3797 if ((empty_duration || start_time) && mov->time_scale > 0) {
3799 empty_duration = av_rescale(empty_duration, sc->time_scale, mov->time_scale);
3800 sc->time_offset = start_time - empty_duration;
3801 sc->min_corrected_pts = start_time;
3802 if (!mov->advanced_editlist)
3803 current_dts = -sc->time_offset;
3806 if (!multiple_edits && !mov->advanced_editlist &&
3807 st->codecpar->codec_id == AV_CODEC_ID_AAC && start_time > 0)
3808 sc->start_pad = start_time;
3811 /* only use old uncompressed audio chunk demuxing when stts specifies it */
3812 if (!(st->codecpar->codec_type == AVMEDIA_TYPE_AUDIO &&
3813 sc->stts_count == 1 && sc->stts_data[0].duration == 1)) {
3814 unsigned int current_sample = 0;
3815 unsigned int stts_sample = 0;
3816 unsigned int sample_size;
3817 unsigned int distance = 0;
3818 unsigned int rap_group_index = 0;
3819 unsigned int rap_group_sample = 0;
3820 int64_t last_dts = 0;
3821 int64_t dts_correction = 0;
3822 int rap_group_present = sc->rap_group_count && sc->rap_group;
3823 int key_off = (sc->keyframe_count && sc->keyframes[0] > 0) || (sc->stps_count && sc->stps_data[0] > 0);
3825 current_dts -= sc->dts_shift;
3826 last_dts = current_dts;
3828 if (!sc->sample_count || st->nb_index_entries)
3830 if (sc->sample_count >= UINT_MAX / sizeof(*st->index_entries) - st->nb_index_entries)
3832 if (av_reallocp_array(&st->index_entries,
3833 st->nb_index_entries + sc->sample_count,
3834 sizeof(*st->index_entries)) < 0) {
3835 st->nb_index_entries = 0;
3838 st->index_entries_allocated_size = (st->nb_index_entries + sc->sample_count) * sizeof(*st->index_entries);
3840 if (ctts_data_old) {
3841 // Expand ctts entries such that we have a 1-1 mapping with samples
3842 if (sc->sample_count >= UINT_MAX / sizeof(*sc->ctts_data))
3845 sc->ctts_allocated_size = 0;
3846 sc->ctts_data = av_fast_realloc(NULL, &sc->ctts_allocated_size,
3847 sc->sample_count * sizeof(*sc->ctts_data));
3848 if (!sc->ctts_data) {
3849 av_free(ctts_data_old);
3853 memset((uint8_t*)(sc->ctts_data), 0, sc->ctts_allocated_size);
3855 for (i = 0; i < ctts_count_old &&
3856 sc->ctts_count < sc->sample_count; i++)
3857 for (j = 0; j < ctts_data_old[i].count &&
3858 sc->ctts_count < sc->sample_count; j++)
3859 add_ctts_entry(&sc->ctts_data, &sc->ctts_count,
3860 &sc->ctts_allocated_size, 1,
3861 ctts_data_old[i].duration);
3862 av_free(ctts_data_old);
3865 for (i = 0; i < sc->chunk_count; i++) {
3866 int64_t next_offset = i+1 < sc->chunk_count ? sc->chunk_offsets[i+1] : INT64_MAX;
3867 current_offset = sc->chunk_offsets[i];
3868 while (mov_stsc_index_valid(stsc_index, sc->stsc_count) &&
3869 i + 1 == sc->stsc_data[stsc_index + 1].first)
3872 if (next_offset > current_offset && sc->sample_size>0 && sc->sample_size < sc->stsz_sample_size &&
3873 sc->stsc_data[stsc_index].count * (int64_t)sc->stsz_sample_size > next_offset - current_offset) {
3874 av_log(mov->fc, AV_LOG_WARNING, "STSZ sample size %d invalid (too large), ignoring\n", sc->stsz_sample_size);
3875 sc->stsz_sample_size = sc->sample_size;
3877 if (sc->stsz_sample_size>0 && sc->stsz_sample_size < sc->sample_size) {
3878 av_log(mov->fc, AV_LOG_WARNING, "STSZ sample size %d invalid (too small), ignoring\n", sc->stsz_sample_size);
3879 sc->stsz_sample_size = sc->sample_size;
3882 for (j = 0; j < sc->stsc_data[stsc_index].count; j++) {
3884 if (current_sample >= sc->sample_count) {
3885 av_log(mov->fc, AV_LOG_ERROR, "wrong sample count\n");
3889 if (!sc->keyframe_absent && (!sc->keyframe_count || current_sample+key_off == sc->keyframes[stss_index])) {
3891 if (stss_index + 1 < sc->keyframe_count)
3893 } else if (sc->stps_count && current_sample+key_off == sc->stps_data[stps_index]) {
3895 if (stps_index + 1 < sc->stps_count)
3898 if (rap_group_present && rap_group_index < sc->rap_group_count) {
3899 if (sc->rap_group[rap_group_index].index > 0)
3901 if (++rap_group_sample == sc->rap_group[rap_group_index].count) {
3902 rap_group_sample = 0;
3906 if (sc->keyframe_absent
3908 && !rap_group_present
3909 && (st->codecpar->codec_type == AVMEDIA_TYPE_AUDIO || (i==0 && j==0)))
3913 sample_size = sc->stsz_sample_size > 0 ? sc->stsz_sample_size : sc->sample_sizes[current_sample];
3914 if (sc->pseudo_stream_id == -1 ||
3915 sc->stsc_data[stsc_index].id - 1 == sc->pseudo_stream_id) {
3917 if (sample_size > 0x3FFFFFFF) {
3918 av_log(mov->fc, AV_LOG_ERROR, "Sample size %u is too large\n", sample_size);
3921 e = &st->index_entries[st->nb_index_entries++];
3922 e->pos = current_offset;
3923 e->timestamp = current_dts;
3924 e->size = sample_size;
3925 e->min_distance = distance;
3926 e->flags = keyframe ? AVINDEX_KEYFRAME : 0;
3927 av_log(mov->fc, AV_LOG_TRACE, "AVIndex stream %d, sample %u, offset %"PRIx64", dts %"PRId64", "
3928 "size %u, distance %u, keyframe %d\n", st->index, current_sample,
3929 current_offset, current_dts, sample_size, distance, keyframe);
3930 if (st->codecpar->codec_type == AVMEDIA_TYPE_VIDEO && st->nb_index_entries < 100)
3931 ff_rfps_add_frame(mov->fc, st, current_dts);
3934 current_offset += sample_size;
3935 stream_size += sample_size;
3937 /* A negative sample duration is invalid based on the spec,
3938 * but some samples need it to correct the DTS. */
3939 if (sc->stts_data[stts_index].duration < 0) {
3940 av_log(mov->fc, AV_LOG_WARNING,
3941 "Invalid SampleDelta %d in STTS, at %d st:%d\n",
3942 sc->stts_data[stts_index].duration, stts_index,
3944 dts_correction += sc->stts_data[stts_index].duration - 1;
3945 sc->stts_data[stts_index].duration = 1;
3947 current_dts += sc->stts_data[stts_index].duration;
3948 if (!dts_correction || current_dts + dts_correction > last_dts) {
3949 current_dts += dts_correction;
3952 /* Avoid creating non-monotonous DTS */
3953 dts_correction += current_dts - last_dts - 1;
3954 current_dts = last_dts + 1;
3956 last_dts = current_dts;
3960 if (stts_index + 1 < sc->stts_count && stts_sample == sc->stts_data[stts_index].count) {
3966 if (st->duration > 0)
3967 st->codecpar->bit_rate = stream_size*8*sc->time_scale/st->duration;
3969 unsigned chunk_samples, total = 0;
3971 if (!sc->chunk_count)
3974 // compute total chunk count
3975 for (i = 0; i < sc->stsc_count; i++) {
3976 unsigned count, chunk_count;
3978 chunk_samples = sc->stsc_data[i].count;
3979 if (i != sc->stsc_count - 1 &&
3980 sc->samples_per_frame && chunk_samples % sc->samples_per_frame) {
3981 av_log(mov->fc, AV_LOG_ERROR, "error unaligned chunk\n");
3985 if (sc->samples_per_frame >= 160) { // gsm
3986 count = chunk_samples / sc->samples_per_frame;
3987 } else if (sc->samples_per_frame > 1) {
3988 unsigned samples = (1024/sc->samples_per_frame)*sc->samples_per_frame;
3989 count = (chunk_samples+samples-1) / samples;
3991 count = (chunk_samples+1023) / 1024;
3994 if (mov_stsc_index_valid(i, sc->stsc_count))
3995 chunk_count = sc->stsc_data[i+1].first - sc->stsc_data[i].first;
3997 chunk_count = sc->chunk_count - (sc->stsc_data[i].first - 1);
3998 total += chunk_count * count;
4001 av_log(mov->fc, AV_LOG_TRACE, "chunk count %u\n", total);
4002 if (total >= UINT_MAX / sizeof(*st->index_entries) - st->nb_index_entries)
4004 if (av_reallocp_array(&st->index_entries,
4005 st->nb_index_entries + total,
4006 sizeof(*st->index_entries)) < 0) {
4007 st->nb_index_entries = 0;
4010 st->index_entries_allocated_size = (st->nb_index_entries + total) * sizeof(*st->index_entries);
4013 for (i = 0; i < sc->chunk_count; i++) {
4014 current_offset = sc->chunk_offsets[i];
4015 if (mov_stsc_index_valid(stsc_index, sc->stsc_count) &&
4016 i + 1 == sc->stsc_data[stsc_index + 1].first)
4018 chunk_samples = sc->stsc_data[stsc_index].count;
4020 while (chunk_samples > 0) {
4022 unsigned size, samples;
4024 if (sc->samples_per_frame > 1 && !sc->bytes_per_frame) {
4025 avpriv_request_sample(mov->fc,
4026 "Zero bytes per frame, but %d samples per frame",
4027 sc->samples_per_frame);
4031 if (sc->samples_per_frame >= 160) { // gsm
4032 samples = sc->samples_per_frame;
4033 size = sc->bytes_per_frame;
4035 if (sc->samples_per_frame > 1) {
4036 samples = FFMIN((1024 / sc->samples_per_frame)*
4037 sc->samples_per_frame, chunk_samples);
4038 size = (samples / sc->samples_per_frame) * sc->bytes_per_frame;
4040 samples = FFMIN(1024, chunk_samples);
4041 size = samples * sc->sample_size;
4045 if (st->nb_index_entries >= total) {
4046 av_log(mov->fc, AV_LOG_ERROR, "wrong chunk count %u\n", total);
4049 if (size > 0x3FFFFFFF) {
4050 av_log(mov->fc, AV_LOG_ERROR, "Sample size %u is too large\n", size);
4053 e = &st->index_entries[st->nb_index_entries++];
4054 e->pos = current_offset;
4055 e->timestamp = current_dts;
4057 e->min_distance = 0;
4058 e->flags = AVINDEX_KEYFRAME;
4059 av_log(mov->fc, AV_LOG_TRACE, "AVIndex stream %d, chunk %u, offset %"PRIx64", dts %"PRId64", "
4060 "size %u, duration %u\n", st->index, i, current_offset, current_dts,
4063 current_offset += size;
4064 current_dts += samples;
4065 chunk_samples -= samples;
4070 if (!mov->ignore_editlist && mov->advanced_editlist) {
4071 // Fix index according to edit lists.
4072 mov_fix_index(mov, st);
4075 // Update start time of the stream.
4076 if (st->start_time == AV_NOPTS_VALUE && st->codecpar->codec_type == AVMEDIA_TYPE_VIDEO && st->nb_index_entries > 0) {
4077 st->start_time = st->index_entries[0].timestamp + sc->dts_shift;
4078 if (sc->ctts_data) {
4079 st->start_time += sc->ctts_data[0].duration;
4083 mov_estimate_video_delay(mov, st);
4086 static int test_same_origin(const char *src, const char *ref) {
4096 av_url_split(src_proto, sizeof(src_proto), src_auth, sizeof(src_auth), src_host, sizeof(src_host), &src_port, NULL, 0, src);
4097 av_url_split(ref_proto, sizeof(ref_proto), ref_auth, sizeof(ref_auth), ref_host, sizeof(ref_host), &ref_port, NULL, 0, ref);
4099 if (strlen(src) == 0) {
4101 } else if (strlen(src_auth) + 1 >= sizeof(src_auth) ||
4102 strlen(ref_auth) + 1 >= sizeof(ref_auth) ||
4103 strlen(src_host) + 1 >= sizeof(src_host) ||
4104 strlen(ref_host) + 1 >= sizeof(ref_host)) {
4106 } else if (strcmp(src_proto, ref_proto) ||
4107 strcmp(src_auth, ref_auth) ||
4108 strcmp(src_host, ref_host) ||
4109 src_port != ref_port) {
4115 static int mov_open_dref(MOVContext *c, AVIOContext **pb, const char *src, MOVDref *ref)
4117 /* try relative path, we do not try the absolute because it can leak information about our
4118 system to an attacker */
4119 if (ref->nlvl_to > 0 && ref->nlvl_from > 0) {
4120 char filename[1025];
4121 const char *src_path;
4124 /* find a source dir */
4125 src_path = strrchr(src, '/');
4131 /* find a next level down to target */
4132 for (i = 0, l = strlen(ref->path) - 1; l >= 0; l--)
4133 if (ref->path[l] == '/') {
4134 if (i == ref->nlvl_to - 1)
4140 /* compose filename if next level down to target was found */
4141 if (i == ref->nlvl_to - 1 && src_path - src < sizeof(filename)) {
4142 memcpy(filename, src, src_path - src);
4143 filename[src_path - src] = 0;
4145 for (i = 1; i < ref->nlvl_from; i++)
4146 av_strlcat(filename, "../", sizeof(filename));
4148 av_strlcat(filename, ref->path + l + 1, sizeof(filename));
4149 if (!c->use_absolute_path) {
4150 int same_origin = test_same_origin(src, filename);
4153 av_log(c->fc, AV_LOG_ERROR,
4154 "Reference with mismatching origin, %s not tried for security reasons, "
4155 "set demuxer option use_absolute_path to allow it anyway\n",
4157 return AVERROR(ENOENT);
4160 if (strstr(ref->path + l + 1, "..") ||
4161 strstr(ref->path + l + 1, ":") ||
4162 (ref->nlvl_from > 1 && same_origin < 0) ||
4163 (filename[0] == '/' && src_path == src))
4164 return AVERROR(ENOENT);
4167 if (strlen(filename) + 1 == sizeof(filename))
4168 return AVERROR(ENOENT);
4169 if (!c->fc->io_open(c->fc, pb, filename, AVIO_FLAG_READ, NULL))
4172 } else if (c->use_absolute_path) {
4173 av_log(c->fc, AV_LOG_WARNING, "Using absolute path on user request, "
4174 "this is a possible security issue\n");
4175 if (!c->fc->io_open(c->fc, pb, ref->path, AVIO_FLAG_READ, NULL))
4178 av_log(c->fc, AV_LOG_ERROR,
4179 "Absolute path %s not tried for security reasons, "
4180 "set demuxer option use_absolute_path to allow absolute paths\n",
4184 return AVERROR(ENOENT);
4187 static void fix_timescale(MOVContext *c, MOVStreamContext *sc)
4189 if (sc->time_scale <= 0) {
4190 av_log(c->fc, AV_LOG_WARNING, "stream %d, timescale not set\n", sc->ffindex);
4191 sc->time_scale = c->time_scale;
4192 if (sc->time_scale <= 0)
4197 static int mov_read_trak(MOVContext *c, AVIOContext *pb, MOVAtom atom)
4200 MOVStreamContext *sc;
4203 st = avformat_new_stream(c->fc, NULL);
4204 if (!st) return AVERROR(ENOMEM);
4206 sc = av_mallocz(sizeof(MOVStreamContext));
4207 if (!sc) return AVERROR(ENOMEM);
4210 st->codecpar->codec_type = AVMEDIA_TYPE_DATA;
4211 sc->ffindex = st->index;
4212 c->trak_index = st->index;
4214 if ((ret = mov_read_default(c, pb, atom)) < 0)
4219 // Here stsc refers to a chunk not described in stco. This is technically invalid,
4220 // but we can overlook it (clearing stsc) whenever stts_count == 0 (indicating no samples).
4221 if (!sc->chunk_count && !sc->stts_count && sc->stsc_count) {
4223 av_freep(&sc->stsc_data);
4227 if ((sc->chunk_count && (!sc->stts_count || !sc->stsc_count ||
4228 (!sc->sample_size && !sc->sample_count))) ||
4229 (!sc->chunk_count && sc->sample_count)) {
4230 av_log(c->fc, AV_LOG_ERROR, "stream %d, missing mandatory atoms, broken header\n",
4234 if (sc->stsc_count && sc->stsc_data[ sc->stsc_count - 1 ].first > sc->chunk_count) {
4235 av_log(c->fc, AV_LOG_ERROR, "stream %d, contradictionary STSC and STCO\n",
4237 return AVERROR_INVALIDDATA;
4240 fix_timescale(c, sc);
4242 avpriv_set_pts_info(st, 64, 1, sc->time_scale);
4244 mov_build_index(c, st);
4246 if (sc->dref_id-1 < sc->drefs_count && sc->drefs[sc->dref_id-1].path) {
4247 MOVDref *dref = &sc->drefs[sc->dref_id - 1];
4248 if (c->enable_drefs) {
4249 if (mov_open_dref(c, &sc->pb, c->fc->url, dref) < 0)
4250 av_log(c->fc, AV_LOG_ERROR,
4251 "stream %d, error opening alias: path='%s', dir='%s', "
4252 "filename='%s', volume='%s', nlvl_from=%d, nlvl_to=%d\n",
4253 st->index, dref->path, dref->dir, dref->filename,
4254 dref->volume, dref->nlvl_from, dref->nlvl_to);
4256 av_log(c->fc, AV_LOG_WARNING,
4257 "Skipped opening external track: "
4258 "stream %d, alias: path='%s', dir='%s', "
4259 "filename='%s', volume='%s', nlvl_from=%d, nlvl_to=%d."
4260 "Set enable_drefs to allow this.\n",
4261 st->index, dref->path, dref->dir, dref->filename,
4262 dref->volume, dref->nlvl_from, dref->nlvl_to);
4266 sc->pb_is_copied = 1;
4269 if (st->codecpar->codec_type == AVMEDIA_TYPE_VIDEO) {
4270 if (!st->sample_aspect_ratio.num && st->codecpar->width && st->codecpar->height &&
4271 sc->height && sc->width &&
4272 (st->codecpar->width != sc->width || st->codecpar->height != sc->height)) {
4273 st->sample_aspect_ratio = av_d2q(((double)st->codecpar->height * sc->width) /
4274 ((double)st->codecpar->width * sc->height), INT_MAX);
4277 #if FF_API_R_FRAME_RATE
4278 if (sc->stts_count == 1 || (sc->stts_count == 2 && sc->stts_data[1].count == 1))
4279 av_reduce(&st->r_frame_rate.num, &st->r_frame_rate.den,
4280 sc->time_scale, sc->stts_data[0].duration, INT_MAX);
4284 // done for ai5q, ai52, ai55, ai1q, ai12 and ai15.
4285 if (!st->codecpar->extradata_size && st->codecpar->codec_id == AV_CODEC_ID_H264 &&
4286 TAG_IS_AVCI(st->codecpar->codec_tag)) {
4287 ret = ff_generate_avci_extradata(st);
4292 switch (st->codecpar->codec_id) {
4293 #if CONFIG_H261_DECODER
4294 case AV_CODEC_ID_H261:
4296 #if CONFIG_H263_DECODER
4297 case AV_CODEC_ID_H263:
4299 #if CONFIG_MPEG4_DECODER
4300 case AV_CODEC_ID_MPEG4:
4302 st->codecpar->width = 0; /* let decoder init width/height */
4303 st->codecpar->height= 0;
4307 // If the duration of the mp3 packets is not constant, then they could need a parser
4308 if (st->codecpar->codec_id == AV_CODEC_ID_MP3
4309 && sc->stts_count > 3
4310 && sc->stts_count*10 > st->nb_frames
4311 && sc->time_scale == st->codecpar->sample_rate) {
4312 st->need_parsing = AVSTREAM_PARSE_FULL;
4314 /* Do not need those anymore. */
4315 av_freep(&sc->chunk_offsets);
4316 av_freep(&sc->sample_sizes);
4317 av_freep(&sc->keyframes);
4318 av_freep(&sc->stts_data);
4319 av_freep(&sc->stps_data);
4320 av_freep(&sc->elst_data);
4321 av_freep(&sc->rap_group);
4326 static int mov_read_ilst(MOVContext *c, AVIOContext *pb, MOVAtom atom)
4329 c->itunes_metadata = 1;
4330 ret = mov_read_default(c, pb, atom);
4331 c->itunes_metadata = 0;
4335 static int mov_read_keys(MOVContext *c, AVIOContext *pb, MOVAtom atom)
4344 count = avio_rb32(pb);
4345 if (count > UINT_MAX / sizeof(*c->meta_keys) - 1) {
4346 av_log(c->fc, AV_LOG_ERROR,
4347 "The 'keys' atom with the invalid key count: %"PRIu32"\n", count);
4348 return AVERROR_INVALIDDATA;
4351 c->meta_keys_count = count + 1;
4352 c->meta_keys = av_mallocz(c->meta_keys_count * sizeof(*c->meta_keys));
4354 return AVERROR(ENOMEM);
4356 for (i = 1; i <= count; ++i) {
4357 uint32_t key_size = avio_rb32(pb);
4358 uint32_t type = avio_rl32(pb);
4360 av_log(c->fc, AV_LOG_ERROR,
4361 "The key# %"PRIu32" in meta has invalid size:"
4362 "%"PRIu32"\n", i, key_size);
4363 return AVERROR_INVALIDDATA;
4366 if (type != MKTAG('m','d','t','a')) {
4367 avio_skip(pb, key_size);
4369 c->meta_keys[i] = av_mallocz(key_size + 1);
4370 if (!c->meta_keys[i])
4371 return AVERROR(ENOMEM);
4372 avio_read(pb, c->meta_keys[i], key_size);
4378 static int mov_read_custom(MOVContext *c, AVIOContext *pb, MOVAtom atom)
4380 int64_t end = avio_tell(pb) + atom.size;
4381 uint8_t *key = NULL, *val = NULL, *mean = NULL;
4385 MOVStreamContext *sc;
4387 if (c->fc->nb_streams < 1)
4389 st = c->fc->streams[c->fc->nb_streams-1];
4392 for (i = 0; i < 3; i++) {
4396 if (end - avio_tell(pb) <= 12)
4399 len = avio_rb32(pb);
4400 tag = avio_rl32(pb);
4401 avio_skip(pb, 4); // flags
4403 if (len < 12 || len - 12 > end - avio_tell(pb))
4407 if (tag == MKTAG('m', 'e', 'a', 'n'))
4409 else if (tag == MKTAG('n', 'a', 'm', 'e'))
4411 else if (tag == MKTAG('d', 'a', 't', 'a') && len > 4) {
4421 *p = av_malloc(len + 1);
4423 ret = AVERROR(ENOMEM);
4426 ret = ffio_read_size(pb, *p, len);
4434 if (mean && key && val) {
4435 if (strcmp(key, "iTunSMPB") == 0) {
4436 int priming, remainder, samples;
4437 if(sscanf(val, "%*X %X %X %X", &priming, &remainder, &samples) == 3){
4438 if(priming>0 && priming<16384)
4439 sc->start_pad = priming;
4442 if (strcmp(key, "cdec") != 0) {
4443 av_dict_set(&c->fc->metadata, key, val,
4444 AV_DICT_DONT_STRDUP_KEY | AV_DICT_DONT_STRDUP_VAL);
4448 av_log(c->fc, AV_LOG_VERBOSE,
4449 "Unhandled or malformed custom metadata of size %"PRId64"\n", atom.size);
4452 avio_seek(pb, end, SEEK_SET);
4459 static int mov_read_meta(MOVContext *c, AVIOContext *pb, MOVAtom atom)
4461 while (atom.size > 8) {
4465 tag = avio_rl32(pb);
4467 if (tag == MKTAG('h','d','l','r')) {
4468 avio_seek(pb, -8, SEEK_CUR);
4470 return mov_read_default(c, pb, atom);
4476 // return 1 when matrix is identity, 0 otherwise
4477 #define IS_MATRIX_IDENT(matrix) \
4478 ( (matrix)[0][0] == (1 << 16) && \
4479 (matrix)[1][1] == (1 << 16) && \
4480 (matrix)[2][2] == (1 << 30) && \
4481 !(matrix)[0][1] && !(matrix)[0][2] && \
4482 !(matrix)[1][0] && !(matrix)[1][2] && \
4483 !(matrix)[2][0] && !(matrix)[2][1])
4485 static int mov_read_tkhd(MOVContext *c, AVIOContext *pb, MOVAtom atom)
4490 int display_matrix[3][3];
4491 int res_display_matrix[3][3] = { { 0 } };
4493 MOVStreamContext *sc;
4497 if (c->fc->nb_streams < 1)
4499 st = c->fc->streams[c->fc->nb_streams-1];
4502 // Each stream (trak) should have exactly 1 tkhd. This catches bad files and
4503 // avoids corrupting AVStreams mapped to an earlier tkhd.
4505 return AVERROR_INVALIDDATA;
4507 version = avio_r8(pb);
4508 flags = avio_rb24(pb);
4509 st->disposition |= (flags & MOV_TKHD_FLAG_ENABLED) ? AV_DISPOSITION_DEFAULT : 0;
4515 avio_rb32(pb); /* creation time */
4516 avio_rb32(pb); /* modification time */
4518 st->id = (int)avio_rb32(pb); /* track id (NOT 0 !)*/
4519 avio_rb32(pb); /* reserved */
4521 /* highlevel (considering edits) duration in movie timebase */
4522 (version == 1) ? avio_rb64(pb) : avio_rb32(pb);
4523 avio_rb32(pb); /* reserved */
4524 avio_rb32(pb); /* reserved */
4526 avio_rb16(pb); /* layer */
4527 avio_rb16(pb); /* alternate group */
4528 avio_rb16(pb); /* volume */
4529 avio_rb16(pb); /* reserved */
4531 //read in the display matrix (outlined in ISO 14496-12, Section 6.2.2)
4532 // they're kept in fixed point format through all calculations
4533 // save u,v,z to store the whole matrix in the AV_PKT_DATA_DISPLAYMATRIX
4534 // side data, but the scale factor is not needed to calculate aspect ratio
4535 for (i = 0; i < 3; i++) {
4536 display_matrix[i][0] = avio_rb32(pb); // 16.16 fixed point
4537 display_matrix[i][1] = avio_rb32(pb); // 16.16 fixed point
4538 display_matrix[i][2] = avio_rb32(pb); // 2.30 fixed point
4541 width = avio_rb32(pb); // 16.16 fixed point track width
4542 height = avio_rb32(pb); // 16.16 fixed point track height
4543 sc->width = width >> 16;
4544 sc->height = height >> 16;
4546 // apply the moov display matrix (after the tkhd one)
4547 for (i = 0; i < 3; i++) {
4548 const int sh[3] = { 16, 16, 30 };
4549 for (j = 0; j < 3; j++) {
4550 for (e = 0; e < 3; e++) {
4551 res_display_matrix[i][j] +=
4552 ((int64_t) display_matrix[i][e] *
4553 c->movie_display_matrix[e][j]) >> sh[e];
4558 // save the matrix when it is not the default identity
4559 if (!IS_MATRIX_IDENT(res_display_matrix)) {
4562 av_freep(&sc->display_matrix);
4563 sc->display_matrix = av_malloc(sizeof(int32_t) * 9);
4564 if (!sc->display_matrix)
4565 return AVERROR(ENOMEM);
4567 for (i = 0; i < 3; i++)
4568 for (j = 0; j < 3; j++)
4569 sc->display_matrix[i * 3 + j] = res_display_matrix[i][j];
4571 #if FF_API_OLD_ROTATE_API
4572 rotate = av_display_rotation_get(sc->display_matrix);
4573 if (!isnan(rotate)) {
4574 char rotate_buf[64];
4576 if (rotate < 0) // for backward compatibility
4578 snprintf(rotate_buf, sizeof(rotate_buf), "%g", rotate);
4579 av_dict_set(&st->metadata, "rotate", rotate_buf, 0);
4584 // transform the display width/height according to the matrix
4585 // to keep the same scale, use [width height 1<<16]
4586 if (width && height && sc->display_matrix) {
4587 double disp_transform[2];
4589 for (i = 0; i < 2; i++)
4590 disp_transform[i] = hypot(sc->display_matrix[0 + i],
4591 sc->display_matrix[3 + i]);
4593 if (disp_transform[0] > 0 && disp_transform[1] > 0 &&
4594 disp_transform[0] < (1<<24) && disp_transform[1] < (1<<24) &&
4595 fabs((disp_transform[0] / disp_transform[1]) - 1.0) > 0.01)
4596 st->sample_aspect_ratio = av_d2q(
4597 disp_transform[0] / disp_transform[1],
4603 static int mov_read_tfhd(MOVContext *c, AVIOContext *pb, MOVAtom atom)
4605 MOVFragment *frag = &c->fragment;
4606 MOVTrackExt *trex = NULL;
4607 int flags, track_id, i;
4608 MOVFragmentStreamInfo * frag_stream_info;
4610 avio_r8(pb); /* version */
4611 flags = avio_rb24(pb);
4613 track_id = avio_rb32(pb);
4615 return AVERROR_INVALIDDATA;
4616 for (i = 0; i < c->trex_count; i++)
4617 if (c->trex_data[i].track_id == track_id) {
4618 trex = &c->trex_data[i];
4622 av_log(c->fc, AV_LOG_WARNING, "could not find corresponding trex (id %u)\n", track_id);
4625 c->fragment.found_tfhd = 1;
4626 frag->track_id = track_id;
4627 set_frag_stream(&c->frag_index, track_id);
4629 frag->base_data_offset = flags & MOV_TFHD_BASE_DATA_OFFSET ?
4630 avio_rb64(pb) : flags & MOV_TFHD_DEFAULT_BASE_IS_MOOF ?
4631 frag->moof_offset : frag->implicit_offset;
4632 frag->stsd_id = flags & MOV_TFHD_STSD_ID ? avio_rb32(pb) : trex->stsd_id;
4634 frag->duration = flags & MOV_TFHD_DEFAULT_DURATION ?
4635 avio_rb32(pb) : trex->duration;
4636 frag->size = flags & MOV_TFHD_DEFAULT_SIZE ?
4637 avio_rb32(pb) : trex->size;
4638 frag->flags = flags & MOV_TFHD_DEFAULT_FLAGS ?
4639 avio_rb32(pb) : trex->flags;
4640 av_log(c->fc, AV_LOG_TRACE, "frag flags 0x%x\n", frag->flags);
4642 frag_stream_info = get_current_frag_stream_info(&c->frag_index);
4643 if (frag_stream_info)
4644 frag_stream_info->next_trun_dts = AV_NOPTS_VALUE;
4649 static int mov_read_chap(MOVContext *c, AVIOContext *pb, MOVAtom atom)
4654 num = atom.size / 4;
4655 if (!(new_tracks = av_malloc_array(num, sizeof(int))))
4656 return AVERROR(ENOMEM);
4658 av_free(c->chapter_tracks);
4659 c->chapter_tracks = new_tracks;
4660 c->nb_chapter_tracks = num;
4662 for (i = 0; i < num && !pb->eof_reached; i++)
4663 c->chapter_tracks[i] = avio_rb32(pb);
4668 static int mov_read_trex(MOVContext *c, AVIOContext *pb, MOVAtom atom)
4673 if ((uint64_t)c->trex_count+1 >= UINT_MAX / sizeof(*c->trex_data))
4674 return AVERROR_INVALIDDATA;
4675 if ((err = av_reallocp_array(&c->trex_data, c->trex_count + 1,
4676 sizeof(*c->trex_data))) < 0) {
4681 c->fc->duration = AV_NOPTS_VALUE; // the duration from mvhd is not representing the whole file when fragments are used.
4683 trex = &c->trex_data[c->trex_count++];
4684 avio_r8(pb); /* version */
4685 avio_rb24(pb); /* flags */
4686 trex->track_id = avio_rb32(pb);
4687 trex->stsd_id = avio_rb32(pb);
4688 trex->duration = avio_rb32(pb);
4689 trex->size = avio_rb32(pb);
4690 trex->flags = avio_rb32(pb);
4694 static int mov_read_tfdt(MOVContext *c, AVIOContext *pb, MOVAtom atom)
4696 MOVFragment *frag = &c->fragment;
4697 AVStream *st = NULL;
4698 MOVStreamContext *sc;
4700 MOVFragmentStreamInfo * frag_stream_info;
4701 int64_t base_media_decode_time;
4703 for (i = 0; i < c->fc->nb_streams; i++) {
4704 if (c->fc->streams[i]->id == frag->track_id) {
4705 st = c->fc->streams[i];
4710 av_log(c->fc, AV_LOG_WARNING, "could not find corresponding track id %u\n", frag->track_id);
4714 if (sc->pseudo_stream_id + 1 != frag->stsd_id && sc->pseudo_stream_id != -1)
4716 version = avio_r8(pb);
4717 avio_rb24(pb); /* flags */
4719 base_media_decode_time = avio_rb64(pb);
4721 base_media_decode_time = avio_rb32(pb);
4724 frag_stream_info = get_current_frag_stream_info(&c->frag_index);
4725 if (frag_stream_info)
4726 frag_stream_info->tfdt_dts = base_media_decode_time;
4727 sc->track_end = base_media_decode_time;
4732 static int mov_read_trun(MOVContext *c, AVIOContext *pb, MOVAtom atom)
4734 MOVFragment *frag = &c->fragment;
4735 AVStream *st = NULL;
4736 MOVStreamContext *sc;
4739 int64_t dts, pts = AV_NOPTS_VALUE;
4740 int data_offset = 0;
4741 unsigned entries, first_sample_flags = frag->flags;
4742 int flags, distance, i;
4743 int64_t prev_dts = AV_NOPTS_VALUE;
4744 int next_frag_index = -1, index_entry_pos;
4745 size_t requested_size;
4746 size_t old_ctts_allocated_size;
4747 AVIndexEntry *new_entries;
4748 MOVFragmentStreamInfo * frag_stream_info;
4750 if (!frag->found_tfhd) {
4751 av_log(c->fc, AV_LOG_ERROR, "trun track id unknown, no tfhd was found\n");
4752 return AVERROR_INVALIDDATA;
4755 for (i = 0; i < c->fc->nb_streams; i++) {
4756 if (c->fc->streams[i]->id == frag->track_id) {
4757 st = c->fc->streams[i];
4762 av_log(c->fc, AV_LOG_WARNING, "could not find corresponding track id %u\n", frag->track_id);
4766 if (sc->pseudo_stream_id+1 != frag->stsd_id && sc->pseudo_stream_id != -1)
4769 // Find the next frag_index index that has a valid index_entry for
4770 // the current track_id.
4772 // A valid index_entry means the trun for the fragment was read
4773 // and it's samples are in index_entries at the given position.
4774 // New index entries will be inserted before the index_entry found.
4775 index_entry_pos = st->nb_index_entries;
4776 for (i = c->frag_index.current + 1; i < c->frag_index.nb_items; i++) {
4777 frag_stream_info = get_frag_stream_info(&c->frag_index, i, frag->track_id);
4778 if (frag_stream_info && frag_stream_info->index_entry >= 0) {
4779 next_frag_index = i;
4780 index_entry_pos = frag_stream_info->index_entry;
4784 av_assert0(index_entry_pos <= st->nb_index_entries);
4786 avio_r8(pb); /* version */
4787 flags = avio_rb24(pb);
4788 entries = avio_rb32(pb);
4789 av_log(c->fc, AV_LOG_TRACE, "flags 0x%x entries %u\n", flags, entries);
4791 if ((uint64_t)entries+sc->ctts_count >= UINT_MAX/sizeof(*sc->ctts_data))
4792 return AVERROR_INVALIDDATA;
4793 if (flags & MOV_TRUN_DATA_OFFSET) data_offset = avio_rb32(pb);
4794 if (flags & MOV_TRUN_FIRST_SAMPLE_FLAGS) first_sample_flags = avio_rb32(pb);
4796 frag_stream_info = get_current_frag_stream_info(&c->frag_index);
4797 if (frag_stream_info) {
4798 if (frag_stream_info->next_trun_dts != AV_NOPTS_VALUE) {
4799 dts = frag_stream_info->next_trun_dts - sc->time_offset;
4800 } else if (frag_stream_info->first_tfra_pts != AV_NOPTS_VALUE &&
4801 c->use_mfra_for == FF_MOV_FLAG_MFRA_PTS) {
4802 pts = frag_stream_info->first_tfra_pts;
4803 av_log(c->fc, AV_LOG_DEBUG, "found mfra time %"PRId64
4804 ", using it for pts\n", pts);
4805 } else if (frag_stream_info->first_tfra_pts != AV_NOPTS_VALUE &&
4806 c->use_mfra_for == FF_MOV_FLAG_MFRA_DTS) {
4807 dts = frag_stream_info->first_tfra_pts;
4808 av_log(c->fc, AV_LOG_DEBUG, "found mfra time %"PRId64
4809 ", using it for dts\n", pts);
4810 } else if (frag_stream_info->sidx_pts != AV_NOPTS_VALUE) {
4811 // FIXME: sidx earliest_presentation_time is *PTS*, s.b.
4812 // pts = frag_stream_info->sidx_pts;
4813 dts = frag_stream_info->sidx_pts - sc->time_offset;
4814 av_log(c->fc, AV_LOG_DEBUG, "found sidx time %"PRId64
4815 ", using it for pts\n", pts);
4816 } else if (frag_stream_info->tfdt_dts != AV_NOPTS_VALUE) {
4817 dts = frag_stream_info->tfdt_dts - sc->time_offset;
4818 av_log(c->fc, AV_LOG_DEBUG, "found tfdt time %"PRId64
4819 ", using it for dts\n", dts);
4821 dts = sc->track_end - sc->time_offset;
4822 av_log(c->fc, AV_LOG_DEBUG, "found track end time %"PRId64
4823 ", using it for dts\n", dts);
4826 dts = sc->track_end - sc->time_offset;
4827 av_log(c->fc, AV_LOG_DEBUG, "found track end time %"PRId64
4828 ", using it for dts\n", dts);
4830 offset = frag->base_data_offset + data_offset;
4832 av_log(c->fc, AV_LOG_TRACE, "first sample flags 0x%x\n", first_sample_flags);
4834 // realloc space for new index entries
4835 if((uint64_t)st->nb_index_entries + entries >= UINT_MAX / sizeof(AVIndexEntry)) {
4836 entries = UINT_MAX / sizeof(AVIndexEntry) - st->nb_index_entries;
4837 av_log(c->fc, AV_LOG_ERROR, "Failed to add index entry\n");
4842 requested_size = (st->nb_index_entries + entries) * sizeof(AVIndexEntry);
4843 new_entries = av_fast_realloc(st->index_entries,
4844 &st->index_entries_allocated_size,
4847 return AVERROR(ENOMEM);
4848 st->index_entries= new_entries;
4850 requested_size = (st->nb_index_entries + entries) * sizeof(*sc->ctts_data);
4851 old_ctts_allocated_size = sc->ctts_allocated_size;
4852 ctts_data = av_fast_realloc(sc->ctts_data, &sc->ctts_allocated_size,
4855 return AVERROR(ENOMEM);
4856 sc->ctts_data = ctts_data;
4858 // In case there were samples without ctts entries, ensure they get
4859 // zero valued entries. This ensures clips which mix boxes with and
4860 // without ctts entries don't pickup uninitialized data.
4861 memset((uint8_t*)(sc->ctts_data) + old_ctts_allocated_size, 0,
4862 sc->ctts_allocated_size - old_ctts_allocated_size);
4864 if (index_entry_pos < st->nb_index_entries) {
4865 // Make hole in index_entries and ctts_data for new samples
4866 memmove(st->index_entries + index_entry_pos + entries,
4867 st->index_entries + index_entry_pos,
4868 sizeof(*st->index_entries) *
4869 (st->nb_index_entries - index_entry_pos));
4870 memmove(sc->ctts_data + index_entry_pos + entries,
4871 sc->ctts_data + index_entry_pos,
4872 sizeof(*sc->ctts_data) * (sc->ctts_count - index_entry_pos));
4873 if (index_entry_pos < sc->current_sample) {
4874 sc->current_sample += entries;
4878 st->nb_index_entries += entries;
4879 sc->ctts_count = st->nb_index_entries;
4881 // Record the index_entry position in frag_index of this fragment
4882 if (frag_stream_info)
4883 frag_stream_info->index_entry = index_entry_pos;
4885 if (index_entry_pos > 0)
4886 prev_dts = st->index_entries[index_entry_pos-1].timestamp;
4888 for (i = 0; i < entries && !pb->eof_reached; i++) {
4889 unsigned sample_size = frag->size;
4890 int sample_flags = i ? frag->flags : first_sample_flags;
4891 unsigned sample_duration = frag->duration;
4892 unsigned ctts_duration = 0;
4894 int index_entry_flags = 0;
4896 if (flags & MOV_TRUN_SAMPLE_DURATION) sample_duration = avio_rb32(pb);
4897 if (flags & MOV_TRUN_SAMPLE_SIZE) sample_size = avio_rb32(pb);
4898 if (flags & MOV_TRUN_SAMPLE_FLAGS) sample_flags = avio_rb32(pb);
4899 if (flags & MOV_TRUN_SAMPLE_CTS) ctts_duration = avio_rb32(pb);
4901 mov_update_dts_shift(sc, ctts_duration, c->fc);
4902 if (pts != AV_NOPTS_VALUE) {
4903 dts = pts - sc->dts_shift;
4904 if (flags & MOV_TRUN_SAMPLE_CTS) {
4905 dts -= ctts_duration;
4907 dts -= sc->time_offset;
4909 av_log(c->fc, AV_LOG_DEBUG,
4910 "pts %"PRId64" calculated dts %"PRId64
4911 " sc->dts_shift %d ctts.duration %d"
4912 " sc->time_offset %"PRId64
4913 " flags & MOV_TRUN_SAMPLE_CTS %d\n",
4915 sc->dts_shift, ctts_duration,
4916 sc->time_offset, flags & MOV_TRUN_SAMPLE_CTS);
4917 pts = AV_NOPTS_VALUE;
4920 if (st->codecpar->codec_type == AVMEDIA_TYPE_AUDIO)
4924 !(sample_flags & (MOV_FRAG_SAMPLE_FLAG_IS_NON_SYNC |
4925 MOV_FRAG_SAMPLE_FLAG_DEPENDS_YES));
4928 index_entry_flags |= AVINDEX_KEYFRAME;
4930 // Fragments can overlap in time. Discard overlapping frames after
4932 if (prev_dts >= dts)
4933 index_entry_flags |= AVINDEX_DISCARD_FRAME;
4935 st->index_entries[index_entry_pos].pos = offset;
4936 st->index_entries[index_entry_pos].timestamp = dts;
4937 st->index_entries[index_entry_pos].size= sample_size;
4938 st->index_entries[index_entry_pos].min_distance= distance;
4939 st->index_entries[index_entry_pos].flags = index_entry_flags;
4941 sc->ctts_data[index_entry_pos].count = 1;
4942 sc->ctts_data[index_entry_pos].duration = ctts_duration;
4945 av_log(c->fc, AV_LOG_TRACE, "AVIndex stream %d, sample %d, offset %"PRIx64", dts %"PRId64", "
4946 "size %u, distance %d, keyframe %d\n", st->index,
4947 index_entry_pos, offset, dts, sample_size, distance, keyframe);
4949 dts += sample_duration;
4950 offset += sample_size;
4951 sc->data_size += sample_size;
4953 if (sample_duration <= INT64_MAX - sc->duration_for_fps &&
4954 1 <= INT_MAX - sc->nb_frames_for_fps
4956 sc->duration_for_fps += sample_duration;
4957 sc->nb_frames_for_fps ++;
4960 if (frag_stream_info)
4961 frag_stream_info->next_trun_dts = dts + sc->time_offset;
4963 // EOF found before reading all entries. Fix the hole this would
4964 // leave in index_entries and ctts_data
4965 int gap = entries - i;
4966 memmove(st->index_entries + index_entry_pos,
4967 st->index_entries + index_entry_pos + gap,
4968 sizeof(*st->index_entries) *
4969 (st->nb_index_entries - (index_entry_pos + gap)));
4970 memmove(sc->ctts_data + index_entry_pos,
4971 sc->ctts_data + index_entry_pos + gap,
4972 sizeof(*sc->ctts_data) *
4973 (sc->ctts_count - (index_entry_pos + gap)));
4975 st->nb_index_entries -= gap;
4976 sc->ctts_count -= gap;
4977 if (index_entry_pos < sc->current_sample) {
4978 sc->current_sample -= gap;
4983 // The end of this new fragment may overlap in time with the start
4984 // of the next fragment in index_entries. Mark the samples in the next
4985 // fragment that overlap with AVINDEX_DISCARD_FRAME
4986 prev_dts = AV_NOPTS_VALUE;
4987 if (index_entry_pos > 0)
4988 prev_dts = st->index_entries[index_entry_pos-1].timestamp;
4989 for (i = index_entry_pos; i < st->nb_index_entries; i++) {
4990 if (prev_dts < st->index_entries[i].timestamp)
4992 st->index_entries[i].flags |= AVINDEX_DISCARD_FRAME;
4995 // If a hole was created to insert the new index_entries into,
4996 // the index_entry recorded for all subsequent moof must
4997 // be incremented by the number of entries inserted.
4998 fix_frag_index_entries(&c->frag_index, next_frag_index,
4999 frag->track_id, entries);
5001 if (pb->eof_reached) {
5002 av_log(c->fc, AV_LOG_WARNING, "reached eof, corrupted TRUN atom\n");
5006 frag->implicit_offset = offset;
5008 sc->track_end = dts + sc->time_offset;
5009 if (st->duration < sc->track_end)
5010 st->duration = sc->track_end;
5015 static int mov_read_sidx(MOVContext *c, AVIOContext *pb, MOVAtom atom)
5017 int64_t offset = avio_tell(pb) + atom.size, pts, timestamp;
5019 unsigned i, j, track_id, item_count;
5020 AVStream *st = NULL;
5021 AVStream *ref_st = NULL;
5022 MOVStreamContext *sc, *ref_sc = NULL;
5023 AVRational timescale;
5025 version = avio_r8(pb);
5027 avpriv_request_sample(c->fc, "sidx version %u", version);
5031 avio_rb24(pb); // flags
5033 track_id = avio_rb32(pb); // Reference ID
5034 for (i = 0; i < c->fc->nb_streams; i++) {
5035 if (c->fc->streams[i]->id == track_id) {
5036 st = c->fc->streams[i];
5041 av_log(c->fc, AV_LOG_WARNING, "could not find corresponding track id %d\n", track_id);
5047 timescale = av_make_q(1, avio_rb32(pb));
5049 if (timescale.den <= 0) {
5050 av_log(c->fc, AV_LOG_ERROR, "Invalid sidx timescale 1/%d\n", timescale.den);
5051 return AVERROR_INVALIDDATA;
5055 pts = avio_rb32(pb);
5056 offset += avio_rb32(pb);
5058 pts = avio_rb64(pb);
5059 offset += avio_rb64(pb);
5062 avio_rb16(pb); // reserved
5064 item_count = avio_rb16(pb);
5066 for (i = 0; i < item_count; i++) {
5068 MOVFragmentStreamInfo * frag_stream_info;
5069 uint32_t size = avio_rb32(pb);
5070 uint32_t duration = avio_rb32(pb);
5071 if (size & 0x80000000) {
5072 avpriv_request_sample(c->fc, "sidx reference_type 1");
5073 return AVERROR_PATCHWELCOME;
5075 avio_rb32(pb); // sap_flags
5076 timestamp = av_rescale_q(pts, timescale, st->time_base);
5078 index = update_frag_index(c, offset);
5079 frag_stream_info = get_frag_stream_info(&c->frag_index, index, track_id);
5080 if (frag_stream_info)
5081 frag_stream_info->sidx_pts = timestamp;
5087 st->duration = sc->track_end = pts;
5091 if (offset == avio_size(pb)) {
5092 // Find first entry in fragment index that came from an sidx.
5093 // This will pretty much always be the first entry.
5094 for (i = 0; i < c->frag_index.nb_items; i++) {
5095 MOVFragmentIndexItem * item = &c->frag_index.item[i];
5096 for (j = 0; ref_st == NULL && j < item->nb_stream_info; j++) {
5097 MOVFragmentStreamInfo * si;
5098 si = &item->stream_info[j];
5099 if (si->sidx_pts != AV_NOPTS_VALUE) {
5100 ref_st = c->fc->streams[j];
5101 ref_sc = ref_st->priv_data;
5106 if (ref_st) for (i = 0; i < c->fc->nb_streams; i++) {
5107 st = c->fc->streams[i];
5109 if (!sc->has_sidx) {
5110 st->duration = sc->track_end = av_rescale(ref_st->duration, sc->time_scale, ref_sc->time_scale);
5114 c->frag_index.complete = 1;
5120 /* this atom should be null (from specs), but some buggy files put the 'moov' atom inside it... */
5121 /* like the files created with Adobe Premiere 5.0, for samples see */
5122 /* http://graphics.tudelft.nl/~wouter/publications/soundtests/ */
5123 static int mov_read_wide(MOVContext *c, AVIOContext *pb, MOVAtom atom)
5128 return 0; /* continue */
5129 if (avio_rb32(pb) != 0) { /* 0 sized mdat atom... use the 'wide' atom size */
5130 avio_skip(pb, atom.size - 4);
5133 atom.type = avio_rl32(pb);
5135 if (atom.type != MKTAG('m','d','a','t')) {
5136 avio_skip(pb, atom.size);
5139 err = mov_read_mdat(c, pb, atom);
5143 static int mov_read_cmov(MOVContext *c, AVIOContext *pb, MOVAtom atom)
5148 uint8_t *moov_data; /* uncompressed data */
5149 long cmov_len, moov_len;
5152 avio_rb32(pb); /* dcom atom */
5153 if (avio_rl32(pb) != MKTAG('d','c','o','m'))
5154 return AVERROR_INVALIDDATA;
5155 if (avio_rl32(pb) != MKTAG('z','l','i','b')) {
5156 av_log(c->fc, AV_LOG_ERROR, "unknown compression for cmov atom !\n");
5157 return AVERROR_INVALIDDATA;
5159 avio_rb32(pb); /* cmvd atom */
5160 if (avio_rl32(pb) != MKTAG('c','m','v','d'))
5161 return AVERROR_INVALIDDATA;
5162 moov_len = avio_rb32(pb); /* uncompressed size */
5163 cmov_len = atom.size - 6 * 4;
5165 cmov_data = av_malloc(cmov_len);
5167 return AVERROR(ENOMEM);
5168 moov_data = av_malloc(moov_len);
5171 return AVERROR(ENOMEM);
5173 ret = ffio_read_size(pb, cmov_data, cmov_len);
5175 goto free_and_return;
5177 ret = AVERROR_INVALIDDATA;
5178 if (uncompress (moov_data, (uLongf *) &moov_len, (const Bytef *)cmov_data, cmov_len) != Z_OK)
5179 goto free_and_return;
5180 if (ffio_init_context(&ctx, moov_data, moov_len, 0, NULL, NULL, NULL, NULL) != 0)
5181 goto free_and_return;
5182 ctx.seekable = AVIO_SEEKABLE_NORMAL;
5183 atom.type = MKTAG('m','o','o','v');
5184 atom.size = moov_len;
5185 ret = mov_read_default(c, &ctx, atom);
5191 av_log(c->fc, AV_LOG_ERROR, "this file requires zlib support compiled in\n");
5192 return AVERROR(ENOSYS);
5196 /* edit list atom */
5197 static int mov_read_elst(MOVContext *c, AVIOContext *pb, MOVAtom atom)
5199 MOVStreamContext *sc;
5200 int i, edit_count, version;
5201 int64_t elst_entry_size;
5203 if (c->fc->nb_streams < 1 || c->ignore_editlist)
5205 sc = c->fc->streams[c->fc->nb_streams-1]->priv_data;
5207 version = avio_r8(pb); /* version */
5208 avio_rb24(pb); /* flags */
5209 edit_count = avio_rb32(pb); /* entries */
5212 elst_entry_size = version == 1 ? 20 : 12;
5213 if (atom.size != edit_count * elst_entry_size) {
5214 if (c->fc->strict_std_compliance >= FF_COMPLIANCE_STRICT) {
5215 av_log(c->fc, AV_LOG_ERROR, "Invalid edit list entry_count: %d for elst atom of size: %"PRId64" bytes.\n",
5216 edit_count, atom.size + 8);
5217 return AVERROR_INVALIDDATA;
5219 edit_count = atom.size / elst_entry_size;
5220 if (edit_count * elst_entry_size != atom.size) {
5221 av_log(c->fc, AV_LOG_WARNING, "ELST atom of %"PRId64" bytes, bigger than %d entries.\n", atom.size, edit_count);
5229 av_log(c->fc, AV_LOG_WARNING, "Duplicated ELST atom\n");
5230 av_free(sc->elst_data);
5232 sc->elst_data = av_malloc_array(edit_count, sizeof(*sc->elst_data));
5234 return AVERROR(ENOMEM);
5236 av_log(c->fc, AV_LOG_TRACE, "track[%u].edit_count = %i\n", c->fc->nb_streams - 1, edit_count);
5237 for (i = 0; i < edit_count && atom.size > 0 && !pb->eof_reached; i++) {
5238 MOVElst *e = &sc->elst_data[i];
5241 e->duration = avio_rb64(pb);
5242 e->time = avio_rb64(pb);
5245 e->duration = avio_rb32(pb); /* segment duration */
5246 e->time = (int32_t)avio_rb32(pb); /* media time */
5249 e->rate = avio_rb32(pb) / 65536.0;
5251 av_log(c->fc, AV_LOG_TRACE, "duration=%"PRId64" time=%"PRId64" rate=%f\n",
5252 e->duration, e->time, e->rate);
5254 if (e->time < 0 && e->time != -1 &&
5255 c->fc->strict_std_compliance >= FF_COMPLIANCE_STRICT) {
5256 av_log(c->fc, AV_LOG_ERROR, "Track %d, edit %d: Invalid edit list media time=%"PRId64"\n",
5257 c->fc->nb_streams-1, i, e->time);
5258 return AVERROR_INVALIDDATA;
5266 static int mov_read_tmcd(MOVContext *c, AVIOContext *pb, MOVAtom atom)
5268 MOVStreamContext *sc;
5270 if (c->fc->nb_streams < 1)
5271 return AVERROR_INVALIDDATA;
5272 sc = c->fc->streams[c->fc->nb_streams - 1]->priv_data;
5273 sc->timecode_track = avio_rb32(pb);
5277 static int mov_read_av1c(MOVContext *c, AVIOContext *pb, MOVAtom atom)
5282 if (c->fc->nb_streams < 1)
5284 st = c->fc->streams[c->fc->nb_streams - 1];
5286 if (atom.size < 4) {
5287 av_log(c->fc, AV_LOG_ERROR, "Empty AV1 Codec Configuration Box\n");
5288 return AVERROR_INVALIDDATA;
5291 /* For now, propagate only the OBUs, if any. Once libavcodec is
5292 updated to handle isobmff style extradata this can be removed. */
5298 ret = ff_get_extradata(c->fc, st->codecpar, pb, atom.size - 4);
5305 static int mov_read_vpcc(MOVContext *c, AVIOContext *pb, MOVAtom atom)
5308 int version, color_range, color_primaries, color_trc, color_space;
5310 if (c->fc->nb_streams < 1)
5312 st = c->fc->streams[c->fc->nb_streams - 1];
5314 if (atom.size < 5) {
5315 av_log(c->fc, AV_LOG_ERROR, "Empty VP Codec Configuration box\n");
5316 return AVERROR_INVALIDDATA;
5319 version = avio_r8(pb);
5321 av_log(c->fc, AV_LOG_WARNING, "Unsupported VP Codec Configuration box version %d\n", version);
5324 avio_skip(pb, 3); /* flags */
5326 avio_skip(pb, 2); /* profile + level */
5327 color_range = avio_r8(pb); /* bitDepth, chromaSubsampling, videoFullRangeFlag */
5328 color_primaries = avio_r8(pb);
5329 color_trc = avio_r8(pb);
5330 color_space = avio_r8(pb);
5331 if (avio_rb16(pb)) /* codecIntializationDataSize */
5332 return AVERROR_INVALIDDATA;
5334 if (!av_color_primaries_name(color_primaries))
5335 color_primaries = AVCOL_PRI_UNSPECIFIED;
5336 if (!av_color_transfer_name(color_trc))
5337 color_trc = AVCOL_TRC_UNSPECIFIED;
5338 if (!av_color_space_name(color_space))
5339 color_space = AVCOL_SPC_UNSPECIFIED;
5341 st->codecpar->color_range = (color_range & 1) ? AVCOL_RANGE_JPEG : AVCOL_RANGE_MPEG;
5342 st->codecpar->color_primaries = color_primaries;
5343 st->codecpar->color_trc = color_trc;
5344 st->codecpar->color_space = color_space;
5349 static int mov_read_smdm(MOVContext *c, AVIOContext *pb, MOVAtom atom)
5351 MOVStreamContext *sc;
5354 if (c->fc->nb_streams < 1)
5355 return AVERROR_INVALIDDATA;
5357 sc = c->fc->streams[c->fc->nb_streams - 1]->priv_data;
5359 if (atom.size < 5) {
5360 av_log(c->fc, AV_LOG_ERROR, "Empty Mastering Display Metadata box\n");
5361 return AVERROR_INVALIDDATA;
5364 version = avio_r8(pb);
5366 av_log(c->fc, AV_LOG_WARNING, "Unsupported Mastering Display Metadata box version %d\n", version);
5369 avio_skip(pb, 3); /* flags */
5371 sc->mastering = av_mastering_display_metadata_alloc();
5373 return AVERROR(ENOMEM);
5375 for (i = 0; i < 3; i++) {
5376 sc->mastering->display_primaries[i][0] = av_make_q(avio_rb16(pb), 1 << 16);
5377 sc->mastering->display_primaries[i][1] = av_make_q(avio_rb16(pb), 1 << 16);
5379 sc->mastering->white_point[0] = av_make_q(avio_rb16(pb), 1 << 16);
5380 sc->mastering->white_point[1] = av_make_q(avio_rb16(pb), 1 << 16);
5382 sc->mastering->max_luminance = av_make_q(avio_rb32(pb), 1 << 8);
5383 sc->mastering->min_luminance = av_make_q(avio_rb32(pb), 1 << 14);
5385 sc->mastering->has_primaries = 1;
5386 sc->mastering->has_luminance = 1;
5391 static int mov_read_mdcv(MOVContext *c, AVIOContext *pb, MOVAtom atom)
5393 MOVStreamContext *sc;
5394 const int mapping[3] = {1, 2, 0};
5395 const int chroma_den = 50000;
5396 const int luma_den = 10000;
5399 if (c->fc->nb_streams < 1)
5400 return AVERROR_INVALIDDATA;
5402 sc = c->fc->streams[c->fc->nb_streams - 1]->priv_data;
5404 if (atom.size < 24) {
5405 av_log(c->fc, AV_LOG_ERROR, "Invalid Mastering Display Color Volume box\n");
5406 return AVERROR_INVALIDDATA;
5409 sc->mastering = av_mastering_display_metadata_alloc();
5411 return AVERROR(ENOMEM);
5413 for (i = 0; i < 3; i++) {
5414 const int j = mapping[i];
5415 sc->mastering->display_primaries[j][0] = av_make_q(avio_rb16(pb), chroma_den);
5416 sc->mastering->display_primaries[j][1] = av_make_q(avio_rb16(pb), chroma_den);
5418 sc->mastering->white_point[0] = av_make_q(avio_rb16(pb), chroma_den);
5419 sc->mastering->white_point[1] = av_make_q(avio_rb16(pb), chroma_den);
5421 sc->mastering->max_luminance = av_make_q(avio_rb32(pb), luma_den);
5422 sc->mastering->min_luminance = av_make_q(avio_rb32(pb), luma_den);
5424 sc->mastering->has_luminance = 1;
5425 sc->mastering->has_primaries = 1;
5430 static int mov_read_coll(MOVContext *c, AVIOContext *pb, MOVAtom atom)
5432 MOVStreamContext *sc;
5435 if (c->fc->nb_streams < 1)
5436 return AVERROR_INVALIDDATA;
5438 sc = c->fc->streams[c->fc->nb_streams - 1]->priv_data;
5440 if (atom.size < 5) {
5441 av_log(c->fc, AV_LOG_ERROR, "Empty Content Light Level box\n");
5442 return AVERROR_INVALIDDATA;
5445 version = avio_r8(pb);
5447 av_log(c->fc, AV_LOG_WARNING, "Unsupported Content Light Level box version %d\n", version);
5450 avio_skip(pb, 3); /* flags */
5452 sc->coll = av_content_light_metadata_alloc(&sc->coll_size);
5454 return AVERROR(ENOMEM);
5456 sc->coll->MaxCLL = avio_rb16(pb);
5457 sc->coll->MaxFALL = avio_rb16(pb);
5462 static int mov_read_clli(MOVContext *c, AVIOContext *pb, MOVAtom atom)
5464 MOVStreamContext *sc;
5466 if (c->fc->nb_streams < 1)
5467 return AVERROR_INVALIDDATA;
5469 sc = c->fc->streams[c->fc->nb_streams - 1]->priv_data;
5471 if (atom.size < 4) {
5472 av_log(c->fc, AV_LOG_ERROR, "Empty Content Light Level Info box\n");
5473 return AVERROR_INVALIDDATA;
5476 sc->coll = av_content_light_metadata_alloc(&sc->coll_size);
5478 return AVERROR(ENOMEM);
5480 sc->coll->MaxCLL = avio_rb16(pb);
5481 sc->coll->MaxFALL = avio_rb16(pb);
5486 static int mov_read_st3d(MOVContext *c, AVIOContext *pb, MOVAtom atom)
5489 MOVStreamContext *sc;
5490 enum AVStereo3DType type;
5493 if (c->fc->nb_streams < 1)
5496 st = c->fc->streams[c->fc->nb_streams - 1];
5499 if (atom.size < 5) {
5500 av_log(c->fc, AV_LOG_ERROR, "Empty stereoscopic video box\n");
5501 return AVERROR_INVALIDDATA;
5503 avio_skip(pb, 4); /* version + flags */
5508 type = AV_STEREO3D_2D;
5511 type = AV_STEREO3D_TOPBOTTOM;
5514 type = AV_STEREO3D_SIDEBYSIDE;
5517 av_log(c->fc, AV_LOG_WARNING, "Unknown st3d mode value %d\n", mode);
5521 sc->stereo3d = av_stereo3d_alloc();
5523 return AVERROR(ENOMEM);
5525 sc->stereo3d->type = type;
5529 static int mov_read_sv3d(MOVContext *c, AVIOContext *pb, MOVAtom atom)
5532 MOVStreamContext *sc;
5533 int size, version, layout;
5534 int32_t yaw, pitch, roll;
5535 uint32_t l = 0, t = 0, r = 0, b = 0;
5536 uint32_t tag, padding = 0;
5537 enum AVSphericalProjection projection;
5539 if (c->fc->nb_streams < 1)
5542 st = c->fc->streams[c->fc->nb_streams - 1];
5545 if (atom.size < 8) {
5546 av_log(c->fc, AV_LOG_ERROR, "Empty spherical video box\n");
5547 return AVERROR_INVALIDDATA;
5550 size = avio_rb32(pb);
5551 if (size <= 12 || size > atom.size)
5552 return AVERROR_INVALIDDATA;
5554 tag = avio_rl32(pb);
5555 if (tag != MKTAG('s','v','h','d')) {
5556 av_log(c->fc, AV_LOG_ERROR, "Missing spherical video header\n");
5559 version = avio_r8(pb);
5561 av_log(c->fc, AV_LOG_WARNING, "Unknown spherical version %d\n",
5565 avio_skip(pb, 3); /* flags */
5566 avio_skip(pb, size - 12); /* metadata_source */
5568 size = avio_rb32(pb);
5569 if (size > atom.size)
5570 return AVERROR_INVALIDDATA;
5572 tag = avio_rl32(pb);
5573 if (tag != MKTAG('p','r','o','j')) {
5574 av_log(c->fc, AV_LOG_ERROR, "Missing projection box\n");
5578 size = avio_rb32(pb);
5579 if (size > atom.size)
5580 return AVERROR_INVALIDDATA;
5582 tag = avio_rl32(pb);
5583 if (tag != MKTAG('p','r','h','d')) {
5584 av_log(c->fc, AV_LOG_ERROR, "Missing projection header box\n");
5587 version = avio_r8(pb);
5589 av_log(c->fc, AV_LOG_WARNING, "Unknown spherical version %d\n",
5593 avio_skip(pb, 3); /* flags */
5595 /* 16.16 fixed point */
5596 yaw = avio_rb32(pb);
5597 pitch = avio_rb32(pb);
5598 roll = avio_rb32(pb);
5600 size = avio_rb32(pb);
5601 if (size > atom.size)
5602 return AVERROR_INVALIDDATA;
5604 tag = avio_rl32(pb);
5605 version = avio_r8(pb);
5607 av_log(c->fc, AV_LOG_WARNING, "Unknown spherical version %d\n",
5611 avio_skip(pb, 3); /* flags */
5613 case MKTAG('c','b','m','p'):
5614 layout = avio_rb32(pb);
5616 av_log(c->fc, AV_LOG_WARNING,
5617 "Unsupported cubemap layout %d\n", layout);
5620 projection = AV_SPHERICAL_CUBEMAP;
5621 padding = avio_rb32(pb);
5623 case MKTAG('e','q','u','i'):
5629 if (b >= UINT_MAX - t || r >= UINT_MAX - l) {
5630 av_log(c->fc, AV_LOG_ERROR,
5631 "Invalid bounding rectangle coordinates "
5632 "%"PRIu32",%"PRIu32",%"PRIu32",%"PRIu32"\n", l, t, r, b);
5633 return AVERROR_INVALIDDATA;
5636 if (l || t || r || b)
5637 projection = AV_SPHERICAL_EQUIRECTANGULAR_TILE;
5639 projection = AV_SPHERICAL_EQUIRECTANGULAR;
5642 av_log(c->fc, AV_LOG_ERROR, "Unknown projection type: %s\n", av_fourcc2str(tag));
5646 sc->spherical = av_spherical_alloc(&sc->spherical_size);
5648 return AVERROR(ENOMEM);
5650 sc->spherical->projection = projection;
5652 sc->spherical->yaw = yaw;
5653 sc->spherical->pitch = pitch;
5654 sc->spherical->roll = roll;
5656 sc->spherical->padding = padding;
5658 sc->spherical->bound_left = l;
5659 sc->spherical->bound_top = t;
5660 sc->spherical->bound_right = r;
5661 sc->spherical->bound_bottom = b;
5666 static int mov_parse_uuid_spherical(MOVStreamContext *sc, AVIOContext *pb, size_t len)
5669 uint8_t *buffer = av_malloc(len + 1);
5673 return AVERROR(ENOMEM);
5676 ret = ffio_read_size(pb, buffer, len);
5680 /* Check for mandatory keys and values, try to support XML as best-effort */
5681 if (!sc->spherical &&
5682 av_stristr(buffer, "<GSpherical:StitchingSoftware>") &&
5683 (val = av_stristr(buffer, "<GSpherical:Spherical>")) &&
5684 av_stristr(val, "true") &&
5685 (val = av_stristr(buffer, "<GSpherical:Stitched>")) &&
5686 av_stristr(val, "true") &&
5687 (val = av_stristr(buffer, "<GSpherical:ProjectionType>")) &&
5688 av_stristr(val, "equirectangular")) {
5689 sc->spherical = av_spherical_alloc(&sc->spherical_size);
5693 sc->spherical->projection = AV_SPHERICAL_EQUIRECTANGULAR;
5695 if (av_stristr(buffer, "<GSpherical:StereoMode>") && !sc->stereo3d) {
5696 enum AVStereo3DType mode;
5698 if (av_stristr(buffer, "left-right"))
5699 mode = AV_STEREO3D_SIDEBYSIDE;
5700 else if (av_stristr(buffer, "top-bottom"))
5701 mode = AV_STEREO3D_TOPBOTTOM;
5703 mode = AV_STEREO3D_2D;
5705 sc->stereo3d = av_stereo3d_alloc();
5709 sc->stereo3d->type = mode;
5713 val = av_stristr(buffer, "<GSpherical:InitialViewHeadingDegrees>");
5715 sc->spherical->yaw = strtol(val, NULL, 10) * (1 << 16);
5716 val = av_stristr(buffer, "<GSpherical:InitialViewPitchDegrees>");
5718 sc->spherical->pitch = strtol(val, NULL, 10) * (1 << 16);
5719 val = av_stristr(buffer, "<GSpherical:InitialViewRollDegrees>");
5721 sc->spherical->roll = strtol(val, NULL, 10) * (1 << 16);
5729 static int mov_read_uuid(MOVContext *c, AVIOContext *pb, MOVAtom atom)
5732 MOVStreamContext *sc;
5735 static const uint8_t uuid_isml_manifest[] = {
5736 0xa5, 0xd4, 0x0b, 0x30, 0xe8, 0x14, 0x11, 0xdd,
5737 0xba, 0x2f, 0x08, 0x00, 0x20, 0x0c, 0x9a, 0x66
5739 static const uint8_t uuid_xmp[] = {
5740 0xbe, 0x7a, 0xcf, 0xcb, 0x97, 0xa9, 0x42, 0xe8,
5741 0x9c, 0x71, 0x99, 0x94, 0x91, 0xe3, 0xaf, 0xac
5743 static const uint8_t uuid_spherical[] = {
5744 0xff, 0xcc, 0x82, 0x63, 0xf8, 0x55, 0x4a, 0x93,
5745 0x88, 0x14, 0x58, 0x7a, 0x02, 0x52, 0x1f, 0xdd,
5748 if (atom.size < sizeof(uuid) || atom.size >= FFMIN(INT_MAX, SIZE_MAX))
5749 return AVERROR_INVALIDDATA;
5751 if (c->fc->nb_streams < 1)
5753 st = c->fc->streams[c->fc->nb_streams - 1];
5756 ret = ffio_read_size(pb, uuid, sizeof(uuid));
5759 if (!memcmp(uuid, uuid_isml_manifest, sizeof(uuid))) {
5760 uint8_t *buffer, *ptr;
5762 size_t len = atom.size - sizeof(uuid);
5765 return AVERROR_INVALIDDATA;
5767 ret = avio_skip(pb, 4); // zeroes
5770 buffer = av_mallocz(len + 1);
5772 return AVERROR(ENOMEM);
5774 ret = ffio_read_size(pb, buffer, len);
5781 while ((ptr = av_stristr(ptr, "systemBitrate=\""))) {
5782 ptr += sizeof("systemBitrate=\"") - 1;
5783 c->bitrates_count++;
5784 c->bitrates = av_realloc_f(c->bitrates, c->bitrates_count, sizeof(*c->bitrates));
5786 c->bitrates_count = 0;
5788 return AVERROR(ENOMEM);
5791 ret = strtol(ptr, &endptr, 10);
5792 if (ret < 0 || errno || *endptr != '"') {
5793 c->bitrates[c->bitrates_count - 1] = 0;
5795 c->bitrates[c->bitrates_count - 1] = ret;
5800 } else if (!memcmp(uuid, uuid_xmp, sizeof(uuid))) {
5802 size_t len = atom.size - sizeof(uuid);
5803 if (c->export_xmp) {
5804 buffer = av_mallocz(len + 1);
5806 return AVERROR(ENOMEM);
5808 ret = ffio_read_size(pb, buffer, len);
5814 av_dict_set(&c->fc->metadata, "xmp",
5815 buffer, AV_DICT_DONT_STRDUP_VAL);
5817 // skip all uuid atom, which makes it fast for long uuid-xmp file
5818 ret = avio_skip(pb, len);
5822 } else if (!memcmp(uuid, uuid_spherical, sizeof(uuid))) {
5823 size_t len = atom.size - sizeof(uuid);
5824 ret = mov_parse_uuid_spherical(sc, pb, len);
5828 av_log(c->fc, AV_LOG_WARNING, "Invalid spherical metadata found\n");
5834 static int mov_read_free(MOVContext *c, AVIOContext *pb, MOVAtom atom)
5837 uint8_t content[16];
5842 ret = avio_read(pb, content, FFMIN(sizeof(content), atom.size));
5848 && !memcmp(content, "Anevia\x1A\x1A", 8)
5849 && c->use_mfra_for == FF_MOV_FLAG_MFRA_AUTO) {
5850 c->use_mfra_for = FF_MOV_FLAG_MFRA_PTS;
5856 static int mov_read_frma(MOVContext *c, AVIOContext *pb, MOVAtom atom)
5858 uint32_t format = avio_rl32(pb);
5859 MOVStreamContext *sc;
5863 if (c->fc->nb_streams < 1)
5865 st = c->fc->streams[c->fc->nb_streams - 1];
5870 case MKTAG('e','n','c','v'): // encrypted video
5871 case MKTAG('e','n','c','a'): // encrypted audio
5872 id = mov_codec_id(st, format);
5873 if (st->codecpar->codec_id != AV_CODEC_ID_NONE &&
5874 st->codecpar->codec_id != id) {
5875 av_log(c->fc, AV_LOG_WARNING,
5876 "ignoring 'frma' atom of '%.4s', stream has codec id %d\n",
5877 (char*)&format, st->codecpar->codec_id);
5881 st->codecpar->codec_id = id;
5882 sc->format = format;
5886 if (format != sc->format) {
5887 av_log(c->fc, AV_LOG_WARNING,
5888 "ignoring 'frma' atom of '%.4s', stream format is '%.4s'\n",
5889 (char*)&format, (char*)&sc->format);
5898 * Gets the current encryption info and associated current stream context. If
5899 * we are parsing a track fragment, this will return the specific encryption
5900 * info for this fragment; otherwise this will return the global encryption
5901 * info for the current stream.
5903 static int get_current_encryption_info(MOVContext *c, MOVEncryptionIndex **encryption_index, MOVStreamContext **sc)
5905 MOVFragmentStreamInfo *frag_stream_info;
5909 frag_stream_info = get_current_frag_stream_info(&c->frag_index);
5910 if (frag_stream_info) {
5911 for (i = 0; i < c->fc->nb_streams; i++) {
5912 if (c->fc->streams[i]->id == frag_stream_info->id) {
5913 st = c->fc->streams[i];
5917 if (i == c->fc->nb_streams)
5919 *sc = st->priv_data;
5921 if (!frag_stream_info->encryption_index) {
5922 // If this stream isn't encrypted, don't create the index.
5923 if (!(*sc)->cenc.default_encrypted_sample)
5925 frag_stream_info->encryption_index = av_mallocz(sizeof(*frag_stream_info->encryption_index));
5926 if (!frag_stream_info->encryption_index)
5927 return AVERROR(ENOMEM);
5929 *encryption_index = frag_stream_info->encryption_index;
5932 // No current track fragment, using stream level encryption info.
5934 if (c->fc->nb_streams < 1)
5936 st = c->fc->streams[c->fc->nb_streams - 1];
5937 *sc = st->priv_data;
5939 if (!(*sc)->cenc.encryption_index) {
5940 // If this stream isn't encrypted, don't create the index.
5941 if (!(*sc)->cenc.default_encrypted_sample)
5943 (*sc)->cenc.encryption_index = av_mallocz(sizeof(*frag_stream_info->encryption_index));
5944 if (!(*sc)->cenc.encryption_index)
5945 return AVERROR(ENOMEM);
5948 *encryption_index = (*sc)->cenc.encryption_index;
5953 static int mov_read_sample_encryption_info(MOVContext *c, AVIOContext *pb, MOVStreamContext *sc, AVEncryptionInfo **sample, int use_subsamples)
5956 unsigned int subsample_count;
5957 AVSubsampleEncryptionInfo *subsamples;
5959 if (!sc->cenc.default_encrypted_sample) {
5960 av_log(c->fc, AV_LOG_ERROR, "Missing schm or tenc\n");
5961 return AVERROR_INVALIDDATA;
5964 *sample = av_encryption_info_clone(sc->cenc.default_encrypted_sample);
5966 return AVERROR(ENOMEM);
5968 if (sc->cenc.per_sample_iv_size != 0) {
5969 if ((ret = ffio_read_size(pb, (*sample)->iv, sc->cenc.per_sample_iv_size)) < 0) {
5970 av_log(c->fc, AV_LOG_ERROR, "failed to read the initialization vector\n");
5971 av_encryption_info_free(*sample);
5977 if (use_subsamples) {
5978 subsample_count = avio_rb16(pb);
5979 av_free((*sample)->subsamples);
5980 (*sample)->subsamples = av_mallocz_array(subsample_count, sizeof(*subsamples));
5981 if (!(*sample)->subsamples) {
5982 av_encryption_info_free(*sample);
5984 return AVERROR(ENOMEM);
5987 for (i = 0; i < subsample_count && !pb->eof_reached; i++) {
5988 (*sample)->subsamples[i].bytes_of_clear_data = avio_rb16(pb);
5989 (*sample)->subsamples[i].bytes_of_protected_data = avio_rb32(pb);
5992 if (pb->eof_reached) {
5993 av_log(c->fc, AV_LOG_ERROR, "hit EOF while reading sub-sample encryption info\n");
5994 av_encryption_info_free(*sample);
5996 return AVERROR_INVALIDDATA;
5998 (*sample)->subsample_count = subsample_count;
6004 static int mov_read_senc(MOVContext *c, AVIOContext *pb, MOVAtom atom)
6006 AVEncryptionInfo **encrypted_samples;
6007 MOVEncryptionIndex *encryption_index;
6008 MOVStreamContext *sc;
6009 int use_subsamples, ret;
6010 unsigned int sample_count, i, alloc_size = 0;
6012 ret = get_current_encryption_info(c, &encryption_index, &sc);
6016 if (encryption_index->nb_encrypted_samples) {
6017 // This can happen if we have both saio/saiz and senc atoms.
6018 av_log(c->fc, AV_LOG_DEBUG, "Ignoring duplicate encryption info in senc\n");
6022 avio_r8(pb); /* version */
6023 use_subsamples = avio_rb24(pb) & 0x02; /* flags */
6025 sample_count = avio_rb32(pb);
6026 if (sample_count >= INT_MAX / sizeof(*encrypted_samples))
6027 return AVERROR(ENOMEM);
6029 for (i = 0; i < sample_count; i++) {
6030 unsigned int min_samples = FFMIN(FFMAX(i + 1, 1024 * 1024), sample_count);
6031 encrypted_samples = av_fast_realloc(encryption_index->encrypted_samples, &alloc_size,
6032 min_samples * sizeof(*encrypted_samples));
6033 if (encrypted_samples) {
6034 encryption_index->encrypted_samples = encrypted_samples;
6036 ret = mov_read_sample_encryption_info(
6037 c, pb, sc, &encryption_index->encrypted_samples[i], use_subsamples);
6039 ret = AVERROR(ENOMEM);
6041 if (pb->eof_reached) {
6042 av_log(c->fc, AV_LOG_ERROR, "Hit EOF while reading senc\n");
6043 ret = AVERROR_INVALIDDATA;
6048 av_encryption_info_free(encryption_index->encrypted_samples[i - 1]);
6049 av_freep(&encryption_index->encrypted_samples);
6053 encryption_index->nb_encrypted_samples = sample_count;
6058 static int mov_parse_auxiliary_info(MOVContext *c, MOVStreamContext *sc, AVIOContext *pb, MOVEncryptionIndex *encryption_index)
6060 AVEncryptionInfo **sample, **encrypted_samples;
6062 size_t sample_count, sample_info_size, i;
6064 unsigned int alloc_size = 0;
6066 if (encryption_index->nb_encrypted_samples)
6068 sample_count = encryption_index->auxiliary_info_sample_count;
6069 if (encryption_index->auxiliary_offsets_count != 1) {
6070 av_log(c->fc, AV_LOG_ERROR, "Multiple auxiliary info chunks are not supported\n");
6071 return AVERROR_PATCHWELCOME;
6073 if (sample_count >= INT_MAX / sizeof(*encrypted_samples))
6074 return AVERROR(ENOMEM);
6076 prev_pos = avio_tell(pb);
6077 if (!(pb->seekable & AVIO_SEEKABLE_NORMAL) ||
6078 avio_seek(pb, encryption_index->auxiliary_offsets[0], SEEK_SET) != encryption_index->auxiliary_offsets[0]) {
6079 av_log(c->fc, AV_LOG_INFO, "Failed to seek for auxiliary info, will only parse senc atoms for encryption info\n");
6083 for (i = 0; i < sample_count && !pb->eof_reached; i++) {
6084 unsigned int min_samples = FFMIN(FFMAX(i + 1, 1024 * 1024), sample_count);
6085 encrypted_samples = av_fast_realloc(encryption_index->encrypted_samples, &alloc_size,
6086 min_samples * sizeof(*encrypted_samples));
6087 if (!encrypted_samples) {
6088 ret = AVERROR(ENOMEM);
6091 encryption_index->encrypted_samples = encrypted_samples;
6093 sample = &encryption_index->encrypted_samples[i];
6094 sample_info_size = encryption_index->auxiliary_info_default_size
6095 ? encryption_index->auxiliary_info_default_size
6096 : encryption_index->auxiliary_info_sizes[i];
6098 ret = mov_read_sample_encryption_info(c, pb, sc, sample, sample_info_size > sc->cenc.per_sample_iv_size);
6102 if (pb->eof_reached) {
6103 av_log(c->fc, AV_LOG_ERROR, "Hit EOF while reading auxiliary info\n");
6104 ret = AVERROR_INVALIDDATA;
6106 encryption_index->nb_encrypted_samples = sample_count;
6110 avio_seek(pb, prev_pos, SEEK_SET);
6112 for (; i > 0; i--) {
6113 av_encryption_info_free(encryption_index->encrypted_samples[i - 1]);
6115 av_freep(&encryption_index->encrypted_samples);
6121 * Tries to read the given number of bytes from the stream and puts it in a
6122 * newly allocated buffer. This reads in small chunks to avoid allocating large
6123 * memory if the file contains an invalid/malicious size value.
6125 static int mov_try_read_block(AVIOContext *pb, size_t size, uint8_t **data)
6127 const unsigned int block_size = 1024 * 1024;
6128 uint8_t *buffer = NULL;
6129 unsigned int alloc_size = 0, offset = 0;
6130 while (offset < size) {
6131 unsigned int new_size =
6132 alloc_size >= INT_MAX - block_size ? INT_MAX : alloc_size + block_size;
6133 uint8_t *new_buffer = av_fast_realloc(buffer, &alloc_size, new_size);
6134 unsigned int to_read = FFMIN(size, alloc_size) - offset;
6137 return AVERROR(ENOMEM);
6139 buffer = new_buffer;
6141 if (avio_read(pb, buffer + offset, to_read) != to_read) {
6143 return AVERROR_INVALIDDATA;
6152 static int mov_read_saiz(MOVContext *c, AVIOContext *pb, MOVAtom atom)
6154 MOVEncryptionIndex *encryption_index;
6155 MOVStreamContext *sc;
6157 unsigned int sample_count, aux_info_type, aux_info_param;
6159 ret = get_current_encryption_info(c, &encryption_index, &sc);
6163 if (encryption_index->nb_encrypted_samples) {
6164 // This can happen if we have both saio/saiz and senc atoms.
6165 av_log(c->fc, AV_LOG_DEBUG, "Ignoring duplicate encryption info in saiz\n");
6169 if (encryption_index->auxiliary_info_sample_count) {
6170 av_log(c->fc, AV_LOG_ERROR, "Duplicate saiz atom\n");
6171 return AVERROR_INVALIDDATA;
6174 avio_r8(pb); /* version */
6175 if (avio_rb24(pb) & 0x01) { /* flags */
6176 aux_info_type = avio_rb32(pb);
6177 aux_info_param = avio_rb32(pb);
6178 if (sc->cenc.default_encrypted_sample) {
6179 if (aux_info_type != sc->cenc.default_encrypted_sample->scheme) {
6180 av_log(c->fc, AV_LOG_DEBUG, "Ignoring saiz box with non-zero aux_info_type\n");
6183 if (aux_info_param != 0) {
6184 av_log(c->fc, AV_LOG_DEBUG, "Ignoring saiz box with non-zero aux_info_type_parameter\n");
6188 // Didn't see 'schm' or 'tenc', so this isn't encrypted.
6189 if ((aux_info_type == MKBETAG('c','e','n','c') ||
6190 aux_info_type == MKBETAG('c','e','n','s') ||
6191 aux_info_type == MKBETAG('c','b','c','1') ||
6192 aux_info_type == MKBETAG('c','b','c','s')) &&
6193 aux_info_param == 0) {
6194 av_log(c->fc, AV_LOG_ERROR, "Saw encrypted saiz without schm/tenc\n");
6195 return AVERROR_INVALIDDATA;
6200 } else if (!sc->cenc.default_encrypted_sample) {
6201 // Didn't see 'schm' or 'tenc', so this isn't encrypted.
6205 encryption_index->auxiliary_info_default_size = avio_r8(pb);
6206 sample_count = avio_rb32(pb);
6207 encryption_index->auxiliary_info_sample_count = sample_count;
6209 if (encryption_index->auxiliary_info_default_size == 0) {
6210 ret = mov_try_read_block(pb, sample_count, &encryption_index->auxiliary_info_sizes);
6212 av_log(c->fc, AV_LOG_ERROR, "Failed to read the auxiliary info\n");
6217 if (encryption_index->auxiliary_offsets_count) {
6218 return mov_parse_auxiliary_info(c, sc, pb, encryption_index);
6224 static int mov_read_saio(MOVContext *c, AVIOContext *pb, MOVAtom atom)
6226 uint64_t *auxiliary_offsets;
6227 MOVEncryptionIndex *encryption_index;
6228 MOVStreamContext *sc;
6230 unsigned int version, entry_count, aux_info_type, aux_info_param;
6231 unsigned int alloc_size = 0;
6233 ret = get_current_encryption_info(c, &encryption_index, &sc);
6237 if (encryption_index->nb_encrypted_samples) {
6238 // This can happen if we have both saio/saiz and senc atoms.
6239 av_log(c->fc, AV_LOG_DEBUG, "Ignoring duplicate encryption info in saio\n");
6243 if (encryption_index->auxiliary_offsets_count) {
6244 av_log(c->fc, AV_LOG_ERROR, "Duplicate saio atom\n");
6245 return AVERROR_INVALIDDATA;
6248 version = avio_r8(pb); /* version */
6249 if (avio_rb24(pb) & 0x01) { /* flags */
6250 aux_info_type = avio_rb32(pb);
6251 aux_info_param = avio_rb32(pb);
6252 if (sc->cenc.default_encrypted_sample) {
6253 if (aux_info_type != sc->cenc.default_encrypted_sample->scheme) {
6254 av_log(c->fc, AV_LOG_DEBUG, "Ignoring saio box with non-zero aux_info_type\n");
6257 if (aux_info_param != 0) {
6258 av_log(c->fc, AV_LOG_DEBUG, "Ignoring saio box with non-zero aux_info_type_parameter\n");
6262 // Didn't see 'schm' or 'tenc', so this isn't encrypted.
6263 if ((aux_info_type == MKBETAG('c','e','n','c') ||
6264 aux_info_type == MKBETAG('c','e','n','s') ||
6265 aux_info_type == MKBETAG('c','b','c','1') ||
6266 aux_info_type == MKBETAG('c','b','c','s')) &&
6267 aux_info_param == 0) {
6268 av_log(c->fc, AV_LOG_ERROR, "Saw encrypted saio without schm/tenc\n");
6269 return AVERROR_INVALIDDATA;
6274 } else if (!sc->cenc.default_encrypted_sample) {
6275 // Didn't see 'schm' or 'tenc', so this isn't encrypted.
6279 entry_count = avio_rb32(pb);
6280 if (entry_count >= INT_MAX / sizeof(*auxiliary_offsets))
6281 return AVERROR(ENOMEM);
6283 for (i = 0; i < entry_count && !pb->eof_reached; i++) {
6284 unsigned int min_offsets = FFMIN(FFMAX(i + 1, 1024), entry_count);
6285 auxiliary_offsets = av_fast_realloc(
6286 encryption_index->auxiliary_offsets, &alloc_size,
6287 min_offsets * sizeof(*auxiliary_offsets));
6288 if (!auxiliary_offsets) {
6289 av_freep(&encryption_index->auxiliary_offsets);
6290 return AVERROR(ENOMEM);
6292 encryption_index->auxiliary_offsets = auxiliary_offsets;
6295 encryption_index->auxiliary_offsets[i] = avio_rb32(pb);
6297 encryption_index->auxiliary_offsets[i] = avio_rb64(pb);
6299 if (c->frag_index.current >= 0) {
6300 encryption_index->auxiliary_offsets[i] += c->fragment.base_data_offset;
6304 if (pb->eof_reached) {
6305 av_log(c->fc, AV_LOG_ERROR, "Hit EOF while reading saio\n");
6306 av_freep(&encryption_index->auxiliary_offsets);
6307 return AVERROR_INVALIDDATA;
6310 encryption_index->auxiliary_offsets_count = entry_count;
6312 if (encryption_index->auxiliary_info_sample_count) {
6313 return mov_parse_auxiliary_info(c, sc, pb, encryption_index);
6319 static int mov_read_pssh(MOVContext *c, AVIOContext *pb, MOVAtom atom)
6321 AVEncryptionInitInfo *info, *old_init_info;
6324 uint8_t *side_data, *extra_data, *old_side_data;
6325 size_t side_data_size;
6326 int ret = 0, old_side_data_size;
6327 unsigned int version, kid_count, extra_data_size, alloc_size = 0;
6329 if (c->fc->nb_streams < 1)
6331 st = c->fc->streams[c->fc->nb_streams-1];
6333 version = avio_r8(pb); /* version */
6334 avio_rb24(pb); /* flags */
6336 info = av_encryption_init_info_alloc(/* system_id_size */ 16, /* num_key_ids */ 0,
6337 /* key_id_size */ 16, /* data_size */ 0);
6339 return AVERROR(ENOMEM);
6341 if ((ret = ffio_read_size(pb, info->system_id, 16)) < 0) {
6342 av_log(c->fc, AV_LOG_ERROR, "Failed to read the system id\n");
6347 kid_count = avio_rb32(pb);
6348 if (kid_count >= INT_MAX / sizeof(*key_ids)) {
6349 ret = AVERROR(ENOMEM);
6353 for (unsigned int i = 0; i < kid_count && !pb->eof_reached; i++) {
6354 unsigned int min_kid_count = FFMIN(FFMAX(i + 1, 1024), kid_count);
6355 key_ids = av_fast_realloc(info->key_ids, &alloc_size,
6356 min_kid_count * sizeof(*key_ids));
6358 ret = AVERROR(ENOMEM);
6361 info->key_ids = key_ids;
6363 info->key_ids[i] = av_mallocz(16);
6364 if (!info->key_ids[i]) {
6365 ret = AVERROR(ENOMEM);
6368 info->num_key_ids = i + 1;
6370 if ((ret = ffio_read_size(pb, info->key_ids[i], 16)) < 0) {
6371 av_log(c->fc, AV_LOG_ERROR, "Failed to read the key id\n");
6376 if (pb->eof_reached) {
6377 av_log(c->fc, AV_LOG_ERROR, "Hit EOF while reading pssh\n");
6378 ret = AVERROR_INVALIDDATA;
6383 extra_data_size = avio_rb32(pb);
6384 ret = mov_try_read_block(pb, extra_data_size, &extra_data);
6388 av_freep(&info->data); // malloc(0) may still allocate something.
6389 info->data = extra_data;
6390 info->data_size = extra_data_size;
6392 // If there is existing initialization data, append to the list.
6393 old_side_data = av_stream_get_side_data(st, AV_PKT_DATA_ENCRYPTION_INIT_INFO, &old_side_data_size);
6394 if (old_side_data) {
6395 old_init_info = av_encryption_init_info_get_side_data(old_side_data, old_side_data_size);
6396 if (old_init_info) {
6397 // Append to the end of the list.
6398 for (AVEncryptionInitInfo *cur = old_init_info;; cur = cur->next) {
6404 info = old_init_info;
6406 // Assume existing side-data will be valid, so the only error we could get is OOM.
6407 ret = AVERROR(ENOMEM);
6412 side_data = av_encryption_init_info_add_side_data(info, &side_data_size);
6414 ret = AVERROR(ENOMEM);
6417 ret = av_stream_add_side_data(st, AV_PKT_DATA_ENCRYPTION_INIT_INFO,
6418 side_data, side_data_size);
6423 av_encryption_init_info_free(info);
6427 static int mov_read_schm(MOVContext *c, AVIOContext *pb, MOVAtom atom)
6430 MOVStreamContext *sc;
6432 if (c->fc->nb_streams < 1)
6434 st = c->fc->streams[c->fc->nb_streams-1];
6437 if (sc->pseudo_stream_id != 0) {
6438 av_log(c->fc, AV_LOG_ERROR, "schm boxes are only supported in first sample descriptor\n");
6439 return AVERROR_PATCHWELCOME;
6443 return AVERROR_INVALIDDATA;
6445 avio_rb32(pb); /* version and flags */
6447 if (!sc->cenc.default_encrypted_sample) {
6448 sc->cenc.default_encrypted_sample = av_encryption_info_alloc(0, 16, 16);
6449 if (!sc->cenc.default_encrypted_sample) {
6450 return AVERROR(ENOMEM);
6454 sc->cenc.default_encrypted_sample->scheme = avio_rb32(pb);
6458 static int mov_read_tenc(MOVContext *c, AVIOContext *pb, MOVAtom atom)
6461 MOVStreamContext *sc;
6462 unsigned int version, pattern, is_protected, iv_size;
6464 if (c->fc->nb_streams < 1)
6466 st = c->fc->streams[c->fc->nb_streams-1];
6469 if (sc->pseudo_stream_id != 0) {
6470 av_log(c->fc, AV_LOG_ERROR, "tenc atom are only supported in first sample descriptor\n");
6471 return AVERROR_PATCHWELCOME;
6474 if (!sc->cenc.default_encrypted_sample) {
6475 sc->cenc.default_encrypted_sample = av_encryption_info_alloc(0, 16, 16);
6476 if (!sc->cenc.default_encrypted_sample) {
6477 return AVERROR(ENOMEM);
6482 return AVERROR_INVALIDDATA;
6484 version = avio_r8(pb); /* version */
6485 avio_rb24(pb); /* flags */
6487 avio_r8(pb); /* reserved */
6488 pattern = avio_r8(pb);
6491 sc->cenc.default_encrypted_sample->crypt_byte_block = pattern >> 4;
6492 sc->cenc.default_encrypted_sample->skip_byte_block = pattern & 0xf;
6495 is_protected = avio_r8(pb);
6496 if (is_protected && !sc->cenc.encryption_index) {
6497 // The whole stream should be by-default encrypted.
6498 sc->cenc.encryption_index = av_mallocz(sizeof(MOVEncryptionIndex));
6499 if (!sc->cenc.encryption_index)
6500 return AVERROR(ENOMEM);
6502 sc->cenc.per_sample_iv_size = avio_r8(pb);
6503 if (sc->cenc.per_sample_iv_size != 0 && sc->cenc.per_sample_iv_size != 8 &&
6504 sc->cenc.per_sample_iv_size != 16) {
6505 av_log(c->fc, AV_LOG_ERROR, "invalid per-sample IV size value\n");
6506 return AVERROR_INVALIDDATA;
6508 if (avio_read(pb, sc->cenc.default_encrypted_sample->key_id, 16) != 16) {
6509 av_log(c->fc, AV_LOG_ERROR, "failed to read the default key ID\n");
6510 return AVERROR_INVALIDDATA;
6513 if (is_protected && !sc->cenc.per_sample_iv_size) {
6514 iv_size = avio_r8(pb);
6515 if (iv_size != 8 && iv_size != 16) {
6516 av_log(c->fc, AV_LOG_ERROR, "invalid default_constant_IV_size in tenc atom\n");
6517 return AVERROR_INVALIDDATA;
6520 if (avio_read(pb, sc->cenc.default_encrypted_sample->iv, iv_size) != iv_size) {
6521 av_log(c->fc, AV_LOG_ERROR, "failed to read the default IV\n");
6522 return AVERROR_INVALIDDATA;
6529 static int mov_read_dfla(MOVContext *c, AVIOContext *pb, MOVAtom atom)
6532 int last, type, size, ret;
6535 if (c->fc->nb_streams < 1)
6537 st = c->fc->streams[c->fc->nb_streams-1];
6539 if ((uint64_t)atom.size > (1<<30) || atom.size < 42)
6540 return AVERROR_INVALIDDATA;
6542 /* Check FlacSpecificBox version. */
6543 if (avio_r8(pb) != 0)
6544 return AVERROR_INVALIDDATA;
6546 avio_rb24(pb); /* Flags */
6548 avio_read(pb, buf, sizeof(buf));
6549 flac_parse_block_header(buf, &last, &type, &size);
6551 if (type != FLAC_METADATA_TYPE_STREAMINFO || size != FLAC_STREAMINFO_SIZE) {
6552 av_log(c->fc, AV_LOG_ERROR, "STREAMINFO must be first FLACMetadataBlock\n");
6553 return AVERROR_INVALIDDATA;
6556 ret = ff_get_extradata(c->fc, st->codecpar, pb, size);
6561 av_log(c->fc, AV_LOG_WARNING, "non-STREAMINFO FLACMetadataBlock(s) ignored\n");
6566 static int cenc_decrypt(MOVContext *c, MOVStreamContext *sc, AVEncryptionInfo *sample, uint8_t *input, int size)
6570 if (sample->scheme != MKBETAG('c','e','n','c') || sample->crypt_byte_block != 0 || sample->skip_byte_block != 0) {
6571 av_log(c->fc, AV_LOG_ERROR, "Only the 'cenc' encryption scheme is supported\n");
6572 return AVERROR_PATCHWELCOME;
6575 if (!sc->cenc.aes_ctr) {
6576 /* initialize the cipher */
6577 sc->cenc.aes_ctr = av_aes_ctr_alloc();
6578 if (!sc->cenc.aes_ctr) {
6579 return AVERROR(ENOMEM);
6582 ret = av_aes_ctr_init(sc->cenc.aes_ctr, c->decryption_key);
6588 av_aes_ctr_set_full_iv(sc->cenc.aes_ctr, sample->iv);
6590 if (!sample->subsample_count) {
6591 /* decrypt the whole packet */
6592 av_aes_ctr_crypt(sc->cenc.aes_ctr, input, input, size);
6596 for (i = 0; i < sample->subsample_count; i++) {
6597 if (sample->subsamples[i].bytes_of_clear_data + sample->subsamples[i].bytes_of_protected_data > size) {
6598 av_log(c->fc, AV_LOG_ERROR, "subsample size exceeds the packet size left\n");
6599 return AVERROR_INVALIDDATA;
6602 /* skip the clear bytes */
6603 input += sample->subsamples[i].bytes_of_clear_data;
6604 size -= sample->subsamples[i].bytes_of_clear_data;
6606 /* decrypt the encrypted bytes */
6607 av_aes_ctr_crypt(sc->cenc.aes_ctr, input, input, sample->subsamples[i].bytes_of_protected_data);
6608 input += sample->subsamples[i].bytes_of_protected_data;
6609 size -= sample->subsamples[i].bytes_of_protected_data;
6613 av_log(c->fc, AV_LOG_ERROR, "leftover packet bytes after subsample processing\n");
6614 return AVERROR_INVALIDDATA;
6620 static int cenc_filter(MOVContext *mov, AVStream* st, MOVStreamContext *sc, AVPacket *pkt, int current_index)
6622 MOVFragmentStreamInfo *frag_stream_info;
6623 MOVEncryptionIndex *encryption_index;
6624 AVEncryptionInfo *encrypted_sample;
6625 int encrypted_index, ret;
6627 frag_stream_info = get_frag_stream_info(&mov->frag_index, mov->frag_index.current, st->id);
6628 encrypted_index = current_index;
6629 encryption_index = NULL;
6630 if (frag_stream_info) {
6631 // Note this only supports encryption info in the first sample descriptor.
6632 if (mov->fragment.stsd_id == 1) {
6633 if (frag_stream_info->encryption_index) {
6634 encrypted_index = current_index - frag_stream_info->index_entry;
6635 encryption_index = frag_stream_info->encryption_index;
6637 encryption_index = sc->cenc.encryption_index;
6641 encryption_index = sc->cenc.encryption_index;
6644 if (encryption_index) {
6645 if (encryption_index->auxiliary_info_sample_count &&
6646 !encryption_index->nb_encrypted_samples) {
6647 av_log(mov->fc, AV_LOG_ERROR, "saiz atom found without saio\n");
6648 return AVERROR_INVALIDDATA;
6650 if (encryption_index->auxiliary_offsets_count &&
6651 !encryption_index->nb_encrypted_samples) {
6652 av_log(mov->fc, AV_LOG_ERROR, "saio atom found without saiz\n");
6653 return AVERROR_INVALIDDATA;
6656 if (!encryption_index->nb_encrypted_samples) {
6657 // Full-sample encryption with default settings.
6658 encrypted_sample = sc->cenc.default_encrypted_sample;
6659 } else if (encrypted_index >= 0 && encrypted_index < encryption_index->nb_encrypted_samples) {
6660 // Per-sample setting override.
6661 encrypted_sample = encryption_index->encrypted_samples[encrypted_index];
6663 av_log(mov->fc, AV_LOG_ERROR, "Incorrect number of samples in encryption info\n");
6664 return AVERROR_INVALIDDATA;
6667 if (mov->decryption_key) {
6668 return cenc_decrypt(mov, sc, encrypted_sample, pkt->data, pkt->size);
6671 uint8_t *side_data = av_encryption_info_add_side_data(encrypted_sample, &size);
6673 return AVERROR(ENOMEM);
6674 ret = av_packet_add_side_data(pkt, AV_PKT_DATA_ENCRYPTION_INFO, side_data, size);
6684 static int mov_read_dops(MOVContext *c, AVIOContext *pb, MOVAtom atom)
6686 const int OPUS_SEEK_PREROLL_MS = 80;
6692 if (c->fc->nb_streams < 1)
6694 st = c->fc->streams[c->fc->nb_streams-1];
6696 if ((uint64_t)atom.size > (1<<30) || atom.size < 11)
6697 return AVERROR_INVALIDDATA;
6699 /* Check OpusSpecificBox version. */
6700 if (avio_r8(pb) != 0) {
6701 av_log(c->fc, AV_LOG_ERROR, "unsupported OpusSpecificBox version\n");
6702 return AVERROR_INVALIDDATA;
6705 /* OpusSpecificBox size plus magic for Ogg OpusHead header. */
6706 size = atom.size + 8;
6708 if ((ret = ff_alloc_extradata(st->codecpar, size)) < 0)
6711 AV_WL32(st->codecpar->extradata, MKTAG('O','p','u','s'));
6712 AV_WL32(st->codecpar->extradata + 4, MKTAG('H','e','a','d'));
6713 AV_WB8(st->codecpar->extradata + 8, 1); /* OpusHead version */
6714 avio_read(pb, st->codecpar->extradata + 9, size - 9);
6716 /* OpusSpecificBox is stored in big-endian, but OpusHead is
6717 little-endian; aside from the preceeding magic and version they're
6718 otherwise currently identical. Data after output gain at offset 16
6719 doesn't need to be bytewapped. */
6720 pre_skip = AV_RB16(st->codecpar->extradata + 10);
6721 AV_WL16(st->codecpar->extradata + 10, pre_skip);
6722 AV_WL32(st->codecpar->extradata + 12, AV_RB32(st->codecpar->extradata + 12));
6723 AV_WL16(st->codecpar->extradata + 16, AV_RB16(st->codecpar->extradata + 16));
6725 st->codecpar->initial_padding = pre_skip;
6726 st->codecpar->seek_preroll = av_rescale_q(OPUS_SEEK_PREROLL_MS,
6727 (AVRational){1, 1000},
6728 (AVRational){1, 48000});
6733 static int mov_read_dmlp(MOVContext *c, AVIOContext *pb, MOVAtom atom)
6736 unsigned format_info;
6737 int channel_assignment, channel_assignment1, channel_assignment2;
6740 if (c->fc->nb_streams < 1)
6742 st = c->fc->streams[c->fc->nb_streams-1];
6745 return AVERROR_INVALIDDATA;
6747 format_info = avio_rb32(pb);
6749 ratebits = (format_info >> 28) & 0xF;
6750 channel_assignment1 = (format_info >> 15) & 0x1F;
6751 channel_assignment2 = format_info & 0x1FFF;
6752 if (channel_assignment2)
6753 channel_assignment = channel_assignment2;
6755 channel_assignment = channel_assignment1;
6757 st->codecpar->frame_size = 40 << (ratebits & 0x7);
6758 st->codecpar->sample_rate = mlp_samplerate(ratebits);
6759 st->codecpar->channels = truehd_channels(channel_assignment);
6760 st->codecpar->channel_layout = truehd_layout(channel_assignment);
6765 static int mov_read_dvcc_dvvc(MOVContext *c, AVIOContext *pb, MOVAtom atom)
6769 AVDOVIDecoderConfigurationRecord *dovi;
6773 if (c->fc->nb_streams < 1)
6775 st = c->fc->streams[c->fc->nb_streams-1];
6777 if ((uint64_t)atom.size > (1<<30) || atom.size < 4)
6778 return AVERROR_INVALIDDATA;
6780 dovi = av_dovi_alloc(&dovi_size);
6782 return AVERROR(ENOMEM);
6784 dovi->dv_version_major = avio_r8(pb);
6785 dovi->dv_version_minor = avio_r8(pb);
6787 buf = avio_rb16(pb);
6788 dovi->dv_profile = (buf >> 9) & 0x7f; // 7 bits
6789 dovi->dv_level = (buf >> 3) & 0x3f; // 6 bits
6790 dovi->rpu_present_flag = (buf >> 2) & 0x01; // 1 bit
6791 dovi->el_present_flag = (buf >> 1) & 0x01; // 1 bit
6792 dovi->bl_present_flag = buf & 0x01; // 1 bit
6793 if (atom.size >= 24) { // 4 + 4 + 4 * 4
6795 dovi->dv_bl_signal_compatibility_id = (buf >> 4) & 0x0f; // 4 bits
6797 // 0 stands for None
6798 // Dolby Vision V1.2.93 profiles and levels
6799 dovi->dv_bl_signal_compatibility_id = 0;
6802 ret = av_stream_add_side_data(st, AV_PKT_DATA_DOVI_CONF,
6803 (uint8_t *)dovi, dovi_size);
6809 av_log(c, AV_LOG_TRACE, "DOVI in dvcC/dvvC box, version: %d.%d, profile: %d, level: %d, "
6810 "rpu flag: %d, el flag: %d, bl flag: %d, compatibility id: %d\n",
6811 dovi->dv_version_major, dovi->dv_version_minor,
6812 dovi->dv_profile, dovi->dv_level,
6813 dovi->rpu_present_flag,
6814 dovi->el_present_flag,
6815 dovi->bl_present_flag,
6816 dovi->dv_bl_signal_compatibility_id
6822 static const MOVParseTableEntry mov_default_parse_table[] = {
6823 { MKTAG('A','C','L','R'), mov_read_aclr },
6824 { MKTAG('A','P','R','G'), mov_read_avid },
6825 { MKTAG('A','A','L','P'), mov_read_avid },
6826 { MKTAG('A','R','E','S'), mov_read_ares },
6827 { MKTAG('a','v','s','s'), mov_read_avss },
6828 { MKTAG('a','v','1','C'), mov_read_av1c },
6829 { MKTAG('c','h','p','l'), mov_read_chpl },
6830 { MKTAG('c','o','6','4'), mov_read_stco },
6831 { MKTAG('c','o','l','r'), mov_read_colr },
6832 { MKTAG('c','t','t','s'), mov_read_ctts }, /* composition time to sample */
6833 { MKTAG('d','i','n','f'), mov_read_default },
6834 { MKTAG('D','p','x','E'), mov_read_dpxe },
6835 { MKTAG('d','r','e','f'), mov_read_dref },
6836 { MKTAG('e','d','t','s'), mov_read_default },
6837 { MKTAG('e','l','s','t'), mov_read_elst },
6838 { MKTAG('e','n','d','a'), mov_read_enda },
6839 { MKTAG('f','i','e','l'), mov_read_fiel },
6840 { MKTAG('a','d','r','m'), mov_read_adrm },
6841 { MKTAG('f','t','y','p'), mov_read_ftyp },
6842 { MKTAG('g','l','b','l'), mov_read_glbl },
6843 { MKTAG('h','d','l','r'), mov_read_hdlr },
6844 { MKTAG('i','l','s','t'), mov_read_ilst },
6845 { MKTAG('j','p','2','h'), mov_read_jp2h },
6846 { MKTAG('m','d','a','t'), mov_read_mdat },
6847 { MKTAG('m','d','h','d'), mov_read_mdhd },
6848 { MKTAG('m','d','i','a'), mov_read_default },
6849 { MKTAG('m','e','t','a'), mov_read_meta },
6850 { MKTAG('m','i','n','f'), mov_read_default },
6851 { MKTAG('m','o','o','f'), mov_read_moof },
6852 { MKTAG('m','o','o','v'), mov_read_moov },
6853 { MKTAG('m','v','e','x'), mov_read_default },
6854 { MKTAG('m','v','h','d'), mov_read_mvhd },
6855 { MKTAG('S','M','I',' '), mov_read_svq3 },
6856 { MKTAG('a','l','a','c'), mov_read_alac }, /* alac specific atom */
6857 { MKTAG('a','v','c','C'), mov_read_glbl },
6858 { MKTAG('p','a','s','p'), mov_read_pasp },
6859 { MKTAG('s','i','d','x'), mov_read_sidx },
6860 { MKTAG('s','t','b','l'), mov_read_default },
6861 { MKTAG('s','t','c','o'), mov_read_stco },
6862 { MKTAG('s','t','p','s'), mov_read_stps },
6863 { MKTAG('s','t','r','f'), mov_read_strf },
6864 { MKTAG('s','t','s','c'), mov_read_stsc },
6865 { MKTAG('s','t','s','d'), mov_read_stsd }, /* sample description */
6866 { MKTAG('s','t','s','s'), mov_read_stss }, /* sync sample */
6867 { MKTAG('s','t','s','z'), mov_read_stsz }, /* sample size */
6868 { MKTAG('s','t','t','s'), mov_read_stts },
6869 { MKTAG('s','t','z','2'), mov_read_stsz }, /* compact sample size */
6870 { MKTAG('s','d','t','p'), mov_read_sdtp }, /* independent and disposable samples */
6871 { MKTAG('t','k','h','d'), mov_read_tkhd }, /* track header */
6872 { MKTAG('t','f','d','t'), mov_read_tfdt },
6873 { MKTAG('t','f','h','d'), mov_read_tfhd }, /* track fragment header */
6874 { MKTAG('t','r','a','k'), mov_read_trak },
6875 { MKTAG('t','r','a','f'), mov_read_default },
6876 { MKTAG('t','r','e','f'), mov_read_default },
6877 { MKTAG('t','m','c','d'), mov_read_tmcd },
6878 { MKTAG('c','h','a','p'), mov_read_chap },
6879 { MKTAG('t','r','e','x'), mov_read_trex },
6880 { MKTAG('t','r','u','n'), mov_read_trun },
6881 { MKTAG('u','d','t','a'), mov_read_default },
6882 { MKTAG('w','a','v','e'), mov_read_wave },
6883 { MKTAG('e','s','d','s'), mov_read_esds },
6884 { MKTAG('d','a','c','3'), mov_read_dac3 }, /* AC-3 info */
6885 { MKTAG('d','e','c','3'), mov_read_dec3 }, /* EAC-3 info */
6886 { MKTAG('d','d','t','s'), mov_read_ddts }, /* DTS audio descriptor */
6887 { MKTAG('w','i','d','e'), mov_read_wide }, /* place holder */
6888 { MKTAG('w','f','e','x'), mov_read_wfex },
6889 { MKTAG('c','m','o','v'), mov_read_cmov },
6890 { MKTAG('c','h','a','n'), mov_read_chan }, /* channel layout */
6891 { MKTAG('d','v','c','1'), mov_read_dvc1 },
6892 { MKTAG('s','b','g','p'), mov_read_sbgp },
6893 { MKTAG('h','v','c','C'), mov_read_glbl },
6894 { MKTAG('u','u','i','d'), mov_read_uuid },
6895 { MKTAG('C','i','n', 0x8e), mov_read_targa_y216 },
6896 { MKTAG('f','r','e','e'), mov_read_free },
6897 { MKTAG('-','-','-','-'), mov_read_custom },
6898 { MKTAG('s','i','n','f'), mov_read_default },
6899 { MKTAG('f','r','m','a'), mov_read_frma },
6900 { MKTAG('s','e','n','c'), mov_read_senc },
6901 { MKTAG('s','a','i','z'), mov_read_saiz },
6902 { MKTAG('s','a','i','o'), mov_read_saio },
6903 { MKTAG('p','s','s','h'), mov_read_pssh },
6904 { MKTAG('s','c','h','m'), mov_read_schm },
6905 { MKTAG('s','c','h','i'), mov_read_default },
6906 { MKTAG('t','e','n','c'), mov_read_tenc },
6907 { MKTAG('d','f','L','a'), mov_read_dfla },
6908 { MKTAG('s','t','3','d'), mov_read_st3d }, /* stereoscopic 3D video box */
6909 { MKTAG('s','v','3','d'), mov_read_sv3d }, /* spherical video box */
6910 { MKTAG('d','O','p','s'), mov_read_dops },
6911 { MKTAG('d','m','l','p'), mov_read_dmlp },
6912 { MKTAG('S','m','D','m'), mov_read_smdm },
6913 { MKTAG('C','o','L','L'), mov_read_coll },
6914 { MKTAG('v','p','c','C'), mov_read_vpcc },
6915 { MKTAG('m','d','c','v'), mov_read_mdcv },
6916 { MKTAG('c','l','l','i'), mov_read_clli },
6917 { MKTAG('d','v','c','C'), mov_read_dvcc_dvvc },
6918 { MKTAG('d','v','v','C'), mov_read_dvcc_dvvc },
6922 static int mov_read_default(MOVContext *c, AVIOContext *pb, MOVAtom atom)
6924 int64_t total_size = 0;
6928 if (c->atom_depth > 10) {
6929 av_log(c->fc, AV_LOG_ERROR, "Atoms too deeply nested\n");
6930 return AVERROR_INVALIDDATA;
6935 atom.size = INT64_MAX;
6936 while (total_size <= atom.size - 8 && !avio_feof(pb)) {
6937 int (*parse)(MOVContext*, AVIOContext*, MOVAtom) = NULL;
6940 if (atom.size >= 8) {
6941 a.size = avio_rb32(pb);
6942 a.type = avio_rl32(pb);
6943 if (((a.type == MKTAG('f','r','e','e') && c->moov_retry) ||
6944 a.type == MKTAG('h','o','o','v')) &&
6946 c->fc->strict_std_compliance < FF_COMPLIANCE_STRICT) {
6949 type = avio_rl32(pb);
6950 avio_seek(pb, -8, SEEK_CUR);
6951 if (type == MKTAG('m','v','h','d') ||
6952 type == MKTAG('c','m','o','v')) {
6953 av_log(c->fc, AV_LOG_ERROR, "Detected moov in a free or hoov atom.\n");
6954 a.type = MKTAG('m','o','o','v');
6957 if (atom.type != MKTAG('r','o','o','t') &&
6958 atom.type != MKTAG('m','o','o','v')) {
6959 if (a.type == MKTAG('t','r','a','k') ||
6960 a.type == MKTAG('m','d','a','t')) {
6961 av_log(c->fc, AV_LOG_ERROR, "Broken file, trak/mdat not at top-level\n");
6968 if (a.size == 1 && total_size + 8 <= atom.size) { /* 64 bit extended size */
6969 a.size = avio_rb64(pb) - 8;
6973 av_log(c->fc, AV_LOG_TRACE, "type:'%s' parent:'%s' sz: %"PRId64" %"PRId64" %"PRId64"\n",
6974 av_fourcc2str(a.type), av_fourcc2str(atom.type), a.size, total_size, atom.size);
6976 a.size = atom.size - total_size + 8;
6981 a.size = FFMIN(a.size, atom.size - total_size);
6983 for (i = 0; mov_default_parse_table[i].type; i++)
6984 if (mov_default_parse_table[i].type == a.type) {
6985 parse = mov_default_parse_table[i].parse;
6989 // container is user data
6990 if (!parse && (atom.type == MKTAG('u','d','t','a') ||
6991 atom.type == MKTAG('i','l','s','t')))
6992 parse = mov_read_udta_string;
6994 // Supports parsing the QuickTime Metadata Keys.
6995 // https://developer.apple.com/library/mac/documentation/QuickTime/QTFF/Metadata/Metadata.html
6996 if (!parse && c->found_hdlr_mdta &&
6997 atom.type == MKTAG('m','e','t','a') &&
6998 a.type == MKTAG('k','e','y','s') &&
6999 c->meta_keys_count == 0) {
7000 parse = mov_read_keys;
7003 if (!parse) { /* skip leaf atoms data */
7004 avio_skip(pb, a.size);
7006 int64_t start_pos = avio_tell(pb);
7008 int err = parse(c, pb, a);
7013 if (c->found_moov && c->found_mdat &&
7014 ((!(pb->seekable & AVIO_SEEKABLE_NORMAL) || c->fc->flags & AVFMT_FLAG_IGNIDX || c->frag_index.complete) ||
7015 start_pos + a.size == avio_size(pb))) {
7016 if (!(pb->seekable & AVIO_SEEKABLE_NORMAL) || c->fc->flags & AVFMT_FLAG_IGNIDX || c->frag_index.complete)
7017 c->next_root_atom = start_pos + a.size;
7021 left = a.size - avio_tell(pb) + start_pos;
7022 if (left > 0) /* skip garbage at atom end */
7023 avio_skip(pb, left);
7024 else if (left < 0) {
7025 av_log(c->fc, AV_LOG_WARNING,
7026 "overread end of atom '%s' by %"PRId64" bytes\n",
7027 av_fourcc2str(a.type), -left);
7028 avio_seek(pb, left, SEEK_CUR);
7032 total_size += a.size;
7035 if (total_size < atom.size && atom.size < 0x7ffff)
7036 avio_skip(pb, atom.size - total_size);
7042 static int mov_probe(const AVProbeData *p)
7047 int moov_offset = -1;
7049 /* check file header */
7052 /* ignore invalid offset */
7053 if ((offset + 8) > (unsigned int)p->buf_size)
7055 tag = AV_RL32(p->buf + offset + 4);
7057 /* check for obvious tags */
7058 case MKTAG('m','o','o','v'):
7059 moov_offset = offset + 4;
7060 case MKTAG('m','d','a','t'):
7061 case MKTAG('p','n','o','t'): /* detect movs with preview pics like ew.mov and april.mov */
7062 case MKTAG('u','d','t','a'): /* Packet Video PVAuthor adds this and a lot of more junk */
7063 case MKTAG('f','t','y','p'):
7064 if (AV_RB32(p->buf+offset) < 8 &&
7065 (AV_RB32(p->buf+offset) != 1 ||
7066 offset + 12 > (unsigned int)p->buf_size ||
7067 AV_RB64(p->buf+offset + 8) == 0)) {
7068 score = FFMAX(score, AVPROBE_SCORE_EXTENSION);
7069 } else if (tag == MKTAG('f','t','y','p') &&
7070 ( AV_RL32(p->buf + offset + 8) == MKTAG('j','p','2',' ')
7071 || AV_RL32(p->buf + offset + 8) == MKTAG('j','p','x',' ')
7073 score = FFMAX(score, 5);
7075 score = AVPROBE_SCORE_MAX;
7077 offset = FFMAX(4, AV_RB32(p->buf+offset)) + offset;
7079 /* those are more common words, so rate then a bit less */
7080 case MKTAG('e','d','i','w'): /* xdcam files have reverted first tags */
7081 case MKTAG('w','i','d','e'):
7082 case MKTAG('f','r','e','e'):
7083 case MKTAG('j','u','n','k'):
7084 case MKTAG('p','i','c','t'):
7085 score = FFMAX(score, AVPROBE_SCORE_MAX - 5);
7086 offset = FFMAX(4, AV_RB32(p->buf+offset)) + offset;
7088 case MKTAG(0x82,0x82,0x7f,0x7d):
7089 case MKTAG('s','k','i','p'):
7090 case MKTAG('u','u','i','d'):
7091 case MKTAG('p','r','f','l'):
7092 /* if we only find those cause probedata is too small at least rate them */
7093 score = FFMAX(score, AVPROBE_SCORE_EXTENSION);
7094 offset = FFMAX(4, AV_RB32(p->buf+offset)) + offset;
7097 offset = FFMAX(4, AV_RB32(p->buf+offset)) + offset;
7100 if (score > AVPROBE_SCORE_MAX - 50 && moov_offset != -1) {
7101 /* moov atom in the header - we should make sure that this is not a
7102 * MOV-packed MPEG-PS */
7103 offset = moov_offset;
7105 while (offset < (p->buf_size - 16)) { /* Sufficient space */
7106 /* We found an actual hdlr atom */
7107 if (AV_RL32(p->buf + offset ) == MKTAG('h','d','l','r') &&
7108 AV_RL32(p->buf + offset + 8) == MKTAG('m','h','l','r') &&
7109 AV_RL32(p->buf + offset + 12) == MKTAG('M','P','E','G')) {
7110 av_log(NULL, AV_LOG_WARNING, "Found media data tag MPEG indicating this is a MOV-packed MPEG-PS.\n");
7111 /* We found a media handler reference atom describing an
7112 * MPEG-PS-in-MOV, return a
7113 * low score to force expanding the probe window until
7114 * mpegps_probe finds what it needs */
7126 // must be done after parsing all trak because there's no order requirement
7127 static void mov_read_chapters(AVFormatContext *s)
7129 MOVContext *mov = s->priv_data;
7131 MOVStreamContext *sc;
7136 for (j = 0; j < mov->nb_chapter_tracks; j++) {
7137 chapter_track = mov->chapter_tracks[j];
7139 for (i = 0; i < s->nb_streams; i++)
7140 if (s->streams[i]->id == chapter_track) {
7145 av_log(s, AV_LOG_ERROR, "Referenced QT chapter track not found\n");
7150 cur_pos = avio_tell(sc->pb);
7152 if (st->codecpar->codec_type == AVMEDIA_TYPE_VIDEO) {
7153 st->disposition |= AV_DISPOSITION_ATTACHED_PIC | AV_DISPOSITION_TIMED_THUMBNAILS;
7154 if (st->nb_index_entries) {
7155 // Retrieve the first frame, if possible
7156 AVIndexEntry *sample = &st->index_entries[0];
7157 if (avio_seek(sc->pb, sample->pos, SEEK_SET) != sample->pos) {
7158 av_log(s, AV_LOG_ERROR, "Failed to retrieve first frame\n");
7162 if (av_get_packet(sc->pb, &st->attached_pic, sample->size) < 0)
7165 st->attached_pic.stream_index = st->index;
7166 st->attached_pic.flags |= AV_PKT_FLAG_KEY;
7169 st->codecpar->codec_type = AVMEDIA_TYPE_DATA;
7170 st->codecpar->codec_id = AV_CODEC_ID_BIN_DATA;
7171 st->discard = AVDISCARD_ALL;
7172 for (i = 0; i < st->nb_index_entries; i++) {
7173 AVIndexEntry *sample = &st->index_entries[i];
7174 int64_t end = i+1 < st->nb_index_entries ? st->index_entries[i+1].timestamp : st->duration;
7179 if (end < sample->timestamp) {
7180 av_log(s, AV_LOG_WARNING, "ignoring stream duration which is shorter than chapters\n");
7181 end = AV_NOPTS_VALUE;
7184 if (avio_seek(sc->pb, sample->pos, SEEK_SET) != sample->pos) {
7185 av_log(s, AV_LOG_ERROR, "Chapter %d not found in file\n", i);
7189 // the first two bytes are the length of the title
7190 len = avio_rb16(sc->pb);
7191 if (len > sample->size-2)
7193 title_len = 2*len + 1;
7194 if (!(title = av_mallocz(title_len)))
7197 // The samples could theoretically be in any encoding if there's an encd
7198 // atom following, but in practice are only utf-8 or utf-16, distinguished
7199 // instead by the presence of a BOM
7203 ch = avio_rb16(sc->pb);
7205 avio_get_str16be(sc->pb, len, title, title_len);
7206 else if (ch == 0xfffe)
7207 avio_get_str16le(sc->pb, len, title, title_len);
7210 if (len == 1 || len == 2)
7213 avio_get_str(sc->pb, INT_MAX, title + 2, len - 1);
7217 avpriv_new_chapter(s, i, st->time_base, sample->timestamp, end, title);
7222 avio_seek(sc->pb, cur_pos, SEEK_SET);
7226 static int parse_timecode_in_framenum_format(AVFormatContext *s, AVStream *st,
7227 uint32_t value, int flags)
7230 char buf[AV_TIMECODE_STR_SIZE];
7231 AVRational rate = st->avg_frame_rate;
7232 int ret = av_timecode_init(&tc, rate, flags, 0, s);
7235 av_dict_set(&st->metadata, "timecode",
7236 av_timecode_make_string(&tc, buf, value), 0);
7240 static int mov_read_rtmd_track(AVFormatContext *s, AVStream *st)
7242 MOVStreamContext *sc = st->priv_data;
7243 char buf[AV_TIMECODE_STR_SIZE];
7244 int64_t cur_pos = avio_tell(sc->pb);
7245 int hh, mm, ss, ff, drop;
7247 if (!st->nb_index_entries)
7250 avio_seek(sc->pb, st->index_entries->pos, SEEK_SET);
7251 avio_skip(s->pb, 13);
7252 hh = avio_r8(s->pb);
7253 mm = avio_r8(s->pb);
7254 ss = avio_r8(s->pb);
7255 drop = avio_r8(s->pb);
7256 ff = avio_r8(s->pb);
7257 snprintf(buf, AV_TIMECODE_STR_SIZE, "%02d:%02d:%02d%c%02d",
7258 hh, mm, ss, drop ? ';' : ':', ff);
7259 av_dict_set(&st->metadata, "timecode", buf, 0);
7261 avio_seek(sc->pb, cur_pos, SEEK_SET);
7265 static int mov_read_timecode_track(AVFormatContext *s, AVStream *st)
7267 MOVStreamContext *sc = st->priv_data;
7269 int64_t cur_pos = avio_tell(sc->pb);
7272 if (!st->nb_index_entries)
7275 avio_seek(sc->pb, st->index_entries->pos, SEEK_SET);
7276 value = avio_rb32(s->pb);
7278 if (sc->tmcd_flags & 0x0001) flags |= AV_TIMECODE_FLAG_DROPFRAME;
7279 if (sc->tmcd_flags & 0x0002) flags |= AV_TIMECODE_FLAG_24HOURSMAX;
7280 if (sc->tmcd_flags & 0x0004) flags |= AV_TIMECODE_FLAG_ALLOWNEGATIVE;
7282 /* Assume Counter flag is set to 1 in tmcd track (even though it is likely
7283 * not the case) and thus assume "frame number format" instead of QT one.
7284 * No sample with tmcd track can be found with a QT timecode at the moment,
7285 * despite what the tmcd track "suggests" (Counter flag set to 0 means QT
7287 parse_timecode_in_framenum_format(s, st, value, flags);
7289 avio_seek(sc->pb, cur_pos, SEEK_SET);
7293 static void mov_free_encryption_index(MOVEncryptionIndex **index) {
7295 if (!index || !*index) return;
7296 for (i = 0; i < (*index)->nb_encrypted_samples; i++) {
7297 av_encryption_info_free((*index)->encrypted_samples[i]);
7299 av_freep(&(*index)->encrypted_samples);
7300 av_freep(&(*index)->auxiliary_info_sizes);
7301 av_freep(&(*index)->auxiliary_offsets);
7305 static int mov_read_close(AVFormatContext *s)
7307 MOVContext *mov = s->priv_data;
7310 for (i = 0; i < s->nb_streams; i++) {
7311 AVStream *st = s->streams[i];
7312 MOVStreamContext *sc = st->priv_data;
7317 av_freep(&sc->ctts_data);
7318 for (j = 0; j < sc->drefs_count; j++) {
7319 av_freep(&sc->drefs[j].path);
7320 av_freep(&sc->drefs[j].dir);
7322 av_freep(&sc->drefs);
7324 sc->drefs_count = 0;
7326 if (!sc->pb_is_copied)
7327 ff_format_io_close(s, &sc->pb);
7330 av_freep(&sc->chunk_offsets);
7331 av_freep(&sc->stsc_data);
7332 av_freep(&sc->sample_sizes);
7333 av_freep(&sc->keyframes);
7334 av_freep(&sc->stts_data);
7335 av_freep(&sc->sdtp_data);
7336 av_freep(&sc->stps_data);
7337 av_freep(&sc->elst_data);
7338 av_freep(&sc->rap_group);
7339 av_freep(&sc->display_matrix);
7340 av_freep(&sc->index_ranges);
7343 for (j = 0; j < sc->stsd_count; j++)
7344 av_free(sc->extradata[j]);
7345 av_freep(&sc->extradata);
7346 av_freep(&sc->extradata_size);
7348 mov_free_encryption_index(&sc->cenc.encryption_index);
7349 av_encryption_info_free(sc->cenc.default_encrypted_sample);
7350 av_aes_ctr_free(sc->cenc.aes_ctr);
7352 av_freep(&sc->stereo3d);
7353 av_freep(&sc->spherical);
7354 av_freep(&sc->mastering);
7355 av_freep(&sc->coll);
7358 av_freep(&mov->dv_demux);
7359 avformat_free_context(mov->dv_fctx);
7360 mov->dv_fctx = NULL;
7362 if (mov->meta_keys) {
7363 for (i = 1; i < mov->meta_keys_count; i++) {
7364 av_freep(&mov->meta_keys[i]);
7366 av_freep(&mov->meta_keys);
7369 av_freep(&mov->trex_data);
7370 av_freep(&mov->bitrates);
7372 for (i = 0; i < mov->frag_index.nb_items; i++) {
7373 MOVFragmentStreamInfo *frag = mov->frag_index.item[i].stream_info;
7374 for (j = 0; j < mov->frag_index.item[i].nb_stream_info; j++) {
7375 mov_free_encryption_index(&frag[j].encryption_index);
7377 av_freep(&mov->frag_index.item[i].stream_info);
7379 av_freep(&mov->frag_index.item);
7381 av_freep(&mov->aes_decrypt);
7382 av_freep(&mov->chapter_tracks);
7387 static int tmcd_is_referenced(AVFormatContext *s, int tmcd_id)
7391 for (i = 0; i < s->nb_streams; i++) {
7392 AVStream *st = s->streams[i];
7393 MOVStreamContext *sc = st->priv_data;
7395 if (st->codecpar->codec_type == AVMEDIA_TYPE_VIDEO &&
7396 sc->timecode_track == tmcd_id)
7402 /* look for a tmcd track not referenced by any video track, and export it globally */
7403 static void export_orphan_timecode(AVFormatContext *s)
7407 for (i = 0; i < s->nb_streams; i++) {
7408 AVStream *st = s->streams[i];
7410 if (st->codecpar->codec_tag == MKTAG('t','m','c','d') &&
7411 !tmcd_is_referenced(s, i + 1)) {
7412 AVDictionaryEntry *tcr = av_dict_get(st->metadata, "timecode", NULL, 0);
7414 av_dict_set(&s->metadata, "timecode", tcr->value, 0);
7421 static int read_tfra(MOVContext *mov, AVIOContext *f)
7423 int version, fieldlength, i, j;
7424 int64_t pos = avio_tell(f);
7425 uint32_t size = avio_rb32(f);
7426 unsigned track_id, item_count;
7428 if (avio_rb32(f) != MKBETAG('t', 'f', 'r', 'a')) {
7431 av_log(mov->fc, AV_LOG_VERBOSE, "found tfra\n");
7433 version = avio_r8(f);
7435 track_id = avio_rb32(f);
7436 fieldlength = avio_rb32(f);
7437 item_count = avio_rb32(f);
7438 for (i = 0; i < item_count; i++) {
7439 int64_t time, offset;
7441 MOVFragmentStreamInfo * frag_stream_info;
7444 return AVERROR_INVALIDDATA;
7448 time = avio_rb64(f);
7449 offset = avio_rb64(f);
7451 time = avio_rb32(f);
7452 offset = avio_rb32(f);
7455 // The first sample of each stream in a fragment is always a random
7456 // access sample. So it's entry in the tfra can be used as the
7457 // initial PTS of the fragment.
7458 index = update_frag_index(mov, offset);
7459 frag_stream_info = get_frag_stream_info(&mov->frag_index, index, track_id);
7460 if (frag_stream_info &&
7461 frag_stream_info->first_tfra_pts == AV_NOPTS_VALUE)
7462 frag_stream_info->first_tfra_pts = time;
7464 for (j = 0; j < ((fieldlength >> 4) & 3) + 1; j++)
7466 for (j = 0; j < ((fieldlength >> 2) & 3) + 1; j++)
7468 for (j = 0; j < ((fieldlength >> 0) & 3) + 1; j++)
7472 avio_seek(f, pos + size, SEEK_SET);
7476 static int mov_read_mfra(MOVContext *c, AVIOContext *f)
7478 int64_t stream_size = avio_size(f);
7479 int64_t original_pos = avio_tell(f);
7483 if ((seek_ret = avio_seek(f, stream_size - 4, SEEK_SET)) < 0) {
7487 mfra_size = avio_rb32(f);
7488 if (mfra_size < 0 || mfra_size > stream_size) {
7489 av_log(c->fc, AV_LOG_DEBUG, "doesn't look like mfra (unreasonable size)\n");
7492 if ((seek_ret = avio_seek(f, -mfra_size, SEEK_CUR)) < 0) {
7496 if (avio_rb32(f) != mfra_size) {
7497 av_log(c->fc, AV_LOG_DEBUG, "doesn't look like mfra (size mismatch)\n");
7500 if (avio_rb32(f) != MKBETAG('m', 'f', 'r', 'a')) {
7501 av_log(c->fc, AV_LOG_DEBUG, "doesn't look like mfra (tag mismatch)\n");
7504 av_log(c->fc, AV_LOG_VERBOSE, "stream has mfra\n");
7506 ret = read_tfra(c, f);
7512 seek_ret = avio_seek(f, original_pos, SEEK_SET);
7514 av_log(c->fc, AV_LOG_ERROR,
7515 "failed to seek back after looking for mfra\n");
7521 static int mov_read_header(AVFormatContext *s)
7523 MOVContext *mov = s->priv_data;
7524 AVIOContext *pb = s->pb;
7526 MOVAtom atom = { AV_RL32("root") };
7529 if (mov->decryption_key_len != 0 && mov->decryption_key_len != AES_CTR_KEY_SIZE) {
7530 av_log(s, AV_LOG_ERROR, "Invalid decryption key len %d expected %d\n",
7531 mov->decryption_key_len, AES_CTR_KEY_SIZE);
7532 return AVERROR(EINVAL);
7536 mov->trak_index = -1;
7537 /* .mov and .mp4 aren't streamable anyway (only progressive download if moov is before mdat) */
7538 if (pb->seekable & AVIO_SEEKABLE_NORMAL)
7539 atom.size = avio_size(pb);
7541 atom.size = INT64_MAX;
7543 /* check MOV header */
7545 if (mov->moov_retry)
7546 avio_seek(pb, 0, SEEK_SET);
7547 if ((err = mov_read_default(mov, pb, atom)) < 0) {
7548 av_log(s, AV_LOG_ERROR, "error reading header\n");
7551 } while ((pb->seekable & AVIO_SEEKABLE_NORMAL) && !mov->found_moov && !mov->moov_retry++);
7552 if (!mov->found_moov) {
7553 av_log(s, AV_LOG_ERROR, "moov atom not found\n");
7554 err = AVERROR_INVALIDDATA;
7557 av_log(mov->fc, AV_LOG_TRACE, "on_parse_exit_offset=%"PRId64"\n", avio_tell(pb));
7559 if (pb->seekable & AVIO_SEEKABLE_NORMAL) {
7560 if (mov->nb_chapter_tracks > 0 && !mov->ignore_chapters)
7561 mov_read_chapters(s);
7562 for (i = 0; i < s->nb_streams; i++)
7563 if (s->streams[i]->codecpar->codec_tag == AV_RL32("tmcd")) {
7564 mov_read_timecode_track(s, s->streams[i]);
7565 } else if (s->streams[i]->codecpar->codec_tag == AV_RL32("rtmd")) {
7566 mov_read_rtmd_track(s, s->streams[i]);
7570 /* copy timecode metadata from tmcd tracks to the related video streams */
7571 for (i = 0; i < s->nb_streams; i++) {
7572 AVStream *st = s->streams[i];
7573 MOVStreamContext *sc = st->priv_data;
7574 if (sc->timecode_track > 0) {
7575 AVDictionaryEntry *tcr;
7576 int tmcd_st_id = -1;
7578 for (j = 0; j < s->nb_streams; j++)
7579 if (s->streams[j]->id == sc->timecode_track)
7582 if (tmcd_st_id < 0 || tmcd_st_id == i)
7584 tcr = av_dict_get(s->streams[tmcd_st_id]->metadata, "timecode", NULL, 0);
7586 av_dict_set(&st->metadata, "timecode", tcr->value, 0);
7589 export_orphan_timecode(s);
7591 for (i = 0; i < s->nb_streams; i++) {
7592 AVStream *st = s->streams[i];
7593 MOVStreamContext *sc = st->priv_data;
7594 fix_timescale(mov, sc);
7595 if (st->codecpar->codec_type == AVMEDIA_TYPE_AUDIO &&
7596 st->codecpar->codec_id == AV_CODEC_ID_AAC) {
7597 st->skip_samples = sc->start_pad;
7599 if (st->codecpar->codec_type == AVMEDIA_TYPE_VIDEO && sc->nb_frames_for_fps > 0 && sc->duration_for_fps > 0)
7600 av_reduce(&st->avg_frame_rate.num, &st->avg_frame_rate.den,
7601 sc->time_scale*(int64_t)sc->nb_frames_for_fps, sc->duration_for_fps, INT_MAX);
7602 if (st->codecpar->codec_type == AVMEDIA_TYPE_SUBTITLE) {
7603 if (st->codecpar->width <= 0 || st->codecpar->height <= 0) {
7604 st->codecpar->width = sc->width;
7605 st->codecpar->height = sc->height;
7607 if (st->codecpar->codec_id == AV_CODEC_ID_DVD_SUBTITLE) {
7608 if ((err = mov_rewrite_dvd_sub_extradata(st)) < 0)
7612 if (mov->handbrake_version &&
7613 mov->handbrake_version <= 1000000*0 + 1000*10 + 2 && // 0.10.2
7614 st->codecpar->codec_id == AV_CODEC_ID_MP3) {
7615 av_log(s, AV_LOG_VERBOSE, "Forcing full parsing for mp3 stream\n");
7616 st->need_parsing = AVSTREAM_PARSE_FULL;
7620 if (mov->trex_data) {
7621 for (i = 0; i < s->nb_streams; i++) {
7622 AVStream *st = s->streams[i];
7623 MOVStreamContext *sc = st->priv_data;
7624 if (st->duration > 0) {
7625 if (sc->data_size > INT64_MAX / sc->time_scale / 8) {
7626 av_log(s, AV_LOG_ERROR, "Overflow during bit rate calculation %"PRId64" * 8 * %d\n",
7627 sc->data_size, sc->time_scale);
7628 err = AVERROR_INVALIDDATA;
7631 st->codecpar->bit_rate = sc->data_size * 8 * sc->time_scale / st->duration;
7636 if (mov->use_mfra_for > 0) {
7637 for (i = 0; i < s->nb_streams; i++) {
7638 AVStream *st = s->streams[i];
7639 MOVStreamContext *sc = st->priv_data;
7640 if (sc->duration_for_fps > 0) {
7641 if (sc->data_size > INT64_MAX / sc->time_scale / 8) {
7642 av_log(s, AV_LOG_ERROR, "Overflow during bit rate calculation %"PRId64" * 8 * %d\n",
7643 sc->data_size, sc->time_scale);
7644 err = AVERROR_INVALIDDATA;
7647 st->codecpar->bit_rate = sc->data_size * 8 * sc->time_scale /
7648 sc->duration_for_fps;
7653 for (i = 0; i < mov->bitrates_count && i < s->nb_streams; i++) {
7654 if (mov->bitrates[i]) {
7655 s->streams[i]->codecpar->bit_rate = mov->bitrates[i];
7659 ff_rfps_calculate(s);
7661 for (i = 0; i < s->nb_streams; i++) {
7662 AVStream *st = s->streams[i];
7663 MOVStreamContext *sc = st->priv_data;
7665 switch (st->codecpar->codec_type) {
7666 case AVMEDIA_TYPE_AUDIO:
7667 err = ff_replaygain_export(st, s->metadata);
7671 case AVMEDIA_TYPE_VIDEO:
7672 if (sc->display_matrix) {
7673 err = av_stream_add_side_data(st, AV_PKT_DATA_DISPLAYMATRIX, (uint8_t*)sc->display_matrix,
7674 sizeof(int32_t) * 9);
7678 sc->display_matrix = NULL;
7681 err = av_stream_add_side_data(st, AV_PKT_DATA_STEREO3D,
7682 (uint8_t *)sc->stereo3d,
7683 sizeof(*sc->stereo3d));
7687 sc->stereo3d = NULL;
7689 if (sc->spherical) {
7690 err = av_stream_add_side_data(st, AV_PKT_DATA_SPHERICAL,
7691 (uint8_t *)sc->spherical,
7692 sc->spherical_size);
7696 sc->spherical = NULL;
7698 if (sc->mastering) {
7699 err = av_stream_add_side_data(st, AV_PKT_DATA_MASTERING_DISPLAY_METADATA,
7700 (uint8_t *)sc->mastering,
7701 sizeof(*sc->mastering));
7705 sc->mastering = NULL;
7708 err = av_stream_add_side_data(st, AV_PKT_DATA_CONTENT_LIGHT_LEVEL,
7709 (uint8_t *)sc->coll,
7719 ff_configure_buffers_for_index(s, AV_TIME_BASE);
7721 for (i = 0; i < mov->frag_index.nb_items; i++)
7722 if (mov->frag_index.item[i].moof_offset <= mov->fragment.moof_offset)
7723 mov->frag_index.item[i].headers_read = 1;
7731 static AVIndexEntry *mov_find_next_sample(AVFormatContext *s, AVStream **st)
7733 AVIndexEntry *sample = NULL;
7734 int64_t best_dts = INT64_MAX;
7736 for (i = 0; i < s->nb_streams; i++) {
7737 AVStream *avst = s->streams[i];
7738 MOVStreamContext *msc = avst->priv_data;
7739 if (msc->pb && msc->current_sample < avst->nb_index_entries) {
7740 AVIndexEntry *current_sample = &avst->index_entries[msc->current_sample];
7741 int64_t dts = av_rescale(current_sample->timestamp, AV_TIME_BASE, msc->time_scale);
7742 av_log(s, AV_LOG_TRACE, "stream %d, sample %d, dts %"PRId64"\n", i, msc->current_sample, dts);
7743 if (!sample || (!(s->pb->seekable & AVIO_SEEKABLE_NORMAL) && current_sample->pos < sample->pos) ||
7744 ((s->pb->seekable & AVIO_SEEKABLE_NORMAL) &&
7745 ((msc->pb != s->pb && dts < best_dts) || (msc->pb == s->pb && dts != AV_NOPTS_VALUE &&
7746 ((FFABS(best_dts - dts) <= AV_TIME_BASE && current_sample->pos < sample->pos) ||
7747 (FFABS(best_dts - dts) > AV_TIME_BASE && dts < best_dts)))))) {
7748 sample = current_sample;
7757 static int should_retry(AVIOContext *pb, int error_code) {
7758 if (error_code == AVERROR_EOF || avio_feof(pb))
7764 static int mov_switch_root(AVFormatContext *s, int64_t target, int index)
7767 MOVContext *mov = s->priv_data;
7769 if (index >= 0 && index < mov->frag_index.nb_items)
7770 target = mov->frag_index.item[index].moof_offset;
7771 if (avio_seek(s->pb, target, SEEK_SET) != target) {
7772 av_log(mov->fc, AV_LOG_ERROR, "root atom offset 0x%"PRIx64": partial file\n", target);
7773 return AVERROR_INVALIDDATA;
7776 mov->next_root_atom = 0;
7777 if (index < 0 || index >= mov->frag_index.nb_items)
7778 index = search_frag_moof_offset(&mov->frag_index, target);
7779 if (index < mov->frag_index.nb_items &&
7780 mov->frag_index.item[index].moof_offset == target) {
7781 if (index + 1 < mov->frag_index.nb_items)
7782 mov->next_root_atom = mov->frag_index.item[index + 1].moof_offset;
7783 if (mov->frag_index.item[index].headers_read)
7785 mov->frag_index.item[index].headers_read = 1;
7788 mov->found_mdat = 0;
7790 ret = mov_read_default(mov, s->pb, (MOVAtom){ AV_RL32("root"), INT64_MAX });
7793 if (avio_feof(s->pb))
7795 av_log(s, AV_LOG_TRACE, "read fragments, offset 0x%"PRIx64"\n", avio_tell(s->pb));
7800 static int mov_change_extradata(MOVStreamContext *sc, AVPacket *pkt)
7802 uint8_t *side, *extradata;
7805 /* Save the current index. */
7806 sc->last_stsd_index = sc->stsc_data[sc->stsc_index].id - 1;
7808 /* Notify the decoder that extradata changed. */
7809 extradata_size = sc->extradata_size[sc->last_stsd_index];
7810 extradata = sc->extradata[sc->last_stsd_index];
7811 if (extradata_size > 0 && extradata) {
7812 side = av_packet_new_side_data(pkt,
7813 AV_PKT_DATA_NEW_EXTRADATA,
7816 return AVERROR(ENOMEM);
7817 memcpy(side, extradata, extradata_size);
7823 static int get_eia608_packet(AVIOContext *pb, AVPacket *pkt, int size)
7828 return AVERROR_INVALIDDATA;
7829 new_size = ((size - 8) / 2) * 3;
7830 ret = av_new_packet(pkt, new_size);
7835 for (int j = 0; j < new_size; j += 3) {
7836 pkt->data[j] = 0xFC;
7837 pkt->data[j+1] = avio_r8(pb);
7838 pkt->data[j+2] = avio_r8(pb);
7844 static int mov_read_packet(AVFormatContext *s, AVPacket *pkt)
7846 MOVContext *mov = s->priv_data;
7847 MOVStreamContext *sc;
7848 AVIndexEntry *sample;
7849 AVStream *st = NULL;
7850 int64_t current_index;
7854 sample = mov_find_next_sample(s, &st);
7855 if (!sample || (mov->next_root_atom && sample->pos > mov->next_root_atom)) {
7856 if (!mov->next_root_atom)
7858 if ((ret = mov_switch_root(s, mov->next_root_atom, -1)) < 0)
7863 /* must be done just before reading, to avoid infinite loop on sample */
7864 current_index = sc->current_index;
7865 mov_current_sample_inc(sc);
7867 if (mov->next_root_atom) {
7868 sample->pos = FFMIN(sample->pos, mov->next_root_atom);
7869 sample->size = FFMIN(sample->size, (mov->next_root_atom - sample->pos));
7872 if (st->discard != AVDISCARD_ALL) {
7873 int64_t ret64 = avio_seek(sc->pb, sample->pos, SEEK_SET);
7874 if (ret64 != sample->pos) {
7875 av_log(mov->fc, AV_LOG_ERROR, "stream %d, offset 0x%"PRIx64": partial file\n",
7876 sc->ffindex, sample->pos);
7877 if (should_retry(sc->pb, ret64)) {
7878 mov_current_sample_dec(sc);
7880 return AVERROR_INVALIDDATA;
7883 if (st->discard == AVDISCARD_NONKEY && !(sample->flags & AVINDEX_KEYFRAME)) {
7884 av_log(mov->fc, AV_LOG_DEBUG, "Nonkey frame from stream %d discarded due to AVDISCARD_NONKEY\n", sc->ffindex);
7888 if (st->codecpar->codec_id == AV_CODEC_ID_EIA_608 && sample->size > 8)
7889 ret = get_eia608_packet(sc->pb, pkt, sample->size);
7891 ret = av_get_packet(sc->pb, pkt, sample->size);
7893 if (should_retry(sc->pb, ret)) {
7894 mov_current_sample_dec(sc);
7898 #if CONFIG_DV_DEMUXER
7899 if (mov->dv_demux && sc->dv_audio_container) {
7900 AVBufferRef *buf = pkt->buf;
7901 ret = avpriv_dv_produce_packet(mov->dv_demux, pkt, pkt->data, pkt->size, pkt->pos);
7903 av_packet_unref(pkt);
7906 ret = avpriv_dv_get_packet(mov->dv_demux, pkt);
7911 if (sc->has_palette) {
7914 pal = av_packet_new_side_data(pkt, AV_PKT_DATA_PALETTE, AVPALETTE_SIZE);
7916 av_log(mov->fc, AV_LOG_ERROR, "Cannot append palette to packet\n");
7918 memcpy(pal, sc->palette, AVPALETTE_SIZE);
7919 sc->has_palette = 0;
7922 if (st->codecpar->codec_id == AV_CODEC_ID_MP3 && !st->need_parsing && pkt->size > 4) {
7923 if (ff_mpa_check_header(AV_RB32(pkt->data)) < 0)
7924 st->need_parsing = AVSTREAM_PARSE_FULL;
7928 pkt->stream_index = sc->ffindex;
7929 pkt->dts = sample->timestamp;
7930 if (sample->flags & AVINDEX_DISCARD_FRAME) {
7931 pkt->flags |= AV_PKT_FLAG_DISCARD;
7933 if (sc->ctts_data && sc->ctts_index < sc->ctts_count) {
7934 pkt->pts = pkt->dts + sc->dts_shift + sc->ctts_data[sc->ctts_index].duration;
7935 /* update ctts context */
7937 if (sc->ctts_index < sc->ctts_count &&
7938 sc->ctts_data[sc->ctts_index].count == sc->ctts_sample) {
7940 sc->ctts_sample = 0;
7943 int64_t next_dts = (sc->current_sample < st->nb_index_entries) ?
7944 st->index_entries[sc->current_sample].timestamp : st->duration;
7946 if (next_dts >= pkt->dts)
7947 pkt->duration = next_dts - pkt->dts;
7948 pkt->pts = pkt->dts;
7950 if (st->discard == AVDISCARD_ALL)
7952 if (sc->sdtp_data && sc->current_sample <= sc->sdtp_count) {
7953 uint8_t sample_flags = sc->sdtp_data[sc->current_sample - 1];
7954 uint8_t sample_is_depended_on = (sample_flags >> 2) & 0x3;
7955 pkt->flags |= sample_is_depended_on == MOV_SAMPLE_DEPENDENCY_NO ? AV_PKT_FLAG_DISPOSABLE : 0;
7957 pkt->flags |= sample->flags & AVINDEX_KEYFRAME ? AV_PKT_FLAG_KEY : 0;
7958 pkt->pos = sample->pos;
7960 /* Multiple stsd handling. */
7961 if (sc->stsc_data) {
7962 /* Keep track of the stsc index for the given sample, then check
7963 * if the stsd index is different from the last used one. */
7965 if (mov_stsc_index_valid(sc->stsc_index, sc->stsc_count) &&
7966 mov_get_stsc_samples(sc, sc->stsc_index) == sc->stsc_sample) {
7968 sc->stsc_sample = 0;
7969 /* Do not check indexes after a switch. */
7970 } else if (sc->stsc_data[sc->stsc_index].id > 0 &&
7971 sc->stsc_data[sc->stsc_index].id - 1 < sc->stsd_count &&
7972 sc->stsc_data[sc->stsc_index].id - 1 != sc->last_stsd_index) {
7973 ret = mov_change_extradata(sc, pkt);
7980 aax_filter(pkt->data, pkt->size, mov);
7982 ret = cenc_filter(mov, st, sc, pkt, current_index);
7990 static int mov_seek_fragment(AVFormatContext *s, AVStream *st, int64_t timestamp)
7992 MOVContext *mov = s->priv_data;
7995 if (!mov->frag_index.complete)
7998 index = search_frag_timestamp(&mov->frag_index, st, timestamp);
8001 if (!mov->frag_index.item[index].headers_read)
8002 return mov_switch_root(s, -1, index);
8003 if (index + 1 < mov->frag_index.nb_items)
8004 mov->next_root_atom = mov->frag_index.item[index + 1].moof_offset;
8009 static int mov_seek_stream(AVFormatContext *s, AVStream *st, int64_t timestamp, int flags)
8011 MOVStreamContext *sc = st->priv_data;
8012 int sample, time_sample, ret;
8015 // Here we consider timestamp to be PTS, hence try to offset it so that we
8016 // can search over the DTS timeline.
8017 timestamp -= (sc->min_corrected_pts + sc->dts_shift);
8019 ret = mov_seek_fragment(s, st, timestamp);
8023 sample = av_index_search_timestamp(st, timestamp, flags);
8024 av_log(s, AV_LOG_TRACE, "stream %d, timestamp %"PRId64", sample %d\n", st->index, timestamp, sample);
8025 if (sample < 0 && st->nb_index_entries && timestamp < st->index_entries[0].timestamp)
8027 if (sample < 0) /* not sure what to do */
8028 return AVERROR_INVALIDDATA;
8029 mov_current_sample_set(sc, sample);
8030 av_log(s, AV_LOG_TRACE, "stream %d, found sample %d\n", st->index, sc->current_sample);
8031 /* adjust ctts index */
8032 if (sc->ctts_data) {
8034 for (i = 0; i < sc->ctts_count; i++) {
8035 int next = time_sample + sc->ctts_data[i].count;
8036 if (next > sc->current_sample) {
8038 sc->ctts_sample = sc->current_sample - time_sample;
8045 /* adjust stsd index */
8046 if (sc->chunk_count) {
8048 for (i = 0; i < sc->stsc_count; i++) {
8049 int64_t next = time_sample + mov_get_stsc_samples(sc, i);
8050 if (next > sc->current_sample) {
8052 sc->stsc_sample = sc->current_sample - time_sample;
8055 av_assert0(next == (int)next);
8063 static int mov_read_seek(AVFormatContext *s, int stream_index, int64_t sample_time, int flags)
8065 MOVContext *mc = s->priv_data;
8070 if (stream_index >= s->nb_streams)
8071 return AVERROR_INVALIDDATA;
8073 st = s->streams[stream_index];
8074 sample = mov_seek_stream(s, st, sample_time, flags);
8078 if (mc->seek_individually) {
8079 /* adjust seek timestamp to found sample timestamp */
8080 int64_t seek_timestamp = st->index_entries[sample].timestamp;
8082 for (i = 0; i < s->nb_streams; i++) {
8084 MOVStreamContext *sc = s->streams[i]->priv_data;
8086 st->skip_samples = (sample_time <= 0) ? sc->start_pad : 0;
8088 if (stream_index == i)
8091 timestamp = av_rescale_q(seek_timestamp, s->streams[stream_index]->time_base, st->time_base);
8092 mov_seek_stream(s, st, timestamp, flags);
8095 for (i = 0; i < s->nb_streams; i++) {
8096 MOVStreamContext *sc;
8099 mov_current_sample_set(sc, 0);
8102 MOVStreamContext *sc;
8103 AVIndexEntry *entry = mov_find_next_sample(s, &st);
8105 return AVERROR_INVALIDDATA;
8107 if (sc->ffindex == stream_index && sc->current_sample == sample)
8109 mov_current_sample_inc(sc);
8115 #define OFFSET(x) offsetof(MOVContext, x)
8116 #define FLAGS AV_OPT_FLAG_VIDEO_PARAM | AV_OPT_FLAG_DECODING_PARAM
8117 static const AVOption mov_options[] = {
8118 {"use_absolute_path",
8119 "allow using absolute path when opening alias, this is a possible security issue",
8120 OFFSET(use_absolute_path), AV_OPT_TYPE_BOOL, {.i64 = 0},
8122 {"seek_streams_individually",
8123 "Seek each stream individually to the closest point",
8124 OFFSET(seek_individually), AV_OPT_TYPE_BOOL, { .i64 = 1 },
8126 {"ignore_editlist", "Ignore the edit list atom.", OFFSET(ignore_editlist), AV_OPT_TYPE_BOOL, {.i64 = 0},
8128 {"advanced_editlist",
8129 "Modify the AVIndex according to the editlists. Use this option to decode in the order specified by the edits.",
8130 OFFSET(advanced_editlist), AV_OPT_TYPE_BOOL, {.i64 = 1},
8132 {"ignore_chapters", "", OFFSET(ignore_chapters), AV_OPT_TYPE_BOOL, {.i64 = 0},
8135 "use mfra for fragment timestamps",
8136 OFFSET(use_mfra_for), AV_OPT_TYPE_INT, {.i64 = FF_MOV_FLAG_MFRA_AUTO},
8137 -1, FF_MOV_FLAG_MFRA_PTS, FLAGS,
8139 {"auto", "auto", 0, AV_OPT_TYPE_CONST, {.i64 = FF_MOV_FLAG_MFRA_AUTO}, 0, 0,
8140 FLAGS, "use_mfra_for" },
8141 {"dts", "dts", 0, AV_OPT_TYPE_CONST, {.i64 = FF_MOV_FLAG_MFRA_DTS}, 0, 0,
8142 FLAGS, "use_mfra_for" },
8143 {"pts", "pts", 0, AV_OPT_TYPE_CONST, {.i64 = FF_MOV_FLAG_MFRA_PTS}, 0, 0,
8144 FLAGS, "use_mfra_for" },
8145 { "export_all", "Export unrecognized metadata entries", OFFSET(export_all),
8146 AV_OPT_TYPE_BOOL, { .i64 = 0 }, 0, 1, .flags = FLAGS },
8147 { "export_xmp", "Export full XMP metadata", OFFSET(export_xmp),
8148 AV_OPT_TYPE_BOOL, { .i64 = 0 }, 0, 1, .flags = FLAGS },
8149 { "activation_bytes", "Secret bytes for Audible AAX files", OFFSET(activation_bytes),
8150 AV_OPT_TYPE_BINARY, .flags = AV_OPT_FLAG_DECODING_PARAM },
8151 { "audible_fixed_key", // extracted from libAAX_SDK.so and AAXSDKWin.dll files!
8152 "Fixed key used for handling Audible AAX files", OFFSET(audible_fixed_key),
8153 AV_OPT_TYPE_BINARY, {.str="77214d4b196a87cd520045fd20a51d67"},
8154 .flags = AV_OPT_FLAG_DECODING_PARAM },
8155 { "decryption_key", "The media decryption key (hex)", OFFSET(decryption_key), AV_OPT_TYPE_BINARY, .flags = AV_OPT_FLAG_DECODING_PARAM },
8156 { "enable_drefs", "Enable external track support.", OFFSET(enable_drefs), AV_OPT_TYPE_BOOL,
8157 {.i64 = 0}, 0, 1, FLAGS },
8162 static const AVClass mov_class = {
8163 .class_name = "mov,mp4,m4a,3gp,3g2,mj2",
8164 .item_name = av_default_item_name,
8165 .option = mov_options,
8166 .version = LIBAVUTIL_VERSION_INT,
8169 AVInputFormat ff_mov_demuxer = {
8170 .name = "mov,mp4,m4a,3gp,3g2,mj2",
8171 .long_name = NULL_IF_CONFIG_SMALL("QuickTime / MOV"),
8172 .priv_class = &mov_class,
8173 .priv_data_size = sizeof(MOVContext),
8174 .extensions = "mov,mp4,m4a,3gp,3g2,mj2,psp,m4b,ism,ismv,isma,f4v",
8175 .read_probe = mov_probe,
8176 .read_header = mov_read_header,
8177 .read_packet = mov_read_packet,
8178 .read_close = mov_read_close,
8179 .read_seek = mov_read_seek,
8180 .flags = AVFMT_NO_BYTE_SEEK | AVFMT_SEEK_TO_PTS,