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 sc = av_mallocz(sizeof(*sc));
201 return AVERROR(ENOMEM);
202 ret = ff_add_attached_pic(c->fc, NULL, pb, NULL, len);
207 st = c->fc->streams[c->fc->nb_streams - 1];
210 if (st->attached_pic.size >= 8 && id != AV_CODEC_ID_BMP) {
211 if (AV_RB64(st->attached_pic.data) == 0x89504e470d0a1a0a) {
212 id = AV_CODEC_ID_PNG;
214 id = AV_CODEC_ID_MJPEG;
217 st->codecpar->codec_id = id;
223 static int mov_metadata_loci(MOVContext *c, AVIOContext *pb, unsigned len)
225 char language[4] = { 0 };
226 char buf[200], place[100];
227 uint16_t langcode = 0;
228 double longitude, latitude, altitude;
229 const char *key = "location";
231 if (len < 4 + 2 + 1 + 1 + 4 + 4 + 4) {
232 av_log(c->fc, AV_LOG_ERROR, "loci too short\n");
233 return AVERROR_INVALIDDATA;
236 avio_skip(pb, 4); // version+flags
237 langcode = avio_rb16(pb);
238 ff_mov_lang_to_iso639(langcode, language);
241 len -= avio_get_str(pb, len, place, sizeof(place));
243 av_log(c->fc, AV_LOG_ERROR, "place name too long\n");
244 return AVERROR_INVALIDDATA;
246 avio_skip(pb, 1); // role
250 av_log(c->fc, AV_LOG_ERROR,
251 "loci too short (%u bytes left, need at least %d)\n", len, 12);
252 return AVERROR_INVALIDDATA;
254 longitude = ((int32_t) avio_rb32(pb)) / (float) (1 << 16);
255 latitude = ((int32_t) avio_rb32(pb)) / (float) (1 << 16);
256 altitude = ((int32_t) avio_rb32(pb)) / (float) (1 << 16);
258 // Try to output in the same format as the ?xyz field
259 snprintf(buf, sizeof(buf), "%+08.4f%+09.4f", latitude, longitude);
261 av_strlcatf(buf, sizeof(buf), "%+f", altitude);
262 av_strlcatf(buf, sizeof(buf), "/%s", place);
264 if (*language && strcmp(language, "und")) {
266 snprintf(key2, sizeof(key2), "%s-%s", key, language);
267 av_dict_set(&c->fc->metadata, key2, buf, 0);
269 c->fc->event_flags |= AVFMT_EVENT_FLAG_METADATA_UPDATED;
270 return av_dict_set(&c->fc->metadata, key, buf, 0);
273 static int mov_metadata_hmmt(MOVContext *c, AVIOContext *pb, unsigned len)
279 if (c->ignore_chapters)
282 n_hmmt = avio_rb32(pb);
283 if (n_hmmt > len / 4)
284 return AVERROR_INVALIDDATA;
285 for (i = 0; i < n_hmmt && !pb->eof_reached; i++) {
286 int moment_time = avio_rb32(pb);
287 avpriv_new_chapter(c->fc, i, av_make_q(1, 1000), moment_time, AV_NOPTS_VALUE, NULL);
292 static int mov_read_udta_string(MOVContext *c, AVIOContext *pb, MOVAtom atom)
294 char tmp_key[AV_FOURCC_MAX_STRING_SIZE] = {0};
295 char key2[32], language[4] = {0};
297 const char *key = NULL;
298 uint16_t langcode = 0;
299 uint32_t data_type = 0, str_size, str_size_alloc;
300 int (*parse)(MOVContext*, AVIOContext*, unsigned, const char*) = NULL;
305 case MKTAG( '@','P','R','M'): key = "premiere_version"; raw = 1; break;
306 case MKTAG( '@','P','R','Q'): key = "quicktime_version"; raw = 1; break;
307 case MKTAG( 'X','M','P','_'):
308 if (c->export_xmp) { key = "xmp"; raw = 1; } break;
309 case MKTAG( 'a','A','R','T'): key = "album_artist"; break;
310 case MKTAG( 'a','k','I','D'): key = "account_type";
311 parse = mov_metadata_int8_no_padding; break;
312 case MKTAG( 'a','p','I','D'): key = "account_id"; break;
313 case MKTAG( 'c','a','t','g'): key = "category"; break;
314 case MKTAG( 'c','p','i','l'): key = "compilation";
315 parse = mov_metadata_int8_no_padding; break;
316 case MKTAG( 'c','p','r','t'): key = "copyright"; break;
317 case MKTAG( 'd','e','s','c'): key = "description"; break;
318 case MKTAG( 'd','i','s','k'): key = "disc";
319 parse = mov_metadata_track_or_disc_number; break;
320 case MKTAG( 'e','g','i','d'): key = "episode_uid";
321 parse = mov_metadata_int8_no_padding; break;
322 case MKTAG( 'F','I','R','M'): key = "firmware"; raw = 1; break;
323 case MKTAG( 'g','n','r','e'): key = "genre";
324 parse = mov_metadata_gnre; break;
325 case MKTAG( 'h','d','v','d'): key = "hd_video";
326 parse = mov_metadata_int8_no_padding; break;
327 case MKTAG( 'H','M','M','T'):
328 return mov_metadata_hmmt(c, pb, atom.size);
329 case MKTAG( 'k','e','y','w'): key = "keywords"; break;
330 case MKTAG( 'l','d','e','s'): key = "synopsis"; break;
331 case MKTAG( 'l','o','c','i'):
332 return mov_metadata_loci(c, pb, atom.size);
333 case MKTAG( 'm','a','n','u'): key = "make"; break;
334 case MKTAG( 'm','o','d','l'): key = "model"; break;
335 case MKTAG( 'p','c','s','t'): key = "podcast";
336 parse = mov_metadata_int8_no_padding; break;
337 case MKTAG( 'p','g','a','p'): key = "gapless_playback";
338 parse = mov_metadata_int8_no_padding; break;
339 case MKTAG( 'p','u','r','d'): key = "purchase_date"; break;
340 case MKTAG( 'r','t','n','g'): key = "rating";
341 parse = mov_metadata_int8_no_padding; break;
342 case MKTAG( 's','o','a','a'): key = "sort_album_artist"; break;
343 case MKTAG( 's','o','a','l'): key = "sort_album"; break;
344 case MKTAG( 's','o','a','r'): key = "sort_artist"; break;
345 case MKTAG( 's','o','c','o'): key = "sort_composer"; break;
346 case MKTAG( 's','o','n','m'): key = "sort_name"; break;
347 case MKTAG( 's','o','s','n'): key = "sort_show"; break;
348 case MKTAG( 's','t','i','k'): key = "media_type";
349 parse = mov_metadata_int8_no_padding; break;
350 case MKTAG( 't','r','k','n'): key = "track";
351 parse = mov_metadata_track_or_disc_number; break;
352 case MKTAG( 't','v','e','n'): key = "episode_id"; break;
353 case MKTAG( 't','v','e','s'): key = "episode_sort";
354 parse = mov_metadata_int8_bypass_padding; break;
355 case MKTAG( 't','v','n','n'): key = "network"; break;
356 case MKTAG( 't','v','s','h'): key = "show"; break;
357 case MKTAG( 't','v','s','n'): key = "season_number";
358 parse = mov_metadata_int8_bypass_padding; break;
359 case MKTAG(0xa9,'A','R','T'): key = "artist"; break;
360 case MKTAG(0xa9,'P','R','D'): key = "producer"; break;
361 case MKTAG(0xa9,'a','l','b'): key = "album"; break;
362 case MKTAG(0xa9,'a','u','t'): key = "artist"; break;
363 case MKTAG(0xa9,'c','h','p'): key = "chapter"; break;
364 case MKTAG(0xa9,'c','m','t'): key = "comment"; break;
365 case MKTAG(0xa9,'c','o','m'): key = "composer"; break;
366 case MKTAG(0xa9,'c','p','y'): key = "copyright"; break;
367 case MKTAG(0xa9,'d','a','y'): key = "date"; break;
368 case MKTAG(0xa9,'d','i','r'): key = "director"; break;
369 case MKTAG(0xa9,'d','i','s'): key = "disclaimer"; break;
370 case MKTAG(0xa9,'e','d','1'): key = "edit_date"; break;
371 case MKTAG(0xa9,'e','n','c'): key = "encoder"; break;
372 case MKTAG(0xa9,'f','m','t'): key = "original_format"; break;
373 case MKTAG(0xa9,'g','e','n'): key = "genre"; break;
374 case MKTAG(0xa9,'g','r','p'): key = "grouping"; break;
375 case MKTAG(0xa9,'h','s','t'): key = "host_computer"; break;
376 case MKTAG(0xa9,'i','n','f'): key = "comment"; break;
377 case MKTAG(0xa9,'l','y','r'): key = "lyrics"; break;
378 case MKTAG(0xa9,'m','a','k'): key = "make"; break;
379 case MKTAG(0xa9,'m','o','d'): key = "model"; break;
380 case MKTAG(0xa9,'n','a','m'): key = "title"; break;
381 case MKTAG(0xa9,'o','p','e'): key = "original_artist"; break;
382 case MKTAG(0xa9,'p','r','d'): key = "producer"; break;
383 case MKTAG(0xa9,'p','r','f'): key = "performers"; break;
384 case MKTAG(0xa9,'r','e','q'): key = "playback_requirements"; break;
385 case MKTAG(0xa9,'s','r','c'): key = "original_source"; break;
386 case MKTAG(0xa9,'s','t','3'): key = "subtitle"; break;
387 case MKTAG(0xa9,'s','w','r'): key = "encoder"; break;
388 case MKTAG(0xa9,'t','o','o'): key = "encoder"; break;
389 case MKTAG(0xa9,'t','r','k'): key = "track"; break;
390 case MKTAG(0xa9,'u','r','l'): key = "URL"; break;
391 case MKTAG(0xa9,'w','r','n'): key = "warning"; break;
392 case MKTAG(0xa9,'w','r','t'): key = "composer"; break;
393 case MKTAG(0xa9,'x','y','z'): key = "location"; break;
396 if (c->itunes_metadata && atom.size > 8) {
397 int data_size = avio_rb32(pb);
398 int tag = avio_rl32(pb);
399 if (tag == MKTAG('d','a','t','a') && data_size <= atom.size && data_size >= 16) {
400 data_type = avio_rb32(pb); // type
401 avio_rb32(pb); // unknown
402 str_size = data_size - 16;
405 if (atom.type == MKTAG('c', 'o', 'v', 'r')) {
406 int ret = mov_read_covr(c, pb, data_type, str_size);
408 av_log(c->fc, AV_LOG_ERROR, "Error parsing cover art.\n");
411 atom.size -= str_size;
415 } else if (!key && c->found_hdlr_mdta && c->meta_keys) {
416 uint32_t index = AV_RB32(&atom.type);
417 if (index < c->meta_keys_count && index > 0) {
418 key = c->meta_keys[index];
420 av_log(c->fc, AV_LOG_WARNING,
421 "The index of 'data' is out of range: %"PRId32" < 1 or >= %d.\n",
422 index, c->meta_keys_count);
426 } else if (atom.size > 4 && key && !c->itunes_metadata && !raw) {
427 str_size = avio_rb16(pb); // string length
428 if (str_size > atom.size) {
430 avio_seek(pb, -2, SEEK_CUR);
431 av_log(c->fc, AV_LOG_WARNING, "UDTA parsing failed retrying raw\n");
434 langcode = avio_rb16(pb);
435 ff_mov_lang_to_iso639(langcode, language);
438 str_size = atom.size;
440 if (c->export_all && !key) {
441 key = av_fourcc_make_string(tmp_key, atom.type);
446 if (atom.size < 0 || str_size >= INT_MAX/2)
447 return AVERROR_INVALIDDATA;
449 // Allocates enough space if data_type is a int32 or float32 number, otherwise
450 // worst-case requirement for output string in case of utf8 coded input
451 num = (data_type >= 21 && data_type <= 23);
452 str_size_alloc = (num ? 512 : (raw ? str_size : str_size * 2)) + 1;
453 str = av_mallocz(str_size_alloc);
455 return AVERROR(ENOMEM);
458 parse(c, pb, str_size, key);
460 if (!raw && (data_type == 3 || (data_type == 0 && (langcode < 0x400 || langcode == 0x7fff)))) { // MAC Encoded
461 mov_read_mac_string(c, pb, str_size, str, str_size_alloc);
462 } else if (data_type == 21) { // BE signed integer, variable size
465 val = (int8_t)avio_r8(pb);
466 else if (str_size == 2)
467 val = (int16_t)avio_rb16(pb);
468 else if (str_size == 3)
469 val = ((int32_t)(avio_rb24(pb)<<8))>>8;
470 else if (str_size == 4)
471 val = (int32_t)avio_rb32(pb);
472 if (snprintf(str, str_size_alloc, "%d", val) >= str_size_alloc) {
473 av_log(c->fc, AV_LOG_ERROR,
474 "Failed to store the number (%d) in string.\n", val);
476 return AVERROR_INVALIDDATA;
478 } else if (data_type == 22) { // BE unsigned integer, variable size
479 unsigned int val = 0;
482 else if (str_size == 2)
484 else if (str_size == 3)
486 else if (str_size == 4)
488 if (snprintf(str, str_size_alloc, "%u", val) >= str_size_alloc) {
489 av_log(c->fc, AV_LOG_ERROR,
490 "Failed to store the number (%u) in string.\n", val);
492 return AVERROR_INVALIDDATA;
494 } else if (data_type == 23 && str_size >= 4) { // BE float32
495 float val = av_int2float(avio_rb32(pb));
496 if (snprintf(str, str_size_alloc, "%f", val) >= str_size_alloc) {
497 av_log(c->fc, AV_LOG_ERROR,
498 "Failed to store the float32 number (%f) in string.\n", val);
500 return AVERROR_INVALIDDATA;
503 int ret = ffio_read_size(pb, str, str_size);
510 c->fc->event_flags |= AVFMT_EVENT_FLAG_METADATA_UPDATED;
511 av_dict_set(&c->fc->metadata, key, str, 0);
512 if (*language && strcmp(language, "und")) {
513 snprintf(key2, sizeof(key2), "%s-%s", key, language);
514 av_dict_set(&c->fc->metadata, key2, str, 0);
516 if (!strcmp(key, "encoder")) {
517 int major, minor, micro;
518 if (sscanf(str, "HandBrake %d.%d.%d", &major, &minor, µ) == 3) {
519 c->handbrake_version = 1000000*major + 1000*minor + micro;
528 static int mov_read_chpl(MOVContext *c, AVIOContext *pb, MOVAtom atom)
531 int i, nb_chapters, str_len, version;
535 if (c->ignore_chapters)
538 if ((atom.size -= 5) < 0)
541 version = avio_r8(pb);
544 avio_rb32(pb); // ???
545 nb_chapters = avio_r8(pb);
547 for (i = 0; i < nb_chapters; i++) {
551 start = avio_rb64(pb);
552 str_len = avio_r8(pb);
554 if ((atom.size -= 9+str_len) < 0)
557 ret = ffio_read_size(pb, str, str_len);
561 avpriv_new_chapter(c->fc, i, (AVRational){1,10000000}, start, AV_NOPTS_VALUE, str);
566 #define MIN_DATA_ENTRY_BOX_SIZE 12
567 static int mov_read_dref(MOVContext *c, AVIOContext *pb, MOVAtom atom)
570 MOVStreamContext *sc;
573 if (c->fc->nb_streams < 1)
575 st = c->fc->streams[c->fc->nb_streams-1];
578 avio_rb32(pb); // version + flags
579 entries = avio_rb32(pb);
581 entries > (atom.size - 1) / MIN_DATA_ENTRY_BOX_SIZE + 1 ||
582 entries >= UINT_MAX / sizeof(*sc->drefs))
583 return AVERROR_INVALIDDATA;
585 for (i = 0; i < sc->drefs_count; i++) {
586 MOVDref *dref = &sc->drefs[i];
587 av_freep(&dref->path);
588 av_freep(&dref->dir);
592 sc->drefs = av_mallocz(entries * sizeof(*sc->drefs));
594 return AVERROR(ENOMEM);
595 sc->drefs_count = entries;
597 for (i = 0; i < entries; i++) {
598 MOVDref *dref = &sc->drefs[i];
599 uint32_t size = avio_rb32(pb);
600 int64_t next = avio_tell(pb) + size - 4;
603 return AVERROR_INVALIDDATA;
605 dref->type = avio_rl32(pb);
606 avio_rb32(pb); // version + flags
608 if (dref->type == MKTAG('a','l','i','s') && size > 150) {
609 /* macintosh alias record */
610 uint16_t volume_len, len;
616 volume_len = avio_r8(pb);
617 volume_len = FFMIN(volume_len, 27);
618 ret = ffio_read_size(pb, dref->volume, 27);
621 dref->volume[volume_len] = 0;
622 av_log(c->fc, AV_LOG_DEBUG, "volume %s, len %d\n", dref->volume, volume_len);
627 len = FFMIN(len, 63);
628 ret = ffio_read_size(pb, dref->filename, 63);
631 dref->filename[len] = 0;
632 av_log(c->fc, AV_LOG_DEBUG, "filename %s, len %d\n", dref->filename, len);
636 /* read next level up_from_alias/down_to_target */
637 dref->nlvl_from = avio_rb16(pb);
638 dref->nlvl_to = avio_rb16(pb);
639 av_log(c->fc, AV_LOG_DEBUG, "nlvl from %d, nlvl to %d\n",
640 dref->nlvl_from, dref->nlvl_to);
644 for (type = 0; type != -1 && avio_tell(pb) < next; ) {
647 type = avio_rb16(pb);
649 av_log(c->fc, AV_LOG_DEBUG, "type %d, len %d\n", type, len);
652 if (type == 2) { // absolute path
654 dref->path = av_mallocz(len+1);
656 return AVERROR(ENOMEM);
658 ret = ffio_read_size(pb, dref->path, len);
660 av_freep(&dref->path);
663 if (len > volume_len && !strncmp(dref->path, dref->volume, volume_len)) {
665 memmove(dref->path, dref->path+volume_len, len);
668 // trim string of any ending zeros
669 for (j = len - 1; j >= 0; j--) {
670 if (dref->path[j] == 0)
675 for (j = 0; j < len; j++)
676 if (dref->path[j] == ':' || dref->path[j] == 0)
678 av_log(c->fc, AV_LOG_DEBUG, "path %s\n", dref->path);
679 } else if (type == 0) { // directory name
681 dref->dir = av_malloc(len+1);
683 return AVERROR(ENOMEM);
685 ret = ffio_read_size(pb, dref->dir, len);
687 av_freep(&dref->dir);
691 for (j = 0; j < len; j++)
692 if (dref->dir[j] == ':')
694 av_log(c->fc, AV_LOG_DEBUG, "dir %s\n", dref->dir);
699 av_log(c->fc, AV_LOG_DEBUG, "Unknown dref type 0x%08"PRIx32" size %"PRIu32"\n",
704 avio_seek(pb, next, SEEK_SET);
709 static int mov_read_hdlr(MOVContext *c, AVIOContext *pb, MOVAtom atom)
718 avio_r8(pb); /* version */
719 avio_rb24(pb); /* flags */
722 ctype = avio_rl32(pb);
723 type = avio_rl32(pb); /* component subtype */
725 av_log(c->fc, AV_LOG_TRACE, "ctype=%s\n", av_fourcc2str(ctype));
726 av_log(c->fc, AV_LOG_TRACE, "stype=%s\n", av_fourcc2str(type));
728 if (c->trak_index < 0) { // meta not inside a trak
729 if (type == MKTAG('m','d','t','a')) {
730 c->found_hdlr_mdta = 1;
735 st = c->fc->streams[c->fc->nb_streams-1];
737 if (type == MKTAG('v','i','d','e'))
738 st->codecpar->codec_type = AVMEDIA_TYPE_VIDEO;
739 else if (type == MKTAG('s','o','u','n'))
740 st->codecpar->codec_type = AVMEDIA_TYPE_AUDIO;
741 else if (type == MKTAG('m','1','a',' '))
742 st->codecpar->codec_id = AV_CODEC_ID_MP2;
743 else if ((type == MKTAG('s','u','b','p')) || (type == MKTAG('c','l','c','p')))
744 st->codecpar->codec_type = AVMEDIA_TYPE_SUBTITLE;
746 avio_rb32(pb); /* component manufacture */
747 avio_rb32(pb); /* component flags */
748 avio_rb32(pb); /* component flags mask */
750 title_size = atom.size - 24;
751 if (title_size > 0) {
752 if (title_size > FFMIN(INT_MAX, SIZE_MAX-1))
753 return AVERROR_INVALIDDATA;
754 title_str = av_malloc(title_size + 1); /* Add null terminator */
756 return AVERROR(ENOMEM);
758 ret = ffio_read_size(pb, title_str, title_size);
760 av_freep(&title_str);
763 title_str[title_size] = 0;
765 int off = (!c->isom && title_str[0] == title_size - 1);
766 // flag added so as to not set stream handler name if already set from mdia->hdlr
767 av_dict_set(&st->metadata, "handler_name", title_str + off, AV_DICT_DONT_OVERWRITE);
769 av_freep(&title_str);
775 static int mov_read_esds(MOVContext *c, AVIOContext *pb, MOVAtom atom)
777 return ff_mov_read_esds(c->fc, pb);
780 static int mov_read_dac3(MOVContext *c, AVIOContext *pb, MOVAtom atom)
783 enum AVAudioServiceType *ast;
784 int ac3info, acmod, lfeon, bsmod;
786 if (c->fc->nb_streams < 1)
788 st = c->fc->streams[c->fc->nb_streams-1];
790 ast = (enum AVAudioServiceType*)av_stream_new_side_data(st, AV_PKT_DATA_AUDIO_SERVICE_TYPE,
793 return AVERROR(ENOMEM);
795 ac3info = avio_rb24(pb);
796 bsmod = (ac3info >> 14) & 0x7;
797 acmod = (ac3info >> 11) & 0x7;
798 lfeon = (ac3info >> 10) & 0x1;
799 st->codecpar->channels = ((int[]){2,1,2,3,3,4,4,5})[acmod] + lfeon;
800 st->codecpar->channel_layout = avpriv_ac3_channel_layout_tab[acmod];
802 st->codecpar->channel_layout |= AV_CH_LOW_FREQUENCY;
804 if (st->codecpar->channels > 1 && bsmod == 0x7)
805 *ast = AV_AUDIO_SERVICE_TYPE_KARAOKE;
810 static int mov_read_dec3(MOVContext *c, AVIOContext *pb, MOVAtom atom)
813 enum AVAudioServiceType *ast;
814 int eac3info, acmod, lfeon, bsmod;
816 if (c->fc->nb_streams < 1)
818 st = c->fc->streams[c->fc->nb_streams-1];
820 ast = (enum AVAudioServiceType*)av_stream_new_side_data(st, AV_PKT_DATA_AUDIO_SERVICE_TYPE,
823 return AVERROR(ENOMEM);
825 /* No need to parse fields for additional independent substreams and its
826 * associated dependent substreams since libavcodec's E-AC-3 decoder
827 * does not support them yet. */
828 avio_rb16(pb); /* data_rate and num_ind_sub */
829 eac3info = avio_rb24(pb);
830 bsmod = (eac3info >> 12) & 0x1f;
831 acmod = (eac3info >> 9) & 0x7;
832 lfeon = (eac3info >> 8) & 0x1;
833 st->codecpar->channel_layout = avpriv_ac3_channel_layout_tab[acmod];
835 st->codecpar->channel_layout |= AV_CH_LOW_FREQUENCY;
836 st->codecpar->channels = av_get_channel_layout_nb_channels(st->codecpar->channel_layout);
838 if (st->codecpar->channels > 1 && bsmod == 0x7)
839 *ast = AV_AUDIO_SERVICE_TYPE_KARAOKE;
844 static int mov_read_ddts(MOVContext *c, AVIOContext *pb, MOVAtom atom)
847 uint8_t buf[DDTS_SIZE + AV_INPUT_BUFFER_PADDING_SIZE];
849 uint32_t frame_duration_code = 0;
850 uint32_t channel_layout_code = 0;
854 if ((ret = ffio_read_size(pb, buf, DDTS_SIZE)) < 0)
857 init_get_bits(&gb, buf, 8 * DDTS_SIZE);
859 if (c->fc->nb_streams < 1) {
862 st = c->fc->streams[c->fc->nb_streams-1];
864 st->codecpar->sample_rate = get_bits_long(&gb, 32);
865 if (st->codecpar->sample_rate <= 0) {
866 av_log(c->fc, AV_LOG_ERROR, "Invalid sample rate %d\n", st->codecpar->sample_rate);
867 return AVERROR_INVALIDDATA;
869 skip_bits_long(&gb, 32); /* max bitrate */
870 st->codecpar->bit_rate = get_bits_long(&gb, 32);
871 st->codecpar->bits_per_coded_sample = get_bits(&gb, 8);
872 frame_duration_code = get_bits(&gb, 2);
873 skip_bits(&gb, 30); /* various fields */
874 channel_layout_code = get_bits(&gb, 16);
876 st->codecpar->frame_size =
877 (frame_duration_code == 0) ? 512 :
878 (frame_duration_code == 1) ? 1024 :
879 (frame_duration_code == 2) ? 2048 :
880 (frame_duration_code == 3) ? 4096 : 0;
882 if (channel_layout_code > 0xff) {
883 av_log(c->fc, AV_LOG_WARNING, "Unsupported DTS audio channel layout\n");
885 st->codecpar->channel_layout =
886 ((channel_layout_code & 0x1) ? AV_CH_FRONT_CENTER : 0) |
887 ((channel_layout_code & 0x2) ? AV_CH_FRONT_LEFT : 0) |
888 ((channel_layout_code & 0x2) ? AV_CH_FRONT_RIGHT : 0) |
889 ((channel_layout_code & 0x4) ? AV_CH_SIDE_LEFT : 0) |
890 ((channel_layout_code & 0x4) ? AV_CH_SIDE_RIGHT : 0) |
891 ((channel_layout_code & 0x8) ? AV_CH_LOW_FREQUENCY : 0);
893 st->codecpar->channels = av_get_channel_layout_nb_channels(st->codecpar->channel_layout);
898 static int mov_read_chan(MOVContext *c, AVIOContext *pb, MOVAtom atom)
902 if (c->fc->nb_streams < 1)
904 st = c->fc->streams[c->fc->nb_streams-1];
909 /* skip version and flags */
912 ff_mov_read_chan(c->fc, pb, st, atom.size - 4);
917 static int mov_read_wfex(MOVContext *c, AVIOContext *pb, MOVAtom atom)
922 if (c->fc->nb_streams < 1)
924 st = c->fc->streams[c->fc->nb_streams-1];
926 if ((ret = ff_get_wav_header(c->fc, pb, st->codecpar, atom.size, 0)) < 0)
927 av_log(c->fc, AV_LOG_WARNING, "get_wav_header failed\n");
932 /* This atom overrides any previously set aspect ratio */
933 static int mov_read_pasp(MOVContext *c, AVIOContext *pb, MOVAtom atom)
935 const int num = avio_rb32(pb);
936 const int den = avio_rb32(pb);
939 if (c->fc->nb_streams < 1)
941 st = c->fc->streams[c->fc->nb_streams-1];
944 av_reduce(&st->sample_aspect_ratio.num, &st->sample_aspect_ratio.den,
950 /* this atom contains actual media data */
951 static int mov_read_mdat(MOVContext *c, AVIOContext *pb, MOVAtom atom)
953 if (atom.size == 0) /* wrong one (MP4) */
956 return 0; /* now go for moov */
959 #define DRM_BLOB_SIZE 56
961 static int mov_read_adrm(MOVContext *c, AVIOContext *pb, MOVAtom atom)
963 uint8_t intermediate_key[20];
964 uint8_t intermediate_iv[20];
967 uint8_t file_checksum[20];
968 uint8_t calculated_checksum[20];
972 uint8_t *activation_bytes = c->activation_bytes;
973 uint8_t *fixed_key = c->audible_fixed_key;
977 sha = av_sha_alloc();
979 return AVERROR(ENOMEM);
980 av_free(c->aes_decrypt);
981 c->aes_decrypt = av_aes_alloc();
982 if (!c->aes_decrypt) {
983 ret = AVERROR(ENOMEM);
987 /* drm blob processing */
988 avio_read(pb, output, 8); // go to offset 8, absolute position 0x251
989 avio_read(pb, input, DRM_BLOB_SIZE);
990 avio_read(pb, output, 4); // go to offset 4, absolute position 0x28d
991 avio_read(pb, file_checksum, 20);
993 av_log(c->fc, AV_LOG_INFO, "[aax] file checksum == "); // required by external tools
994 for (i = 0; i < 20; i++)
995 av_log(c->fc, AV_LOG_INFO, "%02x", file_checksum[i]);
996 av_log(c->fc, AV_LOG_INFO, "\n");
998 /* verify activation data */
999 if (!activation_bytes) {
1000 av_log(c->fc, AV_LOG_WARNING, "[aax] activation_bytes option is missing!\n");
1001 ret = 0; /* allow ffprobe to continue working on .aax files */
1004 if (c->activation_bytes_size != 4) {
1005 av_log(c->fc, AV_LOG_FATAL, "[aax] activation_bytes value needs to be 4 bytes!\n");
1006 ret = AVERROR(EINVAL);
1010 /* verify fixed key */
1011 if (c->audible_fixed_key_size != 16) {
1012 av_log(c->fc, AV_LOG_FATAL, "[aax] audible_fixed_key value needs to be 16 bytes!\n");
1013 ret = AVERROR(EINVAL);
1017 /* AAX (and AAX+) key derivation */
1018 av_sha_init(sha, 160);
1019 av_sha_update(sha, fixed_key, 16);
1020 av_sha_update(sha, activation_bytes, 4);
1021 av_sha_final(sha, intermediate_key);
1022 av_sha_init(sha, 160);
1023 av_sha_update(sha, fixed_key, 16);
1024 av_sha_update(sha, intermediate_key, 20);
1025 av_sha_update(sha, activation_bytes, 4);
1026 av_sha_final(sha, intermediate_iv);
1027 av_sha_init(sha, 160);
1028 av_sha_update(sha, intermediate_key, 16);
1029 av_sha_update(sha, intermediate_iv, 16);
1030 av_sha_final(sha, calculated_checksum);
1031 if (memcmp(calculated_checksum, file_checksum, 20)) { // critical error
1032 av_log(c->fc, AV_LOG_ERROR, "[aax] mismatch in checksums!\n");
1033 ret = AVERROR_INVALIDDATA;
1036 av_aes_init(c->aes_decrypt, intermediate_key, 128, 1);
1037 av_aes_crypt(c->aes_decrypt, output, input, DRM_BLOB_SIZE >> 4, intermediate_iv, 1);
1038 for (i = 0; i < 4; i++) {
1039 // file data (in output) is stored in big-endian mode
1040 if (activation_bytes[i] != output[3 - i]) { // critical error
1041 av_log(c->fc, AV_LOG_ERROR, "[aax] error in drm blob decryption!\n");
1042 ret = AVERROR_INVALIDDATA;
1046 memcpy(c->file_key, output + 8, 16);
1047 memcpy(input, output + 26, 16);
1048 av_sha_init(sha, 160);
1049 av_sha_update(sha, input, 16);
1050 av_sha_update(sha, c->file_key, 16);
1051 av_sha_update(sha, fixed_key, 16);
1052 av_sha_final(sha, c->file_iv);
1060 static int mov_aaxc_crypto(MOVContext *c)
1062 if (c->audible_key_size != 16) {
1063 av_log(c->fc, AV_LOG_FATAL, "[aaxc] audible_key value needs to be 16 bytes!\n");
1064 return AVERROR(EINVAL);
1067 if (c->audible_iv_size != 16) {
1068 av_log(c->fc, AV_LOG_FATAL, "[aaxc] audible_iv value needs to be 16 bytes!\n");
1069 return AVERROR(EINVAL);
1072 c->aes_decrypt = av_aes_alloc();
1073 if (!c->aes_decrypt) {
1074 return AVERROR(ENOMEM);
1077 memcpy(c->file_key, c->audible_key, 16);
1078 memcpy(c->file_iv, c->audible_iv, 16);
1084 // Audible AAX (and AAX+) bytestream decryption
1085 static int aax_filter(uint8_t *input, int size, MOVContext *c)
1088 unsigned char iv[16];
1090 memcpy(iv, c->file_iv, 16); // iv is overwritten
1091 blocks = size >> 4; // trailing bytes are not encrypted!
1092 av_aes_init(c->aes_decrypt, c->file_key, 128, 1);
1093 av_aes_crypt(c->aes_decrypt, input, input, blocks, iv, 1);
1098 /* read major brand, minor version and compatible brands and store them as metadata */
1099 static int mov_read_ftyp(MOVContext *c, AVIOContext *pb, MOVAtom atom)
1102 int comp_brand_size;
1103 char* comp_brands_str;
1104 uint8_t type[5] = {0};
1105 int ret = ffio_read_size(pb, type, 4);
1109 if (strcmp(type, "qt "))
1111 av_log(c->fc, AV_LOG_DEBUG, "ISO: File Type Major Brand: %.4s\n",(char *)&type);
1112 av_dict_set(&c->fc->metadata, "major_brand", type, 0);
1113 minor_ver = avio_rb32(pb); /* minor version */
1114 av_dict_set_int(&c->fc->metadata, "minor_version", minor_ver, 0);
1116 comp_brand_size = atom.size - 8;
1117 if (comp_brand_size < 0 || comp_brand_size == INT_MAX)
1118 return AVERROR_INVALIDDATA;
1119 comp_brands_str = av_malloc(comp_brand_size + 1); /* Add null terminator */
1120 if (!comp_brands_str)
1121 return AVERROR(ENOMEM);
1123 ret = ffio_read_size(pb, comp_brands_str, comp_brand_size);
1125 av_freep(&comp_brands_str);
1128 comp_brands_str[comp_brand_size] = 0;
1129 av_dict_set(&c->fc->metadata, "compatible_brands",
1130 comp_brands_str, AV_DICT_DONT_STRDUP_VAL);
1132 // Logic for handling Audible's .aaxc files
1133 if (!strcmp(type, "aaxc")) {
1140 /* this atom should contain all header atoms */
1141 static int mov_read_moov(MOVContext *c, AVIOContext *pb, MOVAtom atom)
1145 if (c->found_moov) {
1146 av_log(c->fc, AV_LOG_WARNING, "Found duplicated MOOV Atom. Skipped it\n");
1147 avio_skip(pb, atom.size);
1151 if ((ret = mov_read_default(c, pb, atom)) < 0)
1153 /* we parsed the 'moov' atom, we can terminate the parsing as soon as we find the 'mdat' */
1154 /* so we don't parse the whole file if over a network */
1156 return 0; /* now go for mdat */
1159 static MOVFragmentStreamInfo * get_frag_stream_info(
1160 MOVFragmentIndex *frag_index,
1165 MOVFragmentIndexItem * item;
1167 if (index < 0 || index >= frag_index->nb_items)
1169 item = &frag_index->item[index];
1170 for (i = 0; i < item->nb_stream_info; i++)
1171 if (item->stream_info[i].id == id)
1172 return &item->stream_info[i];
1174 // This shouldn't happen
1178 static void set_frag_stream(MOVFragmentIndex *frag_index, int id)
1181 MOVFragmentIndexItem * item;
1183 if (frag_index->current < 0 ||
1184 frag_index->current >= frag_index->nb_items)
1187 item = &frag_index->item[frag_index->current];
1188 for (i = 0; i < item->nb_stream_info; i++)
1189 if (item->stream_info[i].id == id) {
1194 // id not found. This shouldn't happen.
1198 static MOVFragmentStreamInfo * get_current_frag_stream_info(
1199 MOVFragmentIndex *frag_index)
1201 MOVFragmentIndexItem *item;
1202 if (frag_index->current < 0 ||
1203 frag_index->current >= frag_index->nb_items)
1206 item = &frag_index->item[frag_index->current];
1207 if (item->current >= 0 && item->current < item->nb_stream_info)
1208 return &item->stream_info[item->current];
1210 // This shouldn't happen
1214 static int search_frag_moof_offset(MOVFragmentIndex *frag_index, int64_t offset)
1217 int64_t moof_offset;
1219 // Optimize for appending new entries
1220 if (!frag_index->nb_items ||
1221 frag_index->item[frag_index->nb_items - 1].moof_offset < offset)
1222 return frag_index->nb_items;
1225 b = frag_index->nb_items;
1229 moof_offset = frag_index->item[m].moof_offset;
1230 if (moof_offset >= offset)
1232 if (moof_offset <= offset)
1238 static int64_t get_stream_info_time(MOVFragmentStreamInfo * frag_stream_info)
1240 av_assert0(frag_stream_info);
1241 if (frag_stream_info->sidx_pts != AV_NOPTS_VALUE)
1242 return frag_stream_info->sidx_pts;
1243 if (frag_stream_info->first_tfra_pts != AV_NOPTS_VALUE)
1244 return frag_stream_info->first_tfra_pts;
1245 return frag_stream_info->tfdt_dts;
1248 static int64_t get_frag_time(MOVFragmentIndex *frag_index,
1249 int index, int track_id)
1251 MOVFragmentStreamInfo * frag_stream_info;
1255 if (track_id >= 0) {
1256 frag_stream_info = get_frag_stream_info(frag_index, index, track_id);
1257 if (frag_stream_info->sidx_pts != AV_NOPTS_VALUE)
1258 return frag_stream_info->sidx_pts;
1259 if (frag_stream_info->first_tfra_pts != AV_NOPTS_VALUE)
1260 return frag_stream_info->first_tfra_pts;
1261 return frag_stream_info->sidx_pts;
1264 for (i = 0; i < frag_index->item[index].nb_stream_info; i++) {
1265 frag_stream_info = &frag_index->item[index].stream_info[i];
1266 timestamp = get_stream_info_time(frag_stream_info);
1267 if (timestamp != AV_NOPTS_VALUE)
1270 return AV_NOPTS_VALUE;
1273 static int search_frag_timestamp(MOVFragmentIndex *frag_index,
1274 AVStream *st, int64_t timestamp)
1281 // If the stream is referenced by any sidx, limit the search
1282 // to fragments that referenced this stream in the sidx
1283 MOVStreamContext *sc = st->priv_data;
1289 b = frag_index->nb_items;
1292 m0 = m = (a + b) >> 1;
1295 (frag_time = get_frag_time(frag_index, m, id)) == AV_NOPTS_VALUE)
1298 if (m < b && frag_time <= timestamp)
1307 static int update_frag_index(MOVContext *c, int64_t offset)
1310 MOVFragmentIndexItem * item;
1311 MOVFragmentStreamInfo * frag_stream_info;
1313 // If moof_offset already exists in frag_index, return index to it
1314 index = search_frag_moof_offset(&c->frag_index, offset);
1315 if (index < c->frag_index.nb_items &&
1316 c->frag_index.item[index].moof_offset == offset)
1319 // offset is not yet in frag index.
1320 // Insert new item at index (sorted by moof offset)
1321 item = av_fast_realloc(c->frag_index.item,
1322 &c->frag_index.allocated_size,
1323 (c->frag_index.nb_items + 1) *
1324 sizeof(*c->frag_index.item));
1327 c->frag_index.item = item;
1329 frag_stream_info = av_realloc_array(NULL, c->fc->nb_streams,
1330 sizeof(*item->stream_info));
1331 if (!frag_stream_info)
1334 for (i = 0; i < c->fc->nb_streams; i++) {
1335 // Avoid building frag index if streams lack track id.
1336 if (c->fc->streams[i]->id < 0) {
1337 av_free(frag_stream_info);
1338 return AVERROR_INVALIDDATA;
1341 frag_stream_info[i].id = c->fc->streams[i]->id;
1342 frag_stream_info[i].sidx_pts = AV_NOPTS_VALUE;
1343 frag_stream_info[i].tfdt_dts = AV_NOPTS_VALUE;
1344 frag_stream_info[i].next_trun_dts = AV_NOPTS_VALUE;
1345 frag_stream_info[i].first_tfra_pts = AV_NOPTS_VALUE;
1346 frag_stream_info[i].index_entry = -1;
1347 frag_stream_info[i].encryption_index = NULL;
1350 if (index < c->frag_index.nb_items)
1351 memmove(c->frag_index.item + index + 1, c->frag_index.item + index,
1352 (c->frag_index.nb_items - index) * sizeof(*c->frag_index.item));
1354 item = &c->frag_index.item[index];
1355 item->headers_read = 0;
1357 item->nb_stream_info = c->fc->nb_streams;
1358 item->moof_offset = offset;
1359 item->stream_info = frag_stream_info;
1360 c->frag_index.nb_items++;
1365 static void fix_frag_index_entries(MOVFragmentIndex *frag_index, int index,
1366 int id, int entries)
1369 MOVFragmentStreamInfo * frag_stream_info;
1373 for (i = index; i < frag_index->nb_items; i++) {
1374 frag_stream_info = get_frag_stream_info(frag_index, i, id);
1375 if (frag_stream_info && frag_stream_info->index_entry >= 0)
1376 frag_stream_info->index_entry += entries;
1380 static int mov_read_moof(MOVContext *c, AVIOContext *pb, MOVAtom atom)
1382 // Set by mov_read_tfhd(). mov_read_trun() will reject files missing tfhd.
1383 c->fragment.found_tfhd = 0;
1385 if (!c->has_looked_for_mfra && c->use_mfra_for > 0) {
1386 c->has_looked_for_mfra = 1;
1387 if (pb->seekable & AVIO_SEEKABLE_NORMAL) {
1389 av_log(c->fc, AV_LOG_VERBOSE, "stream has moof boxes, will look "
1391 if ((ret = mov_read_mfra(c, pb)) < 0) {
1392 av_log(c->fc, AV_LOG_VERBOSE, "found a moof box but failed to "
1393 "read the mfra (may be a live ismv)\n");
1396 av_log(c->fc, AV_LOG_VERBOSE, "found a moof box but stream is not "
1397 "seekable, can not look for mfra\n");
1400 c->fragment.moof_offset = c->fragment.implicit_offset = avio_tell(pb) - 8;
1401 av_log(c->fc, AV_LOG_TRACE, "moof offset %"PRIx64"\n", c->fragment.moof_offset);
1402 c->frag_index.current = update_frag_index(c, c->fragment.moof_offset);
1403 return mov_read_default(c, pb, atom);
1406 static void mov_metadata_creation_time(AVDictionary **metadata, int64_t time, void *logctx)
1409 if (time >= 2082844800)
1410 time -= 2082844800; /* seconds between 1904-01-01 and Epoch */
1412 if ((int64_t)(time * 1000000ULL) / 1000000 != time) {
1413 av_log(logctx, AV_LOG_DEBUG, "creation_time is not representable\n");
1417 avpriv_dict_set_timestamp(metadata, "creation_time", time * 1000000);
1421 static int mov_read_mdhd(MOVContext *c, AVIOContext *pb, MOVAtom atom)
1424 MOVStreamContext *sc;
1426 char language[4] = {0};
1428 int64_t creation_time;
1430 if (c->fc->nb_streams < 1)
1432 st = c->fc->streams[c->fc->nb_streams-1];
1435 if (sc->time_scale) {
1436 av_log(c->fc, AV_LOG_ERROR, "Multiple mdhd?\n");
1437 return AVERROR_INVALIDDATA;
1440 version = avio_r8(pb);
1442 avpriv_request_sample(c->fc, "Version %d", version);
1443 return AVERROR_PATCHWELCOME;
1445 avio_rb24(pb); /* flags */
1447 creation_time = avio_rb64(pb);
1450 creation_time = avio_rb32(pb);
1451 avio_rb32(pb); /* modification time */
1453 mov_metadata_creation_time(&st->metadata, creation_time, c->fc);
1455 sc->time_scale = avio_rb32(pb);
1456 if (sc->time_scale <= 0) {
1457 av_log(c->fc, AV_LOG_ERROR, "Invalid mdhd time scale %d, defaulting to 1\n", sc->time_scale);
1460 st->duration = (version == 1) ? avio_rb64(pb) : avio_rb32(pb); /* duration */
1462 lang = avio_rb16(pb); /* language */
1463 if (ff_mov_lang_to_iso639(lang, language))
1464 av_dict_set(&st->metadata, "language", language, 0);
1465 avio_rb16(pb); /* quality */
1470 static int mov_read_mvhd(MOVContext *c, AVIOContext *pb, MOVAtom atom)
1473 int64_t creation_time;
1474 int version = avio_r8(pb); /* version */
1475 avio_rb24(pb); /* flags */
1478 creation_time = avio_rb64(pb);
1481 creation_time = avio_rb32(pb);
1482 avio_rb32(pb); /* modification time */
1484 mov_metadata_creation_time(&c->fc->metadata, creation_time, c->fc);
1485 c->time_scale = avio_rb32(pb); /* time scale */
1486 if (c->time_scale <= 0) {
1487 av_log(c->fc, AV_LOG_ERROR, "Invalid mvhd time scale %d, defaulting to 1\n", c->time_scale);
1490 av_log(c->fc, AV_LOG_TRACE, "time scale = %i\n", c->time_scale);
1492 c->duration = (version == 1) ? avio_rb64(pb) : avio_rb32(pb); /* duration */
1493 // set the AVFormatContext duration because the duration of individual tracks
1494 // may be inaccurate
1496 c->fc->duration = av_rescale(c->duration, AV_TIME_BASE, c->time_scale);
1497 avio_rb32(pb); /* preferred scale */
1499 avio_rb16(pb); /* preferred volume */
1501 avio_skip(pb, 10); /* reserved */
1503 /* movie display matrix, store it in main context and use it later on */
1504 for (i = 0; i < 3; i++) {
1505 c->movie_display_matrix[i][0] = avio_rb32(pb); // 16.16 fixed point
1506 c->movie_display_matrix[i][1] = avio_rb32(pb); // 16.16 fixed point
1507 c->movie_display_matrix[i][2] = avio_rb32(pb); // 2.30 fixed point
1510 avio_rb32(pb); /* preview time */
1511 avio_rb32(pb); /* preview duration */
1512 avio_rb32(pb); /* poster time */
1513 avio_rb32(pb); /* selection time */
1514 avio_rb32(pb); /* selection duration */
1515 avio_rb32(pb); /* current time */
1516 avio_rb32(pb); /* next track ID */
1521 static int mov_read_enda(MOVContext *c, AVIOContext *pb, MOVAtom atom)
1526 if (c->fc->nb_streams < 1)
1528 st = c->fc->streams[c->fc->nb_streams-1];
1530 little_endian = avio_rb16(pb) & 0xFF;
1531 av_log(c->fc, AV_LOG_TRACE, "enda %d\n", little_endian);
1532 if (little_endian == 1) {
1533 switch (st->codecpar->codec_id) {
1534 case AV_CODEC_ID_PCM_S24BE:
1535 st->codecpar->codec_id = AV_CODEC_ID_PCM_S24LE;
1537 case AV_CODEC_ID_PCM_S32BE:
1538 st->codecpar->codec_id = AV_CODEC_ID_PCM_S32LE;
1540 case AV_CODEC_ID_PCM_F32BE:
1541 st->codecpar->codec_id = AV_CODEC_ID_PCM_F32LE;
1543 case AV_CODEC_ID_PCM_F64BE:
1544 st->codecpar->codec_id = AV_CODEC_ID_PCM_F64LE;
1553 static int mov_read_colr(MOVContext *c, AVIOContext *pb, MOVAtom atom)
1556 uint8_t *icc_profile;
1557 char color_parameter_type[5] = { 0 };
1558 uint16_t color_primaries, color_trc, color_matrix;
1561 if (c->fc->nb_streams < 1)
1563 st = c->fc->streams[c->fc->nb_streams - 1];
1565 ret = ffio_read_size(pb, color_parameter_type, 4);
1568 if (strncmp(color_parameter_type, "nclx", 4) &&
1569 strncmp(color_parameter_type, "nclc", 4) &&
1570 strncmp(color_parameter_type, "prof", 4)) {
1571 av_log(c->fc, AV_LOG_WARNING, "unsupported color_parameter_type %s\n",
1572 color_parameter_type);
1576 if (!strncmp(color_parameter_type, "prof", 4)) {
1577 icc_profile = av_stream_new_side_data(st, AV_PKT_DATA_ICC_PROFILE, atom.size - 4);
1579 return AVERROR(ENOMEM);
1580 ret = ffio_read_size(pb, icc_profile, atom.size - 4);
1584 color_primaries = avio_rb16(pb);
1585 color_trc = avio_rb16(pb);
1586 color_matrix = avio_rb16(pb);
1588 av_log(c->fc, AV_LOG_TRACE,
1589 "%s: pri %d trc %d matrix %d",
1590 color_parameter_type, color_primaries, color_trc, color_matrix);
1592 if (!strncmp(color_parameter_type, "nclx", 4)) {
1593 uint8_t color_range = avio_r8(pb) >> 7;
1594 av_log(c->fc, AV_LOG_TRACE, " full %"PRIu8"", color_range);
1596 st->codecpar->color_range = AVCOL_RANGE_JPEG;
1598 st->codecpar->color_range = AVCOL_RANGE_MPEG;
1601 if (!av_color_primaries_name(color_primaries))
1602 color_primaries = AVCOL_PRI_UNSPECIFIED;
1603 if (!av_color_transfer_name(color_trc))
1604 color_trc = AVCOL_TRC_UNSPECIFIED;
1605 if (!av_color_space_name(color_matrix))
1606 color_matrix = AVCOL_SPC_UNSPECIFIED;
1608 st->codecpar->color_primaries = color_primaries;
1609 st->codecpar->color_trc = color_trc;
1610 st->codecpar->color_space = color_matrix;
1611 av_log(c->fc, AV_LOG_TRACE, "\n");
1616 static int mov_read_fiel(MOVContext *c, AVIOContext *pb, MOVAtom atom)
1619 unsigned mov_field_order;
1620 enum AVFieldOrder decoded_field_order = AV_FIELD_UNKNOWN;
1622 if (c->fc->nb_streams < 1) // will happen with jp2 files
1624 st = c->fc->streams[c->fc->nb_streams-1];
1626 return AVERROR_INVALIDDATA;
1627 mov_field_order = avio_rb16(pb);
1628 if ((mov_field_order & 0xFF00) == 0x0100)
1629 decoded_field_order = AV_FIELD_PROGRESSIVE;
1630 else if ((mov_field_order & 0xFF00) == 0x0200) {
1631 switch (mov_field_order & 0xFF) {
1632 case 0x01: decoded_field_order = AV_FIELD_TT;
1634 case 0x06: decoded_field_order = AV_FIELD_BB;
1636 case 0x09: decoded_field_order = AV_FIELD_TB;
1638 case 0x0E: decoded_field_order = AV_FIELD_BT;
1642 if (decoded_field_order == AV_FIELD_UNKNOWN && mov_field_order) {
1643 av_log(c->fc, AV_LOG_ERROR, "Unknown MOV field order 0x%04x\n", mov_field_order);
1645 st->codecpar->field_order = decoded_field_order;
1650 static int mov_realloc_extradata(AVCodecParameters *par, MOVAtom atom)
1653 uint64_t size = (uint64_t)par->extradata_size + atom.size + 8 + AV_INPUT_BUFFER_PADDING_SIZE;
1654 if (size > INT_MAX || (uint64_t)atom.size > INT_MAX)
1655 return AVERROR_INVALIDDATA;
1656 if ((err = av_reallocp(&par->extradata, size)) < 0) {
1657 par->extradata_size = 0;
1660 par->extradata_size = size - AV_INPUT_BUFFER_PADDING_SIZE;
1664 /* Read a whole atom into the extradata return the size of the atom read, possibly truncated if != atom.size */
1665 static int64_t mov_read_atom_into_extradata(MOVContext *c, AVIOContext *pb, MOVAtom atom,
1666 AVCodecParameters *par, uint8_t *buf)
1668 int64_t result = atom.size;
1671 AV_WB32(buf , atom.size + 8);
1672 AV_WL32(buf + 4, atom.type);
1673 err = ffio_read_size(pb, buf + 8, atom.size);
1675 par->extradata_size -= atom.size;
1677 } else if (err < atom.size) {
1678 av_log(c->fc, AV_LOG_WARNING, "truncated extradata\n");
1679 par->extradata_size -= atom.size - err;
1682 memset(buf + 8 + err, 0, AV_INPUT_BUFFER_PADDING_SIZE);
1686 /* FIXME modify QDM2/SVQ3/H.264 decoders to take full atom as extradata */
1687 static int mov_read_extradata(MOVContext *c, AVIOContext *pb, MOVAtom atom,
1688 enum AVCodecID codec_id)
1691 uint64_t original_size;
1694 if (c->fc->nb_streams < 1) // will happen with jp2 files
1696 st = c->fc->streams[c->fc->nb_streams-1];
1698 if (st->codecpar->codec_id != codec_id)
1699 return 0; /* unexpected codec_id - don't mess with extradata */
1701 original_size = st->codecpar->extradata_size;
1702 err = mov_realloc_extradata(st->codecpar, atom);
1706 err = mov_read_atom_into_extradata(c, pb, atom, st->codecpar, st->codecpar->extradata + original_size);
1709 return 0; // Note: this is the original behavior to ignore truncation.
1712 /* wrapper functions for reading ALAC/AVS/MJPEG/MJPEG2000 extradata atoms only for those codecs */
1713 static int mov_read_alac(MOVContext *c, AVIOContext *pb, MOVAtom atom)
1715 return mov_read_extradata(c, pb, atom, AV_CODEC_ID_ALAC);
1718 static int mov_read_avss(MOVContext *c, AVIOContext *pb, MOVAtom atom)
1720 return mov_read_extradata(c, pb, atom, AV_CODEC_ID_AVS);
1723 static int mov_read_jp2h(MOVContext *c, AVIOContext *pb, MOVAtom atom)
1725 return mov_read_extradata(c, pb, atom, AV_CODEC_ID_JPEG2000);
1728 static int mov_read_dpxe(MOVContext *c, AVIOContext *pb, MOVAtom atom)
1730 return mov_read_extradata(c, pb, atom, AV_CODEC_ID_R10K);
1733 static int mov_read_avid(MOVContext *c, AVIOContext *pb, MOVAtom atom)
1735 int ret = mov_read_extradata(c, pb, atom, AV_CODEC_ID_AVUI);
1737 ret = mov_read_extradata(c, pb, atom, AV_CODEC_ID_DNXHD);
1741 static int mov_read_targa_y216(MOVContext *c, AVIOContext *pb, MOVAtom atom)
1743 int ret = mov_read_extradata(c, pb, atom, AV_CODEC_ID_TARGA_Y216);
1745 if (!ret && c->fc->nb_streams >= 1) {
1746 AVCodecParameters *par = c->fc->streams[c->fc->nb_streams-1]->codecpar;
1747 if (par->extradata_size >= 40) {
1748 par->height = AV_RB16(&par->extradata[36]);
1749 par->width = AV_RB16(&par->extradata[38]);
1755 static int mov_read_ares(MOVContext *c, AVIOContext *pb, MOVAtom atom)
1757 if (c->fc->nb_streams >= 1) {
1758 AVCodecParameters *par = c->fc->streams[c->fc->nb_streams-1]->codecpar;
1759 if (par->codec_tag == MKTAG('A', 'V', 'i', 'n') &&
1760 par->codec_id == AV_CODEC_ID_H264 &&
1764 cid = avio_rb16(pb);
1765 /* For AVID AVCI50, force width of 1440 to be able to select the correct SPS and PPS */
1766 if (cid == 0xd4d || cid == 0xd4e)
1769 } else if ((par->codec_tag == MKTAG('A', 'V', 'd', '1') ||
1770 par->codec_tag == MKTAG('A', 'V', 'j', '2') ||
1771 par->codec_tag == MKTAG('A', 'V', 'd', 'n')) &&
1775 num = avio_rb32(pb);
1776 den = avio_rb32(pb);
1777 if (num <= 0 || den <= 0)
1779 switch (avio_rb32(pb)) {
1781 if (den >= INT_MAX / 2)
1785 c->fc->streams[c->fc->nb_streams-1]->internal->display_aspect_ratio.num = num;
1786 c->fc->streams[c->fc->nb_streams-1]->internal->display_aspect_ratio.den = den;
1793 return mov_read_avid(c, pb, atom);
1796 static int mov_read_aclr(MOVContext *c, AVIOContext *pb, MOVAtom atom)
1800 uint64_t original_size;
1801 if (c->fc->nb_streams >= 1) {
1802 AVCodecParameters *par = c->fc->streams[c->fc->nb_streams-1]->codecpar;
1803 if (par->codec_id == AV_CODEC_ID_H264)
1805 if (atom.size == 16) {
1806 original_size = par->extradata_size;
1807 ret = mov_realloc_extradata(par, atom);
1809 length = mov_read_atom_into_extradata(c, pb, atom, par, par->extradata + original_size);
1810 if (length == atom.size) {
1811 const uint8_t range_value = par->extradata[original_size + 19];
1812 switch (range_value) {
1814 par->color_range = AVCOL_RANGE_MPEG;
1817 par->color_range = AVCOL_RANGE_JPEG;
1820 av_log(c->fc, AV_LOG_WARNING, "ignored unknown aclr value (%d)\n", range_value);
1823 ff_dlog(c->fc, "color_range: %d\n", par->color_range);
1825 /* For some reason the whole atom was not added to the extradata */
1826 av_log(c->fc, AV_LOG_ERROR, "aclr not decoded - incomplete atom\n");
1829 av_log(c->fc, AV_LOG_ERROR, "aclr not decoded - unable to add atom to extradata\n");
1832 av_log(c->fc, AV_LOG_WARNING, "aclr not decoded - unexpected size %"PRId64"\n", atom.size);
1839 static int mov_read_svq3(MOVContext *c, AVIOContext *pb, MOVAtom atom)
1841 return mov_read_extradata(c, pb, atom, AV_CODEC_ID_SVQ3);
1844 static int mov_read_wave(MOVContext *c, AVIOContext *pb, MOVAtom atom)
1849 if (c->fc->nb_streams < 1)
1851 st = c->fc->streams[c->fc->nb_streams-1];
1853 if ((uint64_t)atom.size > (1<<30))
1854 return AVERROR_INVALIDDATA;
1856 if (st->codecpar->codec_id == AV_CODEC_ID_QDM2 ||
1857 st->codecpar->codec_id == AV_CODEC_ID_QDMC ||
1858 st->codecpar->codec_id == AV_CODEC_ID_SPEEX) {
1859 // pass all frma atom to codec, needed at least for QDMC and QDM2
1860 ret = ff_get_extradata(c->fc, st->codecpar, pb, atom.size);
1863 } else if (atom.size > 8) { /* to read frma, esds atoms */
1864 if (st->codecpar->codec_id == AV_CODEC_ID_ALAC && atom.size >= 24) {
1866 ret = ffio_ensure_seekback(pb, 8);
1869 buffer = avio_rb64(pb);
1871 if ( (buffer & 0xFFFFFFFF) == MKBETAG('f','r','m','a')
1872 && buffer >> 32 <= atom.size
1873 && buffer >> 32 >= 8) {
1876 } else if (!st->codecpar->extradata_size) {
1877 #define ALAC_EXTRADATA_SIZE 36
1878 st->codecpar->extradata = av_mallocz(ALAC_EXTRADATA_SIZE + AV_INPUT_BUFFER_PADDING_SIZE);
1879 if (!st->codecpar->extradata)
1880 return AVERROR(ENOMEM);
1881 st->codecpar->extradata_size = ALAC_EXTRADATA_SIZE;
1882 AV_WB32(st->codecpar->extradata , ALAC_EXTRADATA_SIZE);
1883 AV_WB32(st->codecpar->extradata + 4, MKTAG('a','l','a','c'));
1884 AV_WB64(st->codecpar->extradata + 12, buffer);
1885 avio_read(pb, st->codecpar->extradata + 20, 16);
1886 avio_skip(pb, atom.size - 24);
1890 if ((ret = mov_read_default(c, pb, atom)) < 0)
1893 avio_skip(pb, atom.size);
1898 * This function reads atom content and puts data in extradata without tag
1899 * nor size unlike mov_read_extradata.
1901 static int mov_read_glbl(MOVContext *c, AVIOContext *pb, MOVAtom atom)
1906 if (c->fc->nb_streams < 1)
1908 st = c->fc->streams[c->fc->nb_streams-1];
1910 if ((uint64_t)atom.size > (1<<30))
1911 return AVERROR_INVALIDDATA;
1913 if (atom.size >= 10) {
1914 // Broken files created by legacy versions of libavformat will
1915 // wrap a whole fiel atom inside of a glbl atom.
1916 unsigned size = avio_rb32(pb);
1917 unsigned type = avio_rl32(pb);
1918 avio_seek(pb, -8, SEEK_CUR);
1919 if (type == MKTAG('f','i','e','l') && size == atom.size)
1920 return mov_read_default(c, pb, atom);
1922 if (st->codecpar->extradata_size > 1 && st->codecpar->extradata) {
1923 av_log(c->fc, AV_LOG_WARNING, "ignoring multiple glbl\n");
1926 ret = ff_get_extradata(c->fc, st->codecpar, pb, atom.size);
1929 if (atom.type == MKTAG('h','v','c','C') && st->codecpar->codec_tag == MKTAG('d','v','h','1'))
1930 /* HEVC-based Dolby Vision derived from hvc1.
1931 Happens to match with an identifier
1932 previously utilized for DV. Thus, if we have
1933 the hvcC extradata box available as specified,
1934 set codec to HEVC */
1935 st->codecpar->codec_id = AV_CODEC_ID_HEVC;
1940 static int mov_read_dvc1(MOVContext *c, AVIOContext *pb, MOVAtom atom)
1943 uint8_t profile_level;
1946 if (c->fc->nb_streams < 1)
1948 st = c->fc->streams[c->fc->nb_streams-1];
1950 if (atom.size >= (1<<28) || atom.size < 7)
1951 return AVERROR_INVALIDDATA;
1953 profile_level = avio_r8(pb);
1954 if ((profile_level & 0xf0) != 0xc0)
1957 avio_seek(pb, 6, SEEK_CUR);
1958 ret = ff_get_extradata(c->fc, st->codecpar, pb, atom.size - 7);
1966 * An strf atom is a BITMAPINFOHEADER struct. This struct is 40 bytes itself,
1967 * but can have extradata appended at the end after the 40 bytes belonging
1970 static int mov_read_strf(MOVContext *c, AVIOContext *pb, MOVAtom atom)
1975 if (c->fc->nb_streams < 1)
1977 if (atom.size <= 40)
1979 st = c->fc->streams[c->fc->nb_streams-1];
1981 if ((uint64_t)atom.size > (1<<30))
1982 return AVERROR_INVALIDDATA;
1985 ret = ff_get_extradata(c->fc, st->codecpar, pb, atom.size - 40);
1992 static int mov_read_stco(MOVContext *c, AVIOContext *pb, MOVAtom atom)
1995 MOVStreamContext *sc;
1996 unsigned int i, entries;
1998 if (c->trak_index < 0) {
1999 av_log(c->fc, AV_LOG_WARNING, "STCO outside TRAK\n");
2002 if (c->fc->nb_streams < 1)
2004 st = c->fc->streams[c->fc->nb_streams-1];
2007 avio_r8(pb); /* version */
2008 avio_rb24(pb); /* flags */
2010 entries = avio_rb32(pb);
2015 if (sc->chunk_offsets) {
2016 av_log(c->fc, AV_LOG_WARNING, "Ignoring duplicated STCO atom\n");
2019 av_free(sc->chunk_offsets);
2020 sc->chunk_count = 0;
2021 sc->chunk_offsets = av_malloc_array(entries, sizeof(*sc->chunk_offsets));
2022 if (!sc->chunk_offsets)
2023 return AVERROR(ENOMEM);
2024 sc->chunk_count = entries;
2026 if (atom.type == MKTAG('s','t','c','o'))
2027 for (i = 0; i < entries && !pb->eof_reached; i++)
2028 sc->chunk_offsets[i] = avio_rb32(pb);
2029 else if (atom.type == MKTAG('c','o','6','4'))
2030 for (i = 0; i < entries && !pb->eof_reached; i++)
2031 sc->chunk_offsets[i] = avio_rb64(pb);
2033 return AVERROR_INVALIDDATA;
2035 sc->chunk_count = i;
2037 if (pb->eof_reached) {
2038 av_log(c->fc, AV_LOG_WARNING, "reached eof, corrupted STCO atom\n");
2045 static int mov_codec_id(AVStream *st, uint32_t format)
2047 int id = ff_codec_get_id(ff_codec_movaudio_tags, format);
2050 ((format & 0xFFFF) == 'm' + ('s' << 8) ||
2051 (format & 0xFFFF) == 'T' + ('S' << 8)))
2052 id = ff_codec_get_id(ff_codec_wav_tags, av_bswap32(format) & 0xFFFF);
2054 if (st->codecpar->codec_type != AVMEDIA_TYPE_VIDEO && id > 0) {
2055 st->codecpar->codec_type = AVMEDIA_TYPE_AUDIO;
2056 } else if (st->codecpar->codec_type != AVMEDIA_TYPE_AUDIO &&
2057 /* skip old ASF MPEG-4 tag */
2058 format && format != MKTAG('m','p','4','s')) {
2059 id = ff_codec_get_id(ff_codec_movvideo_tags, format);
2061 id = ff_codec_get_id(ff_codec_bmp_tags, format);
2063 st->codecpar->codec_type = AVMEDIA_TYPE_VIDEO;
2064 else if (st->codecpar->codec_type == AVMEDIA_TYPE_DATA ||
2065 (st->codecpar->codec_type == AVMEDIA_TYPE_SUBTITLE &&
2066 st->codecpar->codec_id == AV_CODEC_ID_NONE)) {
2067 id = ff_codec_get_id(ff_codec_movsubtitle_tags, format);
2069 st->codecpar->codec_type = AVMEDIA_TYPE_SUBTITLE;
2071 id = ff_codec_get_id(ff_codec_movdata_tags, format);
2075 st->codecpar->codec_tag = format;
2080 static void mov_parse_stsd_video(MOVContext *c, AVIOContext *pb,
2081 AVStream *st, MOVStreamContext *sc)
2083 uint8_t codec_name[32] = { 0 };
2088 /* The first 16 bytes of the video sample description are already
2089 * read in ff_mov_read_stsd_entries() */
2090 stsd_start = avio_tell(pb) - 16;
2092 avio_rb16(pb); /* version */
2093 avio_rb16(pb); /* revision level */
2094 id = avio_rl32(pb); /* vendor */
2095 av_dict_set(&st->metadata, "vendor_id", av_fourcc2str(id), 0);
2096 avio_rb32(pb); /* temporal quality */
2097 avio_rb32(pb); /* spatial quality */
2099 st->codecpar->width = avio_rb16(pb); /* width */
2100 st->codecpar->height = avio_rb16(pb); /* height */
2102 avio_rb32(pb); /* horiz resolution */
2103 avio_rb32(pb); /* vert resolution */
2104 avio_rb32(pb); /* data size, always 0 */
2105 avio_rb16(pb); /* frames per samples */
2107 len = avio_r8(pb); /* codec name, pascal string */
2110 mov_read_mac_string(c, pb, len, codec_name, sizeof(codec_name));
2112 avio_skip(pb, 31 - len);
2115 av_dict_set(&st->metadata, "encoder", codec_name, 0);
2117 /* codec_tag YV12 triggers an UV swap in rawdec.c */
2118 if (!strncmp(codec_name, "Planar Y'CbCr 8-bit 4:2:0", 25)) {
2119 st->codecpar->codec_tag = MKTAG('I', '4', '2', '0');
2120 st->codecpar->width &= ~1;
2121 st->codecpar->height &= ~1;
2123 /* Flash Media Server uses tag H.263 with Sorenson Spark */
2124 if (st->codecpar->codec_tag == MKTAG('H','2','6','3') &&
2125 !strncmp(codec_name, "Sorenson H263", 13))
2126 st->codecpar->codec_id = AV_CODEC_ID_FLV1;
2128 st->codecpar->bits_per_coded_sample = avio_rb16(pb); /* depth */
2130 avio_seek(pb, stsd_start, SEEK_SET);
2132 if (ff_get_qtpalette(st->codecpar->codec_id, pb, sc->palette)) {
2133 st->codecpar->bits_per_coded_sample &= 0x1F;
2134 sc->has_palette = 1;
2138 static void mov_parse_stsd_audio(MOVContext *c, AVIOContext *pb,
2139 AVStream *st, MOVStreamContext *sc)
2141 int bits_per_sample, flags;
2142 uint16_t version = avio_rb16(pb);
2144 AVDictionaryEntry *compatible_brands = av_dict_get(c->fc->metadata, "compatible_brands", NULL, AV_DICT_MATCH_CASE);
2146 avio_rb16(pb); /* revision level */
2147 id = avio_rl32(pb); /* vendor */
2148 av_dict_set(&st->metadata, "vendor_id", av_fourcc2str(id), 0);
2150 st->codecpar->channels = avio_rb16(pb); /* channel count */
2151 st->codecpar->bits_per_coded_sample = avio_rb16(pb); /* sample size */
2152 av_log(c->fc, AV_LOG_TRACE, "audio channels %d\n", st->codecpar->channels);
2154 sc->audio_cid = avio_rb16(pb);
2155 avio_rb16(pb); /* packet size = 0 */
2157 st->codecpar->sample_rate = ((avio_rb32(pb) >> 16));
2159 // Read QT version 1 fields. In version 0 these do not exist.
2160 av_log(c->fc, AV_LOG_TRACE, "version =%d, isom =%d\n", version, c->isom);
2162 (compatible_brands && strstr(compatible_brands->value, "qt ")) ||
2163 (sc->stsd_version == 0 && version > 0)) {
2165 sc->samples_per_frame = avio_rb32(pb);
2166 avio_rb32(pb); /* bytes per packet */
2167 sc->bytes_per_frame = avio_rb32(pb);
2168 avio_rb32(pb); /* bytes per sample */
2169 } else if (version == 2) {
2170 avio_rb32(pb); /* sizeof struct only */
2171 st->codecpar->sample_rate = av_int2double(avio_rb64(pb));
2172 st->codecpar->channels = avio_rb32(pb);
2173 avio_rb32(pb); /* always 0x7F000000 */
2174 st->codecpar->bits_per_coded_sample = avio_rb32(pb);
2176 flags = avio_rb32(pb); /* lpcm format specific flag */
2177 sc->bytes_per_frame = avio_rb32(pb);
2178 sc->samples_per_frame = avio_rb32(pb);
2179 if (st->codecpar->codec_tag == MKTAG('l','p','c','m'))
2180 st->codecpar->codec_id =
2181 ff_mov_get_lpcm_codec_id(st->codecpar->bits_per_coded_sample,
2184 if (version == 0 || (version == 1 && sc->audio_cid != -2)) {
2185 /* can't correctly handle variable sized packet as audio unit */
2186 switch (st->codecpar->codec_id) {
2187 case AV_CODEC_ID_MP2:
2188 case AV_CODEC_ID_MP3:
2189 st->need_parsing = AVSTREAM_PARSE_FULL;
2195 if (sc->format == 0) {
2196 if (st->codecpar->bits_per_coded_sample == 8)
2197 st->codecpar->codec_id = mov_codec_id(st, MKTAG('r','a','w',' '));
2198 else if (st->codecpar->bits_per_coded_sample == 16)
2199 st->codecpar->codec_id = mov_codec_id(st, MKTAG('t','w','o','s'));
2202 switch (st->codecpar->codec_id) {
2203 case AV_CODEC_ID_PCM_S8:
2204 case AV_CODEC_ID_PCM_U8:
2205 if (st->codecpar->bits_per_coded_sample == 16)
2206 st->codecpar->codec_id = AV_CODEC_ID_PCM_S16BE;
2208 case AV_CODEC_ID_PCM_S16LE:
2209 case AV_CODEC_ID_PCM_S16BE:
2210 if (st->codecpar->bits_per_coded_sample == 8)
2211 st->codecpar->codec_id = AV_CODEC_ID_PCM_S8;
2212 else if (st->codecpar->bits_per_coded_sample == 24)
2213 st->codecpar->codec_id =
2214 st->codecpar->codec_id == AV_CODEC_ID_PCM_S16BE ?
2215 AV_CODEC_ID_PCM_S24BE : AV_CODEC_ID_PCM_S24LE;
2216 else if (st->codecpar->bits_per_coded_sample == 32)
2217 st->codecpar->codec_id =
2218 st->codecpar->codec_id == AV_CODEC_ID_PCM_S16BE ?
2219 AV_CODEC_ID_PCM_S32BE : AV_CODEC_ID_PCM_S32LE;
2221 /* set values for old format before stsd version 1 appeared */
2222 case AV_CODEC_ID_MACE3:
2223 sc->samples_per_frame = 6;
2224 sc->bytes_per_frame = 2 * st->codecpar->channels;
2226 case AV_CODEC_ID_MACE6:
2227 sc->samples_per_frame = 6;
2228 sc->bytes_per_frame = 1 * st->codecpar->channels;
2230 case AV_CODEC_ID_ADPCM_IMA_QT:
2231 sc->samples_per_frame = 64;
2232 sc->bytes_per_frame = 34 * st->codecpar->channels;
2234 case AV_CODEC_ID_GSM:
2235 sc->samples_per_frame = 160;
2236 sc->bytes_per_frame = 33;
2242 bits_per_sample = av_get_bits_per_sample(st->codecpar->codec_id);
2243 if (bits_per_sample && (bits_per_sample >> 3) * (uint64_t)st->codecpar->channels <= INT_MAX) {
2244 st->codecpar->bits_per_coded_sample = bits_per_sample;
2245 sc->sample_size = (bits_per_sample >> 3) * st->codecpar->channels;
2249 static void mov_parse_stsd_subtitle(MOVContext *c, AVIOContext *pb,
2250 AVStream *st, MOVStreamContext *sc,
2253 // ttxt stsd contains display flags, justification, background
2254 // color, fonts, and default styles, so fake an atom to read it
2255 MOVAtom fake_atom = { .size = size };
2256 // mp4s contains a regular esds atom
2257 if (st->codecpar->codec_tag != AV_RL32("mp4s"))
2258 mov_read_glbl(c, pb, fake_atom);
2259 st->codecpar->width = sc->width;
2260 st->codecpar->height = sc->height;
2263 static uint32_t yuv_to_rgba(uint32_t ycbcr)
2268 y = (ycbcr >> 16) & 0xFF;
2269 cr = (ycbcr >> 8) & 0xFF;
2272 b = av_clip_uint8((1164 * (y - 16) + 2018 * (cb - 128)) / 1000);
2273 g = av_clip_uint8((1164 * (y - 16) - 813 * (cr - 128) - 391 * (cb - 128)) / 1000);
2274 r = av_clip_uint8((1164 * (y - 16) + 1596 * (cr - 128) ) / 1000);
2276 return (r << 16) | (g << 8) | b;
2279 static int mov_rewrite_dvd_sub_extradata(AVStream *st)
2281 char buf[256] = {0};
2282 uint8_t *src = st->codecpar->extradata;
2285 if (st->codecpar->extradata_size != 64)
2288 if (st->codecpar->width > 0 && st->codecpar->height > 0)
2289 snprintf(buf, sizeof(buf), "size: %dx%d\n",
2290 st->codecpar->width, st->codecpar->height);
2291 av_strlcat(buf, "palette: ", sizeof(buf));
2293 for (i = 0; i < 16; i++) {
2294 uint32_t yuv = AV_RB32(src + i * 4);
2295 uint32_t rgba = yuv_to_rgba(yuv);
2297 av_strlcatf(buf, sizeof(buf), "%06"PRIx32"%s", rgba, i != 15 ? ", " : "");
2300 if (av_strlcat(buf, "\n", sizeof(buf)) >= sizeof(buf))
2303 ret = ff_alloc_extradata(st->codecpar, strlen(buf));
2306 memcpy(st->codecpar->extradata, buf, st->codecpar->extradata_size);
2311 static int mov_parse_stsd_data(MOVContext *c, AVIOContext *pb,
2312 AVStream *st, MOVStreamContext *sc,
2317 if (st->codecpar->codec_tag == MKTAG('t','m','c','d')) {
2318 if ((int)size != size)
2319 return AVERROR(ENOMEM);
2321 ret = ff_get_extradata(c->fc, st->codecpar, pb, size);
2325 MOVStreamContext *tmcd_ctx = st->priv_data;
2327 val = AV_RB32(st->codecpar->extradata + 4);
2328 tmcd_ctx->tmcd_flags = val;
2329 st->avg_frame_rate.num = AV_RB32(st->codecpar->extradata + 8); /* timescale */
2330 st->avg_frame_rate.den = AV_RB32(st->codecpar->extradata + 12); /* frameDuration */
2332 uint32_t len = AV_RB32(st->codecpar->extradata + 18); /* name atom length */
2333 uint32_t format = AV_RB32(st->codecpar->extradata + 22);
2334 if (format == AV_RB32("name") && (int64_t)size >= (int64_t)len + 18) {
2335 uint16_t str_size = AV_RB16(st->codecpar->extradata + 26); /* string length */
2336 if (str_size > 0 && size >= (int)str_size + 30 &&
2337 st->codecpar->extradata[30] /* Don't add empty string */) {
2338 char *reel_name = av_malloc(str_size + 1);
2340 return AVERROR(ENOMEM);
2341 memcpy(reel_name, st->codecpar->extradata + 30, str_size);
2342 reel_name[str_size] = 0; /* Add null terminator */
2343 av_dict_set(&st->metadata, "reel_name", reel_name,
2344 AV_DICT_DONT_STRDUP_VAL);
2350 /* other codec type, just skip (rtp, mp4s ...) */
2351 avio_skip(pb, size);
2356 static int mov_finalize_stsd_codec(MOVContext *c, AVIOContext *pb,
2357 AVStream *st, MOVStreamContext *sc)
2359 if (st->codecpar->codec_type == AVMEDIA_TYPE_AUDIO &&
2360 !st->codecpar->sample_rate && sc->time_scale > 1)
2361 st->codecpar->sample_rate = sc->time_scale;
2363 /* special codec parameters handling */
2364 switch (st->codecpar->codec_id) {
2365 #if CONFIG_DV_DEMUXER
2366 case AV_CODEC_ID_DVAUDIO:
2367 c->dv_fctx = avformat_alloc_context();
2369 av_log(c->fc, AV_LOG_ERROR, "dv demux context alloc error\n");
2370 return AVERROR(ENOMEM);
2372 c->dv_demux = avpriv_dv_init_demux(c->dv_fctx);
2374 av_log(c->fc, AV_LOG_ERROR, "dv demux context init error\n");
2375 return AVERROR(ENOMEM);
2377 sc->dv_audio_container = 1;
2378 st->codecpar->codec_id = AV_CODEC_ID_PCM_S16LE;
2381 /* no ifdef since parameters are always those */
2382 case AV_CODEC_ID_QCELP:
2383 st->codecpar->channels = 1;
2384 // force sample rate for qcelp when not stored in mov
2385 if (st->codecpar->codec_tag != MKTAG('Q','c','l','p'))
2386 st->codecpar->sample_rate = 8000;
2387 // FIXME: Why is the following needed for some files?
2388 sc->samples_per_frame = 160;
2389 if (!sc->bytes_per_frame)
2390 sc->bytes_per_frame = 35;
2392 case AV_CODEC_ID_AMR_NB:
2393 st->codecpar->channels = 1;
2394 /* force sample rate for amr, stsd in 3gp does not store sample rate */
2395 st->codecpar->sample_rate = 8000;
2397 case AV_CODEC_ID_AMR_WB:
2398 st->codecpar->channels = 1;
2399 st->codecpar->sample_rate = 16000;
2401 case AV_CODEC_ID_MP2:
2402 case AV_CODEC_ID_MP3:
2403 /* force type after stsd for m1a hdlr */
2404 st->codecpar->codec_type = AVMEDIA_TYPE_AUDIO;
2406 case AV_CODEC_ID_GSM:
2407 case AV_CODEC_ID_ADPCM_MS:
2408 case AV_CODEC_ID_ADPCM_IMA_WAV:
2409 case AV_CODEC_ID_ILBC:
2410 case AV_CODEC_ID_MACE3:
2411 case AV_CODEC_ID_MACE6:
2412 case AV_CODEC_ID_QDM2:
2413 st->codecpar->block_align = sc->bytes_per_frame;
2415 case AV_CODEC_ID_ALAC:
2416 if (st->codecpar->extradata_size == 36) {
2417 st->codecpar->channels = AV_RB8 (st->codecpar->extradata + 21);
2418 st->codecpar->sample_rate = AV_RB32(st->codecpar->extradata + 32);
2421 case AV_CODEC_ID_AC3:
2422 case AV_CODEC_ID_EAC3:
2423 case AV_CODEC_ID_MPEG1VIDEO:
2424 case AV_CODEC_ID_VC1:
2425 case AV_CODEC_ID_VP8:
2426 case AV_CODEC_ID_VP9:
2427 st->need_parsing = AVSTREAM_PARSE_FULL;
2429 case AV_CODEC_ID_AV1:
2430 st->need_parsing = AVSTREAM_PARSE_HEADERS;
2438 static int mov_skip_multiple_stsd(MOVContext *c, AVIOContext *pb,
2439 int codec_tag, int format,
2442 int video_codec_id = ff_codec_get_id(ff_codec_movvideo_tags, format);
2445 (codec_tag != format &&
2446 // AVID 1:1 samples with differing data format and codec tag exist
2447 (codec_tag != AV_RL32("AV1x") || format != AV_RL32("AVup")) &&
2448 // prores is allowed to have differing data format and codec tag
2449 codec_tag != AV_RL32("apcn") && codec_tag != AV_RL32("apch") &&
2451 codec_tag != AV_RL32("dvpp") && codec_tag != AV_RL32("dvcp") &&
2452 (c->fc->video_codec_id ? video_codec_id != c->fc->video_codec_id
2453 : codec_tag != MKTAG('j','p','e','g')))) {
2454 /* Multiple fourcc, we skip JPEG. This is not correct, we should
2455 * export it as a separate AVStream but this needs a few changes
2456 * in the MOV demuxer, patch welcome. */
2458 av_log(c->fc, AV_LOG_WARNING, "multiple fourcc not supported\n");
2459 avio_skip(pb, size);
2466 int ff_mov_read_stsd_entries(MOVContext *c, AVIOContext *pb, int entries)
2469 MOVStreamContext *sc;
2470 int pseudo_stream_id;
2472 av_assert0 (c->fc->nb_streams >= 1);
2473 st = c->fc->streams[c->fc->nb_streams-1];
2476 for (pseudo_stream_id = 0;
2477 pseudo_stream_id < entries && !pb->eof_reached;
2478 pseudo_stream_id++) {
2479 //Parsing Sample description table
2481 int ret, dref_id = 1;
2482 MOVAtom a = { AV_RL32("stsd") };
2483 int64_t start_pos = avio_tell(pb);
2484 int64_t size = avio_rb32(pb); /* size */
2485 uint32_t format = avio_rl32(pb); /* data format */
2488 avio_rb32(pb); /* reserved */
2489 avio_rb16(pb); /* reserved */
2490 dref_id = avio_rb16(pb);
2491 } else if (size <= 7) {
2492 av_log(c->fc, AV_LOG_ERROR,
2493 "invalid size %"PRId64" in stsd\n", size);
2494 return AVERROR_INVALIDDATA;
2497 if (mov_skip_multiple_stsd(c, pb, st->codecpar->codec_tag, format,
2498 size - (avio_tell(pb) - start_pos))) {
2503 sc->pseudo_stream_id = st->codecpar->codec_tag ? -1 : pseudo_stream_id;
2504 sc->dref_id= dref_id;
2505 sc->format = format;
2507 id = mov_codec_id(st, format);
2509 av_log(c->fc, AV_LOG_TRACE,
2510 "size=%"PRId64" 4CC=%s codec_type=%d\n", size,
2511 av_fourcc2str(format), st->codecpar->codec_type);
2513 st->codecpar->codec_id = id;
2514 if (st->codecpar->codec_type==AVMEDIA_TYPE_VIDEO) {
2515 mov_parse_stsd_video(c, pb, st, sc);
2516 } else if (st->codecpar->codec_type==AVMEDIA_TYPE_AUDIO) {
2517 mov_parse_stsd_audio(c, pb, st, sc);
2518 if (st->codecpar->sample_rate < 0) {
2519 av_log(c->fc, AV_LOG_ERROR, "Invalid sample rate %d\n", st->codecpar->sample_rate);
2520 return AVERROR_INVALIDDATA;
2522 } else if (st->codecpar->codec_type==AVMEDIA_TYPE_SUBTITLE){
2523 mov_parse_stsd_subtitle(c, pb, st, sc,
2524 size - (avio_tell(pb) - start_pos));
2526 ret = mov_parse_stsd_data(c, pb, st, sc,
2527 size - (avio_tell(pb) - start_pos));
2531 /* this will read extra atoms at the end (wave, alac, damr, avcC, hvcC, SMI ...) */
2532 a.size = size - (avio_tell(pb) - start_pos);
2534 if ((ret = mov_read_default(c, pb, a)) < 0)
2536 } else if (a.size > 0)
2537 avio_skip(pb, a.size);
2539 if (sc->extradata && st->codecpar->extradata) {
2540 int extra_size = st->codecpar->extradata_size;
2542 /* Move the current stream extradata to the stream context one. */
2543 sc->extradata_size[pseudo_stream_id] = extra_size;
2544 sc->extradata[pseudo_stream_id] = st->codecpar->extradata;
2545 st->codecpar->extradata = NULL;
2546 st->codecpar->extradata_size = 0;
2551 if (pb->eof_reached) {
2552 av_log(c->fc, AV_LOG_WARNING, "reached eof, corrupted STSD atom\n");
2559 static int mov_read_stsd(MOVContext *c, AVIOContext *pb, MOVAtom atom)
2562 MOVStreamContext *sc;
2565 if (c->fc->nb_streams < 1)
2567 st = c->fc->streams[c->fc->nb_streams - 1];
2570 sc->stsd_version = avio_r8(pb);
2571 avio_rb24(pb); /* flags */
2572 entries = avio_rb32(pb);
2574 /* Each entry contains a size (4 bytes) and format (4 bytes). */
2575 if (entries <= 0 || entries > atom.size / 8 || entries > 1024) {
2576 av_log(c->fc, AV_LOG_ERROR, "invalid STSD entries %d\n", entries);
2577 return AVERROR_INVALIDDATA;
2580 if (sc->extradata) {
2581 av_log(c->fc, AV_LOG_ERROR,
2582 "Duplicate stsd found in this track.\n");
2583 return AVERROR_INVALIDDATA;
2586 /* Prepare space for hosting multiple extradata. */
2587 sc->extradata = av_mallocz_array(entries, sizeof(*sc->extradata));
2589 return AVERROR(ENOMEM);
2591 sc->extradata_size = av_mallocz_array(entries, sizeof(*sc->extradata_size));
2592 if (!sc->extradata_size) {
2593 ret = AVERROR(ENOMEM);
2597 ret = ff_mov_read_stsd_entries(c, pb, entries);
2601 /* Restore back the primary extradata. */
2602 av_freep(&st->codecpar->extradata);
2603 st->codecpar->extradata_size = sc->extradata_size[0];
2604 if (sc->extradata_size[0]) {
2605 st->codecpar->extradata = av_mallocz(sc->extradata_size[0] + AV_INPUT_BUFFER_PADDING_SIZE);
2606 if (!st->codecpar->extradata)
2607 return AVERROR(ENOMEM);
2608 memcpy(st->codecpar->extradata, sc->extradata[0], sc->extradata_size[0]);
2611 return mov_finalize_stsd_codec(c, pb, st, sc);
2613 if (sc->extradata) {
2615 for (j = 0; j < sc->stsd_count; j++)
2616 av_freep(&sc->extradata[j]);
2619 av_freep(&sc->extradata);
2620 av_freep(&sc->extradata_size);
2624 static int mov_read_stsc(MOVContext *c, AVIOContext *pb, MOVAtom atom)
2627 MOVStreamContext *sc;
2628 unsigned int i, entries;
2630 if (c->fc->nb_streams < 1)
2632 st = c->fc->streams[c->fc->nb_streams-1];
2635 avio_r8(pb); /* version */
2636 avio_rb24(pb); /* flags */
2638 entries = avio_rb32(pb);
2639 if ((uint64_t)entries * 12 + 4 > atom.size)
2640 return AVERROR_INVALIDDATA;
2642 av_log(c->fc, AV_LOG_TRACE, "track[%u].stsc.entries = %u\n", c->fc->nb_streams - 1, entries);
2646 if (sc->stsc_data) {
2647 av_log(c->fc, AV_LOG_WARNING, "Ignoring duplicated STSC atom\n");
2650 av_free(sc->stsc_data);
2652 sc->stsc_data = av_malloc_array(entries, sizeof(*sc->stsc_data));
2654 return AVERROR(ENOMEM);
2656 for (i = 0; i < entries && !pb->eof_reached; i++) {
2657 sc->stsc_data[i].first = avio_rb32(pb);
2658 sc->stsc_data[i].count = avio_rb32(pb);
2659 sc->stsc_data[i].id = avio_rb32(pb);
2663 for (i = sc->stsc_count - 1; i < UINT_MAX; i--) {
2664 int64_t first_min = i + 1;
2665 if ((i+1 < sc->stsc_count && sc->stsc_data[i].first >= sc->stsc_data[i+1].first) ||
2666 (i > 0 && sc->stsc_data[i].first <= sc->stsc_data[i-1].first) ||
2667 sc->stsc_data[i].first < first_min ||
2668 sc->stsc_data[i].count < 1 ||
2669 sc->stsc_data[i].id < 1) {
2670 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);
2671 if (i+1 >= sc->stsc_count) {
2672 if (sc->stsc_data[i].count == 0 && i > 0) {
2676 sc->stsc_data[i].first = FFMAX(sc->stsc_data[i].first, first_min);
2677 if (i > 0 && sc->stsc_data[i].first <= sc->stsc_data[i-1].first)
2678 sc->stsc_data[i].first = FFMIN(sc->stsc_data[i-1].first + 1LL, INT_MAX);
2679 sc->stsc_data[i].count = FFMAX(sc->stsc_data[i].count, 1);
2680 sc->stsc_data[i].id = FFMAX(sc->stsc_data[i].id, 1);
2683 av_assert0(sc->stsc_data[i+1].first >= 2);
2684 // We replace this entry by the next valid
2685 sc->stsc_data[i].first = sc->stsc_data[i+1].first - 1;
2686 sc->stsc_data[i].count = sc->stsc_data[i+1].count;
2687 sc->stsc_data[i].id = sc->stsc_data[i+1].id;
2691 if (pb->eof_reached) {
2692 av_log(c->fc, AV_LOG_WARNING, "reached eof, corrupted STSC atom\n");
2699 static inline int mov_stsc_index_valid(unsigned int index, unsigned int count)
2701 return index < count - 1;
2704 /* Compute the samples value for the stsc entry at the given index. */
2705 static inline int64_t mov_get_stsc_samples(MOVStreamContext *sc, unsigned int index)
2709 if (mov_stsc_index_valid(index, sc->stsc_count))
2710 chunk_count = sc->stsc_data[index + 1].first - sc->stsc_data[index].first;
2712 // Validation for stsc / stco happens earlier in mov_read_stsc + mov_read_trak.
2713 av_assert0(sc->stsc_data[index].first <= sc->chunk_count);
2714 chunk_count = sc->chunk_count - (sc->stsc_data[index].first - 1);
2717 return sc->stsc_data[index].count * (int64_t)chunk_count;
2720 static int mov_read_stps(MOVContext *c, AVIOContext *pb, MOVAtom atom)
2723 MOVStreamContext *sc;
2724 unsigned i, entries;
2726 if (c->fc->nb_streams < 1)
2728 st = c->fc->streams[c->fc->nb_streams-1];
2731 avio_rb32(pb); // version + flags
2733 entries = avio_rb32(pb);
2735 av_log(c->fc, AV_LOG_WARNING, "Duplicated STPS atom\n");
2736 av_free(sc->stps_data);
2738 sc->stps_data = av_malloc_array(entries, sizeof(*sc->stps_data));
2740 return AVERROR(ENOMEM);
2742 for (i = 0; i < entries && !pb->eof_reached; i++) {
2743 sc->stps_data[i] = avio_rb32(pb);
2748 if (pb->eof_reached) {
2749 av_log(c->fc, AV_LOG_WARNING, "reached eof, corrupted STPS atom\n");
2756 static int mov_read_stss(MOVContext *c, AVIOContext *pb, MOVAtom atom)
2759 MOVStreamContext *sc;
2760 unsigned int i, entries;
2762 if (c->fc->nb_streams < 1)
2764 st = c->fc->streams[c->fc->nb_streams-1];
2767 avio_r8(pb); /* version */
2768 avio_rb24(pb); /* flags */
2770 entries = avio_rb32(pb);
2772 av_log(c->fc, AV_LOG_TRACE, "keyframe_count = %u\n", entries);
2775 sc->keyframe_absent = 1;
2776 if (!st->need_parsing && st->codecpar->codec_type == AVMEDIA_TYPE_VIDEO)
2777 st->need_parsing = AVSTREAM_PARSE_HEADERS;
2781 av_log(c->fc, AV_LOG_WARNING, "Duplicated STSS atom\n");
2782 if (entries >= UINT_MAX / sizeof(int))
2783 return AVERROR_INVALIDDATA;
2784 av_freep(&sc->keyframes);
2785 sc->keyframe_count = 0;
2786 sc->keyframes = av_malloc_array(entries, sizeof(*sc->keyframes));
2788 return AVERROR(ENOMEM);
2790 for (i = 0; i < entries && !pb->eof_reached; i++) {
2791 sc->keyframes[i] = avio_rb32(pb);
2794 sc->keyframe_count = i;
2796 if (pb->eof_reached) {
2797 av_log(c->fc, AV_LOG_WARNING, "reached eof, corrupted STSS atom\n");
2804 static int mov_read_stsz(MOVContext *c, AVIOContext *pb, MOVAtom atom)
2807 MOVStreamContext *sc;
2808 unsigned int i, entries, sample_size, field_size, num_bytes;
2813 if (c->fc->nb_streams < 1)
2815 st = c->fc->streams[c->fc->nb_streams-1];
2818 avio_r8(pb); /* version */
2819 avio_rb24(pb); /* flags */
2821 if (atom.type == MKTAG('s','t','s','z')) {
2822 sample_size = avio_rb32(pb);
2823 if (!sc->sample_size) /* do not overwrite value computed in stsd */
2824 sc->sample_size = sample_size;
2825 sc->stsz_sample_size = sample_size;
2829 avio_rb24(pb); /* reserved */
2830 field_size = avio_r8(pb);
2832 entries = avio_rb32(pb);
2834 av_log(c->fc, AV_LOG_TRACE, "sample_size = %u sample_count = %u\n", sc->sample_size, entries);
2836 sc->sample_count = entries;
2840 if (field_size != 4 && field_size != 8 && field_size != 16 && field_size != 32) {
2841 av_log(c->fc, AV_LOG_ERROR, "Invalid sample field size %u\n", field_size);
2842 return AVERROR_INVALIDDATA;
2847 if (entries >= (UINT_MAX - 4) / field_size)
2848 return AVERROR_INVALIDDATA;
2849 if (sc->sample_sizes)
2850 av_log(c->fc, AV_LOG_WARNING, "Duplicated STSZ atom\n");
2851 av_free(sc->sample_sizes);
2852 sc->sample_count = 0;
2853 sc->sample_sizes = av_malloc_array(entries, sizeof(*sc->sample_sizes));
2854 if (!sc->sample_sizes)
2855 return AVERROR(ENOMEM);
2857 num_bytes = (entries*field_size+4)>>3;
2859 buf = av_malloc(num_bytes+AV_INPUT_BUFFER_PADDING_SIZE);
2861 av_freep(&sc->sample_sizes);
2862 return AVERROR(ENOMEM);
2865 ret = ffio_read_size(pb, buf, num_bytes);
2867 av_freep(&sc->sample_sizes);
2869 av_log(c->fc, AV_LOG_WARNING, "STSZ atom truncated\n");
2873 init_get_bits(&gb, buf, 8*num_bytes);
2875 for (i = 0; i < entries && !pb->eof_reached; i++) {
2876 sc->sample_sizes[i] = get_bits_long(&gb, field_size);
2877 if (sc->sample_sizes[i] < 0) {
2879 av_log(c->fc, AV_LOG_ERROR, "Invalid sample size %d\n", sc->sample_sizes[i]);
2880 return AVERROR_INVALIDDATA;
2882 sc->data_size += sc->sample_sizes[i];
2885 sc->sample_count = i;
2889 if (pb->eof_reached) {
2890 av_log(c->fc, AV_LOG_WARNING, "reached eof, corrupted STSZ atom\n");
2897 static int mov_read_stts(MOVContext *c, AVIOContext *pb, MOVAtom atom)
2900 MOVStreamContext *sc;
2901 unsigned int i, entries, alloc_size = 0;
2902 int64_t duration = 0;
2903 int64_t total_sample_count = 0;
2905 if (c->fc->nb_streams < 1)
2907 st = c->fc->streams[c->fc->nb_streams-1];
2910 avio_r8(pb); /* version */
2911 avio_rb24(pb); /* flags */
2912 entries = avio_rb32(pb);
2914 av_log(c->fc, AV_LOG_TRACE, "track[%u].stts.entries = %u\n",
2915 c->fc->nb_streams-1, entries);
2918 av_log(c->fc, AV_LOG_WARNING, "Duplicated STTS atom\n");
2919 av_freep(&sc->stts_data);
2921 if (entries >= INT_MAX / sizeof(*sc->stts_data))
2922 return AVERROR(ENOMEM);
2924 for (i = 0; i < entries && !pb->eof_reached; i++) {
2925 int sample_duration;
2926 unsigned int sample_count;
2927 unsigned int min_entries = FFMIN(FFMAX(i + 1, 1024 * 1024), entries);
2928 MOVStts *stts_data = av_fast_realloc(sc->stts_data, &alloc_size,
2929 min_entries * sizeof(*sc->stts_data));
2931 av_freep(&sc->stts_data);
2933 return AVERROR(ENOMEM);
2935 sc->stts_count = min_entries;
2936 sc->stts_data = stts_data;
2938 sample_count = avio_rb32(pb);
2939 sample_duration = avio_rb32(pb);
2941 sc->stts_data[i].count= sample_count;
2942 sc->stts_data[i].duration= sample_duration;
2944 av_log(c->fc, AV_LOG_TRACE, "sample_count=%d, sample_duration=%d\n",
2945 sample_count, sample_duration);
2947 duration+=(int64_t)sample_duration*(uint64_t)sample_count;
2948 total_sample_count+=sample_count;
2954 duration <= INT64_MAX - sc->duration_for_fps &&
2955 total_sample_count <= INT_MAX - sc->nb_frames_for_fps) {
2956 sc->duration_for_fps += duration;
2957 sc->nb_frames_for_fps += total_sample_count;
2960 if (pb->eof_reached) {
2961 av_log(c->fc, AV_LOG_WARNING, "reached eof, corrupted STTS atom\n");
2965 st->nb_frames= total_sample_count;
2967 st->duration= FFMIN(st->duration, duration);
2968 sc->track_end = duration;
2972 static int mov_read_sdtp(MOVContext *c, AVIOContext *pb, MOVAtom atom)
2975 MOVStreamContext *sc;
2978 if (c->fc->nb_streams < 1)
2980 st = c->fc->streams[c->fc->nb_streams - 1];
2983 avio_r8(pb); /* version */
2984 avio_rb24(pb); /* flags */
2985 entries = atom.size - 4;
2987 av_log(c->fc, AV_LOG_TRACE, "track[%u].sdtp.entries = %" PRId64 "\n",
2988 c->fc->nb_streams - 1, entries);
2991 av_log(c->fc, AV_LOG_WARNING, "Duplicated SDTP atom\n");
2992 av_freep(&sc->sdtp_data);
2995 sc->sdtp_data = av_malloc(entries);
2997 return AVERROR(ENOMEM);
2999 for (i = 0; i < entries && !pb->eof_reached; i++)
3000 sc->sdtp_data[i] = avio_r8(pb);
3006 static void mov_update_dts_shift(MOVStreamContext *sc, int duration, void *logctx)
3009 if (duration == INT_MIN) {
3010 av_log(logctx, AV_LOG_WARNING, "mov_update_dts_shift(): dts_shift set to %d\n", INT_MAX);
3013 sc->dts_shift = FFMAX(sc->dts_shift, -duration);
3017 static int mov_read_ctts(MOVContext *c, AVIOContext *pb, MOVAtom atom)
3020 MOVStreamContext *sc;
3021 unsigned int i, entries, ctts_count = 0;
3023 if (c->fc->nb_streams < 1)
3025 st = c->fc->streams[c->fc->nb_streams-1];
3028 avio_r8(pb); /* version */
3029 avio_rb24(pb); /* flags */
3030 entries = avio_rb32(pb);
3032 av_log(c->fc, AV_LOG_TRACE, "track[%u].ctts.entries = %u\n", c->fc->nb_streams - 1, entries);
3036 if (entries >= UINT_MAX / sizeof(*sc->ctts_data))
3037 return AVERROR_INVALIDDATA;
3038 av_freep(&sc->ctts_data);
3039 sc->ctts_data = av_fast_realloc(NULL, &sc->ctts_allocated_size, entries * sizeof(*sc->ctts_data));
3041 return AVERROR(ENOMEM);
3043 for (i = 0; i < entries && !pb->eof_reached; i++) {
3044 int count = avio_rb32(pb);
3045 int duration = avio_rb32(pb);
3048 av_log(c->fc, AV_LOG_TRACE,
3049 "ignoring CTTS entry with count=%d duration=%d\n",
3054 add_ctts_entry(&sc->ctts_data, &ctts_count, &sc->ctts_allocated_size,
3057 av_log(c->fc, AV_LOG_TRACE, "count=%d, duration=%d\n",
3060 if (FFNABS(duration) < -(1<<28) && i+2<entries) {
3061 av_log(c->fc, AV_LOG_WARNING, "CTTS invalid\n");
3062 av_freep(&sc->ctts_data);
3068 mov_update_dts_shift(sc, duration, c->fc);
3071 sc->ctts_count = ctts_count;
3073 if (pb->eof_reached) {
3074 av_log(c->fc, AV_LOG_WARNING, "reached eof, corrupted CTTS atom\n");
3078 av_log(c->fc, AV_LOG_TRACE, "dts shift %d\n", sc->dts_shift);
3083 static int mov_read_sbgp(MOVContext *c, AVIOContext *pb, MOVAtom atom)
3086 MOVStreamContext *sc;
3087 unsigned int i, entries;
3089 uint32_t grouping_type;
3091 if (c->fc->nb_streams < 1)
3093 st = c->fc->streams[c->fc->nb_streams-1];
3096 version = avio_r8(pb); /* version */
3097 avio_rb24(pb); /* flags */
3098 grouping_type = avio_rl32(pb);
3099 if (grouping_type != MKTAG( 'r','a','p',' '))
3100 return 0; /* only support 'rap ' grouping */
3102 avio_rb32(pb); /* grouping_type_parameter */
3104 entries = avio_rb32(pb);
3108 av_log(c->fc, AV_LOG_WARNING, "Duplicated SBGP atom\n");
3109 av_free(sc->rap_group);
3110 sc->rap_group_count = 0;
3111 sc->rap_group = av_malloc_array(entries, sizeof(*sc->rap_group));
3113 return AVERROR(ENOMEM);
3115 for (i = 0; i < entries && !pb->eof_reached; i++) {
3116 sc->rap_group[i].count = avio_rb32(pb); /* sample_count */
3117 sc->rap_group[i].index = avio_rb32(pb); /* group_description_index */
3120 sc->rap_group_count = i;
3122 if (pb->eof_reached) {
3123 av_log(c->fc, AV_LOG_WARNING, "reached eof, corrupted SBGP atom\n");
3131 * Get ith edit list entry (media time, duration).
3133 static int get_edit_list_entry(MOVContext *mov,
3134 const MOVStreamContext *msc,
3135 unsigned int edit_list_index,
3136 int64_t *edit_list_media_time,
3137 int64_t *edit_list_duration,
3138 int64_t global_timescale)
3140 if (edit_list_index == msc->elst_count) {
3143 *edit_list_media_time = msc->elst_data[edit_list_index].time;
3144 *edit_list_duration = msc->elst_data[edit_list_index].duration;
3146 /* duration is in global timescale units;convert to msc timescale */
3147 if (global_timescale == 0) {
3148 avpriv_request_sample(mov->fc, "Support for mvhd.timescale = 0 with editlists");
3151 *edit_list_duration = av_rescale(*edit_list_duration, msc->time_scale,
3157 * Find the closest previous frame to the timestamp_pts, in e_old index
3158 * entries. Searching for just any frame / just key frames can be controlled by
3159 * last argument 'flag'.
3160 * Note that if ctts_data is not NULL, we will always search for a key frame
3161 * irrespective of the value of 'flag'. If we don't find any keyframe, we will
3162 * return the first frame of the video.
3164 * Here the timestamp_pts is considered to be a presentation timestamp and
3165 * the timestamp of index entries are considered to be decoding timestamps.
3167 * Returns 0 if successful in finding a frame, else returns -1.
3168 * Places the found index corresponding output arg.
3170 * If ctts_old is not NULL, then refines the searched entry by searching
3171 * backwards from the found timestamp, to find the frame with correct PTS.
3173 * Places the found ctts_index and ctts_sample in corresponding output args.
3175 static int find_prev_closest_index(AVStream *st,
3176 AVIndexEntry *e_old,
3180 int64_t timestamp_pts,
3183 int64_t* ctts_index,
3184 int64_t* ctts_sample)
3186 MOVStreamContext *msc = st->priv_data;
3187 AVIndexEntry *e_keep = st->internal->index_entries;
3188 int nb_keep = st->internal->nb_index_entries;
3190 int64_t index_ctts_count;
3194 // If dts_shift > 0, then all the index timestamps will have to be offset by
3195 // at least dts_shift amount to obtain PTS.
3196 // Hence we decrement the searched timestamp_pts by dts_shift to find the closest index element.
3197 if (msc->dts_shift > 0) {
3198 timestamp_pts -= msc->dts_shift;
3201 st->internal->index_entries = e_old;
3202 st->internal->nb_index_entries = nb_old;
3203 *index = av_index_search_timestamp(st, timestamp_pts, flag | AVSEEK_FLAG_BACKWARD);
3205 // Keep going backwards in the index entries until the timestamp is the same.
3207 for (i = *index; i > 0 && e_old[i].timestamp == e_old[i - 1].timestamp;
3209 if ((flag & AVSEEK_FLAG_ANY) ||
3210 (e_old[i - 1].flags & AVINDEX_KEYFRAME)) {
3216 // If we have CTTS then refine the search, by searching backwards over PTS
3217 // computed by adding corresponding CTTS durations to index timestamps.
3218 if (ctts_data && *index >= 0) {
3219 av_assert0(ctts_index);
3220 av_assert0(ctts_sample);
3221 // Find out the ctts_index for the found frame.
3224 for (index_ctts_count = 0; index_ctts_count < *index; index_ctts_count++) {
3225 if (*ctts_index < ctts_count) {
3227 if (ctts_data[*ctts_index].count == *ctts_sample) {
3234 while (*index >= 0 && (*ctts_index) >= 0 && (*ctts_index) < ctts_count) {
3235 // Find a "key frame" with PTS <= timestamp_pts (So that we can decode B-frames correctly).
3236 // No need to add dts_shift to the timestamp here becase timestamp_pts has already been
3237 // compensated by dts_shift above.
3238 if ((e_old[*index].timestamp + ctts_data[*ctts_index].duration) <= timestamp_pts &&
3239 (e_old[*index].flags & AVINDEX_KEYFRAME)) {
3244 if (*ctts_sample == 0) {
3246 if (*ctts_index >= 0)
3247 *ctts_sample = ctts_data[*ctts_index].count - 1;
3254 /* restore AVStream state*/
3255 st->internal->index_entries = e_keep;
3256 st->internal->nb_index_entries = nb_keep;
3257 return *index >= 0 ? 0 : -1;
3261 * Add index entry with the given values, to the end of st->internal->index_entries.
3262 * Returns the new size st->internal->index_entries if successful, else returns -1.
3264 * This function is similar to ff_add_index_entry in libavformat/utils.c
3265 * except that here we are always unconditionally adding an index entry to
3266 * the end, instead of searching the entries list and skipping the add if
3267 * there is an existing entry with the same timestamp.
3268 * This is needed because the mov_fix_index calls this func with the same
3269 * unincremented timestamp for successive discarded frames.
3271 static int64_t add_index_entry(AVStream *st, int64_t pos, int64_t timestamp,
3272 int size, int distance, int flags)
3274 AVIndexEntry *entries, *ie;
3276 const size_t min_size_needed = (st->internal->nb_index_entries + 1) * sizeof(AVIndexEntry);
3278 // Double the allocation each time, to lower memory fragmentation.
3279 // Another difference from ff_add_index_entry function.
3280 const size_t requested_size =
3281 min_size_needed > st->internal->index_entries_allocated_size ?
3282 FFMAX(min_size_needed, 2 * st->internal->index_entries_allocated_size) :
3285 if (st->internal->nb_index_entries + 1U >= UINT_MAX / sizeof(AVIndexEntry))
3288 entries = av_fast_realloc(st->internal->index_entries,
3289 &st->internal->index_entries_allocated_size,
3294 st->internal->index_entries= entries;
3296 index= st->internal->nb_index_entries++;
3297 ie= &entries[index];
3300 ie->timestamp = timestamp;
3301 ie->min_distance= distance;
3308 * Rewrite timestamps of index entries in the range [end_index - frame_duration_buffer_size, end_index)
3309 * by subtracting end_ts successively by the amounts given in frame_duration_buffer.
3311 static void fix_index_entry_timestamps(AVStream* st, int end_index, int64_t end_ts,
3312 int64_t* frame_duration_buffer,
3313 int frame_duration_buffer_size) {
3315 av_assert0(end_index >= 0 && end_index <= st->internal->nb_index_entries);
3316 for (i = 0; i < frame_duration_buffer_size; i++) {
3317 end_ts -= frame_duration_buffer[frame_duration_buffer_size - 1 - i];
3318 st->internal->index_entries[end_index - 1 - i].timestamp = end_ts;
3323 * Append a new ctts entry to ctts_data.
3324 * Returns the new ctts_count if successful, else returns -1.
3326 static int64_t add_ctts_entry(MOVStts** ctts_data, unsigned int* ctts_count, unsigned int* allocated_size,
3327 int count, int duration)
3329 MOVStts *ctts_buf_new;
3330 const size_t min_size_needed = (*ctts_count + 1) * sizeof(MOVStts);
3331 const size_t requested_size =
3332 min_size_needed > *allocated_size ?
3333 FFMAX(min_size_needed, 2 * (*allocated_size)) :
3336 if ((unsigned)(*ctts_count) >= UINT_MAX / sizeof(MOVStts) - 1)
3339 ctts_buf_new = av_fast_realloc(*ctts_data, allocated_size, requested_size);
3344 *ctts_data = ctts_buf_new;
3346 ctts_buf_new[*ctts_count].count = count;
3347 ctts_buf_new[*ctts_count].duration = duration;
3349 *ctts_count = (*ctts_count) + 1;
3353 #define MAX_REORDER_DELAY 16
3354 static void mov_estimate_video_delay(MOVContext *c, AVStream* st)
3356 MOVStreamContext *msc = st->priv_data;
3359 int ctts_sample = 0;
3360 int64_t pts_buf[MAX_REORDER_DELAY + 1]; // Circular buffer to sort pts.
3362 int j, r, num_swaps;
3364 for (j = 0; j < MAX_REORDER_DELAY + 1; j++)
3365 pts_buf[j] = INT64_MIN;
3367 if (st->codecpar->video_delay <= 0 && msc->ctts_data &&
3368 st->codecpar->codec_id == AV_CODEC_ID_H264) {
3369 st->codecpar->video_delay = 0;
3370 for (ind = 0; ind < st->internal->nb_index_entries && ctts_ind < msc->ctts_count; ++ind) {
3371 // Point j to the last elem of the buffer and insert the current pts there.
3373 buf_start = (buf_start + 1);
3374 if (buf_start == MAX_REORDER_DELAY + 1)
3377 pts_buf[j] = st->internal->index_entries[ind].timestamp + msc->ctts_data[ctts_ind].duration;
3379 // The timestamps that are already in the sorted buffer, and are greater than the
3380 // current pts, are exactly the timestamps that need to be buffered to output PTS
3381 // in correct sorted order.
3382 // Hence the video delay (which is the buffer size used to sort DTS and output PTS),
3383 // can be computed as the maximum no. of swaps any particular timestamp needs to
3384 // go through, to keep this buffer in sorted order.
3386 while (j != buf_start) {
3388 if (r < 0) r = MAX_REORDER_DELAY;
3389 if (pts_buf[j] < pts_buf[r]) {
3390 FFSWAP(int64_t, pts_buf[j], pts_buf[r]);
3397 st->codecpar->video_delay = FFMAX(st->codecpar->video_delay, num_swaps);
3400 if (ctts_sample == msc->ctts_data[ctts_ind].count) {
3405 av_log(c->fc, AV_LOG_DEBUG, "Setting codecpar->delay to %d for stream st: %d\n",
3406 st->codecpar->video_delay, st->index);
3410 static void mov_current_sample_inc(MOVStreamContext *sc)
3412 sc->current_sample++;
3413 sc->current_index++;
3414 if (sc->index_ranges &&
3415 sc->current_index >= sc->current_index_range->end &&
3416 sc->current_index_range->end) {
3417 sc->current_index_range++;
3418 sc->current_index = sc->current_index_range->start;
3422 static void mov_current_sample_dec(MOVStreamContext *sc)
3424 sc->current_sample--;
3425 sc->current_index--;
3426 if (sc->index_ranges &&
3427 sc->current_index < sc->current_index_range->start &&
3428 sc->current_index_range > sc->index_ranges) {
3429 sc->current_index_range--;
3430 sc->current_index = sc->current_index_range->end - 1;
3434 static void mov_current_sample_set(MOVStreamContext *sc, int current_sample)
3438 sc->current_sample = current_sample;
3439 sc->current_index = current_sample;
3440 if (!sc->index_ranges) {
3444 for (sc->current_index_range = sc->index_ranges;
3445 sc->current_index_range->end;
3446 sc->current_index_range++) {
3447 range_size = sc->current_index_range->end - sc->current_index_range->start;
3448 if (range_size > current_sample) {
3449 sc->current_index = sc->current_index_range->start + current_sample;
3452 current_sample -= range_size;
3457 * Fix st->internal->index_entries, so that it contains only the entries (and the entries
3458 * which are needed to decode them) that fall in the edit list time ranges.
3459 * Also fixes the timestamps of the index entries to match the timeline
3460 * specified the edit lists.
3462 static void mov_fix_index(MOVContext *mov, AVStream *st)
3464 MOVStreamContext *msc = st->priv_data;
3465 AVIndexEntry *e_old = st->internal->index_entries;
3466 int nb_old = st->internal->nb_index_entries;
3467 const AVIndexEntry *e_old_end = e_old + nb_old;
3468 const AVIndexEntry *current = NULL;
3469 MOVStts *ctts_data_old = msc->ctts_data;
3470 int64_t ctts_index_old = 0;
3471 int64_t ctts_sample_old = 0;
3472 int64_t ctts_count_old = msc->ctts_count;
3473 int64_t edit_list_media_time = 0;
3474 int64_t edit_list_duration = 0;
3475 int64_t frame_duration = 0;
3476 int64_t edit_list_dts_counter = 0;
3477 int64_t edit_list_dts_entry_end = 0;
3478 int64_t edit_list_start_ctts_sample = 0;
3480 int64_t curr_ctts = 0;
3481 int64_t empty_edits_sum_duration = 0;
3482 int64_t edit_list_index = 0;
3485 int64_t start_dts = 0;
3486 int64_t edit_list_start_encountered = 0;
3487 int64_t search_timestamp = 0;
3488 int64_t* frame_duration_buffer = NULL;
3489 int num_discarded_begin = 0;
3490 int first_non_zero_audio_edit = -1;
3491 int packet_skip_samples = 0;
3492 MOVIndexRange *current_index_range;
3494 int found_keyframe_after_edit = 0;
3495 int found_non_empty_edit = 0;
3497 if (!msc->elst_data || msc->elst_count <= 0 || nb_old <= 0) {
3501 // allocate the index ranges array
3502 msc->index_ranges = av_malloc((msc->elst_count + 1) * sizeof(msc->index_ranges[0]));
3503 if (!msc->index_ranges) {
3504 av_log(mov->fc, AV_LOG_ERROR, "Cannot allocate index ranges buffer\n");
3507 msc->current_index_range = msc->index_ranges;
3508 current_index_range = msc->index_ranges - 1;
3510 // Clean AVStream from traces of old index
3511 st->internal->index_entries = NULL;
3512 st->internal->index_entries_allocated_size = 0;
3513 st->internal->nb_index_entries = 0;
3515 // Clean ctts fields of MOVStreamContext
3516 msc->ctts_data = NULL;
3517 msc->ctts_count = 0;
3518 msc->ctts_index = 0;
3519 msc->ctts_sample = 0;
3520 msc->ctts_allocated_size = 0;
3522 // Reinitialize min_corrected_pts so that it can be computed again.
3523 msc->min_corrected_pts = -1;
3525 // If the dts_shift is positive (in case of negative ctts values in mov),
3526 // then negate the DTS by dts_shift
3527 if (msc->dts_shift > 0) {
3528 edit_list_dts_entry_end -= msc->dts_shift;
3529 av_log(mov->fc, AV_LOG_DEBUG, "Shifting DTS by %d because of negative CTTS.\n", msc->dts_shift);
3532 start_dts = edit_list_dts_entry_end;
3534 while (get_edit_list_entry(mov, msc, edit_list_index, &edit_list_media_time,
3535 &edit_list_duration, mov->time_scale)) {
3536 av_log(mov->fc, AV_LOG_DEBUG, "Processing st: %d, edit list %"PRId64" - media time: %"PRId64", duration: %"PRId64"\n",
3537 st->index, edit_list_index, edit_list_media_time, edit_list_duration);
3539 edit_list_dts_counter = edit_list_dts_entry_end;
3540 edit_list_dts_entry_end += edit_list_duration;
3541 num_discarded_begin = 0;
3542 if (!found_non_empty_edit && edit_list_media_time == -1) {
3543 empty_edits_sum_duration += edit_list_duration;
3546 found_non_empty_edit = 1;
3548 // If we encounter a non-negative edit list reset the skip_samples/start_pad fields and set them
3549 // according to the edit list below.
3550 if (st->codecpar->codec_type == AVMEDIA_TYPE_AUDIO) {
3551 if (first_non_zero_audio_edit < 0) {
3552 first_non_zero_audio_edit = 1;
3554 first_non_zero_audio_edit = 0;
3557 if (first_non_zero_audio_edit > 0)
3558 st->internal->skip_samples = msc->start_pad = 0;
3561 // While reordering frame index according to edit list we must handle properly
3562 // the scenario when edit list entry starts from none key frame.
3563 // We find closest previous key frame and preserve it and consequent frames in index.
3564 // All frames which are outside edit list entry time boundaries will be dropped after decoding.
3565 search_timestamp = edit_list_media_time;
3566 if (st->codecpar->codec_type == AVMEDIA_TYPE_AUDIO) {
3567 // Audio decoders like AAC need need a decoder delay samples previous to the current sample,
3568 // to correctly decode this frame. Hence for audio we seek to a frame 1 sec. before the
3569 // edit_list_media_time to cover the decoder delay.
3570 search_timestamp = FFMAX(search_timestamp - msc->time_scale, e_old[0].timestamp);
3573 if (find_prev_closest_index(st, e_old, nb_old, ctts_data_old, ctts_count_old, search_timestamp, 0,
3574 &index, &ctts_index_old, &ctts_sample_old) < 0) {
3575 av_log(mov->fc, AV_LOG_WARNING,
3576 "st: %d edit list: %"PRId64" Missing key frame while searching for timestamp: %"PRId64"\n",
3577 st->index, edit_list_index, search_timestamp);
3578 if (find_prev_closest_index(st, e_old, nb_old, ctts_data_old, ctts_count_old, search_timestamp, AVSEEK_FLAG_ANY,
3579 &index, &ctts_index_old, &ctts_sample_old) < 0) {
3580 av_log(mov->fc, AV_LOG_WARNING,
3581 "st: %d edit list %"PRId64" Cannot find an index entry before timestamp: %"PRId64".\n",
3582 st->index, edit_list_index, search_timestamp);
3585 ctts_sample_old = 0;
3588 current = e_old + index;
3589 edit_list_start_ctts_sample = ctts_sample_old;
3591 // Iterate over index and arrange it according to edit list
3592 edit_list_start_encountered = 0;
3593 found_keyframe_after_edit = 0;
3594 for (; current < e_old_end; current++, index++) {
3595 // check if frame outside edit list mark it for discard
3596 frame_duration = (current + 1 < e_old_end) ?
3597 ((current + 1)->timestamp - current->timestamp) : edit_list_duration;
3599 flags = current->flags;
3601 // frames (pts) before or after edit list
3602 curr_cts = current->timestamp + msc->dts_shift;
3605 if (ctts_data_old && ctts_index_old < ctts_count_old) {
3606 curr_ctts = ctts_data_old[ctts_index_old].duration;
3607 av_log(mov->fc, AV_LOG_DEBUG, "stts: %"PRId64" ctts: %"PRId64", ctts_index: %"PRId64", ctts_count: %"PRId64"\n",
3608 curr_cts, curr_ctts, ctts_index_old, ctts_count_old);
3609 curr_cts += curr_ctts;
3611 if (ctts_sample_old == ctts_data_old[ctts_index_old].count) {
3612 if (add_ctts_entry(&msc->ctts_data, &msc->ctts_count,
3613 &msc->ctts_allocated_size,
3614 ctts_data_old[ctts_index_old].count - edit_list_start_ctts_sample,
3615 ctts_data_old[ctts_index_old].duration) == -1) {
3616 av_log(mov->fc, AV_LOG_ERROR, "Cannot add CTTS entry %"PRId64" - {%"PRId64", %d}\n",
3618 ctts_data_old[ctts_index_old].count - edit_list_start_ctts_sample,
3619 ctts_data_old[ctts_index_old].duration);
3623 ctts_sample_old = 0;
3624 edit_list_start_ctts_sample = 0;
3628 if (curr_cts < edit_list_media_time || curr_cts >= (edit_list_duration + edit_list_media_time)) {
3629 if (st->codecpar->codec_type == AVMEDIA_TYPE_AUDIO && st->codecpar->codec_id != AV_CODEC_ID_VORBIS &&
3630 curr_cts < edit_list_media_time && curr_cts + frame_duration > edit_list_media_time &&
3631 first_non_zero_audio_edit > 0) {
3632 packet_skip_samples = edit_list_media_time - curr_cts;
3633 st->internal->skip_samples += packet_skip_samples;
3635 // Shift the index entry timestamp by packet_skip_samples to be correct.
3636 edit_list_dts_counter -= packet_skip_samples;
3637 if (edit_list_start_encountered == 0) {
3638 edit_list_start_encountered = 1;
3639 // Make timestamps strictly monotonically increasing for audio, by rewriting timestamps for
3640 // discarded packets.
3641 if (frame_duration_buffer) {
3642 fix_index_entry_timestamps(st, st->internal->nb_index_entries, edit_list_dts_counter,
3643 frame_duration_buffer, num_discarded_begin);
3644 av_freep(&frame_duration_buffer);
3648 av_log(mov->fc, AV_LOG_DEBUG, "skip %d audio samples from curr_cts: %"PRId64"\n", packet_skip_samples, curr_cts);
3650 flags |= AVINDEX_DISCARD_FRAME;
3651 av_log(mov->fc, AV_LOG_DEBUG, "drop a frame at curr_cts: %"PRId64" @ %"PRId64"\n", curr_cts, index);
3653 if (edit_list_start_encountered == 0) {
3654 num_discarded_begin++;
3655 frame_duration_buffer = av_realloc(frame_duration_buffer,
3656 num_discarded_begin * sizeof(int64_t));
3657 if (!frame_duration_buffer) {
3658 av_log(mov->fc, AV_LOG_ERROR, "Cannot reallocate frame duration buffer\n");
3661 frame_duration_buffer[num_discarded_begin - 1] = frame_duration;
3663 // Increment skip_samples for the first non-zero audio edit list
3664 if (st->codecpar->codec_type == AVMEDIA_TYPE_AUDIO &&
3665 first_non_zero_audio_edit > 0 && st->codecpar->codec_id != AV_CODEC_ID_VORBIS) {
3666 st->internal->skip_samples += frame_duration;
3671 if (msc->min_corrected_pts < 0) {
3672 msc->min_corrected_pts = edit_list_dts_counter + curr_ctts + msc->dts_shift;
3674 msc->min_corrected_pts = FFMIN(msc->min_corrected_pts, edit_list_dts_counter + curr_ctts + msc->dts_shift);
3676 if (edit_list_start_encountered == 0) {
3677 edit_list_start_encountered = 1;
3678 // Make timestamps strictly monotonically increasing by rewriting timestamps for
3679 // discarded packets.
3680 if (frame_duration_buffer) {
3681 fix_index_entry_timestamps(st, st->internal->nb_index_entries, edit_list_dts_counter,
3682 frame_duration_buffer, num_discarded_begin);
3683 av_freep(&frame_duration_buffer);
3688 if (add_index_entry(st, current->pos, edit_list_dts_counter, current->size,
3689 current->min_distance, flags) == -1) {
3690 av_log(mov->fc, AV_LOG_ERROR, "Cannot add index entry\n");
3694 // Update the index ranges array
3695 if (current_index_range < msc->index_ranges || index != current_index_range->end) {
3696 current_index_range++;
3697 current_index_range->start = index;
3699 current_index_range->end = index + 1;
3701 // Only start incrementing DTS in frame_duration amounts, when we encounter a frame in edit list.
3702 if (edit_list_start_encountered > 0) {
3703 edit_list_dts_counter = edit_list_dts_counter + frame_duration;
3706 // Break when found first key frame after edit entry completion
3707 if ((curr_cts + frame_duration >= (edit_list_duration + edit_list_media_time)) &&
3708 ((flags & AVINDEX_KEYFRAME) || ((st->codecpar->codec_type == AVMEDIA_TYPE_AUDIO)))) {
3709 if (ctts_data_old) {
3710 // If we have CTTS and this is the first keyframe after edit elist,
3711 // wait for one more, because there might be trailing B-frames after this I-frame
3712 // that do belong to the edit.
3713 if (st->codecpar->codec_type != AVMEDIA_TYPE_AUDIO && found_keyframe_after_edit == 0) {
3714 found_keyframe_after_edit = 1;
3717 if (ctts_sample_old != 0) {
3718 if (add_ctts_entry(&msc->ctts_data, &msc->ctts_count,
3719 &msc->ctts_allocated_size,
3720 ctts_sample_old - edit_list_start_ctts_sample,
3721 ctts_data_old[ctts_index_old].duration) == -1) {
3722 av_log(mov->fc, AV_LOG_ERROR, "Cannot add CTTS entry %"PRId64" - {%"PRId64", %d}\n",
3723 ctts_index_old, ctts_sample_old - edit_list_start_ctts_sample,
3724 ctts_data_old[ctts_index_old].duration);
3733 // If there are empty edits, then msc->min_corrected_pts might be positive
3734 // intentionally. So we subtract the sum duration of emtpy edits here.
3735 msc->min_corrected_pts -= empty_edits_sum_duration;
3737 // If the minimum pts turns out to be greater than zero after fixing the index, then we subtract the
3738 // dts by that amount to make the first pts zero.
3739 if (st->codecpar->codec_type == AVMEDIA_TYPE_VIDEO) {
3740 if (msc->min_corrected_pts > 0) {
3741 av_log(mov->fc, AV_LOG_DEBUG, "Offset DTS by %"PRId64" to make first pts zero.\n", msc->min_corrected_pts);
3742 for (i = 0; i < st->internal->nb_index_entries; ++i) {
3743 st->internal->index_entries[i].timestamp -= msc->min_corrected_pts;
3747 // Start time should be equal to zero or the duration of any empty edits.
3748 st->start_time = empty_edits_sum_duration;
3750 // Update av stream length, if it ends up shorter than the track's media duration
3751 st->duration = FFMIN(st->duration, edit_list_dts_entry_end - start_dts);
3752 msc->start_pad = st->internal->skip_samples;
3754 // Free the old index and the old CTTS structures
3756 av_free(ctts_data_old);
3757 av_freep(&frame_duration_buffer);
3759 // Null terminate the index ranges array
3760 current_index_range++;
3761 current_index_range->start = 0;
3762 current_index_range->end = 0;
3763 msc->current_index = msc->index_ranges[0].start;
3766 static void mov_build_index(MOVContext *mov, AVStream *st)
3768 MOVStreamContext *sc = st->priv_data;
3769 int64_t current_offset;
3770 int64_t current_dts = 0;
3771 unsigned int stts_index = 0;
3772 unsigned int stsc_index = 0;
3773 unsigned int stss_index = 0;
3774 unsigned int stps_index = 0;
3776 uint64_t stream_size = 0;
3777 MOVStts *ctts_data_old = sc->ctts_data;
3778 unsigned int ctts_count_old = sc->ctts_count;
3780 if (sc->elst_count) {
3781 int i, edit_start_index = 0, multiple_edits = 0;
3782 int64_t empty_duration = 0; // empty duration of the first edit list entry
3783 int64_t start_time = 0; // start time of the media
3785 for (i = 0; i < sc->elst_count; i++) {
3786 const MOVElst *e = &sc->elst_data[i];
3787 if (i == 0 && e->time == -1) {
3788 /* if empty, the first entry is the start time of the stream
3789 * relative to the presentation itself */
3790 empty_duration = e->duration;
3791 edit_start_index = 1;
3792 } else if (i == edit_start_index && e->time >= 0) {
3793 start_time = e->time;
3799 if (multiple_edits && !mov->advanced_editlist)
3800 av_log(mov->fc, AV_LOG_WARNING, "multiple edit list entries, "
3801 "Use -advanced_editlist to correctly decode otherwise "
3802 "a/v desync might occur\n");
3804 /* adjust first dts according to edit list */
3805 if ((empty_duration || start_time) && mov->time_scale > 0) {
3807 empty_duration = av_rescale(empty_duration, sc->time_scale, mov->time_scale);
3808 sc->time_offset = start_time - empty_duration;
3809 sc->min_corrected_pts = start_time;
3810 if (!mov->advanced_editlist)
3811 current_dts = -sc->time_offset;
3814 if (!multiple_edits && !mov->advanced_editlist &&
3815 st->codecpar->codec_id == AV_CODEC_ID_AAC && start_time > 0)
3816 sc->start_pad = start_time;
3819 /* only use old uncompressed audio chunk demuxing when stts specifies it */
3820 if (!(st->codecpar->codec_type == AVMEDIA_TYPE_AUDIO &&
3821 sc->stts_count == 1 && sc->stts_data[0].duration == 1)) {
3822 unsigned int current_sample = 0;
3823 unsigned int stts_sample = 0;
3824 unsigned int sample_size;
3825 unsigned int distance = 0;
3826 unsigned int rap_group_index = 0;
3827 unsigned int rap_group_sample = 0;
3828 int64_t last_dts = 0;
3829 int64_t dts_correction = 0;
3830 int rap_group_present = sc->rap_group_count && sc->rap_group;
3831 int key_off = (sc->keyframe_count && sc->keyframes[0] > 0) || (sc->stps_count && sc->stps_data[0] > 0);
3833 current_dts -= sc->dts_shift;
3834 last_dts = current_dts;
3836 if (!sc->sample_count || st->internal->nb_index_entries)
3838 if (sc->sample_count >= UINT_MAX / sizeof(*st->internal->index_entries) - st->internal->nb_index_entries)
3840 if (av_reallocp_array(&st->internal->index_entries,
3841 st->internal->nb_index_entries + sc->sample_count,
3842 sizeof(*st->internal->index_entries)) < 0) {
3843 st->internal->nb_index_entries = 0;
3846 st->internal->index_entries_allocated_size = (st->internal->nb_index_entries + sc->sample_count) * sizeof(*st->internal->index_entries);
3848 if (ctts_data_old) {
3849 // Expand ctts entries such that we have a 1-1 mapping with samples
3850 if (sc->sample_count >= UINT_MAX / sizeof(*sc->ctts_data))
3853 sc->ctts_allocated_size = 0;
3854 sc->ctts_data = av_fast_realloc(NULL, &sc->ctts_allocated_size,
3855 sc->sample_count * sizeof(*sc->ctts_data));
3856 if (!sc->ctts_data) {
3857 av_free(ctts_data_old);
3861 memset((uint8_t*)(sc->ctts_data), 0, sc->ctts_allocated_size);
3863 for (i = 0; i < ctts_count_old &&
3864 sc->ctts_count < sc->sample_count; i++)
3865 for (j = 0; j < ctts_data_old[i].count &&
3866 sc->ctts_count < sc->sample_count; j++)
3867 add_ctts_entry(&sc->ctts_data, &sc->ctts_count,
3868 &sc->ctts_allocated_size, 1,
3869 ctts_data_old[i].duration);
3870 av_free(ctts_data_old);
3873 for (i = 0; i < sc->chunk_count; i++) {
3874 int64_t next_offset = i+1 < sc->chunk_count ? sc->chunk_offsets[i+1] : INT64_MAX;
3875 current_offset = sc->chunk_offsets[i];
3876 while (mov_stsc_index_valid(stsc_index, sc->stsc_count) &&
3877 i + 1 == sc->stsc_data[stsc_index + 1].first)
3880 if (next_offset > current_offset && sc->sample_size>0 && sc->sample_size < sc->stsz_sample_size &&
3881 sc->stsc_data[stsc_index].count * (int64_t)sc->stsz_sample_size > next_offset - current_offset) {
3882 av_log(mov->fc, AV_LOG_WARNING, "STSZ sample size %d invalid (too large), ignoring\n", sc->stsz_sample_size);
3883 sc->stsz_sample_size = sc->sample_size;
3885 if (sc->stsz_sample_size>0 && sc->stsz_sample_size < sc->sample_size) {
3886 av_log(mov->fc, AV_LOG_WARNING, "STSZ sample size %d invalid (too small), ignoring\n", sc->stsz_sample_size);
3887 sc->stsz_sample_size = sc->sample_size;
3890 for (j = 0; j < sc->stsc_data[stsc_index].count; j++) {
3892 if (current_sample >= sc->sample_count) {
3893 av_log(mov->fc, AV_LOG_ERROR, "wrong sample count\n");
3897 if (!sc->keyframe_absent && (!sc->keyframe_count || current_sample+key_off == sc->keyframes[stss_index])) {
3899 if (stss_index + 1 < sc->keyframe_count)
3901 } else if (sc->stps_count && current_sample+key_off == sc->stps_data[stps_index]) {
3903 if (stps_index + 1 < sc->stps_count)
3906 if (rap_group_present && rap_group_index < sc->rap_group_count) {
3907 if (sc->rap_group[rap_group_index].index > 0)
3909 if (++rap_group_sample == sc->rap_group[rap_group_index].count) {
3910 rap_group_sample = 0;
3914 if (sc->keyframe_absent
3916 && !rap_group_present
3917 && (st->codecpar->codec_type == AVMEDIA_TYPE_AUDIO || (i==0 && j==0)))
3921 sample_size = sc->stsz_sample_size > 0 ? sc->stsz_sample_size : sc->sample_sizes[current_sample];
3922 if (sc->pseudo_stream_id == -1 ||
3923 sc->stsc_data[stsc_index].id - 1 == sc->pseudo_stream_id) {
3925 if (sample_size > 0x3FFFFFFF) {
3926 av_log(mov->fc, AV_LOG_ERROR, "Sample size %u is too large\n", sample_size);
3929 e = &st->internal->index_entries[st->internal->nb_index_entries++];
3930 e->pos = current_offset;
3931 e->timestamp = current_dts;
3932 e->size = sample_size;
3933 e->min_distance = distance;
3934 e->flags = keyframe ? AVINDEX_KEYFRAME : 0;
3935 av_log(mov->fc, AV_LOG_TRACE, "AVIndex stream %d, sample %u, offset %"PRIx64", dts %"PRId64", "
3936 "size %u, distance %u, keyframe %d\n", st->index, current_sample,
3937 current_offset, current_dts, sample_size, distance, keyframe);
3938 if (st->codecpar->codec_type == AVMEDIA_TYPE_VIDEO && st->internal->nb_index_entries < 100)
3939 ff_rfps_add_frame(mov->fc, st, current_dts);
3942 current_offset += sample_size;
3943 stream_size += sample_size;
3945 /* A negative sample duration is invalid based on the spec,
3946 * but some samples need it to correct the DTS. */
3947 if (sc->stts_data[stts_index].duration < 0) {
3948 av_log(mov->fc, AV_LOG_WARNING,
3949 "Invalid SampleDelta %d in STTS, at %d st:%d\n",
3950 sc->stts_data[stts_index].duration, stts_index,
3952 dts_correction += sc->stts_data[stts_index].duration - 1;
3953 sc->stts_data[stts_index].duration = 1;
3955 current_dts += sc->stts_data[stts_index].duration;
3956 if (!dts_correction || current_dts + dts_correction > last_dts) {
3957 current_dts += dts_correction;
3960 /* Avoid creating non-monotonous DTS */
3961 dts_correction += current_dts - last_dts - 1;
3962 current_dts = last_dts + 1;
3964 last_dts = current_dts;
3968 if (stts_index + 1 < sc->stts_count && stts_sample == sc->stts_data[stts_index].count) {
3974 if (st->duration > 0)
3975 st->codecpar->bit_rate = stream_size*8*sc->time_scale/st->duration;
3977 unsigned chunk_samples, total = 0;
3979 if (!sc->chunk_count)
3982 // compute total chunk count
3983 for (i = 0; i < sc->stsc_count; i++) {
3984 unsigned count, chunk_count;
3986 chunk_samples = sc->stsc_data[i].count;
3987 if (i != sc->stsc_count - 1 &&
3988 sc->samples_per_frame && chunk_samples % sc->samples_per_frame) {
3989 av_log(mov->fc, AV_LOG_ERROR, "error unaligned chunk\n");
3993 if (sc->samples_per_frame >= 160) { // gsm
3994 count = chunk_samples / sc->samples_per_frame;
3995 } else if (sc->samples_per_frame > 1) {
3996 unsigned samples = (1024/sc->samples_per_frame)*sc->samples_per_frame;
3997 count = (chunk_samples+samples-1) / samples;
3999 count = (chunk_samples+1023) / 1024;
4002 if (mov_stsc_index_valid(i, sc->stsc_count))
4003 chunk_count = sc->stsc_data[i+1].first - sc->stsc_data[i].first;
4005 chunk_count = sc->chunk_count - (sc->stsc_data[i].first - 1);
4006 total += chunk_count * count;
4009 av_log(mov->fc, AV_LOG_TRACE, "chunk count %u\n", total);
4010 if (total >= UINT_MAX / sizeof(*st->internal->index_entries) - st->internal->nb_index_entries)
4012 if (av_reallocp_array(&st->internal->index_entries,
4013 st->internal->nb_index_entries + total,
4014 sizeof(*st->internal->index_entries)) < 0) {
4015 st->internal->nb_index_entries = 0;
4018 st->internal->index_entries_allocated_size = (st->internal->nb_index_entries + total) * sizeof(*st->internal->index_entries);
4021 for (i = 0; i < sc->chunk_count; i++) {
4022 current_offset = sc->chunk_offsets[i];
4023 if (mov_stsc_index_valid(stsc_index, sc->stsc_count) &&
4024 i + 1 == sc->stsc_data[stsc_index + 1].first)
4026 chunk_samples = sc->stsc_data[stsc_index].count;
4028 while (chunk_samples > 0) {
4030 unsigned size, samples;
4032 if (sc->samples_per_frame > 1 && !sc->bytes_per_frame) {
4033 avpriv_request_sample(mov->fc,
4034 "Zero bytes per frame, but %d samples per frame",
4035 sc->samples_per_frame);
4039 if (sc->samples_per_frame >= 160) { // gsm
4040 samples = sc->samples_per_frame;
4041 size = sc->bytes_per_frame;
4043 if (sc->samples_per_frame > 1) {
4044 samples = FFMIN((1024 / sc->samples_per_frame)*
4045 sc->samples_per_frame, chunk_samples);
4046 size = (samples / sc->samples_per_frame) * sc->bytes_per_frame;
4048 samples = FFMIN(1024, chunk_samples);
4049 size = samples * sc->sample_size;
4053 if (st->internal->nb_index_entries >= total) {
4054 av_log(mov->fc, AV_LOG_ERROR, "wrong chunk count %u\n", total);
4057 if (size > 0x3FFFFFFF) {
4058 av_log(mov->fc, AV_LOG_ERROR, "Sample size %u is too large\n", size);
4061 e = &st->internal->index_entries[st->internal->nb_index_entries++];
4062 e->pos = current_offset;
4063 e->timestamp = current_dts;
4065 e->min_distance = 0;
4066 e->flags = AVINDEX_KEYFRAME;
4067 av_log(mov->fc, AV_LOG_TRACE, "AVIndex stream %d, chunk %u, offset %"PRIx64", dts %"PRId64", "
4068 "size %u, duration %u\n", st->index, i, current_offset, current_dts,
4071 current_offset += size;
4072 current_dts += samples;
4073 chunk_samples -= samples;
4078 if (!mov->ignore_editlist && mov->advanced_editlist) {
4079 // Fix index according to edit lists.
4080 mov_fix_index(mov, st);
4083 // Update start time of the stream.
4084 if (st->start_time == AV_NOPTS_VALUE && st->codecpar->codec_type == AVMEDIA_TYPE_VIDEO && st->internal->nb_index_entries > 0) {
4085 st->start_time = st->internal->index_entries[0].timestamp + sc->dts_shift;
4086 if (sc->ctts_data) {
4087 st->start_time += sc->ctts_data[0].duration;
4091 mov_estimate_video_delay(mov, st);
4094 static int test_same_origin(const char *src, const char *ref) {
4104 av_url_split(src_proto, sizeof(src_proto), src_auth, sizeof(src_auth), src_host, sizeof(src_host), &src_port, NULL, 0, src);
4105 av_url_split(ref_proto, sizeof(ref_proto), ref_auth, sizeof(ref_auth), ref_host, sizeof(ref_host), &ref_port, NULL, 0, ref);
4107 if (strlen(src) == 0) {
4109 } else if (strlen(src_auth) + 1 >= sizeof(src_auth) ||
4110 strlen(ref_auth) + 1 >= sizeof(ref_auth) ||
4111 strlen(src_host) + 1 >= sizeof(src_host) ||
4112 strlen(ref_host) + 1 >= sizeof(ref_host)) {
4114 } else if (strcmp(src_proto, ref_proto) ||
4115 strcmp(src_auth, ref_auth) ||
4116 strcmp(src_host, ref_host) ||
4117 src_port != ref_port) {
4123 static int mov_open_dref(MOVContext *c, AVIOContext **pb, const char *src, MOVDref *ref)
4125 /* try relative path, we do not try the absolute because it can leak information about our
4126 system to an attacker */
4127 if (ref->nlvl_to > 0 && ref->nlvl_from > 0) {
4128 char filename[1025];
4129 const char *src_path;
4132 /* find a source dir */
4133 src_path = strrchr(src, '/');
4139 /* find a next level down to target */
4140 for (i = 0, l = strlen(ref->path) - 1; l >= 0; l--)
4141 if (ref->path[l] == '/') {
4142 if (i == ref->nlvl_to - 1)
4148 /* compose filename if next level down to target was found */
4149 if (i == ref->nlvl_to - 1 && src_path - src < sizeof(filename)) {
4150 memcpy(filename, src, src_path - src);
4151 filename[src_path - src] = 0;
4153 for (i = 1; i < ref->nlvl_from; i++)
4154 av_strlcat(filename, "../", sizeof(filename));
4156 av_strlcat(filename, ref->path + l + 1, sizeof(filename));
4157 if (!c->use_absolute_path) {
4158 int same_origin = test_same_origin(src, filename);
4161 av_log(c->fc, AV_LOG_ERROR,
4162 "Reference with mismatching origin, %s not tried for security reasons, "
4163 "set demuxer option use_absolute_path to allow it anyway\n",
4165 return AVERROR(ENOENT);
4168 if (strstr(ref->path + l + 1, "..") ||
4169 strstr(ref->path + l + 1, ":") ||
4170 (ref->nlvl_from > 1 && same_origin < 0) ||
4171 (filename[0] == '/' && src_path == src))
4172 return AVERROR(ENOENT);
4175 if (strlen(filename) + 1 == sizeof(filename))
4176 return AVERROR(ENOENT);
4177 if (!c->fc->io_open(c->fc, pb, filename, AVIO_FLAG_READ, NULL))
4180 } else if (c->use_absolute_path) {
4181 av_log(c->fc, AV_LOG_WARNING, "Using absolute path on user request, "
4182 "this is a possible security issue\n");
4183 if (!c->fc->io_open(c->fc, pb, ref->path, AVIO_FLAG_READ, NULL))
4186 av_log(c->fc, AV_LOG_ERROR,
4187 "Absolute path %s not tried for security reasons, "
4188 "set demuxer option use_absolute_path to allow absolute paths\n",
4192 return AVERROR(ENOENT);
4195 static void fix_timescale(MOVContext *c, MOVStreamContext *sc)
4197 if (sc->time_scale <= 0) {
4198 av_log(c->fc, AV_LOG_WARNING, "stream %d, timescale not set\n", sc->ffindex);
4199 sc->time_scale = c->time_scale;
4200 if (sc->time_scale <= 0)
4205 static int mov_read_trak(MOVContext *c, AVIOContext *pb, MOVAtom atom)
4208 MOVStreamContext *sc;
4211 st = avformat_new_stream(c->fc, NULL);
4212 if (!st) return AVERROR(ENOMEM);
4214 sc = av_mallocz(sizeof(MOVStreamContext));
4215 if (!sc) return AVERROR(ENOMEM);
4218 st->codecpar->codec_type = AVMEDIA_TYPE_DATA;
4219 sc->ffindex = st->index;
4220 c->trak_index = st->index;
4222 if ((ret = mov_read_default(c, pb, atom)) < 0)
4227 // Here stsc refers to a chunk not described in stco. This is technically invalid,
4228 // but we can overlook it (clearing stsc) whenever stts_count == 0 (indicating no samples).
4229 if (!sc->chunk_count && !sc->stts_count && sc->stsc_count) {
4231 av_freep(&sc->stsc_data);
4235 if ((sc->chunk_count && (!sc->stts_count || !sc->stsc_count ||
4236 (!sc->sample_size && !sc->sample_count))) ||
4237 (!sc->chunk_count && sc->sample_count)) {
4238 av_log(c->fc, AV_LOG_ERROR, "stream %d, missing mandatory atoms, broken header\n",
4242 if (sc->stsc_count && sc->stsc_data[ sc->stsc_count - 1 ].first > sc->chunk_count) {
4243 av_log(c->fc, AV_LOG_ERROR, "stream %d, contradictionary STSC and STCO\n",
4245 return AVERROR_INVALIDDATA;
4248 fix_timescale(c, sc);
4250 avpriv_set_pts_info(st, 64, 1, sc->time_scale);
4252 mov_build_index(c, st);
4254 if (sc->dref_id-1 < sc->drefs_count && sc->drefs[sc->dref_id-1].path) {
4255 MOVDref *dref = &sc->drefs[sc->dref_id - 1];
4256 if (c->enable_drefs) {
4257 if (mov_open_dref(c, &sc->pb, c->fc->url, dref) < 0)
4258 av_log(c->fc, AV_LOG_ERROR,
4259 "stream %d, error opening alias: path='%s', dir='%s', "
4260 "filename='%s', volume='%s', nlvl_from=%d, nlvl_to=%d\n",
4261 st->index, dref->path, dref->dir, dref->filename,
4262 dref->volume, dref->nlvl_from, dref->nlvl_to);
4264 av_log(c->fc, AV_LOG_WARNING,
4265 "Skipped opening external track: "
4266 "stream %d, alias: path='%s', dir='%s', "
4267 "filename='%s', volume='%s', nlvl_from=%d, nlvl_to=%d."
4268 "Set enable_drefs to allow this.\n",
4269 st->index, dref->path, dref->dir, dref->filename,
4270 dref->volume, dref->nlvl_from, dref->nlvl_to);
4274 sc->pb_is_copied = 1;
4277 if (st->codecpar->codec_type == AVMEDIA_TYPE_VIDEO) {
4278 if (!st->sample_aspect_ratio.num && st->codecpar->width && st->codecpar->height &&
4279 sc->height && sc->width &&
4280 (st->codecpar->width != sc->width || st->codecpar->height != sc->height)) {
4281 st->sample_aspect_ratio = av_d2q(((double)st->codecpar->height * sc->width) /
4282 ((double)st->codecpar->width * sc->height), INT_MAX);
4285 #if FF_API_R_FRAME_RATE
4286 if (sc->stts_count == 1 || (sc->stts_count == 2 && sc->stts_data[1].count == 1))
4287 av_reduce(&st->r_frame_rate.num, &st->r_frame_rate.den,
4288 sc->time_scale, sc->stts_data[0].duration, INT_MAX);
4292 // done for ai5q, ai52, ai55, ai1q, ai12 and ai15.
4293 if (!st->codecpar->extradata_size && st->codecpar->codec_id == AV_CODEC_ID_H264 &&
4294 TAG_IS_AVCI(st->codecpar->codec_tag)) {
4295 ret = ff_generate_avci_extradata(st);
4300 switch (st->codecpar->codec_id) {
4301 #if CONFIG_H261_DECODER
4302 case AV_CODEC_ID_H261:
4304 #if CONFIG_H263_DECODER
4305 case AV_CODEC_ID_H263:
4307 #if CONFIG_MPEG4_DECODER
4308 case AV_CODEC_ID_MPEG4:
4310 st->codecpar->width = 0; /* let decoder init width/height */
4311 st->codecpar->height= 0;
4315 // If the duration of the mp3 packets is not constant, then they could need a parser
4316 if (st->codecpar->codec_id == AV_CODEC_ID_MP3
4317 && sc->stts_count > 3
4318 && sc->stts_count*10 > st->nb_frames
4319 && sc->time_scale == st->codecpar->sample_rate) {
4320 st->need_parsing = AVSTREAM_PARSE_FULL;
4322 /* Do not need those anymore. */
4323 av_freep(&sc->chunk_offsets);
4324 av_freep(&sc->sample_sizes);
4325 av_freep(&sc->keyframes);
4326 av_freep(&sc->stts_data);
4327 av_freep(&sc->stps_data);
4328 av_freep(&sc->elst_data);
4329 av_freep(&sc->rap_group);
4334 static int mov_read_ilst(MOVContext *c, AVIOContext *pb, MOVAtom atom)
4337 c->itunes_metadata = 1;
4338 ret = mov_read_default(c, pb, atom);
4339 c->itunes_metadata = 0;
4343 static int mov_read_keys(MOVContext *c, AVIOContext *pb, MOVAtom atom)
4352 count = avio_rb32(pb);
4353 if (count > UINT_MAX / sizeof(*c->meta_keys) - 1) {
4354 av_log(c->fc, AV_LOG_ERROR,
4355 "The 'keys' atom with the invalid key count: %"PRIu32"\n", count);
4356 return AVERROR_INVALIDDATA;
4359 c->meta_keys_count = count + 1;
4360 c->meta_keys = av_mallocz(c->meta_keys_count * sizeof(*c->meta_keys));
4362 return AVERROR(ENOMEM);
4364 for (i = 1; i <= count; ++i) {
4365 uint32_t key_size = avio_rb32(pb);
4366 uint32_t type = avio_rl32(pb);
4368 av_log(c->fc, AV_LOG_ERROR,
4369 "The key# %"PRIu32" in meta has invalid size:"
4370 "%"PRIu32"\n", i, key_size);
4371 return AVERROR_INVALIDDATA;
4374 if (type != MKTAG('m','d','t','a')) {
4375 avio_skip(pb, key_size);
4377 c->meta_keys[i] = av_mallocz(key_size + 1);
4378 if (!c->meta_keys[i])
4379 return AVERROR(ENOMEM);
4380 avio_read(pb, c->meta_keys[i], key_size);
4386 static int mov_read_custom(MOVContext *c, AVIOContext *pb, MOVAtom atom)
4388 int64_t end = av_sat_add64(avio_tell(pb), atom.size);
4389 uint8_t *key = NULL, *val = NULL, *mean = NULL;
4393 MOVStreamContext *sc;
4395 if (c->fc->nb_streams < 1)
4397 st = c->fc->streams[c->fc->nb_streams-1];
4400 for (i = 0; i < 3; i++) {
4404 if (end - avio_tell(pb) <= 12)
4407 len = avio_rb32(pb);
4408 tag = avio_rl32(pb);
4409 avio_skip(pb, 4); // flags
4411 if (len < 12 || len - 12 > end - avio_tell(pb))
4415 if (tag == MKTAG('m', 'e', 'a', 'n'))
4417 else if (tag == MKTAG('n', 'a', 'm', 'e'))
4419 else if (tag == MKTAG('d', 'a', 't', 'a') && len > 4) {
4429 *p = av_malloc(len + 1);
4431 ret = AVERROR(ENOMEM);
4434 ret = ffio_read_size(pb, *p, len);
4442 if (mean && key && val) {
4443 if (strcmp(key, "iTunSMPB") == 0) {
4444 int priming, remainder, samples;
4445 if(sscanf(val, "%*X %X %X %X", &priming, &remainder, &samples) == 3){
4446 if(priming>0 && priming<16384)
4447 sc->start_pad = priming;
4450 if (strcmp(key, "cdec") != 0) {
4451 av_dict_set(&c->fc->metadata, key, val,
4452 AV_DICT_DONT_STRDUP_KEY | AV_DICT_DONT_STRDUP_VAL);
4456 av_log(c->fc, AV_LOG_VERBOSE,
4457 "Unhandled or malformed custom metadata of size %"PRId64"\n", atom.size);
4460 avio_seek(pb, end, SEEK_SET);
4467 static int mov_read_meta(MOVContext *c, AVIOContext *pb, MOVAtom atom)
4469 while (atom.size > 8) {
4473 tag = avio_rl32(pb);
4475 if (tag == MKTAG('h','d','l','r')) {
4476 avio_seek(pb, -8, SEEK_CUR);
4478 return mov_read_default(c, pb, atom);
4484 // return 1 when matrix is identity, 0 otherwise
4485 #define IS_MATRIX_IDENT(matrix) \
4486 ( (matrix)[0][0] == (1 << 16) && \
4487 (matrix)[1][1] == (1 << 16) && \
4488 (matrix)[2][2] == (1 << 30) && \
4489 !(matrix)[0][1] && !(matrix)[0][2] && \
4490 !(matrix)[1][0] && !(matrix)[1][2] && \
4491 !(matrix)[2][0] && !(matrix)[2][1])
4493 static int mov_read_tkhd(MOVContext *c, AVIOContext *pb, MOVAtom atom)
4498 int display_matrix[3][3];
4499 int res_display_matrix[3][3] = { { 0 } };
4501 MOVStreamContext *sc;
4505 if (c->fc->nb_streams < 1)
4507 st = c->fc->streams[c->fc->nb_streams-1];
4510 // Each stream (trak) should have exactly 1 tkhd. This catches bad files and
4511 // avoids corrupting AVStreams mapped to an earlier tkhd.
4513 return AVERROR_INVALIDDATA;
4515 version = avio_r8(pb);
4516 flags = avio_rb24(pb);
4517 st->disposition |= (flags & MOV_TKHD_FLAG_ENABLED) ? AV_DISPOSITION_DEFAULT : 0;
4523 avio_rb32(pb); /* creation time */
4524 avio_rb32(pb); /* modification time */
4526 st->id = (int)avio_rb32(pb); /* track id (NOT 0 !)*/
4527 avio_rb32(pb); /* reserved */
4529 /* highlevel (considering edits) duration in movie timebase */
4530 (version == 1) ? avio_rb64(pb) : avio_rb32(pb);
4531 avio_rb32(pb); /* reserved */
4532 avio_rb32(pb); /* reserved */
4534 avio_rb16(pb); /* layer */
4535 avio_rb16(pb); /* alternate group */
4536 avio_rb16(pb); /* volume */
4537 avio_rb16(pb); /* reserved */
4539 //read in the display matrix (outlined in ISO 14496-12, Section 6.2.2)
4540 // they're kept in fixed point format through all calculations
4541 // save u,v,z to store the whole matrix in the AV_PKT_DATA_DISPLAYMATRIX
4542 // side data, but the scale factor is not needed to calculate aspect ratio
4543 for (i = 0; i < 3; i++) {
4544 display_matrix[i][0] = avio_rb32(pb); // 16.16 fixed point
4545 display_matrix[i][1] = avio_rb32(pb); // 16.16 fixed point
4546 display_matrix[i][2] = avio_rb32(pb); // 2.30 fixed point
4549 width = avio_rb32(pb); // 16.16 fixed point track width
4550 height = avio_rb32(pb); // 16.16 fixed point track height
4551 sc->width = width >> 16;
4552 sc->height = height >> 16;
4554 // apply the moov display matrix (after the tkhd one)
4555 for (i = 0; i < 3; i++) {
4556 const int sh[3] = { 16, 16, 30 };
4557 for (j = 0; j < 3; j++) {
4558 for (e = 0; e < 3; e++) {
4559 res_display_matrix[i][j] +=
4560 ((int64_t) display_matrix[i][e] *
4561 c->movie_display_matrix[e][j]) >> sh[e];
4566 // save the matrix when it is not the default identity
4567 if (!IS_MATRIX_IDENT(res_display_matrix)) {
4568 av_freep(&sc->display_matrix);
4569 sc->display_matrix = av_malloc(sizeof(int32_t) * 9);
4570 if (!sc->display_matrix)
4571 return AVERROR(ENOMEM);
4573 for (i = 0; i < 3; i++)
4574 for (j = 0; j < 3; j++)
4575 sc->display_matrix[i * 3 + j] = res_display_matrix[i][j];
4578 // transform the display width/height according to the matrix
4579 // to keep the same scale, use [width height 1<<16]
4580 if (width && height && sc->display_matrix) {
4581 double disp_transform[2];
4583 for (i = 0; i < 2; i++)
4584 disp_transform[i] = hypot(sc->display_matrix[0 + i],
4585 sc->display_matrix[3 + i]);
4587 if (disp_transform[0] > 1 && disp_transform[1] > 1 &&
4588 disp_transform[0] < (1<<24) && disp_transform[1] < (1<<24) &&
4589 fabs((disp_transform[0] / disp_transform[1]) - 1.0) > 0.01)
4590 st->sample_aspect_ratio = av_d2q(
4591 disp_transform[0] / disp_transform[1],
4597 static int mov_read_tfhd(MOVContext *c, AVIOContext *pb, MOVAtom atom)
4599 MOVFragment *frag = &c->fragment;
4600 MOVTrackExt *trex = NULL;
4601 int flags, track_id, i;
4602 MOVFragmentStreamInfo * frag_stream_info;
4604 avio_r8(pb); /* version */
4605 flags = avio_rb24(pb);
4607 track_id = avio_rb32(pb);
4609 return AVERROR_INVALIDDATA;
4610 for (i = 0; i < c->trex_count; i++)
4611 if (c->trex_data[i].track_id == track_id) {
4612 trex = &c->trex_data[i];
4616 av_log(c->fc, AV_LOG_WARNING, "could not find corresponding trex (id %u)\n", track_id);
4619 c->fragment.found_tfhd = 1;
4620 frag->track_id = track_id;
4621 set_frag_stream(&c->frag_index, track_id);
4623 frag->base_data_offset = flags & MOV_TFHD_BASE_DATA_OFFSET ?
4624 avio_rb64(pb) : flags & MOV_TFHD_DEFAULT_BASE_IS_MOOF ?
4625 frag->moof_offset : frag->implicit_offset;
4626 frag->stsd_id = flags & MOV_TFHD_STSD_ID ? avio_rb32(pb) : trex->stsd_id;
4628 frag->duration = flags & MOV_TFHD_DEFAULT_DURATION ?
4629 avio_rb32(pb) : trex->duration;
4630 frag->size = flags & MOV_TFHD_DEFAULT_SIZE ?
4631 avio_rb32(pb) : trex->size;
4632 frag->flags = flags & MOV_TFHD_DEFAULT_FLAGS ?
4633 avio_rb32(pb) : trex->flags;
4634 av_log(c->fc, AV_LOG_TRACE, "frag flags 0x%x\n", frag->flags);
4636 frag_stream_info = get_current_frag_stream_info(&c->frag_index);
4637 if (frag_stream_info)
4638 frag_stream_info->next_trun_dts = AV_NOPTS_VALUE;
4643 static int mov_read_chap(MOVContext *c, AVIOContext *pb, MOVAtom atom)
4648 num = atom.size / 4;
4649 if (!(new_tracks = av_malloc_array(num, sizeof(int))))
4650 return AVERROR(ENOMEM);
4652 av_free(c->chapter_tracks);
4653 c->chapter_tracks = new_tracks;
4654 c->nb_chapter_tracks = num;
4656 for (i = 0; i < num && !pb->eof_reached; i++)
4657 c->chapter_tracks[i] = avio_rb32(pb);
4662 static int mov_read_trex(MOVContext *c, AVIOContext *pb, MOVAtom atom)
4667 if ((uint64_t)c->trex_count+1 >= UINT_MAX / sizeof(*c->trex_data))
4668 return AVERROR_INVALIDDATA;
4669 if ((err = av_reallocp_array(&c->trex_data, c->trex_count + 1,
4670 sizeof(*c->trex_data))) < 0) {
4675 c->fc->duration = AV_NOPTS_VALUE; // the duration from mvhd is not representing the whole file when fragments are used.
4677 trex = &c->trex_data[c->trex_count++];
4678 avio_r8(pb); /* version */
4679 avio_rb24(pb); /* flags */
4680 trex->track_id = avio_rb32(pb);
4681 trex->stsd_id = avio_rb32(pb);
4682 trex->duration = avio_rb32(pb);
4683 trex->size = avio_rb32(pb);
4684 trex->flags = avio_rb32(pb);
4688 static int mov_read_tfdt(MOVContext *c, AVIOContext *pb, MOVAtom atom)
4690 MOVFragment *frag = &c->fragment;
4691 AVStream *st = NULL;
4692 MOVStreamContext *sc;
4694 MOVFragmentStreamInfo * frag_stream_info;
4695 int64_t base_media_decode_time;
4697 for (i = 0; i < c->fc->nb_streams; i++) {
4698 if (c->fc->streams[i]->id == frag->track_id) {
4699 st = c->fc->streams[i];
4704 av_log(c->fc, AV_LOG_WARNING, "could not find corresponding track id %u\n", frag->track_id);
4708 if (sc->pseudo_stream_id + 1 != frag->stsd_id && sc->pseudo_stream_id != -1)
4710 version = avio_r8(pb);
4711 avio_rb24(pb); /* flags */
4713 base_media_decode_time = avio_rb64(pb);
4715 base_media_decode_time = avio_rb32(pb);
4718 frag_stream_info = get_current_frag_stream_info(&c->frag_index);
4719 if (frag_stream_info)
4720 frag_stream_info->tfdt_dts = base_media_decode_time;
4721 sc->track_end = base_media_decode_time;
4726 static int mov_read_trun(MOVContext *c, AVIOContext *pb, MOVAtom atom)
4728 MOVFragment *frag = &c->fragment;
4729 AVStream *st = NULL;
4730 MOVStreamContext *sc;
4733 int64_t dts, pts = AV_NOPTS_VALUE;
4734 int data_offset = 0;
4735 unsigned entries, first_sample_flags = frag->flags;
4736 int flags, distance, i;
4737 int64_t prev_dts = AV_NOPTS_VALUE;
4738 int next_frag_index = -1, index_entry_pos;
4739 size_t requested_size;
4740 size_t old_ctts_allocated_size;
4741 AVIndexEntry *new_entries;
4742 MOVFragmentStreamInfo * frag_stream_info;
4744 if (!frag->found_tfhd) {
4745 av_log(c->fc, AV_LOG_ERROR, "trun track id unknown, no tfhd was found\n");
4746 return AVERROR_INVALIDDATA;
4749 for (i = 0; i < c->fc->nb_streams; i++) {
4750 if (c->fc->streams[i]->id == frag->track_id) {
4751 st = c->fc->streams[i];
4756 av_log(c->fc, AV_LOG_WARNING, "could not find corresponding track id %u\n", frag->track_id);
4760 if (sc->pseudo_stream_id+1 != frag->stsd_id && sc->pseudo_stream_id != -1)
4763 // Find the next frag_index index that has a valid index_entry for
4764 // the current track_id.
4766 // A valid index_entry means the trun for the fragment was read
4767 // and it's samples are in index_entries at the given position.
4768 // New index entries will be inserted before the index_entry found.
4769 index_entry_pos = st->internal->nb_index_entries;
4770 for (i = c->frag_index.current + 1; i < c->frag_index.nb_items; i++) {
4771 frag_stream_info = get_frag_stream_info(&c->frag_index, i, frag->track_id);
4772 if (frag_stream_info && frag_stream_info->index_entry >= 0) {
4773 next_frag_index = i;
4774 index_entry_pos = frag_stream_info->index_entry;
4778 av_assert0(index_entry_pos <= st->internal->nb_index_entries);
4780 avio_r8(pb); /* version */
4781 flags = avio_rb24(pb);
4782 entries = avio_rb32(pb);
4783 av_log(c->fc, AV_LOG_TRACE, "flags 0x%x entries %u\n", flags, entries);
4785 if ((uint64_t)entries+sc->ctts_count >= UINT_MAX/sizeof(*sc->ctts_data))
4786 return AVERROR_INVALIDDATA;
4787 if (flags & MOV_TRUN_DATA_OFFSET) data_offset = avio_rb32(pb);
4788 if (flags & MOV_TRUN_FIRST_SAMPLE_FLAGS) first_sample_flags = avio_rb32(pb);
4790 frag_stream_info = get_current_frag_stream_info(&c->frag_index);
4791 if (frag_stream_info) {
4792 if (frag_stream_info->next_trun_dts != AV_NOPTS_VALUE) {
4793 dts = frag_stream_info->next_trun_dts - sc->time_offset;
4794 } else if (frag_stream_info->first_tfra_pts != AV_NOPTS_VALUE &&
4795 c->use_mfra_for == FF_MOV_FLAG_MFRA_PTS) {
4796 pts = frag_stream_info->first_tfra_pts;
4797 av_log(c->fc, AV_LOG_DEBUG, "found mfra time %"PRId64
4798 ", using it for pts\n", pts);
4799 } else if (frag_stream_info->first_tfra_pts != AV_NOPTS_VALUE &&
4800 c->use_mfra_for == FF_MOV_FLAG_MFRA_DTS) {
4801 dts = frag_stream_info->first_tfra_pts;
4802 av_log(c->fc, AV_LOG_DEBUG, "found mfra time %"PRId64
4803 ", using it for dts\n", pts);
4804 } else if (frag_stream_info->sidx_pts != AV_NOPTS_VALUE) {
4805 // FIXME: sidx earliest_presentation_time is *PTS*, s.b.
4806 // pts = frag_stream_info->sidx_pts;
4807 dts = frag_stream_info->sidx_pts - sc->time_offset;
4808 av_log(c->fc, AV_LOG_DEBUG, "found sidx time %"PRId64
4809 ", using it for pts\n", pts);
4810 } else if (frag_stream_info->tfdt_dts != AV_NOPTS_VALUE) {
4811 dts = frag_stream_info->tfdt_dts - sc->time_offset;
4812 av_log(c->fc, AV_LOG_DEBUG, "found tfdt time %"PRId64
4813 ", using it for dts\n", dts);
4815 dts = sc->track_end - sc->time_offset;
4816 av_log(c->fc, AV_LOG_DEBUG, "found track end time %"PRId64
4817 ", using it for dts\n", dts);
4820 dts = sc->track_end - sc->time_offset;
4821 av_log(c->fc, AV_LOG_DEBUG, "found track end time %"PRId64
4822 ", using it for dts\n", dts);
4824 offset = frag->base_data_offset + data_offset;
4826 av_log(c->fc, AV_LOG_TRACE, "first sample flags 0x%x\n", first_sample_flags);
4828 // realloc space for new index entries
4829 if((uint64_t)st->internal->nb_index_entries + entries >= UINT_MAX / sizeof(AVIndexEntry)) {
4830 entries = UINT_MAX / sizeof(AVIndexEntry) - st->internal->nb_index_entries;
4831 av_log(c->fc, AV_LOG_ERROR, "Failed to add index entry\n");
4836 requested_size = (st->internal->nb_index_entries + entries) * sizeof(AVIndexEntry);
4837 new_entries = av_fast_realloc(st->internal->index_entries,
4838 &st->internal->index_entries_allocated_size,
4841 return AVERROR(ENOMEM);
4842 st->internal->index_entries= new_entries;
4844 requested_size = (st->internal->nb_index_entries + entries) * sizeof(*sc->ctts_data);
4845 old_ctts_allocated_size = sc->ctts_allocated_size;
4846 ctts_data = av_fast_realloc(sc->ctts_data, &sc->ctts_allocated_size,
4849 return AVERROR(ENOMEM);
4850 sc->ctts_data = ctts_data;
4852 // In case there were samples without ctts entries, ensure they get
4853 // zero valued entries. This ensures clips which mix boxes with and
4854 // without ctts entries don't pickup uninitialized data.
4855 memset((uint8_t*)(sc->ctts_data) + old_ctts_allocated_size, 0,
4856 sc->ctts_allocated_size - old_ctts_allocated_size);
4858 if (index_entry_pos < st->internal->nb_index_entries) {
4859 // Make hole in index_entries and ctts_data for new samples
4860 memmove(st->internal->index_entries + index_entry_pos + entries,
4861 st->internal->index_entries + index_entry_pos,
4862 sizeof(*st->internal->index_entries) *
4863 (st->internal->nb_index_entries - index_entry_pos));
4864 memmove(sc->ctts_data + index_entry_pos + entries,
4865 sc->ctts_data + index_entry_pos,
4866 sizeof(*sc->ctts_data) * (sc->ctts_count - index_entry_pos));
4867 if (index_entry_pos < sc->current_sample) {
4868 sc->current_sample += entries;
4872 st->internal->nb_index_entries += entries;
4873 sc->ctts_count = st->internal->nb_index_entries;
4875 // Record the index_entry position in frag_index of this fragment
4876 if (frag_stream_info)
4877 frag_stream_info->index_entry = index_entry_pos;
4879 if (index_entry_pos > 0)
4880 prev_dts = st->internal->index_entries[index_entry_pos-1].timestamp;
4882 for (i = 0; i < entries && !pb->eof_reached; i++) {
4883 unsigned sample_size = frag->size;
4884 int sample_flags = i ? frag->flags : first_sample_flags;
4885 unsigned sample_duration = frag->duration;
4886 unsigned ctts_duration = 0;
4888 int index_entry_flags = 0;
4890 if (flags & MOV_TRUN_SAMPLE_DURATION) sample_duration = avio_rb32(pb);
4891 if (flags & MOV_TRUN_SAMPLE_SIZE) sample_size = avio_rb32(pb);
4892 if (flags & MOV_TRUN_SAMPLE_FLAGS) sample_flags = avio_rb32(pb);
4893 if (flags & MOV_TRUN_SAMPLE_CTS) ctts_duration = avio_rb32(pb);
4895 mov_update_dts_shift(sc, ctts_duration, c->fc);
4896 if (pts != AV_NOPTS_VALUE) {
4897 dts = pts - sc->dts_shift;
4898 if (flags & MOV_TRUN_SAMPLE_CTS) {
4899 dts -= ctts_duration;
4901 dts -= sc->time_offset;
4903 av_log(c->fc, AV_LOG_DEBUG,
4904 "pts %"PRId64" calculated dts %"PRId64
4905 " sc->dts_shift %d ctts.duration %d"
4906 " sc->time_offset %"PRId64
4907 " flags & MOV_TRUN_SAMPLE_CTS %d\n",
4909 sc->dts_shift, ctts_duration,
4910 sc->time_offset, flags & MOV_TRUN_SAMPLE_CTS);
4911 pts = AV_NOPTS_VALUE;
4914 if (st->codecpar->codec_type == AVMEDIA_TYPE_AUDIO)
4918 !(sample_flags & (MOV_FRAG_SAMPLE_FLAG_IS_NON_SYNC |
4919 MOV_FRAG_SAMPLE_FLAG_DEPENDS_YES));
4922 index_entry_flags |= AVINDEX_KEYFRAME;
4924 // Fragments can overlap in time. Discard overlapping frames after
4926 if (prev_dts >= dts)
4927 index_entry_flags |= AVINDEX_DISCARD_FRAME;
4929 st->internal->index_entries[index_entry_pos].pos = offset;
4930 st->internal->index_entries[index_entry_pos].timestamp = dts;
4931 st->internal->index_entries[index_entry_pos].size= sample_size;
4932 st->internal->index_entries[index_entry_pos].min_distance= distance;
4933 st->internal->index_entries[index_entry_pos].flags = index_entry_flags;
4935 sc->ctts_data[index_entry_pos].count = 1;
4936 sc->ctts_data[index_entry_pos].duration = ctts_duration;
4939 av_log(c->fc, AV_LOG_TRACE, "AVIndex stream %d, sample %d, offset %"PRIx64", dts %"PRId64", "
4940 "size %u, distance %d, keyframe %d\n", st->index,
4941 index_entry_pos, offset, dts, sample_size, distance, keyframe);
4943 dts += sample_duration;
4944 offset += sample_size;
4945 sc->data_size += sample_size;
4947 if (sample_duration <= INT64_MAX - sc->duration_for_fps &&
4948 1 <= INT_MAX - sc->nb_frames_for_fps
4950 sc->duration_for_fps += sample_duration;
4951 sc->nb_frames_for_fps ++;
4954 if (frag_stream_info)
4955 frag_stream_info->next_trun_dts = dts + sc->time_offset;
4957 // EOF found before reading all entries. Fix the hole this would
4958 // leave in index_entries and ctts_data
4959 int gap = entries - i;
4960 memmove(st->internal->index_entries + index_entry_pos,
4961 st->internal->index_entries + index_entry_pos + gap,
4962 sizeof(*st->internal->index_entries) *
4963 (st->internal->nb_index_entries - (index_entry_pos + gap)));
4964 memmove(sc->ctts_data + index_entry_pos,
4965 sc->ctts_data + index_entry_pos + gap,
4966 sizeof(*sc->ctts_data) *
4967 (sc->ctts_count - (index_entry_pos + gap)));
4969 st->internal->nb_index_entries -= gap;
4970 sc->ctts_count -= gap;
4971 if (index_entry_pos < sc->current_sample) {
4972 sc->current_sample -= gap;
4977 // The end of this new fragment may overlap in time with the start
4978 // of the next fragment in index_entries. Mark the samples in the next
4979 // fragment that overlap with AVINDEX_DISCARD_FRAME
4980 prev_dts = AV_NOPTS_VALUE;
4981 if (index_entry_pos > 0)
4982 prev_dts = st->internal->index_entries[index_entry_pos-1].timestamp;
4983 for (i = index_entry_pos; i < st->internal->nb_index_entries; i++) {
4984 if (prev_dts < st->internal->index_entries[i].timestamp)
4986 st->internal->index_entries[i].flags |= AVINDEX_DISCARD_FRAME;
4989 // If a hole was created to insert the new index_entries into,
4990 // the index_entry recorded for all subsequent moof must
4991 // be incremented by the number of entries inserted.
4992 fix_frag_index_entries(&c->frag_index, next_frag_index,
4993 frag->track_id, entries);
4995 if (pb->eof_reached) {
4996 av_log(c->fc, AV_LOG_WARNING, "reached eof, corrupted TRUN atom\n");
5000 frag->implicit_offset = offset;
5002 sc->track_end = dts + sc->time_offset;
5003 if (st->duration < sc->track_end)
5004 st->duration = sc->track_end;
5009 static int mov_read_sidx(MOVContext *c, AVIOContext *pb, MOVAtom atom)
5011 int64_t stream_size = avio_size(pb);
5012 int64_t offset = av_sat_add64(avio_tell(pb), atom.size), pts, timestamp;
5013 uint8_t version, is_complete;
5015 unsigned i, j, track_id, item_count;
5016 AVStream *st = NULL;
5017 AVStream *ref_st = NULL;
5018 MOVStreamContext *sc, *ref_sc = NULL;
5019 AVRational timescale;
5021 version = avio_r8(pb);
5023 avpriv_request_sample(c->fc, "sidx version %u", version);
5027 avio_rb24(pb); // flags
5029 track_id = avio_rb32(pb); // Reference ID
5030 for (i = 0; i < c->fc->nb_streams; i++) {
5031 if (c->fc->streams[i]->id == track_id) {
5032 st = c->fc->streams[i];
5037 av_log(c->fc, AV_LOG_WARNING, "could not find corresponding track id %d\n", track_id);
5043 timescale = av_make_q(1, avio_rb32(pb));
5045 if (timescale.den <= 0) {
5046 av_log(c->fc, AV_LOG_ERROR, "Invalid sidx timescale 1/%d\n", timescale.den);
5047 return AVERROR_INVALIDDATA;
5051 pts = avio_rb32(pb);
5052 offadd= avio_rb32(pb);
5054 pts = avio_rb64(pb);
5055 offadd= avio_rb64(pb);
5057 if (av_sat_add64(offset, offadd) != offset + (uint64_t)offadd)
5058 return AVERROR_INVALIDDATA;
5060 offset += (uint64_t)offadd;
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;
5083 if (av_sat_add64(offset, size) != offset + size ||
5084 av_sat_add64(pts, duration) != pts + (uint64_t)duration
5086 return AVERROR_INVALIDDATA;
5091 st->duration = sc->track_end = pts;
5095 // See if the remaining bytes are just an mfra which we can ignore.
5096 is_complete = offset == stream_size;
5097 if (!is_complete && (pb->seekable & AVIO_SEEKABLE_NORMAL)) {
5099 int64_t original_pos = avio_tell(pb);
5100 if (!c->have_read_mfra_size) {
5101 if ((ret = avio_seek(pb, stream_size - 4, SEEK_SET)) < 0)
5103 c->mfra_size = avio_rb32(pb);
5104 c->have_read_mfra_size = 1;
5105 if ((ret = avio_seek(pb, original_pos, SEEK_SET)) < 0)
5108 if (offset + c->mfra_size == stream_size)
5113 // Find first entry in fragment index that came from an sidx.
5114 // This will pretty much always be the first entry.
5115 for (i = 0; i < c->frag_index.nb_items; i++) {
5116 MOVFragmentIndexItem * item = &c->frag_index.item[i];
5117 for (j = 0; ref_st == NULL && j < item->nb_stream_info; j++) {
5118 MOVFragmentStreamInfo * si;
5119 si = &item->stream_info[j];
5120 if (si->sidx_pts != AV_NOPTS_VALUE) {
5121 ref_st = c->fc->streams[j];
5122 ref_sc = ref_st->priv_data;
5127 if (ref_st) for (i = 0; i < c->fc->nb_streams; i++) {
5128 st = c->fc->streams[i];
5130 if (!sc->has_sidx) {
5131 st->duration = sc->track_end = av_rescale(ref_st->duration, sc->time_scale, ref_sc->time_scale);
5135 c->frag_index.complete = 1;
5141 /* this atom should be null (from specs), but some buggy files put the 'moov' atom inside it... */
5142 /* like the files created with Adobe Premiere 5.0, for samples see */
5143 /* http://graphics.tudelft.nl/~wouter/publications/soundtests/ */
5144 static int mov_read_wide(MOVContext *c, AVIOContext *pb, MOVAtom atom)
5149 return 0; /* continue */
5150 if (avio_rb32(pb) != 0) { /* 0 sized mdat atom... use the 'wide' atom size */
5151 avio_skip(pb, atom.size - 4);
5154 atom.type = avio_rl32(pb);
5156 if (atom.type != MKTAG('m','d','a','t')) {
5157 avio_skip(pb, atom.size);
5160 err = mov_read_mdat(c, pb, atom);
5164 static int mov_read_cmov(MOVContext *c, AVIOContext *pb, MOVAtom atom)
5169 uint8_t *moov_data; /* uncompressed data */
5170 long cmov_len, moov_len;
5173 avio_rb32(pb); /* dcom atom */
5174 if (avio_rl32(pb) != MKTAG('d','c','o','m'))
5175 return AVERROR_INVALIDDATA;
5176 if (avio_rl32(pb) != MKTAG('z','l','i','b')) {
5177 av_log(c->fc, AV_LOG_ERROR, "unknown compression for cmov atom !\n");
5178 return AVERROR_INVALIDDATA;
5180 avio_rb32(pb); /* cmvd atom */
5181 if (avio_rl32(pb) != MKTAG('c','m','v','d'))
5182 return AVERROR_INVALIDDATA;
5183 moov_len = avio_rb32(pb); /* uncompressed size */
5184 cmov_len = atom.size - 6 * 4;
5186 cmov_data = av_malloc(cmov_len);
5188 return AVERROR(ENOMEM);
5189 moov_data = av_malloc(moov_len);
5192 return AVERROR(ENOMEM);
5194 ret = ffio_read_size(pb, cmov_data, cmov_len);
5196 goto free_and_return;
5198 ret = AVERROR_INVALIDDATA;
5199 if (uncompress (moov_data, (uLongf *) &moov_len, (const Bytef *)cmov_data, cmov_len) != Z_OK)
5200 goto free_and_return;
5201 if (ffio_init_context(&ctx, moov_data, moov_len, 0, NULL, NULL, NULL, NULL) != 0)
5202 goto free_and_return;
5203 ctx.seekable = AVIO_SEEKABLE_NORMAL;
5204 atom.type = MKTAG('m','o','o','v');
5205 atom.size = moov_len;
5206 ret = mov_read_default(c, &ctx, atom);
5212 av_log(c->fc, AV_LOG_ERROR, "this file requires zlib support compiled in\n");
5213 return AVERROR(ENOSYS);
5217 /* edit list atom */
5218 static int mov_read_elst(MOVContext *c, AVIOContext *pb, MOVAtom atom)
5220 MOVStreamContext *sc;
5221 int i, edit_count, version;
5222 int64_t elst_entry_size;
5224 if (c->fc->nb_streams < 1 || c->ignore_editlist)
5226 sc = c->fc->streams[c->fc->nb_streams-1]->priv_data;
5228 version = avio_r8(pb); /* version */
5229 avio_rb24(pb); /* flags */
5230 edit_count = avio_rb32(pb); /* entries */
5233 elst_entry_size = version == 1 ? 20 : 12;
5234 if (atom.size != edit_count * elst_entry_size) {
5235 if (c->fc->strict_std_compliance >= FF_COMPLIANCE_STRICT) {
5236 av_log(c->fc, AV_LOG_ERROR, "Invalid edit list entry_count: %d for elst atom of size: %"PRId64" bytes.\n",
5237 edit_count, atom.size + 8);
5238 return AVERROR_INVALIDDATA;
5240 edit_count = atom.size / elst_entry_size;
5241 if (edit_count * elst_entry_size != atom.size) {
5242 av_log(c->fc, AV_LOG_WARNING, "ELST atom of %"PRId64" bytes, bigger than %d entries.\n", atom.size, edit_count);
5250 av_log(c->fc, AV_LOG_WARNING, "Duplicated ELST atom\n");
5251 av_free(sc->elst_data);
5253 sc->elst_data = av_malloc_array(edit_count, sizeof(*sc->elst_data));
5255 return AVERROR(ENOMEM);
5257 av_log(c->fc, AV_LOG_TRACE, "track[%u].edit_count = %i\n", c->fc->nb_streams - 1, edit_count);
5258 for (i = 0; i < edit_count && atom.size > 0 && !pb->eof_reached; i++) {
5259 MOVElst *e = &sc->elst_data[i];
5262 e->duration = avio_rb64(pb);
5263 e->time = avio_rb64(pb);
5266 e->duration = avio_rb32(pb); /* segment duration */
5267 e->time = (int32_t)avio_rb32(pb); /* media time */
5270 e->rate = avio_rb32(pb) / 65536.0;
5272 av_log(c->fc, AV_LOG_TRACE, "duration=%"PRId64" time=%"PRId64" rate=%f\n",
5273 e->duration, e->time, e->rate);
5275 if (e->time < 0 && e->time != -1 &&
5276 c->fc->strict_std_compliance >= FF_COMPLIANCE_STRICT) {
5277 av_log(c->fc, AV_LOG_ERROR, "Track %d, edit %d: Invalid edit list media time=%"PRId64"\n",
5278 c->fc->nb_streams-1, i, e->time);
5279 return AVERROR_INVALIDDATA;
5287 static int mov_read_tmcd(MOVContext *c, AVIOContext *pb, MOVAtom atom)
5289 MOVStreamContext *sc;
5291 if (c->fc->nb_streams < 1)
5292 return AVERROR_INVALIDDATA;
5293 sc = c->fc->streams[c->fc->nb_streams - 1]->priv_data;
5294 sc->timecode_track = avio_rb32(pb);
5298 static int mov_read_av1c(MOVContext *c, AVIOContext *pb, MOVAtom atom)
5303 if (c->fc->nb_streams < 1)
5305 st = c->fc->streams[c->fc->nb_streams - 1];
5307 if (atom.size < 4) {
5308 av_log(c->fc, AV_LOG_ERROR, "Empty AV1 Codec Configuration Box\n");
5309 return AVERROR_INVALIDDATA;
5312 /* For now, propagate only the OBUs, if any. Once libavcodec is
5313 updated to handle isobmff style extradata this can be removed. */
5319 ret = ff_get_extradata(c->fc, st->codecpar, pb, atom.size - 4);
5326 static int mov_read_vpcc(MOVContext *c, AVIOContext *pb, MOVAtom atom)
5329 int version, color_range, color_primaries, color_trc, color_space;
5331 if (c->fc->nb_streams < 1)
5333 st = c->fc->streams[c->fc->nb_streams - 1];
5335 if (atom.size < 5) {
5336 av_log(c->fc, AV_LOG_ERROR, "Empty VP Codec Configuration box\n");
5337 return AVERROR_INVALIDDATA;
5340 version = avio_r8(pb);
5342 av_log(c->fc, AV_LOG_WARNING, "Unsupported VP Codec Configuration box version %d\n", version);
5345 avio_skip(pb, 3); /* flags */
5347 avio_skip(pb, 2); /* profile + level */
5348 color_range = avio_r8(pb); /* bitDepth, chromaSubsampling, videoFullRangeFlag */
5349 color_primaries = avio_r8(pb);
5350 color_trc = avio_r8(pb);
5351 color_space = avio_r8(pb);
5352 if (avio_rb16(pb)) /* codecIntializationDataSize */
5353 return AVERROR_INVALIDDATA;
5355 if (!av_color_primaries_name(color_primaries))
5356 color_primaries = AVCOL_PRI_UNSPECIFIED;
5357 if (!av_color_transfer_name(color_trc))
5358 color_trc = AVCOL_TRC_UNSPECIFIED;
5359 if (!av_color_space_name(color_space))
5360 color_space = AVCOL_SPC_UNSPECIFIED;
5362 st->codecpar->color_range = (color_range & 1) ? AVCOL_RANGE_JPEG : AVCOL_RANGE_MPEG;
5363 st->codecpar->color_primaries = color_primaries;
5364 st->codecpar->color_trc = color_trc;
5365 st->codecpar->color_space = color_space;
5370 static int mov_read_smdm(MOVContext *c, AVIOContext *pb, MOVAtom atom)
5372 MOVStreamContext *sc;
5375 if (c->fc->nb_streams < 1)
5376 return AVERROR_INVALIDDATA;
5378 sc = c->fc->streams[c->fc->nb_streams - 1]->priv_data;
5380 if (atom.size < 5) {
5381 av_log(c->fc, AV_LOG_ERROR, "Empty Mastering Display Metadata box\n");
5382 return AVERROR_INVALIDDATA;
5385 version = avio_r8(pb);
5387 av_log(c->fc, AV_LOG_WARNING, "Unsupported Mastering Display Metadata box version %d\n", version);
5390 avio_skip(pb, 3); /* flags */
5392 sc->mastering = av_mastering_display_metadata_alloc();
5394 return AVERROR(ENOMEM);
5396 for (i = 0; i < 3; i++) {
5397 sc->mastering->display_primaries[i][0] = av_make_q(avio_rb16(pb), 1 << 16);
5398 sc->mastering->display_primaries[i][1] = av_make_q(avio_rb16(pb), 1 << 16);
5400 sc->mastering->white_point[0] = av_make_q(avio_rb16(pb), 1 << 16);
5401 sc->mastering->white_point[1] = av_make_q(avio_rb16(pb), 1 << 16);
5403 sc->mastering->max_luminance = av_make_q(avio_rb32(pb), 1 << 8);
5404 sc->mastering->min_luminance = av_make_q(avio_rb32(pb), 1 << 14);
5406 sc->mastering->has_primaries = 1;
5407 sc->mastering->has_luminance = 1;
5412 static int mov_read_mdcv(MOVContext *c, AVIOContext *pb, MOVAtom atom)
5414 MOVStreamContext *sc;
5415 const int mapping[3] = {1, 2, 0};
5416 const int chroma_den = 50000;
5417 const int luma_den = 10000;
5420 if (c->fc->nb_streams < 1)
5421 return AVERROR_INVALIDDATA;
5423 sc = c->fc->streams[c->fc->nb_streams - 1]->priv_data;
5425 if (atom.size < 24) {
5426 av_log(c->fc, AV_LOG_ERROR, "Invalid Mastering Display Color Volume box\n");
5427 return AVERROR_INVALIDDATA;
5430 sc->mastering = av_mastering_display_metadata_alloc();
5432 return AVERROR(ENOMEM);
5434 for (i = 0; i < 3; i++) {
5435 const int j = mapping[i];
5436 sc->mastering->display_primaries[j][0] = av_make_q(avio_rb16(pb), chroma_den);
5437 sc->mastering->display_primaries[j][1] = av_make_q(avio_rb16(pb), chroma_den);
5439 sc->mastering->white_point[0] = av_make_q(avio_rb16(pb), chroma_den);
5440 sc->mastering->white_point[1] = av_make_q(avio_rb16(pb), chroma_den);
5442 sc->mastering->max_luminance = av_make_q(avio_rb32(pb), luma_den);
5443 sc->mastering->min_luminance = av_make_q(avio_rb32(pb), luma_den);
5445 sc->mastering->has_luminance = 1;
5446 sc->mastering->has_primaries = 1;
5451 static int mov_read_coll(MOVContext *c, AVIOContext *pb, MOVAtom atom)
5453 MOVStreamContext *sc;
5456 if (c->fc->nb_streams < 1)
5457 return AVERROR_INVALIDDATA;
5459 sc = c->fc->streams[c->fc->nb_streams - 1]->priv_data;
5461 if (atom.size < 5) {
5462 av_log(c->fc, AV_LOG_ERROR, "Empty Content Light Level box\n");
5463 return AVERROR_INVALIDDATA;
5466 version = avio_r8(pb);
5468 av_log(c->fc, AV_LOG_WARNING, "Unsupported Content Light Level box version %d\n", version);
5471 avio_skip(pb, 3); /* flags */
5473 sc->coll = av_content_light_metadata_alloc(&sc->coll_size);
5475 return AVERROR(ENOMEM);
5477 sc->coll->MaxCLL = avio_rb16(pb);
5478 sc->coll->MaxFALL = avio_rb16(pb);
5483 static int mov_read_clli(MOVContext *c, AVIOContext *pb, MOVAtom atom)
5485 MOVStreamContext *sc;
5487 if (c->fc->nb_streams < 1)
5488 return AVERROR_INVALIDDATA;
5490 sc = c->fc->streams[c->fc->nb_streams - 1]->priv_data;
5492 if (atom.size < 4) {
5493 av_log(c->fc, AV_LOG_ERROR, "Empty Content Light Level Info box\n");
5494 return AVERROR_INVALIDDATA;
5497 sc->coll = av_content_light_metadata_alloc(&sc->coll_size);
5499 return AVERROR(ENOMEM);
5501 sc->coll->MaxCLL = avio_rb16(pb);
5502 sc->coll->MaxFALL = avio_rb16(pb);
5507 static int mov_read_st3d(MOVContext *c, AVIOContext *pb, MOVAtom atom)
5510 MOVStreamContext *sc;
5511 enum AVStereo3DType type;
5514 if (c->fc->nb_streams < 1)
5517 st = c->fc->streams[c->fc->nb_streams - 1];
5520 if (atom.size < 5) {
5521 av_log(c->fc, AV_LOG_ERROR, "Empty stereoscopic video box\n");
5522 return AVERROR_INVALIDDATA;
5526 return AVERROR_INVALIDDATA;
5528 avio_skip(pb, 4); /* version + flags */
5533 type = AV_STEREO3D_2D;
5536 type = AV_STEREO3D_TOPBOTTOM;
5539 type = AV_STEREO3D_SIDEBYSIDE;
5542 av_log(c->fc, AV_LOG_WARNING, "Unknown st3d mode value %d\n", mode);
5546 sc->stereo3d = av_stereo3d_alloc();
5548 return AVERROR(ENOMEM);
5550 sc->stereo3d->type = type;
5554 static int mov_read_sv3d(MOVContext *c, AVIOContext *pb, MOVAtom atom)
5557 MOVStreamContext *sc;
5558 int size, version, layout;
5559 int32_t yaw, pitch, roll;
5560 uint32_t l = 0, t = 0, r = 0, b = 0;
5561 uint32_t tag, padding = 0;
5562 enum AVSphericalProjection projection;
5564 if (c->fc->nb_streams < 1)
5567 st = c->fc->streams[c->fc->nb_streams - 1];
5570 if (atom.size < 8) {
5571 av_log(c->fc, AV_LOG_ERROR, "Empty spherical video box\n");
5572 return AVERROR_INVALIDDATA;
5575 size = avio_rb32(pb);
5576 if (size <= 12 || size > atom.size)
5577 return AVERROR_INVALIDDATA;
5579 tag = avio_rl32(pb);
5580 if (tag != MKTAG('s','v','h','d')) {
5581 av_log(c->fc, AV_LOG_ERROR, "Missing spherical video header\n");
5584 version = avio_r8(pb);
5586 av_log(c->fc, AV_LOG_WARNING, "Unknown spherical version %d\n",
5590 avio_skip(pb, 3); /* flags */
5591 avio_skip(pb, size - 12); /* metadata_source */
5593 size = avio_rb32(pb);
5594 if (size > atom.size)
5595 return AVERROR_INVALIDDATA;
5597 tag = avio_rl32(pb);
5598 if (tag != MKTAG('p','r','o','j')) {
5599 av_log(c->fc, AV_LOG_ERROR, "Missing projection box\n");
5603 size = avio_rb32(pb);
5604 if (size > atom.size)
5605 return AVERROR_INVALIDDATA;
5607 tag = avio_rl32(pb);
5608 if (tag != MKTAG('p','r','h','d')) {
5609 av_log(c->fc, AV_LOG_ERROR, "Missing projection header box\n");
5612 version = avio_r8(pb);
5614 av_log(c->fc, AV_LOG_WARNING, "Unknown spherical version %d\n",
5618 avio_skip(pb, 3); /* flags */
5620 /* 16.16 fixed point */
5621 yaw = avio_rb32(pb);
5622 pitch = avio_rb32(pb);
5623 roll = avio_rb32(pb);
5625 size = avio_rb32(pb);
5626 if (size > atom.size)
5627 return AVERROR_INVALIDDATA;
5629 tag = avio_rl32(pb);
5630 version = avio_r8(pb);
5632 av_log(c->fc, AV_LOG_WARNING, "Unknown spherical version %d\n",
5636 avio_skip(pb, 3); /* flags */
5638 case MKTAG('c','b','m','p'):
5639 layout = avio_rb32(pb);
5641 av_log(c->fc, AV_LOG_WARNING,
5642 "Unsupported cubemap layout %d\n", layout);
5645 projection = AV_SPHERICAL_CUBEMAP;
5646 padding = avio_rb32(pb);
5648 case MKTAG('e','q','u','i'):
5654 if (b >= UINT_MAX - t || r >= UINT_MAX - l) {
5655 av_log(c->fc, AV_LOG_ERROR,
5656 "Invalid bounding rectangle coordinates "
5657 "%"PRIu32",%"PRIu32",%"PRIu32",%"PRIu32"\n", l, t, r, b);
5658 return AVERROR_INVALIDDATA;
5661 if (l || t || r || b)
5662 projection = AV_SPHERICAL_EQUIRECTANGULAR_TILE;
5664 projection = AV_SPHERICAL_EQUIRECTANGULAR;
5667 av_log(c->fc, AV_LOG_ERROR, "Unknown projection type: %s\n", av_fourcc2str(tag));
5671 sc->spherical = av_spherical_alloc(&sc->spherical_size);
5673 return AVERROR(ENOMEM);
5675 sc->spherical->projection = projection;
5677 sc->spherical->yaw = yaw;
5678 sc->spherical->pitch = pitch;
5679 sc->spherical->roll = roll;
5681 sc->spherical->padding = padding;
5683 sc->spherical->bound_left = l;
5684 sc->spherical->bound_top = t;
5685 sc->spherical->bound_right = r;
5686 sc->spherical->bound_bottom = b;
5691 static int mov_parse_uuid_spherical(MOVStreamContext *sc, AVIOContext *pb, size_t len)
5694 uint8_t *buffer = av_malloc(len + 1);
5698 return AVERROR(ENOMEM);
5701 ret = ffio_read_size(pb, buffer, len);
5705 /* Check for mandatory keys and values, try to support XML as best-effort */
5706 if (!sc->spherical &&
5707 av_stristr(buffer, "<GSpherical:StitchingSoftware>") &&
5708 (val = av_stristr(buffer, "<GSpherical:Spherical>")) &&
5709 av_stristr(val, "true") &&
5710 (val = av_stristr(buffer, "<GSpherical:Stitched>")) &&
5711 av_stristr(val, "true") &&
5712 (val = av_stristr(buffer, "<GSpherical:ProjectionType>")) &&
5713 av_stristr(val, "equirectangular")) {
5714 sc->spherical = av_spherical_alloc(&sc->spherical_size);
5718 sc->spherical->projection = AV_SPHERICAL_EQUIRECTANGULAR;
5720 if (av_stristr(buffer, "<GSpherical:StereoMode>") && !sc->stereo3d) {
5721 enum AVStereo3DType mode;
5723 if (av_stristr(buffer, "left-right"))
5724 mode = AV_STEREO3D_SIDEBYSIDE;
5725 else if (av_stristr(buffer, "top-bottom"))
5726 mode = AV_STEREO3D_TOPBOTTOM;
5728 mode = AV_STEREO3D_2D;
5730 sc->stereo3d = av_stereo3d_alloc();
5734 sc->stereo3d->type = mode;
5738 val = av_stristr(buffer, "<GSpherical:InitialViewHeadingDegrees>");
5740 sc->spherical->yaw = strtol(val, NULL, 10) * (1 << 16);
5741 val = av_stristr(buffer, "<GSpherical:InitialViewPitchDegrees>");
5743 sc->spherical->pitch = strtol(val, NULL, 10) * (1 << 16);
5744 val = av_stristr(buffer, "<GSpherical:InitialViewRollDegrees>");
5746 sc->spherical->roll = strtol(val, NULL, 10) * (1 << 16);
5754 static int mov_read_uuid(MOVContext *c, AVIOContext *pb, MOVAtom atom)
5757 MOVStreamContext *sc;
5760 static const uint8_t uuid_isml_manifest[] = {
5761 0xa5, 0xd4, 0x0b, 0x30, 0xe8, 0x14, 0x11, 0xdd,
5762 0xba, 0x2f, 0x08, 0x00, 0x20, 0x0c, 0x9a, 0x66
5764 static const uint8_t uuid_xmp[] = {
5765 0xbe, 0x7a, 0xcf, 0xcb, 0x97, 0xa9, 0x42, 0xe8,
5766 0x9c, 0x71, 0x99, 0x94, 0x91, 0xe3, 0xaf, 0xac
5768 static const uint8_t uuid_spherical[] = {
5769 0xff, 0xcc, 0x82, 0x63, 0xf8, 0x55, 0x4a, 0x93,
5770 0x88, 0x14, 0x58, 0x7a, 0x02, 0x52, 0x1f, 0xdd,
5773 if (atom.size < sizeof(uuid) || atom.size >= FFMIN(INT_MAX, SIZE_MAX))
5774 return AVERROR_INVALIDDATA;
5776 if (c->fc->nb_streams < 1)
5778 st = c->fc->streams[c->fc->nb_streams - 1];
5781 ret = ffio_read_size(pb, uuid, sizeof(uuid));
5784 if (!memcmp(uuid, uuid_isml_manifest, sizeof(uuid))) {
5785 uint8_t *buffer, *ptr;
5787 size_t len = atom.size - sizeof(uuid);
5790 return AVERROR_INVALIDDATA;
5792 ret = avio_skip(pb, 4); // zeroes
5795 buffer = av_mallocz(len + 1);
5797 return AVERROR(ENOMEM);
5799 ret = ffio_read_size(pb, buffer, len);
5806 while ((ptr = av_stristr(ptr, "systemBitrate=\""))) {
5807 ptr += sizeof("systemBitrate=\"") - 1;
5808 c->bitrates_count++;
5809 c->bitrates = av_realloc_f(c->bitrates, c->bitrates_count, sizeof(*c->bitrates));
5811 c->bitrates_count = 0;
5813 return AVERROR(ENOMEM);
5816 ret = strtol(ptr, &endptr, 10);
5817 if (ret < 0 || errno || *endptr != '"') {
5818 c->bitrates[c->bitrates_count - 1] = 0;
5820 c->bitrates[c->bitrates_count - 1] = ret;
5825 } else if (!memcmp(uuid, uuid_xmp, sizeof(uuid))) {
5827 size_t len = atom.size - sizeof(uuid);
5828 if (c->export_xmp) {
5829 buffer = av_mallocz(len + 1);
5831 return AVERROR(ENOMEM);
5833 ret = ffio_read_size(pb, buffer, len);
5839 av_dict_set(&c->fc->metadata, "xmp",
5840 buffer, AV_DICT_DONT_STRDUP_VAL);
5842 // skip all uuid atom, which makes it fast for long uuid-xmp file
5843 ret = avio_skip(pb, len);
5847 } else if (!memcmp(uuid, uuid_spherical, sizeof(uuid))) {
5848 size_t len = atom.size - sizeof(uuid);
5849 ret = mov_parse_uuid_spherical(sc, pb, len);
5853 av_log(c->fc, AV_LOG_WARNING, "Invalid spherical metadata found\n");
5859 static int mov_read_free(MOVContext *c, AVIOContext *pb, MOVAtom atom)
5862 uint8_t content[16];
5867 ret = avio_read(pb, content, FFMIN(sizeof(content), atom.size));
5873 && !memcmp(content, "Anevia\x1A\x1A", 8)
5874 && c->use_mfra_for == FF_MOV_FLAG_MFRA_AUTO) {
5875 c->use_mfra_for = FF_MOV_FLAG_MFRA_PTS;
5881 static int mov_read_frma(MOVContext *c, AVIOContext *pb, MOVAtom atom)
5883 uint32_t format = avio_rl32(pb);
5884 MOVStreamContext *sc;
5888 if (c->fc->nb_streams < 1)
5890 st = c->fc->streams[c->fc->nb_streams - 1];
5895 case MKTAG('e','n','c','v'): // encrypted video
5896 case MKTAG('e','n','c','a'): // encrypted audio
5897 id = mov_codec_id(st, format);
5898 if (st->codecpar->codec_id != AV_CODEC_ID_NONE &&
5899 st->codecpar->codec_id != id) {
5900 av_log(c->fc, AV_LOG_WARNING,
5901 "ignoring 'frma' atom of '%.4s', stream has codec id %d\n",
5902 (char*)&format, st->codecpar->codec_id);
5906 st->codecpar->codec_id = id;
5907 sc->format = format;
5911 if (format != sc->format) {
5912 av_log(c->fc, AV_LOG_WARNING,
5913 "ignoring 'frma' atom of '%.4s', stream format is '%.4s'\n",
5914 (char*)&format, (char*)&sc->format);
5923 * Gets the current encryption info and associated current stream context. If
5924 * we are parsing a track fragment, this will return the specific encryption
5925 * info for this fragment; otherwise this will return the global encryption
5926 * info for the current stream.
5928 static int get_current_encryption_info(MOVContext *c, MOVEncryptionIndex **encryption_index, MOVStreamContext **sc)
5930 MOVFragmentStreamInfo *frag_stream_info;
5934 frag_stream_info = get_current_frag_stream_info(&c->frag_index);
5935 if (frag_stream_info) {
5936 for (i = 0; i < c->fc->nb_streams; i++) {
5937 if (c->fc->streams[i]->id == frag_stream_info->id) {
5938 st = c->fc->streams[i];
5942 if (i == c->fc->nb_streams)
5944 *sc = st->priv_data;
5946 if (!frag_stream_info->encryption_index) {
5947 // If this stream isn't encrypted, don't create the index.
5948 if (!(*sc)->cenc.default_encrypted_sample)
5950 frag_stream_info->encryption_index = av_mallocz(sizeof(*frag_stream_info->encryption_index));
5951 if (!frag_stream_info->encryption_index)
5952 return AVERROR(ENOMEM);
5954 *encryption_index = frag_stream_info->encryption_index;
5957 // No current track fragment, using stream level encryption info.
5959 if (c->fc->nb_streams < 1)
5961 st = c->fc->streams[c->fc->nb_streams - 1];
5962 *sc = st->priv_data;
5964 if (!(*sc)->cenc.encryption_index) {
5965 // If this stream isn't encrypted, don't create the index.
5966 if (!(*sc)->cenc.default_encrypted_sample)
5968 (*sc)->cenc.encryption_index = av_mallocz(sizeof(*frag_stream_info->encryption_index));
5969 if (!(*sc)->cenc.encryption_index)
5970 return AVERROR(ENOMEM);
5973 *encryption_index = (*sc)->cenc.encryption_index;
5978 static int mov_read_sample_encryption_info(MOVContext *c, AVIOContext *pb, MOVStreamContext *sc, AVEncryptionInfo **sample, int use_subsamples)
5981 unsigned int subsample_count;
5982 AVSubsampleEncryptionInfo *subsamples;
5984 if (!sc->cenc.default_encrypted_sample) {
5985 av_log(c->fc, AV_LOG_ERROR, "Missing schm or tenc\n");
5986 return AVERROR_INVALIDDATA;
5989 *sample = av_encryption_info_clone(sc->cenc.default_encrypted_sample);
5991 return AVERROR(ENOMEM);
5993 if (sc->cenc.per_sample_iv_size != 0) {
5994 if ((ret = ffio_read_size(pb, (*sample)->iv, sc->cenc.per_sample_iv_size)) < 0) {
5995 av_log(c->fc, AV_LOG_ERROR, "failed to read the initialization vector\n");
5996 av_encryption_info_free(*sample);
6002 if (use_subsamples) {
6003 subsample_count = avio_rb16(pb);
6004 av_free((*sample)->subsamples);
6005 (*sample)->subsamples = av_mallocz_array(subsample_count, sizeof(*subsamples));
6006 if (!(*sample)->subsamples) {
6007 av_encryption_info_free(*sample);
6009 return AVERROR(ENOMEM);
6012 for (i = 0; i < subsample_count && !pb->eof_reached; i++) {
6013 (*sample)->subsamples[i].bytes_of_clear_data = avio_rb16(pb);
6014 (*sample)->subsamples[i].bytes_of_protected_data = avio_rb32(pb);
6017 if (pb->eof_reached) {
6018 av_log(c->fc, AV_LOG_ERROR, "hit EOF while reading sub-sample encryption info\n");
6019 av_encryption_info_free(*sample);
6021 return AVERROR_INVALIDDATA;
6023 (*sample)->subsample_count = subsample_count;
6029 static int mov_read_senc(MOVContext *c, AVIOContext *pb, MOVAtom atom)
6031 AVEncryptionInfo **encrypted_samples;
6032 MOVEncryptionIndex *encryption_index;
6033 MOVStreamContext *sc;
6034 int use_subsamples, ret;
6035 unsigned int sample_count, i, alloc_size = 0;
6037 ret = get_current_encryption_info(c, &encryption_index, &sc);
6041 if (encryption_index->nb_encrypted_samples) {
6042 // This can happen if we have both saio/saiz and senc atoms.
6043 av_log(c->fc, AV_LOG_DEBUG, "Ignoring duplicate encryption info in senc\n");
6047 avio_r8(pb); /* version */
6048 use_subsamples = avio_rb24(pb) & 0x02; /* flags */
6050 sample_count = avio_rb32(pb);
6051 if (sample_count >= INT_MAX / sizeof(*encrypted_samples))
6052 return AVERROR(ENOMEM);
6054 for (i = 0; i < sample_count; i++) {
6055 unsigned int min_samples = FFMIN(FFMAX(i + 1, 1024 * 1024), sample_count);
6056 encrypted_samples = av_fast_realloc(encryption_index->encrypted_samples, &alloc_size,
6057 min_samples * sizeof(*encrypted_samples));
6058 if (encrypted_samples) {
6059 encryption_index->encrypted_samples = encrypted_samples;
6061 ret = mov_read_sample_encryption_info(
6062 c, pb, sc, &encryption_index->encrypted_samples[i], use_subsamples);
6064 ret = AVERROR(ENOMEM);
6066 if (pb->eof_reached) {
6067 av_log(c->fc, AV_LOG_ERROR, "Hit EOF while reading senc\n");
6068 ret = AVERROR_INVALIDDATA;
6073 av_encryption_info_free(encryption_index->encrypted_samples[i - 1]);
6074 av_freep(&encryption_index->encrypted_samples);
6078 encryption_index->nb_encrypted_samples = sample_count;
6083 static int mov_parse_auxiliary_info(MOVContext *c, MOVStreamContext *sc, AVIOContext *pb, MOVEncryptionIndex *encryption_index)
6085 AVEncryptionInfo **sample, **encrypted_samples;
6087 size_t sample_count, sample_info_size, i;
6089 unsigned int alloc_size = 0;
6091 if (encryption_index->nb_encrypted_samples)
6093 sample_count = encryption_index->auxiliary_info_sample_count;
6094 if (encryption_index->auxiliary_offsets_count != 1) {
6095 av_log(c->fc, AV_LOG_ERROR, "Multiple auxiliary info chunks are not supported\n");
6096 return AVERROR_PATCHWELCOME;
6098 if (sample_count >= INT_MAX / sizeof(*encrypted_samples))
6099 return AVERROR(ENOMEM);
6101 prev_pos = avio_tell(pb);
6102 if (!(pb->seekable & AVIO_SEEKABLE_NORMAL) ||
6103 avio_seek(pb, encryption_index->auxiliary_offsets[0], SEEK_SET) != encryption_index->auxiliary_offsets[0]) {
6104 av_log(c->fc, AV_LOG_INFO, "Failed to seek for auxiliary info, will only parse senc atoms for encryption info\n");
6108 for (i = 0; i < sample_count && !pb->eof_reached; i++) {
6109 unsigned int min_samples = FFMIN(FFMAX(i + 1, 1024 * 1024), sample_count);
6110 encrypted_samples = av_fast_realloc(encryption_index->encrypted_samples, &alloc_size,
6111 min_samples * sizeof(*encrypted_samples));
6112 if (!encrypted_samples) {
6113 ret = AVERROR(ENOMEM);
6116 encryption_index->encrypted_samples = encrypted_samples;
6118 sample = &encryption_index->encrypted_samples[i];
6119 sample_info_size = encryption_index->auxiliary_info_default_size
6120 ? encryption_index->auxiliary_info_default_size
6121 : encryption_index->auxiliary_info_sizes[i];
6123 ret = mov_read_sample_encryption_info(c, pb, sc, sample, sample_info_size > sc->cenc.per_sample_iv_size);
6127 if (pb->eof_reached) {
6128 av_log(c->fc, AV_LOG_ERROR, "Hit EOF while reading auxiliary info\n");
6129 ret = AVERROR_INVALIDDATA;
6131 encryption_index->nb_encrypted_samples = sample_count;
6135 avio_seek(pb, prev_pos, SEEK_SET);
6137 for (; i > 0; i--) {
6138 av_encryption_info_free(encryption_index->encrypted_samples[i - 1]);
6140 av_freep(&encryption_index->encrypted_samples);
6146 * Tries to read the given number of bytes from the stream and puts it in a
6147 * newly allocated buffer. This reads in small chunks to avoid allocating large
6148 * memory if the file contains an invalid/malicious size value.
6150 static int mov_try_read_block(AVIOContext *pb, size_t size, uint8_t **data)
6152 const unsigned int block_size = 1024 * 1024;
6153 uint8_t *buffer = NULL;
6154 unsigned int alloc_size = 0, offset = 0;
6155 while (offset < size) {
6156 unsigned int new_size =
6157 alloc_size >= INT_MAX - block_size ? INT_MAX : alloc_size + block_size;
6158 uint8_t *new_buffer = av_fast_realloc(buffer, &alloc_size, new_size);
6159 unsigned int to_read = FFMIN(size, alloc_size) - offset;
6162 return AVERROR(ENOMEM);
6164 buffer = new_buffer;
6166 if (avio_read(pb, buffer + offset, to_read) != to_read) {
6168 return AVERROR_INVALIDDATA;
6177 static int mov_read_saiz(MOVContext *c, AVIOContext *pb, MOVAtom atom)
6179 MOVEncryptionIndex *encryption_index;
6180 MOVStreamContext *sc;
6182 unsigned int sample_count, aux_info_type, aux_info_param;
6184 ret = get_current_encryption_info(c, &encryption_index, &sc);
6188 if (encryption_index->nb_encrypted_samples) {
6189 // This can happen if we have both saio/saiz and senc atoms.
6190 av_log(c->fc, AV_LOG_DEBUG, "Ignoring duplicate encryption info in saiz\n");
6194 if (encryption_index->auxiliary_info_sample_count) {
6195 av_log(c->fc, AV_LOG_ERROR, "Duplicate saiz atom\n");
6196 return AVERROR_INVALIDDATA;
6199 avio_r8(pb); /* version */
6200 if (avio_rb24(pb) & 0x01) { /* flags */
6201 aux_info_type = avio_rb32(pb);
6202 aux_info_param = avio_rb32(pb);
6203 if (sc->cenc.default_encrypted_sample) {
6204 if (aux_info_type != sc->cenc.default_encrypted_sample->scheme) {
6205 av_log(c->fc, AV_LOG_DEBUG, "Ignoring saiz box with non-zero aux_info_type\n");
6208 if (aux_info_param != 0) {
6209 av_log(c->fc, AV_LOG_DEBUG, "Ignoring saiz box with non-zero aux_info_type_parameter\n");
6213 // Didn't see 'schm' or 'tenc', so this isn't encrypted.
6214 if ((aux_info_type == MKBETAG('c','e','n','c') ||
6215 aux_info_type == MKBETAG('c','e','n','s') ||
6216 aux_info_type == MKBETAG('c','b','c','1') ||
6217 aux_info_type == MKBETAG('c','b','c','s')) &&
6218 aux_info_param == 0) {
6219 av_log(c->fc, AV_LOG_ERROR, "Saw encrypted saiz without schm/tenc\n");
6220 return AVERROR_INVALIDDATA;
6225 } else if (!sc->cenc.default_encrypted_sample) {
6226 // Didn't see 'schm' or 'tenc', so this isn't encrypted.
6230 encryption_index->auxiliary_info_default_size = avio_r8(pb);
6231 sample_count = avio_rb32(pb);
6232 encryption_index->auxiliary_info_sample_count = sample_count;
6234 if (encryption_index->auxiliary_info_default_size == 0) {
6235 ret = mov_try_read_block(pb, sample_count, &encryption_index->auxiliary_info_sizes);
6237 av_log(c->fc, AV_LOG_ERROR, "Failed to read the auxiliary info\n");
6242 if (encryption_index->auxiliary_offsets_count) {
6243 return mov_parse_auxiliary_info(c, sc, pb, encryption_index);
6249 static int mov_read_saio(MOVContext *c, AVIOContext *pb, MOVAtom atom)
6251 uint64_t *auxiliary_offsets;
6252 MOVEncryptionIndex *encryption_index;
6253 MOVStreamContext *sc;
6255 unsigned int version, entry_count, aux_info_type, aux_info_param;
6256 unsigned int alloc_size = 0;
6258 ret = get_current_encryption_info(c, &encryption_index, &sc);
6262 if (encryption_index->nb_encrypted_samples) {
6263 // This can happen if we have both saio/saiz and senc atoms.
6264 av_log(c->fc, AV_LOG_DEBUG, "Ignoring duplicate encryption info in saio\n");
6268 if (encryption_index->auxiliary_offsets_count) {
6269 av_log(c->fc, AV_LOG_ERROR, "Duplicate saio atom\n");
6270 return AVERROR_INVALIDDATA;
6273 version = avio_r8(pb); /* version */
6274 if (avio_rb24(pb) & 0x01) { /* flags */
6275 aux_info_type = avio_rb32(pb);
6276 aux_info_param = avio_rb32(pb);
6277 if (sc->cenc.default_encrypted_sample) {
6278 if (aux_info_type != sc->cenc.default_encrypted_sample->scheme) {
6279 av_log(c->fc, AV_LOG_DEBUG, "Ignoring saio box with non-zero aux_info_type\n");
6282 if (aux_info_param != 0) {
6283 av_log(c->fc, AV_LOG_DEBUG, "Ignoring saio box with non-zero aux_info_type_parameter\n");
6287 // Didn't see 'schm' or 'tenc', so this isn't encrypted.
6288 if ((aux_info_type == MKBETAG('c','e','n','c') ||
6289 aux_info_type == MKBETAG('c','e','n','s') ||
6290 aux_info_type == MKBETAG('c','b','c','1') ||
6291 aux_info_type == MKBETAG('c','b','c','s')) &&
6292 aux_info_param == 0) {
6293 av_log(c->fc, AV_LOG_ERROR, "Saw encrypted saio without schm/tenc\n");
6294 return AVERROR_INVALIDDATA;
6299 } else if (!sc->cenc.default_encrypted_sample) {
6300 // Didn't see 'schm' or 'tenc', so this isn't encrypted.
6304 entry_count = avio_rb32(pb);
6305 if (entry_count >= INT_MAX / sizeof(*auxiliary_offsets))
6306 return AVERROR(ENOMEM);
6308 for (i = 0; i < entry_count && !pb->eof_reached; i++) {
6309 unsigned int min_offsets = FFMIN(FFMAX(i + 1, 1024), entry_count);
6310 auxiliary_offsets = av_fast_realloc(
6311 encryption_index->auxiliary_offsets, &alloc_size,
6312 min_offsets * sizeof(*auxiliary_offsets));
6313 if (!auxiliary_offsets) {
6314 av_freep(&encryption_index->auxiliary_offsets);
6315 return AVERROR(ENOMEM);
6317 encryption_index->auxiliary_offsets = auxiliary_offsets;
6320 encryption_index->auxiliary_offsets[i] = avio_rb32(pb);
6322 encryption_index->auxiliary_offsets[i] = avio_rb64(pb);
6324 if (c->frag_index.current >= 0) {
6325 encryption_index->auxiliary_offsets[i] += c->fragment.base_data_offset;
6329 if (pb->eof_reached) {
6330 av_log(c->fc, AV_LOG_ERROR, "Hit EOF while reading saio\n");
6331 av_freep(&encryption_index->auxiliary_offsets);
6332 return AVERROR_INVALIDDATA;
6335 encryption_index->auxiliary_offsets_count = entry_count;
6337 if (encryption_index->auxiliary_info_sample_count) {
6338 return mov_parse_auxiliary_info(c, sc, pb, encryption_index);
6344 static int mov_read_pssh(MOVContext *c, AVIOContext *pb, MOVAtom atom)
6346 AVEncryptionInitInfo *info, *old_init_info;
6349 uint8_t *side_data, *extra_data, *old_side_data;
6350 size_t side_data_size, old_side_data_size;
6352 unsigned int version, kid_count, extra_data_size, alloc_size = 0;
6354 if (c->fc->nb_streams < 1)
6356 st = c->fc->streams[c->fc->nb_streams-1];
6358 version = avio_r8(pb); /* version */
6359 avio_rb24(pb); /* flags */
6361 info = av_encryption_init_info_alloc(/* system_id_size */ 16, /* num_key_ids */ 0,
6362 /* key_id_size */ 16, /* data_size */ 0);
6364 return AVERROR(ENOMEM);
6366 if ((ret = ffio_read_size(pb, info->system_id, 16)) < 0) {
6367 av_log(c->fc, AV_LOG_ERROR, "Failed to read the system id\n");
6372 kid_count = avio_rb32(pb);
6373 if (kid_count >= INT_MAX / sizeof(*key_ids)) {
6374 ret = AVERROR(ENOMEM);
6378 for (unsigned int i = 0; i < kid_count && !pb->eof_reached; i++) {
6379 unsigned int min_kid_count = FFMIN(FFMAX(i + 1, 1024), kid_count);
6380 key_ids = av_fast_realloc(info->key_ids, &alloc_size,
6381 min_kid_count * sizeof(*key_ids));
6383 ret = AVERROR(ENOMEM);
6386 info->key_ids = key_ids;
6388 info->key_ids[i] = av_mallocz(16);
6389 if (!info->key_ids[i]) {
6390 ret = AVERROR(ENOMEM);
6393 info->num_key_ids = i + 1;
6395 if ((ret = ffio_read_size(pb, info->key_ids[i], 16)) < 0) {
6396 av_log(c->fc, AV_LOG_ERROR, "Failed to read the key id\n");
6401 if (pb->eof_reached) {
6402 av_log(c->fc, AV_LOG_ERROR, "Hit EOF while reading pssh\n");
6403 ret = AVERROR_INVALIDDATA;
6408 extra_data_size = avio_rb32(pb);
6409 ret = mov_try_read_block(pb, extra_data_size, &extra_data);
6413 av_freep(&info->data); // malloc(0) may still allocate something.
6414 info->data = extra_data;
6415 info->data_size = extra_data_size;
6417 // If there is existing initialization data, append to the list.
6418 old_side_data = av_stream_get_side_data(st, AV_PKT_DATA_ENCRYPTION_INIT_INFO, &old_side_data_size);
6419 if (old_side_data) {
6420 old_init_info = av_encryption_init_info_get_side_data(old_side_data, old_side_data_size);
6421 if (old_init_info) {
6422 // Append to the end of the list.
6423 for (AVEncryptionInitInfo *cur = old_init_info;; cur = cur->next) {
6429 info = old_init_info;
6431 // Assume existing side-data will be valid, so the only error we could get is OOM.
6432 ret = AVERROR(ENOMEM);
6437 side_data = av_encryption_init_info_add_side_data(info, &side_data_size);
6439 ret = AVERROR(ENOMEM);
6442 ret = av_stream_add_side_data(st, AV_PKT_DATA_ENCRYPTION_INIT_INFO,
6443 side_data, side_data_size);
6448 av_encryption_init_info_free(info);
6452 static int mov_read_schm(MOVContext *c, AVIOContext *pb, MOVAtom atom)
6455 MOVStreamContext *sc;
6457 if (c->fc->nb_streams < 1)
6459 st = c->fc->streams[c->fc->nb_streams-1];
6462 if (sc->pseudo_stream_id != 0) {
6463 av_log(c->fc, AV_LOG_ERROR, "schm boxes are only supported in first sample descriptor\n");
6464 return AVERROR_PATCHWELCOME;
6468 return AVERROR_INVALIDDATA;
6470 avio_rb32(pb); /* version and flags */
6472 if (!sc->cenc.default_encrypted_sample) {
6473 sc->cenc.default_encrypted_sample = av_encryption_info_alloc(0, 16, 16);
6474 if (!sc->cenc.default_encrypted_sample) {
6475 return AVERROR(ENOMEM);
6479 sc->cenc.default_encrypted_sample->scheme = avio_rb32(pb);
6483 static int mov_read_tenc(MOVContext *c, AVIOContext *pb, MOVAtom atom)
6486 MOVStreamContext *sc;
6487 unsigned int version, pattern, is_protected, iv_size;
6489 if (c->fc->nb_streams < 1)
6491 st = c->fc->streams[c->fc->nb_streams-1];
6494 if (sc->pseudo_stream_id != 0) {
6495 av_log(c->fc, AV_LOG_ERROR, "tenc atom are only supported in first sample descriptor\n");
6496 return AVERROR_PATCHWELCOME;
6499 if (!sc->cenc.default_encrypted_sample) {
6500 sc->cenc.default_encrypted_sample = av_encryption_info_alloc(0, 16, 16);
6501 if (!sc->cenc.default_encrypted_sample) {
6502 return AVERROR(ENOMEM);
6507 return AVERROR_INVALIDDATA;
6509 version = avio_r8(pb); /* version */
6510 avio_rb24(pb); /* flags */
6512 avio_r8(pb); /* reserved */
6513 pattern = avio_r8(pb);
6516 sc->cenc.default_encrypted_sample->crypt_byte_block = pattern >> 4;
6517 sc->cenc.default_encrypted_sample->skip_byte_block = pattern & 0xf;
6520 is_protected = avio_r8(pb);
6521 if (is_protected && !sc->cenc.encryption_index) {
6522 // The whole stream should be by-default encrypted.
6523 sc->cenc.encryption_index = av_mallocz(sizeof(MOVEncryptionIndex));
6524 if (!sc->cenc.encryption_index)
6525 return AVERROR(ENOMEM);
6527 sc->cenc.per_sample_iv_size = avio_r8(pb);
6528 if (sc->cenc.per_sample_iv_size != 0 && sc->cenc.per_sample_iv_size != 8 &&
6529 sc->cenc.per_sample_iv_size != 16) {
6530 av_log(c->fc, AV_LOG_ERROR, "invalid per-sample IV size value\n");
6531 return AVERROR_INVALIDDATA;
6533 if (avio_read(pb, sc->cenc.default_encrypted_sample->key_id, 16) != 16) {
6534 av_log(c->fc, AV_LOG_ERROR, "failed to read the default key ID\n");
6535 return AVERROR_INVALIDDATA;
6538 if (is_protected && !sc->cenc.per_sample_iv_size) {
6539 iv_size = avio_r8(pb);
6540 if (iv_size != 8 && iv_size != 16) {
6541 av_log(c->fc, AV_LOG_ERROR, "invalid default_constant_IV_size in tenc atom\n");
6542 return AVERROR_INVALIDDATA;
6545 if (avio_read(pb, sc->cenc.default_encrypted_sample->iv, iv_size) != iv_size) {
6546 av_log(c->fc, AV_LOG_ERROR, "failed to read the default IV\n");
6547 return AVERROR_INVALIDDATA;
6554 static int mov_read_dfla(MOVContext *c, AVIOContext *pb, MOVAtom atom)
6557 int last, type, size, ret;
6560 if (c->fc->nb_streams < 1)
6562 st = c->fc->streams[c->fc->nb_streams-1];
6564 if ((uint64_t)atom.size > (1<<30) || atom.size < 42)
6565 return AVERROR_INVALIDDATA;
6567 /* Check FlacSpecificBox version. */
6568 if (avio_r8(pb) != 0)
6569 return AVERROR_INVALIDDATA;
6571 avio_rb24(pb); /* Flags */
6573 avio_read(pb, buf, sizeof(buf));
6574 flac_parse_block_header(buf, &last, &type, &size);
6576 if (type != FLAC_METADATA_TYPE_STREAMINFO || size != FLAC_STREAMINFO_SIZE) {
6577 av_log(c->fc, AV_LOG_ERROR, "STREAMINFO must be first FLACMetadataBlock\n");
6578 return AVERROR_INVALIDDATA;
6581 ret = ff_get_extradata(c->fc, st->codecpar, pb, size);
6586 av_log(c->fc, AV_LOG_WARNING, "non-STREAMINFO FLACMetadataBlock(s) ignored\n");
6591 static int cenc_decrypt(MOVContext *c, MOVStreamContext *sc, AVEncryptionInfo *sample, uint8_t *input, int size)
6595 if (sample->scheme != MKBETAG('c','e','n','c') || sample->crypt_byte_block != 0 || sample->skip_byte_block != 0) {
6596 av_log(c->fc, AV_LOG_ERROR, "Only the 'cenc' encryption scheme is supported\n");
6597 return AVERROR_PATCHWELCOME;
6600 if (!sc->cenc.aes_ctr) {
6601 /* initialize the cipher */
6602 sc->cenc.aes_ctr = av_aes_ctr_alloc();
6603 if (!sc->cenc.aes_ctr) {
6604 return AVERROR(ENOMEM);
6607 ret = av_aes_ctr_init(sc->cenc.aes_ctr, c->decryption_key);
6613 av_aes_ctr_set_full_iv(sc->cenc.aes_ctr, sample->iv);
6615 if (!sample->subsample_count) {
6616 /* decrypt the whole packet */
6617 av_aes_ctr_crypt(sc->cenc.aes_ctr, input, input, size);
6621 for (i = 0; i < sample->subsample_count; i++) {
6622 if (sample->subsamples[i].bytes_of_clear_data + sample->subsamples[i].bytes_of_protected_data > size) {
6623 av_log(c->fc, AV_LOG_ERROR, "subsample size exceeds the packet size left\n");
6624 return AVERROR_INVALIDDATA;
6627 /* skip the clear bytes */
6628 input += sample->subsamples[i].bytes_of_clear_data;
6629 size -= sample->subsamples[i].bytes_of_clear_data;
6631 /* decrypt the encrypted bytes */
6632 av_aes_ctr_crypt(sc->cenc.aes_ctr, input, input, sample->subsamples[i].bytes_of_protected_data);
6633 input += sample->subsamples[i].bytes_of_protected_data;
6634 size -= sample->subsamples[i].bytes_of_protected_data;
6638 av_log(c->fc, AV_LOG_ERROR, "leftover packet bytes after subsample processing\n");
6639 return AVERROR_INVALIDDATA;
6645 static int cenc_filter(MOVContext *mov, AVStream* st, MOVStreamContext *sc, AVPacket *pkt, int current_index)
6647 MOVFragmentStreamInfo *frag_stream_info;
6648 MOVEncryptionIndex *encryption_index;
6649 AVEncryptionInfo *encrypted_sample;
6650 int encrypted_index, ret;
6652 frag_stream_info = get_frag_stream_info(&mov->frag_index, mov->frag_index.current, st->id);
6653 encrypted_index = current_index;
6654 encryption_index = NULL;
6655 if (frag_stream_info) {
6656 // Note this only supports encryption info in the first sample descriptor.
6657 if (mov->fragment.stsd_id == 1) {
6658 if (frag_stream_info->encryption_index) {
6659 encrypted_index = current_index - frag_stream_info->index_entry;
6660 encryption_index = frag_stream_info->encryption_index;
6662 encryption_index = sc->cenc.encryption_index;
6666 encryption_index = sc->cenc.encryption_index;
6669 if (encryption_index) {
6670 if (encryption_index->auxiliary_info_sample_count &&
6671 !encryption_index->nb_encrypted_samples) {
6672 av_log(mov->fc, AV_LOG_ERROR, "saiz atom found without saio\n");
6673 return AVERROR_INVALIDDATA;
6675 if (encryption_index->auxiliary_offsets_count &&
6676 !encryption_index->nb_encrypted_samples) {
6677 av_log(mov->fc, AV_LOG_ERROR, "saio atom found without saiz\n");
6678 return AVERROR_INVALIDDATA;
6681 if (!encryption_index->nb_encrypted_samples) {
6682 // Full-sample encryption with default settings.
6683 encrypted_sample = sc->cenc.default_encrypted_sample;
6684 } else if (encrypted_index >= 0 && encrypted_index < encryption_index->nb_encrypted_samples) {
6685 // Per-sample setting override.
6686 encrypted_sample = encryption_index->encrypted_samples[encrypted_index];
6688 av_log(mov->fc, AV_LOG_ERROR, "Incorrect number of samples in encryption info\n");
6689 return AVERROR_INVALIDDATA;
6692 if (mov->decryption_key) {
6693 return cenc_decrypt(mov, sc, encrypted_sample, pkt->data, pkt->size);
6696 uint8_t *side_data = av_encryption_info_add_side_data(encrypted_sample, &size);
6698 return AVERROR(ENOMEM);
6699 ret = av_packet_add_side_data(pkt, AV_PKT_DATA_ENCRYPTION_INFO, side_data, size);
6709 static int mov_read_dops(MOVContext *c, AVIOContext *pb, MOVAtom atom)
6711 const int OPUS_SEEK_PREROLL_MS = 80;
6717 if (c->fc->nb_streams < 1)
6719 st = c->fc->streams[c->fc->nb_streams-1];
6721 if ((uint64_t)atom.size > (1<<30) || atom.size < 11)
6722 return AVERROR_INVALIDDATA;
6724 /* Check OpusSpecificBox version. */
6725 if (avio_r8(pb) != 0) {
6726 av_log(c->fc, AV_LOG_ERROR, "unsupported OpusSpecificBox version\n");
6727 return AVERROR_INVALIDDATA;
6730 /* OpusSpecificBox size plus magic for Ogg OpusHead header. */
6731 size = atom.size + 8;
6733 if ((ret = ff_alloc_extradata(st->codecpar, size)) < 0)
6736 AV_WL32(st->codecpar->extradata, MKTAG('O','p','u','s'));
6737 AV_WL32(st->codecpar->extradata + 4, MKTAG('H','e','a','d'));
6738 AV_WB8(st->codecpar->extradata + 8, 1); /* OpusHead version */
6739 avio_read(pb, st->codecpar->extradata + 9, size - 9);
6741 /* OpusSpecificBox is stored in big-endian, but OpusHead is
6742 little-endian; aside from the preceeding magic and version they're
6743 otherwise currently identical. Data after output gain at offset 16
6744 doesn't need to be bytewapped. */
6745 pre_skip = AV_RB16(st->codecpar->extradata + 10);
6746 AV_WL16(st->codecpar->extradata + 10, pre_skip);
6747 AV_WL32(st->codecpar->extradata + 12, AV_RB32(st->codecpar->extradata + 12));
6748 AV_WL16(st->codecpar->extradata + 16, AV_RB16(st->codecpar->extradata + 16));
6750 st->codecpar->initial_padding = pre_skip;
6751 st->codecpar->seek_preroll = av_rescale_q(OPUS_SEEK_PREROLL_MS,
6752 (AVRational){1, 1000},
6753 (AVRational){1, 48000});
6758 static int mov_read_dmlp(MOVContext *c, AVIOContext *pb, MOVAtom atom)
6761 unsigned format_info;
6762 int channel_assignment, channel_assignment1, channel_assignment2;
6765 if (c->fc->nb_streams < 1)
6767 st = c->fc->streams[c->fc->nb_streams-1];
6770 return AVERROR_INVALIDDATA;
6772 format_info = avio_rb32(pb);
6774 ratebits = (format_info >> 28) & 0xF;
6775 channel_assignment1 = (format_info >> 15) & 0x1F;
6776 channel_assignment2 = format_info & 0x1FFF;
6777 if (channel_assignment2)
6778 channel_assignment = channel_assignment2;
6780 channel_assignment = channel_assignment1;
6782 st->codecpar->frame_size = 40 << (ratebits & 0x7);
6783 st->codecpar->sample_rate = mlp_samplerate(ratebits);
6784 st->codecpar->channels = truehd_channels(channel_assignment);
6785 st->codecpar->channel_layout = truehd_layout(channel_assignment);
6790 static int mov_read_dvcc_dvvc(MOVContext *c, AVIOContext *pb, MOVAtom atom)
6794 AVDOVIDecoderConfigurationRecord *dovi;
6798 if (c->fc->nb_streams < 1)
6800 st = c->fc->streams[c->fc->nb_streams-1];
6802 if ((uint64_t)atom.size > (1<<30) || atom.size < 4)
6803 return AVERROR_INVALIDDATA;
6805 dovi = av_dovi_alloc(&dovi_size);
6807 return AVERROR(ENOMEM);
6809 dovi->dv_version_major = avio_r8(pb);
6810 dovi->dv_version_minor = avio_r8(pb);
6812 buf = avio_rb16(pb);
6813 dovi->dv_profile = (buf >> 9) & 0x7f; // 7 bits
6814 dovi->dv_level = (buf >> 3) & 0x3f; // 6 bits
6815 dovi->rpu_present_flag = (buf >> 2) & 0x01; // 1 bit
6816 dovi->el_present_flag = (buf >> 1) & 0x01; // 1 bit
6817 dovi->bl_present_flag = buf & 0x01; // 1 bit
6818 if (atom.size >= 24) { // 4 + 4 + 4 * 4
6820 dovi->dv_bl_signal_compatibility_id = (buf >> 4) & 0x0f; // 4 bits
6822 // 0 stands for None
6823 // Dolby Vision V1.2.93 profiles and levels
6824 dovi->dv_bl_signal_compatibility_id = 0;
6827 ret = av_stream_add_side_data(st, AV_PKT_DATA_DOVI_CONF,
6828 (uint8_t *)dovi, dovi_size);
6834 av_log(c, AV_LOG_TRACE, "DOVI in dvcC/dvvC box, version: %d.%d, profile: %d, level: %d, "
6835 "rpu flag: %d, el flag: %d, bl flag: %d, compatibility id: %d\n",
6836 dovi->dv_version_major, dovi->dv_version_minor,
6837 dovi->dv_profile, dovi->dv_level,
6838 dovi->rpu_present_flag,
6839 dovi->el_present_flag,
6840 dovi->bl_present_flag,
6841 dovi->dv_bl_signal_compatibility_id
6847 static const MOVParseTableEntry mov_default_parse_table[] = {
6848 { MKTAG('A','C','L','R'), mov_read_aclr },
6849 { MKTAG('A','P','R','G'), mov_read_avid },
6850 { MKTAG('A','A','L','P'), mov_read_avid },
6851 { MKTAG('A','R','E','S'), mov_read_ares },
6852 { MKTAG('a','v','s','s'), mov_read_avss },
6853 { MKTAG('a','v','1','C'), mov_read_av1c },
6854 { MKTAG('c','h','p','l'), mov_read_chpl },
6855 { MKTAG('c','o','6','4'), mov_read_stco },
6856 { MKTAG('c','o','l','r'), mov_read_colr },
6857 { MKTAG('c','t','t','s'), mov_read_ctts }, /* composition time to sample */
6858 { MKTAG('d','i','n','f'), mov_read_default },
6859 { MKTAG('D','p','x','E'), mov_read_dpxe },
6860 { MKTAG('d','r','e','f'), mov_read_dref },
6861 { MKTAG('e','d','t','s'), mov_read_default },
6862 { MKTAG('e','l','s','t'), mov_read_elst },
6863 { MKTAG('e','n','d','a'), mov_read_enda },
6864 { MKTAG('f','i','e','l'), mov_read_fiel },
6865 { MKTAG('a','d','r','m'), mov_read_adrm },
6866 { MKTAG('f','t','y','p'), mov_read_ftyp },
6867 { MKTAG('g','l','b','l'), mov_read_glbl },
6868 { MKTAG('h','d','l','r'), mov_read_hdlr },
6869 { MKTAG('i','l','s','t'), mov_read_ilst },
6870 { MKTAG('j','p','2','h'), mov_read_jp2h },
6871 { MKTAG('m','d','a','t'), mov_read_mdat },
6872 { MKTAG('m','d','h','d'), mov_read_mdhd },
6873 { MKTAG('m','d','i','a'), mov_read_default },
6874 { MKTAG('m','e','t','a'), mov_read_meta },
6875 { MKTAG('m','i','n','f'), mov_read_default },
6876 { MKTAG('m','o','o','f'), mov_read_moof },
6877 { MKTAG('m','o','o','v'), mov_read_moov },
6878 { MKTAG('m','v','e','x'), mov_read_default },
6879 { MKTAG('m','v','h','d'), mov_read_mvhd },
6880 { MKTAG('S','M','I',' '), mov_read_svq3 },
6881 { MKTAG('a','l','a','c'), mov_read_alac }, /* alac specific atom */
6882 { MKTAG('a','v','c','C'), mov_read_glbl },
6883 { MKTAG('p','a','s','p'), mov_read_pasp },
6884 { MKTAG('s','i','d','x'), mov_read_sidx },
6885 { MKTAG('s','t','b','l'), mov_read_default },
6886 { MKTAG('s','t','c','o'), mov_read_stco },
6887 { MKTAG('s','t','p','s'), mov_read_stps },
6888 { MKTAG('s','t','r','f'), mov_read_strf },
6889 { MKTAG('s','t','s','c'), mov_read_stsc },
6890 { MKTAG('s','t','s','d'), mov_read_stsd }, /* sample description */
6891 { MKTAG('s','t','s','s'), mov_read_stss }, /* sync sample */
6892 { MKTAG('s','t','s','z'), mov_read_stsz }, /* sample size */
6893 { MKTAG('s','t','t','s'), mov_read_stts },
6894 { MKTAG('s','t','z','2'), mov_read_stsz }, /* compact sample size */
6895 { MKTAG('s','d','t','p'), mov_read_sdtp }, /* independent and disposable samples */
6896 { MKTAG('t','k','h','d'), mov_read_tkhd }, /* track header */
6897 { MKTAG('t','f','d','t'), mov_read_tfdt },
6898 { MKTAG('t','f','h','d'), mov_read_tfhd }, /* track fragment header */
6899 { MKTAG('t','r','a','k'), mov_read_trak },
6900 { MKTAG('t','r','a','f'), mov_read_default },
6901 { MKTAG('t','r','e','f'), mov_read_default },
6902 { MKTAG('t','m','c','d'), mov_read_tmcd },
6903 { MKTAG('c','h','a','p'), mov_read_chap },
6904 { MKTAG('t','r','e','x'), mov_read_trex },
6905 { MKTAG('t','r','u','n'), mov_read_trun },
6906 { MKTAG('u','d','t','a'), mov_read_default },
6907 { MKTAG('w','a','v','e'), mov_read_wave },
6908 { MKTAG('e','s','d','s'), mov_read_esds },
6909 { MKTAG('d','a','c','3'), mov_read_dac3 }, /* AC-3 info */
6910 { MKTAG('d','e','c','3'), mov_read_dec3 }, /* EAC-3 info */
6911 { MKTAG('d','d','t','s'), mov_read_ddts }, /* DTS audio descriptor */
6912 { MKTAG('w','i','d','e'), mov_read_wide }, /* place holder */
6913 { MKTAG('w','f','e','x'), mov_read_wfex },
6914 { MKTAG('c','m','o','v'), mov_read_cmov },
6915 { MKTAG('c','h','a','n'), mov_read_chan }, /* channel layout */
6916 { MKTAG('d','v','c','1'), mov_read_dvc1 },
6917 { MKTAG('s','b','g','p'), mov_read_sbgp },
6918 { MKTAG('h','v','c','C'), mov_read_glbl },
6919 { MKTAG('u','u','i','d'), mov_read_uuid },
6920 { MKTAG('C','i','n', 0x8e), mov_read_targa_y216 },
6921 { MKTAG('f','r','e','e'), mov_read_free },
6922 { MKTAG('-','-','-','-'), mov_read_custom },
6923 { MKTAG('s','i','n','f'), mov_read_default },
6924 { MKTAG('f','r','m','a'), mov_read_frma },
6925 { MKTAG('s','e','n','c'), mov_read_senc },
6926 { MKTAG('s','a','i','z'), mov_read_saiz },
6927 { MKTAG('s','a','i','o'), mov_read_saio },
6928 { MKTAG('p','s','s','h'), mov_read_pssh },
6929 { MKTAG('s','c','h','m'), mov_read_schm },
6930 { MKTAG('s','c','h','i'), mov_read_default },
6931 { MKTAG('t','e','n','c'), mov_read_tenc },
6932 { MKTAG('d','f','L','a'), mov_read_dfla },
6933 { MKTAG('s','t','3','d'), mov_read_st3d }, /* stereoscopic 3D video box */
6934 { MKTAG('s','v','3','d'), mov_read_sv3d }, /* spherical video box */
6935 { MKTAG('d','O','p','s'), mov_read_dops },
6936 { MKTAG('d','m','l','p'), mov_read_dmlp },
6937 { MKTAG('S','m','D','m'), mov_read_smdm },
6938 { MKTAG('C','o','L','L'), mov_read_coll },
6939 { MKTAG('v','p','c','C'), mov_read_vpcc },
6940 { MKTAG('m','d','c','v'), mov_read_mdcv },
6941 { MKTAG('c','l','l','i'), mov_read_clli },
6942 { MKTAG('d','v','c','C'), mov_read_dvcc_dvvc },
6943 { MKTAG('d','v','v','C'), mov_read_dvcc_dvvc },
6947 static int mov_read_default(MOVContext *c, AVIOContext *pb, MOVAtom atom)
6949 int64_t total_size = 0;
6953 if (c->atom_depth > 10) {
6954 av_log(c->fc, AV_LOG_ERROR, "Atoms too deeply nested\n");
6955 return AVERROR_INVALIDDATA;
6960 atom.size = INT64_MAX;
6961 while (total_size <= atom.size - 8 && !avio_feof(pb)) {
6962 int (*parse)(MOVContext*, AVIOContext*, MOVAtom) = NULL;
6965 if (atom.size >= 8) {
6966 a.size = avio_rb32(pb);
6967 a.type = avio_rl32(pb);
6968 if (((a.type == MKTAG('f','r','e','e') && c->moov_retry) ||
6969 a.type == MKTAG('h','o','o','v')) &&
6971 c->fc->strict_std_compliance < FF_COMPLIANCE_STRICT) {
6974 type = avio_rl32(pb);
6977 avio_seek(pb, -8, SEEK_CUR);
6978 if (type == MKTAG('m','v','h','d') ||
6979 type == MKTAG('c','m','o','v')) {
6980 av_log(c->fc, AV_LOG_ERROR, "Detected moov in a free or hoov atom.\n");
6981 a.type = MKTAG('m','o','o','v');
6984 if (atom.type != MKTAG('r','o','o','t') &&
6985 atom.type != MKTAG('m','o','o','v')) {
6986 if (a.type == MKTAG('t','r','a','k') ||
6987 a.type == MKTAG('m','d','a','t')) {
6988 av_log(c->fc, AV_LOG_ERROR, "Broken file, trak/mdat not at top-level\n");
6995 if (a.size == 1 && total_size + 8 <= atom.size) { /* 64 bit extended size */
6996 a.size = avio_rb64(pb) - 8;
7000 av_log(c->fc, AV_LOG_TRACE, "type:'%s' parent:'%s' sz: %"PRId64" %"PRId64" %"PRId64"\n",
7001 av_fourcc2str(a.type), av_fourcc2str(atom.type), a.size, total_size, atom.size);
7003 a.size = atom.size - total_size + 8;
7008 a.size = FFMIN(a.size, atom.size - total_size);
7010 for (i = 0; mov_default_parse_table[i].type; i++)
7011 if (mov_default_parse_table[i].type == a.type) {
7012 parse = mov_default_parse_table[i].parse;
7016 // container is user data
7017 if (!parse && (atom.type == MKTAG('u','d','t','a') ||
7018 atom.type == MKTAG('i','l','s','t')))
7019 parse = mov_read_udta_string;
7021 // Supports parsing the QuickTime Metadata Keys.
7022 // https://developer.apple.com/library/mac/documentation/QuickTime/QTFF/Metadata/Metadata.html
7023 if (!parse && c->found_hdlr_mdta &&
7024 atom.type == MKTAG('m','e','t','a') &&
7025 a.type == MKTAG('k','e','y','s') &&
7026 c->meta_keys_count == 0) {
7027 parse = mov_read_keys;
7030 if (!parse) { /* skip leaf atoms data */
7031 avio_skip(pb, a.size);
7033 int64_t start_pos = avio_tell(pb);
7035 int err = parse(c, pb, a);
7040 if (c->found_moov && c->found_mdat && a.size <= INT64_MAX - start_pos &&
7041 ((!(pb->seekable & AVIO_SEEKABLE_NORMAL) || c->fc->flags & AVFMT_FLAG_IGNIDX || c->frag_index.complete) ||
7042 start_pos + a.size == avio_size(pb))) {
7043 if (!(pb->seekable & AVIO_SEEKABLE_NORMAL) || c->fc->flags & AVFMT_FLAG_IGNIDX || c->frag_index.complete)
7044 c->next_root_atom = start_pos + a.size;
7048 left = a.size - avio_tell(pb) + start_pos;
7049 if (left > 0) /* skip garbage at atom end */
7050 avio_skip(pb, left);
7051 else if (left < 0) {
7052 av_log(c->fc, AV_LOG_WARNING,
7053 "overread end of atom '%s' by %"PRId64" bytes\n",
7054 av_fourcc2str(a.type), -left);
7055 avio_seek(pb, left, SEEK_CUR);
7059 total_size += a.size;
7062 if (total_size < atom.size && atom.size < 0x7ffff)
7063 avio_skip(pb, atom.size - total_size);
7069 static int mov_probe(const AVProbeData *p)
7074 int moov_offset = -1;
7076 /* check file header */
7081 /* ignore invalid offset */
7082 if ((offset + 8ULL) > (unsigned int)p->buf_size)
7084 size = AV_RB32(p->buf + offset);
7085 if (size == 1 && offset + 16 <= (unsigned int)p->buf_size) {
7086 size = AV_RB64(p->buf+offset + 8);
7088 } else if (size == 0) {
7089 size = p->buf_size - offset;
7091 if (size < minsize) {
7095 tag = AV_RL32(p->buf + offset + 4);
7097 /* check for obvious tags */
7098 case MKTAG('m','o','o','v'):
7099 moov_offset = offset + 4;
7100 case MKTAG('m','d','a','t'):
7101 case MKTAG('p','n','o','t'): /* detect movs with preview pics like ew.mov and april.mov */
7102 case MKTAG('u','d','t','a'): /* Packet Video PVAuthor adds this and a lot of more junk */
7103 case MKTAG('f','t','y','p'):
7104 if (tag == MKTAG('f','t','y','p') &&
7105 ( AV_RL32(p->buf + offset + 8) == MKTAG('j','p','2',' ')
7106 || AV_RL32(p->buf + offset + 8) == MKTAG('j','p','x',' ')
7108 score = FFMAX(score, 5);
7110 score = AVPROBE_SCORE_MAX;
7113 /* those are more common words, so rate then a bit less */
7114 case MKTAG('e','d','i','w'): /* xdcam files have reverted first tags */
7115 case MKTAG('w','i','d','e'):
7116 case MKTAG('f','r','e','e'):
7117 case MKTAG('j','u','n','k'):
7118 case MKTAG('p','i','c','t'):
7119 score = FFMAX(score, AVPROBE_SCORE_MAX - 5);
7121 case MKTAG(0x82,0x82,0x7f,0x7d):
7122 case MKTAG('s','k','i','p'):
7123 case MKTAG('u','u','i','d'):
7124 case MKTAG('p','r','f','l'):
7125 /* if we only find those cause probedata is too small at least rate them */
7126 score = FFMAX(score, AVPROBE_SCORE_EXTENSION);
7129 if (size > INT64_MAX - offset)
7133 if (score > AVPROBE_SCORE_MAX - 50 && moov_offset != -1) {
7134 /* moov atom in the header - we should make sure that this is not a
7135 * MOV-packed MPEG-PS */
7136 offset = moov_offset;
7138 while (offset < (p->buf_size - 16)) { /* Sufficient space */
7139 /* We found an actual hdlr atom */
7140 if (AV_RL32(p->buf + offset ) == MKTAG('h','d','l','r') &&
7141 AV_RL32(p->buf + offset + 8) == MKTAG('m','h','l','r') &&
7142 AV_RL32(p->buf + offset + 12) == MKTAG('M','P','E','G')) {
7143 av_log(NULL, AV_LOG_WARNING, "Found media data tag MPEG indicating this is a MOV-packed MPEG-PS.\n");
7144 /* We found a media handler reference atom describing an
7145 * MPEG-PS-in-MOV, return a
7146 * low score to force expanding the probe window until
7147 * mpegps_probe finds what it needs */
7159 // must be done after parsing all trak because there's no order requirement
7160 static void mov_read_chapters(AVFormatContext *s)
7162 MOVContext *mov = s->priv_data;
7164 MOVStreamContext *sc;
7169 for (j = 0; j < mov->nb_chapter_tracks; j++) {
7170 chapter_track = mov->chapter_tracks[j];
7172 for (i = 0; i < s->nb_streams; i++)
7173 if (s->streams[i]->id == chapter_track) {
7178 av_log(s, AV_LOG_ERROR, "Referenced QT chapter track not found\n");
7183 cur_pos = avio_tell(sc->pb);
7185 if (st->codecpar->codec_type == AVMEDIA_TYPE_VIDEO) {
7186 st->disposition |= AV_DISPOSITION_ATTACHED_PIC | AV_DISPOSITION_TIMED_THUMBNAILS;
7187 if (st->internal->nb_index_entries) {
7188 // Retrieve the first frame, if possible
7189 AVIndexEntry *sample = &st->internal->index_entries[0];
7190 if (avio_seek(sc->pb, sample->pos, SEEK_SET) != sample->pos) {
7191 av_log(s, AV_LOG_ERROR, "Failed to retrieve first frame\n");
7195 if (ff_add_attached_pic(s, st, sc->pb, NULL, sample->size) < 0)
7199 st->codecpar->codec_type = AVMEDIA_TYPE_DATA;
7200 st->codecpar->codec_id = AV_CODEC_ID_BIN_DATA;
7201 st->discard = AVDISCARD_ALL;
7202 for (i = 0; i < st->internal->nb_index_entries; i++) {
7203 AVIndexEntry *sample = &st->internal->index_entries[i];
7204 int64_t end = i+1 < st->internal->nb_index_entries ? st->internal->index_entries[i+1].timestamp : st->duration;
7209 if (end < sample->timestamp) {
7210 av_log(s, AV_LOG_WARNING, "ignoring stream duration which is shorter than chapters\n");
7211 end = AV_NOPTS_VALUE;
7214 if (avio_seek(sc->pb, sample->pos, SEEK_SET) != sample->pos) {
7215 av_log(s, AV_LOG_ERROR, "Chapter %d not found in file\n", i);
7219 // the first two bytes are the length of the title
7220 len = avio_rb16(sc->pb);
7221 if (len > sample->size-2)
7223 title_len = 2*len + 1;
7224 if (!(title = av_mallocz(title_len)))
7227 // The samples could theoretically be in any encoding if there's an encd
7228 // atom following, but in practice are only utf-8 or utf-16, distinguished
7229 // instead by the presence of a BOM
7233 ch = avio_rb16(sc->pb);
7235 avio_get_str16be(sc->pb, len, title, title_len);
7236 else if (ch == 0xfffe)
7237 avio_get_str16le(sc->pb, len, title, title_len);
7240 if (len == 1 || len == 2)
7243 avio_get_str(sc->pb, INT_MAX, title + 2, len - 1);
7247 avpriv_new_chapter(s, i, st->time_base, sample->timestamp, end, title);
7252 avio_seek(sc->pb, cur_pos, SEEK_SET);
7256 static int parse_timecode_in_framenum_format(AVFormatContext *s, AVStream *st,
7257 uint32_t value, int flags)
7260 char buf[AV_TIMECODE_STR_SIZE];
7261 AVRational rate = st->avg_frame_rate;
7262 int ret = av_timecode_init(&tc, rate, flags, 0, s);
7265 av_dict_set(&st->metadata, "timecode",
7266 av_timecode_make_string(&tc, buf, value), 0);
7270 static int mov_read_rtmd_track(AVFormatContext *s, AVStream *st)
7272 MOVStreamContext *sc = st->priv_data;
7273 char buf[AV_TIMECODE_STR_SIZE];
7274 int64_t cur_pos = avio_tell(sc->pb);
7275 int hh, mm, ss, ff, drop;
7277 if (!st->internal->nb_index_entries)
7280 avio_seek(sc->pb, st->internal->index_entries->pos, SEEK_SET);
7281 avio_skip(s->pb, 13);
7282 hh = avio_r8(s->pb);
7283 mm = avio_r8(s->pb);
7284 ss = avio_r8(s->pb);
7285 drop = avio_r8(s->pb);
7286 ff = avio_r8(s->pb);
7287 snprintf(buf, AV_TIMECODE_STR_SIZE, "%02d:%02d:%02d%c%02d",
7288 hh, mm, ss, drop ? ';' : ':', ff);
7289 av_dict_set(&st->metadata, "timecode", buf, 0);
7291 avio_seek(sc->pb, cur_pos, SEEK_SET);
7295 static int mov_read_timecode_track(AVFormatContext *s, AVStream *st)
7297 MOVStreamContext *sc = st->priv_data;
7299 int64_t cur_pos = avio_tell(sc->pb);
7302 if (!st->internal->nb_index_entries)
7305 avio_seek(sc->pb, st->internal->index_entries->pos, SEEK_SET);
7306 value = avio_rb32(s->pb);
7308 if (sc->tmcd_flags & 0x0001) flags |= AV_TIMECODE_FLAG_DROPFRAME;
7309 if (sc->tmcd_flags & 0x0002) flags |= AV_TIMECODE_FLAG_24HOURSMAX;
7310 if (sc->tmcd_flags & 0x0004) flags |= AV_TIMECODE_FLAG_ALLOWNEGATIVE;
7312 /* Assume Counter flag is set to 1 in tmcd track (even though it is likely
7313 * not the case) and thus assume "frame number format" instead of QT one.
7314 * No sample with tmcd track can be found with a QT timecode at the moment,
7315 * despite what the tmcd track "suggests" (Counter flag set to 0 means QT
7317 parse_timecode_in_framenum_format(s, st, value, flags);
7319 avio_seek(sc->pb, cur_pos, SEEK_SET);
7323 static void mov_free_encryption_index(MOVEncryptionIndex **index) {
7325 if (!index || !*index) return;
7326 for (i = 0; i < (*index)->nb_encrypted_samples; i++) {
7327 av_encryption_info_free((*index)->encrypted_samples[i]);
7329 av_freep(&(*index)->encrypted_samples);
7330 av_freep(&(*index)->auxiliary_info_sizes);
7331 av_freep(&(*index)->auxiliary_offsets);
7335 static int mov_read_close(AVFormatContext *s)
7337 MOVContext *mov = s->priv_data;
7340 for (i = 0; i < s->nb_streams; i++) {
7341 AVStream *st = s->streams[i];
7342 MOVStreamContext *sc = st->priv_data;
7347 av_freep(&sc->ctts_data);
7348 for (j = 0; j < sc->drefs_count; j++) {
7349 av_freep(&sc->drefs[j].path);
7350 av_freep(&sc->drefs[j].dir);
7352 av_freep(&sc->drefs);
7354 sc->drefs_count = 0;
7356 if (!sc->pb_is_copied)
7357 ff_format_io_close(s, &sc->pb);
7360 av_freep(&sc->chunk_offsets);
7361 av_freep(&sc->stsc_data);
7362 av_freep(&sc->sample_sizes);
7363 av_freep(&sc->keyframes);
7364 av_freep(&sc->stts_data);
7365 av_freep(&sc->sdtp_data);
7366 av_freep(&sc->stps_data);
7367 av_freep(&sc->elst_data);
7368 av_freep(&sc->rap_group);
7369 av_freep(&sc->display_matrix);
7370 av_freep(&sc->index_ranges);
7373 for (j = 0; j < sc->stsd_count; j++)
7374 av_free(sc->extradata[j]);
7375 av_freep(&sc->extradata);
7376 av_freep(&sc->extradata_size);
7378 mov_free_encryption_index(&sc->cenc.encryption_index);
7379 av_encryption_info_free(sc->cenc.default_encrypted_sample);
7380 av_aes_ctr_free(sc->cenc.aes_ctr);
7382 av_freep(&sc->stereo3d);
7383 av_freep(&sc->spherical);
7384 av_freep(&sc->mastering);
7385 av_freep(&sc->coll);
7388 av_freep(&mov->dv_demux);
7389 avformat_free_context(mov->dv_fctx);
7390 mov->dv_fctx = NULL;
7392 if (mov->meta_keys) {
7393 for (i = 1; i < mov->meta_keys_count; i++) {
7394 av_freep(&mov->meta_keys[i]);
7396 av_freep(&mov->meta_keys);
7399 av_freep(&mov->trex_data);
7400 av_freep(&mov->bitrates);
7402 for (i = 0; i < mov->frag_index.nb_items; i++) {
7403 MOVFragmentStreamInfo *frag = mov->frag_index.item[i].stream_info;
7404 for (j = 0; j < mov->frag_index.item[i].nb_stream_info; j++) {
7405 mov_free_encryption_index(&frag[j].encryption_index);
7407 av_freep(&mov->frag_index.item[i].stream_info);
7409 av_freep(&mov->frag_index.item);
7411 av_freep(&mov->aes_decrypt);
7412 av_freep(&mov->chapter_tracks);
7417 static int tmcd_is_referenced(AVFormatContext *s, int tmcd_id)
7421 for (i = 0; i < s->nb_streams; i++) {
7422 AVStream *st = s->streams[i];
7423 MOVStreamContext *sc = st->priv_data;
7425 if (st->codecpar->codec_type == AVMEDIA_TYPE_VIDEO &&
7426 sc->timecode_track == tmcd_id)
7432 /* look for a tmcd track not referenced by any video track, and export it globally */
7433 static void export_orphan_timecode(AVFormatContext *s)
7437 for (i = 0; i < s->nb_streams; i++) {
7438 AVStream *st = s->streams[i];
7440 if (st->codecpar->codec_tag == MKTAG('t','m','c','d') &&
7441 !tmcd_is_referenced(s, i + 1)) {
7442 AVDictionaryEntry *tcr = av_dict_get(st->metadata, "timecode", NULL, 0);
7444 av_dict_set(&s->metadata, "timecode", tcr->value, 0);
7451 static int read_tfra(MOVContext *mov, AVIOContext *f)
7453 int version, fieldlength, i, j;
7454 int64_t pos = avio_tell(f);
7455 uint32_t size = avio_rb32(f);
7456 unsigned track_id, item_count;
7458 if (avio_rb32(f) != MKBETAG('t', 'f', 'r', 'a')) {
7461 av_log(mov->fc, AV_LOG_VERBOSE, "found tfra\n");
7463 version = avio_r8(f);
7465 track_id = avio_rb32(f);
7466 fieldlength = avio_rb32(f);
7467 item_count = avio_rb32(f);
7468 for (i = 0; i < item_count; i++) {
7469 int64_t time, offset;
7471 MOVFragmentStreamInfo * frag_stream_info;
7474 return AVERROR_INVALIDDATA;
7478 time = avio_rb64(f);
7479 offset = avio_rb64(f);
7481 time = avio_rb32(f);
7482 offset = avio_rb32(f);
7485 // The first sample of each stream in a fragment is always a random
7486 // access sample. So it's entry in the tfra can be used as the
7487 // initial PTS of the fragment.
7488 index = update_frag_index(mov, offset);
7489 frag_stream_info = get_frag_stream_info(&mov->frag_index, index, track_id);
7490 if (frag_stream_info &&
7491 frag_stream_info->first_tfra_pts == AV_NOPTS_VALUE)
7492 frag_stream_info->first_tfra_pts = time;
7494 for (j = 0; j < ((fieldlength >> 4) & 3) + 1; j++)
7496 for (j = 0; j < ((fieldlength >> 2) & 3) + 1; j++)
7498 for (j = 0; j < ((fieldlength >> 0) & 3) + 1; j++)
7502 avio_seek(f, pos + size, SEEK_SET);
7506 static int mov_read_mfra(MOVContext *c, AVIOContext *f)
7508 int64_t stream_size = avio_size(f);
7509 int64_t original_pos = avio_tell(f);
7512 if ((seek_ret = avio_seek(f, stream_size - 4, SEEK_SET)) < 0) {
7516 c->mfra_size = avio_rb32(f);
7517 c->have_read_mfra_size = 1;
7518 if (!c->mfra_size || c->mfra_size > stream_size) {
7519 av_log(c->fc, AV_LOG_DEBUG, "doesn't look like mfra (unreasonable size)\n");
7522 if ((seek_ret = avio_seek(f, -((int64_t) c->mfra_size), SEEK_CUR)) < 0) {
7526 if (avio_rb32(f) != c->mfra_size) {
7527 av_log(c->fc, AV_LOG_DEBUG, "doesn't look like mfra (size mismatch)\n");
7530 if (avio_rb32(f) != MKBETAG('m', 'f', 'r', 'a')) {
7531 av_log(c->fc, AV_LOG_DEBUG, "doesn't look like mfra (tag mismatch)\n");
7534 av_log(c->fc, AV_LOG_VERBOSE, "stream has mfra\n");
7536 ret = read_tfra(c, f);
7541 c->frag_index.complete = 1;
7543 seek_ret = avio_seek(f, original_pos, SEEK_SET);
7545 av_log(c->fc, AV_LOG_ERROR,
7546 "failed to seek back after looking for mfra\n");
7552 static int mov_read_header(AVFormatContext *s)
7554 MOVContext *mov = s->priv_data;
7555 AVIOContext *pb = s->pb;
7557 MOVAtom atom = { AV_RL32("root") };
7560 if (mov->decryption_key_len != 0 && mov->decryption_key_len != AES_CTR_KEY_SIZE) {
7561 av_log(s, AV_LOG_ERROR, "Invalid decryption key len %d expected %d\n",
7562 mov->decryption_key_len, AES_CTR_KEY_SIZE);
7563 return AVERROR(EINVAL);
7567 mov->trak_index = -1;
7568 /* .mov and .mp4 aren't streamable anyway (only progressive download if moov is before mdat) */
7569 if (pb->seekable & AVIO_SEEKABLE_NORMAL)
7570 atom.size = avio_size(pb);
7572 atom.size = INT64_MAX;
7574 /* check MOV header */
7576 if (mov->moov_retry)
7577 avio_seek(pb, 0, SEEK_SET);
7578 if ((err = mov_read_default(mov, pb, atom)) < 0) {
7579 av_log(s, AV_LOG_ERROR, "error reading header\n");
7582 } while ((pb->seekable & AVIO_SEEKABLE_NORMAL) && !mov->found_moov && !mov->moov_retry++);
7583 if (!mov->found_moov) {
7584 av_log(s, AV_LOG_ERROR, "moov atom not found\n");
7585 err = AVERROR_INVALIDDATA;
7588 av_log(mov->fc, AV_LOG_TRACE, "on_parse_exit_offset=%"PRId64"\n", avio_tell(pb));
7590 if (pb->seekable & AVIO_SEEKABLE_NORMAL) {
7591 if (mov->nb_chapter_tracks > 0 && !mov->ignore_chapters)
7592 mov_read_chapters(s);
7593 for (i = 0; i < s->nb_streams; i++)
7594 if (s->streams[i]->codecpar->codec_tag == AV_RL32("tmcd")) {
7595 mov_read_timecode_track(s, s->streams[i]);
7596 } else if (s->streams[i]->codecpar->codec_tag == AV_RL32("rtmd")) {
7597 mov_read_rtmd_track(s, s->streams[i]);
7601 /* copy timecode metadata from tmcd tracks to the related video streams */
7602 for (i = 0; i < s->nb_streams; i++) {
7603 AVStream *st = s->streams[i];
7604 MOVStreamContext *sc = st->priv_data;
7605 if (sc->timecode_track > 0) {
7606 AVDictionaryEntry *tcr;
7607 int tmcd_st_id = -1;
7609 for (j = 0; j < s->nb_streams; j++)
7610 if (s->streams[j]->id == sc->timecode_track)
7613 if (tmcd_st_id < 0 || tmcd_st_id == i)
7615 tcr = av_dict_get(s->streams[tmcd_st_id]->metadata, "timecode", NULL, 0);
7617 av_dict_set(&st->metadata, "timecode", tcr->value, 0);
7620 export_orphan_timecode(s);
7622 for (i = 0; i < s->nb_streams; i++) {
7623 AVStream *st = s->streams[i];
7624 MOVStreamContext *sc = st->priv_data;
7625 fix_timescale(mov, sc);
7626 if (st->codecpar->codec_type == AVMEDIA_TYPE_AUDIO &&
7627 st->codecpar->codec_id == AV_CODEC_ID_AAC) {
7628 st->internal->skip_samples = sc->start_pad;
7630 if (st->codecpar->codec_type == AVMEDIA_TYPE_VIDEO && sc->nb_frames_for_fps > 0 && sc->duration_for_fps > 0)
7631 av_reduce(&st->avg_frame_rate.num, &st->avg_frame_rate.den,
7632 sc->time_scale*(int64_t)sc->nb_frames_for_fps, sc->duration_for_fps, INT_MAX);
7633 if (st->codecpar->codec_type == AVMEDIA_TYPE_SUBTITLE) {
7634 if (st->codecpar->width <= 0 || st->codecpar->height <= 0) {
7635 st->codecpar->width = sc->width;
7636 st->codecpar->height = sc->height;
7638 if (st->codecpar->codec_id == AV_CODEC_ID_DVD_SUBTITLE) {
7639 if ((err = mov_rewrite_dvd_sub_extradata(st)) < 0)
7643 if (mov->handbrake_version &&
7644 mov->handbrake_version <= 1000000*0 + 1000*10 + 2 && // 0.10.2
7645 st->codecpar->codec_id == AV_CODEC_ID_MP3) {
7646 av_log(s, AV_LOG_VERBOSE, "Forcing full parsing for mp3 stream\n");
7647 st->need_parsing = AVSTREAM_PARSE_FULL;
7651 if (mov->trex_data) {
7652 for (i = 0; i < s->nb_streams; i++) {
7653 AVStream *st = s->streams[i];
7654 MOVStreamContext *sc = st->priv_data;
7655 if (st->duration > 0) {
7656 if (sc->data_size > INT64_MAX / sc->time_scale / 8) {
7657 av_log(s, AV_LOG_ERROR, "Overflow during bit rate calculation %"PRId64" * 8 * %d\n",
7658 sc->data_size, sc->time_scale);
7659 err = AVERROR_INVALIDDATA;
7662 st->codecpar->bit_rate = sc->data_size * 8 * sc->time_scale / st->duration;
7667 if (mov->use_mfra_for > 0) {
7668 for (i = 0; i < s->nb_streams; i++) {
7669 AVStream *st = s->streams[i];
7670 MOVStreamContext *sc = st->priv_data;
7671 if (sc->duration_for_fps > 0) {
7672 if (sc->data_size > INT64_MAX / sc->time_scale / 8) {
7673 av_log(s, AV_LOG_ERROR, "Overflow during bit rate calculation %"PRId64" * 8 * %d\n",
7674 sc->data_size, sc->time_scale);
7675 err = AVERROR_INVALIDDATA;
7678 st->codecpar->bit_rate = sc->data_size * 8 * sc->time_scale /
7679 sc->duration_for_fps;
7684 for (i = 0; i < mov->bitrates_count && i < s->nb_streams; i++) {
7685 if (mov->bitrates[i]) {
7686 s->streams[i]->codecpar->bit_rate = mov->bitrates[i];
7690 ff_rfps_calculate(s);
7692 for (i = 0; i < s->nb_streams; i++) {
7693 AVStream *st = s->streams[i];
7694 MOVStreamContext *sc = st->priv_data;
7696 switch (st->codecpar->codec_type) {
7697 case AVMEDIA_TYPE_AUDIO:
7698 err = ff_replaygain_export(st, s->metadata);
7702 case AVMEDIA_TYPE_VIDEO:
7703 if (sc->display_matrix) {
7704 err = av_stream_add_side_data(st, AV_PKT_DATA_DISPLAYMATRIX, (uint8_t*)sc->display_matrix,
7705 sizeof(int32_t) * 9);
7709 sc->display_matrix = NULL;
7712 err = av_stream_add_side_data(st, AV_PKT_DATA_STEREO3D,
7713 (uint8_t *)sc->stereo3d,
7714 sizeof(*sc->stereo3d));
7718 sc->stereo3d = NULL;
7720 if (sc->spherical) {
7721 err = av_stream_add_side_data(st, AV_PKT_DATA_SPHERICAL,
7722 (uint8_t *)sc->spherical,
7723 sc->spherical_size);
7727 sc->spherical = NULL;
7729 if (sc->mastering) {
7730 err = av_stream_add_side_data(st, AV_PKT_DATA_MASTERING_DISPLAY_METADATA,
7731 (uint8_t *)sc->mastering,
7732 sizeof(*sc->mastering));
7736 sc->mastering = NULL;
7739 err = av_stream_add_side_data(st, AV_PKT_DATA_CONTENT_LIGHT_LEVEL,
7740 (uint8_t *)sc->coll,
7750 ff_configure_buffers_for_index(s, AV_TIME_BASE);
7752 for (i = 0; i < mov->frag_index.nb_items; i++)
7753 if (mov->frag_index.item[i].moof_offset <= mov->fragment.moof_offset)
7754 mov->frag_index.item[i].headers_read = 1;
7762 static AVIndexEntry *mov_find_next_sample(AVFormatContext *s, AVStream **st)
7764 AVIndexEntry *sample = NULL;
7765 int64_t best_dts = INT64_MAX;
7767 for (i = 0; i < s->nb_streams; i++) {
7768 AVStream *avst = s->streams[i];
7769 MOVStreamContext *msc = avst->priv_data;
7770 if (msc->pb && msc->current_sample < avst->internal->nb_index_entries) {
7771 AVIndexEntry *current_sample = &avst->internal->index_entries[msc->current_sample];
7772 int64_t dts = av_rescale(current_sample->timestamp, AV_TIME_BASE, msc->time_scale);
7773 av_log(s, AV_LOG_TRACE, "stream %d, sample %d, dts %"PRId64"\n", i, msc->current_sample, dts);
7774 if (!sample || (!(s->pb->seekable & AVIO_SEEKABLE_NORMAL) && current_sample->pos < sample->pos) ||
7775 ((s->pb->seekable & AVIO_SEEKABLE_NORMAL) &&
7776 ((msc->pb != s->pb && dts < best_dts) || (msc->pb == s->pb && dts != AV_NOPTS_VALUE &&
7777 ((FFABS(best_dts - dts) <= AV_TIME_BASE && current_sample->pos < sample->pos) ||
7778 (FFABS(best_dts - dts) > AV_TIME_BASE && dts < best_dts)))))) {
7779 sample = current_sample;
7788 static int should_retry(AVIOContext *pb, int error_code) {
7789 if (error_code == AVERROR_EOF || avio_feof(pb))
7795 static int mov_switch_root(AVFormatContext *s, int64_t target, int index)
7798 MOVContext *mov = s->priv_data;
7800 if (index >= 0 && index < mov->frag_index.nb_items)
7801 target = mov->frag_index.item[index].moof_offset;
7802 if (avio_seek(s->pb, target, SEEK_SET) != target) {
7803 av_log(mov->fc, AV_LOG_ERROR, "root atom offset 0x%"PRIx64": partial file\n", target);
7804 return AVERROR_INVALIDDATA;
7807 mov->next_root_atom = 0;
7808 if (index < 0 || index >= mov->frag_index.nb_items)
7809 index = search_frag_moof_offset(&mov->frag_index, target);
7810 if (index < mov->frag_index.nb_items &&
7811 mov->frag_index.item[index].moof_offset == target) {
7812 if (index + 1 < mov->frag_index.nb_items)
7813 mov->next_root_atom = mov->frag_index.item[index + 1].moof_offset;
7814 if (mov->frag_index.item[index].headers_read)
7816 mov->frag_index.item[index].headers_read = 1;
7819 mov->found_mdat = 0;
7821 ret = mov_read_default(mov, s->pb, (MOVAtom){ AV_RL32("root"), INT64_MAX });
7824 if (avio_feof(s->pb))
7826 av_log(s, AV_LOG_TRACE, "read fragments, offset 0x%"PRIx64"\n", avio_tell(s->pb));
7831 static int mov_change_extradata(MOVStreamContext *sc, AVPacket *pkt)
7833 uint8_t *side, *extradata;
7836 /* Save the current index. */
7837 sc->last_stsd_index = sc->stsc_data[sc->stsc_index].id - 1;
7839 /* Notify the decoder that extradata changed. */
7840 extradata_size = sc->extradata_size[sc->last_stsd_index];
7841 extradata = sc->extradata[sc->last_stsd_index];
7842 if (extradata_size > 0 && extradata) {
7843 side = av_packet_new_side_data(pkt,
7844 AV_PKT_DATA_NEW_EXTRADATA,
7847 return AVERROR(ENOMEM);
7848 memcpy(side, extradata, extradata_size);
7854 static int get_eia608_packet(AVIOContext *pb, AVPacket *pkt, int size)
7859 return AVERROR_INVALIDDATA;
7860 new_size = ((size - 8) / 2) * 3;
7861 ret = av_new_packet(pkt, new_size);
7866 for (int j = 0; j < new_size; j += 3) {
7867 pkt->data[j] = 0xFC;
7868 pkt->data[j+1] = avio_r8(pb);
7869 pkt->data[j+2] = avio_r8(pb);
7875 static int mov_read_packet(AVFormatContext *s, AVPacket *pkt)
7877 MOVContext *mov = s->priv_data;
7878 MOVStreamContext *sc;
7879 AVIndexEntry *sample;
7880 AVStream *st = NULL;
7881 int64_t current_index;
7885 sample = mov_find_next_sample(s, &st);
7886 if (!sample || (mov->next_root_atom && sample->pos > mov->next_root_atom)) {
7887 if (!mov->next_root_atom)
7889 if ((ret = mov_switch_root(s, mov->next_root_atom, -1)) < 0)
7894 /* must be done just before reading, to avoid infinite loop on sample */
7895 current_index = sc->current_index;
7896 mov_current_sample_inc(sc);
7898 if (mov->next_root_atom) {
7899 sample->pos = FFMIN(sample->pos, mov->next_root_atom);
7900 sample->size = FFMIN(sample->size, (mov->next_root_atom - sample->pos));
7903 if (st->discard != AVDISCARD_ALL) {
7904 int64_t ret64 = avio_seek(sc->pb, sample->pos, SEEK_SET);
7905 if (ret64 != sample->pos) {
7906 av_log(mov->fc, AV_LOG_ERROR, "stream %d, offset 0x%"PRIx64": partial file\n",
7907 sc->ffindex, sample->pos);
7908 if (should_retry(sc->pb, ret64)) {
7909 mov_current_sample_dec(sc);
7910 } else if (ret64 < 0) {
7913 return AVERROR_INVALIDDATA;
7916 if (st->discard == AVDISCARD_NONKEY && !(sample->flags & AVINDEX_KEYFRAME)) {
7917 av_log(mov->fc, AV_LOG_DEBUG, "Nonkey frame from stream %d discarded due to AVDISCARD_NONKEY\n", sc->ffindex);
7921 if (st->codecpar->codec_id == AV_CODEC_ID_EIA_608 && sample->size > 8)
7922 ret = get_eia608_packet(sc->pb, pkt, sample->size);
7924 ret = av_get_packet(sc->pb, pkt, sample->size);
7926 if (should_retry(sc->pb, ret)) {
7927 mov_current_sample_dec(sc);
7931 #if CONFIG_DV_DEMUXER
7932 if (mov->dv_demux && sc->dv_audio_container) {
7933 AVBufferRef *buf = pkt->buf;
7934 ret = avpriv_dv_produce_packet(mov->dv_demux, pkt, pkt->data, pkt->size, pkt->pos);
7936 av_packet_unref(pkt);
7939 ret = avpriv_dv_get_packet(mov->dv_demux, pkt);
7944 if (sc->has_palette) {
7947 pal = av_packet_new_side_data(pkt, AV_PKT_DATA_PALETTE, AVPALETTE_SIZE);
7949 av_log(mov->fc, AV_LOG_ERROR, "Cannot append palette to packet\n");
7951 memcpy(pal, sc->palette, AVPALETTE_SIZE);
7952 sc->has_palette = 0;
7955 if (st->codecpar->codec_id == AV_CODEC_ID_MP3 && !st->need_parsing && pkt->size > 4) {
7956 if (ff_mpa_check_header(AV_RB32(pkt->data)) < 0)
7957 st->need_parsing = AVSTREAM_PARSE_FULL;
7961 pkt->stream_index = sc->ffindex;
7962 pkt->dts = sample->timestamp;
7963 if (sample->flags & AVINDEX_DISCARD_FRAME) {
7964 pkt->flags |= AV_PKT_FLAG_DISCARD;
7966 if (sc->ctts_data && sc->ctts_index < sc->ctts_count) {
7967 pkt->pts = pkt->dts + sc->dts_shift + sc->ctts_data[sc->ctts_index].duration;
7968 /* update ctts context */
7970 if (sc->ctts_index < sc->ctts_count &&
7971 sc->ctts_data[sc->ctts_index].count == sc->ctts_sample) {
7973 sc->ctts_sample = 0;
7976 int64_t next_dts = (sc->current_sample < st->internal->nb_index_entries) ?
7977 st->internal->index_entries[sc->current_sample].timestamp : st->duration;
7979 if (next_dts >= pkt->dts)
7980 pkt->duration = next_dts - pkt->dts;
7981 pkt->pts = pkt->dts;
7983 if (st->discard == AVDISCARD_ALL)
7985 if (sc->sdtp_data && sc->current_sample <= sc->sdtp_count) {
7986 uint8_t sample_flags = sc->sdtp_data[sc->current_sample - 1];
7987 uint8_t sample_is_depended_on = (sample_flags >> 2) & 0x3;
7988 pkt->flags |= sample_is_depended_on == MOV_SAMPLE_DEPENDENCY_NO ? AV_PKT_FLAG_DISPOSABLE : 0;
7990 pkt->flags |= sample->flags & AVINDEX_KEYFRAME ? AV_PKT_FLAG_KEY : 0;
7991 pkt->pos = sample->pos;
7993 /* Multiple stsd handling. */
7994 if (sc->stsc_data) {
7995 /* Keep track of the stsc index for the given sample, then check
7996 * if the stsd index is different from the last used one. */
7998 if (mov_stsc_index_valid(sc->stsc_index, sc->stsc_count) &&
7999 mov_get_stsc_samples(sc, sc->stsc_index) == sc->stsc_sample) {
8001 sc->stsc_sample = 0;
8002 /* Do not check indexes after a switch. */
8003 } else if (sc->stsc_data[sc->stsc_index].id > 0 &&
8004 sc->stsc_data[sc->stsc_index].id - 1 < sc->stsd_count &&
8005 sc->stsc_data[sc->stsc_index].id - 1 != sc->last_stsd_index) {
8006 ret = mov_change_extradata(sc, pkt);
8013 aax_filter(pkt->data, pkt->size, mov);
8015 ret = cenc_filter(mov, st, sc, pkt, current_index);
8023 static int mov_seek_fragment(AVFormatContext *s, AVStream *st, int64_t timestamp)
8025 MOVContext *mov = s->priv_data;
8028 if (!mov->frag_index.complete)
8031 index = search_frag_timestamp(&mov->frag_index, st, timestamp);
8034 if (!mov->frag_index.item[index].headers_read)
8035 return mov_switch_root(s, -1, index);
8036 if (index + 1 < mov->frag_index.nb_items)
8037 mov->next_root_atom = mov->frag_index.item[index + 1].moof_offset;
8042 static int mov_seek_stream(AVFormatContext *s, AVStream *st, int64_t timestamp, int flags)
8044 MOVStreamContext *sc = st->priv_data;
8045 int sample, time_sample, ret;
8048 // Here we consider timestamp to be PTS, hence try to offset it so that we
8049 // can search over the DTS timeline.
8050 timestamp -= (sc->min_corrected_pts + sc->dts_shift);
8052 ret = mov_seek_fragment(s, st, timestamp);
8056 sample = av_index_search_timestamp(st, timestamp, flags);
8057 av_log(s, AV_LOG_TRACE, "stream %d, timestamp %"PRId64", sample %d\n", st->index, timestamp, sample);
8058 if (sample < 0 && st->internal->nb_index_entries && timestamp < st->internal->index_entries[0].timestamp)
8060 if (sample < 0) /* not sure what to do */
8061 return AVERROR_INVALIDDATA;
8062 mov_current_sample_set(sc, sample);
8063 av_log(s, AV_LOG_TRACE, "stream %d, found sample %d\n", st->index, sc->current_sample);
8064 /* adjust ctts index */
8065 if (sc->ctts_data) {
8067 for (i = 0; i < sc->ctts_count; i++) {
8068 int next = time_sample + sc->ctts_data[i].count;
8069 if (next > sc->current_sample) {
8071 sc->ctts_sample = sc->current_sample - time_sample;
8078 /* adjust stsd index */
8079 if (sc->chunk_count) {
8081 for (i = 0; i < sc->stsc_count; i++) {
8082 int64_t next = time_sample + mov_get_stsc_samples(sc, i);
8083 if (next > sc->current_sample) {
8085 sc->stsc_sample = sc->current_sample - time_sample;
8088 av_assert0(next == (int)next);
8096 static int64_t mov_get_skip_samples(AVStream *st, int sample)
8098 MOVStreamContext *sc = st->priv_data;
8099 int64_t first_ts = st->internal->index_entries[0].timestamp;
8100 int64_t ts = st->internal->index_entries[sample].timestamp;
8103 if (st->codecpar->codec_type != AVMEDIA_TYPE_AUDIO)
8106 /* compute skip samples according to stream start_pad, seek ts and first ts */
8107 off = av_rescale_q(ts - first_ts, st->time_base,
8108 (AVRational){1, st->codecpar->sample_rate});
8109 return FFMAX(sc->start_pad - off, 0);
8112 static int mov_read_seek(AVFormatContext *s, int stream_index, int64_t sample_time, int flags)
8114 MOVContext *mc = s->priv_data;
8119 if (stream_index >= s->nb_streams)
8120 return AVERROR_INVALIDDATA;
8122 st = s->streams[stream_index];
8123 sample = mov_seek_stream(s, st, sample_time, flags);
8127 if (mc->seek_individually) {
8128 /* adjust seek timestamp to found sample timestamp */
8129 int64_t seek_timestamp = st->internal->index_entries[sample].timestamp;
8130 st->internal->skip_samples = mov_get_skip_samples(st, sample);
8132 for (i = 0; i < s->nb_streams; i++) {
8136 if (stream_index == i)
8139 timestamp = av_rescale_q(seek_timestamp, s->streams[stream_index]->time_base, st->time_base);
8140 sample = mov_seek_stream(s, st, timestamp, flags);
8142 st->internal->skip_samples = mov_get_skip_samples(st, sample);
8145 for (i = 0; i < s->nb_streams; i++) {
8146 MOVStreamContext *sc;
8149 mov_current_sample_set(sc, 0);
8152 MOVStreamContext *sc;
8153 AVIndexEntry *entry = mov_find_next_sample(s, &st);
8155 return AVERROR_INVALIDDATA;
8157 if (sc->ffindex == stream_index && sc->current_sample == sample)
8159 mov_current_sample_inc(sc);
8165 #define OFFSET(x) offsetof(MOVContext, x)
8166 #define FLAGS AV_OPT_FLAG_VIDEO_PARAM | AV_OPT_FLAG_DECODING_PARAM
8167 static const AVOption mov_options[] = {
8168 {"use_absolute_path",
8169 "allow using absolute path when opening alias, this is a possible security issue",
8170 OFFSET(use_absolute_path), AV_OPT_TYPE_BOOL, {.i64 = 0},
8172 {"seek_streams_individually",
8173 "Seek each stream individually to the closest point",
8174 OFFSET(seek_individually), AV_OPT_TYPE_BOOL, { .i64 = 1 },
8176 {"ignore_editlist", "Ignore the edit list atom.", OFFSET(ignore_editlist), AV_OPT_TYPE_BOOL, {.i64 = 0},
8178 {"advanced_editlist",
8179 "Modify the AVIndex according to the editlists. Use this option to decode in the order specified by the edits.",
8180 OFFSET(advanced_editlist), AV_OPT_TYPE_BOOL, {.i64 = 1},
8182 {"ignore_chapters", "", OFFSET(ignore_chapters), AV_OPT_TYPE_BOOL, {.i64 = 0},
8185 "use mfra for fragment timestamps",
8186 OFFSET(use_mfra_for), AV_OPT_TYPE_INT, {.i64 = FF_MOV_FLAG_MFRA_AUTO},
8187 -1, FF_MOV_FLAG_MFRA_PTS, FLAGS,
8189 {"auto", "auto", 0, AV_OPT_TYPE_CONST, {.i64 = FF_MOV_FLAG_MFRA_AUTO}, 0, 0,
8190 FLAGS, "use_mfra_for" },
8191 {"dts", "dts", 0, AV_OPT_TYPE_CONST, {.i64 = FF_MOV_FLAG_MFRA_DTS}, 0, 0,
8192 FLAGS, "use_mfra_for" },
8193 {"pts", "pts", 0, AV_OPT_TYPE_CONST, {.i64 = FF_MOV_FLAG_MFRA_PTS}, 0, 0,
8194 FLAGS, "use_mfra_for" },
8195 { "export_all", "Export unrecognized metadata entries", OFFSET(export_all),
8196 AV_OPT_TYPE_BOOL, { .i64 = 0 }, 0, 1, .flags = FLAGS },
8197 { "export_xmp", "Export full XMP metadata", OFFSET(export_xmp),
8198 AV_OPT_TYPE_BOOL, { .i64 = 0 }, 0, 1, .flags = FLAGS },
8199 { "activation_bytes", "Secret bytes for Audible AAX files", OFFSET(activation_bytes),
8200 AV_OPT_TYPE_BINARY, .flags = AV_OPT_FLAG_DECODING_PARAM },
8201 { "audible_key", "AES-128 Key for Audible AAXC files", OFFSET(audible_key),
8202 AV_OPT_TYPE_BINARY, .flags = AV_OPT_FLAG_DECODING_PARAM },
8203 { "audible_iv", "AES-128 IV for Audible AAXC files", OFFSET(audible_iv),
8204 AV_OPT_TYPE_BINARY, .flags = AV_OPT_FLAG_DECODING_PARAM },
8205 { "audible_fixed_key", // extracted from libAAX_SDK.so and AAXSDKWin.dll files!
8206 "Fixed key used for handling Audible AAX files", OFFSET(audible_fixed_key),
8207 AV_OPT_TYPE_BINARY, {.str="77214d4b196a87cd520045fd20a51d67"},
8208 .flags = AV_OPT_FLAG_DECODING_PARAM },
8209 { "decryption_key", "The media decryption key (hex)", OFFSET(decryption_key), AV_OPT_TYPE_BINARY, .flags = AV_OPT_FLAG_DECODING_PARAM },
8210 { "enable_drefs", "Enable external track support.", OFFSET(enable_drefs), AV_OPT_TYPE_BOOL,
8211 {.i64 = 0}, 0, 1, FLAGS },
8216 static const AVClass mov_class = {
8217 .class_name = "mov,mp4,m4a,3gp,3g2,mj2",
8218 .item_name = av_default_item_name,
8219 .option = mov_options,
8220 .version = LIBAVUTIL_VERSION_INT,
8223 AVInputFormat ff_mov_demuxer = {
8224 .name = "mov,mp4,m4a,3gp,3g2,mj2",
8225 .long_name = NULL_IF_CONFIG_SMALL("QuickTime / MOV"),
8226 .priv_class = &mov_class,
8227 .priv_data_size = sizeof(MOVContext),
8228 .extensions = "mov,mp4,m4a,3gp,3g2,mj2,psp,m4b,ism,ismv,isma,f4v",
8229 .read_probe = mov_probe,
8230 .read_header = mov_read_header,
8231 .read_packet = mov_read_packet,
8232 .read_close = mov_read_close,
8233 .read_seek = mov_read_seek,
8234 .flags = AVFMT_NO_BYTE_SEEK | AVFMT_SEEK_TO_PTS,