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;
807 #if FF_API_LAVF_AVCTX
808 FF_DISABLE_DEPRECATION_WARNINGS
809 st->codec->audio_service_type = *ast;
810 FF_ENABLE_DEPRECATION_WARNINGS
816 static int mov_read_dec3(MOVContext *c, AVIOContext *pb, MOVAtom atom)
819 enum AVAudioServiceType *ast;
820 int eac3info, acmod, lfeon, bsmod;
822 if (c->fc->nb_streams < 1)
824 st = c->fc->streams[c->fc->nb_streams-1];
826 ast = (enum AVAudioServiceType*)av_stream_new_side_data(st, AV_PKT_DATA_AUDIO_SERVICE_TYPE,
829 return AVERROR(ENOMEM);
831 /* No need to parse fields for additional independent substreams and its
832 * associated dependent substreams since libavcodec's E-AC-3 decoder
833 * does not support them yet. */
834 avio_rb16(pb); /* data_rate and num_ind_sub */
835 eac3info = avio_rb24(pb);
836 bsmod = (eac3info >> 12) & 0x1f;
837 acmod = (eac3info >> 9) & 0x7;
838 lfeon = (eac3info >> 8) & 0x1;
839 st->codecpar->channel_layout = avpriv_ac3_channel_layout_tab[acmod];
841 st->codecpar->channel_layout |= AV_CH_LOW_FREQUENCY;
842 st->codecpar->channels = av_get_channel_layout_nb_channels(st->codecpar->channel_layout);
844 if (st->codecpar->channels > 1 && bsmod == 0x7)
845 *ast = AV_AUDIO_SERVICE_TYPE_KARAOKE;
847 #if FF_API_LAVF_AVCTX
848 FF_DISABLE_DEPRECATION_WARNINGS
849 st->codec->audio_service_type = *ast;
850 FF_ENABLE_DEPRECATION_WARNINGS
856 static int mov_read_ddts(MOVContext *c, AVIOContext *pb, MOVAtom atom)
859 uint8_t buf[DDTS_SIZE + AV_INPUT_BUFFER_PADDING_SIZE];
861 uint32_t frame_duration_code = 0;
862 uint32_t channel_layout_code = 0;
866 if ((ret = ffio_read_size(pb, buf, DDTS_SIZE)) < 0)
869 init_get_bits(&gb, buf, 8 * DDTS_SIZE);
871 if (c->fc->nb_streams < 1) {
874 st = c->fc->streams[c->fc->nb_streams-1];
876 st->codecpar->sample_rate = get_bits_long(&gb, 32);
877 if (st->codecpar->sample_rate <= 0) {
878 av_log(c->fc, AV_LOG_ERROR, "Invalid sample rate %d\n", st->codecpar->sample_rate);
879 return AVERROR_INVALIDDATA;
881 skip_bits_long(&gb, 32); /* max bitrate */
882 st->codecpar->bit_rate = get_bits_long(&gb, 32);
883 st->codecpar->bits_per_coded_sample = get_bits(&gb, 8);
884 frame_duration_code = get_bits(&gb, 2);
885 skip_bits(&gb, 30); /* various fields */
886 channel_layout_code = get_bits(&gb, 16);
888 st->codecpar->frame_size =
889 (frame_duration_code == 0) ? 512 :
890 (frame_duration_code == 1) ? 1024 :
891 (frame_duration_code == 2) ? 2048 :
892 (frame_duration_code == 3) ? 4096 : 0;
894 if (channel_layout_code > 0xff) {
895 av_log(c->fc, AV_LOG_WARNING, "Unsupported DTS audio channel layout\n");
897 st->codecpar->channel_layout =
898 ((channel_layout_code & 0x1) ? AV_CH_FRONT_CENTER : 0) |
899 ((channel_layout_code & 0x2) ? AV_CH_FRONT_LEFT : 0) |
900 ((channel_layout_code & 0x2) ? AV_CH_FRONT_RIGHT : 0) |
901 ((channel_layout_code & 0x4) ? AV_CH_SIDE_LEFT : 0) |
902 ((channel_layout_code & 0x4) ? AV_CH_SIDE_RIGHT : 0) |
903 ((channel_layout_code & 0x8) ? AV_CH_LOW_FREQUENCY : 0);
905 st->codecpar->channels = av_get_channel_layout_nb_channels(st->codecpar->channel_layout);
910 static int mov_read_chan(MOVContext *c, AVIOContext *pb, MOVAtom atom)
914 if (c->fc->nb_streams < 1)
916 st = c->fc->streams[c->fc->nb_streams-1];
921 /* skip version and flags */
924 ff_mov_read_chan(c->fc, pb, st, atom.size - 4);
929 static int mov_read_wfex(MOVContext *c, AVIOContext *pb, MOVAtom atom)
934 if (c->fc->nb_streams < 1)
936 st = c->fc->streams[c->fc->nb_streams-1];
938 if ((ret = ff_get_wav_header(c->fc, pb, st->codecpar, atom.size, 0)) < 0)
939 av_log(c->fc, AV_LOG_WARNING, "get_wav_header failed\n");
944 /* This atom overrides any previously set aspect ratio */
945 static int mov_read_pasp(MOVContext *c, AVIOContext *pb, MOVAtom atom)
947 const int num = avio_rb32(pb);
948 const int den = avio_rb32(pb);
951 if (c->fc->nb_streams < 1)
953 st = c->fc->streams[c->fc->nb_streams-1];
956 av_reduce(&st->sample_aspect_ratio.num, &st->sample_aspect_ratio.den,
962 /* this atom contains actual media data */
963 static int mov_read_mdat(MOVContext *c, AVIOContext *pb, MOVAtom atom)
965 if (atom.size == 0) /* wrong one (MP4) */
968 return 0; /* now go for moov */
971 #define DRM_BLOB_SIZE 56
973 static int mov_read_adrm(MOVContext *c, AVIOContext *pb, MOVAtom atom)
975 uint8_t intermediate_key[20];
976 uint8_t intermediate_iv[20];
979 uint8_t file_checksum[20];
980 uint8_t calculated_checksum[20];
984 uint8_t *activation_bytes = c->activation_bytes;
985 uint8_t *fixed_key = c->audible_fixed_key;
989 sha = av_sha_alloc();
991 return AVERROR(ENOMEM);
992 av_free(c->aes_decrypt);
993 c->aes_decrypt = av_aes_alloc();
994 if (!c->aes_decrypt) {
995 ret = AVERROR(ENOMEM);
999 /* drm blob processing */
1000 avio_read(pb, output, 8); // go to offset 8, absolute position 0x251
1001 avio_read(pb, input, DRM_BLOB_SIZE);
1002 avio_read(pb, output, 4); // go to offset 4, absolute position 0x28d
1003 avio_read(pb, file_checksum, 20);
1005 av_log(c->fc, AV_LOG_INFO, "[aax] file checksum == "); // required by external tools
1006 for (i = 0; i < 20; i++)
1007 av_log(c->fc, AV_LOG_INFO, "%02x", file_checksum[i]);
1008 av_log(c->fc, AV_LOG_INFO, "\n");
1010 /* verify activation data */
1011 if (!activation_bytes) {
1012 av_log(c->fc, AV_LOG_WARNING, "[aax] activation_bytes option is missing!\n");
1013 ret = 0; /* allow ffprobe to continue working on .aax files */
1016 if (c->activation_bytes_size != 4) {
1017 av_log(c->fc, AV_LOG_FATAL, "[aax] activation_bytes value needs to be 4 bytes!\n");
1018 ret = AVERROR(EINVAL);
1022 /* verify fixed key */
1023 if (c->audible_fixed_key_size != 16) {
1024 av_log(c->fc, AV_LOG_FATAL, "[aax] audible_fixed_key value needs to be 16 bytes!\n");
1025 ret = AVERROR(EINVAL);
1029 /* AAX (and AAX+) key derivation */
1030 av_sha_init(sha, 160);
1031 av_sha_update(sha, fixed_key, 16);
1032 av_sha_update(sha, activation_bytes, 4);
1033 av_sha_final(sha, intermediate_key);
1034 av_sha_init(sha, 160);
1035 av_sha_update(sha, fixed_key, 16);
1036 av_sha_update(sha, intermediate_key, 20);
1037 av_sha_update(sha, activation_bytes, 4);
1038 av_sha_final(sha, intermediate_iv);
1039 av_sha_init(sha, 160);
1040 av_sha_update(sha, intermediate_key, 16);
1041 av_sha_update(sha, intermediate_iv, 16);
1042 av_sha_final(sha, calculated_checksum);
1043 if (memcmp(calculated_checksum, file_checksum, 20)) { // critical error
1044 av_log(c->fc, AV_LOG_ERROR, "[aax] mismatch in checksums!\n");
1045 ret = AVERROR_INVALIDDATA;
1048 av_aes_init(c->aes_decrypt, intermediate_key, 128, 1);
1049 av_aes_crypt(c->aes_decrypt, output, input, DRM_BLOB_SIZE >> 4, intermediate_iv, 1);
1050 for (i = 0; i < 4; i++) {
1051 // file data (in output) is stored in big-endian mode
1052 if (activation_bytes[i] != output[3 - i]) { // critical error
1053 av_log(c->fc, AV_LOG_ERROR, "[aax] error in drm blob decryption!\n");
1054 ret = AVERROR_INVALIDDATA;
1058 memcpy(c->file_key, output + 8, 16);
1059 memcpy(input, output + 26, 16);
1060 av_sha_init(sha, 160);
1061 av_sha_update(sha, input, 16);
1062 av_sha_update(sha, c->file_key, 16);
1063 av_sha_update(sha, fixed_key, 16);
1064 av_sha_final(sha, c->file_iv);
1072 static int mov_aaxc_crypto(MOVContext *c)
1074 if (c->audible_key_size != 16) {
1075 av_log(c->fc, AV_LOG_FATAL, "[aaxc] audible_key value needs to be 16 bytes!\n");
1076 return AVERROR(EINVAL);
1079 if (c->audible_iv_size != 16) {
1080 av_log(c->fc, AV_LOG_FATAL, "[aaxc] audible_iv value needs to be 16 bytes!\n");
1081 return AVERROR(EINVAL);
1084 c->aes_decrypt = av_aes_alloc();
1085 if (!c->aes_decrypt) {
1086 return AVERROR(ENOMEM);
1089 memcpy(c->file_key, c->audible_key, 16);
1090 memcpy(c->file_iv, c->audible_iv, 16);
1096 // Audible AAX (and AAX+) bytestream decryption
1097 static int aax_filter(uint8_t *input, int size, MOVContext *c)
1100 unsigned char iv[16];
1102 memcpy(iv, c->file_iv, 16); // iv is overwritten
1103 blocks = size >> 4; // trailing bytes are not encrypted!
1104 av_aes_init(c->aes_decrypt, c->file_key, 128, 1);
1105 av_aes_crypt(c->aes_decrypt, input, input, blocks, iv, 1);
1110 /* read major brand, minor version and compatible brands and store them as metadata */
1111 static int mov_read_ftyp(MOVContext *c, AVIOContext *pb, MOVAtom atom)
1114 int comp_brand_size;
1115 char* comp_brands_str;
1116 uint8_t type[5] = {0};
1117 int ret = ffio_read_size(pb, type, 4);
1121 if (strcmp(type, "qt "))
1123 av_log(c->fc, AV_LOG_DEBUG, "ISO: File Type Major Brand: %.4s\n",(char *)&type);
1124 av_dict_set(&c->fc->metadata, "major_brand", type, 0);
1125 minor_ver = avio_rb32(pb); /* minor version */
1126 av_dict_set_int(&c->fc->metadata, "minor_version", minor_ver, 0);
1128 comp_brand_size = atom.size - 8;
1129 if (comp_brand_size < 0 || comp_brand_size == INT_MAX)
1130 return AVERROR_INVALIDDATA;
1131 comp_brands_str = av_malloc(comp_brand_size + 1); /* Add null terminator */
1132 if (!comp_brands_str)
1133 return AVERROR(ENOMEM);
1135 ret = ffio_read_size(pb, comp_brands_str, comp_brand_size);
1137 av_freep(&comp_brands_str);
1140 comp_brands_str[comp_brand_size] = 0;
1141 av_dict_set(&c->fc->metadata, "compatible_brands",
1142 comp_brands_str, AV_DICT_DONT_STRDUP_VAL);
1144 // Logic for handling Audible's .aaxc files
1145 if (!strcmp(type, "aaxc")) {
1152 /* this atom should contain all header atoms */
1153 static int mov_read_moov(MOVContext *c, AVIOContext *pb, MOVAtom atom)
1157 if (c->found_moov) {
1158 av_log(c->fc, AV_LOG_WARNING, "Found duplicated MOOV Atom. Skipped it\n");
1159 avio_skip(pb, atom.size);
1163 if ((ret = mov_read_default(c, pb, atom)) < 0)
1165 /* we parsed the 'moov' atom, we can terminate the parsing as soon as we find the 'mdat' */
1166 /* so we don't parse the whole file if over a network */
1168 return 0; /* now go for mdat */
1171 static MOVFragmentStreamInfo * get_frag_stream_info(
1172 MOVFragmentIndex *frag_index,
1177 MOVFragmentIndexItem * item;
1179 if (index < 0 || index >= frag_index->nb_items)
1181 item = &frag_index->item[index];
1182 for (i = 0; i < item->nb_stream_info; i++)
1183 if (item->stream_info[i].id == id)
1184 return &item->stream_info[i];
1186 // This shouldn't happen
1190 static void set_frag_stream(MOVFragmentIndex *frag_index, int id)
1193 MOVFragmentIndexItem * item;
1195 if (frag_index->current < 0 ||
1196 frag_index->current >= frag_index->nb_items)
1199 item = &frag_index->item[frag_index->current];
1200 for (i = 0; i < item->nb_stream_info; i++)
1201 if (item->stream_info[i].id == id) {
1206 // id not found. This shouldn't happen.
1210 static MOVFragmentStreamInfo * get_current_frag_stream_info(
1211 MOVFragmentIndex *frag_index)
1213 MOVFragmentIndexItem *item;
1214 if (frag_index->current < 0 ||
1215 frag_index->current >= frag_index->nb_items)
1218 item = &frag_index->item[frag_index->current];
1219 if (item->current >= 0 && item->current < item->nb_stream_info)
1220 return &item->stream_info[item->current];
1222 // This shouldn't happen
1226 static int search_frag_moof_offset(MOVFragmentIndex *frag_index, int64_t offset)
1229 int64_t moof_offset;
1231 // Optimize for appending new entries
1232 if (!frag_index->nb_items ||
1233 frag_index->item[frag_index->nb_items - 1].moof_offset < offset)
1234 return frag_index->nb_items;
1237 b = frag_index->nb_items;
1241 moof_offset = frag_index->item[m].moof_offset;
1242 if (moof_offset >= offset)
1244 if (moof_offset <= offset)
1250 static int64_t get_stream_info_time(MOVFragmentStreamInfo * frag_stream_info)
1252 av_assert0(frag_stream_info);
1253 if (frag_stream_info->sidx_pts != AV_NOPTS_VALUE)
1254 return frag_stream_info->sidx_pts;
1255 if (frag_stream_info->first_tfra_pts != AV_NOPTS_VALUE)
1256 return frag_stream_info->first_tfra_pts;
1257 return frag_stream_info->tfdt_dts;
1260 static int64_t get_frag_time(MOVFragmentIndex *frag_index,
1261 int index, int track_id)
1263 MOVFragmentStreamInfo * frag_stream_info;
1267 if (track_id >= 0) {
1268 frag_stream_info = get_frag_stream_info(frag_index, index, track_id);
1269 if (frag_stream_info->sidx_pts != AV_NOPTS_VALUE)
1270 return frag_stream_info->sidx_pts;
1271 if (frag_stream_info->first_tfra_pts != AV_NOPTS_VALUE)
1272 return frag_stream_info->first_tfra_pts;
1273 return frag_stream_info->sidx_pts;
1276 for (i = 0; i < frag_index->item[index].nb_stream_info; i++) {
1277 frag_stream_info = &frag_index->item[index].stream_info[i];
1278 timestamp = get_stream_info_time(frag_stream_info);
1279 if (timestamp != AV_NOPTS_VALUE)
1282 return AV_NOPTS_VALUE;
1285 static int search_frag_timestamp(MOVFragmentIndex *frag_index,
1286 AVStream *st, int64_t timestamp)
1293 // If the stream is referenced by any sidx, limit the search
1294 // to fragments that referenced this stream in the sidx
1295 MOVStreamContext *sc = st->priv_data;
1301 b = frag_index->nb_items;
1304 m0 = m = (a + b) >> 1;
1307 (frag_time = get_frag_time(frag_index, m, id)) == AV_NOPTS_VALUE)
1310 if (m < b && frag_time <= timestamp)
1319 static int update_frag_index(MOVContext *c, int64_t offset)
1322 MOVFragmentIndexItem * item;
1323 MOVFragmentStreamInfo * frag_stream_info;
1325 // If moof_offset already exists in frag_index, return index to it
1326 index = search_frag_moof_offset(&c->frag_index, offset);
1327 if (index < c->frag_index.nb_items &&
1328 c->frag_index.item[index].moof_offset == offset)
1331 // offset is not yet in frag index.
1332 // Insert new item at index (sorted by moof offset)
1333 item = av_fast_realloc(c->frag_index.item,
1334 &c->frag_index.allocated_size,
1335 (c->frag_index.nb_items + 1) *
1336 sizeof(*c->frag_index.item));
1339 c->frag_index.item = item;
1341 frag_stream_info = av_realloc_array(NULL, c->fc->nb_streams,
1342 sizeof(*item->stream_info));
1343 if (!frag_stream_info)
1346 for (i = 0; i < c->fc->nb_streams; i++) {
1347 // Avoid building frag index if streams lack track id.
1348 if (c->fc->streams[i]->id < 0) {
1349 av_free(frag_stream_info);
1350 return AVERROR_INVALIDDATA;
1353 frag_stream_info[i].id = c->fc->streams[i]->id;
1354 frag_stream_info[i].sidx_pts = AV_NOPTS_VALUE;
1355 frag_stream_info[i].tfdt_dts = AV_NOPTS_VALUE;
1356 frag_stream_info[i].next_trun_dts = AV_NOPTS_VALUE;
1357 frag_stream_info[i].first_tfra_pts = AV_NOPTS_VALUE;
1358 frag_stream_info[i].index_entry = -1;
1359 frag_stream_info[i].encryption_index = NULL;
1362 if (index < c->frag_index.nb_items)
1363 memmove(c->frag_index.item + index + 1, c->frag_index.item + index,
1364 (c->frag_index.nb_items - index) * sizeof(*c->frag_index.item));
1366 item = &c->frag_index.item[index];
1367 item->headers_read = 0;
1369 item->nb_stream_info = c->fc->nb_streams;
1370 item->moof_offset = offset;
1371 item->stream_info = frag_stream_info;
1372 c->frag_index.nb_items++;
1377 static void fix_frag_index_entries(MOVFragmentIndex *frag_index, int index,
1378 int id, int entries)
1381 MOVFragmentStreamInfo * frag_stream_info;
1385 for (i = index; i < frag_index->nb_items; i++) {
1386 frag_stream_info = get_frag_stream_info(frag_index, i, id);
1387 if (frag_stream_info && frag_stream_info->index_entry >= 0)
1388 frag_stream_info->index_entry += entries;
1392 static int mov_read_moof(MOVContext *c, AVIOContext *pb, MOVAtom atom)
1394 // Set by mov_read_tfhd(). mov_read_trun() will reject files missing tfhd.
1395 c->fragment.found_tfhd = 0;
1397 if (!c->has_looked_for_mfra && c->use_mfra_for > 0) {
1398 c->has_looked_for_mfra = 1;
1399 if (pb->seekable & AVIO_SEEKABLE_NORMAL) {
1401 av_log(c->fc, AV_LOG_VERBOSE, "stream has moof boxes, will look "
1403 if ((ret = mov_read_mfra(c, pb)) < 0) {
1404 av_log(c->fc, AV_LOG_VERBOSE, "found a moof box but failed to "
1405 "read the mfra (may be a live ismv)\n");
1408 av_log(c->fc, AV_LOG_VERBOSE, "found a moof box but stream is not "
1409 "seekable, can not look for mfra\n");
1412 c->fragment.moof_offset = c->fragment.implicit_offset = avio_tell(pb) - 8;
1413 av_log(c->fc, AV_LOG_TRACE, "moof offset %"PRIx64"\n", c->fragment.moof_offset);
1414 c->frag_index.current = update_frag_index(c, c->fragment.moof_offset);
1415 return mov_read_default(c, pb, atom);
1418 static void mov_metadata_creation_time(AVDictionary **metadata, int64_t time, void *logctx)
1421 if (time >= 2082844800)
1422 time -= 2082844800; /* seconds between 1904-01-01 and Epoch */
1424 if ((int64_t)(time * 1000000ULL) / 1000000 != time) {
1425 av_log(logctx, AV_LOG_DEBUG, "creation_time is not representable\n");
1429 avpriv_dict_set_timestamp(metadata, "creation_time", time * 1000000);
1433 static int mov_read_mdhd(MOVContext *c, AVIOContext *pb, MOVAtom atom)
1436 MOVStreamContext *sc;
1438 char language[4] = {0};
1440 int64_t creation_time;
1442 if (c->fc->nb_streams < 1)
1444 st = c->fc->streams[c->fc->nb_streams-1];
1447 if (sc->time_scale) {
1448 av_log(c->fc, AV_LOG_ERROR, "Multiple mdhd?\n");
1449 return AVERROR_INVALIDDATA;
1452 version = avio_r8(pb);
1454 avpriv_request_sample(c->fc, "Version %d", version);
1455 return AVERROR_PATCHWELCOME;
1457 avio_rb24(pb); /* flags */
1459 creation_time = avio_rb64(pb);
1462 creation_time = avio_rb32(pb);
1463 avio_rb32(pb); /* modification time */
1465 mov_metadata_creation_time(&st->metadata, creation_time, c->fc);
1467 sc->time_scale = avio_rb32(pb);
1468 if (sc->time_scale <= 0) {
1469 av_log(c->fc, AV_LOG_ERROR, "Invalid mdhd time scale %d, defaulting to 1\n", sc->time_scale);
1472 st->duration = (version == 1) ? avio_rb64(pb) : avio_rb32(pb); /* duration */
1474 lang = avio_rb16(pb); /* language */
1475 if (ff_mov_lang_to_iso639(lang, language))
1476 av_dict_set(&st->metadata, "language", language, 0);
1477 avio_rb16(pb); /* quality */
1482 static int mov_read_mvhd(MOVContext *c, AVIOContext *pb, MOVAtom atom)
1485 int64_t creation_time;
1486 int version = avio_r8(pb); /* version */
1487 avio_rb24(pb); /* flags */
1490 creation_time = avio_rb64(pb);
1493 creation_time = avio_rb32(pb);
1494 avio_rb32(pb); /* modification time */
1496 mov_metadata_creation_time(&c->fc->metadata, creation_time, c->fc);
1497 c->time_scale = avio_rb32(pb); /* time scale */
1498 if (c->time_scale <= 0) {
1499 av_log(c->fc, AV_LOG_ERROR, "Invalid mvhd time scale %d, defaulting to 1\n", c->time_scale);
1502 av_log(c->fc, AV_LOG_TRACE, "time scale = %i\n", c->time_scale);
1504 c->duration = (version == 1) ? avio_rb64(pb) : avio_rb32(pb); /* duration */
1505 // set the AVFormatContext duration because the duration of individual tracks
1506 // may be inaccurate
1508 c->fc->duration = av_rescale(c->duration, AV_TIME_BASE, c->time_scale);
1509 avio_rb32(pb); /* preferred scale */
1511 avio_rb16(pb); /* preferred volume */
1513 avio_skip(pb, 10); /* reserved */
1515 /* movie display matrix, store it in main context and use it later on */
1516 for (i = 0; i < 3; i++) {
1517 c->movie_display_matrix[i][0] = avio_rb32(pb); // 16.16 fixed point
1518 c->movie_display_matrix[i][1] = avio_rb32(pb); // 16.16 fixed point
1519 c->movie_display_matrix[i][2] = avio_rb32(pb); // 2.30 fixed point
1522 avio_rb32(pb); /* preview time */
1523 avio_rb32(pb); /* preview duration */
1524 avio_rb32(pb); /* poster time */
1525 avio_rb32(pb); /* selection time */
1526 avio_rb32(pb); /* selection duration */
1527 avio_rb32(pb); /* current time */
1528 avio_rb32(pb); /* next track ID */
1533 static int mov_read_enda(MOVContext *c, AVIOContext *pb, MOVAtom atom)
1538 if (c->fc->nb_streams < 1)
1540 st = c->fc->streams[c->fc->nb_streams-1];
1542 little_endian = avio_rb16(pb) & 0xFF;
1543 av_log(c->fc, AV_LOG_TRACE, "enda %d\n", little_endian);
1544 if (little_endian == 1) {
1545 switch (st->codecpar->codec_id) {
1546 case AV_CODEC_ID_PCM_S24BE:
1547 st->codecpar->codec_id = AV_CODEC_ID_PCM_S24LE;
1549 case AV_CODEC_ID_PCM_S32BE:
1550 st->codecpar->codec_id = AV_CODEC_ID_PCM_S32LE;
1552 case AV_CODEC_ID_PCM_F32BE:
1553 st->codecpar->codec_id = AV_CODEC_ID_PCM_F32LE;
1555 case AV_CODEC_ID_PCM_F64BE:
1556 st->codecpar->codec_id = AV_CODEC_ID_PCM_F64LE;
1565 static int mov_read_colr(MOVContext *c, AVIOContext *pb, MOVAtom atom)
1568 uint8_t *icc_profile;
1569 char color_parameter_type[5] = { 0 };
1570 uint16_t color_primaries, color_trc, color_matrix;
1573 if (c->fc->nb_streams < 1)
1575 st = c->fc->streams[c->fc->nb_streams - 1];
1577 ret = ffio_read_size(pb, color_parameter_type, 4);
1580 if (strncmp(color_parameter_type, "nclx", 4) &&
1581 strncmp(color_parameter_type, "nclc", 4) &&
1582 strncmp(color_parameter_type, "prof", 4)) {
1583 av_log(c->fc, AV_LOG_WARNING, "unsupported color_parameter_type %s\n",
1584 color_parameter_type);
1588 if (!strncmp(color_parameter_type, "prof", 4)) {
1589 icc_profile = av_stream_new_side_data(st, AV_PKT_DATA_ICC_PROFILE, atom.size - 4);
1591 return AVERROR(ENOMEM);
1592 ret = ffio_read_size(pb, icc_profile, atom.size - 4);
1596 color_primaries = avio_rb16(pb);
1597 color_trc = avio_rb16(pb);
1598 color_matrix = avio_rb16(pb);
1600 av_log(c->fc, AV_LOG_TRACE,
1601 "%s: pri %d trc %d matrix %d",
1602 color_parameter_type, color_primaries, color_trc, color_matrix);
1604 if (!strncmp(color_parameter_type, "nclx", 4)) {
1605 uint8_t color_range = avio_r8(pb) >> 7;
1606 av_log(c->fc, AV_LOG_TRACE, " full %"PRIu8"", color_range);
1608 st->codecpar->color_range = AVCOL_RANGE_JPEG;
1610 st->codecpar->color_range = AVCOL_RANGE_MPEG;
1613 if (!av_color_primaries_name(color_primaries))
1614 color_primaries = AVCOL_PRI_UNSPECIFIED;
1615 if (!av_color_transfer_name(color_trc))
1616 color_trc = AVCOL_TRC_UNSPECIFIED;
1617 if (!av_color_space_name(color_matrix))
1618 color_matrix = AVCOL_SPC_UNSPECIFIED;
1620 st->codecpar->color_primaries = color_primaries;
1621 st->codecpar->color_trc = color_trc;
1622 st->codecpar->color_space = color_matrix;
1623 av_log(c->fc, AV_LOG_TRACE, "\n");
1628 static int mov_read_fiel(MOVContext *c, AVIOContext *pb, MOVAtom atom)
1631 unsigned mov_field_order;
1632 enum AVFieldOrder decoded_field_order = AV_FIELD_UNKNOWN;
1634 if (c->fc->nb_streams < 1) // will happen with jp2 files
1636 st = c->fc->streams[c->fc->nb_streams-1];
1638 return AVERROR_INVALIDDATA;
1639 mov_field_order = avio_rb16(pb);
1640 if ((mov_field_order & 0xFF00) == 0x0100)
1641 decoded_field_order = AV_FIELD_PROGRESSIVE;
1642 else if ((mov_field_order & 0xFF00) == 0x0200) {
1643 switch (mov_field_order & 0xFF) {
1644 case 0x01: decoded_field_order = AV_FIELD_TT;
1646 case 0x06: decoded_field_order = AV_FIELD_BB;
1648 case 0x09: decoded_field_order = AV_FIELD_TB;
1650 case 0x0E: decoded_field_order = AV_FIELD_BT;
1654 if (decoded_field_order == AV_FIELD_UNKNOWN && mov_field_order) {
1655 av_log(c->fc, AV_LOG_ERROR, "Unknown MOV field order 0x%04x\n", mov_field_order);
1657 st->codecpar->field_order = decoded_field_order;
1662 static int mov_realloc_extradata(AVCodecParameters *par, MOVAtom atom)
1665 uint64_t size = (uint64_t)par->extradata_size + atom.size + 8 + AV_INPUT_BUFFER_PADDING_SIZE;
1666 if (size > INT_MAX || (uint64_t)atom.size > INT_MAX)
1667 return AVERROR_INVALIDDATA;
1668 if ((err = av_reallocp(&par->extradata, size)) < 0) {
1669 par->extradata_size = 0;
1672 par->extradata_size = size - AV_INPUT_BUFFER_PADDING_SIZE;
1676 /* Read a whole atom into the extradata return the size of the atom read, possibly truncated if != atom.size */
1677 static int64_t mov_read_atom_into_extradata(MOVContext *c, AVIOContext *pb, MOVAtom atom,
1678 AVCodecParameters *par, uint8_t *buf)
1680 int64_t result = atom.size;
1683 AV_WB32(buf , atom.size + 8);
1684 AV_WL32(buf + 4, atom.type);
1685 err = ffio_read_size(pb, buf + 8, atom.size);
1687 par->extradata_size -= atom.size;
1689 } else if (err < atom.size) {
1690 av_log(c->fc, AV_LOG_WARNING, "truncated extradata\n");
1691 par->extradata_size -= atom.size - err;
1694 memset(buf + 8 + err, 0, AV_INPUT_BUFFER_PADDING_SIZE);
1698 /* FIXME modify QDM2/SVQ3/H.264 decoders to take full atom as extradata */
1699 static int mov_read_extradata(MOVContext *c, AVIOContext *pb, MOVAtom atom,
1700 enum AVCodecID codec_id)
1703 uint64_t original_size;
1706 if (c->fc->nb_streams < 1) // will happen with jp2 files
1708 st = c->fc->streams[c->fc->nb_streams-1];
1710 if (st->codecpar->codec_id != codec_id)
1711 return 0; /* unexpected codec_id - don't mess with extradata */
1713 original_size = st->codecpar->extradata_size;
1714 err = mov_realloc_extradata(st->codecpar, atom);
1718 err = mov_read_atom_into_extradata(c, pb, atom, st->codecpar, st->codecpar->extradata + original_size);
1721 return 0; // Note: this is the original behavior to ignore truncation.
1724 /* wrapper functions for reading ALAC/AVS/MJPEG/MJPEG2000 extradata atoms only for those codecs */
1725 static int mov_read_alac(MOVContext *c, AVIOContext *pb, MOVAtom atom)
1727 return mov_read_extradata(c, pb, atom, AV_CODEC_ID_ALAC);
1730 static int mov_read_avss(MOVContext *c, AVIOContext *pb, MOVAtom atom)
1732 return mov_read_extradata(c, pb, atom, AV_CODEC_ID_AVS);
1735 static int mov_read_jp2h(MOVContext *c, AVIOContext *pb, MOVAtom atom)
1737 return mov_read_extradata(c, pb, atom, AV_CODEC_ID_JPEG2000);
1740 static int mov_read_dpxe(MOVContext *c, AVIOContext *pb, MOVAtom atom)
1742 return mov_read_extradata(c, pb, atom, AV_CODEC_ID_R10K);
1745 static int mov_read_avid(MOVContext *c, AVIOContext *pb, MOVAtom atom)
1747 int ret = mov_read_extradata(c, pb, atom, AV_CODEC_ID_AVUI);
1749 ret = mov_read_extradata(c, pb, atom, AV_CODEC_ID_DNXHD);
1753 static int mov_read_targa_y216(MOVContext *c, AVIOContext *pb, MOVAtom atom)
1755 int ret = mov_read_extradata(c, pb, atom, AV_CODEC_ID_TARGA_Y216);
1757 if (!ret && c->fc->nb_streams >= 1) {
1758 AVCodecParameters *par = c->fc->streams[c->fc->nb_streams-1]->codecpar;
1759 if (par->extradata_size >= 40) {
1760 par->height = AV_RB16(&par->extradata[36]);
1761 par->width = AV_RB16(&par->extradata[38]);
1767 static int mov_read_ares(MOVContext *c, AVIOContext *pb, MOVAtom atom)
1769 if (c->fc->nb_streams >= 1) {
1770 AVCodecParameters *par = c->fc->streams[c->fc->nb_streams-1]->codecpar;
1771 if (par->codec_tag == MKTAG('A', 'V', 'i', 'n') &&
1772 par->codec_id == AV_CODEC_ID_H264 &&
1776 cid = avio_rb16(pb);
1777 /* For AVID AVCI50, force width of 1440 to be able to select the correct SPS and PPS */
1778 if (cid == 0xd4d || cid == 0xd4e)
1781 } else if ((par->codec_tag == MKTAG('A', 'V', 'd', '1') ||
1782 par->codec_tag == MKTAG('A', 'V', 'j', '2') ||
1783 par->codec_tag == MKTAG('A', 'V', 'd', 'n')) &&
1787 num = avio_rb32(pb);
1788 den = avio_rb32(pb);
1789 if (num <= 0 || den <= 0)
1791 switch (avio_rb32(pb)) {
1793 if (den >= INT_MAX / 2)
1797 c->fc->streams[c->fc->nb_streams-1]->internal->display_aspect_ratio.num = num;
1798 c->fc->streams[c->fc->nb_streams-1]->internal->display_aspect_ratio.den = den;
1805 return mov_read_avid(c, pb, atom);
1808 static int mov_read_aclr(MOVContext *c, AVIOContext *pb, MOVAtom atom)
1812 uint64_t original_size;
1813 if (c->fc->nb_streams >= 1) {
1814 AVCodecParameters *par = c->fc->streams[c->fc->nb_streams-1]->codecpar;
1815 if (par->codec_id == AV_CODEC_ID_H264)
1817 if (atom.size == 16) {
1818 original_size = par->extradata_size;
1819 ret = mov_realloc_extradata(par, atom);
1821 length = mov_read_atom_into_extradata(c, pb, atom, par, par->extradata + original_size);
1822 if (length == atom.size) {
1823 const uint8_t range_value = par->extradata[original_size + 19];
1824 switch (range_value) {
1826 par->color_range = AVCOL_RANGE_MPEG;
1829 par->color_range = AVCOL_RANGE_JPEG;
1832 av_log(c->fc, AV_LOG_WARNING, "ignored unknown aclr value (%d)\n", range_value);
1835 ff_dlog(c->fc, "color_range: %d\n", par->color_range);
1837 /* For some reason the whole atom was not added to the extradata */
1838 av_log(c->fc, AV_LOG_ERROR, "aclr not decoded - incomplete atom\n");
1841 av_log(c->fc, AV_LOG_ERROR, "aclr not decoded - unable to add atom to extradata\n");
1844 av_log(c->fc, AV_LOG_WARNING, "aclr not decoded - unexpected size %"PRId64"\n", atom.size);
1851 static int mov_read_svq3(MOVContext *c, AVIOContext *pb, MOVAtom atom)
1853 return mov_read_extradata(c, pb, atom, AV_CODEC_ID_SVQ3);
1856 static int mov_read_wave(MOVContext *c, AVIOContext *pb, MOVAtom atom)
1861 if (c->fc->nb_streams < 1)
1863 st = c->fc->streams[c->fc->nb_streams-1];
1865 if ((uint64_t)atom.size > (1<<30))
1866 return AVERROR_INVALIDDATA;
1868 if (st->codecpar->codec_id == AV_CODEC_ID_QDM2 ||
1869 st->codecpar->codec_id == AV_CODEC_ID_QDMC ||
1870 st->codecpar->codec_id == AV_CODEC_ID_SPEEX) {
1871 // pass all frma atom to codec, needed at least for QDMC and QDM2
1872 ret = ff_get_extradata(c->fc, st->codecpar, pb, atom.size);
1875 } else if (atom.size > 8) { /* to read frma, esds atoms */
1876 if (st->codecpar->codec_id == AV_CODEC_ID_ALAC && atom.size >= 24) {
1878 ret = ffio_ensure_seekback(pb, 8);
1881 buffer = avio_rb64(pb);
1883 if ( (buffer & 0xFFFFFFFF) == MKBETAG('f','r','m','a')
1884 && buffer >> 32 <= atom.size
1885 && buffer >> 32 >= 8) {
1888 } else if (!st->codecpar->extradata_size) {
1889 #define ALAC_EXTRADATA_SIZE 36
1890 st->codecpar->extradata = av_mallocz(ALAC_EXTRADATA_SIZE + AV_INPUT_BUFFER_PADDING_SIZE);
1891 if (!st->codecpar->extradata)
1892 return AVERROR(ENOMEM);
1893 st->codecpar->extradata_size = ALAC_EXTRADATA_SIZE;
1894 AV_WB32(st->codecpar->extradata , ALAC_EXTRADATA_SIZE);
1895 AV_WB32(st->codecpar->extradata + 4, MKTAG('a','l','a','c'));
1896 AV_WB64(st->codecpar->extradata + 12, buffer);
1897 avio_read(pb, st->codecpar->extradata + 20, 16);
1898 avio_skip(pb, atom.size - 24);
1902 if ((ret = mov_read_default(c, pb, atom)) < 0)
1905 avio_skip(pb, atom.size);
1910 * This function reads atom content and puts data in extradata without tag
1911 * nor size unlike mov_read_extradata.
1913 static int mov_read_glbl(MOVContext *c, AVIOContext *pb, MOVAtom atom)
1918 if (c->fc->nb_streams < 1)
1920 st = c->fc->streams[c->fc->nb_streams-1];
1922 if ((uint64_t)atom.size > (1<<30))
1923 return AVERROR_INVALIDDATA;
1925 if (atom.size >= 10) {
1926 // Broken files created by legacy versions of libavformat will
1927 // wrap a whole fiel atom inside of a glbl atom.
1928 unsigned size = avio_rb32(pb);
1929 unsigned type = avio_rl32(pb);
1930 avio_seek(pb, -8, SEEK_CUR);
1931 if (type == MKTAG('f','i','e','l') && size == atom.size)
1932 return mov_read_default(c, pb, atom);
1934 if (st->codecpar->extradata_size > 1 && st->codecpar->extradata) {
1935 av_log(c->fc, AV_LOG_WARNING, "ignoring multiple glbl\n");
1938 ret = ff_get_extradata(c->fc, st->codecpar, pb, atom.size);
1941 if (atom.type == MKTAG('h','v','c','C') && st->codecpar->codec_tag == MKTAG('d','v','h','1'))
1942 /* HEVC-based Dolby Vision derived from hvc1.
1943 Happens to match with an identifier
1944 previously utilized for DV. Thus, if we have
1945 the hvcC extradata box available as specified,
1946 set codec to HEVC */
1947 st->codecpar->codec_id = AV_CODEC_ID_HEVC;
1952 static int mov_read_dvc1(MOVContext *c, AVIOContext *pb, MOVAtom atom)
1955 uint8_t profile_level;
1958 if (c->fc->nb_streams < 1)
1960 st = c->fc->streams[c->fc->nb_streams-1];
1962 if (atom.size >= (1<<28) || atom.size < 7)
1963 return AVERROR_INVALIDDATA;
1965 profile_level = avio_r8(pb);
1966 if ((profile_level & 0xf0) != 0xc0)
1969 avio_seek(pb, 6, SEEK_CUR);
1970 ret = ff_get_extradata(c->fc, st->codecpar, pb, atom.size - 7);
1978 * An strf atom is a BITMAPINFOHEADER struct. This struct is 40 bytes itself,
1979 * but can have extradata appended at the end after the 40 bytes belonging
1982 static int mov_read_strf(MOVContext *c, AVIOContext *pb, MOVAtom atom)
1987 if (c->fc->nb_streams < 1)
1989 if (atom.size <= 40)
1991 st = c->fc->streams[c->fc->nb_streams-1];
1993 if ((uint64_t)atom.size > (1<<30))
1994 return AVERROR_INVALIDDATA;
1997 ret = ff_get_extradata(c->fc, st->codecpar, pb, atom.size - 40);
2004 static int mov_read_stco(MOVContext *c, AVIOContext *pb, MOVAtom atom)
2007 MOVStreamContext *sc;
2008 unsigned int i, entries;
2010 if (c->trak_index < 0) {
2011 av_log(c->fc, AV_LOG_WARNING, "STCO outside TRAK\n");
2014 if (c->fc->nb_streams < 1)
2016 st = c->fc->streams[c->fc->nb_streams-1];
2019 avio_r8(pb); /* version */
2020 avio_rb24(pb); /* flags */
2022 entries = avio_rb32(pb);
2027 if (sc->chunk_offsets) {
2028 av_log(c->fc, AV_LOG_WARNING, "Ignoring duplicated STCO atom\n");
2031 av_free(sc->chunk_offsets);
2032 sc->chunk_count = 0;
2033 sc->chunk_offsets = av_malloc_array(entries, sizeof(*sc->chunk_offsets));
2034 if (!sc->chunk_offsets)
2035 return AVERROR(ENOMEM);
2036 sc->chunk_count = entries;
2038 if (atom.type == MKTAG('s','t','c','o'))
2039 for (i = 0; i < entries && !pb->eof_reached; i++)
2040 sc->chunk_offsets[i] = avio_rb32(pb);
2041 else if (atom.type == MKTAG('c','o','6','4'))
2042 for (i = 0; i < entries && !pb->eof_reached; i++)
2043 sc->chunk_offsets[i] = avio_rb64(pb);
2045 return AVERROR_INVALIDDATA;
2047 sc->chunk_count = i;
2049 if (pb->eof_reached) {
2050 av_log(c->fc, AV_LOG_WARNING, "reached eof, corrupted STCO atom\n");
2057 static int mov_codec_id(AVStream *st, uint32_t format)
2059 int id = ff_codec_get_id(ff_codec_movaudio_tags, format);
2062 ((format & 0xFFFF) == 'm' + ('s' << 8) ||
2063 (format & 0xFFFF) == 'T' + ('S' << 8)))
2064 id = ff_codec_get_id(ff_codec_wav_tags, av_bswap32(format) & 0xFFFF);
2066 if (st->codecpar->codec_type != AVMEDIA_TYPE_VIDEO && id > 0) {
2067 st->codecpar->codec_type = AVMEDIA_TYPE_AUDIO;
2068 } else if (st->codecpar->codec_type != AVMEDIA_TYPE_AUDIO &&
2069 /* skip old ASF MPEG-4 tag */
2070 format && format != MKTAG('m','p','4','s')) {
2071 id = ff_codec_get_id(ff_codec_movvideo_tags, format);
2073 id = ff_codec_get_id(ff_codec_bmp_tags, format);
2075 st->codecpar->codec_type = AVMEDIA_TYPE_VIDEO;
2076 else if (st->codecpar->codec_type == AVMEDIA_TYPE_DATA ||
2077 (st->codecpar->codec_type == AVMEDIA_TYPE_SUBTITLE &&
2078 st->codecpar->codec_id == AV_CODEC_ID_NONE)) {
2079 id = ff_codec_get_id(ff_codec_movsubtitle_tags, format);
2081 st->codecpar->codec_type = AVMEDIA_TYPE_SUBTITLE;
2083 id = ff_codec_get_id(ff_codec_movdata_tags, format);
2087 st->codecpar->codec_tag = format;
2092 static void mov_parse_stsd_video(MOVContext *c, AVIOContext *pb,
2093 AVStream *st, MOVStreamContext *sc)
2095 uint8_t codec_name[32] = { 0 };
2100 /* The first 16 bytes of the video sample description are already
2101 * read in ff_mov_read_stsd_entries() */
2102 stsd_start = avio_tell(pb) - 16;
2104 avio_rb16(pb); /* version */
2105 avio_rb16(pb); /* revision level */
2106 id = avio_rl32(pb); /* vendor */
2107 av_dict_set(&st->metadata, "vendor_id", av_fourcc2str(id), 0);
2108 avio_rb32(pb); /* temporal quality */
2109 avio_rb32(pb); /* spatial quality */
2111 st->codecpar->width = avio_rb16(pb); /* width */
2112 st->codecpar->height = avio_rb16(pb); /* height */
2114 avio_rb32(pb); /* horiz resolution */
2115 avio_rb32(pb); /* vert resolution */
2116 avio_rb32(pb); /* data size, always 0 */
2117 avio_rb16(pb); /* frames per samples */
2119 len = avio_r8(pb); /* codec name, pascal string */
2122 mov_read_mac_string(c, pb, len, codec_name, sizeof(codec_name));
2124 avio_skip(pb, 31 - len);
2127 av_dict_set(&st->metadata, "encoder", codec_name, 0);
2129 /* codec_tag YV12 triggers an UV swap in rawdec.c */
2130 if (!strncmp(codec_name, "Planar Y'CbCr 8-bit 4:2:0", 25)) {
2131 st->codecpar->codec_tag = MKTAG('I', '4', '2', '0');
2132 st->codecpar->width &= ~1;
2133 st->codecpar->height &= ~1;
2135 /* Flash Media Server uses tag H.263 with Sorenson Spark */
2136 if (st->codecpar->codec_tag == MKTAG('H','2','6','3') &&
2137 !strncmp(codec_name, "Sorenson H263", 13))
2138 st->codecpar->codec_id = AV_CODEC_ID_FLV1;
2140 st->codecpar->bits_per_coded_sample = avio_rb16(pb); /* depth */
2142 avio_seek(pb, stsd_start, SEEK_SET);
2144 if (ff_get_qtpalette(st->codecpar->codec_id, pb, sc->palette)) {
2145 st->codecpar->bits_per_coded_sample &= 0x1F;
2146 sc->has_palette = 1;
2150 static void mov_parse_stsd_audio(MOVContext *c, AVIOContext *pb,
2151 AVStream *st, MOVStreamContext *sc)
2153 int bits_per_sample, flags;
2154 uint16_t version = avio_rb16(pb);
2156 AVDictionaryEntry *compatible_brands = av_dict_get(c->fc->metadata, "compatible_brands", NULL, AV_DICT_MATCH_CASE);
2158 avio_rb16(pb); /* revision level */
2159 id = avio_rl32(pb); /* vendor */
2160 av_dict_set(&st->metadata, "vendor_id", av_fourcc2str(id), 0);
2162 st->codecpar->channels = avio_rb16(pb); /* channel count */
2163 st->codecpar->bits_per_coded_sample = avio_rb16(pb); /* sample size */
2164 av_log(c->fc, AV_LOG_TRACE, "audio channels %d\n", st->codecpar->channels);
2166 sc->audio_cid = avio_rb16(pb);
2167 avio_rb16(pb); /* packet size = 0 */
2169 st->codecpar->sample_rate = ((avio_rb32(pb) >> 16));
2171 // Read QT version 1 fields. In version 0 these do not exist.
2172 av_log(c->fc, AV_LOG_TRACE, "version =%d, isom =%d\n", version, c->isom);
2174 (compatible_brands && strstr(compatible_brands->value, "qt ")) ||
2175 (sc->stsd_version == 0 && version > 0)) {
2177 sc->samples_per_frame = avio_rb32(pb);
2178 avio_rb32(pb); /* bytes per packet */
2179 sc->bytes_per_frame = avio_rb32(pb);
2180 avio_rb32(pb); /* bytes per sample */
2181 } else if (version == 2) {
2182 avio_rb32(pb); /* sizeof struct only */
2183 st->codecpar->sample_rate = av_int2double(avio_rb64(pb));
2184 st->codecpar->channels = avio_rb32(pb);
2185 avio_rb32(pb); /* always 0x7F000000 */
2186 st->codecpar->bits_per_coded_sample = avio_rb32(pb);
2188 flags = avio_rb32(pb); /* lpcm format specific flag */
2189 sc->bytes_per_frame = avio_rb32(pb);
2190 sc->samples_per_frame = avio_rb32(pb);
2191 if (st->codecpar->codec_tag == MKTAG('l','p','c','m'))
2192 st->codecpar->codec_id =
2193 ff_mov_get_lpcm_codec_id(st->codecpar->bits_per_coded_sample,
2196 if (version == 0 || (version == 1 && sc->audio_cid != -2)) {
2197 /* can't correctly handle variable sized packet as audio unit */
2198 switch (st->codecpar->codec_id) {
2199 case AV_CODEC_ID_MP2:
2200 case AV_CODEC_ID_MP3:
2201 st->need_parsing = AVSTREAM_PARSE_FULL;
2207 if (sc->format == 0) {
2208 if (st->codecpar->bits_per_coded_sample == 8)
2209 st->codecpar->codec_id = mov_codec_id(st, MKTAG('r','a','w',' '));
2210 else if (st->codecpar->bits_per_coded_sample == 16)
2211 st->codecpar->codec_id = mov_codec_id(st, MKTAG('t','w','o','s'));
2214 switch (st->codecpar->codec_id) {
2215 case AV_CODEC_ID_PCM_S8:
2216 case AV_CODEC_ID_PCM_U8:
2217 if (st->codecpar->bits_per_coded_sample == 16)
2218 st->codecpar->codec_id = AV_CODEC_ID_PCM_S16BE;
2220 case AV_CODEC_ID_PCM_S16LE:
2221 case AV_CODEC_ID_PCM_S16BE:
2222 if (st->codecpar->bits_per_coded_sample == 8)
2223 st->codecpar->codec_id = AV_CODEC_ID_PCM_S8;
2224 else if (st->codecpar->bits_per_coded_sample == 24)
2225 st->codecpar->codec_id =
2226 st->codecpar->codec_id == AV_CODEC_ID_PCM_S16BE ?
2227 AV_CODEC_ID_PCM_S24BE : AV_CODEC_ID_PCM_S24LE;
2228 else if (st->codecpar->bits_per_coded_sample == 32)
2229 st->codecpar->codec_id =
2230 st->codecpar->codec_id == AV_CODEC_ID_PCM_S16BE ?
2231 AV_CODEC_ID_PCM_S32BE : AV_CODEC_ID_PCM_S32LE;
2233 /* set values for old format before stsd version 1 appeared */
2234 case AV_CODEC_ID_MACE3:
2235 sc->samples_per_frame = 6;
2236 sc->bytes_per_frame = 2 * st->codecpar->channels;
2238 case AV_CODEC_ID_MACE6:
2239 sc->samples_per_frame = 6;
2240 sc->bytes_per_frame = 1 * st->codecpar->channels;
2242 case AV_CODEC_ID_ADPCM_IMA_QT:
2243 sc->samples_per_frame = 64;
2244 sc->bytes_per_frame = 34 * st->codecpar->channels;
2246 case AV_CODEC_ID_GSM:
2247 sc->samples_per_frame = 160;
2248 sc->bytes_per_frame = 33;
2254 bits_per_sample = av_get_bits_per_sample(st->codecpar->codec_id);
2255 if (bits_per_sample && (bits_per_sample >> 3) * (uint64_t)st->codecpar->channels <= INT_MAX) {
2256 st->codecpar->bits_per_coded_sample = bits_per_sample;
2257 sc->sample_size = (bits_per_sample >> 3) * st->codecpar->channels;
2261 static void mov_parse_stsd_subtitle(MOVContext *c, AVIOContext *pb,
2262 AVStream *st, MOVStreamContext *sc,
2265 // ttxt stsd contains display flags, justification, background
2266 // color, fonts, and default styles, so fake an atom to read it
2267 MOVAtom fake_atom = { .size = size };
2268 // mp4s contains a regular esds atom
2269 if (st->codecpar->codec_tag != AV_RL32("mp4s"))
2270 mov_read_glbl(c, pb, fake_atom);
2271 st->codecpar->width = sc->width;
2272 st->codecpar->height = sc->height;
2275 static uint32_t yuv_to_rgba(uint32_t ycbcr)
2280 y = (ycbcr >> 16) & 0xFF;
2281 cr = (ycbcr >> 8) & 0xFF;
2284 b = av_clip_uint8((1164 * (y - 16) + 2018 * (cb - 128)) / 1000);
2285 g = av_clip_uint8((1164 * (y - 16) - 813 * (cr - 128) - 391 * (cb - 128)) / 1000);
2286 r = av_clip_uint8((1164 * (y - 16) + 1596 * (cr - 128) ) / 1000);
2288 return (r << 16) | (g << 8) | b;
2291 static int mov_rewrite_dvd_sub_extradata(AVStream *st)
2293 char buf[256] = {0};
2294 uint8_t *src = st->codecpar->extradata;
2297 if (st->codecpar->extradata_size != 64)
2300 if (st->codecpar->width > 0 && st->codecpar->height > 0)
2301 snprintf(buf, sizeof(buf), "size: %dx%d\n",
2302 st->codecpar->width, st->codecpar->height);
2303 av_strlcat(buf, "palette: ", sizeof(buf));
2305 for (i = 0; i < 16; i++) {
2306 uint32_t yuv = AV_RB32(src + i * 4);
2307 uint32_t rgba = yuv_to_rgba(yuv);
2309 av_strlcatf(buf, sizeof(buf), "%06"PRIx32"%s", rgba, i != 15 ? ", " : "");
2312 if (av_strlcat(buf, "\n", sizeof(buf)) >= sizeof(buf))
2315 ret = ff_alloc_extradata(st->codecpar, strlen(buf));
2318 memcpy(st->codecpar->extradata, buf, st->codecpar->extradata_size);
2323 static int mov_parse_stsd_data(MOVContext *c, AVIOContext *pb,
2324 AVStream *st, MOVStreamContext *sc,
2329 if (st->codecpar->codec_tag == MKTAG('t','m','c','d')) {
2330 if ((int)size != size)
2331 return AVERROR(ENOMEM);
2333 ret = ff_get_extradata(c->fc, st->codecpar, pb, size);
2337 MOVStreamContext *tmcd_ctx = st->priv_data;
2339 val = AV_RB32(st->codecpar->extradata + 4);
2340 tmcd_ctx->tmcd_flags = val;
2341 st->avg_frame_rate.num = AV_RB32(st->codecpar->extradata + 8); /* timescale */
2342 st->avg_frame_rate.den = AV_RB32(st->codecpar->extradata + 12); /* frameDuration */
2343 #if FF_API_LAVF_AVCTX
2344 FF_DISABLE_DEPRECATION_WARNINGS
2345 st->codec->time_base = av_inv_q(st->avg_frame_rate);
2346 FF_ENABLE_DEPRECATION_WARNINGS
2349 uint32_t len = AV_RB32(st->codecpar->extradata + 18); /* name atom length */
2350 uint32_t format = AV_RB32(st->codecpar->extradata + 22);
2351 if (format == AV_RB32("name") && (int64_t)size >= (int64_t)len + 18) {
2352 uint16_t str_size = AV_RB16(st->codecpar->extradata + 26); /* string length */
2353 if (str_size > 0 && size >= (int)str_size + 30 &&
2354 st->codecpar->extradata[30] /* Don't add empty string */) {
2355 char *reel_name = av_malloc(str_size + 1);
2357 return AVERROR(ENOMEM);
2358 memcpy(reel_name, st->codecpar->extradata + 30, str_size);
2359 reel_name[str_size] = 0; /* Add null terminator */
2360 av_dict_set(&st->metadata, "reel_name", reel_name,
2361 AV_DICT_DONT_STRDUP_VAL);
2367 /* other codec type, just skip (rtp, mp4s ...) */
2368 avio_skip(pb, size);
2373 static int mov_finalize_stsd_codec(MOVContext *c, AVIOContext *pb,
2374 AVStream *st, MOVStreamContext *sc)
2376 if (st->codecpar->codec_type == AVMEDIA_TYPE_AUDIO &&
2377 !st->codecpar->sample_rate && sc->time_scale > 1)
2378 st->codecpar->sample_rate = sc->time_scale;
2380 /* special codec parameters handling */
2381 switch (st->codecpar->codec_id) {
2382 #if CONFIG_DV_DEMUXER
2383 case AV_CODEC_ID_DVAUDIO:
2384 c->dv_fctx = avformat_alloc_context();
2386 av_log(c->fc, AV_LOG_ERROR, "dv demux context alloc error\n");
2387 return AVERROR(ENOMEM);
2389 c->dv_demux = avpriv_dv_init_demux(c->dv_fctx);
2391 av_log(c->fc, AV_LOG_ERROR, "dv demux context init error\n");
2392 return AVERROR(ENOMEM);
2394 sc->dv_audio_container = 1;
2395 st->codecpar->codec_id = AV_CODEC_ID_PCM_S16LE;
2398 /* no ifdef since parameters are always those */
2399 case AV_CODEC_ID_QCELP:
2400 st->codecpar->channels = 1;
2401 // force sample rate for qcelp when not stored in mov
2402 if (st->codecpar->codec_tag != MKTAG('Q','c','l','p'))
2403 st->codecpar->sample_rate = 8000;
2404 // FIXME: Why is the following needed for some files?
2405 sc->samples_per_frame = 160;
2406 if (!sc->bytes_per_frame)
2407 sc->bytes_per_frame = 35;
2409 case AV_CODEC_ID_AMR_NB:
2410 st->codecpar->channels = 1;
2411 /* force sample rate for amr, stsd in 3gp does not store sample rate */
2412 st->codecpar->sample_rate = 8000;
2414 case AV_CODEC_ID_AMR_WB:
2415 st->codecpar->channels = 1;
2416 st->codecpar->sample_rate = 16000;
2418 case AV_CODEC_ID_MP2:
2419 case AV_CODEC_ID_MP3:
2420 /* force type after stsd for m1a hdlr */
2421 st->codecpar->codec_type = AVMEDIA_TYPE_AUDIO;
2423 case AV_CODEC_ID_GSM:
2424 case AV_CODEC_ID_ADPCM_MS:
2425 case AV_CODEC_ID_ADPCM_IMA_WAV:
2426 case AV_CODEC_ID_ILBC:
2427 case AV_CODEC_ID_MACE3:
2428 case AV_CODEC_ID_MACE6:
2429 case AV_CODEC_ID_QDM2:
2430 st->codecpar->block_align = sc->bytes_per_frame;
2432 case AV_CODEC_ID_ALAC:
2433 if (st->codecpar->extradata_size == 36) {
2434 st->codecpar->channels = AV_RB8 (st->codecpar->extradata + 21);
2435 st->codecpar->sample_rate = AV_RB32(st->codecpar->extradata + 32);
2438 case AV_CODEC_ID_AC3:
2439 case AV_CODEC_ID_EAC3:
2440 case AV_CODEC_ID_MPEG1VIDEO:
2441 case AV_CODEC_ID_VC1:
2442 case AV_CODEC_ID_VP8:
2443 case AV_CODEC_ID_VP9:
2444 st->need_parsing = AVSTREAM_PARSE_FULL;
2446 case AV_CODEC_ID_AV1:
2447 st->need_parsing = AVSTREAM_PARSE_HEADERS;
2455 static int mov_skip_multiple_stsd(MOVContext *c, AVIOContext *pb,
2456 int codec_tag, int format,
2459 int video_codec_id = ff_codec_get_id(ff_codec_movvideo_tags, format);
2462 (codec_tag != format &&
2463 // AVID 1:1 samples with differing data format and codec tag exist
2464 (codec_tag != AV_RL32("AV1x") || format != AV_RL32("AVup")) &&
2465 // prores is allowed to have differing data format and codec tag
2466 codec_tag != AV_RL32("apcn") && codec_tag != AV_RL32("apch") &&
2468 codec_tag != AV_RL32("dvpp") && codec_tag != AV_RL32("dvcp") &&
2469 (c->fc->video_codec_id ? video_codec_id != c->fc->video_codec_id
2470 : codec_tag != MKTAG('j','p','e','g')))) {
2471 /* Multiple fourcc, we skip JPEG. This is not correct, we should
2472 * export it as a separate AVStream but this needs a few changes
2473 * in the MOV demuxer, patch welcome. */
2475 av_log(c->fc, AV_LOG_WARNING, "multiple fourcc not supported\n");
2476 avio_skip(pb, size);
2483 int ff_mov_read_stsd_entries(MOVContext *c, AVIOContext *pb, int entries)
2486 MOVStreamContext *sc;
2487 int pseudo_stream_id;
2489 av_assert0 (c->fc->nb_streams >= 1);
2490 st = c->fc->streams[c->fc->nb_streams-1];
2493 for (pseudo_stream_id = 0;
2494 pseudo_stream_id < entries && !pb->eof_reached;
2495 pseudo_stream_id++) {
2496 //Parsing Sample description table
2498 int ret, dref_id = 1;
2499 MOVAtom a = { AV_RL32("stsd") };
2500 int64_t start_pos = avio_tell(pb);
2501 int64_t size = avio_rb32(pb); /* size */
2502 uint32_t format = avio_rl32(pb); /* data format */
2505 avio_rb32(pb); /* reserved */
2506 avio_rb16(pb); /* reserved */
2507 dref_id = avio_rb16(pb);
2508 } else if (size <= 7) {
2509 av_log(c->fc, AV_LOG_ERROR,
2510 "invalid size %"PRId64" in stsd\n", size);
2511 return AVERROR_INVALIDDATA;
2514 if (mov_skip_multiple_stsd(c, pb, st->codecpar->codec_tag, format,
2515 size - (avio_tell(pb) - start_pos))) {
2520 sc->pseudo_stream_id = st->codecpar->codec_tag ? -1 : pseudo_stream_id;
2521 sc->dref_id= dref_id;
2522 sc->format = format;
2524 id = mov_codec_id(st, format);
2526 av_log(c->fc, AV_LOG_TRACE,
2527 "size=%"PRId64" 4CC=%s codec_type=%d\n", size,
2528 av_fourcc2str(format), st->codecpar->codec_type);
2530 st->codecpar->codec_id = id;
2531 if (st->codecpar->codec_type==AVMEDIA_TYPE_VIDEO) {
2532 mov_parse_stsd_video(c, pb, st, sc);
2533 } else if (st->codecpar->codec_type==AVMEDIA_TYPE_AUDIO) {
2534 mov_parse_stsd_audio(c, pb, st, sc);
2535 if (st->codecpar->sample_rate < 0) {
2536 av_log(c->fc, AV_LOG_ERROR, "Invalid sample rate %d\n", st->codecpar->sample_rate);
2537 return AVERROR_INVALIDDATA;
2539 } else if (st->codecpar->codec_type==AVMEDIA_TYPE_SUBTITLE){
2540 mov_parse_stsd_subtitle(c, pb, st, sc,
2541 size - (avio_tell(pb) - start_pos));
2543 ret = mov_parse_stsd_data(c, pb, st, sc,
2544 size - (avio_tell(pb) - start_pos));
2548 /* this will read extra atoms at the end (wave, alac, damr, avcC, hvcC, SMI ...) */
2549 a.size = size - (avio_tell(pb) - start_pos);
2551 if ((ret = mov_read_default(c, pb, a)) < 0)
2553 } else if (a.size > 0)
2554 avio_skip(pb, a.size);
2556 if (sc->extradata && st->codecpar->extradata) {
2557 int extra_size = st->codecpar->extradata_size;
2559 /* Move the current stream extradata to the stream context one. */
2560 sc->extradata_size[pseudo_stream_id] = extra_size;
2561 sc->extradata[pseudo_stream_id] = st->codecpar->extradata;
2562 st->codecpar->extradata = NULL;
2563 st->codecpar->extradata_size = 0;
2568 if (pb->eof_reached) {
2569 av_log(c->fc, AV_LOG_WARNING, "reached eof, corrupted STSD atom\n");
2576 static int mov_read_stsd(MOVContext *c, AVIOContext *pb, MOVAtom atom)
2579 MOVStreamContext *sc;
2582 if (c->fc->nb_streams < 1)
2584 st = c->fc->streams[c->fc->nb_streams - 1];
2587 sc->stsd_version = avio_r8(pb);
2588 avio_rb24(pb); /* flags */
2589 entries = avio_rb32(pb);
2591 /* Each entry contains a size (4 bytes) and format (4 bytes). */
2592 if (entries <= 0 || entries > atom.size / 8 || entries > 1024) {
2593 av_log(c->fc, AV_LOG_ERROR, "invalid STSD entries %d\n", entries);
2594 return AVERROR_INVALIDDATA;
2597 if (sc->extradata) {
2598 av_log(c->fc, AV_LOG_ERROR,
2599 "Duplicate stsd found in this track.\n");
2600 return AVERROR_INVALIDDATA;
2603 /* Prepare space for hosting multiple extradata. */
2604 sc->extradata = av_mallocz_array(entries, sizeof(*sc->extradata));
2606 return AVERROR(ENOMEM);
2608 sc->extradata_size = av_mallocz_array(entries, sizeof(*sc->extradata_size));
2609 if (!sc->extradata_size) {
2610 ret = AVERROR(ENOMEM);
2614 ret = ff_mov_read_stsd_entries(c, pb, entries);
2618 /* Restore back the primary extradata. */
2619 av_freep(&st->codecpar->extradata);
2620 st->codecpar->extradata_size = sc->extradata_size[0];
2621 if (sc->extradata_size[0]) {
2622 st->codecpar->extradata = av_mallocz(sc->extradata_size[0] + AV_INPUT_BUFFER_PADDING_SIZE);
2623 if (!st->codecpar->extradata)
2624 return AVERROR(ENOMEM);
2625 memcpy(st->codecpar->extradata, sc->extradata[0], sc->extradata_size[0]);
2628 return mov_finalize_stsd_codec(c, pb, st, sc);
2630 if (sc->extradata) {
2632 for (j = 0; j < sc->stsd_count; j++)
2633 av_freep(&sc->extradata[j]);
2636 av_freep(&sc->extradata);
2637 av_freep(&sc->extradata_size);
2641 static int mov_read_stsc(MOVContext *c, AVIOContext *pb, MOVAtom atom)
2644 MOVStreamContext *sc;
2645 unsigned int i, entries;
2647 if (c->fc->nb_streams < 1)
2649 st = c->fc->streams[c->fc->nb_streams-1];
2652 avio_r8(pb); /* version */
2653 avio_rb24(pb); /* flags */
2655 entries = avio_rb32(pb);
2656 if ((uint64_t)entries * 12 + 4 > atom.size)
2657 return AVERROR_INVALIDDATA;
2659 av_log(c->fc, AV_LOG_TRACE, "track[%u].stsc.entries = %u\n", c->fc->nb_streams - 1, entries);
2663 if (sc->stsc_data) {
2664 av_log(c->fc, AV_LOG_WARNING, "Ignoring duplicated STSC atom\n");
2667 av_free(sc->stsc_data);
2669 sc->stsc_data = av_malloc_array(entries, sizeof(*sc->stsc_data));
2671 return AVERROR(ENOMEM);
2673 for (i = 0; i < entries && !pb->eof_reached; i++) {
2674 sc->stsc_data[i].first = avio_rb32(pb);
2675 sc->stsc_data[i].count = avio_rb32(pb);
2676 sc->stsc_data[i].id = avio_rb32(pb);
2680 for (i = sc->stsc_count - 1; i < UINT_MAX; i--) {
2681 int64_t first_min = i + 1;
2682 if ((i+1 < sc->stsc_count && sc->stsc_data[i].first >= sc->stsc_data[i+1].first) ||
2683 (i > 0 && sc->stsc_data[i].first <= sc->stsc_data[i-1].first) ||
2684 sc->stsc_data[i].first < first_min ||
2685 sc->stsc_data[i].count < 1 ||
2686 sc->stsc_data[i].id < 1) {
2687 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);
2688 if (i+1 >= sc->stsc_count) {
2689 if (sc->stsc_data[i].count == 0 && i > 0) {
2693 sc->stsc_data[i].first = FFMAX(sc->stsc_data[i].first, first_min);
2694 if (i > 0 && sc->stsc_data[i].first <= sc->stsc_data[i-1].first)
2695 sc->stsc_data[i].first = FFMIN(sc->stsc_data[i-1].first + 1LL, INT_MAX);
2696 sc->stsc_data[i].count = FFMAX(sc->stsc_data[i].count, 1);
2697 sc->stsc_data[i].id = FFMAX(sc->stsc_data[i].id, 1);
2700 av_assert0(sc->stsc_data[i+1].first >= 2);
2701 // We replace this entry by the next valid
2702 sc->stsc_data[i].first = sc->stsc_data[i+1].first - 1;
2703 sc->stsc_data[i].count = sc->stsc_data[i+1].count;
2704 sc->stsc_data[i].id = sc->stsc_data[i+1].id;
2708 if (pb->eof_reached) {
2709 av_log(c->fc, AV_LOG_WARNING, "reached eof, corrupted STSC atom\n");
2716 static inline int mov_stsc_index_valid(unsigned int index, unsigned int count)
2718 return index < count - 1;
2721 /* Compute the samples value for the stsc entry at the given index. */
2722 static inline int64_t mov_get_stsc_samples(MOVStreamContext *sc, unsigned int index)
2726 if (mov_stsc_index_valid(index, sc->stsc_count))
2727 chunk_count = sc->stsc_data[index + 1].first - sc->stsc_data[index].first;
2729 // Validation for stsc / stco happens earlier in mov_read_stsc + mov_read_trak.
2730 av_assert0(sc->stsc_data[index].first <= sc->chunk_count);
2731 chunk_count = sc->chunk_count - (sc->stsc_data[index].first - 1);
2734 return sc->stsc_data[index].count * (int64_t)chunk_count;
2737 static int mov_read_stps(MOVContext *c, AVIOContext *pb, MOVAtom atom)
2740 MOVStreamContext *sc;
2741 unsigned i, entries;
2743 if (c->fc->nb_streams < 1)
2745 st = c->fc->streams[c->fc->nb_streams-1];
2748 avio_rb32(pb); // version + flags
2750 entries = avio_rb32(pb);
2752 av_log(c->fc, AV_LOG_WARNING, "Duplicated STPS atom\n");
2753 av_free(sc->stps_data);
2755 sc->stps_data = av_malloc_array(entries, sizeof(*sc->stps_data));
2757 return AVERROR(ENOMEM);
2759 for (i = 0; i < entries && !pb->eof_reached; i++) {
2760 sc->stps_data[i] = avio_rb32(pb);
2765 if (pb->eof_reached) {
2766 av_log(c->fc, AV_LOG_WARNING, "reached eof, corrupted STPS atom\n");
2773 static int mov_read_stss(MOVContext *c, AVIOContext *pb, MOVAtom atom)
2776 MOVStreamContext *sc;
2777 unsigned int i, entries;
2779 if (c->fc->nb_streams < 1)
2781 st = c->fc->streams[c->fc->nb_streams-1];
2784 avio_r8(pb); /* version */
2785 avio_rb24(pb); /* flags */
2787 entries = avio_rb32(pb);
2789 av_log(c->fc, AV_LOG_TRACE, "keyframe_count = %u\n", entries);
2792 sc->keyframe_absent = 1;
2793 if (!st->need_parsing && st->codecpar->codec_type == AVMEDIA_TYPE_VIDEO)
2794 st->need_parsing = AVSTREAM_PARSE_HEADERS;
2798 av_log(c->fc, AV_LOG_WARNING, "Duplicated STSS atom\n");
2799 if (entries >= UINT_MAX / sizeof(int))
2800 return AVERROR_INVALIDDATA;
2801 av_freep(&sc->keyframes);
2802 sc->keyframe_count = 0;
2803 sc->keyframes = av_malloc_array(entries, sizeof(*sc->keyframes));
2805 return AVERROR(ENOMEM);
2807 for (i = 0; i < entries && !pb->eof_reached; i++) {
2808 sc->keyframes[i] = avio_rb32(pb);
2811 sc->keyframe_count = i;
2813 if (pb->eof_reached) {
2814 av_log(c->fc, AV_LOG_WARNING, "reached eof, corrupted STSS atom\n");
2821 static int mov_read_stsz(MOVContext *c, AVIOContext *pb, MOVAtom atom)
2824 MOVStreamContext *sc;
2825 unsigned int i, entries, sample_size, field_size, num_bytes;
2830 if (c->fc->nb_streams < 1)
2832 st = c->fc->streams[c->fc->nb_streams-1];
2835 avio_r8(pb); /* version */
2836 avio_rb24(pb); /* flags */
2838 if (atom.type == MKTAG('s','t','s','z')) {
2839 sample_size = avio_rb32(pb);
2840 if (!sc->sample_size) /* do not overwrite value computed in stsd */
2841 sc->sample_size = sample_size;
2842 sc->stsz_sample_size = sample_size;
2846 avio_rb24(pb); /* reserved */
2847 field_size = avio_r8(pb);
2849 entries = avio_rb32(pb);
2851 av_log(c->fc, AV_LOG_TRACE, "sample_size = %u sample_count = %u\n", sc->sample_size, entries);
2853 sc->sample_count = entries;
2857 if (field_size != 4 && field_size != 8 && field_size != 16 && field_size != 32) {
2858 av_log(c->fc, AV_LOG_ERROR, "Invalid sample field size %u\n", field_size);
2859 return AVERROR_INVALIDDATA;
2864 if (entries >= (UINT_MAX - 4) / field_size)
2865 return AVERROR_INVALIDDATA;
2866 if (sc->sample_sizes)
2867 av_log(c->fc, AV_LOG_WARNING, "Duplicated STSZ atom\n");
2868 av_free(sc->sample_sizes);
2869 sc->sample_count = 0;
2870 sc->sample_sizes = av_malloc_array(entries, sizeof(*sc->sample_sizes));
2871 if (!sc->sample_sizes)
2872 return AVERROR(ENOMEM);
2874 num_bytes = (entries*field_size+4)>>3;
2876 buf = av_malloc(num_bytes+AV_INPUT_BUFFER_PADDING_SIZE);
2878 av_freep(&sc->sample_sizes);
2879 return AVERROR(ENOMEM);
2882 ret = ffio_read_size(pb, buf, num_bytes);
2884 av_freep(&sc->sample_sizes);
2886 av_log(c->fc, AV_LOG_WARNING, "STSZ atom truncated\n");
2890 init_get_bits(&gb, buf, 8*num_bytes);
2892 for (i = 0; i < entries && !pb->eof_reached; i++) {
2893 sc->sample_sizes[i] = get_bits_long(&gb, field_size);
2894 if (sc->sample_sizes[i] < 0) {
2896 av_log(c->fc, AV_LOG_ERROR, "Invalid sample size %d\n", sc->sample_sizes[i]);
2897 return AVERROR_INVALIDDATA;
2899 sc->data_size += sc->sample_sizes[i];
2902 sc->sample_count = i;
2906 if (pb->eof_reached) {
2907 av_log(c->fc, AV_LOG_WARNING, "reached eof, corrupted STSZ atom\n");
2914 static int mov_read_stts(MOVContext *c, AVIOContext *pb, MOVAtom atom)
2917 MOVStreamContext *sc;
2918 unsigned int i, entries, alloc_size = 0;
2919 int64_t duration = 0;
2920 int64_t total_sample_count = 0;
2922 if (c->fc->nb_streams < 1)
2924 st = c->fc->streams[c->fc->nb_streams-1];
2927 avio_r8(pb); /* version */
2928 avio_rb24(pb); /* flags */
2929 entries = avio_rb32(pb);
2931 av_log(c->fc, AV_LOG_TRACE, "track[%u].stts.entries = %u\n",
2932 c->fc->nb_streams-1, entries);
2935 av_log(c->fc, AV_LOG_WARNING, "Duplicated STTS atom\n");
2936 av_freep(&sc->stts_data);
2938 if (entries >= INT_MAX / sizeof(*sc->stts_data))
2939 return AVERROR(ENOMEM);
2941 for (i = 0; i < entries && !pb->eof_reached; i++) {
2942 int sample_duration;
2943 unsigned int sample_count;
2944 unsigned int min_entries = FFMIN(FFMAX(i + 1, 1024 * 1024), entries);
2945 MOVStts *stts_data = av_fast_realloc(sc->stts_data, &alloc_size,
2946 min_entries * sizeof(*sc->stts_data));
2948 av_freep(&sc->stts_data);
2950 return AVERROR(ENOMEM);
2952 sc->stts_count = min_entries;
2953 sc->stts_data = stts_data;
2955 sample_count = avio_rb32(pb);
2956 sample_duration = avio_rb32(pb);
2958 sc->stts_data[i].count= sample_count;
2959 sc->stts_data[i].duration= sample_duration;
2961 av_log(c->fc, AV_LOG_TRACE, "sample_count=%d, sample_duration=%d\n",
2962 sample_count, sample_duration);
2964 duration+=(int64_t)sample_duration*(uint64_t)sample_count;
2965 total_sample_count+=sample_count;
2971 duration <= INT64_MAX - sc->duration_for_fps &&
2972 total_sample_count <= INT_MAX - sc->nb_frames_for_fps) {
2973 sc->duration_for_fps += duration;
2974 sc->nb_frames_for_fps += total_sample_count;
2977 if (pb->eof_reached) {
2978 av_log(c->fc, AV_LOG_WARNING, "reached eof, corrupted STTS atom\n");
2982 st->nb_frames= total_sample_count;
2984 st->duration= FFMIN(st->duration, duration);
2985 sc->track_end = duration;
2989 static int mov_read_sdtp(MOVContext *c, AVIOContext *pb, MOVAtom atom)
2992 MOVStreamContext *sc;
2995 if (c->fc->nb_streams < 1)
2997 st = c->fc->streams[c->fc->nb_streams - 1];
3000 avio_r8(pb); /* version */
3001 avio_rb24(pb); /* flags */
3002 entries = atom.size - 4;
3004 av_log(c->fc, AV_LOG_TRACE, "track[%u].sdtp.entries = %" PRId64 "\n",
3005 c->fc->nb_streams - 1, entries);
3008 av_log(c->fc, AV_LOG_WARNING, "Duplicated SDTP atom\n");
3009 av_freep(&sc->sdtp_data);
3012 sc->sdtp_data = av_malloc(entries);
3014 return AVERROR(ENOMEM);
3016 for (i = 0; i < entries && !pb->eof_reached; i++)
3017 sc->sdtp_data[i] = avio_r8(pb);
3023 static void mov_update_dts_shift(MOVStreamContext *sc, int duration, void *logctx)
3026 if (duration == INT_MIN) {
3027 av_log(logctx, AV_LOG_WARNING, "mov_update_dts_shift(): dts_shift set to %d\n", INT_MAX);
3030 sc->dts_shift = FFMAX(sc->dts_shift, -duration);
3034 static int mov_read_ctts(MOVContext *c, AVIOContext *pb, MOVAtom atom)
3037 MOVStreamContext *sc;
3038 unsigned int i, entries, ctts_count = 0;
3040 if (c->fc->nb_streams < 1)
3042 st = c->fc->streams[c->fc->nb_streams-1];
3045 avio_r8(pb); /* version */
3046 avio_rb24(pb); /* flags */
3047 entries = avio_rb32(pb);
3049 av_log(c->fc, AV_LOG_TRACE, "track[%u].ctts.entries = %u\n", c->fc->nb_streams - 1, entries);
3053 if (entries >= UINT_MAX / sizeof(*sc->ctts_data))
3054 return AVERROR_INVALIDDATA;
3055 av_freep(&sc->ctts_data);
3056 sc->ctts_data = av_fast_realloc(NULL, &sc->ctts_allocated_size, entries * sizeof(*sc->ctts_data));
3058 return AVERROR(ENOMEM);
3060 for (i = 0; i < entries && !pb->eof_reached; i++) {
3061 int count = avio_rb32(pb);
3062 int duration = avio_rb32(pb);
3065 av_log(c->fc, AV_LOG_TRACE,
3066 "ignoring CTTS entry with count=%d duration=%d\n",
3071 add_ctts_entry(&sc->ctts_data, &ctts_count, &sc->ctts_allocated_size,
3074 av_log(c->fc, AV_LOG_TRACE, "count=%d, duration=%d\n",
3077 if (FFNABS(duration) < -(1<<28) && i+2<entries) {
3078 av_log(c->fc, AV_LOG_WARNING, "CTTS invalid\n");
3079 av_freep(&sc->ctts_data);
3085 mov_update_dts_shift(sc, duration, c->fc);
3088 sc->ctts_count = ctts_count;
3090 if (pb->eof_reached) {
3091 av_log(c->fc, AV_LOG_WARNING, "reached eof, corrupted CTTS atom\n");
3095 av_log(c->fc, AV_LOG_TRACE, "dts shift %d\n", sc->dts_shift);
3100 static int mov_read_sbgp(MOVContext *c, AVIOContext *pb, MOVAtom atom)
3103 MOVStreamContext *sc;
3104 unsigned int i, entries;
3106 uint32_t grouping_type;
3108 if (c->fc->nb_streams < 1)
3110 st = c->fc->streams[c->fc->nb_streams-1];
3113 version = avio_r8(pb); /* version */
3114 avio_rb24(pb); /* flags */
3115 grouping_type = avio_rl32(pb);
3116 if (grouping_type != MKTAG( 'r','a','p',' '))
3117 return 0; /* only support 'rap ' grouping */
3119 avio_rb32(pb); /* grouping_type_parameter */
3121 entries = avio_rb32(pb);
3125 av_log(c->fc, AV_LOG_WARNING, "Duplicated SBGP atom\n");
3126 av_free(sc->rap_group);
3127 sc->rap_group_count = 0;
3128 sc->rap_group = av_malloc_array(entries, sizeof(*sc->rap_group));
3130 return AVERROR(ENOMEM);
3132 for (i = 0; i < entries && !pb->eof_reached; i++) {
3133 sc->rap_group[i].count = avio_rb32(pb); /* sample_count */
3134 sc->rap_group[i].index = avio_rb32(pb); /* group_description_index */
3137 sc->rap_group_count = i;
3139 if (pb->eof_reached) {
3140 av_log(c->fc, AV_LOG_WARNING, "reached eof, corrupted SBGP atom\n");
3148 * Get ith edit list entry (media time, duration).
3150 static int get_edit_list_entry(MOVContext *mov,
3151 const MOVStreamContext *msc,
3152 unsigned int edit_list_index,
3153 int64_t *edit_list_media_time,
3154 int64_t *edit_list_duration,
3155 int64_t global_timescale)
3157 if (edit_list_index == msc->elst_count) {
3160 *edit_list_media_time = msc->elst_data[edit_list_index].time;
3161 *edit_list_duration = msc->elst_data[edit_list_index].duration;
3163 /* duration is in global timescale units;convert to msc timescale */
3164 if (global_timescale == 0) {
3165 avpriv_request_sample(mov->fc, "Support for mvhd.timescale = 0 with editlists");
3168 *edit_list_duration = av_rescale(*edit_list_duration, msc->time_scale,
3174 * Find the closest previous frame to the timestamp_pts, in e_old index
3175 * entries. Searching for just any frame / just key frames can be controlled by
3176 * last argument 'flag'.
3177 * Note that if ctts_data is not NULL, we will always search for a key frame
3178 * irrespective of the value of 'flag'. If we don't find any keyframe, we will
3179 * return the first frame of the video.
3181 * Here the timestamp_pts is considered to be a presentation timestamp and
3182 * the timestamp of index entries are considered to be decoding timestamps.
3184 * Returns 0 if successful in finding a frame, else returns -1.
3185 * Places the found index corresponding output arg.
3187 * If ctts_old is not NULL, then refines the searched entry by searching
3188 * backwards from the found timestamp, to find the frame with correct PTS.
3190 * Places the found ctts_index and ctts_sample in corresponding output args.
3192 static int find_prev_closest_index(AVStream *st,
3193 AVIndexEntry *e_old,
3197 int64_t timestamp_pts,
3200 int64_t* ctts_index,
3201 int64_t* ctts_sample)
3203 MOVStreamContext *msc = st->priv_data;
3204 AVIndexEntry *e_keep = st->internal->index_entries;
3205 int nb_keep = st->internal->nb_index_entries;
3207 int64_t index_ctts_count;
3211 // If dts_shift > 0, then all the index timestamps will have to be offset by
3212 // at least dts_shift amount to obtain PTS.
3213 // Hence we decrement the searched timestamp_pts by dts_shift to find the closest index element.
3214 if (msc->dts_shift > 0) {
3215 timestamp_pts -= msc->dts_shift;
3218 st->internal->index_entries = e_old;
3219 st->internal->nb_index_entries = nb_old;
3220 *index = av_index_search_timestamp(st, timestamp_pts, flag | AVSEEK_FLAG_BACKWARD);
3222 // Keep going backwards in the index entries until the timestamp is the same.
3224 for (i = *index; i > 0 && e_old[i].timestamp == e_old[i - 1].timestamp;
3226 if ((flag & AVSEEK_FLAG_ANY) ||
3227 (e_old[i - 1].flags & AVINDEX_KEYFRAME)) {
3233 // If we have CTTS then refine the search, by searching backwards over PTS
3234 // computed by adding corresponding CTTS durations to index timestamps.
3235 if (ctts_data && *index >= 0) {
3236 av_assert0(ctts_index);
3237 av_assert0(ctts_sample);
3238 // Find out the ctts_index for the found frame.
3241 for (index_ctts_count = 0; index_ctts_count < *index; index_ctts_count++) {
3242 if (*ctts_index < ctts_count) {
3244 if (ctts_data[*ctts_index].count == *ctts_sample) {
3251 while (*index >= 0 && (*ctts_index) >= 0 && (*ctts_index) < ctts_count) {
3252 // Find a "key frame" with PTS <= timestamp_pts (So that we can decode B-frames correctly).
3253 // No need to add dts_shift to the timestamp here becase timestamp_pts has already been
3254 // compensated by dts_shift above.
3255 if ((e_old[*index].timestamp + ctts_data[*ctts_index].duration) <= timestamp_pts &&
3256 (e_old[*index].flags & AVINDEX_KEYFRAME)) {
3261 if (*ctts_sample == 0) {
3263 if (*ctts_index >= 0)
3264 *ctts_sample = ctts_data[*ctts_index].count - 1;
3271 /* restore AVStream state*/
3272 st->internal->index_entries = e_keep;
3273 st->internal->nb_index_entries = nb_keep;
3274 return *index >= 0 ? 0 : -1;
3278 * Add index entry with the given values, to the end of st->internal->index_entries.
3279 * Returns the new size st->internal->index_entries if successful, else returns -1.
3281 * This function is similar to ff_add_index_entry in libavformat/utils.c
3282 * except that here we are always unconditionally adding an index entry to
3283 * the end, instead of searching the entries list and skipping the add if
3284 * there is an existing entry with the same timestamp.
3285 * This is needed because the mov_fix_index calls this func with the same
3286 * unincremented timestamp for successive discarded frames.
3288 static int64_t add_index_entry(AVStream *st, int64_t pos, int64_t timestamp,
3289 int size, int distance, int flags)
3291 AVIndexEntry *entries, *ie;
3293 const size_t min_size_needed = (st->internal->nb_index_entries + 1) * sizeof(AVIndexEntry);
3295 // Double the allocation each time, to lower memory fragmentation.
3296 // Another difference from ff_add_index_entry function.
3297 const size_t requested_size =
3298 min_size_needed > st->internal->index_entries_allocated_size ?
3299 FFMAX(min_size_needed, 2 * st->internal->index_entries_allocated_size) :
3302 if (st->internal->nb_index_entries + 1U >= UINT_MAX / sizeof(AVIndexEntry))
3305 entries = av_fast_realloc(st->internal->index_entries,
3306 &st->internal->index_entries_allocated_size,
3311 st->internal->index_entries= entries;
3313 index= st->internal->nb_index_entries++;
3314 ie= &entries[index];
3317 ie->timestamp = timestamp;
3318 ie->min_distance= distance;
3325 * Rewrite timestamps of index entries in the range [end_index - frame_duration_buffer_size, end_index)
3326 * by subtracting end_ts successively by the amounts given in frame_duration_buffer.
3328 static void fix_index_entry_timestamps(AVStream* st, int end_index, int64_t end_ts,
3329 int64_t* frame_duration_buffer,
3330 int frame_duration_buffer_size) {
3332 av_assert0(end_index >= 0 && end_index <= st->internal->nb_index_entries);
3333 for (i = 0; i < frame_duration_buffer_size; i++) {
3334 end_ts -= frame_duration_buffer[frame_duration_buffer_size - 1 - i];
3335 st->internal->index_entries[end_index - 1 - i].timestamp = end_ts;
3340 * Append a new ctts entry to ctts_data.
3341 * Returns the new ctts_count if successful, else returns -1.
3343 static int64_t add_ctts_entry(MOVStts** ctts_data, unsigned int* ctts_count, unsigned int* allocated_size,
3344 int count, int duration)
3346 MOVStts *ctts_buf_new;
3347 const size_t min_size_needed = (*ctts_count + 1) * sizeof(MOVStts);
3348 const size_t requested_size =
3349 min_size_needed > *allocated_size ?
3350 FFMAX(min_size_needed, 2 * (*allocated_size)) :
3353 if ((unsigned)(*ctts_count) >= UINT_MAX / sizeof(MOVStts) - 1)
3356 ctts_buf_new = av_fast_realloc(*ctts_data, allocated_size, requested_size);
3361 *ctts_data = ctts_buf_new;
3363 ctts_buf_new[*ctts_count].count = count;
3364 ctts_buf_new[*ctts_count].duration = duration;
3366 *ctts_count = (*ctts_count) + 1;
3370 #define MAX_REORDER_DELAY 16
3371 static void mov_estimate_video_delay(MOVContext *c, AVStream* st)
3373 MOVStreamContext *msc = st->priv_data;
3376 int ctts_sample = 0;
3377 int64_t pts_buf[MAX_REORDER_DELAY + 1]; // Circular buffer to sort pts.
3379 int j, r, num_swaps;
3381 for (j = 0; j < MAX_REORDER_DELAY + 1; j++)
3382 pts_buf[j] = INT64_MIN;
3384 if (st->codecpar->video_delay <= 0 && msc->ctts_data &&
3385 st->codecpar->codec_id == AV_CODEC_ID_H264) {
3386 st->codecpar->video_delay = 0;
3387 for (ind = 0; ind < st->internal->nb_index_entries && ctts_ind < msc->ctts_count; ++ind) {
3388 // Point j to the last elem of the buffer and insert the current pts there.
3390 buf_start = (buf_start + 1);
3391 if (buf_start == MAX_REORDER_DELAY + 1)
3394 pts_buf[j] = st->internal->index_entries[ind].timestamp + msc->ctts_data[ctts_ind].duration;
3396 // The timestamps that are already in the sorted buffer, and are greater than the
3397 // current pts, are exactly the timestamps that need to be buffered to output PTS
3398 // in correct sorted order.
3399 // Hence the video delay (which is the buffer size used to sort DTS and output PTS),
3400 // can be computed as the maximum no. of swaps any particular timestamp needs to
3401 // go through, to keep this buffer in sorted order.
3403 while (j != buf_start) {
3405 if (r < 0) r = MAX_REORDER_DELAY;
3406 if (pts_buf[j] < pts_buf[r]) {
3407 FFSWAP(int64_t, pts_buf[j], pts_buf[r]);
3414 st->codecpar->video_delay = FFMAX(st->codecpar->video_delay, num_swaps);
3417 if (ctts_sample == msc->ctts_data[ctts_ind].count) {
3422 av_log(c->fc, AV_LOG_DEBUG, "Setting codecpar->delay to %d for stream st: %d\n",
3423 st->codecpar->video_delay, st->index);
3427 static void mov_current_sample_inc(MOVStreamContext *sc)
3429 sc->current_sample++;
3430 sc->current_index++;
3431 if (sc->index_ranges &&
3432 sc->current_index >= sc->current_index_range->end &&
3433 sc->current_index_range->end) {
3434 sc->current_index_range++;
3435 sc->current_index = sc->current_index_range->start;
3439 static void mov_current_sample_dec(MOVStreamContext *sc)
3441 sc->current_sample--;
3442 sc->current_index--;
3443 if (sc->index_ranges &&
3444 sc->current_index < sc->current_index_range->start &&
3445 sc->current_index_range > sc->index_ranges) {
3446 sc->current_index_range--;
3447 sc->current_index = sc->current_index_range->end - 1;
3451 static void mov_current_sample_set(MOVStreamContext *sc, int current_sample)
3455 sc->current_sample = current_sample;
3456 sc->current_index = current_sample;
3457 if (!sc->index_ranges) {
3461 for (sc->current_index_range = sc->index_ranges;
3462 sc->current_index_range->end;
3463 sc->current_index_range++) {
3464 range_size = sc->current_index_range->end - sc->current_index_range->start;
3465 if (range_size > current_sample) {
3466 sc->current_index = sc->current_index_range->start + current_sample;
3469 current_sample -= range_size;
3474 * Fix st->internal->index_entries, so that it contains only the entries (and the entries
3475 * which are needed to decode them) that fall in the edit list time ranges.
3476 * Also fixes the timestamps of the index entries to match the timeline
3477 * specified the edit lists.
3479 static void mov_fix_index(MOVContext *mov, AVStream *st)
3481 MOVStreamContext *msc = st->priv_data;
3482 AVIndexEntry *e_old = st->internal->index_entries;
3483 int nb_old = st->internal->nb_index_entries;
3484 const AVIndexEntry *e_old_end = e_old + nb_old;
3485 const AVIndexEntry *current = NULL;
3486 MOVStts *ctts_data_old = msc->ctts_data;
3487 int64_t ctts_index_old = 0;
3488 int64_t ctts_sample_old = 0;
3489 int64_t ctts_count_old = msc->ctts_count;
3490 int64_t edit_list_media_time = 0;
3491 int64_t edit_list_duration = 0;
3492 int64_t frame_duration = 0;
3493 int64_t edit_list_dts_counter = 0;
3494 int64_t edit_list_dts_entry_end = 0;
3495 int64_t edit_list_start_ctts_sample = 0;
3497 int64_t curr_ctts = 0;
3498 int64_t empty_edits_sum_duration = 0;
3499 int64_t edit_list_index = 0;
3502 int64_t start_dts = 0;
3503 int64_t edit_list_start_encountered = 0;
3504 int64_t search_timestamp = 0;
3505 int64_t* frame_duration_buffer = NULL;
3506 int num_discarded_begin = 0;
3507 int first_non_zero_audio_edit = -1;
3508 int packet_skip_samples = 0;
3509 MOVIndexRange *current_index_range;
3511 int found_keyframe_after_edit = 0;
3512 int found_non_empty_edit = 0;
3514 if (!msc->elst_data || msc->elst_count <= 0 || nb_old <= 0) {
3518 // allocate the index ranges array
3519 msc->index_ranges = av_malloc((msc->elst_count + 1) * sizeof(msc->index_ranges[0]));
3520 if (!msc->index_ranges) {
3521 av_log(mov->fc, AV_LOG_ERROR, "Cannot allocate index ranges buffer\n");
3524 msc->current_index_range = msc->index_ranges;
3525 current_index_range = msc->index_ranges - 1;
3527 // Clean AVStream from traces of old index
3528 st->internal->index_entries = NULL;
3529 st->internal->index_entries_allocated_size = 0;
3530 st->internal->nb_index_entries = 0;
3532 // Clean ctts fields of MOVStreamContext
3533 msc->ctts_data = NULL;
3534 msc->ctts_count = 0;
3535 msc->ctts_index = 0;
3536 msc->ctts_sample = 0;
3537 msc->ctts_allocated_size = 0;
3539 // Reinitialize min_corrected_pts so that it can be computed again.
3540 msc->min_corrected_pts = -1;
3542 // If the dts_shift is positive (in case of negative ctts values in mov),
3543 // then negate the DTS by dts_shift
3544 if (msc->dts_shift > 0) {
3545 edit_list_dts_entry_end -= msc->dts_shift;
3546 av_log(mov->fc, AV_LOG_DEBUG, "Shifting DTS by %d because of negative CTTS.\n", msc->dts_shift);
3549 start_dts = edit_list_dts_entry_end;
3551 while (get_edit_list_entry(mov, msc, edit_list_index, &edit_list_media_time,
3552 &edit_list_duration, mov->time_scale)) {
3553 av_log(mov->fc, AV_LOG_DEBUG, "Processing st: %d, edit list %"PRId64" - media time: %"PRId64", duration: %"PRId64"\n",
3554 st->index, edit_list_index, edit_list_media_time, edit_list_duration);
3556 edit_list_dts_counter = edit_list_dts_entry_end;
3557 edit_list_dts_entry_end += edit_list_duration;
3558 num_discarded_begin = 0;
3559 if (!found_non_empty_edit && edit_list_media_time == -1) {
3560 empty_edits_sum_duration += edit_list_duration;
3563 found_non_empty_edit = 1;
3565 // If we encounter a non-negative edit list reset the skip_samples/start_pad fields and set them
3566 // according to the edit list below.
3567 if (st->codecpar->codec_type == AVMEDIA_TYPE_AUDIO) {
3568 if (first_non_zero_audio_edit < 0) {
3569 first_non_zero_audio_edit = 1;
3571 first_non_zero_audio_edit = 0;
3574 if (first_non_zero_audio_edit > 0)
3575 st->internal->skip_samples = msc->start_pad = 0;
3578 // While reordering frame index according to edit list we must handle properly
3579 // the scenario when edit list entry starts from none key frame.
3580 // We find closest previous key frame and preserve it and consequent frames in index.
3581 // All frames which are outside edit list entry time boundaries will be dropped after decoding.
3582 search_timestamp = edit_list_media_time;
3583 if (st->codecpar->codec_type == AVMEDIA_TYPE_AUDIO) {
3584 // Audio decoders like AAC need need a decoder delay samples previous to the current sample,
3585 // to correctly decode this frame. Hence for audio we seek to a frame 1 sec. before the
3586 // edit_list_media_time to cover the decoder delay.
3587 search_timestamp = FFMAX(search_timestamp - msc->time_scale, e_old[0].timestamp);
3590 if (find_prev_closest_index(st, e_old, nb_old, ctts_data_old, ctts_count_old, search_timestamp, 0,
3591 &index, &ctts_index_old, &ctts_sample_old) < 0) {
3592 av_log(mov->fc, AV_LOG_WARNING,
3593 "st: %d edit list: %"PRId64" Missing key frame while searching for timestamp: %"PRId64"\n",
3594 st->index, edit_list_index, search_timestamp);
3595 if (find_prev_closest_index(st, e_old, nb_old, ctts_data_old, ctts_count_old, search_timestamp, AVSEEK_FLAG_ANY,
3596 &index, &ctts_index_old, &ctts_sample_old) < 0) {
3597 av_log(mov->fc, AV_LOG_WARNING,
3598 "st: %d edit list %"PRId64" Cannot find an index entry before timestamp: %"PRId64".\n",
3599 st->index, edit_list_index, search_timestamp);
3602 ctts_sample_old = 0;
3605 current = e_old + index;
3606 edit_list_start_ctts_sample = ctts_sample_old;
3608 // Iterate over index and arrange it according to edit list
3609 edit_list_start_encountered = 0;
3610 found_keyframe_after_edit = 0;
3611 for (; current < e_old_end; current++, index++) {
3612 // check if frame outside edit list mark it for discard
3613 frame_duration = (current + 1 < e_old_end) ?
3614 ((current + 1)->timestamp - current->timestamp) : edit_list_duration;
3616 flags = current->flags;
3618 // frames (pts) before or after edit list
3619 curr_cts = current->timestamp + msc->dts_shift;
3622 if (ctts_data_old && ctts_index_old < ctts_count_old) {
3623 curr_ctts = ctts_data_old[ctts_index_old].duration;
3624 av_log(mov->fc, AV_LOG_DEBUG, "stts: %"PRId64" ctts: %"PRId64", ctts_index: %"PRId64", ctts_count: %"PRId64"\n",
3625 curr_cts, curr_ctts, ctts_index_old, ctts_count_old);
3626 curr_cts += curr_ctts;
3628 if (ctts_sample_old == ctts_data_old[ctts_index_old].count) {
3629 if (add_ctts_entry(&msc->ctts_data, &msc->ctts_count,
3630 &msc->ctts_allocated_size,
3631 ctts_data_old[ctts_index_old].count - edit_list_start_ctts_sample,
3632 ctts_data_old[ctts_index_old].duration) == -1) {
3633 av_log(mov->fc, AV_LOG_ERROR, "Cannot add CTTS entry %"PRId64" - {%"PRId64", %d}\n",
3635 ctts_data_old[ctts_index_old].count - edit_list_start_ctts_sample,
3636 ctts_data_old[ctts_index_old].duration);
3640 ctts_sample_old = 0;
3641 edit_list_start_ctts_sample = 0;
3645 if (curr_cts < edit_list_media_time || curr_cts >= (edit_list_duration + edit_list_media_time)) {
3646 if (st->codecpar->codec_type == AVMEDIA_TYPE_AUDIO && st->codecpar->codec_id != AV_CODEC_ID_VORBIS &&
3647 curr_cts < edit_list_media_time && curr_cts + frame_duration > edit_list_media_time &&
3648 first_non_zero_audio_edit > 0) {
3649 packet_skip_samples = edit_list_media_time - curr_cts;
3650 st->internal->skip_samples += packet_skip_samples;
3652 // Shift the index entry timestamp by packet_skip_samples to be correct.
3653 edit_list_dts_counter -= packet_skip_samples;
3654 if (edit_list_start_encountered == 0) {
3655 edit_list_start_encountered = 1;
3656 // Make timestamps strictly monotonically increasing for audio, by rewriting timestamps for
3657 // discarded packets.
3658 if (frame_duration_buffer) {
3659 fix_index_entry_timestamps(st, st->internal->nb_index_entries, edit_list_dts_counter,
3660 frame_duration_buffer, num_discarded_begin);
3661 av_freep(&frame_duration_buffer);
3665 av_log(mov->fc, AV_LOG_DEBUG, "skip %d audio samples from curr_cts: %"PRId64"\n", packet_skip_samples, curr_cts);
3667 flags |= AVINDEX_DISCARD_FRAME;
3668 av_log(mov->fc, AV_LOG_DEBUG, "drop a frame at curr_cts: %"PRId64" @ %"PRId64"\n", curr_cts, index);
3670 if (edit_list_start_encountered == 0) {
3671 num_discarded_begin++;
3672 frame_duration_buffer = av_realloc(frame_duration_buffer,
3673 num_discarded_begin * sizeof(int64_t));
3674 if (!frame_duration_buffer) {
3675 av_log(mov->fc, AV_LOG_ERROR, "Cannot reallocate frame duration buffer\n");
3678 frame_duration_buffer[num_discarded_begin - 1] = frame_duration;
3680 // Increment skip_samples for the first non-zero audio edit list
3681 if (st->codecpar->codec_type == AVMEDIA_TYPE_AUDIO &&
3682 first_non_zero_audio_edit > 0 && st->codecpar->codec_id != AV_CODEC_ID_VORBIS) {
3683 st->internal->skip_samples += frame_duration;
3688 if (msc->min_corrected_pts < 0) {
3689 msc->min_corrected_pts = edit_list_dts_counter + curr_ctts + msc->dts_shift;
3691 msc->min_corrected_pts = FFMIN(msc->min_corrected_pts, edit_list_dts_counter + curr_ctts + msc->dts_shift);
3693 if (edit_list_start_encountered == 0) {
3694 edit_list_start_encountered = 1;
3695 // Make timestamps strictly monotonically increasing by rewriting timestamps for
3696 // discarded packets.
3697 if (frame_duration_buffer) {
3698 fix_index_entry_timestamps(st, st->internal->nb_index_entries, edit_list_dts_counter,
3699 frame_duration_buffer, num_discarded_begin);
3700 av_freep(&frame_duration_buffer);
3705 if (add_index_entry(st, current->pos, edit_list_dts_counter, current->size,
3706 current->min_distance, flags) == -1) {
3707 av_log(mov->fc, AV_LOG_ERROR, "Cannot add index entry\n");
3711 // Update the index ranges array
3712 if (current_index_range < msc->index_ranges || index != current_index_range->end) {
3713 current_index_range++;
3714 current_index_range->start = index;
3716 current_index_range->end = index + 1;
3718 // Only start incrementing DTS in frame_duration amounts, when we encounter a frame in edit list.
3719 if (edit_list_start_encountered > 0) {
3720 edit_list_dts_counter = edit_list_dts_counter + frame_duration;
3723 // Break when found first key frame after edit entry completion
3724 if ((curr_cts + frame_duration >= (edit_list_duration + edit_list_media_time)) &&
3725 ((flags & AVINDEX_KEYFRAME) || ((st->codecpar->codec_type == AVMEDIA_TYPE_AUDIO)))) {
3726 if (ctts_data_old) {
3727 // If we have CTTS and this is the first keyframe after edit elist,
3728 // wait for one more, because there might be trailing B-frames after this I-frame
3729 // that do belong to the edit.
3730 if (st->codecpar->codec_type != AVMEDIA_TYPE_AUDIO && found_keyframe_after_edit == 0) {
3731 found_keyframe_after_edit = 1;
3734 if (ctts_sample_old != 0) {
3735 if (add_ctts_entry(&msc->ctts_data, &msc->ctts_count,
3736 &msc->ctts_allocated_size,
3737 ctts_sample_old - edit_list_start_ctts_sample,
3738 ctts_data_old[ctts_index_old].duration) == -1) {
3739 av_log(mov->fc, AV_LOG_ERROR, "Cannot add CTTS entry %"PRId64" - {%"PRId64", %d}\n",
3740 ctts_index_old, ctts_sample_old - edit_list_start_ctts_sample,
3741 ctts_data_old[ctts_index_old].duration);
3750 // If there are empty edits, then msc->min_corrected_pts might be positive
3751 // intentionally. So we subtract the sum duration of emtpy edits here.
3752 msc->min_corrected_pts -= empty_edits_sum_duration;
3754 // If the minimum pts turns out to be greater than zero after fixing the index, then we subtract the
3755 // dts by that amount to make the first pts zero.
3756 if (st->codecpar->codec_type == AVMEDIA_TYPE_VIDEO) {
3757 if (msc->min_corrected_pts > 0) {
3758 av_log(mov->fc, AV_LOG_DEBUG, "Offset DTS by %"PRId64" to make first pts zero.\n", msc->min_corrected_pts);
3759 for (i = 0; i < st->internal->nb_index_entries; ++i) {
3760 st->internal->index_entries[i].timestamp -= msc->min_corrected_pts;
3764 // Start time should be equal to zero or the duration of any empty edits.
3765 st->start_time = empty_edits_sum_duration;
3767 // Update av stream length, if it ends up shorter than the track's media duration
3768 st->duration = FFMIN(st->duration, edit_list_dts_entry_end - start_dts);
3769 msc->start_pad = st->internal->skip_samples;
3771 // Free the old index and the old CTTS structures
3773 av_free(ctts_data_old);
3774 av_freep(&frame_duration_buffer);
3776 // Null terminate the index ranges array
3777 current_index_range++;
3778 current_index_range->start = 0;
3779 current_index_range->end = 0;
3780 msc->current_index = msc->index_ranges[0].start;
3783 static void mov_build_index(MOVContext *mov, AVStream *st)
3785 MOVStreamContext *sc = st->priv_data;
3786 int64_t current_offset;
3787 int64_t current_dts = 0;
3788 unsigned int stts_index = 0;
3789 unsigned int stsc_index = 0;
3790 unsigned int stss_index = 0;
3791 unsigned int stps_index = 0;
3793 uint64_t stream_size = 0;
3794 MOVStts *ctts_data_old = sc->ctts_data;
3795 unsigned int ctts_count_old = sc->ctts_count;
3797 if (sc->elst_count) {
3798 int i, edit_start_index = 0, multiple_edits = 0;
3799 int64_t empty_duration = 0; // empty duration of the first edit list entry
3800 int64_t start_time = 0; // start time of the media
3802 for (i = 0; i < sc->elst_count; i++) {
3803 const MOVElst *e = &sc->elst_data[i];
3804 if (i == 0 && e->time == -1) {
3805 /* if empty, the first entry is the start time of the stream
3806 * relative to the presentation itself */
3807 empty_duration = e->duration;
3808 edit_start_index = 1;
3809 } else if (i == edit_start_index && e->time >= 0) {
3810 start_time = e->time;
3816 if (multiple_edits && !mov->advanced_editlist)
3817 av_log(mov->fc, AV_LOG_WARNING, "multiple edit list entries, "
3818 "Use -advanced_editlist to correctly decode otherwise "
3819 "a/v desync might occur\n");
3821 /* adjust first dts according to edit list */
3822 if ((empty_duration || start_time) && mov->time_scale > 0) {
3824 empty_duration = av_rescale(empty_duration, sc->time_scale, mov->time_scale);
3825 sc->time_offset = start_time - empty_duration;
3826 sc->min_corrected_pts = start_time;
3827 if (!mov->advanced_editlist)
3828 current_dts = -sc->time_offset;
3831 if (!multiple_edits && !mov->advanced_editlist &&
3832 st->codecpar->codec_id == AV_CODEC_ID_AAC && start_time > 0)
3833 sc->start_pad = start_time;
3836 /* only use old uncompressed audio chunk demuxing when stts specifies it */
3837 if (!(st->codecpar->codec_type == AVMEDIA_TYPE_AUDIO &&
3838 sc->stts_count == 1 && sc->stts_data[0].duration == 1)) {
3839 unsigned int current_sample = 0;
3840 unsigned int stts_sample = 0;
3841 unsigned int sample_size;
3842 unsigned int distance = 0;
3843 unsigned int rap_group_index = 0;
3844 unsigned int rap_group_sample = 0;
3845 int64_t last_dts = 0;
3846 int64_t dts_correction = 0;
3847 int rap_group_present = sc->rap_group_count && sc->rap_group;
3848 int key_off = (sc->keyframe_count && sc->keyframes[0] > 0) || (sc->stps_count && sc->stps_data[0] > 0);
3850 current_dts -= sc->dts_shift;
3851 last_dts = current_dts;
3853 if (!sc->sample_count || st->internal->nb_index_entries)
3855 if (sc->sample_count >= UINT_MAX / sizeof(*st->internal->index_entries) - st->internal->nb_index_entries)
3857 if (av_reallocp_array(&st->internal->index_entries,
3858 st->internal->nb_index_entries + sc->sample_count,
3859 sizeof(*st->internal->index_entries)) < 0) {
3860 st->internal->nb_index_entries = 0;
3863 st->internal->index_entries_allocated_size = (st->internal->nb_index_entries + sc->sample_count) * sizeof(*st->internal->index_entries);
3865 if (ctts_data_old) {
3866 // Expand ctts entries such that we have a 1-1 mapping with samples
3867 if (sc->sample_count >= UINT_MAX / sizeof(*sc->ctts_data))
3870 sc->ctts_allocated_size = 0;
3871 sc->ctts_data = av_fast_realloc(NULL, &sc->ctts_allocated_size,
3872 sc->sample_count * sizeof(*sc->ctts_data));
3873 if (!sc->ctts_data) {
3874 av_free(ctts_data_old);
3878 memset((uint8_t*)(sc->ctts_data), 0, sc->ctts_allocated_size);
3880 for (i = 0; i < ctts_count_old &&
3881 sc->ctts_count < sc->sample_count; i++)
3882 for (j = 0; j < ctts_data_old[i].count &&
3883 sc->ctts_count < sc->sample_count; j++)
3884 add_ctts_entry(&sc->ctts_data, &sc->ctts_count,
3885 &sc->ctts_allocated_size, 1,
3886 ctts_data_old[i].duration);
3887 av_free(ctts_data_old);
3890 for (i = 0; i < sc->chunk_count; i++) {
3891 int64_t next_offset = i+1 < sc->chunk_count ? sc->chunk_offsets[i+1] : INT64_MAX;
3892 current_offset = sc->chunk_offsets[i];
3893 while (mov_stsc_index_valid(stsc_index, sc->stsc_count) &&
3894 i + 1 == sc->stsc_data[stsc_index + 1].first)
3897 if (next_offset > current_offset && sc->sample_size>0 && sc->sample_size < sc->stsz_sample_size &&
3898 sc->stsc_data[stsc_index].count * (int64_t)sc->stsz_sample_size > next_offset - current_offset) {
3899 av_log(mov->fc, AV_LOG_WARNING, "STSZ sample size %d invalid (too large), ignoring\n", sc->stsz_sample_size);
3900 sc->stsz_sample_size = sc->sample_size;
3902 if (sc->stsz_sample_size>0 && sc->stsz_sample_size < sc->sample_size) {
3903 av_log(mov->fc, AV_LOG_WARNING, "STSZ sample size %d invalid (too small), ignoring\n", sc->stsz_sample_size);
3904 sc->stsz_sample_size = sc->sample_size;
3907 for (j = 0; j < sc->stsc_data[stsc_index].count; j++) {
3909 if (current_sample >= sc->sample_count) {
3910 av_log(mov->fc, AV_LOG_ERROR, "wrong sample count\n");
3914 if (!sc->keyframe_absent && (!sc->keyframe_count || current_sample+key_off == sc->keyframes[stss_index])) {
3916 if (stss_index + 1 < sc->keyframe_count)
3918 } else if (sc->stps_count && current_sample+key_off == sc->stps_data[stps_index]) {
3920 if (stps_index + 1 < sc->stps_count)
3923 if (rap_group_present && rap_group_index < sc->rap_group_count) {
3924 if (sc->rap_group[rap_group_index].index > 0)
3926 if (++rap_group_sample == sc->rap_group[rap_group_index].count) {
3927 rap_group_sample = 0;
3931 if (sc->keyframe_absent
3933 && !rap_group_present
3934 && (st->codecpar->codec_type == AVMEDIA_TYPE_AUDIO || (i==0 && j==0)))
3938 sample_size = sc->stsz_sample_size > 0 ? sc->stsz_sample_size : sc->sample_sizes[current_sample];
3939 if (sc->pseudo_stream_id == -1 ||
3940 sc->stsc_data[stsc_index].id - 1 == sc->pseudo_stream_id) {
3942 if (sample_size > 0x3FFFFFFF) {
3943 av_log(mov->fc, AV_LOG_ERROR, "Sample size %u is too large\n", sample_size);
3946 e = &st->internal->index_entries[st->internal->nb_index_entries++];
3947 e->pos = current_offset;
3948 e->timestamp = current_dts;
3949 e->size = sample_size;
3950 e->min_distance = distance;
3951 e->flags = keyframe ? AVINDEX_KEYFRAME : 0;
3952 av_log(mov->fc, AV_LOG_TRACE, "AVIndex stream %d, sample %u, offset %"PRIx64", dts %"PRId64", "
3953 "size %u, distance %u, keyframe %d\n", st->index, current_sample,
3954 current_offset, current_dts, sample_size, distance, keyframe);
3955 if (st->codecpar->codec_type == AVMEDIA_TYPE_VIDEO && st->internal->nb_index_entries < 100)
3956 ff_rfps_add_frame(mov->fc, st, current_dts);
3959 current_offset += sample_size;
3960 stream_size += sample_size;
3962 /* A negative sample duration is invalid based on the spec,
3963 * but some samples need it to correct the DTS. */
3964 if (sc->stts_data[stts_index].duration < 0) {
3965 av_log(mov->fc, AV_LOG_WARNING,
3966 "Invalid SampleDelta %d in STTS, at %d st:%d\n",
3967 sc->stts_data[stts_index].duration, stts_index,
3969 dts_correction += sc->stts_data[stts_index].duration - 1;
3970 sc->stts_data[stts_index].duration = 1;
3972 current_dts += sc->stts_data[stts_index].duration;
3973 if (!dts_correction || current_dts + dts_correction > last_dts) {
3974 current_dts += dts_correction;
3977 /* Avoid creating non-monotonous DTS */
3978 dts_correction += current_dts - last_dts - 1;
3979 current_dts = last_dts + 1;
3981 last_dts = current_dts;
3985 if (stts_index + 1 < sc->stts_count && stts_sample == sc->stts_data[stts_index].count) {
3991 if (st->duration > 0)
3992 st->codecpar->bit_rate = stream_size*8*sc->time_scale/st->duration;
3994 unsigned chunk_samples, total = 0;
3996 if (!sc->chunk_count)
3999 // compute total chunk count
4000 for (i = 0; i < sc->stsc_count; i++) {
4001 unsigned count, chunk_count;
4003 chunk_samples = sc->stsc_data[i].count;
4004 if (i != sc->stsc_count - 1 &&
4005 sc->samples_per_frame && chunk_samples % sc->samples_per_frame) {
4006 av_log(mov->fc, AV_LOG_ERROR, "error unaligned chunk\n");
4010 if (sc->samples_per_frame >= 160) { // gsm
4011 count = chunk_samples / sc->samples_per_frame;
4012 } else if (sc->samples_per_frame > 1) {
4013 unsigned samples = (1024/sc->samples_per_frame)*sc->samples_per_frame;
4014 count = (chunk_samples+samples-1) / samples;
4016 count = (chunk_samples+1023) / 1024;
4019 if (mov_stsc_index_valid(i, sc->stsc_count))
4020 chunk_count = sc->stsc_data[i+1].first - sc->stsc_data[i].first;
4022 chunk_count = sc->chunk_count - (sc->stsc_data[i].first - 1);
4023 total += chunk_count * count;
4026 av_log(mov->fc, AV_LOG_TRACE, "chunk count %u\n", total);
4027 if (total >= UINT_MAX / sizeof(*st->internal->index_entries) - st->internal->nb_index_entries)
4029 if (av_reallocp_array(&st->internal->index_entries,
4030 st->internal->nb_index_entries + total,
4031 sizeof(*st->internal->index_entries)) < 0) {
4032 st->internal->nb_index_entries = 0;
4035 st->internal->index_entries_allocated_size = (st->internal->nb_index_entries + total) * sizeof(*st->internal->index_entries);
4038 for (i = 0; i < sc->chunk_count; i++) {
4039 current_offset = sc->chunk_offsets[i];
4040 if (mov_stsc_index_valid(stsc_index, sc->stsc_count) &&
4041 i + 1 == sc->stsc_data[stsc_index + 1].first)
4043 chunk_samples = sc->stsc_data[stsc_index].count;
4045 while (chunk_samples > 0) {
4047 unsigned size, samples;
4049 if (sc->samples_per_frame > 1 && !sc->bytes_per_frame) {
4050 avpriv_request_sample(mov->fc,
4051 "Zero bytes per frame, but %d samples per frame",
4052 sc->samples_per_frame);
4056 if (sc->samples_per_frame >= 160) { // gsm
4057 samples = sc->samples_per_frame;
4058 size = sc->bytes_per_frame;
4060 if (sc->samples_per_frame > 1) {
4061 samples = FFMIN((1024 / sc->samples_per_frame)*
4062 sc->samples_per_frame, chunk_samples);
4063 size = (samples / sc->samples_per_frame) * sc->bytes_per_frame;
4065 samples = FFMIN(1024, chunk_samples);
4066 size = samples * sc->sample_size;
4070 if (st->internal->nb_index_entries >= total) {
4071 av_log(mov->fc, AV_LOG_ERROR, "wrong chunk count %u\n", total);
4074 if (size > 0x3FFFFFFF) {
4075 av_log(mov->fc, AV_LOG_ERROR, "Sample size %u is too large\n", size);
4078 e = &st->internal->index_entries[st->internal->nb_index_entries++];
4079 e->pos = current_offset;
4080 e->timestamp = current_dts;
4082 e->min_distance = 0;
4083 e->flags = AVINDEX_KEYFRAME;
4084 av_log(mov->fc, AV_LOG_TRACE, "AVIndex stream %d, chunk %u, offset %"PRIx64", dts %"PRId64", "
4085 "size %u, duration %u\n", st->index, i, current_offset, current_dts,
4088 current_offset += size;
4089 current_dts += samples;
4090 chunk_samples -= samples;
4095 if (!mov->ignore_editlist && mov->advanced_editlist) {
4096 // Fix index according to edit lists.
4097 mov_fix_index(mov, st);
4100 // Update start time of the stream.
4101 if (st->start_time == AV_NOPTS_VALUE && st->codecpar->codec_type == AVMEDIA_TYPE_VIDEO && st->internal->nb_index_entries > 0) {
4102 st->start_time = st->internal->index_entries[0].timestamp + sc->dts_shift;
4103 if (sc->ctts_data) {
4104 st->start_time += sc->ctts_data[0].duration;
4108 mov_estimate_video_delay(mov, st);
4111 static int test_same_origin(const char *src, const char *ref) {
4121 av_url_split(src_proto, sizeof(src_proto), src_auth, sizeof(src_auth), src_host, sizeof(src_host), &src_port, NULL, 0, src);
4122 av_url_split(ref_proto, sizeof(ref_proto), ref_auth, sizeof(ref_auth), ref_host, sizeof(ref_host), &ref_port, NULL, 0, ref);
4124 if (strlen(src) == 0) {
4126 } else if (strlen(src_auth) + 1 >= sizeof(src_auth) ||
4127 strlen(ref_auth) + 1 >= sizeof(ref_auth) ||
4128 strlen(src_host) + 1 >= sizeof(src_host) ||
4129 strlen(ref_host) + 1 >= sizeof(ref_host)) {
4131 } else if (strcmp(src_proto, ref_proto) ||
4132 strcmp(src_auth, ref_auth) ||
4133 strcmp(src_host, ref_host) ||
4134 src_port != ref_port) {
4140 static int mov_open_dref(MOVContext *c, AVIOContext **pb, const char *src, MOVDref *ref)
4142 /* try relative path, we do not try the absolute because it can leak information about our
4143 system to an attacker */
4144 if (ref->nlvl_to > 0 && ref->nlvl_from > 0) {
4145 char filename[1025];
4146 const char *src_path;
4149 /* find a source dir */
4150 src_path = strrchr(src, '/');
4156 /* find a next level down to target */
4157 for (i = 0, l = strlen(ref->path) - 1; l >= 0; l--)
4158 if (ref->path[l] == '/') {
4159 if (i == ref->nlvl_to - 1)
4165 /* compose filename if next level down to target was found */
4166 if (i == ref->nlvl_to - 1 && src_path - src < sizeof(filename)) {
4167 memcpy(filename, src, src_path - src);
4168 filename[src_path - src] = 0;
4170 for (i = 1; i < ref->nlvl_from; i++)
4171 av_strlcat(filename, "../", sizeof(filename));
4173 av_strlcat(filename, ref->path + l + 1, sizeof(filename));
4174 if (!c->use_absolute_path) {
4175 int same_origin = test_same_origin(src, filename);
4178 av_log(c->fc, AV_LOG_ERROR,
4179 "Reference with mismatching origin, %s not tried for security reasons, "
4180 "set demuxer option use_absolute_path to allow it anyway\n",
4182 return AVERROR(ENOENT);
4185 if (strstr(ref->path + l + 1, "..") ||
4186 strstr(ref->path + l + 1, ":") ||
4187 (ref->nlvl_from > 1 && same_origin < 0) ||
4188 (filename[0] == '/' && src_path == src))
4189 return AVERROR(ENOENT);
4192 if (strlen(filename) + 1 == sizeof(filename))
4193 return AVERROR(ENOENT);
4194 if (!c->fc->io_open(c->fc, pb, filename, AVIO_FLAG_READ, NULL))
4197 } else if (c->use_absolute_path) {
4198 av_log(c->fc, AV_LOG_WARNING, "Using absolute path on user request, "
4199 "this is a possible security issue\n");
4200 if (!c->fc->io_open(c->fc, pb, ref->path, AVIO_FLAG_READ, NULL))
4203 av_log(c->fc, AV_LOG_ERROR,
4204 "Absolute path %s not tried for security reasons, "
4205 "set demuxer option use_absolute_path to allow absolute paths\n",
4209 return AVERROR(ENOENT);
4212 static void fix_timescale(MOVContext *c, MOVStreamContext *sc)
4214 if (sc->time_scale <= 0) {
4215 av_log(c->fc, AV_LOG_WARNING, "stream %d, timescale not set\n", sc->ffindex);
4216 sc->time_scale = c->time_scale;
4217 if (sc->time_scale <= 0)
4222 static int mov_read_trak(MOVContext *c, AVIOContext *pb, MOVAtom atom)
4225 MOVStreamContext *sc;
4228 st = avformat_new_stream(c->fc, NULL);
4229 if (!st) return AVERROR(ENOMEM);
4231 sc = av_mallocz(sizeof(MOVStreamContext));
4232 if (!sc) return AVERROR(ENOMEM);
4235 st->codecpar->codec_type = AVMEDIA_TYPE_DATA;
4236 sc->ffindex = st->index;
4237 c->trak_index = st->index;
4239 if ((ret = mov_read_default(c, pb, atom)) < 0)
4244 // Here stsc refers to a chunk not described in stco. This is technically invalid,
4245 // but we can overlook it (clearing stsc) whenever stts_count == 0 (indicating no samples).
4246 if (!sc->chunk_count && !sc->stts_count && sc->stsc_count) {
4248 av_freep(&sc->stsc_data);
4252 if ((sc->chunk_count && (!sc->stts_count || !sc->stsc_count ||
4253 (!sc->sample_size && !sc->sample_count))) ||
4254 (!sc->chunk_count && sc->sample_count)) {
4255 av_log(c->fc, AV_LOG_ERROR, "stream %d, missing mandatory atoms, broken header\n",
4259 if (sc->stsc_count && sc->stsc_data[ sc->stsc_count - 1 ].first > sc->chunk_count) {
4260 av_log(c->fc, AV_LOG_ERROR, "stream %d, contradictionary STSC and STCO\n",
4262 return AVERROR_INVALIDDATA;
4265 fix_timescale(c, sc);
4267 avpriv_set_pts_info(st, 64, 1, sc->time_scale);
4269 mov_build_index(c, st);
4271 if (sc->dref_id-1 < sc->drefs_count && sc->drefs[sc->dref_id-1].path) {
4272 MOVDref *dref = &sc->drefs[sc->dref_id - 1];
4273 if (c->enable_drefs) {
4274 if (mov_open_dref(c, &sc->pb, c->fc->url, dref) < 0)
4275 av_log(c->fc, AV_LOG_ERROR,
4276 "stream %d, error opening alias: path='%s', dir='%s', "
4277 "filename='%s', volume='%s', nlvl_from=%d, nlvl_to=%d\n",
4278 st->index, dref->path, dref->dir, dref->filename,
4279 dref->volume, dref->nlvl_from, dref->nlvl_to);
4281 av_log(c->fc, AV_LOG_WARNING,
4282 "Skipped opening external track: "
4283 "stream %d, alias: path='%s', dir='%s', "
4284 "filename='%s', volume='%s', nlvl_from=%d, nlvl_to=%d."
4285 "Set enable_drefs to allow this.\n",
4286 st->index, dref->path, dref->dir, dref->filename,
4287 dref->volume, dref->nlvl_from, dref->nlvl_to);
4291 sc->pb_is_copied = 1;
4294 if (st->codecpar->codec_type == AVMEDIA_TYPE_VIDEO) {
4295 if (!st->sample_aspect_ratio.num && st->codecpar->width && st->codecpar->height &&
4296 sc->height && sc->width &&
4297 (st->codecpar->width != sc->width || st->codecpar->height != sc->height)) {
4298 st->sample_aspect_ratio = av_d2q(((double)st->codecpar->height * sc->width) /
4299 ((double)st->codecpar->width * sc->height), INT_MAX);
4302 #if FF_API_R_FRAME_RATE
4303 if (sc->stts_count == 1 || (sc->stts_count == 2 && sc->stts_data[1].count == 1))
4304 av_reduce(&st->r_frame_rate.num, &st->r_frame_rate.den,
4305 sc->time_scale, sc->stts_data[0].duration, INT_MAX);
4309 // done for ai5q, ai52, ai55, ai1q, ai12 and ai15.
4310 if (!st->codecpar->extradata_size && st->codecpar->codec_id == AV_CODEC_ID_H264 &&
4311 TAG_IS_AVCI(st->codecpar->codec_tag)) {
4312 ret = ff_generate_avci_extradata(st);
4317 switch (st->codecpar->codec_id) {
4318 #if CONFIG_H261_DECODER
4319 case AV_CODEC_ID_H261:
4321 #if CONFIG_H263_DECODER
4322 case AV_CODEC_ID_H263:
4324 #if CONFIG_MPEG4_DECODER
4325 case AV_CODEC_ID_MPEG4:
4327 st->codecpar->width = 0; /* let decoder init width/height */
4328 st->codecpar->height= 0;
4332 // If the duration of the mp3 packets is not constant, then they could need a parser
4333 if (st->codecpar->codec_id == AV_CODEC_ID_MP3
4334 && sc->stts_count > 3
4335 && sc->stts_count*10 > st->nb_frames
4336 && sc->time_scale == st->codecpar->sample_rate) {
4337 st->need_parsing = AVSTREAM_PARSE_FULL;
4339 /* Do not need those anymore. */
4340 av_freep(&sc->chunk_offsets);
4341 av_freep(&sc->sample_sizes);
4342 av_freep(&sc->keyframes);
4343 av_freep(&sc->stts_data);
4344 av_freep(&sc->stps_data);
4345 av_freep(&sc->elst_data);
4346 av_freep(&sc->rap_group);
4351 static int mov_read_ilst(MOVContext *c, AVIOContext *pb, MOVAtom atom)
4354 c->itunes_metadata = 1;
4355 ret = mov_read_default(c, pb, atom);
4356 c->itunes_metadata = 0;
4360 static int mov_read_keys(MOVContext *c, AVIOContext *pb, MOVAtom atom)
4369 count = avio_rb32(pb);
4370 if (count > UINT_MAX / sizeof(*c->meta_keys) - 1) {
4371 av_log(c->fc, AV_LOG_ERROR,
4372 "The 'keys' atom with the invalid key count: %"PRIu32"\n", count);
4373 return AVERROR_INVALIDDATA;
4376 c->meta_keys_count = count + 1;
4377 c->meta_keys = av_mallocz(c->meta_keys_count * sizeof(*c->meta_keys));
4379 return AVERROR(ENOMEM);
4381 for (i = 1; i <= count; ++i) {
4382 uint32_t key_size = avio_rb32(pb);
4383 uint32_t type = avio_rl32(pb);
4385 av_log(c->fc, AV_LOG_ERROR,
4386 "The key# %"PRIu32" in meta has invalid size:"
4387 "%"PRIu32"\n", i, key_size);
4388 return AVERROR_INVALIDDATA;
4391 if (type != MKTAG('m','d','t','a')) {
4392 avio_skip(pb, key_size);
4394 c->meta_keys[i] = av_mallocz(key_size + 1);
4395 if (!c->meta_keys[i])
4396 return AVERROR(ENOMEM);
4397 avio_read(pb, c->meta_keys[i], key_size);
4403 static int mov_read_custom(MOVContext *c, AVIOContext *pb, MOVAtom atom)
4405 int64_t end = av_sat_add64(avio_tell(pb), atom.size);
4406 uint8_t *key = NULL, *val = NULL, *mean = NULL;
4410 MOVStreamContext *sc;
4412 if (c->fc->nb_streams < 1)
4414 st = c->fc->streams[c->fc->nb_streams-1];
4417 for (i = 0; i < 3; i++) {
4421 if (end - avio_tell(pb) <= 12)
4424 len = avio_rb32(pb);
4425 tag = avio_rl32(pb);
4426 avio_skip(pb, 4); // flags
4428 if (len < 12 || len - 12 > end - avio_tell(pb))
4432 if (tag == MKTAG('m', 'e', 'a', 'n'))
4434 else if (tag == MKTAG('n', 'a', 'm', 'e'))
4436 else if (tag == MKTAG('d', 'a', 't', 'a') && len > 4) {
4446 *p = av_malloc(len + 1);
4448 ret = AVERROR(ENOMEM);
4451 ret = ffio_read_size(pb, *p, len);
4459 if (mean && key && val) {
4460 if (strcmp(key, "iTunSMPB") == 0) {
4461 int priming, remainder, samples;
4462 if(sscanf(val, "%*X %X %X %X", &priming, &remainder, &samples) == 3){
4463 if(priming>0 && priming<16384)
4464 sc->start_pad = priming;
4467 if (strcmp(key, "cdec") != 0) {
4468 av_dict_set(&c->fc->metadata, key, val,
4469 AV_DICT_DONT_STRDUP_KEY | AV_DICT_DONT_STRDUP_VAL);
4473 av_log(c->fc, AV_LOG_VERBOSE,
4474 "Unhandled or malformed custom metadata of size %"PRId64"\n", atom.size);
4477 avio_seek(pb, end, SEEK_SET);
4484 static int mov_read_meta(MOVContext *c, AVIOContext *pb, MOVAtom atom)
4486 while (atom.size > 8) {
4490 tag = avio_rl32(pb);
4492 if (tag == MKTAG('h','d','l','r')) {
4493 avio_seek(pb, -8, SEEK_CUR);
4495 return mov_read_default(c, pb, atom);
4501 // return 1 when matrix is identity, 0 otherwise
4502 #define IS_MATRIX_IDENT(matrix) \
4503 ( (matrix)[0][0] == (1 << 16) && \
4504 (matrix)[1][1] == (1 << 16) && \
4505 (matrix)[2][2] == (1 << 30) && \
4506 !(matrix)[0][1] && !(matrix)[0][2] && \
4507 !(matrix)[1][0] && !(matrix)[1][2] && \
4508 !(matrix)[2][0] && !(matrix)[2][1])
4510 static int mov_read_tkhd(MOVContext *c, AVIOContext *pb, MOVAtom atom)
4515 int display_matrix[3][3];
4516 int res_display_matrix[3][3] = { { 0 } };
4518 MOVStreamContext *sc;
4522 if (c->fc->nb_streams < 1)
4524 st = c->fc->streams[c->fc->nb_streams-1];
4527 // Each stream (trak) should have exactly 1 tkhd. This catches bad files and
4528 // avoids corrupting AVStreams mapped to an earlier tkhd.
4530 return AVERROR_INVALIDDATA;
4532 version = avio_r8(pb);
4533 flags = avio_rb24(pb);
4534 st->disposition |= (flags & MOV_TKHD_FLAG_ENABLED) ? AV_DISPOSITION_DEFAULT : 0;
4540 avio_rb32(pb); /* creation time */
4541 avio_rb32(pb); /* modification time */
4543 st->id = (int)avio_rb32(pb); /* track id (NOT 0 !)*/
4544 avio_rb32(pb); /* reserved */
4546 /* highlevel (considering edits) duration in movie timebase */
4547 (version == 1) ? avio_rb64(pb) : avio_rb32(pb);
4548 avio_rb32(pb); /* reserved */
4549 avio_rb32(pb); /* reserved */
4551 avio_rb16(pb); /* layer */
4552 avio_rb16(pb); /* alternate group */
4553 avio_rb16(pb); /* volume */
4554 avio_rb16(pb); /* reserved */
4556 //read in the display matrix (outlined in ISO 14496-12, Section 6.2.2)
4557 // they're kept in fixed point format through all calculations
4558 // save u,v,z to store the whole matrix in the AV_PKT_DATA_DISPLAYMATRIX
4559 // side data, but the scale factor is not needed to calculate aspect ratio
4560 for (i = 0; i < 3; i++) {
4561 display_matrix[i][0] = avio_rb32(pb); // 16.16 fixed point
4562 display_matrix[i][1] = avio_rb32(pb); // 16.16 fixed point
4563 display_matrix[i][2] = avio_rb32(pb); // 2.30 fixed point
4566 width = avio_rb32(pb); // 16.16 fixed point track width
4567 height = avio_rb32(pb); // 16.16 fixed point track height
4568 sc->width = width >> 16;
4569 sc->height = height >> 16;
4571 // apply the moov display matrix (after the tkhd one)
4572 for (i = 0; i < 3; i++) {
4573 const int sh[3] = { 16, 16, 30 };
4574 for (j = 0; j < 3; j++) {
4575 for (e = 0; e < 3; e++) {
4576 res_display_matrix[i][j] +=
4577 ((int64_t) display_matrix[i][e] *
4578 c->movie_display_matrix[e][j]) >> sh[e];
4583 // save the matrix when it is not the default identity
4584 if (!IS_MATRIX_IDENT(res_display_matrix)) {
4585 av_freep(&sc->display_matrix);
4586 sc->display_matrix = av_malloc(sizeof(int32_t) * 9);
4587 if (!sc->display_matrix)
4588 return AVERROR(ENOMEM);
4590 for (i = 0; i < 3; i++)
4591 for (j = 0; j < 3; j++)
4592 sc->display_matrix[i * 3 + j] = res_display_matrix[i][j];
4595 // transform the display width/height according to the matrix
4596 // to keep the same scale, use [width height 1<<16]
4597 if (width && height && sc->display_matrix) {
4598 double disp_transform[2];
4600 for (i = 0; i < 2; i++)
4601 disp_transform[i] = hypot(sc->display_matrix[0 + i],
4602 sc->display_matrix[3 + i]);
4604 if (disp_transform[0] > 1 && disp_transform[1] > 1 &&
4605 disp_transform[0] < (1<<24) && disp_transform[1] < (1<<24) &&
4606 fabs((disp_transform[0] / disp_transform[1]) - 1.0) > 0.01)
4607 st->sample_aspect_ratio = av_d2q(
4608 disp_transform[0] / disp_transform[1],
4614 static int mov_read_tfhd(MOVContext *c, AVIOContext *pb, MOVAtom atom)
4616 MOVFragment *frag = &c->fragment;
4617 MOVTrackExt *trex = NULL;
4618 int flags, track_id, i;
4619 MOVFragmentStreamInfo * frag_stream_info;
4621 avio_r8(pb); /* version */
4622 flags = avio_rb24(pb);
4624 track_id = avio_rb32(pb);
4626 return AVERROR_INVALIDDATA;
4627 for (i = 0; i < c->trex_count; i++)
4628 if (c->trex_data[i].track_id == track_id) {
4629 trex = &c->trex_data[i];
4633 av_log(c->fc, AV_LOG_WARNING, "could not find corresponding trex (id %u)\n", track_id);
4636 c->fragment.found_tfhd = 1;
4637 frag->track_id = track_id;
4638 set_frag_stream(&c->frag_index, track_id);
4640 frag->base_data_offset = flags & MOV_TFHD_BASE_DATA_OFFSET ?
4641 avio_rb64(pb) : flags & MOV_TFHD_DEFAULT_BASE_IS_MOOF ?
4642 frag->moof_offset : frag->implicit_offset;
4643 frag->stsd_id = flags & MOV_TFHD_STSD_ID ? avio_rb32(pb) : trex->stsd_id;
4645 frag->duration = flags & MOV_TFHD_DEFAULT_DURATION ?
4646 avio_rb32(pb) : trex->duration;
4647 frag->size = flags & MOV_TFHD_DEFAULT_SIZE ?
4648 avio_rb32(pb) : trex->size;
4649 frag->flags = flags & MOV_TFHD_DEFAULT_FLAGS ?
4650 avio_rb32(pb) : trex->flags;
4651 av_log(c->fc, AV_LOG_TRACE, "frag flags 0x%x\n", frag->flags);
4653 frag_stream_info = get_current_frag_stream_info(&c->frag_index);
4654 if (frag_stream_info)
4655 frag_stream_info->next_trun_dts = AV_NOPTS_VALUE;
4660 static int mov_read_chap(MOVContext *c, AVIOContext *pb, MOVAtom atom)
4665 num = atom.size / 4;
4666 if (!(new_tracks = av_malloc_array(num, sizeof(int))))
4667 return AVERROR(ENOMEM);
4669 av_free(c->chapter_tracks);
4670 c->chapter_tracks = new_tracks;
4671 c->nb_chapter_tracks = num;
4673 for (i = 0; i < num && !pb->eof_reached; i++)
4674 c->chapter_tracks[i] = avio_rb32(pb);
4679 static int mov_read_trex(MOVContext *c, AVIOContext *pb, MOVAtom atom)
4684 if ((uint64_t)c->trex_count+1 >= UINT_MAX / sizeof(*c->trex_data))
4685 return AVERROR_INVALIDDATA;
4686 if ((err = av_reallocp_array(&c->trex_data, c->trex_count + 1,
4687 sizeof(*c->trex_data))) < 0) {
4692 c->fc->duration = AV_NOPTS_VALUE; // the duration from mvhd is not representing the whole file when fragments are used.
4694 trex = &c->trex_data[c->trex_count++];
4695 avio_r8(pb); /* version */
4696 avio_rb24(pb); /* flags */
4697 trex->track_id = avio_rb32(pb);
4698 trex->stsd_id = avio_rb32(pb);
4699 trex->duration = avio_rb32(pb);
4700 trex->size = avio_rb32(pb);
4701 trex->flags = avio_rb32(pb);
4705 static int mov_read_tfdt(MOVContext *c, AVIOContext *pb, MOVAtom atom)
4707 MOVFragment *frag = &c->fragment;
4708 AVStream *st = NULL;
4709 MOVStreamContext *sc;
4711 MOVFragmentStreamInfo * frag_stream_info;
4712 int64_t base_media_decode_time;
4714 for (i = 0; i < c->fc->nb_streams; i++) {
4715 if (c->fc->streams[i]->id == frag->track_id) {
4716 st = c->fc->streams[i];
4721 av_log(c->fc, AV_LOG_WARNING, "could not find corresponding track id %u\n", frag->track_id);
4725 if (sc->pseudo_stream_id + 1 != frag->stsd_id && sc->pseudo_stream_id != -1)
4727 version = avio_r8(pb);
4728 avio_rb24(pb); /* flags */
4730 base_media_decode_time = avio_rb64(pb);
4732 base_media_decode_time = avio_rb32(pb);
4735 frag_stream_info = get_current_frag_stream_info(&c->frag_index);
4736 if (frag_stream_info)
4737 frag_stream_info->tfdt_dts = base_media_decode_time;
4738 sc->track_end = base_media_decode_time;
4743 static int mov_read_trun(MOVContext *c, AVIOContext *pb, MOVAtom atom)
4745 MOVFragment *frag = &c->fragment;
4746 AVStream *st = NULL;
4747 MOVStreamContext *sc;
4750 int64_t dts, pts = AV_NOPTS_VALUE;
4751 int data_offset = 0;
4752 unsigned entries, first_sample_flags = frag->flags;
4753 int flags, distance, i;
4754 int64_t prev_dts = AV_NOPTS_VALUE;
4755 int next_frag_index = -1, index_entry_pos;
4756 size_t requested_size;
4757 size_t old_ctts_allocated_size;
4758 AVIndexEntry *new_entries;
4759 MOVFragmentStreamInfo * frag_stream_info;
4761 if (!frag->found_tfhd) {
4762 av_log(c->fc, AV_LOG_ERROR, "trun track id unknown, no tfhd was found\n");
4763 return AVERROR_INVALIDDATA;
4766 for (i = 0; i < c->fc->nb_streams; i++) {
4767 if (c->fc->streams[i]->id == frag->track_id) {
4768 st = c->fc->streams[i];
4773 av_log(c->fc, AV_LOG_WARNING, "could not find corresponding track id %u\n", frag->track_id);
4777 if (sc->pseudo_stream_id+1 != frag->stsd_id && sc->pseudo_stream_id != -1)
4780 // Find the next frag_index index that has a valid index_entry for
4781 // the current track_id.
4783 // A valid index_entry means the trun for the fragment was read
4784 // and it's samples are in index_entries at the given position.
4785 // New index entries will be inserted before the index_entry found.
4786 index_entry_pos = st->internal->nb_index_entries;
4787 for (i = c->frag_index.current + 1; i < c->frag_index.nb_items; i++) {
4788 frag_stream_info = get_frag_stream_info(&c->frag_index, i, frag->track_id);
4789 if (frag_stream_info && frag_stream_info->index_entry >= 0) {
4790 next_frag_index = i;
4791 index_entry_pos = frag_stream_info->index_entry;
4795 av_assert0(index_entry_pos <= st->internal->nb_index_entries);
4797 avio_r8(pb); /* version */
4798 flags = avio_rb24(pb);
4799 entries = avio_rb32(pb);
4800 av_log(c->fc, AV_LOG_TRACE, "flags 0x%x entries %u\n", flags, entries);
4802 if ((uint64_t)entries+sc->ctts_count >= UINT_MAX/sizeof(*sc->ctts_data))
4803 return AVERROR_INVALIDDATA;
4804 if (flags & MOV_TRUN_DATA_OFFSET) data_offset = avio_rb32(pb);
4805 if (flags & MOV_TRUN_FIRST_SAMPLE_FLAGS) first_sample_flags = avio_rb32(pb);
4807 frag_stream_info = get_current_frag_stream_info(&c->frag_index);
4808 if (frag_stream_info) {
4809 if (frag_stream_info->next_trun_dts != AV_NOPTS_VALUE) {
4810 dts = frag_stream_info->next_trun_dts - sc->time_offset;
4811 } else if (frag_stream_info->first_tfra_pts != AV_NOPTS_VALUE &&
4812 c->use_mfra_for == FF_MOV_FLAG_MFRA_PTS) {
4813 pts = frag_stream_info->first_tfra_pts;
4814 av_log(c->fc, AV_LOG_DEBUG, "found mfra time %"PRId64
4815 ", using it for pts\n", pts);
4816 } else if (frag_stream_info->first_tfra_pts != AV_NOPTS_VALUE &&
4817 c->use_mfra_for == FF_MOV_FLAG_MFRA_DTS) {
4818 dts = frag_stream_info->first_tfra_pts;
4819 av_log(c->fc, AV_LOG_DEBUG, "found mfra time %"PRId64
4820 ", using it for dts\n", pts);
4821 } else if (frag_stream_info->sidx_pts != AV_NOPTS_VALUE) {
4822 // FIXME: sidx earliest_presentation_time is *PTS*, s.b.
4823 // pts = frag_stream_info->sidx_pts;
4824 dts = frag_stream_info->sidx_pts - sc->time_offset;
4825 av_log(c->fc, AV_LOG_DEBUG, "found sidx time %"PRId64
4826 ", using it for pts\n", pts);
4827 } else if (frag_stream_info->tfdt_dts != AV_NOPTS_VALUE) {
4828 dts = frag_stream_info->tfdt_dts - sc->time_offset;
4829 av_log(c->fc, AV_LOG_DEBUG, "found tfdt time %"PRId64
4830 ", using it for dts\n", dts);
4832 dts = sc->track_end - sc->time_offset;
4833 av_log(c->fc, AV_LOG_DEBUG, "found track end time %"PRId64
4834 ", using it for dts\n", dts);
4837 dts = sc->track_end - sc->time_offset;
4838 av_log(c->fc, AV_LOG_DEBUG, "found track end time %"PRId64
4839 ", using it for dts\n", dts);
4841 offset = frag->base_data_offset + data_offset;
4843 av_log(c->fc, AV_LOG_TRACE, "first sample flags 0x%x\n", first_sample_flags);
4845 // realloc space for new index entries
4846 if((uint64_t)st->internal->nb_index_entries + entries >= UINT_MAX / sizeof(AVIndexEntry)) {
4847 entries = UINT_MAX / sizeof(AVIndexEntry) - st->internal->nb_index_entries;
4848 av_log(c->fc, AV_LOG_ERROR, "Failed to add index entry\n");
4853 requested_size = (st->internal->nb_index_entries + entries) * sizeof(AVIndexEntry);
4854 new_entries = av_fast_realloc(st->internal->index_entries,
4855 &st->internal->index_entries_allocated_size,
4858 return AVERROR(ENOMEM);
4859 st->internal->index_entries= new_entries;
4861 requested_size = (st->internal->nb_index_entries + entries) * sizeof(*sc->ctts_data);
4862 old_ctts_allocated_size = sc->ctts_allocated_size;
4863 ctts_data = av_fast_realloc(sc->ctts_data, &sc->ctts_allocated_size,
4866 return AVERROR(ENOMEM);
4867 sc->ctts_data = ctts_data;
4869 // In case there were samples without ctts entries, ensure they get
4870 // zero valued entries. This ensures clips which mix boxes with and
4871 // without ctts entries don't pickup uninitialized data.
4872 memset((uint8_t*)(sc->ctts_data) + old_ctts_allocated_size, 0,
4873 sc->ctts_allocated_size - old_ctts_allocated_size);
4875 if (index_entry_pos < st->internal->nb_index_entries) {
4876 // Make hole in index_entries and ctts_data for new samples
4877 memmove(st->internal->index_entries + index_entry_pos + entries,
4878 st->internal->index_entries + index_entry_pos,
4879 sizeof(*st->internal->index_entries) *
4880 (st->internal->nb_index_entries - index_entry_pos));
4881 memmove(sc->ctts_data + index_entry_pos + entries,
4882 sc->ctts_data + index_entry_pos,
4883 sizeof(*sc->ctts_data) * (sc->ctts_count - index_entry_pos));
4884 if (index_entry_pos < sc->current_sample) {
4885 sc->current_sample += entries;
4889 st->internal->nb_index_entries += entries;
4890 sc->ctts_count = st->internal->nb_index_entries;
4892 // Record the index_entry position in frag_index of this fragment
4893 if (frag_stream_info)
4894 frag_stream_info->index_entry = index_entry_pos;
4896 if (index_entry_pos > 0)
4897 prev_dts = st->internal->index_entries[index_entry_pos-1].timestamp;
4899 for (i = 0; i < entries && !pb->eof_reached; i++) {
4900 unsigned sample_size = frag->size;
4901 int sample_flags = i ? frag->flags : first_sample_flags;
4902 unsigned sample_duration = frag->duration;
4903 unsigned ctts_duration = 0;
4905 int index_entry_flags = 0;
4907 if (flags & MOV_TRUN_SAMPLE_DURATION) sample_duration = avio_rb32(pb);
4908 if (flags & MOV_TRUN_SAMPLE_SIZE) sample_size = avio_rb32(pb);
4909 if (flags & MOV_TRUN_SAMPLE_FLAGS) sample_flags = avio_rb32(pb);
4910 if (flags & MOV_TRUN_SAMPLE_CTS) ctts_duration = avio_rb32(pb);
4912 mov_update_dts_shift(sc, ctts_duration, c->fc);
4913 if (pts != AV_NOPTS_VALUE) {
4914 dts = pts - sc->dts_shift;
4915 if (flags & MOV_TRUN_SAMPLE_CTS) {
4916 dts -= ctts_duration;
4918 dts -= sc->time_offset;
4920 av_log(c->fc, AV_LOG_DEBUG,
4921 "pts %"PRId64" calculated dts %"PRId64
4922 " sc->dts_shift %d ctts.duration %d"
4923 " sc->time_offset %"PRId64
4924 " flags & MOV_TRUN_SAMPLE_CTS %d\n",
4926 sc->dts_shift, ctts_duration,
4927 sc->time_offset, flags & MOV_TRUN_SAMPLE_CTS);
4928 pts = AV_NOPTS_VALUE;
4931 if (st->codecpar->codec_type == AVMEDIA_TYPE_AUDIO)
4935 !(sample_flags & (MOV_FRAG_SAMPLE_FLAG_IS_NON_SYNC |
4936 MOV_FRAG_SAMPLE_FLAG_DEPENDS_YES));
4939 index_entry_flags |= AVINDEX_KEYFRAME;
4941 // Fragments can overlap in time. Discard overlapping frames after
4943 if (prev_dts >= dts)
4944 index_entry_flags |= AVINDEX_DISCARD_FRAME;
4946 st->internal->index_entries[index_entry_pos].pos = offset;
4947 st->internal->index_entries[index_entry_pos].timestamp = dts;
4948 st->internal->index_entries[index_entry_pos].size= sample_size;
4949 st->internal->index_entries[index_entry_pos].min_distance= distance;
4950 st->internal->index_entries[index_entry_pos].flags = index_entry_flags;
4952 sc->ctts_data[index_entry_pos].count = 1;
4953 sc->ctts_data[index_entry_pos].duration = ctts_duration;
4956 av_log(c->fc, AV_LOG_TRACE, "AVIndex stream %d, sample %d, offset %"PRIx64", dts %"PRId64", "
4957 "size %u, distance %d, keyframe %d\n", st->index,
4958 index_entry_pos, offset, dts, sample_size, distance, keyframe);
4960 dts += sample_duration;
4961 offset += sample_size;
4962 sc->data_size += sample_size;
4964 if (sample_duration <= INT64_MAX - sc->duration_for_fps &&
4965 1 <= INT_MAX - sc->nb_frames_for_fps
4967 sc->duration_for_fps += sample_duration;
4968 sc->nb_frames_for_fps ++;
4971 if (frag_stream_info)
4972 frag_stream_info->next_trun_dts = dts + sc->time_offset;
4974 // EOF found before reading all entries. Fix the hole this would
4975 // leave in index_entries and ctts_data
4976 int gap = entries - i;
4977 memmove(st->internal->index_entries + index_entry_pos,
4978 st->internal->index_entries + index_entry_pos + gap,
4979 sizeof(*st->internal->index_entries) *
4980 (st->internal->nb_index_entries - (index_entry_pos + gap)));
4981 memmove(sc->ctts_data + index_entry_pos,
4982 sc->ctts_data + index_entry_pos + gap,
4983 sizeof(*sc->ctts_data) *
4984 (sc->ctts_count - (index_entry_pos + gap)));
4986 st->internal->nb_index_entries -= gap;
4987 sc->ctts_count -= gap;
4988 if (index_entry_pos < sc->current_sample) {
4989 sc->current_sample -= gap;
4994 // The end of this new fragment may overlap in time with the start
4995 // of the next fragment in index_entries. Mark the samples in the next
4996 // fragment that overlap with AVINDEX_DISCARD_FRAME
4997 prev_dts = AV_NOPTS_VALUE;
4998 if (index_entry_pos > 0)
4999 prev_dts = st->internal->index_entries[index_entry_pos-1].timestamp;
5000 for (i = index_entry_pos; i < st->internal->nb_index_entries; i++) {
5001 if (prev_dts < st->internal->index_entries[i].timestamp)
5003 st->internal->index_entries[i].flags |= AVINDEX_DISCARD_FRAME;
5006 // If a hole was created to insert the new index_entries into,
5007 // the index_entry recorded for all subsequent moof must
5008 // be incremented by the number of entries inserted.
5009 fix_frag_index_entries(&c->frag_index, next_frag_index,
5010 frag->track_id, entries);
5012 if (pb->eof_reached) {
5013 av_log(c->fc, AV_LOG_WARNING, "reached eof, corrupted TRUN atom\n");
5017 frag->implicit_offset = offset;
5019 sc->track_end = dts + sc->time_offset;
5020 if (st->duration < sc->track_end)
5021 st->duration = sc->track_end;
5026 static int mov_read_sidx(MOVContext *c, AVIOContext *pb, MOVAtom atom)
5028 int64_t stream_size = avio_size(pb);
5029 int64_t offset = av_sat_add64(avio_tell(pb), atom.size), pts, timestamp;
5030 uint8_t version, is_complete;
5032 unsigned i, j, track_id, item_count;
5033 AVStream *st = NULL;
5034 AVStream *ref_st = NULL;
5035 MOVStreamContext *sc, *ref_sc = NULL;
5036 AVRational timescale;
5038 version = avio_r8(pb);
5040 avpriv_request_sample(c->fc, "sidx version %u", version);
5044 avio_rb24(pb); // flags
5046 track_id = avio_rb32(pb); // Reference ID
5047 for (i = 0; i < c->fc->nb_streams; i++) {
5048 if (c->fc->streams[i]->id == track_id) {
5049 st = c->fc->streams[i];
5054 av_log(c->fc, AV_LOG_WARNING, "could not find corresponding track id %d\n", track_id);
5060 timescale = av_make_q(1, avio_rb32(pb));
5062 if (timescale.den <= 0) {
5063 av_log(c->fc, AV_LOG_ERROR, "Invalid sidx timescale 1/%d\n", timescale.den);
5064 return AVERROR_INVALIDDATA;
5068 pts = avio_rb32(pb);
5069 offadd= avio_rb32(pb);
5071 pts = avio_rb64(pb);
5072 offadd= avio_rb64(pb);
5074 if (av_sat_add64(offset, offadd) != offset + (uint64_t)offadd)
5075 return AVERROR_INVALIDDATA;
5077 offset += (uint64_t)offadd;
5079 avio_rb16(pb); // reserved
5081 item_count = avio_rb16(pb);
5083 for (i = 0; i < item_count; i++) {
5085 MOVFragmentStreamInfo * frag_stream_info;
5086 uint32_t size = avio_rb32(pb);
5087 uint32_t duration = avio_rb32(pb);
5088 if (size & 0x80000000) {
5089 avpriv_request_sample(c->fc, "sidx reference_type 1");
5090 return AVERROR_PATCHWELCOME;
5092 avio_rb32(pb); // sap_flags
5093 timestamp = av_rescale_q(pts, timescale, st->time_base);
5095 index = update_frag_index(c, offset);
5096 frag_stream_info = get_frag_stream_info(&c->frag_index, index, track_id);
5097 if (frag_stream_info)
5098 frag_stream_info->sidx_pts = timestamp;
5100 if (av_sat_add64(offset, size) != offset + size ||
5101 av_sat_add64(pts, duration) != pts + (uint64_t)duration
5103 return AVERROR_INVALIDDATA;
5108 st->duration = sc->track_end = pts;
5112 // See if the remaining bytes are just an mfra which we can ignore.
5113 is_complete = offset == stream_size;
5114 if (!is_complete && (pb->seekable & AVIO_SEEKABLE_NORMAL)) {
5116 int64_t original_pos = avio_tell(pb);
5117 if (!c->have_read_mfra_size) {
5118 if ((ret = avio_seek(pb, stream_size - 4, SEEK_SET)) < 0)
5120 c->mfra_size = avio_rb32(pb);
5121 c->have_read_mfra_size = 1;
5122 if ((ret = avio_seek(pb, original_pos, SEEK_SET)) < 0)
5125 if (offset + c->mfra_size == stream_size)
5130 // Find first entry in fragment index that came from an sidx.
5131 // This will pretty much always be the first entry.
5132 for (i = 0; i < c->frag_index.nb_items; i++) {
5133 MOVFragmentIndexItem * item = &c->frag_index.item[i];
5134 for (j = 0; ref_st == NULL && j < item->nb_stream_info; j++) {
5135 MOVFragmentStreamInfo * si;
5136 si = &item->stream_info[j];
5137 if (si->sidx_pts != AV_NOPTS_VALUE) {
5138 ref_st = c->fc->streams[j];
5139 ref_sc = ref_st->priv_data;
5144 if (ref_st) for (i = 0; i < c->fc->nb_streams; i++) {
5145 st = c->fc->streams[i];
5147 if (!sc->has_sidx) {
5148 st->duration = sc->track_end = av_rescale(ref_st->duration, sc->time_scale, ref_sc->time_scale);
5152 c->frag_index.complete = 1;
5158 /* this atom should be null (from specs), but some buggy files put the 'moov' atom inside it... */
5159 /* like the files created with Adobe Premiere 5.0, for samples see */
5160 /* http://graphics.tudelft.nl/~wouter/publications/soundtests/ */
5161 static int mov_read_wide(MOVContext *c, AVIOContext *pb, MOVAtom atom)
5166 return 0; /* continue */
5167 if (avio_rb32(pb) != 0) { /* 0 sized mdat atom... use the 'wide' atom size */
5168 avio_skip(pb, atom.size - 4);
5171 atom.type = avio_rl32(pb);
5173 if (atom.type != MKTAG('m','d','a','t')) {
5174 avio_skip(pb, atom.size);
5177 err = mov_read_mdat(c, pb, atom);
5181 static int mov_read_cmov(MOVContext *c, AVIOContext *pb, MOVAtom atom)
5186 uint8_t *moov_data; /* uncompressed data */
5187 long cmov_len, moov_len;
5190 avio_rb32(pb); /* dcom atom */
5191 if (avio_rl32(pb) != MKTAG('d','c','o','m'))
5192 return AVERROR_INVALIDDATA;
5193 if (avio_rl32(pb) != MKTAG('z','l','i','b')) {
5194 av_log(c->fc, AV_LOG_ERROR, "unknown compression for cmov atom !\n");
5195 return AVERROR_INVALIDDATA;
5197 avio_rb32(pb); /* cmvd atom */
5198 if (avio_rl32(pb) != MKTAG('c','m','v','d'))
5199 return AVERROR_INVALIDDATA;
5200 moov_len = avio_rb32(pb); /* uncompressed size */
5201 cmov_len = atom.size - 6 * 4;
5203 cmov_data = av_malloc(cmov_len);
5205 return AVERROR(ENOMEM);
5206 moov_data = av_malloc(moov_len);
5209 return AVERROR(ENOMEM);
5211 ret = ffio_read_size(pb, cmov_data, cmov_len);
5213 goto free_and_return;
5215 ret = AVERROR_INVALIDDATA;
5216 if (uncompress (moov_data, (uLongf *) &moov_len, (const Bytef *)cmov_data, cmov_len) != Z_OK)
5217 goto free_and_return;
5218 if (ffio_init_context(&ctx, moov_data, moov_len, 0, NULL, NULL, NULL, NULL) != 0)
5219 goto free_and_return;
5220 ctx.seekable = AVIO_SEEKABLE_NORMAL;
5221 atom.type = MKTAG('m','o','o','v');
5222 atom.size = moov_len;
5223 ret = mov_read_default(c, &ctx, atom);
5229 av_log(c->fc, AV_LOG_ERROR, "this file requires zlib support compiled in\n");
5230 return AVERROR(ENOSYS);
5234 /* edit list atom */
5235 static int mov_read_elst(MOVContext *c, AVIOContext *pb, MOVAtom atom)
5237 MOVStreamContext *sc;
5238 int i, edit_count, version;
5239 int64_t elst_entry_size;
5241 if (c->fc->nb_streams < 1 || c->ignore_editlist)
5243 sc = c->fc->streams[c->fc->nb_streams-1]->priv_data;
5245 version = avio_r8(pb); /* version */
5246 avio_rb24(pb); /* flags */
5247 edit_count = avio_rb32(pb); /* entries */
5250 elst_entry_size = version == 1 ? 20 : 12;
5251 if (atom.size != edit_count * elst_entry_size) {
5252 if (c->fc->strict_std_compliance >= FF_COMPLIANCE_STRICT) {
5253 av_log(c->fc, AV_LOG_ERROR, "Invalid edit list entry_count: %d for elst atom of size: %"PRId64" bytes.\n",
5254 edit_count, atom.size + 8);
5255 return AVERROR_INVALIDDATA;
5257 edit_count = atom.size / elst_entry_size;
5258 if (edit_count * elst_entry_size != atom.size) {
5259 av_log(c->fc, AV_LOG_WARNING, "ELST atom of %"PRId64" bytes, bigger than %d entries.\n", atom.size, edit_count);
5267 av_log(c->fc, AV_LOG_WARNING, "Duplicated ELST atom\n");
5268 av_free(sc->elst_data);
5270 sc->elst_data = av_malloc_array(edit_count, sizeof(*sc->elst_data));
5272 return AVERROR(ENOMEM);
5274 av_log(c->fc, AV_LOG_TRACE, "track[%u].edit_count = %i\n", c->fc->nb_streams - 1, edit_count);
5275 for (i = 0; i < edit_count && atom.size > 0 && !pb->eof_reached; i++) {
5276 MOVElst *e = &sc->elst_data[i];
5279 e->duration = avio_rb64(pb);
5280 e->time = avio_rb64(pb);
5283 e->duration = avio_rb32(pb); /* segment duration */
5284 e->time = (int32_t)avio_rb32(pb); /* media time */
5287 e->rate = avio_rb32(pb) / 65536.0;
5289 av_log(c->fc, AV_LOG_TRACE, "duration=%"PRId64" time=%"PRId64" rate=%f\n",
5290 e->duration, e->time, e->rate);
5292 if (e->time < 0 && e->time != -1 &&
5293 c->fc->strict_std_compliance >= FF_COMPLIANCE_STRICT) {
5294 av_log(c->fc, AV_LOG_ERROR, "Track %d, edit %d: Invalid edit list media time=%"PRId64"\n",
5295 c->fc->nb_streams-1, i, e->time);
5296 return AVERROR_INVALIDDATA;
5304 static int mov_read_tmcd(MOVContext *c, AVIOContext *pb, MOVAtom atom)
5306 MOVStreamContext *sc;
5308 if (c->fc->nb_streams < 1)
5309 return AVERROR_INVALIDDATA;
5310 sc = c->fc->streams[c->fc->nb_streams - 1]->priv_data;
5311 sc->timecode_track = avio_rb32(pb);
5315 static int mov_read_av1c(MOVContext *c, AVIOContext *pb, MOVAtom atom)
5320 if (c->fc->nb_streams < 1)
5322 st = c->fc->streams[c->fc->nb_streams - 1];
5324 if (atom.size < 4) {
5325 av_log(c->fc, AV_LOG_ERROR, "Empty AV1 Codec Configuration Box\n");
5326 return AVERROR_INVALIDDATA;
5329 /* For now, propagate only the OBUs, if any. Once libavcodec is
5330 updated to handle isobmff style extradata this can be removed. */
5336 ret = ff_get_extradata(c->fc, st->codecpar, pb, atom.size - 4);
5343 static int mov_read_vpcc(MOVContext *c, AVIOContext *pb, MOVAtom atom)
5346 int version, color_range, color_primaries, color_trc, color_space;
5348 if (c->fc->nb_streams < 1)
5350 st = c->fc->streams[c->fc->nb_streams - 1];
5352 if (atom.size < 5) {
5353 av_log(c->fc, AV_LOG_ERROR, "Empty VP Codec Configuration box\n");
5354 return AVERROR_INVALIDDATA;
5357 version = avio_r8(pb);
5359 av_log(c->fc, AV_LOG_WARNING, "Unsupported VP Codec Configuration box version %d\n", version);
5362 avio_skip(pb, 3); /* flags */
5364 avio_skip(pb, 2); /* profile + level */
5365 color_range = avio_r8(pb); /* bitDepth, chromaSubsampling, videoFullRangeFlag */
5366 color_primaries = avio_r8(pb);
5367 color_trc = avio_r8(pb);
5368 color_space = avio_r8(pb);
5369 if (avio_rb16(pb)) /* codecIntializationDataSize */
5370 return AVERROR_INVALIDDATA;
5372 if (!av_color_primaries_name(color_primaries))
5373 color_primaries = AVCOL_PRI_UNSPECIFIED;
5374 if (!av_color_transfer_name(color_trc))
5375 color_trc = AVCOL_TRC_UNSPECIFIED;
5376 if (!av_color_space_name(color_space))
5377 color_space = AVCOL_SPC_UNSPECIFIED;
5379 st->codecpar->color_range = (color_range & 1) ? AVCOL_RANGE_JPEG : AVCOL_RANGE_MPEG;
5380 st->codecpar->color_primaries = color_primaries;
5381 st->codecpar->color_trc = color_trc;
5382 st->codecpar->color_space = color_space;
5387 static int mov_read_smdm(MOVContext *c, AVIOContext *pb, MOVAtom atom)
5389 MOVStreamContext *sc;
5392 if (c->fc->nb_streams < 1)
5393 return AVERROR_INVALIDDATA;
5395 sc = c->fc->streams[c->fc->nb_streams - 1]->priv_data;
5397 if (atom.size < 5) {
5398 av_log(c->fc, AV_LOG_ERROR, "Empty Mastering Display Metadata box\n");
5399 return AVERROR_INVALIDDATA;
5402 version = avio_r8(pb);
5404 av_log(c->fc, AV_LOG_WARNING, "Unsupported Mastering Display Metadata box version %d\n", version);
5407 avio_skip(pb, 3); /* flags */
5409 sc->mastering = av_mastering_display_metadata_alloc();
5411 return AVERROR(ENOMEM);
5413 for (i = 0; i < 3; i++) {
5414 sc->mastering->display_primaries[i][0] = av_make_q(avio_rb16(pb), 1 << 16);
5415 sc->mastering->display_primaries[i][1] = av_make_q(avio_rb16(pb), 1 << 16);
5417 sc->mastering->white_point[0] = av_make_q(avio_rb16(pb), 1 << 16);
5418 sc->mastering->white_point[1] = av_make_q(avio_rb16(pb), 1 << 16);
5420 sc->mastering->max_luminance = av_make_q(avio_rb32(pb), 1 << 8);
5421 sc->mastering->min_luminance = av_make_q(avio_rb32(pb), 1 << 14);
5423 sc->mastering->has_primaries = 1;
5424 sc->mastering->has_luminance = 1;
5429 static int mov_read_mdcv(MOVContext *c, AVIOContext *pb, MOVAtom atom)
5431 MOVStreamContext *sc;
5432 const int mapping[3] = {1, 2, 0};
5433 const int chroma_den = 50000;
5434 const int luma_den = 10000;
5437 if (c->fc->nb_streams < 1)
5438 return AVERROR_INVALIDDATA;
5440 sc = c->fc->streams[c->fc->nb_streams - 1]->priv_data;
5442 if (atom.size < 24) {
5443 av_log(c->fc, AV_LOG_ERROR, "Invalid Mastering Display Color Volume box\n");
5444 return AVERROR_INVALIDDATA;
5447 sc->mastering = av_mastering_display_metadata_alloc();
5449 return AVERROR(ENOMEM);
5451 for (i = 0; i < 3; i++) {
5452 const int j = mapping[i];
5453 sc->mastering->display_primaries[j][0] = av_make_q(avio_rb16(pb), chroma_den);
5454 sc->mastering->display_primaries[j][1] = av_make_q(avio_rb16(pb), chroma_den);
5456 sc->mastering->white_point[0] = av_make_q(avio_rb16(pb), chroma_den);
5457 sc->mastering->white_point[1] = av_make_q(avio_rb16(pb), chroma_den);
5459 sc->mastering->max_luminance = av_make_q(avio_rb32(pb), luma_den);
5460 sc->mastering->min_luminance = av_make_q(avio_rb32(pb), luma_den);
5462 sc->mastering->has_luminance = 1;
5463 sc->mastering->has_primaries = 1;
5468 static int mov_read_coll(MOVContext *c, AVIOContext *pb, MOVAtom atom)
5470 MOVStreamContext *sc;
5473 if (c->fc->nb_streams < 1)
5474 return AVERROR_INVALIDDATA;
5476 sc = c->fc->streams[c->fc->nb_streams - 1]->priv_data;
5478 if (atom.size < 5) {
5479 av_log(c->fc, AV_LOG_ERROR, "Empty Content Light Level box\n");
5480 return AVERROR_INVALIDDATA;
5483 version = avio_r8(pb);
5485 av_log(c->fc, AV_LOG_WARNING, "Unsupported Content Light Level box version %d\n", version);
5488 avio_skip(pb, 3); /* flags */
5490 sc->coll = av_content_light_metadata_alloc(&sc->coll_size);
5492 return AVERROR(ENOMEM);
5494 sc->coll->MaxCLL = avio_rb16(pb);
5495 sc->coll->MaxFALL = avio_rb16(pb);
5500 static int mov_read_clli(MOVContext *c, AVIOContext *pb, MOVAtom atom)
5502 MOVStreamContext *sc;
5504 if (c->fc->nb_streams < 1)
5505 return AVERROR_INVALIDDATA;
5507 sc = c->fc->streams[c->fc->nb_streams - 1]->priv_data;
5509 if (atom.size < 4) {
5510 av_log(c->fc, AV_LOG_ERROR, "Empty Content Light Level Info box\n");
5511 return AVERROR_INVALIDDATA;
5514 sc->coll = av_content_light_metadata_alloc(&sc->coll_size);
5516 return AVERROR(ENOMEM);
5518 sc->coll->MaxCLL = avio_rb16(pb);
5519 sc->coll->MaxFALL = avio_rb16(pb);
5524 static int mov_read_st3d(MOVContext *c, AVIOContext *pb, MOVAtom atom)
5527 MOVStreamContext *sc;
5528 enum AVStereo3DType type;
5531 if (c->fc->nb_streams < 1)
5534 st = c->fc->streams[c->fc->nb_streams - 1];
5537 if (atom.size < 5) {
5538 av_log(c->fc, AV_LOG_ERROR, "Empty stereoscopic video box\n");
5539 return AVERROR_INVALIDDATA;
5543 return AVERROR_INVALIDDATA;
5545 avio_skip(pb, 4); /* version + flags */
5550 type = AV_STEREO3D_2D;
5553 type = AV_STEREO3D_TOPBOTTOM;
5556 type = AV_STEREO3D_SIDEBYSIDE;
5559 av_log(c->fc, AV_LOG_WARNING, "Unknown st3d mode value %d\n", mode);
5563 sc->stereo3d = av_stereo3d_alloc();
5565 return AVERROR(ENOMEM);
5567 sc->stereo3d->type = type;
5571 static int mov_read_sv3d(MOVContext *c, AVIOContext *pb, MOVAtom atom)
5574 MOVStreamContext *sc;
5575 int size, version, layout;
5576 int32_t yaw, pitch, roll;
5577 uint32_t l = 0, t = 0, r = 0, b = 0;
5578 uint32_t tag, padding = 0;
5579 enum AVSphericalProjection projection;
5581 if (c->fc->nb_streams < 1)
5584 st = c->fc->streams[c->fc->nb_streams - 1];
5587 if (atom.size < 8) {
5588 av_log(c->fc, AV_LOG_ERROR, "Empty spherical video box\n");
5589 return AVERROR_INVALIDDATA;
5592 size = avio_rb32(pb);
5593 if (size <= 12 || size > atom.size)
5594 return AVERROR_INVALIDDATA;
5596 tag = avio_rl32(pb);
5597 if (tag != MKTAG('s','v','h','d')) {
5598 av_log(c->fc, AV_LOG_ERROR, "Missing spherical video header\n");
5601 version = avio_r8(pb);
5603 av_log(c->fc, AV_LOG_WARNING, "Unknown spherical version %d\n",
5607 avio_skip(pb, 3); /* flags */
5608 avio_skip(pb, size - 12); /* metadata_source */
5610 size = avio_rb32(pb);
5611 if (size > atom.size)
5612 return AVERROR_INVALIDDATA;
5614 tag = avio_rl32(pb);
5615 if (tag != MKTAG('p','r','o','j')) {
5616 av_log(c->fc, AV_LOG_ERROR, "Missing projection box\n");
5620 size = avio_rb32(pb);
5621 if (size > atom.size)
5622 return AVERROR_INVALIDDATA;
5624 tag = avio_rl32(pb);
5625 if (tag != MKTAG('p','r','h','d')) {
5626 av_log(c->fc, AV_LOG_ERROR, "Missing projection header box\n");
5629 version = avio_r8(pb);
5631 av_log(c->fc, AV_LOG_WARNING, "Unknown spherical version %d\n",
5635 avio_skip(pb, 3); /* flags */
5637 /* 16.16 fixed point */
5638 yaw = avio_rb32(pb);
5639 pitch = avio_rb32(pb);
5640 roll = avio_rb32(pb);
5642 size = avio_rb32(pb);
5643 if (size > atom.size)
5644 return AVERROR_INVALIDDATA;
5646 tag = avio_rl32(pb);
5647 version = avio_r8(pb);
5649 av_log(c->fc, AV_LOG_WARNING, "Unknown spherical version %d\n",
5653 avio_skip(pb, 3); /* flags */
5655 case MKTAG('c','b','m','p'):
5656 layout = avio_rb32(pb);
5658 av_log(c->fc, AV_LOG_WARNING,
5659 "Unsupported cubemap layout %d\n", layout);
5662 projection = AV_SPHERICAL_CUBEMAP;
5663 padding = avio_rb32(pb);
5665 case MKTAG('e','q','u','i'):
5671 if (b >= UINT_MAX - t || r >= UINT_MAX - l) {
5672 av_log(c->fc, AV_LOG_ERROR,
5673 "Invalid bounding rectangle coordinates "
5674 "%"PRIu32",%"PRIu32",%"PRIu32",%"PRIu32"\n", l, t, r, b);
5675 return AVERROR_INVALIDDATA;
5678 if (l || t || r || b)
5679 projection = AV_SPHERICAL_EQUIRECTANGULAR_TILE;
5681 projection = AV_SPHERICAL_EQUIRECTANGULAR;
5684 av_log(c->fc, AV_LOG_ERROR, "Unknown projection type: %s\n", av_fourcc2str(tag));
5688 sc->spherical = av_spherical_alloc(&sc->spherical_size);
5690 return AVERROR(ENOMEM);
5692 sc->spherical->projection = projection;
5694 sc->spherical->yaw = yaw;
5695 sc->spherical->pitch = pitch;
5696 sc->spherical->roll = roll;
5698 sc->spherical->padding = padding;
5700 sc->spherical->bound_left = l;
5701 sc->spherical->bound_top = t;
5702 sc->spherical->bound_right = r;
5703 sc->spherical->bound_bottom = b;
5708 static int mov_parse_uuid_spherical(MOVStreamContext *sc, AVIOContext *pb, size_t len)
5711 uint8_t *buffer = av_malloc(len + 1);
5715 return AVERROR(ENOMEM);
5718 ret = ffio_read_size(pb, buffer, len);
5722 /* Check for mandatory keys and values, try to support XML as best-effort */
5723 if (!sc->spherical &&
5724 av_stristr(buffer, "<GSpherical:StitchingSoftware>") &&
5725 (val = av_stristr(buffer, "<GSpherical:Spherical>")) &&
5726 av_stristr(val, "true") &&
5727 (val = av_stristr(buffer, "<GSpherical:Stitched>")) &&
5728 av_stristr(val, "true") &&
5729 (val = av_stristr(buffer, "<GSpherical:ProjectionType>")) &&
5730 av_stristr(val, "equirectangular")) {
5731 sc->spherical = av_spherical_alloc(&sc->spherical_size);
5735 sc->spherical->projection = AV_SPHERICAL_EQUIRECTANGULAR;
5737 if (av_stristr(buffer, "<GSpherical:StereoMode>") && !sc->stereo3d) {
5738 enum AVStereo3DType mode;
5740 if (av_stristr(buffer, "left-right"))
5741 mode = AV_STEREO3D_SIDEBYSIDE;
5742 else if (av_stristr(buffer, "top-bottom"))
5743 mode = AV_STEREO3D_TOPBOTTOM;
5745 mode = AV_STEREO3D_2D;
5747 sc->stereo3d = av_stereo3d_alloc();
5751 sc->stereo3d->type = mode;
5755 val = av_stristr(buffer, "<GSpherical:InitialViewHeadingDegrees>");
5757 sc->spherical->yaw = strtol(val, NULL, 10) * (1 << 16);
5758 val = av_stristr(buffer, "<GSpherical:InitialViewPitchDegrees>");
5760 sc->spherical->pitch = strtol(val, NULL, 10) * (1 << 16);
5761 val = av_stristr(buffer, "<GSpherical:InitialViewRollDegrees>");
5763 sc->spherical->roll = strtol(val, NULL, 10) * (1 << 16);
5771 static int mov_read_uuid(MOVContext *c, AVIOContext *pb, MOVAtom atom)
5774 MOVStreamContext *sc;
5777 static const uint8_t uuid_isml_manifest[] = {
5778 0xa5, 0xd4, 0x0b, 0x30, 0xe8, 0x14, 0x11, 0xdd,
5779 0xba, 0x2f, 0x08, 0x00, 0x20, 0x0c, 0x9a, 0x66
5781 static const uint8_t uuid_xmp[] = {
5782 0xbe, 0x7a, 0xcf, 0xcb, 0x97, 0xa9, 0x42, 0xe8,
5783 0x9c, 0x71, 0x99, 0x94, 0x91, 0xe3, 0xaf, 0xac
5785 static const uint8_t uuid_spherical[] = {
5786 0xff, 0xcc, 0x82, 0x63, 0xf8, 0x55, 0x4a, 0x93,
5787 0x88, 0x14, 0x58, 0x7a, 0x02, 0x52, 0x1f, 0xdd,
5790 if (atom.size < sizeof(uuid) || atom.size >= FFMIN(INT_MAX, SIZE_MAX))
5791 return AVERROR_INVALIDDATA;
5793 if (c->fc->nb_streams < 1)
5795 st = c->fc->streams[c->fc->nb_streams - 1];
5798 ret = ffio_read_size(pb, uuid, sizeof(uuid));
5801 if (!memcmp(uuid, uuid_isml_manifest, sizeof(uuid))) {
5802 uint8_t *buffer, *ptr;
5804 size_t len = atom.size - sizeof(uuid);
5807 return AVERROR_INVALIDDATA;
5809 ret = avio_skip(pb, 4); // zeroes
5812 buffer = av_mallocz(len + 1);
5814 return AVERROR(ENOMEM);
5816 ret = ffio_read_size(pb, buffer, len);
5823 while ((ptr = av_stristr(ptr, "systemBitrate=\""))) {
5824 ptr += sizeof("systemBitrate=\"") - 1;
5825 c->bitrates_count++;
5826 c->bitrates = av_realloc_f(c->bitrates, c->bitrates_count, sizeof(*c->bitrates));
5828 c->bitrates_count = 0;
5830 return AVERROR(ENOMEM);
5833 ret = strtol(ptr, &endptr, 10);
5834 if (ret < 0 || errno || *endptr != '"') {
5835 c->bitrates[c->bitrates_count - 1] = 0;
5837 c->bitrates[c->bitrates_count - 1] = ret;
5842 } else if (!memcmp(uuid, uuid_xmp, sizeof(uuid))) {
5844 size_t len = atom.size - sizeof(uuid);
5845 if (c->export_xmp) {
5846 buffer = av_mallocz(len + 1);
5848 return AVERROR(ENOMEM);
5850 ret = ffio_read_size(pb, buffer, len);
5856 av_dict_set(&c->fc->metadata, "xmp",
5857 buffer, AV_DICT_DONT_STRDUP_VAL);
5859 // skip all uuid atom, which makes it fast for long uuid-xmp file
5860 ret = avio_skip(pb, len);
5864 } else if (!memcmp(uuid, uuid_spherical, sizeof(uuid))) {
5865 size_t len = atom.size - sizeof(uuid);
5866 ret = mov_parse_uuid_spherical(sc, pb, len);
5870 av_log(c->fc, AV_LOG_WARNING, "Invalid spherical metadata found\n");
5876 static int mov_read_free(MOVContext *c, AVIOContext *pb, MOVAtom atom)
5879 uint8_t content[16];
5884 ret = avio_read(pb, content, FFMIN(sizeof(content), atom.size));
5890 && !memcmp(content, "Anevia\x1A\x1A", 8)
5891 && c->use_mfra_for == FF_MOV_FLAG_MFRA_AUTO) {
5892 c->use_mfra_for = FF_MOV_FLAG_MFRA_PTS;
5898 static int mov_read_frma(MOVContext *c, AVIOContext *pb, MOVAtom atom)
5900 uint32_t format = avio_rl32(pb);
5901 MOVStreamContext *sc;
5905 if (c->fc->nb_streams < 1)
5907 st = c->fc->streams[c->fc->nb_streams - 1];
5912 case MKTAG('e','n','c','v'): // encrypted video
5913 case MKTAG('e','n','c','a'): // encrypted audio
5914 id = mov_codec_id(st, format);
5915 if (st->codecpar->codec_id != AV_CODEC_ID_NONE &&
5916 st->codecpar->codec_id != id) {
5917 av_log(c->fc, AV_LOG_WARNING,
5918 "ignoring 'frma' atom of '%.4s', stream has codec id %d\n",
5919 (char*)&format, st->codecpar->codec_id);
5923 st->codecpar->codec_id = id;
5924 sc->format = format;
5928 if (format != sc->format) {
5929 av_log(c->fc, AV_LOG_WARNING,
5930 "ignoring 'frma' atom of '%.4s', stream format is '%.4s'\n",
5931 (char*)&format, (char*)&sc->format);
5940 * Gets the current encryption info and associated current stream context. If
5941 * we are parsing a track fragment, this will return the specific encryption
5942 * info for this fragment; otherwise this will return the global encryption
5943 * info for the current stream.
5945 static int get_current_encryption_info(MOVContext *c, MOVEncryptionIndex **encryption_index, MOVStreamContext **sc)
5947 MOVFragmentStreamInfo *frag_stream_info;
5951 frag_stream_info = get_current_frag_stream_info(&c->frag_index);
5952 if (frag_stream_info) {
5953 for (i = 0; i < c->fc->nb_streams; i++) {
5954 if (c->fc->streams[i]->id == frag_stream_info->id) {
5955 st = c->fc->streams[i];
5959 if (i == c->fc->nb_streams)
5961 *sc = st->priv_data;
5963 if (!frag_stream_info->encryption_index) {
5964 // If this stream isn't encrypted, don't create the index.
5965 if (!(*sc)->cenc.default_encrypted_sample)
5967 frag_stream_info->encryption_index = av_mallocz(sizeof(*frag_stream_info->encryption_index));
5968 if (!frag_stream_info->encryption_index)
5969 return AVERROR(ENOMEM);
5971 *encryption_index = frag_stream_info->encryption_index;
5974 // No current track fragment, using stream level encryption info.
5976 if (c->fc->nb_streams < 1)
5978 st = c->fc->streams[c->fc->nb_streams - 1];
5979 *sc = st->priv_data;
5981 if (!(*sc)->cenc.encryption_index) {
5982 // If this stream isn't encrypted, don't create the index.
5983 if (!(*sc)->cenc.default_encrypted_sample)
5985 (*sc)->cenc.encryption_index = av_mallocz(sizeof(*frag_stream_info->encryption_index));
5986 if (!(*sc)->cenc.encryption_index)
5987 return AVERROR(ENOMEM);
5990 *encryption_index = (*sc)->cenc.encryption_index;
5995 static int mov_read_sample_encryption_info(MOVContext *c, AVIOContext *pb, MOVStreamContext *sc, AVEncryptionInfo **sample, int use_subsamples)
5998 unsigned int subsample_count;
5999 AVSubsampleEncryptionInfo *subsamples;
6001 if (!sc->cenc.default_encrypted_sample) {
6002 av_log(c->fc, AV_LOG_ERROR, "Missing schm or tenc\n");
6003 return AVERROR_INVALIDDATA;
6006 *sample = av_encryption_info_clone(sc->cenc.default_encrypted_sample);
6008 return AVERROR(ENOMEM);
6010 if (sc->cenc.per_sample_iv_size != 0) {
6011 if ((ret = ffio_read_size(pb, (*sample)->iv, sc->cenc.per_sample_iv_size)) < 0) {
6012 av_log(c->fc, AV_LOG_ERROR, "failed to read the initialization vector\n");
6013 av_encryption_info_free(*sample);
6019 if (use_subsamples) {
6020 subsample_count = avio_rb16(pb);
6021 av_free((*sample)->subsamples);
6022 (*sample)->subsamples = av_mallocz_array(subsample_count, sizeof(*subsamples));
6023 if (!(*sample)->subsamples) {
6024 av_encryption_info_free(*sample);
6026 return AVERROR(ENOMEM);
6029 for (i = 0; i < subsample_count && !pb->eof_reached; i++) {
6030 (*sample)->subsamples[i].bytes_of_clear_data = avio_rb16(pb);
6031 (*sample)->subsamples[i].bytes_of_protected_data = avio_rb32(pb);
6034 if (pb->eof_reached) {
6035 av_log(c->fc, AV_LOG_ERROR, "hit EOF while reading sub-sample encryption info\n");
6036 av_encryption_info_free(*sample);
6038 return AVERROR_INVALIDDATA;
6040 (*sample)->subsample_count = subsample_count;
6046 static int mov_read_senc(MOVContext *c, AVIOContext *pb, MOVAtom atom)
6048 AVEncryptionInfo **encrypted_samples;
6049 MOVEncryptionIndex *encryption_index;
6050 MOVStreamContext *sc;
6051 int use_subsamples, ret;
6052 unsigned int sample_count, i, alloc_size = 0;
6054 ret = get_current_encryption_info(c, &encryption_index, &sc);
6058 if (encryption_index->nb_encrypted_samples) {
6059 // This can happen if we have both saio/saiz and senc atoms.
6060 av_log(c->fc, AV_LOG_DEBUG, "Ignoring duplicate encryption info in senc\n");
6064 avio_r8(pb); /* version */
6065 use_subsamples = avio_rb24(pb) & 0x02; /* flags */
6067 sample_count = avio_rb32(pb);
6068 if (sample_count >= INT_MAX / sizeof(*encrypted_samples))
6069 return AVERROR(ENOMEM);
6071 for (i = 0; i < sample_count; i++) {
6072 unsigned int min_samples = FFMIN(FFMAX(i + 1, 1024 * 1024), sample_count);
6073 encrypted_samples = av_fast_realloc(encryption_index->encrypted_samples, &alloc_size,
6074 min_samples * sizeof(*encrypted_samples));
6075 if (encrypted_samples) {
6076 encryption_index->encrypted_samples = encrypted_samples;
6078 ret = mov_read_sample_encryption_info(
6079 c, pb, sc, &encryption_index->encrypted_samples[i], use_subsamples);
6081 ret = AVERROR(ENOMEM);
6083 if (pb->eof_reached) {
6084 av_log(c->fc, AV_LOG_ERROR, "Hit EOF while reading senc\n");
6085 ret = AVERROR_INVALIDDATA;
6090 av_encryption_info_free(encryption_index->encrypted_samples[i - 1]);
6091 av_freep(&encryption_index->encrypted_samples);
6095 encryption_index->nb_encrypted_samples = sample_count;
6100 static int mov_parse_auxiliary_info(MOVContext *c, MOVStreamContext *sc, AVIOContext *pb, MOVEncryptionIndex *encryption_index)
6102 AVEncryptionInfo **sample, **encrypted_samples;
6104 size_t sample_count, sample_info_size, i;
6106 unsigned int alloc_size = 0;
6108 if (encryption_index->nb_encrypted_samples)
6110 sample_count = encryption_index->auxiliary_info_sample_count;
6111 if (encryption_index->auxiliary_offsets_count != 1) {
6112 av_log(c->fc, AV_LOG_ERROR, "Multiple auxiliary info chunks are not supported\n");
6113 return AVERROR_PATCHWELCOME;
6115 if (sample_count >= INT_MAX / sizeof(*encrypted_samples))
6116 return AVERROR(ENOMEM);
6118 prev_pos = avio_tell(pb);
6119 if (!(pb->seekable & AVIO_SEEKABLE_NORMAL) ||
6120 avio_seek(pb, encryption_index->auxiliary_offsets[0], SEEK_SET) != encryption_index->auxiliary_offsets[0]) {
6121 av_log(c->fc, AV_LOG_INFO, "Failed to seek for auxiliary info, will only parse senc atoms for encryption info\n");
6125 for (i = 0; i < sample_count && !pb->eof_reached; i++) {
6126 unsigned int min_samples = FFMIN(FFMAX(i + 1, 1024 * 1024), sample_count);
6127 encrypted_samples = av_fast_realloc(encryption_index->encrypted_samples, &alloc_size,
6128 min_samples * sizeof(*encrypted_samples));
6129 if (!encrypted_samples) {
6130 ret = AVERROR(ENOMEM);
6133 encryption_index->encrypted_samples = encrypted_samples;
6135 sample = &encryption_index->encrypted_samples[i];
6136 sample_info_size = encryption_index->auxiliary_info_default_size
6137 ? encryption_index->auxiliary_info_default_size
6138 : encryption_index->auxiliary_info_sizes[i];
6140 ret = mov_read_sample_encryption_info(c, pb, sc, sample, sample_info_size > sc->cenc.per_sample_iv_size);
6144 if (pb->eof_reached) {
6145 av_log(c->fc, AV_LOG_ERROR, "Hit EOF while reading auxiliary info\n");
6146 ret = AVERROR_INVALIDDATA;
6148 encryption_index->nb_encrypted_samples = sample_count;
6152 avio_seek(pb, prev_pos, SEEK_SET);
6154 for (; i > 0; i--) {
6155 av_encryption_info_free(encryption_index->encrypted_samples[i - 1]);
6157 av_freep(&encryption_index->encrypted_samples);
6163 * Tries to read the given number of bytes from the stream and puts it in a
6164 * newly allocated buffer. This reads in small chunks to avoid allocating large
6165 * memory if the file contains an invalid/malicious size value.
6167 static int mov_try_read_block(AVIOContext *pb, size_t size, uint8_t **data)
6169 const unsigned int block_size = 1024 * 1024;
6170 uint8_t *buffer = NULL;
6171 unsigned int alloc_size = 0, offset = 0;
6172 while (offset < size) {
6173 unsigned int new_size =
6174 alloc_size >= INT_MAX - block_size ? INT_MAX : alloc_size + block_size;
6175 uint8_t *new_buffer = av_fast_realloc(buffer, &alloc_size, new_size);
6176 unsigned int to_read = FFMIN(size, alloc_size) - offset;
6179 return AVERROR(ENOMEM);
6181 buffer = new_buffer;
6183 if (avio_read(pb, buffer + offset, to_read) != to_read) {
6185 return AVERROR_INVALIDDATA;
6194 static int mov_read_saiz(MOVContext *c, AVIOContext *pb, MOVAtom atom)
6196 MOVEncryptionIndex *encryption_index;
6197 MOVStreamContext *sc;
6199 unsigned int sample_count, aux_info_type, aux_info_param;
6201 ret = get_current_encryption_info(c, &encryption_index, &sc);
6205 if (encryption_index->nb_encrypted_samples) {
6206 // This can happen if we have both saio/saiz and senc atoms.
6207 av_log(c->fc, AV_LOG_DEBUG, "Ignoring duplicate encryption info in saiz\n");
6211 if (encryption_index->auxiliary_info_sample_count) {
6212 av_log(c->fc, AV_LOG_ERROR, "Duplicate saiz atom\n");
6213 return AVERROR_INVALIDDATA;
6216 avio_r8(pb); /* version */
6217 if (avio_rb24(pb) & 0x01) { /* flags */
6218 aux_info_type = avio_rb32(pb);
6219 aux_info_param = avio_rb32(pb);
6220 if (sc->cenc.default_encrypted_sample) {
6221 if (aux_info_type != sc->cenc.default_encrypted_sample->scheme) {
6222 av_log(c->fc, AV_LOG_DEBUG, "Ignoring saiz box with non-zero aux_info_type\n");
6225 if (aux_info_param != 0) {
6226 av_log(c->fc, AV_LOG_DEBUG, "Ignoring saiz box with non-zero aux_info_type_parameter\n");
6230 // Didn't see 'schm' or 'tenc', so this isn't encrypted.
6231 if ((aux_info_type == MKBETAG('c','e','n','c') ||
6232 aux_info_type == MKBETAG('c','e','n','s') ||
6233 aux_info_type == MKBETAG('c','b','c','1') ||
6234 aux_info_type == MKBETAG('c','b','c','s')) &&
6235 aux_info_param == 0) {
6236 av_log(c->fc, AV_LOG_ERROR, "Saw encrypted saiz without schm/tenc\n");
6237 return AVERROR_INVALIDDATA;
6242 } else if (!sc->cenc.default_encrypted_sample) {
6243 // Didn't see 'schm' or 'tenc', so this isn't encrypted.
6247 encryption_index->auxiliary_info_default_size = avio_r8(pb);
6248 sample_count = avio_rb32(pb);
6249 encryption_index->auxiliary_info_sample_count = sample_count;
6251 if (encryption_index->auxiliary_info_default_size == 0) {
6252 ret = mov_try_read_block(pb, sample_count, &encryption_index->auxiliary_info_sizes);
6254 av_log(c->fc, AV_LOG_ERROR, "Failed to read the auxiliary info\n");
6259 if (encryption_index->auxiliary_offsets_count) {
6260 return mov_parse_auxiliary_info(c, sc, pb, encryption_index);
6266 static int mov_read_saio(MOVContext *c, AVIOContext *pb, MOVAtom atom)
6268 uint64_t *auxiliary_offsets;
6269 MOVEncryptionIndex *encryption_index;
6270 MOVStreamContext *sc;
6272 unsigned int version, entry_count, aux_info_type, aux_info_param;
6273 unsigned int alloc_size = 0;
6275 ret = get_current_encryption_info(c, &encryption_index, &sc);
6279 if (encryption_index->nb_encrypted_samples) {
6280 // This can happen if we have both saio/saiz and senc atoms.
6281 av_log(c->fc, AV_LOG_DEBUG, "Ignoring duplicate encryption info in saio\n");
6285 if (encryption_index->auxiliary_offsets_count) {
6286 av_log(c->fc, AV_LOG_ERROR, "Duplicate saio atom\n");
6287 return AVERROR_INVALIDDATA;
6290 version = avio_r8(pb); /* version */
6291 if (avio_rb24(pb) & 0x01) { /* flags */
6292 aux_info_type = avio_rb32(pb);
6293 aux_info_param = avio_rb32(pb);
6294 if (sc->cenc.default_encrypted_sample) {
6295 if (aux_info_type != sc->cenc.default_encrypted_sample->scheme) {
6296 av_log(c->fc, AV_LOG_DEBUG, "Ignoring saio box with non-zero aux_info_type\n");
6299 if (aux_info_param != 0) {
6300 av_log(c->fc, AV_LOG_DEBUG, "Ignoring saio box with non-zero aux_info_type_parameter\n");
6304 // Didn't see 'schm' or 'tenc', so this isn't encrypted.
6305 if ((aux_info_type == MKBETAG('c','e','n','c') ||
6306 aux_info_type == MKBETAG('c','e','n','s') ||
6307 aux_info_type == MKBETAG('c','b','c','1') ||
6308 aux_info_type == MKBETAG('c','b','c','s')) &&
6309 aux_info_param == 0) {
6310 av_log(c->fc, AV_LOG_ERROR, "Saw encrypted saio without schm/tenc\n");
6311 return AVERROR_INVALIDDATA;
6316 } else if (!sc->cenc.default_encrypted_sample) {
6317 // Didn't see 'schm' or 'tenc', so this isn't encrypted.
6321 entry_count = avio_rb32(pb);
6322 if (entry_count >= INT_MAX / sizeof(*auxiliary_offsets))
6323 return AVERROR(ENOMEM);
6325 for (i = 0; i < entry_count && !pb->eof_reached; i++) {
6326 unsigned int min_offsets = FFMIN(FFMAX(i + 1, 1024), entry_count);
6327 auxiliary_offsets = av_fast_realloc(
6328 encryption_index->auxiliary_offsets, &alloc_size,
6329 min_offsets * sizeof(*auxiliary_offsets));
6330 if (!auxiliary_offsets) {
6331 av_freep(&encryption_index->auxiliary_offsets);
6332 return AVERROR(ENOMEM);
6334 encryption_index->auxiliary_offsets = auxiliary_offsets;
6337 encryption_index->auxiliary_offsets[i] = avio_rb32(pb);
6339 encryption_index->auxiliary_offsets[i] = avio_rb64(pb);
6341 if (c->frag_index.current >= 0) {
6342 encryption_index->auxiliary_offsets[i] += c->fragment.base_data_offset;
6346 if (pb->eof_reached) {
6347 av_log(c->fc, AV_LOG_ERROR, "Hit EOF while reading saio\n");
6348 av_freep(&encryption_index->auxiliary_offsets);
6349 return AVERROR_INVALIDDATA;
6352 encryption_index->auxiliary_offsets_count = entry_count;
6354 if (encryption_index->auxiliary_info_sample_count) {
6355 return mov_parse_auxiliary_info(c, sc, pb, encryption_index);
6361 static int mov_read_pssh(MOVContext *c, AVIOContext *pb, MOVAtom atom)
6363 AVEncryptionInitInfo *info, *old_init_info;
6366 uint8_t *side_data, *extra_data, *old_side_data;
6367 size_t side_data_size;
6368 buffer_size_t old_side_data_size;
6370 unsigned int version, kid_count, extra_data_size, alloc_size = 0;
6372 if (c->fc->nb_streams < 1)
6374 st = c->fc->streams[c->fc->nb_streams-1];
6376 version = avio_r8(pb); /* version */
6377 avio_rb24(pb); /* flags */
6379 info = av_encryption_init_info_alloc(/* system_id_size */ 16, /* num_key_ids */ 0,
6380 /* key_id_size */ 16, /* data_size */ 0);
6382 return AVERROR(ENOMEM);
6384 if ((ret = ffio_read_size(pb, info->system_id, 16)) < 0) {
6385 av_log(c->fc, AV_LOG_ERROR, "Failed to read the system id\n");
6390 kid_count = avio_rb32(pb);
6391 if (kid_count >= INT_MAX / sizeof(*key_ids)) {
6392 ret = AVERROR(ENOMEM);
6396 for (unsigned int i = 0; i < kid_count && !pb->eof_reached; i++) {
6397 unsigned int min_kid_count = FFMIN(FFMAX(i + 1, 1024), kid_count);
6398 key_ids = av_fast_realloc(info->key_ids, &alloc_size,
6399 min_kid_count * sizeof(*key_ids));
6401 ret = AVERROR(ENOMEM);
6404 info->key_ids = key_ids;
6406 info->key_ids[i] = av_mallocz(16);
6407 if (!info->key_ids[i]) {
6408 ret = AVERROR(ENOMEM);
6411 info->num_key_ids = i + 1;
6413 if ((ret = ffio_read_size(pb, info->key_ids[i], 16)) < 0) {
6414 av_log(c->fc, AV_LOG_ERROR, "Failed to read the key id\n");
6419 if (pb->eof_reached) {
6420 av_log(c->fc, AV_LOG_ERROR, "Hit EOF while reading pssh\n");
6421 ret = AVERROR_INVALIDDATA;
6426 extra_data_size = avio_rb32(pb);
6427 ret = mov_try_read_block(pb, extra_data_size, &extra_data);
6431 av_freep(&info->data); // malloc(0) may still allocate something.
6432 info->data = extra_data;
6433 info->data_size = extra_data_size;
6435 // If there is existing initialization data, append to the list.
6436 old_side_data = av_stream_get_side_data(st, AV_PKT_DATA_ENCRYPTION_INIT_INFO, &old_side_data_size);
6437 if (old_side_data) {
6438 old_init_info = av_encryption_init_info_get_side_data(old_side_data, old_side_data_size);
6439 if (old_init_info) {
6440 // Append to the end of the list.
6441 for (AVEncryptionInitInfo *cur = old_init_info;; cur = cur->next) {
6447 info = old_init_info;
6449 // Assume existing side-data will be valid, so the only error we could get is OOM.
6450 ret = AVERROR(ENOMEM);
6455 side_data = av_encryption_init_info_add_side_data(info, &side_data_size);
6457 ret = AVERROR(ENOMEM);
6460 ret = av_stream_add_side_data(st, AV_PKT_DATA_ENCRYPTION_INIT_INFO,
6461 side_data, side_data_size);
6466 av_encryption_init_info_free(info);
6470 static int mov_read_schm(MOVContext *c, AVIOContext *pb, MOVAtom atom)
6473 MOVStreamContext *sc;
6475 if (c->fc->nb_streams < 1)
6477 st = c->fc->streams[c->fc->nb_streams-1];
6480 if (sc->pseudo_stream_id != 0) {
6481 av_log(c->fc, AV_LOG_ERROR, "schm boxes are only supported in first sample descriptor\n");
6482 return AVERROR_PATCHWELCOME;
6486 return AVERROR_INVALIDDATA;
6488 avio_rb32(pb); /* version and flags */
6490 if (!sc->cenc.default_encrypted_sample) {
6491 sc->cenc.default_encrypted_sample = av_encryption_info_alloc(0, 16, 16);
6492 if (!sc->cenc.default_encrypted_sample) {
6493 return AVERROR(ENOMEM);
6497 sc->cenc.default_encrypted_sample->scheme = avio_rb32(pb);
6501 static int mov_read_tenc(MOVContext *c, AVIOContext *pb, MOVAtom atom)
6504 MOVStreamContext *sc;
6505 unsigned int version, pattern, is_protected, iv_size;
6507 if (c->fc->nb_streams < 1)
6509 st = c->fc->streams[c->fc->nb_streams-1];
6512 if (sc->pseudo_stream_id != 0) {
6513 av_log(c->fc, AV_LOG_ERROR, "tenc atom are only supported in first sample descriptor\n");
6514 return AVERROR_PATCHWELCOME;
6517 if (!sc->cenc.default_encrypted_sample) {
6518 sc->cenc.default_encrypted_sample = av_encryption_info_alloc(0, 16, 16);
6519 if (!sc->cenc.default_encrypted_sample) {
6520 return AVERROR(ENOMEM);
6525 return AVERROR_INVALIDDATA;
6527 version = avio_r8(pb); /* version */
6528 avio_rb24(pb); /* flags */
6530 avio_r8(pb); /* reserved */
6531 pattern = avio_r8(pb);
6534 sc->cenc.default_encrypted_sample->crypt_byte_block = pattern >> 4;
6535 sc->cenc.default_encrypted_sample->skip_byte_block = pattern & 0xf;
6538 is_protected = avio_r8(pb);
6539 if (is_protected && !sc->cenc.encryption_index) {
6540 // The whole stream should be by-default encrypted.
6541 sc->cenc.encryption_index = av_mallocz(sizeof(MOVEncryptionIndex));
6542 if (!sc->cenc.encryption_index)
6543 return AVERROR(ENOMEM);
6545 sc->cenc.per_sample_iv_size = avio_r8(pb);
6546 if (sc->cenc.per_sample_iv_size != 0 && sc->cenc.per_sample_iv_size != 8 &&
6547 sc->cenc.per_sample_iv_size != 16) {
6548 av_log(c->fc, AV_LOG_ERROR, "invalid per-sample IV size value\n");
6549 return AVERROR_INVALIDDATA;
6551 if (avio_read(pb, sc->cenc.default_encrypted_sample->key_id, 16) != 16) {
6552 av_log(c->fc, AV_LOG_ERROR, "failed to read the default key ID\n");
6553 return AVERROR_INVALIDDATA;
6556 if (is_protected && !sc->cenc.per_sample_iv_size) {
6557 iv_size = avio_r8(pb);
6558 if (iv_size != 8 && iv_size != 16) {
6559 av_log(c->fc, AV_LOG_ERROR, "invalid default_constant_IV_size in tenc atom\n");
6560 return AVERROR_INVALIDDATA;
6563 if (avio_read(pb, sc->cenc.default_encrypted_sample->iv, iv_size) != iv_size) {
6564 av_log(c->fc, AV_LOG_ERROR, "failed to read the default IV\n");
6565 return AVERROR_INVALIDDATA;
6572 static int mov_read_dfla(MOVContext *c, AVIOContext *pb, MOVAtom atom)
6575 int last, type, size, ret;
6578 if (c->fc->nb_streams < 1)
6580 st = c->fc->streams[c->fc->nb_streams-1];
6582 if ((uint64_t)atom.size > (1<<30) || atom.size < 42)
6583 return AVERROR_INVALIDDATA;
6585 /* Check FlacSpecificBox version. */
6586 if (avio_r8(pb) != 0)
6587 return AVERROR_INVALIDDATA;
6589 avio_rb24(pb); /* Flags */
6591 avio_read(pb, buf, sizeof(buf));
6592 flac_parse_block_header(buf, &last, &type, &size);
6594 if (type != FLAC_METADATA_TYPE_STREAMINFO || size != FLAC_STREAMINFO_SIZE) {
6595 av_log(c->fc, AV_LOG_ERROR, "STREAMINFO must be first FLACMetadataBlock\n");
6596 return AVERROR_INVALIDDATA;
6599 ret = ff_get_extradata(c->fc, st->codecpar, pb, size);
6604 av_log(c->fc, AV_LOG_WARNING, "non-STREAMINFO FLACMetadataBlock(s) ignored\n");
6609 static int cenc_decrypt(MOVContext *c, MOVStreamContext *sc, AVEncryptionInfo *sample, uint8_t *input, int size)
6613 if (sample->scheme != MKBETAG('c','e','n','c') || sample->crypt_byte_block != 0 || sample->skip_byte_block != 0) {
6614 av_log(c->fc, AV_LOG_ERROR, "Only the 'cenc' encryption scheme is supported\n");
6615 return AVERROR_PATCHWELCOME;
6618 if (!sc->cenc.aes_ctr) {
6619 /* initialize the cipher */
6620 sc->cenc.aes_ctr = av_aes_ctr_alloc();
6621 if (!sc->cenc.aes_ctr) {
6622 return AVERROR(ENOMEM);
6625 ret = av_aes_ctr_init(sc->cenc.aes_ctr, c->decryption_key);
6631 av_aes_ctr_set_full_iv(sc->cenc.aes_ctr, sample->iv);
6633 if (!sample->subsample_count) {
6634 /* decrypt the whole packet */
6635 av_aes_ctr_crypt(sc->cenc.aes_ctr, input, input, size);
6639 for (i = 0; i < sample->subsample_count; i++) {
6640 if (sample->subsamples[i].bytes_of_clear_data + sample->subsamples[i].bytes_of_protected_data > size) {
6641 av_log(c->fc, AV_LOG_ERROR, "subsample size exceeds the packet size left\n");
6642 return AVERROR_INVALIDDATA;
6645 /* skip the clear bytes */
6646 input += sample->subsamples[i].bytes_of_clear_data;
6647 size -= sample->subsamples[i].bytes_of_clear_data;
6649 /* decrypt the encrypted bytes */
6650 av_aes_ctr_crypt(sc->cenc.aes_ctr, input, input, sample->subsamples[i].bytes_of_protected_data);
6651 input += sample->subsamples[i].bytes_of_protected_data;
6652 size -= sample->subsamples[i].bytes_of_protected_data;
6656 av_log(c->fc, AV_LOG_ERROR, "leftover packet bytes after subsample processing\n");
6657 return AVERROR_INVALIDDATA;
6663 static int cenc_filter(MOVContext *mov, AVStream* st, MOVStreamContext *sc, AVPacket *pkt, int current_index)
6665 MOVFragmentStreamInfo *frag_stream_info;
6666 MOVEncryptionIndex *encryption_index;
6667 AVEncryptionInfo *encrypted_sample;
6668 int encrypted_index, ret;
6670 frag_stream_info = get_frag_stream_info(&mov->frag_index, mov->frag_index.current, st->id);
6671 encrypted_index = current_index;
6672 encryption_index = NULL;
6673 if (frag_stream_info) {
6674 // Note this only supports encryption info in the first sample descriptor.
6675 if (mov->fragment.stsd_id == 1) {
6676 if (frag_stream_info->encryption_index) {
6677 encrypted_index = current_index - frag_stream_info->index_entry;
6678 encryption_index = frag_stream_info->encryption_index;
6680 encryption_index = sc->cenc.encryption_index;
6684 encryption_index = sc->cenc.encryption_index;
6687 if (encryption_index) {
6688 if (encryption_index->auxiliary_info_sample_count &&
6689 !encryption_index->nb_encrypted_samples) {
6690 av_log(mov->fc, AV_LOG_ERROR, "saiz atom found without saio\n");
6691 return AVERROR_INVALIDDATA;
6693 if (encryption_index->auxiliary_offsets_count &&
6694 !encryption_index->nb_encrypted_samples) {
6695 av_log(mov->fc, AV_LOG_ERROR, "saio atom found without saiz\n");
6696 return AVERROR_INVALIDDATA;
6699 if (!encryption_index->nb_encrypted_samples) {
6700 // Full-sample encryption with default settings.
6701 encrypted_sample = sc->cenc.default_encrypted_sample;
6702 } else if (encrypted_index >= 0 && encrypted_index < encryption_index->nb_encrypted_samples) {
6703 // Per-sample setting override.
6704 encrypted_sample = encryption_index->encrypted_samples[encrypted_index];
6706 av_log(mov->fc, AV_LOG_ERROR, "Incorrect number of samples in encryption info\n");
6707 return AVERROR_INVALIDDATA;
6710 if (mov->decryption_key) {
6711 return cenc_decrypt(mov, sc, encrypted_sample, pkt->data, pkt->size);
6714 uint8_t *side_data = av_encryption_info_add_side_data(encrypted_sample, &size);
6716 return AVERROR(ENOMEM);
6717 ret = av_packet_add_side_data(pkt, AV_PKT_DATA_ENCRYPTION_INFO, side_data, size);
6727 static int mov_read_dops(MOVContext *c, AVIOContext *pb, MOVAtom atom)
6729 const int OPUS_SEEK_PREROLL_MS = 80;
6735 if (c->fc->nb_streams < 1)
6737 st = c->fc->streams[c->fc->nb_streams-1];
6739 if ((uint64_t)atom.size > (1<<30) || atom.size < 11)
6740 return AVERROR_INVALIDDATA;
6742 /* Check OpusSpecificBox version. */
6743 if (avio_r8(pb) != 0) {
6744 av_log(c->fc, AV_LOG_ERROR, "unsupported OpusSpecificBox version\n");
6745 return AVERROR_INVALIDDATA;
6748 /* OpusSpecificBox size plus magic for Ogg OpusHead header. */
6749 size = atom.size + 8;
6751 if ((ret = ff_alloc_extradata(st->codecpar, size)) < 0)
6754 AV_WL32(st->codecpar->extradata, MKTAG('O','p','u','s'));
6755 AV_WL32(st->codecpar->extradata + 4, MKTAG('H','e','a','d'));
6756 AV_WB8(st->codecpar->extradata + 8, 1); /* OpusHead version */
6757 avio_read(pb, st->codecpar->extradata + 9, size - 9);
6759 /* OpusSpecificBox is stored in big-endian, but OpusHead is
6760 little-endian; aside from the preceeding magic and version they're
6761 otherwise currently identical. Data after output gain at offset 16
6762 doesn't need to be bytewapped. */
6763 pre_skip = AV_RB16(st->codecpar->extradata + 10);
6764 AV_WL16(st->codecpar->extradata + 10, pre_skip);
6765 AV_WL32(st->codecpar->extradata + 12, AV_RB32(st->codecpar->extradata + 12));
6766 AV_WL16(st->codecpar->extradata + 16, AV_RB16(st->codecpar->extradata + 16));
6768 st->codecpar->initial_padding = pre_skip;
6769 st->codecpar->seek_preroll = av_rescale_q(OPUS_SEEK_PREROLL_MS,
6770 (AVRational){1, 1000},
6771 (AVRational){1, 48000});
6776 static int mov_read_dmlp(MOVContext *c, AVIOContext *pb, MOVAtom atom)
6779 unsigned format_info;
6780 int channel_assignment, channel_assignment1, channel_assignment2;
6783 if (c->fc->nb_streams < 1)
6785 st = c->fc->streams[c->fc->nb_streams-1];
6788 return AVERROR_INVALIDDATA;
6790 format_info = avio_rb32(pb);
6792 ratebits = (format_info >> 28) & 0xF;
6793 channel_assignment1 = (format_info >> 15) & 0x1F;
6794 channel_assignment2 = format_info & 0x1FFF;
6795 if (channel_assignment2)
6796 channel_assignment = channel_assignment2;
6798 channel_assignment = channel_assignment1;
6800 st->codecpar->frame_size = 40 << (ratebits & 0x7);
6801 st->codecpar->sample_rate = mlp_samplerate(ratebits);
6802 st->codecpar->channels = truehd_channels(channel_assignment);
6803 st->codecpar->channel_layout = truehd_layout(channel_assignment);
6808 static int mov_read_dvcc_dvvc(MOVContext *c, AVIOContext *pb, MOVAtom atom)
6812 AVDOVIDecoderConfigurationRecord *dovi;
6816 if (c->fc->nb_streams < 1)
6818 st = c->fc->streams[c->fc->nb_streams-1];
6820 if ((uint64_t)atom.size > (1<<30) || atom.size < 4)
6821 return AVERROR_INVALIDDATA;
6823 dovi = av_dovi_alloc(&dovi_size);
6825 return AVERROR(ENOMEM);
6827 dovi->dv_version_major = avio_r8(pb);
6828 dovi->dv_version_minor = avio_r8(pb);
6830 buf = avio_rb16(pb);
6831 dovi->dv_profile = (buf >> 9) & 0x7f; // 7 bits
6832 dovi->dv_level = (buf >> 3) & 0x3f; // 6 bits
6833 dovi->rpu_present_flag = (buf >> 2) & 0x01; // 1 bit
6834 dovi->el_present_flag = (buf >> 1) & 0x01; // 1 bit
6835 dovi->bl_present_flag = buf & 0x01; // 1 bit
6836 if (atom.size >= 24) { // 4 + 4 + 4 * 4
6838 dovi->dv_bl_signal_compatibility_id = (buf >> 4) & 0x0f; // 4 bits
6840 // 0 stands for None
6841 // Dolby Vision V1.2.93 profiles and levels
6842 dovi->dv_bl_signal_compatibility_id = 0;
6845 ret = av_stream_add_side_data(st, AV_PKT_DATA_DOVI_CONF,
6846 (uint8_t *)dovi, dovi_size);
6852 av_log(c, AV_LOG_TRACE, "DOVI in dvcC/dvvC box, version: %d.%d, profile: %d, level: %d, "
6853 "rpu flag: %d, el flag: %d, bl flag: %d, compatibility id: %d\n",
6854 dovi->dv_version_major, dovi->dv_version_minor,
6855 dovi->dv_profile, dovi->dv_level,
6856 dovi->rpu_present_flag,
6857 dovi->el_present_flag,
6858 dovi->bl_present_flag,
6859 dovi->dv_bl_signal_compatibility_id
6865 static const MOVParseTableEntry mov_default_parse_table[] = {
6866 { MKTAG('A','C','L','R'), mov_read_aclr },
6867 { MKTAG('A','P','R','G'), mov_read_avid },
6868 { MKTAG('A','A','L','P'), mov_read_avid },
6869 { MKTAG('A','R','E','S'), mov_read_ares },
6870 { MKTAG('a','v','s','s'), mov_read_avss },
6871 { MKTAG('a','v','1','C'), mov_read_av1c },
6872 { MKTAG('c','h','p','l'), mov_read_chpl },
6873 { MKTAG('c','o','6','4'), mov_read_stco },
6874 { MKTAG('c','o','l','r'), mov_read_colr },
6875 { MKTAG('c','t','t','s'), mov_read_ctts }, /* composition time to sample */
6876 { MKTAG('d','i','n','f'), mov_read_default },
6877 { MKTAG('D','p','x','E'), mov_read_dpxe },
6878 { MKTAG('d','r','e','f'), mov_read_dref },
6879 { MKTAG('e','d','t','s'), mov_read_default },
6880 { MKTAG('e','l','s','t'), mov_read_elst },
6881 { MKTAG('e','n','d','a'), mov_read_enda },
6882 { MKTAG('f','i','e','l'), mov_read_fiel },
6883 { MKTAG('a','d','r','m'), mov_read_adrm },
6884 { MKTAG('f','t','y','p'), mov_read_ftyp },
6885 { MKTAG('g','l','b','l'), mov_read_glbl },
6886 { MKTAG('h','d','l','r'), mov_read_hdlr },
6887 { MKTAG('i','l','s','t'), mov_read_ilst },
6888 { MKTAG('j','p','2','h'), mov_read_jp2h },
6889 { MKTAG('m','d','a','t'), mov_read_mdat },
6890 { MKTAG('m','d','h','d'), mov_read_mdhd },
6891 { MKTAG('m','d','i','a'), mov_read_default },
6892 { MKTAG('m','e','t','a'), mov_read_meta },
6893 { MKTAG('m','i','n','f'), mov_read_default },
6894 { MKTAG('m','o','o','f'), mov_read_moof },
6895 { MKTAG('m','o','o','v'), mov_read_moov },
6896 { MKTAG('m','v','e','x'), mov_read_default },
6897 { MKTAG('m','v','h','d'), mov_read_mvhd },
6898 { MKTAG('S','M','I',' '), mov_read_svq3 },
6899 { MKTAG('a','l','a','c'), mov_read_alac }, /* alac specific atom */
6900 { MKTAG('a','v','c','C'), mov_read_glbl },
6901 { MKTAG('p','a','s','p'), mov_read_pasp },
6902 { MKTAG('s','i','d','x'), mov_read_sidx },
6903 { MKTAG('s','t','b','l'), mov_read_default },
6904 { MKTAG('s','t','c','o'), mov_read_stco },
6905 { MKTAG('s','t','p','s'), mov_read_stps },
6906 { MKTAG('s','t','r','f'), mov_read_strf },
6907 { MKTAG('s','t','s','c'), mov_read_stsc },
6908 { MKTAG('s','t','s','d'), mov_read_stsd }, /* sample description */
6909 { MKTAG('s','t','s','s'), mov_read_stss }, /* sync sample */
6910 { MKTAG('s','t','s','z'), mov_read_stsz }, /* sample size */
6911 { MKTAG('s','t','t','s'), mov_read_stts },
6912 { MKTAG('s','t','z','2'), mov_read_stsz }, /* compact sample size */
6913 { MKTAG('s','d','t','p'), mov_read_sdtp }, /* independent and disposable samples */
6914 { MKTAG('t','k','h','d'), mov_read_tkhd }, /* track header */
6915 { MKTAG('t','f','d','t'), mov_read_tfdt },
6916 { MKTAG('t','f','h','d'), mov_read_tfhd }, /* track fragment header */
6917 { MKTAG('t','r','a','k'), mov_read_trak },
6918 { MKTAG('t','r','a','f'), mov_read_default },
6919 { MKTAG('t','r','e','f'), mov_read_default },
6920 { MKTAG('t','m','c','d'), mov_read_tmcd },
6921 { MKTAG('c','h','a','p'), mov_read_chap },
6922 { MKTAG('t','r','e','x'), mov_read_trex },
6923 { MKTAG('t','r','u','n'), mov_read_trun },
6924 { MKTAG('u','d','t','a'), mov_read_default },
6925 { MKTAG('w','a','v','e'), mov_read_wave },
6926 { MKTAG('e','s','d','s'), mov_read_esds },
6927 { MKTAG('d','a','c','3'), mov_read_dac3 }, /* AC-3 info */
6928 { MKTAG('d','e','c','3'), mov_read_dec3 }, /* EAC-3 info */
6929 { MKTAG('d','d','t','s'), mov_read_ddts }, /* DTS audio descriptor */
6930 { MKTAG('w','i','d','e'), mov_read_wide }, /* place holder */
6931 { MKTAG('w','f','e','x'), mov_read_wfex },
6932 { MKTAG('c','m','o','v'), mov_read_cmov },
6933 { MKTAG('c','h','a','n'), mov_read_chan }, /* channel layout */
6934 { MKTAG('d','v','c','1'), mov_read_dvc1 },
6935 { MKTAG('s','b','g','p'), mov_read_sbgp },
6936 { MKTAG('h','v','c','C'), mov_read_glbl },
6937 { MKTAG('u','u','i','d'), mov_read_uuid },
6938 { MKTAG('C','i','n', 0x8e), mov_read_targa_y216 },
6939 { MKTAG('f','r','e','e'), mov_read_free },
6940 { MKTAG('-','-','-','-'), mov_read_custom },
6941 { MKTAG('s','i','n','f'), mov_read_default },
6942 { MKTAG('f','r','m','a'), mov_read_frma },
6943 { MKTAG('s','e','n','c'), mov_read_senc },
6944 { MKTAG('s','a','i','z'), mov_read_saiz },
6945 { MKTAG('s','a','i','o'), mov_read_saio },
6946 { MKTAG('p','s','s','h'), mov_read_pssh },
6947 { MKTAG('s','c','h','m'), mov_read_schm },
6948 { MKTAG('s','c','h','i'), mov_read_default },
6949 { MKTAG('t','e','n','c'), mov_read_tenc },
6950 { MKTAG('d','f','L','a'), mov_read_dfla },
6951 { MKTAG('s','t','3','d'), mov_read_st3d }, /* stereoscopic 3D video box */
6952 { MKTAG('s','v','3','d'), mov_read_sv3d }, /* spherical video box */
6953 { MKTAG('d','O','p','s'), mov_read_dops },
6954 { MKTAG('d','m','l','p'), mov_read_dmlp },
6955 { MKTAG('S','m','D','m'), mov_read_smdm },
6956 { MKTAG('C','o','L','L'), mov_read_coll },
6957 { MKTAG('v','p','c','C'), mov_read_vpcc },
6958 { MKTAG('m','d','c','v'), mov_read_mdcv },
6959 { MKTAG('c','l','l','i'), mov_read_clli },
6960 { MKTAG('d','v','c','C'), mov_read_dvcc_dvvc },
6961 { MKTAG('d','v','v','C'), mov_read_dvcc_dvvc },
6965 static int mov_read_default(MOVContext *c, AVIOContext *pb, MOVAtom atom)
6967 int64_t total_size = 0;
6971 if (c->atom_depth > 10) {
6972 av_log(c->fc, AV_LOG_ERROR, "Atoms too deeply nested\n");
6973 return AVERROR_INVALIDDATA;
6978 atom.size = INT64_MAX;
6979 while (total_size <= atom.size - 8 && !avio_feof(pb)) {
6980 int (*parse)(MOVContext*, AVIOContext*, MOVAtom) = NULL;
6983 if (atom.size >= 8) {
6984 a.size = avio_rb32(pb);
6985 a.type = avio_rl32(pb);
6986 if (((a.type == MKTAG('f','r','e','e') && c->moov_retry) ||
6987 a.type == MKTAG('h','o','o','v')) &&
6989 c->fc->strict_std_compliance < FF_COMPLIANCE_STRICT) {
6992 type = avio_rl32(pb);
6995 avio_seek(pb, -8, SEEK_CUR);
6996 if (type == MKTAG('m','v','h','d') ||
6997 type == MKTAG('c','m','o','v')) {
6998 av_log(c->fc, AV_LOG_ERROR, "Detected moov in a free or hoov atom.\n");
6999 a.type = MKTAG('m','o','o','v');
7002 if (atom.type != MKTAG('r','o','o','t') &&
7003 atom.type != MKTAG('m','o','o','v')) {
7004 if (a.type == MKTAG('t','r','a','k') ||
7005 a.type == MKTAG('m','d','a','t')) {
7006 av_log(c->fc, AV_LOG_ERROR, "Broken file, trak/mdat not at top-level\n");
7013 if (a.size == 1 && total_size + 8 <= atom.size) { /* 64 bit extended size */
7014 a.size = avio_rb64(pb) - 8;
7018 av_log(c->fc, AV_LOG_TRACE, "type:'%s' parent:'%s' sz: %"PRId64" %"PRId64" %"PRId64"\n",
7019 av_fourcc2str(a.type), av_fourcc2str(atom.type), a.size, total_size, atom.size);
7021 a.size = atom.size - total_size + 8;
7026 a.size = FFMIN(a.size, atom.size - total_size);
7028 for (i = 0; mov_default_parse_table[i].type; i++)
7029 if (mov_default_parse_table[i].type == a.type) {
7030 parse = mov_default_parse_table[i].parse;
7034 // container is user data
7035 if (!parse && (atom.type == MKTAG('u','d','t','a') ||
7036 atom.type == MKTAG('i','l','s','t')))
7037 parse = mov_read_udta_string;
7039 // Supports parsing the QuickTime Metadata Keys.
7040 // https://developer.apple.com/library/mac/documentation/QuickTime/QTFF/Metadata/Metadata.html
7041 if (!parse && c->found_hdlr_mdta &&
7042 atom.type == MKTAG('m','e','t','a') &&
7043 a.type == MKTAG('k','e','y','s') &&
7044 c->meta_keys_count == 0) {
7045 parse = mov_read_keys;
7048 if (!parse) { /* skip leaf atoms data */
7049 avio_skip(pb, a.size);
7051 int64_t start_pos = avio_tell(pb);
7053 int err = parse(c, pb, a);
7058 if (c->found_moov && c->found_mdat && a.size <= INT64_MAX - start_pos &&
7059 ((!(pb->seekable & AVIO_SEEKABLE_NORMAL) || c->fc->flags & AVFMT_FLAG_IGNIDX || c->frag_index.complete) ||
7060 start_pos + a.size == avio_size(pb))) {
7061 if (!(pb->seekable & AVIO_SEEKABLE_NORMAL) || c->fc->flags & AVFMT_FLAG_IGNIDX || c->frag_index.complete)
7062 c->next_root_atom = start_pos + a.size;
7066 left = a.size - avio_tell(pb) + start_pos;
7067 if (left > 0) /* skip garbage at atom end */
7068 avio_skip(pb, left);
7069 else if (left < 0) {
7070 av_log(c->fc, AV_LOG_WARNING,
7071 "overread end of atom '%s' by %"PRId64" bytes\n",
7072 av_fourcc2str(a.type), -left);
7073 avio_seek(pb, left, SEEK_CUR);
7077 total_size += a.size;
7080 if (total_size < atom.size && atom.size < 0x7ffff)
7081 avio_skip(pb, atom.size - total_size);
7087 static int mov_probe(const AVProbeData *p)
7092 int moov_offset = -1;
7094 /* check file header */
7099 /* ignore invalid offset */
7100 if ((offset + 8ULL) > (unsigned int)p->buf_size)
7102 size = AV_RB32(p->buf + offset);
7103 if (size == 1 && offset + 16 <= (unsigned int)p->buf_size) {
7104 size = AV_RB64(p->buf+offset + 8);
7106 } else if (size == 0) {
7107 size = p->buf_size - offset;
7109 if (size < minsize) {
7113 tag = AV_RL32(p->buf + offset + 4);
7115 /* check for obvious tags */
7116 case MKTAG('m','o','o','v'):
7117 moov_offset = offset + 4;
7118 case MKTAG('m','d','a','t'):
7119 case MKTAG('p','n','o','t'): /* detect movs with preview pics like ew.mov and april.mov */
7120 case MKTAG('u','d','t','a'): /* Packet Video PVAuthor adds this and a lot of more junk */
7121 case MKTAG('f','t','y','p'):
7122 if (tag == MKTAG('f','t','y','p') &&
7123 ( AV_RL32(p->buf + offset + 8) == MKTAG('j','p','2',' ')
7124 || AV_RL32(p->buf + offset + 8) == MKTAG('j','p','x',' ')
7126 score = FFMAX(score, 5);
7128 score = AVPROBE_SCORE_MAX;
7131 /* those are more common words, so rate then a bit less */
7132 case MKTAG('e','d','i','w'): /* xdcam files have reverted first tags */
7133 case MKTAG('w','i','d','e'):
7134 case MKTAG('f','r','e','e'):
7135 case MKTAG('j','u','n','k'):
7136 case MKTAG('p','i','c','t'):
7137 score = FFMAX(score, AVPROBE_SCORE_MAX - 5);
7139 case MKTAG(0x82,0x82,0x7f,0x7d):
7140 case MKTAG('s','k','i','p'):
7141 case MKTAG('u','u','i','d'):
7142 case MKTAG('p','r','f','l'):
7143 /* if we only find those cause probedata is too small at least rate them */
7144 score = FFMAX(score, AVPROBE_SCORE_EXTENSION);
7147 if (size > INT64_MAX - offset)
7151 if (score > AVPROBE_SCORE_MAX - 50 && moov_offset != -1) {
7152 /* moov atom in the header - we should make sure that this is not a
7153 * MOV-packed MPEG-PS */
7154 offset = moov_offset;
7156 while (offset < (p->buf_size - 16)) { /* Sufficient space */
7157 /* We found an actual hdlr atom */
7158 if (AV_RL32(p->buf + offset ) == MKTAG('h','d','l','r') &&
7159 AV_RL32(p->buf + offset + 8) == MKTAG('m','h','l','r') &&
7160 AV_RL32(p->buf + offset + 12) == MKTAG('M','P','E','G')) {
7161 av_log(NULL, AV_LOG_WARNING, "Found media data tag MPEG indicating this is a MOV-packed MPEG-PS.\n");
7162 /* We found a media handler reference atom describing an
7163 * MPEG-PS-in-MOV, return a
7164 * low score to force expanding the probe window until
7165 * mpegps_probe finds what it needs */
7177 // must be done after parsing all trak because there's no order requirement
7178 static void mov_read_chapters(AVFormatContext *s)
7180 MOVContext *mov = s->priv_data;
7182 MOVStreamContext *sc;
7187 for (j = 0; j < mov->nb_chapter_tracks; j++) {
7188 chapter_track = mov->chapter_tracks[j];
7190 for (i = 0; i < s->nb_streams; i++)
7191 if (s->streams[i]->id == chapter_track) {
7196 av_log(s, AV_LOG_ERROR, "Referenced QT chapter track not found\n");
7201 cur_pos = avio_tell(sc->pb);
7203 if (st->codecpar->codec_type == AVMEDIA_TYPE_VIDEO) {
7204 st->disposition |= AV_DISPOSITION_ATTACHED_PIC | AV_DISPOSITION_TIMED_THUMBNAILS;
7205 if (st->internal->nb_index_entries) {
7206 // Retrieve the first frame, if possible
7207 AVIndexEntry *sample = &st->internal->index_entries[0];
7208 if (avio_seek(sc->pb, sample->pos, SEEK_SET) != sample->pos) {
7209 av_log(s, AV_LOG_ERROR, "Failed to retrieve first frame\n");
7213 if (ff_add_attached_pic(s, st, sc->pb, NULL, sample->size) < 0)
7217 st->codecpar->codec_type = AVMEDIA_TYPE_DATA;
7218 st->codecpar->codec_id = AV_CODEC_ID_BIN_DATA;
7219 st->discard = AVDISCARD_ALL;
7220 for (i = 0; i < st->internal->nb_index_entries; i++) {
7221 AVIndexEntry *sample = &st->internal->index_entries[i];
7222 int64_t end = i+1 < st->internal->nb_index_entries ? st->internal->index_entries[i+1].timestamp : st->duration;
7227 if (end < sample->timestamp) {
7228 av_log(s, AV_LOG_WARNING, "ignoring stream duration which is shorter than chapters\n");
7229 end = AV_NOPTS_VALUE;
7232 if (avio_seek(sc->pb, sample->pos, SEEK_SET) != sample->pos) {
7233 av_log(s, AV_LOG_ERROR, "Chapter %d not found in file\n", i);
7237 // the first two bytes are the length of the title
7238 len = avio_rb16(sc->pb);
7239 if (len > sample->size-2)
7241 title_len = 2*len + 1;
7242 if (!(title = av_mallocz(title_len)))
7245 // The samples could theoretically be in any encoding if there's an encd
7246 // atom following, but in practice are only utf-8 or utf-16, distinguished
7247 // instead by the presence of a BOM
7251 ch = avio_rb16(sc->pb);
7253 avio_get_str16be(sc->pb, len, title, title_len);
7254 else if (ch == 0xfffe)
7255 avio_get_str16le(sc->pb, len, title, title_len);
7258 if (len == 1 || len == 2)
7261 avio_get_str(sc->pb, INT_MAX, title + 2, len - 1);
7265 avpriv_new_chapter(s, i, st->time_base, sample->timestamp, end, title);
7270 avio_seek(sc->pb, cur_pos, SEEK_SET);
7274 static int parse_timecode_in_framenum_format(AVFormatContext *s, AVStream *st,
7275 uint32_t value, int flags)
7278 char buf[AV_TIMECODE_STR_SIZE];
7279 AVRational rate = st->avg_frame_rate;
7280 int ret = av_timecode_init(&tc, rate, flags, 0, s);
7283 av_dict_set(&st->metadata, "timecode",
7284 av_timecode_make_string(&tc, buf, value), 0);
7288 static int mov_read_rtmd_track(AVFormatContext *s, AVStream *st)
7290 MOVStreamContext *sc = st->priv_data;
7291 char buf[AV_TIMECODE_STR_SIZE];
7292 int64_t cur_pos = avio_tell(sc->pb);
7293 int hh, mm, ss, ff, drop;
7295 if (!st->internal->nb_index_entries)
7298 avio_seek(sc->pb, st->internal->index_entries->pos, SEEK_SET);
7299 avio_skip(s->pb, 13);
7300 hh = avio_r8(s->pb);
7301 mm = avio_r8(s->pb);
7302 ss = avio_r8(s->pb);
7303 drop = avio_r8(s->pb);
7304 ff = avio_r8(s->pb);
7305 snprintf(buf, AV_TIMECODE_STR_SIZE, "%02d:%02d:%02d%c%02d",
7306 hh, mm, ss, drop ? ';' : ':', ff);
7307 av_dict_set(&st->metadata, "timecode", buf, 0);
7309 avio_seek(sc->pb, cur_pos, SEEK_SET);
7313 static int mov_read_timecode_track(AVFormatContext *s, AVStream *st)
7315 MOVStreamContext *sc = st->priv_data;
7317 int64_t cur_pos = avio_tell(sc->pb);
7320 if (!st->internal->nb_index_entries)
7323 avio_seek(sc->pb, st->internal->index_entries->pos, SEEK_SET);
7324 value = avio_rb32(s->pb);
7326 if (sc->tmcd_flags & 0x0001) flags |= AV_TIMECODE_FLAG_DROPFRAME;
7327 if (sc->tmcd_flags & 0x0002) flags |= AV_TIMECODE_FLAG_24HOURSMAX;
7328 if (sc->tmcd_flags & 0x0004) flags |= AV_TIMECODE_FLAG_ALLOWNEGATIVE;
7330 /* Assume Counter flag is set to 1 in tmcd track (even though it is likely
7331 * not the case) and thus assume "frame number format" instead of QT one.
7332 * No sample with tmcd track can be found with a QT timecode at the moment,
7333 * despite what the tmcd track "suggests" (Counter flag set to 0 means QT
7335 parse_timecode_in_framenum_format(s, st, value, flags);
7337 avio_seek(sc->pb, cur_pos, SEEK_SET);
7341 static void mov_free_encryption_index(MOVEncryptionIndex **index) {
7343 if (!index || !*index) return;
7344 for (i = 0; i < (*index)->nb_encrypted_samples; i++) {
7345 av_encryption_info_free((*index)->encrypted_samples[i]);
7347 av_freep(&(*index)->encrypted_samples);
7348 av_freep(&(*index)->auxiliary_info_sizes);
7349 av_freep(&(*index)->auxiliary_offsets);
7353 static int mov_read_close(AVFormatContext *s)
7355 MOVContext *mov = s->priv_data;
7358 for (i = 0; i < s->nb_streams; i++) {
7359 AVStream *st = s->streams[i];
7360 MOVStreamContext *sc = st->priv_data;
7365 av_freep(&sc->ctts_data);
7366 for (j = 0; j < sc->drefs_count; j++) {
7367 av_freep(&sc->drefs[j].path);
7368 av_freep(&sc->drefs[j].dir);
7370 av_freep(&sc->drefs);
7372 sc->drefs_count = 0;
7374 if (!sc->pb_is_copied)
7375 ff_format_io_close(s, &sc->pb);
7378 av_freep(&sc->chunk_offsets);
7379 av_freep(&sc->stsc_data);
7380 av_freep(&sc->sample_sizes);
7381 av_freep(&sc->keyframes);
7382 av_freep(&sc->stts_data);
7383 av_freep(&sc->sdtp_data);
7384 av_freep(&sc->stps_data);
7385 av_freep(&sc->elst_data);
7386 av_freep(&sc->rap_group);
7387 av_freep(&sc->display_matrix);
7388 av_freep(&sc->index_ranges);
7391 for (j = 0; j < sc->stsd_count; j++)
7392 av_free(sc->extradata[j]);
7393 av_freep(&sc->extradata);
7394 av_freep(&sc->extradata_size);
7396 mov_free_encryption_index(&sc->cenc.encryption_index);
7397 av_encryption_info_free(sc->cenc.default_encrypted_sample);
7398 av_aes_ctr_free(sc->cenc.aes_ctr);
7400 av_freep(&sc->stereo3d);
7401 av_freep(&sc->spherical);
7402 av_freep(&sc->mastering);
7403 av_freep(&sc->coll);
7406 av_freep(&mov->dv_demux);
7407 avformat_free_context(mov->dv_fctx);
7408 mov->dv_fctx = NULL;
7410 if (mov->meta_keys) {
7411 for (i = 1; i < mov->meta_keys_count; i++) {
7412 av_freep(&mov->meta_keys[i]);
7414 av_freep(&mov->meta_keys);
7417 av_freep(&mov->trex_data);
7418 av_freep(&mov->bitrates);
7420 for (i = 0; i < mov->frag_index.nb_items; i++) {
7421 MOVFragmentStreamInfo *frag = mov->frag_index.item[i].stream_info;
7422 for (j = 0; j < mov->frag_index.item[i].nb_stream_info; j++) {
7423 mov_free_encryption_index(&frag[j].encryption_index);
7425 av_freep(&mov->frag_index.item[i].stream_info);
7427 av_freep(&mov->frag_index.item);
7429 av_freep(&mov->aes_decrypt);
7430 av_freep(&mov->chapter_tracks);
7435 static int tmcd_is_referenced(AVFormatContext *s, int tmcd_id)
7439 for (i = 0; i < s->nb_streams; i++) {
7440 AVStream *st = s->streams[i];
7441 MOVStreamContext *sc = st->priv_data;
7443 if (st->codecpar->codec_type == AVMEDIA_TYPE_VIDEO &&
7444 sc->timecode_track == tmcd_id)
7450 /* look for a tmcd track not referenced by any video track, and export it globally */
7451 static void export_orphan_timecode(AVFormatContext *s)
7455 for (i = 0; i < s->nb_streams; i++) {
7456 AVStream *st = s->streams[i];
7458 if (st->codecpar->codec_tag == MKTAG('t','m','c','d') &&
7459 !tmcd_is_referenced(s, i + 1)) {
7460 AVDictionaryEntry *tcr = av_dict_get(st->metadata, "timecode", NULL, 0);
7462 av_dict_set(&s->metadata, "timecode", tcr->value, 0);
7469 static int read_tfra(MOVContext *mov, AVIOContext *f)
7471 int version, fieldlength, i, j;
7472 int64_t pos = avio_tell(f);
7473 uint32_t size = avio_rb32(f);
7474 unsigned track_id, item_count;
7476 if (avio_rb32(f) != MKBETAG('t', 'f', 'r', 'a')) {
7479 av_log(mov->fc, AV_LOG_VERBOSE, "found tfra\n");
7481 version = avio_r8(f);
7483 track_id = avio_rb32(f);
7484 fieldlength = avio_rb32(f);
7485 item_count = avio_rb32(f);
7486 for (i = 0; i < item_count; i++) {
7487 int64_t time, offset;
7489 MOVFragmentStreamInfo * frag_stream_info;
7492 return AVERROR_INVALIDDATA;
7496 time = avio_rb64(f);
7497 offset = avio_rb64(f);
7499 time = avio_rb32(f);
7500 offset = avio_rb32(f);
7503 // The first sample of each stream in a fragment is always a random
7504 // access sample. So it's entry in the tfra can be used as the
7505 // initial PTS of the fragment.
7506 index = update_frag_index(mov, offset);
7507 frag_stream_info = get_frag_stream_info(&mov->frag_index, index, track_id);
7508 if (frag_stream_info &&
7509 frag_stream_info->first_tfra_pts == AV_NOPTS_VALUE)
7510 frag_stream_info->first_tfra_pts = time;
7512 for (j = 0; j < ((fieldlength >> 4) & 3) + 1; j++)
7514 for (j = 0; j < ((fieldlength >> 2) & 3) + 1; j++)
7516 for (j = 0; j < ((fieldlength >> 0) & 3) + 1; j++)
7520 avio_seek(f, pos + size, SEEK_SET);
7524 static int mov_read_mfra(MOVContext *c, AVIOContext *f)
7526 int64_t stream_size = avio_size(f);
7527 int64_t original_pos = avio_tell(f);
7530 if ((seek_ret = avio_seek(f, stream_size - 4, SEEK_SET)) < 0) {
7534 c->mfra_size = avio_rb32(f);
7535 c->have_read_mfra_size = 1;
7536 if (!c->mfra_size || c->mfra_size > stream_size) {
7537 av_log(c->fc, AV_LOG_DEBUG, "doesn't look like mfra (unreasonable size)\n");
7540 if ((seek_ret = avio_seek(f, -((int64_t) c->mfra_size), SEEK_CUR)) < 0) {
7544 if (avio_rb32(f) != c->mfra_size) {
7545 av_log(c->fc, AV_LOG_DEBUG, "doesn't look like mfra (size mismatch)\n");
7548 if (avio_rb32(f) != MKBETAG('m', 'f', 'r', 'a')) {
7549 av_log(c->fc, AV_LOG_DEBUG, "doesn't look like mfra (tag mismatch)\n");
7552 av_log(c->fc, AV_LOG_VERBOSE, "stream has mfra\n");
7554 ret = read_tfra(c, f);
7559 c->frag_index.complete = 1;
7561 seek_ret = avio_seek(f, original_pos, SEEK_SET);
7563 av_log(c->fc, AV_LOG_ERROR,
7564 "failed to seek back after looking for mfra\n");
7570 static int mov_read_header(AVFormatContext *s)
7572 MOVContext *mov = s->priv_data;
7573 AVIOContext *pb = s->pb;
7575 MOVAtom atom = { AV_RL32("root") };
7578 if (mov->decryption_key_len != 0 && mov->decryption_key_len != AES_CTR_KEY_SIZE) {
7579 av_log(s, AV_LOG_ERROR, "Invalid decryption key len %d expected %d\n",
7580 mov->decryption_key_len, AES_CTR_KEY_SIZE);
7581 return AVERROR(EINVAL);
7585 mov->trak_index = -1;
7586 /* .mov and .mp4 aren't streamable anyway (only progressive download if moov is before mdat) */
7587 if (pb->seekable & AVIO_SEEKABLE_NORMAL)
7588 atom.size = avio_size(pb);
7590 atom.size = INT64_MAX;
7592 /* check MOV header */
7594 if (mov->moov_retry)
7595 avio_seek(pb, 0, SEEK_SET);
7596 if ((err = mov_read_default(mov, pb, atom)) < 0) {
7597 av_log(s, AV_LOG_ERROR, "error reading header\n");
7600 } while ((pb->seekable & AVIO_SEEKABLE_NORMAL) && !mov->found_moov && !mov->moov_retry++);
7601 if (!mov->found_moov) {
7602 av_log(s, AV_LOG_ERROR, "moov atom not found\n");
7603 err = AVERROR_INVALIDDATA;
7606 av_log(mov->fc, AV_LOG_TRACE, "on_parse_exit_offset=%"PRId64"\n", avio_tell(pb));
7608 if (pb->seekable & AVIO_SEEKABLE_NORMAL) {
7609 if (mov->nb_chapter_tracks > 0 && !mov->ignore_chapters)
7610 mov_read_chapters(s);
7611 for (i = 0; i < s->nb_streams; i++)
7612 if (s->streams[i]->codecpar->codec_tag == AV_RL32("tmcd")) {
7613 mov_read_timecode_track(s, s->streams[i]);
7614 } else if (s->streams[i]->codecpar->codec_tag == AV_RL32("rtmd")) {
7615 mov_read_rtmd_track(s, s->streams[i]);
7619 /* copy timecode metadata from tmcd tracks to the related video streams */
7620 for (i = 0; i < s->nb_streams; i++) {
7621 AVStream *st = s->streams[i];
7622 MOVStreamContext *sc = st->priv_data;
7623 if (sc->timecode_track > 0) {
7624 AVDictionaryEntry *tcr;
7625 int tmcd_st_id = -1;
7627 for (j = 0; j < s->nb_streams; j++)
7628 if (s->streams[j]->id == sc->timecode_track)
7631 if (tmcd_st_id < 0 || tmcd_st_id == i)
7633 tcr = av_dict_get(s->streams[tmcd_st_id]->metadata, "timecode", NULL, 0);
7635 av_dict_set(&st->metadata, "timecode", tcr->value, 0);
7638 export_orphan_timecode(s);
7640 for (i = 0; i < s->nb_streams; i++) {
7641 AVStream *st = s->streams[i];
7642 MOVStreamContext *sc = st->priv_data;
7643 fix_timescale(mov, sc);
7644 if (st->codecpar->codec_type == AVMEDIA_TYPE_AUDIO &&
7645 st->codecpar->codec_id == AV_CODEC_ID_AAC) {
7646 st->internal->skip_samples = sc->start_pad;
7648 if (st->codecpar->codec_type == AVMEDIA_TYPE_VIDEO && sc->nb_frames_for_fps > 0 && sc->duration_for_fps > 0)
7649 av_reduce(&st->avg_frame_rate.num, &st->avg_frame_rate.den,
7650 sc->time_scale*(int64_t)sc->nb_frames_for_fps, sc->duration_for_fps, INT_MAX);
7651 if (st->codecpar->codec_type == AVMEDIA_TYPE_SUBTITLE) {
7652 if (st->codecpar->width <= 0 || st->codecpar->height <= 0) {
7653 st->codecpar->width = sc->width;
7654 st->codecpar->height = sc->height;
7656 if (st->codecpar->codec_id == AV_CODEC_ID_DVD_SUBTITLE) {
7657 if ((err = mov_rewrite_dvd_sub_extradata(st)) < 0)
7661 if (mov->handbrake_version &&
7662 mov->handbrake_version <= 1000000*0 + 1000*10 + 2 && // 0.10.2
7663 st->codecpar->codec_id == AV_CODEC_ID_MP3) {
7664 av_log(s, AV_LOG_VERBOSE, "Forcing full parsing for mp3 stream\n");
7665 st->need_parsing = AVSTREAM_PARSE_FULL;
7669 if (mov->trex_data) {
7670 for (i = 0; i < s->nb_streams; i++) {
7671 AVStream *st = s->streams[i];
7672 MOVStreamContext *sc = st->priv_data;
7673 if (st->duration > 0) {
7674 if (sc->data_size > INT64_MAX / sc->time_scale / 8) {
7675 av_log(s, AV_LOG_ERROR, "Overflow during bit rate calculation %"PRId64" * 8 * %d\n",
7676 sc->data_size, sc->time_scale);
7677 err = AVERROR_INVALIDDATA;
7680 st->codecpar->bit_rate = sc->data_size * 8 * sc->time_scale / st->duration;
7685 if (mov->use_mfra_for > 0) {
7686 for (i = 0; i < s->nb_streams; i++) {
7687 AVStream *st = s->streams[i];
7688 MOVStreamContext *sc = st->priv_data;
7689 if (sc->duration_for_fps > 0) {
7690 if (sc->data_size > INT64_MAX / sc->time_scale / 8) {
7691 av_log(s, AV_LOG_ERROR, "Overflow during bit rate calculation %"PRId64" * 8 * %d\n",
7692 sc->data_size, sc->time_scale);
7693 err = AVERROR_INVALIDDATA;
7696 st->codecpar->bit_rate = sc->data_size * 8 * sc->time_scale /
7697 sc->duration_for_fps;
7702 for (i = 0; i < mov->bitrates_count && i < s->nb_streams; i++) {
7703 if (mov->bitrates[i]) {
7704 s->streams[i]->codecpar->bit_rate = mov->bitrates[i];
7708 ff_rfps_calculate(s);
7710 for (i = 0; i < s->nb_streams; i++) {
7711 AVStream *st = s->streams[i];
7712 MOVStreamContext *sc = st->priv_data;
7714 switch (st->codecpar->codec_type) {
7715 case AVMEDIA_TYPE_AUDIO:
7716 err = ff_replaygain_export(st, s->metadata);
7720 case AVMEDIA_TYPE_VIDEO:
7721 if (sc->display_matrix) {
7722 err = av_stream_add_side_data(st, AV_PKT_DATA_DISPLAYMATRIX, (uint8_t*)sc->display_matrix,
7723 sizeof(int32_t) * 9);
7727 sc->display_matrix = NULL;
7730 err = av_stream_add_side_data(st, AV_PKT_DATA_STEREO3D,
7731 (uint8_t *)sc->stereo3d,
7732 sizeof(*sc->stereo3d));
7736 sc->stereo3d = NULL;
7738 if (sc->spherical) {
7739 err = av_stream_add_side_data(st, AV_PKT_DATA_SPHERICAL,
7740 (uint8_t *)sc->spherical,
7741 sc->spherical_size);
7745 sc->spherical = NULL;
7747 if (sc->mastering) {
7748 err = av_stream_add_side_data(st, AV_PKT_DATA_MASTERING_DISPLAY_METADATA,
7749 (uint8_t *)sc->mastering,
7750 sizeof(*sc->mastering));
7754 sc->mastering = NULL;
7757 err = av_stream_add_side_data(st, AV_PKT_DATA_CONTENT_LIGHT_LEVEL,
7758 (uint8_t *)sc->coll,
7768 ff_configure_buffers_for_index(s, AV_TIME_BASE);
7770 for (i = 0; i < mov->frag_index.nb_items; i++)
7771 if (mov->frag_index.item[i].moof_offset <= mov->fragment.moof_offset)
7772 mov->frag_index.item[i].headers_read = 1;
7780 static AVIndexEntry *mov_find_next_sample(AVFormatContext *s, AVStream **st)
7782 AVIndexEntry *sample = NULL;
7783 int64_t best_dts = INT64_MAX;
7785 for (i = 0; i < s->nb_streams; i++) {
7786 AVStream *avst = s->streams[i];
7787 MOVStreamContext *msc = avst->priv_data;
7788 if (msc->pb && msc->current_sample < avst->internal->nb_index_entries) {
7789 AVIndexEntry *current_sample = &avst->internal->index_entries[msc->current_sample];
7790 int64_t dts = av_rescale(current_sample->timestamp, AV_TIME_BASE, msc->time_scale);
7791 av_log(s, AV_LOG_TRACE, "stream %d, sample %d, dts %"PRId64"\n", i, msc->current_sample, dts);
7792 if (!sample || (!(s->pb->seekable & AVIO_SEEKABLE_NORMAL) && current_sample->pos < sample->pos) ||
7793 ((s->pb->seekable & AVIO_SEEKABLE_NORMAL) &&
7794 ((msc->pb != s->pb && dts < best_dts) || (msc->pb == s->pb && dts != AV_NOPTS_VALUE &&
7795 ((FFABS(best_dts - dts) <= AV_TIME_BASE && current_sample->pos < sample->pos) ||
7796 (FFABS(best_dts - dts) > AV_TIME_BASE && dts < best_dts)))))) {
7797 sample = current_sample;
7806 static int should_retry(AVIOContext *pb, int error_code) {
7807 if (error_code == AVERROR_EOF || avio_feof(pb))
7813 static int mov_switch_root(AVFormatContext *s, int64_t target, int index)
7816 MOVContext *mov = s->priv_data;
7818 if (index >= 0 && index < mov->frag_index.nb_items)
7819 target = mov->frag_index.item[index].moof_offset;
7820 if (avio_seek(s->pb, target, SEEK_SET) != target) {
7821 av_log(mov->fc, AV_LOG_ERROR, "root atom offset 0x%"PRIx64": partial file\n", target);
7822 return AVERROR_INVALIDDATA;
7825 mov->next_root_atom = 0;
7826 if (index < 0 || index >= mov->frag_index.nb_items)
7827 index = search_frag_moof_offset(&mov->frag_index, target);
7828 if (index < mov->frag_index.nb_items &&
7829 mov->frag_index.item[index].moof_offset == target) {
7830 if (index + 1 < mov->frag_index.nb_items)
7831 mov->next_root_atom = mov->frag_index.item[index + 1].moof_offset;
7832 if (mov->frag_index.item[index].headers_read)
7834 mov->frag_index.item[index].headers_read = 1;
7837 mov->found_mdat = 0;
7839 ret = mov_read_default(mov, s->pb, (MOVAtom){ AV_RL32("root"), INT64_MAX });
7842 if (avio_feof(s->pb))
7844 av_log(s, AV_LOG_TRACE, "read fragments, offset 0x%"PRIx64"\n", avio_tell(s->pb));
7849 static int mov_change_extradata(MOVStreamContext *sc, AVPacket *pkt)
7851 uint8_t *side, *extradata;
7854 /* Save the current index. */
7855 sc->last_stsd_index = sc->stsc_data[sc->stsc_index].id - 1;
7857 /* Notify the decoder that extradata changed. */
7858 extradata_size = sc->extradata_size[sc->last_stsd_index];
7859 extradata = sc->extradata[sc->last_stsd_index];
7860 if (extradata_size > 0 && extradata) {
7861 side = av_packet_new_side_data(pkt,
7862 AV_PKT_DATA_NEW_EXTRADATA,
7865 return AVERROR(ENOMEM);
7866 memcpy(side, extradata, extradata_size);
7872 static int get_eia608_packet(AVIOContext *pb, AVPacket *pkt, int size)
7877 return AVERROR_INVALIDDATA;
7878 new_size = ((size - 8) / 2) * 3;
7879 ret = av_new_packet(pkt, new_size);
7884 for (int j = 0; j < new_size; j += 3) {
7885 pkt->data[j] = 0xFC;
7886 pkt->data[j+1] = avio_r8(pb);
7887 pkt->data[j+2] = avio_r8(pb);
7893 static int mov_read_packet(AVFormatContext *s, AVPacket *pkt)
7895 MOVContext *mov = s->priv_data;
7896 MOVStreamContext *sc;
7897 AVIndexEntry *sample;
7898 AVStream *st = NULL;
7899 int64_t current_index;
7903 sample = mov_find_next_sample(s, &st);
7904 if (!sample || (mov->next_root_atom && sample->pos > mov->next_root_atom)) {
7905 if (!mov->next_root_atom)
7907 if ((ret = mov_switch_root(s, mov->next_root_atom, -1)) < 0)
7912 /* must be done just before reading, to avoid infinite loop on sample */
7913 current_index = sc->current_index;
7914 mov_current_sample_inc(sc);
7916 if (mov->next_root_atom) {
7917 sample->pos = FFMIN(sample->pos, mov->next_root_atom);
7918 sample->size = FFMIN(sample->size, (mov->next_root_atom - sample->pos));
7921 if (st->discard != AVDISCARD_ALL) {
7922 int64_t ret64 = avio_seek(sc->pb, sample->pos, SEEK_SET);
7923 if (ret64 != sample->pos) {
7924 av_log(mov->fc, AV_LOG_ERROR, "stream %d, offset 0x%"PRIx64": partial file\n",
7925 sc->ffindex, sample->pos);
7926 if (should_retry(sc->pb, ret64)) {
7927 mov_current_sample_dec(sc);
7928 } else if (ret64 < 0) {
7931 return AVERROR_INVALIDDATA;
7934 if (st->discard == AVDISCARD_NONKEY && !(sample->flags & AVINDEX_KEYFRAME)) {
7935 av_log(mov->fc, AV_LOG_DEBUG, "Nonkey frame from stream %d discarded due to AVDISCARD_NONKEY\n", sc->ffindex);
7939 if (st->codecpar->codec_id == AV_CODEC_ID_EIA_608 && sample->size > 8)
7940 ret = get_eia608_packet(sc->pb, pkt, sample->size);
7942 ret = av_get_packet(sc->pb, pkt, sample->size);
7944 if (should_retry(sc->pb, ret)) {
7945 mov_current_sample_dec(sc);
7949 #if CONFIG_DV_DEMUXER
7950 if (mov->dv_demux && sc->dv_audio_container) {
7951 AVBufferRef *buf = pkt->buf;
7952 ret = avpriv_dv_produce_packet(mov->dv_demux, pkt, pkt->data, pkt->size, pkt->pos);
7954 av_packet_unref(pkt);
7957 ret = avpriv_dv_get_packet(mov->dv_demux, pkt);
7962 if (sc->has_palette) {
7965 pal = av_packet_new_side_data(pkt, AV_PKT_DATA_PALETTE, AVPALETTE_SIZE);
7967 av_log(mov->fc, AV_LOG_ERROR, "Cannot append palette to packet\n");
7969 memcpy(pal, sc->palette, AVPALETTE_SIZE);
7970 sc->has_palette = 0;
7973 if (st->codecpar->codec_id == AV_CODEC_ID_MP3 && !st->need_parsing && pkt->size > 4) {
7974 if (ff_mpa_check_header(AV_RB32(pkt->data)) < 0)
7975 st->need_parsing = AVSTREAM_PARSE_FULL;
7979 pkt->stream_index = sc->ffindex;
7980 pkt->dts = sample->timestamp;
7981 if (sample->flags & AVINDEX_DISCARD_FRAME) {
7982 pkt->flags |= AV_PKT_FLAG_DISCARD;
7984 if (sc->ctts_data && sc->ctts_index < sc->ctts_count) {
7985 pkt->pts = pkt->dts + sc->dts_shift + sc->ctts_data[sc->ctts_index].duration;
7986 /* update ctts context */
7988 if (sc->ctts_index < sc->ctts_count &&
7989 sc->ctts_data[sc->ctts_index].count == sc->ctts_sample) {
7991 sc->ctts_sample = 0;
7994 int64_t next_dts = (sc->current_sample < st->internal->nb_index_entries) ?
7995 st->internal->index_entries[sc->current_sample].timestamp : st->duration;
7997 if (next_dts >= pkt->dts)
7998 pkt->duration = next_dts - pkt->dts;
7999 pkt->pts = pkt->dts;
8001 if (st->discard == AVDISCARD_ALL)
8003 if (sc->sdtp_data && sc->current_sample <= sc->sdtp_count) {
8004 uint8_t sample_flags = sc->sdtp_data[sc->current_sample - 1];
8005 uint8_t sample_is_depended_on = (sample_flags >> 2) & 0x3;
8006 pkt->flags |= sample_is_depended_on == MOV_SAMPLE_DEPENDENCY_NO ? AV_PKT_FLAG_DISPOSABLE : 0;
8008 pkt->flags |= sample->flags & AVINDEX_KEYFRAME ? AV_PKT_FLAG_KEY : 0;
8009 pkt->pos = sample->pos;
8011 /* Multiple stsd handling. */
8012 if (sc->stsc_data) {
8013 /* Keep track of the stsc index for the given sample, then check
8014 * if the stsd index is different from the last used one. */
8016 if (mov_stsc_index_valid(sc->stsc_index, sc->stsc_count) &&
8017 mov_get_stsc_samples(sc, sc->stsc_index) == sc->stsc_sample) {
8019 sc->stsc_sample = 0;
8020 /* Do not check indexes after a switch. */
8021 } else if (sc->stsc_data[sc->stsc_index].id > 0 &&
8022 sc->stsc_data[sc->stsc_index].id - 1 < sc->stsd_count &&
8023 sc->stsc_data[sc->stsc_index].id - 1 != sc->last_stsd_index) {
8024 ret = mov_change_extradata(sc, pkt);
8031 aax_filter(pkt->data, pkt->size, mov);
8033 ret = cenc_filter(mov, st, sc, pkt, current_index);
8041 static int mov_seek_fragment(AVFormatContext *s, AVStream *st, int64_t timestamp)
8043 MOVContext *mov = s->priv_data;
8046 if (!mov->frag_index.complete)
8049 index = search_frag_timestamp(&mov->frag_index, st, timestamp);
8052 if (!mov->frag_index.item[index].headers_read)
8053 return mov_switch_root(s, -1, index);
8054 if (index + 1 < mov->frag_index.nb_items)
8055 mov->next_root_atom = mov->frag_index.item[index + 1].moof_offset;
8060 static int mov_seek_stream(AVFormatContext *s, AVStream *st, int64_t timestamp, int flags)
8062 MOVStreamContext *sc = st->priv_data;
8063 int sample, time_sample, ret;
8066 // Here we consider timestamp to be PTS, hence try to offset it so that we
8067 // can search over the DTS timeline.
8068 timestamp -= (sc->min_corrected_pts + sc->dts_shift);
8070 ret = mov_seek_fragment(s, st, timestamp);
8074 sample = av_index_search_timestamp(st, timestamp, flags);
8075 av_log(s, AV_LOG_TRACE, "stream %d, timestamp %"PRId64", sample %d\n", st->index, timestamp, sample);
8076 if (sample < 0 && st->internal->nb_index_entries && timestamp < st->internal->index_entries[0].timestamp)
8078 if (sample < 0) /* not sure what to do */
8079 return AVERROR_INVALIDDATA;
8080 mov_current_sample_set(sc, sample);
8081 av_log(s, AV_LOG_TRACE, "stream %d, found sample %d\n", st->index, sc->current_sample);
8082 /* adjust ctts index */
8083 if (sc->ctts_data) {
8085 for (i = 0; i < sc->ctts_count; i++) {
8086 int next = time_sample + sc->ctts_data[i].count;
8087 if (next > sc->current_sample) {
8089 sc->ctts_sample = sc->current_sample - time_sample;
8096 /* adjust stsd index */
8097 if (sc->chunk_count) {
8099 for (i = 0; i < sc->stsc_count; i++) {
8100 int64_t next = time_sample + mov_get_stsc_samples(sc, i);
8101 if (next > sc->current_sample) {
8103 sc->stsc_sample = sc->current_sample - time_sample;
8106 av_assert0(next == (int)next);
8114 static int64_t mov_get_skip_samples(AVStream *st, int sample)
8116 MOVStreamContext *sc = st->priv_data;
8117 int64_t first_ts = st->internal->index_entries[0].timestamp;
8118 int64_t ts = st->internal->index_entries[sample].timestamp;
8121 if (st->codecpar->codec_type != AVMEDIA_TYPE_AUDIO)
8124 /* compute skip samples according to stream start_pad, seek ts and first ts */
8125 off = av_rescale_q(ts - first_ts, st->time_base,
8126 (AVRational){1, st->codecpar->sample_rate});
8127 return FFMAX(sc->start_pad - off, 0);
8130 static int mov_read_seek(AVFormatContext *s, int stream_index, int64_t sample_time, int flags)
8132 MOVContext *mc = s->priv_data;
8137 if (stream_index >= s->nb_streams)
8138 return AVERROR_INVALIDDATA;
8140 st = s->streams[stream_index];
8141 sample = mov_seek_stream(s, st, sample_time, flags);
8145 if (mc->seek_individually) {
8146 /* adjust seek timestamp to found sample timestamp */
8147 int64_t seek_timestamp = st->internal->index_entries[sample].timestamp;
8148 st->internal->skip_samples = mov_get_skip_samples(st, sample);
8150 for (i = 0; i < s->nb_streams; i++) {
8154 if (stream_index == i)
8157 timestamp = av_rescale_q(seek_timestamp, s->streams[stream_index]->time_base, st->time_base);
8158 sample = mov_seek_stream(s, st, timestamp, flags);
8160 st->internal->skip_samples = mov_get_skip_samples(st, sample);
8163 for (i = 0; i < s->nb_streams; i++) {
8164 MOVStreamContext *sc;
8167 mov_current_sample_set(sc, 0);
8170 MOVStreamContext *sc;
8171 AVIndexEntry *entry = mov_find_next_sample(s, &st);
8173 return AVERROR_INVALIDDATA;
8175 if (sc->ffindex == stream_index && sc->current_sample == sample)
8177 mov_current_sample_inc(sc);
8183 #define OFFSET(x) offsetof(MOVContext, x)
8184 #define FLAGS AV_OPT_FLAG_VIDEO_PARAM | AV_OPT_FLAG_DECODING_PARAM
8185 static const AVOption mov_options[] = {
8186 {"use_absolute_path",
8187 "allow using absolute path when opening alias, this is a possible security issue",
8188 OFFSET(use_absolute_path), AV_OPT_TYPE_BOOL, {.i64 = 0},
8190 {"seek_streams_individually",
8191 "Seek each stream individually to the closest point",
8192 OFFSET(seek_individually), AV_OPT_TYPE_BOOL, { .i64 = 1 },
8194 {"ignore_editlist", "Ignore the edit list atom.", OFFSET(ignore_editlist), AV_OPT_TYPE_BOOL, {.i64 = 0},
8196 {"advanced_editlist",
8197 "Modify the AVIndex according to the editlists. Use this option to decode in the order specified by the edits.",
8198 OFFSET(advanced_editlist), AV_OPT_TYPE_BOOL, {.i64 = 1},
8200 {"ignore_chapters", "", OFFSET(ignore_chapters), AV_OPT_TYPE_BOOL, {.i64 = 0},
8203 "use mfra for fragment timestamps",
8204 OFFSET(use_mfra_for), AV_OPT_TYPE_INT, {.i64 = FF_MOV_FLAG_MFRA_AUTO},
8205 -1, FF_MOV_FLAG_MFRA_PTS, FLAGS,
8207 {"auto", "auto", 0, AV_OPT_TYPE_CONST, {.i64 = FF_MOV_FLAG_MFRA_AUTO}, 0, 0,
8208 FLAGS, "use_mfra_for" },
8209 {"dts", "dts", 0, AV_OPT_TYPE_CONST, {.i64 = FF_MOV_FLAG_MFRA_DTS}, 0, 0,
8210 FLAGS, "use_mfra_for" },
8211 {"pts", "pts", 0, AV_OPT_TYPE_CONST, {.i64 = FF_MOV_FLAG_MFRA_PTS}, 0, 0,
8212 FLAGS, "use_mfra_for" },
8213 { "export_all", "Export unrecognized metadata entries", OFFSET(export_all),
8214 AV_OPT_TYPE_BOOL, { .i64 = 0 }, 0, 1, .flags = FLAGS },
8215 { "export_xmp", "Export full XMP metadata", OFFSET(export_xmp),
8216 AV_OPT_TYPE_BOOL, { .i64 = 0 }, 0, 1, .flags = FLAGS },
8217 { "activation_bytes", "Secret bytes for Audible AAX files", OFFSET(activation_bytes),
8218 AV_OPT_TYPE_BINARY, .flags = AV_OPT_FLAG_DECODING_PARAM },
8219 { "audible_key", "AES-128 Key for Audible AAXC files", OFFSET(audible_key),
8220 AV_OPT_TYPE_BINARY, .flags = AV_OPT_FLAG_DECODING_PARAM },
8221 { "audible_iv", "AES-128 IV for Audible AAXC files", OFFSET(audible_iv),
8222 AV_OPT_TYPE_BINARY, .flags = AV_OPT_FLAG_DECODING_PARAM },
8223 { "audible_fixed_key", // extracted from libAAX_SDK.so and AAXSDKWin.dll files!
8224 "Fixed key used for handling Audible AAX files", OFFSET(audible_fixed_key),
8225 AV_OPT_TYPE_BINARY, {.str="77214d4b196a87cd520045fd20a51d67"},
8226 .flags = AV_OPT_FLAG_DECODING_PARAM },
8227 { "decryption_key", "The media decryption key (hex)", OFFSET(decryption_key), AV_OPT_TYPE_BINARY, .flags = AV_OPT_FLAG_DECODING_PARAM },
8228 { "enable_drefs", "Enable external track support.", OFFSET(enable_drefs), AV_OPT_TYPE_BOOL,
8229 {.i64 = 0}, 0, 1, FLAGS },
8234 static const AVClass mov_class = {
8235 .class_name = "mov,mp4,m4a,3gp,3g2,mj2",
8236 .item_name = av_default_item_name,
8237 .option = mov_options,
8238 .version = LIBAVUTIL_VERSION_INT,
8241 AVInputFormat ff_mov_demuxer = {
8242 .name = "mov,mp4,m4a,3gp,3g2,mj2",
8243 .long_name = NULL_IF_CONFIG_SMALL("QuickTime / MOV"),
8244 .priv_class = &mov_class,
8245 .priv_data_size = sizeof(MOVContext),
8246 .extensions = "mov,mp4,m4a,3gp,3g2,mj2,psp,m4b,ism,ismv,isma,f4v",
8247 .read_probe = mov_probe,
8248 .read_header = mov_read_header,
8249 .read_packet = mov_read_packet,
8250 .read_close = mov_read_close,
8251 .read_seek = mov_read_seek,
8252 .flags = AVFMT_NO_BYTE_SEEK | AVFMT_SEEK_TO_PTS,