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, old_side_data_size;
6369 unsigned int version, kid_count, extra_data_size, alloc_size = 0;
6371 if (c->fc->nb_streams < 1)
6373 st = c->fc->streams[c->fc->nb_streams-1];
6375 version = avio_r8(pb); /* version */
6376 avio_rb24(pb); /* flags */
6378 info = av_encryption_init_info_alloc(/* system_id_size */ 16, /* num_key_ids */ 0,
6379 /* key_id_size */ 16, /* data_size */ 0);
6381 return AVERROR(ENOMEM);
6383 if ((ret = ffio_read_size(pb, info->system_id, 16)) < 0) {
6384 av_log(c->fc, AV_LOG_ERROR, "Failed to read the system id\n");
6389 kid_count = avio_rb32(pb);
6390 if (kid_count >= INT_MAX / sizeof(*key_ids)) {
6391 ret = AVERROR(ENOMEM);
6395 for (unsigned int i = 0; i < kid_count && !pb->eof_reached; i++) {
6396 unsigned int min_kid_count = FFMIN(FFMAX(i + 1, 1024), kid_count);
6397 key_ids = av_fast_realloc(info->key_ids, &alloc_size,
6398 min_kid_count * sizeof(*key_ids));
6400 ret = AVERROR(ENOMEM);
6403 info->key_ids = key_ids;
6405 info->key_ids[i] = av_mallocz(16);
6406 if (!info->key_ids[i]) {
6407 ret = AVERROR(ENOMEM);
6410 info->num_key_ids = i + 1;
6412 if ((ret = ffio_read_size(pb, info->key_ids[i], 16)) < 0) {
6413 av_log(c->fc, AV_LOG_ERROR, "Failed to read the key id\n");
6418 if (pb->eof_reached) {
6419 av_log(c->fc, AV_LOG_ERROR, "Hit EOF while reading pssh\n");
6420 ret = AVERROR_INVALIDDATA;
6425 extra_data_size = avio_rb32(pb);
6426 ret = mov_try_read_block(pb, extra_data_size, &extra_data);
6430 av_freep(&info->data); // malloc(0) may still allocate something.
6431 info->data = extra_data;
6432 info->data_size = extra_data_size;
6434 // If there is existing initialization data, append to the list.
6435 old_side_data = av_stream_get_side_data(st, AV_PKT_DATA_ENCRYPTION_INIT_INFO, &old_side_data_size);
6436 if (old_side_data) {
6437 old_init_info = av_encryption_init_info_get_side_data(old_side_data, old_side_data_size);
6438 if (old_init_info) {
6439 // Append to the end of the list.
6440 for (AVEncryptionInitInfo *cur = old_init_info;; cur = cur->next) {
6446 info = old_init_info;
6448 // Assume existing side-data will be valid, so the only error we could get is OOM.
6449 ret = AVERROR(ENOMEM);
6454 side_data = av_encryption_init_info_add_side_data(info, &side_data_size);
6456 ret = AVERROR(ENOMEM);
6459 ret = av_stream_add_side_data(st, AV_PKT_DATA_ENCRYPTION_INIT_INFO,
6460 side_data, side_data_size);
6465 av_encryption_init_info_free(info);
6469 static int mov_read_schm(MOVContext *c, AVIOContext *pb, MOVAtom atom)
6472 MOVStreamContext *sc;
6474 if (c->fc->nb_streams < 1)
6476 st = c->fc->streams[c->fc->nb_streams-1];
6479 if (sc->pseudo_stream_id != 0) {
6480 av_log(c->fc, AV_LOG_ERROR, "schm boxes are only supported in first sample descriptor\n");
6481 return AVERROR_PATCHWELCOME;
6485 return AVERROR_INVALIDDATA;
6487 avio_rb32(pb); /* version and flags */
6489 if (!sc->cenc.default_encrypted_sample) {
6490 sc->cenc.default_encrypted_sample = av_encryption_info_alloc(0, 16, 16);
6491 if (!sc->cenc.default_encrypted_sample) {
6492 return AVERROR(ENOMEM);
6496 sc->cenc.default_encrypted_sample->scheme = avio_rb32(pb);
6500 static int mov_read_tenc(MOVContext *c, AVIOContext *pb, MOVAtom atom)
6503 MOVStreamContext *sc;
6504 unsigned int version, pattern, is_protected, iv_size;
6506 if (c->fc->nb_streams < 1)
6508 st = c->fc->streams[c->fc->nb_streams-1];
6511 if (sc->pseudo_stream_id != 0) {
6512 av_log(c->fc, AV_LOG_ERROR, "tenc atom are only supported in first sample descriptor\n");
6513 return AVERROR_PATCHWELCOME;
6516 if (!sc->cenc.default_encrypted_sample) {
6517 sc->cenc.default_encrypted_sample = av_encryption_info_alloc(0, 16, 16);
6518 if (!sc->cenc.default_encrypted_sample) {
6519 return AVERROR(ENOMEM);
6524 return AVERROR_INVALIDDATA;
6526 version = avio_r8(pb); /* version */
6527 avio_rb24(pb); /* flags */
6529 avio_r8(pb); /* reserved */
6530 pattern = avio_r8(pb);
6533 sc->cenc.default_encrypted_sample->crypt_byte_block = pattern >> 4;
6534 sc->cenc.default_encrypted_sample->skip_byte_block = pattern & 0xf;
6537 is_protected = avio_r8(pb);
6538 if (is_protected && !sc->cenc.encryption_index) {
6539 // The whole stream should be by-default encrypted.
6540 sc->cenc.encryption_index = av_mallocz(sizeof(MOVEncryptionIndex));
6541 if (!sc->cenc.encryption_index)
6542 return AVERROR(ENOMEM);
6544 sc->cenc.per_sample_iv_size = avio_r8(pb);
6545 if (sc->cenc.per_sample_iv_size != 0 && sc->cenc.per_sample_iv_size != 8 &&
6546 sc->cenc.per_sample_iv_size != 16) {
6547 av_log(c->fc, AV_LOG_ERROR, "invalid per-sample IV size value\n");
6548 return AVERROR_INVALIDDATA;
6550 if (avio_read(pb, sc->cenc.default_encrypted_sample->key_id, 16) != 16) {
6551 av_log(c->fc, AV_LOG_ERROR, "failed to read the default key ID\n");
6552 return AVERROR_INVALIDDATA;
6555 if (is_protected && !sc->cenc.per_sample_iv_size) {
6556 iv_size = avio_r8(pb);
6557 if (iv_size != 8 && iv_size != 16) {
6558 av_log(c->fc, AV_LOG_ERROR, "invalid default_constant_IV_size in tenc atom\n");
6559 return AVERROR_INVALIDDATA;
6562 if (avio_read(pb, sc->cenc.default_encrypted_sample->iv, iv_size) != iv_size) {
6563 av_log(c->fc, AV_LOG_ERROR, "failed to read the default IV\n");
6564 return AVERROR_INVALIDDATA;
6571 static int mov_read_dfla(MOVContext *c, AVIOContext *pb, MOVAtom atom)
6574 int last, type, size, ret;
6577 if (c->fc->nb_streams < 1)
6579 st = c->fc->streams[c->fc->nb_streams-1];
6581 if ((uint64_t)atom.size > (1<<30) || atom.size < 42)
6582 return AVERROR_INVALIDDATA;
6584 /* Check FlacSpecificBox version. */
6585 if (avio_r8(pb) != 0)
6586 return AVERROR_INVALIDDATA;
6588 avio_rb24(pb); /* Flags */
6590 avio_read(pb, buf, sizeof(buf));
6591 flac_parse_block_header(buf, &last, &type, &size);
6593 if (type != FLAC_METADATA_TYPE_STREAMINFO || size != FLAC_STREAMINFO_SIZE) {
6594 av_log(c->fc, AV_LOG_ERROR, "STREAMINFO must be first FLACMetadataBlock\n");
6595 return AVERROR_INVALIDDATA;
6598 ret = ff_get_extradata(c->fc, st->codecpar, pb, size);
6603 av_log(c->fc, AV_LOG_WARNING, "non-STREAMINFO FLACMetadataBlock(s) ignored\n");
6608 static int cenc_decrypt(MOVContext *c, MOVStreamContext *sc, AVEncryptionInfo *sample, uint8_t *input, int size)
6612 if (sample->scheme != MKBETAG('c','e','n','c') || sample->crypt_byte_block != 0 || sample->skip_byte_block != 0) {
6613 av_log(c->fc, AV_LOG_ERROR, "Only the 'cenc' encryption scheme is supported\n");
6614 return AVERROR_PATCHWELCOME;
6617 if (!sc->cenc.aes_ctr) {
6618 /* initialize the cipher */
6619 sc->cenc.aes_ctr = av_aes_ctr_alloc();
6620 if (!sc->cenc.aes_ctr) {
6621 return AVERROR(ENOMEM);
6624 ret = av_aes_ctr_init(sc->cenc.aes_ctr, c->decryption_key);
6630 av_aes_ctr_set_full_iv(sc->cenc.aes_ctr, sample->iv);
6632 if (!sample->subsample_count) {
6633 /* decrypt the whole packet */
6634 av_aes_ctr_crypt(sc->cenc.aes_ctr, input, input, size);
6638 for (i = 0; i < sample->subsample_count; i++) {
6639 if (sample->subsamples[i].bytes_of_clear_data + sample->subsamples[i].bytes_of_protected_data > size) {
6640 av_log(c->fc, AV_LOG_ERROR, "subsample size exceeds the packet size left\n");
6641 return AVERROR_INVALIDDATA;
6644 /* skip the clear bytes */
6645 input += sample->subsamples[i].bytes_of_clear_data;
6646 size -= sample->subsamples[i].bytes_of_clear_data;
6648 /* decrypt the encrypted bytes */
6649 av_aes_ctr_crypt(sc->cenc.aes_ctr, input, input, sample->subsamples[i].bytes_of_protected_data);
6650 input += sample->subsamples[i].bytes_of_protected_data;
6651 size -= sample->subsamples[i].bytes_of_protected_data;
6655 av_log(c->fc, AV_LOG_ERROR, "leftover packet bytes after subsample processing\n");
6656 return AVERROR_INVALIDDATA;
6662 static int cenc_filter(MOVContext *mov, AVStream* st, MOVStreamContext *sc, AVPacket *pkt, int current_index)
6664 MOVFragmentStreamInfo *frag_stream_info;
6665 MOVEncryptionIndex *encryption_index;
6666 AVEncryptionInfo *encrypted_sample;
6667 int encrypted_index, ret;
6669 frag_stream_info = get_frag_stream_info(&mov->frag_index, mov->frag_index.current, st->id);
6670 encrypted_index = current_index;
6671 encryption_index = NULL;
6672 if (frag_stream_info) {
6673 // Note this only supports encryption info in the first sample descriptor.
6674 if (mov->fragment.stsd_id == 1) {
6675 if (frag_stream_info->encryption_index) {
6676 encrypted_index = current_index - frag_stream_info->index_entry;
6677 encryption_index = frag_stream_info->encryption_index;
6679 encryption_index = sc->cenc.encryption_index;
6683 encryption_index = sc->cenc.encryption_index;
6686 if (encryption_index) {
6687 if (encryption_index->auxiliary_info_sample_count &&
6688 !encryption_index->nb_encrypted_samples) {
6689 av_log(mov->fc, AV_LOG_ERROR, "saiz atom found without saio\n");
6690 return AVERROR_INVALIDDATA;
6692 if (encryption_index->auxiliary_offsets_count &&
6693 !encryption_index->nb_encrypted_samples) {
6694 av_log(mov->fc, AV_LOG_ERROR, "saio atom found without saiz\n");
6695 return AVERROR_INVALIDDATA;
6698 if (!encryption_index->nb_encrypted_samples) {
6699 // Full-sample encryption with default settings.
6700 encrypted_sample = sc->cenc.default_encrypted_sample;
6701 } else if (encrypted_index >= 0 && encrypted_index < encryption_index->nb_encrypted_samples) {
6702 // Per-sample setting override.
6703 encrypted_sample = encryption_index->encrypted_samples[encrypted_index];
6705 av_log(mov->fc, AV_LOG_ERROR, "Incorrect number of samples in encryption info\n");
6706 return AVERROR_INVALIDDATA;
6709 if (mov->decryption_key) {
6710 return cenc_decrypt(mov, sc, encrypted_sample, pkt->data, pkt->size);
6713 uint8_t *side_data = av_encryption_info_add_side_data(encrypted_sample, &size);
6715 return AVERROR(ENOMEM);
6716 ret = av_packet_add_side_data(pkt, AV_PKT_DATA_ENCRYPTION_INFO, side_data, size);
6726 static int mov_read_dops(MOVContext *c, AVIOContext *pb, MOVAtom atom)
6728 const int OPUS_SEEK_PREROLL_MS = 80;
6734 if (c->fc->nb_streams < 1)
6736 st = c->fc->streams[c->fc->nb_streams-1];
6738 if ((uint64_t)atom.size > (1<<30) || atom.size < 11)
6739 return AVERROR_INVALIDDATA;
6741 /* Check OpusSpecificBox version. */
6742 if (avio_r8(pb) != 0) {
6743 av_log(c->fc, AV_LOG_ERROR, "unsupported OpusSpecificBox version\n");
6744 return AVERROR_INVALIDDATA;
6747 /* OpusSpecificBox size plus magic for Ogg OpusHead header. */
6748 size = atom.size + 8;
6750 if ((ret = ff_alloc_extradata(st->codecpar, size)) < 0)
6753 AV_WL32(st->codecpar->extradata, MKTAG('O','p','u','s'));
6754 AV_WL32(st->codecpar->extradata + 4, MKTAG('H','e','a','d'));
6755 AV_WB8(st->codecpar->extradata + 8, 1); /* OpusHead version */
6756 avio_read(pb, st->codecpar->extradata + 9, size - 9);
6758 /* OpusSpecificBox is stored in big-endian, but OpusHead is
6759 little-endian; aside from the preceeding magic and version they're
6760 otherwise currently identical. Data after output gain at offset 16
6761 doesn't need to be bytewapped. */
6762 pre_skip = AV_RB16(st->codecpar->extradata + 10);
6763 AV_WL16(st->codecpar->extradata + 10, pre_skip);
6764 AV_WL32(st->codecpar->extradata + 12, AV_RB32(st->codecpar->extradata + 12));
6765 AV_WL16(st->codecpar->extradata + 16, AV_RB16(st->codecpar->extradata + 16));
6767 st->codecpar->initial_padding = pre_skip;
6768 st->codecpar->seek_preroll = av_rescale_q(OPUS_SEEK_PREROLL_MS,
6769 (AVRational){1, 1000},
6770 (AVRational){1, 48000});
6775 static int mov_read_dmlp(MOVContext *c, AVIOContext *pb, MOVAtom atom)
6778 unsigned format_info;
6779 int channel_assignment, channel_assignment1, channel_assignment2;
6782 if (c->fc->nb_streams < 1)
6784 st = c->fc->streams[c->fc->nb_streams-1];
6787 return AVERROR_INVALIDDATA;
6789 format_info = avio_rb32(pb);
6791 ratebits = (format_info >> 28) & 0xF;
6792 channel_assignment1 = (format_info >> 15) & 0x1F;
6793 channel_assignment2 = format_info & 0x1FFF;
6794 if (channel_assignment2)
6795 channel_assignment = channel_assignment2;
6797 channel_assignment = channel_assignment1;
6799 st->codecpar->frame_size = 40 << (ratebits & 0x7);
6800 st->codecpar->sample_rate = mlp_samplerate(ratebits);
6801 st->codecpar->channels = truehd_channels(channel_assignment);
6802 st->codecpar->channel_layout = truehd_layout(channel_assignment);
6807 static int mov_read_dvcc_dvvc(MOVContext *c, AVIOContext *pb, MOVAtom atom)
6811 AVDOVIDecoderConfigurationRecord *dovi;
6815 if (c->fc->nb_streams < 1)
6817 st = c->fc->streams[c->fc->nb_streams-1];
6819 if ((uint64_t)atom.size > (1<<30) || atom.size < 4)
6820 return AVERROR_INVALIDDATA;
6822 dovi = av_dovi_alloc(&dovi_size);
6824 return AVERROR(ENOMEM);
6826 dovi->dv_version_major = avio_r8(pb);
6827 dovi->dv_version_minor = avio_r8(pb);
6829 buf = avio_rb16(pb);
6830 dovi->dv_profile = (buf >> 9) & 0x7f; // 7 bits
6831 dovi->dv_level = (buf >> 3) & 0x3f; // 6 bits
6832 dovi->rpu_present_flag = (buf >> 2) & 0x01; // 1 bit
6833 dovi->el_present_flag = (buf >> 1) & 0x01; // 1 bit
6834 dovi->bl_present_flag = buf & 0x01; // 1 bit
6835 if (atom.size >= 24) { // 4 + 4 + 4 * 4
6837 dovi->dv_bl_signal_compatibility_id = (buf >> 4) & 0x0f; // 4 bits
6839 // 0 stands for None
6840 // Dolby Vision V1.2.93 profiles and levels
6841 dovi->dv_bl_signal_compatibility_id = 0;
6844 ret = av_stream_add_side_data(st, AV_PKT_DATA_DOVI_CONF,
6845 (uint8_t *)dovi, dovi_size);
6851 av_log(c, AV_LOG_TRACE, "DOVI in dvcC/dvvC box, version: %d.%d, profile: %d, level: %d, "
6852 "rpu flag: %d, el flag: %d, bl flag: %d, compatibility id: %d\n",
6853 dovi->dv_version_major, dovi->dv_version_minor,
6854 dovi->dv_profile, dovi->dv_level,
6855 dovi->rpu_present_flag,
6856 dovi->el_present_flag,
6857 dovi->bl_present_flag,
6858 dovi->dv_bl_signal_compatibility_id
6864 static const MOVParseTableEntry mov_default_parse_table[] = {
6865 { MKTAG('A','C','L','R'), mov_read_aclr },
6866 { MKTAG('A','P','R','G'), mov_read_avid },
6867 { MKTAG('A','A','L','P'), mov_read_avid },
6868 { MKTAG('A','R','E','S'), mov_read_ares },
6869 { MKTAG('a','v','s','s'), mov_read_avss },
6870 { MKTAG('a','v','1','C'), mov_read_av1c },
6871 { MKTAG('c','h','p','l'), mov_read_chpl },
6872 { MKTAG('c','o','6','4'), mov_read_stco },
6873 { MKTAG('c','o','l','r'), mov_read_colr },
6874 { MKTAG('c','t','t','s'), mov_read_ctts }, /* composition time to sample */
6875 { MKTAG('d','i','n','f'), mov_read_default },
6876 { MKTAG('D','p','x','E'), mov_read_dpxe },
6877 { MKTAG('d','r','e','f'), mov_read_dref },
6878 { MKTAG('e','d','t','s'), mov_read_default },
6879 { MKTAG('e','l','s','t'), mov_read_elst },
6880 { MKTAG('e','n','d','a'), mov_read_enda },
6881 { MKTAG('f','i','e','l'), mov_read_fiel },
6882 { MKTAG('a','d','r','m'), mov_read_adrm },
6883 { MKTAG('f','t','y','p'), mov_read_ftyp },
6884 { MKTAG('g','l','b','l'), mov_read_glbl },
6885 { MKTAG('h','d','l','r'), mov_read_hdlr },
6886 { MKTAG('i','l','s','t'), mov_read_ilst },
6887 { MKTAG('j','p','2','h'), mov_read_jp2h },
6888 { MKTAG('m','d','a','t'), mov_read_mdat },
6889 { MKTAG('m','d','h','d'), mov_read_mdhd },
6890 { MKTAG('m','d','i','a'), mov_read_default },
6891 { MKTAG('m','e','t','a'), mov_read_meta },
6892 { MKTAG('m','i','n','f'), mov_read_default },
6893 { MKTAG('m','o','o','f'), mov_read_moof },
6894 { MKTAG('m','o','o','v'), mov_read_moov },
6895 { MKTAG('m','v','e','x'), mov_read_default },
6896 { MKTAG('m','v','h','d'), mov_read_mvhd },
6897 { MKTAG('S','M','I',' '), mov_read_svq3 },
6898 { MKTAG('a','l','a','c'), mov_read_alac }, /* alac specific atom */
6899 { MKTAG('a','v','c','C'), mov_read_glbl },
6900 { MKTAG('p','a','s','p'), mov_read_pasp },
6901 { MKTAG('s','i','d','x'), mov_read_sidx },
6902 { MKTAG('s','t','b','l'), mov_read_default },
6903 { MKTAG('s','t','c','o'), mov_read_stco },
6904 { MKTAG('s','t','p','s'), mov_read_stps },
6905 { MKTAG('s','t','r','f'), mov_read_strf },
6906 { MKTAG('s','t','s','c'), mov_read_stsc },
6907 { MKTAG('s','t','s','d'), mov_read_stsd }, /* sample description */
6908 { MKTAG('s','t','s','s'), mov_read_stss }, /* sync sample */
6909 { MKTAG('s','t','s','z'), mov_read_stsz }, /* sample size */
6910 { MKTAG('s','t','t','s'), mov_read_stts },
6911 { MKTAG('s','t','z','2'), mov_read_stsz }, /* compact sample size */
6912 { MKTAG('s','d','t','p'), mov_read_sdtp }, /* independent and disposable samples */
6913 { MKTAG('t','k','h','d'), mov_read_tkhd }, /* track header */
6914 { MKTAG('t','f','d','t'), mov_read_tfdt },
6915 { MKTAG('t','f','h','d'), mov_read_tfhd }, /* track fragment header */
6916 { MKTAG('t','r','a','k'), mov_read_trak },
6917 { MKTAG('t','r','a','f'), mov_read_default },
6918 { MKTAG('t','r','e','f'), mov_read_default },
6919 { MKTAG('t','m','c','d'), mov_read_tmcd },
6920 { MKTAG('c','h','a','p'), mov_read_chap },
6921 { MKTAG('t','r','e','x'), mov_read_trex },
6922 { MKTAG('t','r','u','n'), mov_read_trun },
6923 { MKTAG('u','d','t','a'), mov_read_default },
6924 { MKTAG('w','a','v','e'), mov_read_wave },
6925 { MKTAG('e','s','d','s'), mov_read_esds },
6926 { MKTAG('d','a','c','3'), mov_read_dac3 }, /* AC-3 info */
6927 { MKTAG('d','e','c','3'), mov_read_dec3 }, /* EAC-3 info */
6928 { MKTAG('d','d','t','s'), mov_read_ddts }, /* DTS audio descriptor */
6929 { MKTAG('w','i','d','e'), mov_read_wide }, /* place holder */
6930 { MKTAG('w','f','e','x'), mov_read_wfex },
6931 { MKTAG('c','m','o','v'), mov_read_cmov },
6932 { MKTAG('c','h','a','n'), mov_read_chan }, /* channel layout */
6933 { MKTAG('d','v','c','1'), mov_read_dvc1 },
6934 { MKTAG('s','b','g','p'), mov_read_sbgp },
6935 { MKTAG('h','v','c','C'), mov_read_glbl },
6936 { MKTAG('u','u','i','d'), mov_read_uuid },
6937 { MKTAG('C','i','n', 0x8e), mov_read_targa_y216 },
6938 { MKTAG('f','r','e','e'), mov_read_free },
6939 { MKTAG('-','-','-','-'), mov_read_custom },
6940 { MKTAG('s','i','n','f'), mov_read_default },
6941 { MKTAG('f','r','m','a'), mov_read_frma },
6942 { MKTAG('s','e','n','c'), mov_read_senc },
6943 { MKTAG('s','a','i','z'), mov_read_saiz },
6944 { MKTAG('s','a','i','o'), mov_read_saio },
6945 { MKTAG('p','s','s','h'), mov_read_pssh },
6946 { MKTAG('s','c','h','m'), mov_read_schm },
6947 { MKTAG('s','c','h','i'), mov_read_default },
6948 { MKTAG('t','e','n','c'), mov_read_tenc },
6949 { MKTAG('d','f','L','a'), mov_read_dfla },
6950 { MKTAG('s','t','3','d'), mov_read_st3d }, /* stereoscopic 3D video box */
6951 { MKTAG('s','v','3','d'), mov_read_sv3d }, /* spherical video box */
6952 { MKTAG('d','O','p','s'), mov_read_dops },
6953 { MKTAG('d','m','l','p'), mov_read_dmlp },
6954 { MKTAG('S','m','D','m'), mov_read_smdm },
6955 { MKTAG('C','o','L','L'), mov_read_coll },
6956 { MKTAG('v','p','c','C'), mov_read_vpcc },
6957 { MKTAG('m','d','c','v'), mov_read_mdcv },
6958 { MKTAG('c','l','l','i'), mov_read_clli },
6959 { MKTAG('d','v','c','C'), mov_read_dvcc_dvvc },
6960 { MKTAG('d','v','v','C'), mov_read_dvcc_dvvc },
6964 static int mov_read_default(MOVContext *c, AVIOContext *pb, MOVAtom atom)
6966 int64_t total_size = 0;
6970 if (c->atom_depth > 10) {
6971 av_log(c->fc, AV_LOG_ERROR, "Atoms too deeply nested\n");
6972 return AVERROR_INVALIDDATA;
6977 atom.size = INT64_MAX;
6978 while (total_size <= atom.size - 8 && !avio_feof(pb)) {
6979 int (*parse)(MOVContext*, AVIOContext*, MOVAtom) = NULL;
6982 if (atom.size >= 8) {
6983 a.size = avio_rb32(pb);
6984 a.type = avio_rl32(pb);
6985 if (((a.type == MKTAG('f','r','e','e') && c->moov_retry) ||
6986 a.type == MKTAG('h','o','o','v')) &&
6988 c->fc->strict_std_compliance < FF_COMPLIANCE_STRICT) {
6991 type = avio_rl32(pb);
6994 avio_seek(pb, -8, SEEK_CUR);
6995 if (type == MKTAG('m','v','h','d') ||
6996 type == MKTAG('c','m','o','v')) {
6997 av_log(c->fc, AV_LOG_ERROR, "Detected moov in a free or hoov atom.\n");
6998 a.type = MKTAG('m','o','o','v');
7001 if (atom.type != MKTAG('r','o','o','t') &&
7002 atom.type != MKTAG('m','o','o','v')) {
7003 if (a.type == MKTAG('t','r','a','k') ||
7004 a.type == MKTAG('m','d','a','t')) {
7005 av_log(c->fc, AV_LOG_ERROR, "Broken file, trak/mdat not at top-level\n");
7012 if (a.size == 1 && total_size + 8 <= atom.size) { /* 64 bit extended size */
7013 a.size = avio_rb64(pb) - 8;
7017 av_log(c->fc, AV_LOG_TRACE, "type:'%s' parent:'%s' sz: %"PRId64" %"PRId64" %"PRId64"\n",
7018 av_fourcc2str(a.type), av_fourcc2str(atom.type), a.size, total_size, atom.size);
7020 a.size = atom.size - total_size + 8;
7025 a.size = FFMIN(a.size, atom.size - total_size);
7027 for (i = 0; mov_default_parse_table[i].type; i++)
7028 if (mov_default_parse_table[i].type == a.type) {
7029 parse = mov_default_parse_table[i].parse;
7033 // container is user data
7034 if (!parse && (atom.type == MKTAG('u','d','t','a') ||
7035 atom.type == MKTAG('i','l','s','t')))
7036 parse = mov_read_udta_string;
7038 // Supports parsing the QuickTime Metadata Keys.
7039 // https://developer.apple.com/library/mac/documentation/QuickTime/QTFF/Metadata/Metadata.html
7040 if (!parse && c->found_hdlr_mdta &&
7041 atom.type == MKTAG('m','e','t','a') &&
7042 a.type == MKTAG('k','e','y','s') &&
7043 c->meta_keys_count == 0) {
7044 parse = mov_read_keys;
7047 if (!parse) { /* skip leaf atoms data */
7048 avio_skip(pb, a.size);
7050 int64_t start_pos = avio_tell(pb);
7052 int err = parse(c, pb, a);
7057 if (c->found_moov && c->found_mdat && a.size <= INT64_MAX - start_pos &&
7058 ((!(pb->seekable & AVIO_SEEKABLE_NORMAL) || c->fc->flags & AVFMT_FLAG_IGNIDX || c->frag_index.complete) ||
7059 start_pos + a.size == avio_size(pb))) {
7060 if (!(pb->seekable & AVIO_SEEKABLE_NORMAL) || c->fc->flags & AVFMT_FLAG_IGNIDX || c->frag_index.complete)
7061 c->next_root_atom = start_pos + a.size;
7065 left = a.size - avio_tell(pb) + start_pos;
7066 if (left > 0) /* skip garbage at atom end */
7067 avio_skip(pb, left);
7068 else if (left < 0) {
7069 av_log(c->fc, AV_LOG_WARNING,
7070 "overread end of atom '%s' by %"PRId64" bytes\n",
7071 av_fourcc2str(a.type), -left);
7072 avio_seek(pb, left, SEEK_CUR);
7076 total_size += a.size;
7079 if (total_size < atom.size && atom.size < 0x7ffff)
7080 avio_skip(pb, atom.size - total_size);
7086 static int mov_probe(const AVProbeData *p)
7091 int moov_offset = -1;
7093 /* check file header */
7098 /* ignore invalid offset */
7099 if ((offset + 8ULL) > (unsigned int)p->buf_size)
7101 size = AV_RB32(p->buf + offset);
7102 if (size == 1 && offset + 16 <= (unsigned int)p->buf_size) {
7103 size = AV_RB64(p->buf+offset + 8);
7105 } else if (size == 0) {
7106 size = p->buf_size - offset;
7108 if (size < minsize) {
7112 tag = AV_RL32(p->buf + offset + 4);
7114 /* check for obvious tags */
7115 case MKTAG('m','o','o','v'):
7116 moov_offset = offset + 4;
7117 case MKTAG('m','d','a','t'):
7118 case MKTAG('p','n','o','t'): /* detect movs with preview pics like ew.mov and april.mov */
7119 case MKTAG('u','d','t','a'): /* Packet Video PVAuthor adds this and a lot of more junk */
7120 case MKTAG('f','t','y','p'):
7121 if (tag == MKTAG('f','t','y','p') &&
7122 ( AV_RL32(p->buf + offset + 8) == MKTAG('j','p','2',' ')
7123 || AV_RL32(p->buf + offset + 8) == MKTAG('j','p','x',' ')
7125 score = FFMAX(score, 5);
7127 score = AVPROBE_SCORE_MAX;
7130 /* those are more common words, so rate then a bit less */
7131 case MKTAG('e','d','i','w'): /* xdcam files have reverted first tags */
7132 case MKTAG('w','i','d','e'):
7133 case MKTAG('f','r','e','e'):
7134 case MKTAG('j','u','n','k'):
7135 case MKTAG('p','i','c','t'):
7136 score = FFMAX(score, AVPROBE_SCORE_MAX - 5);
7138 case MKTAG(0x82,0x82,0x7f,0x7d):
7139 case MKTAG('s','k','i','p'):
7140 case MKTAG('u','u','i','d'):
7141 case MKTAG('p','r','f','l'):
7142 /* if we only find those cause probedata is too small at least rate them */
7143 score = FFMAX(score, AVPROBE_SCORE_EXTENSION);
7146 if (size > INT64_MAX - offset)
7150 if (score > AVPROBE_SCORE_MAX - 50 && moov_offset != -1) {
7151 /* moov atom in the header - we should make sure that this is not a
7152 * MOV-packed MPEG-PS */
7153 offset = moov_offset;
7155 while (offset < (p->buf_size - 16)) { /* Sufficient space */
7156 /* We found an actual hdlr atom */
7157 if (AV_RL32(p->buf + offset ) == MKTAG('h','d','l','r') &&
7158 AV_RL32(p->buf + offset + 8) == MKTAG('m','h','l','r') &&
7159 AV_RL32(p->buf + offset + 12) == MKTAG('M','P','E','G')) {
7160 av_log(NULL, AV_LOG_WARNING, "Found media data tag MPEG indicating this is a MOV-packed MPEG-PS.\n");
7161 /* We found a media handler reference atom describing an
7162 * MPEG-PS-in-MOV, return a
7163 * low score to force expanding the probe window until
7164 * mpegps_probe finds what it needs */
7176 // must be done after parsing all trak because there's no order requirement
7177 static void mov_read_chapters(AVFormatContext *s)
7179 MOVContext *mov = s->priv_data;
7181 MOVStreamContext *sc;
7186 for (j = 0; j < mov->nb_chapter_tracks; j++) {
7187 chapter_track = mov->chapter_tracks[j];
7189 for (i = 0; i < s->nb_streams; i++)
7190 if (s->streams[i]->id == chapter_track) {
7195 av_log(s, AV_LOG_ERROR, "Referenced QT chapter track not found\n");
7200 cur_pos = avio_tell(sc->pb);
7202 if (st->codecpar->codec_type == AVMEDIA_TYPE_VIDEO) {
7203 st->disposition |= AV_DISPOSITION_ATTACHED_PIC | AV_DISPOSITION_TIMED_THUMBNAILS;
7204 if (st->internal->nb_index_entries) {
7205 // Retrieve the first frame, if possible
7206 AVIndexEntry *sample = &st->internal->index_entries[0];
7207 if (avio_seek(sc->pb, sample->pos, SEEK_SET) != sample->pos) {
7208 av_log(s, AV_LOG_ERROR, "Failed to retrieve first frame\n");
7212 if (ff_add_attached_pic(s, st, sc->pb, NULL, sample->size) < 0)
7216 st->codecpar->codec_type = AVMEDIA_TYPE_DATA;
7217 st->codecpar->codec_id = AV_CODEC_ID_BIN_DATA;
7218 st->discard = AVDISCARD_ALL;
7219 for (i = 0; i < st->internal->nb_index_entries; i++) {
7220 AVIndexEntry *sample = &st->internal->index_entries[i];
7221 int64_t end = i+1 < st->internal->nb_index_entries ? st->internal->index_entries[i+1].timestamp : st->duration;
7226 if (end < sample->timestamp) {
7227 av_log(s, AV_LOG_WARNING, "ignoring stream duration which is shorter than chapters\n");
7228 end = AV_NOPTS_VALUE;
7231 if (avio_seek(sc->pb, sample->pos, SEEK_SET) != sample->pos) {
7232 av_log(s, AV_LOG_ERROR, "Chapter %d not found in file\n", i);
7236 // the first two bytes are the length of the title
7237 len = avio_rb16(sc->pb);
7238 if (len > sample->size-2)
7240 title_len = 2*len + 1;
7241 if (!(title = av_mallocz(title_len)))
7244 // The samples could theoretically be in any encoding if there's an encd
7245 // atom following, but in practice are only utf-8 or utf-16, distinguished
7246 // instead by the presence of a BOM
7250 ch = avio_rb16(sc->pb);
7252 avio_get_str16be(sc->pb, len, title, title_len);
7253 else if (ch == 0xfffe)
7254 avio_get_str16le(sc->pb, len, title, title_len);
7257 if (len == 1 || len == 2)
7260 avio_get_str(sc->pb, INT_MAX, title + 2, len - 1);
7264 avpriv_new_chapter(s, i, st->time_base, sample->timestamp, end, title);
7269 avio_seek(sc->pb, cur_pos, SEEK_SET);
7273 static int parse_timecode_in_framenum_format(AVFormatContext *s, AVStream *st,
7274 uint32_t value, int flags)
7277 char buf[AV_TIMECODE_STR_SIZE];
7278 AVRational rate = st->avg_frame_rate;
7279 int ret = av_timecode_init(&tc, rate, flags, 0, s);
7282 av_dict_set(&st->metadata, "timecode",
7283 av_timecode_make_string(&tc, buf, value), 0);
7287 static int mov_read_rtmd_track(AVFormatContext *s, AVStream *st)
7289 MOVStreamContext *sc = st->priv_data;
7290 char buf[AV_TIMECODE_STR_SIZE];
7291 int64_t cur_pos = avio_tell(sc->pb);
7292 int hh, mm, ss, ff, drop;
7294 if (!st->internal->nb_index_entries)
7297 avio_seek(sc->pb, st->internal->index_entries->pos, SEEK_SET);
7298 avio_skip(s->pb, 13);
7299 hh = avio_r8(s->pb);
7300 mm = avio_r8(s->pb);
7301 ss = avio_r8(s->pb);
7302 drop = avio_r8(s->pb);
7303 ff = avio_r8(s->pb);
7304 snprintf(buf, AV_TIMECODE_STR_SIZE, "%02d:%02d:%02d%c%02d",
7305 hh, mm, ss, drop ? ';' : ':', ff);
7306 av_dict_set(&st->metadata, "timecode", buf, 0);
7308 avio_seek(sc->pb, cur_pos, SEEK_SET);
7312 static int mov_read_timecode_track(AVFormatContext *s, AVStream *st)
7314 MOVStreamContext *sc = st->priv_data;
7316 int64_t cur_pos = avio_tell(sc->pb);
7319 if (!st->internal->nb_index_entries)
7322 avio_seek(sc->pb, st->internal->index_entries->pos, SEEK_SET);
7323 value = avio_rb32(s->pb);
7325 if (sc->tmcd_flags & 0x0001) flags |= AV_TIMECODE_FLAG_DROPFRAME;
7326 if (sc->tmcd_flags & 0x0002) flags |= AV_TIMECODE_FLAG_24HOURSMAX;
7327 if (sc->tmcd_flags & 0x0004) flags |= AV_TIMECODE_FLAG_ALLOWNEGATIVE;
7329 /* Assume Counter flag is set to 1 in tmcd track (even though it is likely
7330 * not the case) and thus assume "frame number format" instead of QT one.
7331 * No sample with tmcd track can be found with a QT timecode at the moment,
7332 * despite what the tmcd track "suggests" (Counter flag set to 0 means QT
7334 parse_timecode_in_framenum_format(s, st, value, flags);
7336 avio_seek(sc->pb, cur_pos, SEEK_SET);
7340 static void mov_free_encryption_index(MOVEncryptionIndex **index) {
7342 if (!index || !*index) return;
7343 for (i = 0; i < (*index)->nb_encrypted_samples; i++) {
7344 av_encryption_info_free((*index)->encrypted_samples[i]);
7346 av_freep(&(*index)->encrypted_samples);
7347 av_freep(&(*index)->auxiliary_info_sizes);
7348 av_freep(&(*index)->auxiliary_offsets);
7352 static int mov_read_close(AVFormatContext *s)
7354 MOVContext *mov = s->priv_data;
7357 for (i = 0; i < s->nb_streams; i++) {
7358 AVStream *st = s->streams[i];
7359 MOVStreamContext *sc = st->priv_data;
7364 av_freep(&sc->ctts_data);
7365 for (j = 0; j < sc->drefs_count; j++) {
7366 av_freep(&sc->drefs[j].path);
7367 av_freep(&sc->drefs[j].dir);
7369 av_freep(&sc->drefs);
7371 sc->drefs_count = 0;
7373 if (!sc->pb_is_copied)
7374 ff_format_io_close(s, &sc->pb);
7377 av_freep(&sc->chunk_offsets);
7378 av_freep(&sc->stsc_data);
7379 av_freep(&sc->sample_sizes);
7380 av_freep(&sc->keyframes);
7381 av_freep(&sc->stts_data);
7382 av_freep(&sc->sdtp_data);
7383 av_freep(&sc->stps_data);
7384 av_freep(&sc->elst_data);
7385 av_freep(&sc->rap_group);
7386 av_freep(&sc->display_matrix);
7387 av_freep(&sc->index_ranges);
7390 for (j = 0; j < sc->stsd_count; j++)
7391 av_free(sc->extradata[j]);
7392 av_freep(&sc->extradata);
7393 av_freep(&sc->extradata_size);
7395 mov_free_encryption_index(&sc->cenc.encryption_index);
7396 av_encryption_info_free(sc->cenc.default_encrypted_sample);
7397 av_aes_ctr_free(sc->cenc.aes_ctr);
7399 av_freep(&sc->stereo3d);
7400 av_freep(&sc->spherical);
7401 av_freep(&sc->mastering);
7402 av_freep(&sc->coll);
7405 av_freep(&mov->dv_demux);
7406 avformat_free_context(mov->dv_fctx);
7407 mov->dv_fctx = NULL;
7409 if (mov->meta_keys) {
7410 for (i = 1; i < mov->meta_keys_count; i++) {
7411 av_freep(&mov->meta_keys[i]);
7413 av_freep(&mov->meta_keys);
7416 av_freep(&mov->trex_data);
7417 av_freep(&mov->bitrates);
7419 for (i = 0; i < mov->frag_index.nb_items; i++) {
7420 MOVFragmentStreamInfo *frag = mov->frag_index.item[i].stream_info;
7421 for (j = 0; j < mov->frag_index.item[i].nb_stream_info; j++) {
7422 mov_free_encryption_index(&frag[j].encryption_index);
7424 av_freep(&mov->frag_index.item[i].stream_info);
7426 av_freep(&mov->frag_index.item);
7428 av_freep(&mov->aes_decrypt);
7429 av_freep(&mov->chapter_tracks);
7434 static int tmcd_is_referenced(AVFormatContext *s, int tmcd_id)
7438 for (i = 0; i < s->nb_streams; i++) {
7439 AVStream *st = s->streams[i];
7440 MOVStreamContext *sc = st->priv_data;
7442 if (st->codecpar->codec_type == AVMEDIA_TYPE_VIDEO &&
7443 sc->timecode_track == tmcd_id)
7449 /* look for a tmcd track not referenced by any video track, and export it globally */
7450 static void export_orphan_timecode(AVFormatContext *s)
7454 for (i = 0; i < s->nb_streams; i++) {
7455 AVStream *st = s->streams[i];
7457 if (st->codecpar->codec_tag == MKTAG('t','m','c','d') &&
7458 !tmcd_is_referenced(s, i + 1)) {
7459 AVDictionaryEntry *tcr = av_dict_get(st->metadata, "timecode", NULL, 0);
7461 av_dict_set(&s->metadata, "timecode", tcr->value, 0);
7468 static int read_tfra(MOVContext *mov, AVIOContext *f)
7470 int version, fieldlength, i, j;
7471 int64_t pos = avio_tell(f);
7472 uint32_t size = avio_rb32(f);
7473 unsigned track_id, item_count;
7475 if (avio_rb32(f) != MKBETAG('t', 'f', 'r', 'a')) {
7478 av_log(mov->fc, AV_LOG_VERBOSE, "found tfra\n");
7480 version = avio_r8(f);
7482 track_id = avio_rb32(f);
7483 fieldlength = avio_rb32(f);
7484 item_count = avio_rb32(f);
7485 for (i = 0; i < item_count; i++) {
7486 int64_t time, offset;
7488 MOVFragmentStreamInfo * frag_stream_info;
7491 return AVERROR_INVALIDDATA;
7495 time = avio_rb64(f);
7496 offset = avio_rb64(f);
7498 time = avio_rb32(f);
7499 offset = avio_rb32(f);
7502 // The first sample of each stream in a fragment is always a random
7503 // access sample. So it's entry in the tfra can be used as the
7504 // initial PTS of the fragment.
7505 index = update_frag_index(mov, offset);
7506 frag_stream_info = get_frag_stream_info(&mov->frag_index, index, track_id);
7507 if (frag_stream_info &&
7508 frag_stream_info->first_tfra_pts == AV_NOPTS_VALUE)
7509 frag_stream_info->first_tfra_pts = time;
7511 for (j = 0; j < ((fieldlength >> 4) & 3) + 1; j++)
7513 for (j = 0; j < ((fieldlength >> 2) & 3) + 1; j++)
7515 for (j = 0; j < ((fieldlength >> 0) & 3) + 1; j++)
7519 avio_seek(f, pos + size, SEEK_SET);
7523 static int mov_read_mfra(MOVContext *c, AVIOContext *f)
7525 int64_t stream_size = avio_size(f);
7526 int64_t original_pos = avio_tell(f);
7529 if ((seek_ret = avio_seek(f, stream_size - 4, SEEK_SET)) < 0) {
7533 c->mfra_size = avio_rb32(f);
7534 c->have_read_mfra_size = 1;
7535 if (!c->mfra_size || c->mfra_size > stream_size) {
7536 av_log(c->fc, AV_LOG_DEBUG, "doesn't look like mfra (unreasonable size)\n");
7539 if ((seek_ret = avio_seek(f, -((int64_t) c->mfra_size), SEEK_CUR)) < 0) {
7543 if (avio_rb32(f) != c->mfra_size) {
7544 av_log(c->fc, AV_LOG_DEBUG, "doesn't look like mfra (size mismatch)\n");
7547 if (avio_rb32(f) != MKBETAG('m', 'f', 'r', 'a')) {
7548 av_log(c->fc, AV_LOG_DEBUG, "doesn't look like mfra (tag mismatch)\n");
7551 av_log(c->fc, AV_LOG_VERBOSE, "stream has mfra\n");
7553 ret = read_tfra(c, f);
7558 c->frag_index.complete = 1;
7560 seek_ret = avio_seek(f, original_pos, SEEK_SET);
7562 av_log(c->fc, AV_LOG_ERROR,
7563 "failed to seek back after looking for mfra\n");
7569 static int mov_read_header(AVFormatContext *s)
7571 MOVContext *mov = s->priv_data;
7572 AVIOContext *pb = s->pb;
7574 MOVAtom atom = { AV_RL32("root") };
7577 if (mov->decryption_key_len != 0 && mov->decryption_key_len != AES_CTR_KEY_SIZE) {
7578 av_log(s, AV_LOG_ERROR, "Invalid decryption key len %d expected %d\n",
7579 mov->decryption_key_len, AES_CTR_KEY_SIZE);
7580 return AVERROR(EINVAL);
7584 mov->trak_index = -1;
7585 /* .mov and .mp4 aren't streamable anyway (only progressive download if moov is before mdat) */
7586 if (pb->seekable & AVIO_SEEKABLE_NORMAL)
7587 atom.size = avio_size(pb);
7589 atom.size = INT64_MAX;
7591 /* check MOV header */
7593 if (mov->moov_retry)
7594 avio_seek(pb, 0, SEEK_SET);
7595 if ((err = mov_read_default(mov, pb, atom)) < 0) {
7596 av_log(s, AV_LOG_ERROR, "error reading header\n");
7599 } while ((pb->seekable & AVIO_SEEKABLE_NORMAL) && !mov->found_moov && !mov->moov_retry++);
7600 if (!mov->found_moov) {
7601 av_log(s, AV_LOG_ERROR, "moov atom not found\n");
7602 err = AVERROR_INVALIDDATA;
7605 av_log(mov->fc, AV_LOG_TRACE, "on_parse_exit_offset=%"PRId64"\n", avio_tell(pb));
7607 if (pb->seekable & AVIO_SEEKABLE_NORMAL) {
7608 if (mov->nb_chapter_tracks > 0 && !mov->ignore_chapters)
7609 mov_read_chapters(s);
7610 for (i = 0; i < s->nb_streams; i++)
7611 if (s->streams[i]->codecpar->codec_tag == AV_RL32("tmcd")) {
7612 mov_read_timecode_track(s, s->streams[i]);
7613 } else if (s->streams[i]->codecpar->codec_tag == AV_RL32("rtmd")) {
7614 mov_read_rtmd_track(s, s->streams[i]);
7618 /* copy timecode metadata from tmcd tracks to the related video streams */
7619 for (i = 0; i < s->nb_streams; i++) {
7620 AVStream *st = s->streams[i];
7621 MOVStreamContext *sc = st->priv_data;
7622 if (sc->timecode_track > 0) {
7623 AVDictionaryEntry *tcr;
7624 int tmcd_st_id = -1;
7626 for (j = 0; j < s->nb_streams; j++)
7627 if (s->streams[j]->id == sc->timecode_track)
7630 if (tmcd_st_id < 0 || tmcd_st_id == i)
7632 tcr = av_dict_get(s->streams[tmcd_st_id]->metadata, "timecode", NULL, 0);
7634 av_dict_set(&st->metadata, "timecode", tcr->value, 0);
7637 export_orphan_timecode(s);
7639 for (i = 0; i < s->nb_streams; i++) {
7640 AVStream *st = s->streams[i];
7641 MOVStreamContext *sc = st->priv_data;
7642 fix_timescale(mov, sc);
7643 if (st->codecpar->codec_type == AVMEDIA_TYPE_AUDIO &&
7644 st->codecpar->codec_id == AV_CODEC_ID_AAC) {
7645 st->internal->skip_samples = sc->start_pad;
7647 if (st->codecpar->codec_type == AVMEDIA_TYPE_VIDEO && sc->nb_frames_for_fps > 0 && sc->duration_for_fps > 0)
7648 av_reduce(&st->avg_frame_rate.num, &st->avg_frame_rate.den,
7649 sc->time_scale*(int64_t)sc->nb_frames_for_fps, sc->duration_for_fps, INT_MAX);
7650 if (st->codecpar->codec_type == AVMEDIA_TYPE_SUBTITLE) {
7651 if (st->codecpar->width <= 0 || st->codecpar->height <= 0) {
7652 st->codecpar->width = sc->width;
7653 st->codecpar->height = sc->height;
7655 if (st->codecpar->codec_id == AV_CODEC_ID_DVD_SUBTITLE) {
7656 if ((err = mov_rewrite_dvd_sub_extradata(st)) < 0)
7660 if (mov->handbrake_version &&
7661 mov->handbrake_version <= 1000000*0 + 1000*10 + 2 && // 0.10.2
7662 st->codecpar->codec_id == AV_CODEC_ID_MP3) {
7663 av_log(s, AV_LOG_VERBOSE, "Forcing full parsing for mp3 stream\n");
7664 st->need_parsing = AVSTREAM_PARSE_FULL;
7668 if (mov->trex_data) {
7669 for (i = 0; i < s->nb_streams; i++) {
7670 AVStream *st = s->streams[i];
7671 MOVStreamContext *sc = st->priv_data;
7672 if (st->duration > 0) {
7673 if (sc->data_size > INT64_MAX / sc->time_scale / 8) {
7674 av_log(s, AV_LOG_ERROR, "Overflow during bit rate calculation %"PRId64" * 8 * %d\n",
7675 sc->data_size, sc->time_scale);
7676 err = AVERROR_INVALIDDATA;
7679 st->codecpar->bit_rate = sc->data_size * 8 * sc->time_scale / st->duration;
7684 if (mov->use_mfra_for > 0) {
7685 for (i = 0; i < s->nb_streams; i++) {
7686 AVStream *st = s->streams[i];
7687 MOVStreamContext *sc = st->priv_data;
7688 if (sc->duration_for_fps > 0) {
7689 if (sc->data_size > INT64_MAX / sc->time_scale / 8) {
7690 av_log(s, AV_LOG_ERROR, "Overflow during bit rate calculation %"PRId64" * 8 * %d\n",
7691 sc->data_size, sc->time_scale);
7692 err = AVERROR_INVALIDDATA;
7695 st->codecpar->bit_rate = sc->data_size * 8 * sc->time_scale /
7696 sc->duration_for_fps;
7701 for (i = 0; i < mov->bitrates_count && i < s->nb_streams; i++) {
7702 if (mov->bitrates[i]) {
7703 s->streams[i]->codecpar->bit_rate = mov->bitrates[i];
7707 ff_rfps_calculate(s);
7709 for (i = 0; i < s->nb_streams; i++) {
7710 AVStream *st = s->streams[i];
7711 MOVStreamContext *sc = st->priv_data;
7713 switch (st->codecpar->codec_type) {
7714 case AVMEDIA_TYPE_AUDIO:
7715 err = ff_replaygain_export(st, s->metadata);
7719 case AVMEDIA_TYPE_VIDEO:
7720 if (sc->display_matrix) {
7721 err = av_stream_add_side_data(st, AV_PKT_DATA_DISPLAYMATRIX, (uint8_t*)sc->display_matrix,
7722 sizeof(int32_t) * 9);
7726 sc->display_matrix = NULL;
7729 err = av_stream_add_side_data(st, AV_PKT_DATA_STEREO3D,
7730 (uint8_t *)sc->stereo3d,
7731 sizeof(*sc->stereo3d));
7735 sc->stereo3d = NULL;
7737 if (sc->spherical) {
7738 err = av_stream_add_side_data(st, AV_PKT_DATA_SPHERICAL,
7739 (uint8_t *)sc->spherical,
7740 sc->spherical_size);
7744 sc->spherical = NULL;
7746 if (sc->mastering) {
7747 err = av_stream_add_side_data(st, AV_PKT_DATA_MASTERING_DISPLAY_METADATA,
7748 (uint8_t *)sc->mastering,
7749 sizeof(*sc->mastering));
7753 sc->mastering = NULL;
7756 err = av_stream_add_side_data(st, AV_PKT_DATA_CONTENT_LIGHT_LEVEL,
7757 (uint8_t *)sc->coll,
7767 ff_configure_buffers_for_index(s, AV_TIME_BASE);
7769 for (i = 0; i < mov->frag_index.nb_items; i++)
7770 if (mov->frag_index.item[i].moof_offset <= mov->fragment.moof_offset)
7771 mov->frag_index.item[i].headers_read = 1;
7779 static AVIndexEntry *mov_find_next_sample(AVFormatContext *s, AVStream **st)
7781 AVIndexEntry *sample = NULL;
7782 int64_t best_dts = INT64_MAX;
7784 for (i = 0; i < s->nb_streams; i++) {
7785 AVStream *avst = s->streams[i];
7786 MOVStreamContext *msc = avst->priv_data;
7787 if (msc->pb && msc->current_sample < avst->internal->nb_index_entries) {
7788 AVIndexEntry *current_sample = &avst->internal->index_entries[msc->current_sample];
7789 int64_t dts = av_rescale(current_sample->timestamp, AV_TIME_BASE, msc->time_scale);
7790 av_log(s, AV_LOG_TRACE, "stream %d, sample %d, dts %"PRId64"\n", i, msc->current_sample, dts);
7791 if (!sample || (!(s->pb->seekable & AVIO_SEEKABLE_NORMAL) && current_sample->pos < sample->pos) ||
7792 ((s->pb->seekable & AVIO_SEEKABLE_NORMAL) &&
7793 ((msc->pb != s->pb && dts < best_dts) || (msc->pb == s->pb && dts != AV_NOPTS_VALUE &&
7794 ((FFABS(best_dts - dts) <= AV_TIME_BASE && current_sample->pos < sample->pos) ||
7795 (FFABS(best_dts - dts) > AV_TIME_BASE && dts < best_dts)))))) {
7796 sample = current_sample;
7805 static int should_retry(AVIOContext *pb, int error_code) {
7806 if (error_code == AVERROR_EOF || avio_feof(pb))
7812 static int mov_switch_root(AVFormatContext *s, int64_t target, int index)
7815 MOVContext *mov = s->priv_data;
7817 if (index >= 0 && index < mov->frag_index.nb_items)
7818 target = mov->frag_index.item[index].moof_offset;
7819 if (avio_seek(s->pb, target, SEEK_SET) != target) {
7820 av_log(mov->fc, AV_LOG_ERROR, "root atom offset 0x%"PRIx64": partial file\n", target);
7821 return AVERROR_INVALIDDATA;
7824 mov->next_root_atom = 0;
7825 if (index < 0 || index >= mov->frag_index.nb_items)
7826 index = search_frag_moof_offset(&mov->frag_index, target);
7827 if (index < mov->frag_index.nb_items &&
7828 mov->frag_index.item[index].moof_offset == target) {
7829 if (index + 1 < mov->frag_index.nb_items)
7830 mov->next_root_atom = mov->frag_index.item[index + 1].moof_offset;
7831 if (mov->frag_index.item[index].headers_read)
7833 mov->frag_index.item[index].headers_read = 1;
7836 mov->found_mdat = 0;
7838 ret = mov_read_default(mov, s->pb, (MOVAtom){ AV_RL32("root"), INT64_MAX });
7841 if (avio_feof(s->pb))
7843 av_log(s, AV_LOG_TRACE, "read fragments, offset 0x%"PRIx64"\n", avio_tell(s->pb));
7848 static int mov_change_extradata(MOVStreamContext *sc, AVPacket *pkt)
7850 uint8_t *side, *extradata;
7853 /* Save the current index. */
7854 sc->last_stsd_index = sc->stsc_data[sc->stsc_index].id - 1;
7856 /* Notify the decoder that extradata changed. */
7857 extradata_size = sc->extradata_size[sc->last_stsd_index];
7858 extradata = sc->extradata[sc->last_stsd_index];
7859 if (extradata_size > 0 && extradata) {
7860 side = av_packet_new_side_data(pkt,
7861 AV_PKT_DATA_NEW_EXTRADATA,
7864 return AVERROR(ENOMEM);
7865 memcpy(side, extradata, extradata_size);
7871 static int get_eia608_packet(AVIOContext *pb, AVPacket *pkt, int size)
7876 return AVERROR_INVALIDDATA;
7877 new_size = ((size - 8) / 2) * 3;
7878 ret = av_new_packet(pkt, new_size);
7883 for (int j = 0; j < new_size; j += 3) {
7884 pkt->data[j] = 0xFC;
7885 pkt->data[j+1] = avio_r8(pb);
7886 pkt->data[j+2] = avio_r8(pb);
7892 static int mov_read_packet(AVFormatContext *s, AVPacket *pkt)
7894 MOVContext *mov = s->priv_data;
7895 MOVStreamContext *sc;
7896 AVIndexEntry *sample;
7897 AVStream *st = NULL;
7898 int64_t current_index;
7902 sample = mov_find_next_sample(s, &st);
7903 if (!sample || (mov->next_root_atom && sample->pos > mov->next_root_atom)) {
7904 if (!mov->next_root_atom)
7906 if ((ret = mov_switch_root(s, mov->next_root_atom, -1)) < 0)
7911 /* must be done just before reading, to avoid infinite loop on sample */
7912 current_index = sc->current_index;
7913 mov_current_sample_inc(sc);
7915 if (mov->next_root_atom) {
7916 sample->pos = FFMIN(sample->pos, mov->next_root_atom);
7917 sample->size = FFMIN(sample->size, (mov->next_root_atom - sample->pos));
7920 if (st->discard != AVDISCARD_ALL) {
7921 int64_t ret64 = avio_seek(sc->pb, sample->pos, SEEK_SET);
7922 if (ret64 != sample->pos) {
7923 av_log(mov->fc, AV_LOG_ERROR, "stream %d, offset 0x%"PRIx64": partial file\n",
7924 sc->ffindex, sample->pos);
7925 if (should_retry(sc->pb, ret64)) {
7926 mov_current_sample_dec(sc);
7927 } else if (ret64 < 0) {
7930 return AVERROR_INVALIDDATA;
7933 if (st->discard == AVDISCARD_NONKEY && !(sample->flags & AVINDEX_KEYFRAME)) {
7934 av_log(mov->fc, AV_LOG_DEBUG, "Nonkey frame from stream %d discarded due to AVDISCARD_NONKEY\n", sc->ffindex);
7938 if (st->codecpar->codec_id == AV_CODEC_ID_EIA_608 && sample->size > 8)
7939 ret = get_eia608_packet(sc->pb, pkt, sample->size);
7941 ret = av_get_packet(sc->pb, pkt, sample->size);
7943 if (should_retry(sc->pb, ret)) {
7944 mov_current_sample_dec(sc);
7948 #if CONFIG_DV_DEMUXER
7949 if (mov->dv_demux && sc->dv_audio_container) {
7950 AVBufferRef *buf = pkt->buf;
7951 ret = avpriv_dv_produce_packet(mov->dv_demux, pkt, pkt->data, pkt->size, pkt->pos);
7953 av_packet_unref(pkt);
7956 ret = avpriv_dv_get_packet(mov->dv_demux, pkt);
7961 if (sc->has_palette) {
7964 pal = av_packet_new_side_data(pkt, AV_PKT_DATA_PALETTE, AVPALETTE_SIZE);
7966 av_log(mov->fc, AV_LOG_ERROR, "Cannot append palette to packet\n");
7968 memcpy(pal, sc->palette, AVPALETTE_SIZE);
7969 sc->has_palette = 0;
7972 if (st->codecpar->codec_id == AV_CODEC_ID_MP3 && !st->need_parsing && pkt->size > 4) {
7973 if (ff_mpa_check_header(AV_RB32(pkt->data)) < 0)
7974 st->need_parsing = AVSTREAM_PARSE_FULL;
7978 pkt->stream_index = sc->ffindex;
7979 pkt->dts = sample->timestamp;
7980 if (sample->flags & AVINDEX_DISCARD_FRAME) {
7981 pkt->flags |= AV_PKT_FLAG_DISCARD;
7983 if (sc->ctts_data && sc->ctts_index < sc->ctts_count) {
7984 pkt->pts = pkt->dts + sc->dts_shift + sc->ctts_data[sc->ctts_index].duration;
7985 /* update ctts context */
7987 if (sc->ctts_index < sc->ctts_count &&
7988 sc->ctts_data[sc->ctts_index].count == sc->ctts_sample) {
7990 sc->ctts_sample = 0;
7993 int64_t next_dts = (sc->current_sample < st->internal->nb_index_entries) ?
7994 st->internal->index_entries[sc->current_sample].timestamp : st->duration;
7996 if (next_dts >= pkt->dts)
7997 pkt->duration = next_dts - pkt->dts;
7998 pkt->pts = pkt->dts;
8000 if (st->discard == AVDISCARD_ALL)
8002 if (sc->sdtp_data && sc->current_sample <= sc->sdtp_count) {
8003 uint8_t sample_flags = sc->sdtp_data[sc->current_sample - 1];
8004 uint8_t sample_is_depended_on = (sample_flags >> 2) & 0x3;
8005 pkt->flags |= sample_is_depended_on == MOV_SAMPLE_DEPENDENCY_NO ? AV_PKT_FLAG_DISPOSABLE : 0;
8007 pkt->flags |= sample->flags & AVINDEX_KEYFRAME ? AV_PKT_FLAG_KEY : 0;
8008 pkt->pos = sample->pos;
8010 /* Multiple stsd handling. */
8011 if (sc->stsc_data) {
8012 /* Keep track of the stsc index for the given sample, then check
8013 * if the stsd index is different from the last used one. */
8015 if (mov_stsc_index_valid(sc->stsc_index, sc->stsc_count) &&
8016 mov_get_stsc_samples(sc, sc->stsc_index) == sc->stsc_sample) {
8018 sc->stsc_sample = 0;
8019 /* Do not check indexes after a switch. */
8020 } else if (sc->stsc_data[sc->stsc_index].id > 0 &&
8021 sc->stsc_data[sc->stsc_index].id - 1 < sc->stsd_count &&
8022 sc->stsc_data[sc->stsc_index].id - 1 != sc->last_stsd_index) {
8023 ret = mov_change_extradata(sc, pkt);
8030 aax_filter(pkt->data, pkt->size, mov);
8032 ret = cenc_filter(mov, st, sc, pkt, current_index);
8040 static int mov_seek_fragment(AVFormatContext *s, AVStream *st, int64_t timestamp)
8042 MOVContext *mov = s->priv_data;
8045 if (!mov->frag_index.complete)
8048 index = search_frag_timestamp(&mov->frag_index, st, timestamp);
8051 if (!mov->frag_index.item[index].headers_read)
8052 return mov_switch_root(s, -1, index);
8053 if (index + 1 < mov->frag_index.nb_items)
8054 mov->next_root_atom = mov->frag_index.item[index + 1].moof_offset;
8059 static int mov_seek_stream(AVFormatContext *s, AVStream *st, int64_t timestamp, int flags)
8061 MOVStreamContext *sc = st->priv_data;
8062 int sample, time_sample, ret;
8065 // Here we consider timestamp to be PTS, hence try to offset it so that we
8066 // can search over the DTS timeline.
8067 timestamp -= (sc->min_corrected_pts + sc->dts_shift);
8069 ret = mov_seek_fragment(s, st, timestamp);
8073 sample = av_index_search_timestamp(st, timestamp, flags);
8074 av_log(s, AV_LOG_TRACE, "stream %d, timestamp %"PRId64", sample %d\n", st->index, timestamp, sample);
8075 if (sample < 0 && st->internal->nb_index_entries && timestamp < st->internal->index_entries[0].timestamp)
8077 if (sample < 0) /* not sure what to do */
8078 return AVERROR_INVALIDDATA;
8079 mov_current_sample_set(sc, sample);
8080 av_log(s, AV_LOG_TRACE, "stream %d, found sample %d\n", st->index, sc->current_sample);
8081 /* adjust ctts index */
8082 if (sc->ctts_data) {
8084 for (i = 0; i < sc->ctts_count; i++) {
8085 int next = time_sample + sc->ctts_data[i].count;
8086 if (next > sc->current_sample) {
8088 sc->ctts_sample = sc->current_sample - time_sample;
8095 /* adjust stsd index */
8096 if (sc->chunk_count) {
8098 for (i = 0; i < sc->stsc_count; i++) {
8099 int64_t next = time_sample + mov_get_stsc_samples(sc, i);
8100 if (next > sc->current_sample) {
8102 sc->stsc_sample = sc->current_sample - time_sample;
8105 av_assert0(next == (int)next);
8113 static int64_t mov_get_skip_samples(AVStream *st, int sample)
8115 MOVStreamContext *sc = st->priv_data;
8116 int64_t first_ts = st->internal->index_entries[0].timestamp;
8117 int64_t ts = st->internal->index_entries[sample].timestamp;
8120 if (st->codecpar->codec_type != AVMEDIA_TYPE_AUDIO)
8123 /* compute skip samples according to stream start_pad, seek ts and first ts */
8124 off = av_rescale_q(ts - first_ts, st->time_base,
8125 (AVRational){1, st->codecpar->sample_rate});
8126 return FFMAX(sc->start_pad - off, 0);
8129 static int mov_read_seek(AVFormatContext *s, int stream_index, int64_t sample_time, int flags)
8131 MOVContext *mc = s->priv_data;
8136 if (stream_index >= s->nb_streams)
8137 return AVERROR_INVALIDDATA;
8139 st = s->streams[stream_index];
8140 sample = mov_seek_stream(s, st, sample_time, flags);
8144 if (mc->seek_individually) {
8145 /* adjust seek timestamp to found sample timestamp */
8146 int64_t seek_timestamp = st->internal->index_entries[sample].timestamp;
8147 st->internal->skip_samples = mov_get_skip_samples(st, sample);
8149 for (i = 0; i < s->nb_streams; i++) {
8153 if (stream_index == i)
8156 timestamp = av_rescale_q(seek_timestamp, s->streams[stream_index]->time_base, st->time_base);
8157 sample = mov_seek_stream(s, st, timestamp, flags);
8159 st->internal->skip_samples = mov_get_skip_samples(st, sample);
8162 for (i = 0; i < s->nb_streams; i++) {
8163 MOVStreamContext *sc;
8166 mov_current_sample_set(sc, 0);
8169 MOVStreamContext *sc;
8170 AVIndexEntry *entry = mov_find_next_sample(s, &st);
8172 return AVERROR_INVALIDDATA;
8174 if (sc->ffindex == stream_index && sc->current_sample == sample)
8176 mov_current_sample_inc(sc);
8182 #define OFFSET(x) offsetof(MOVContext, x)
8183 #define FLAGS AV_OPT_FLAG_VIDEO_PARAM | AV_OPT_FLAG_DECODING_PARAM
8184 static const AVOption mov_options[] = {
8185 {"use_absolute_path",
8186 "allow using absolute path when opening alias, this is a possible security issue",
8187 OFFSET(use_absolute_path), AV_OPT_TYPE_BOOL, {.i64 = 0},
8189 {"seek_streams_individually",
8190 "Seek each stream individually to the closest point",
8191 OFFSET(seek_individually), AV_OPT_TYPE_BOOL, { .i64 = 1 },
8193 {"ignore_editlist", "Ignore the edit list atom.", OFFSET(ignore_editlist), AV_OPT_TYPE_BOOL, {.i64 = 0},
8195 {"advanced_editlist",
8196 "Modify the AVIndex according to the editlists. Use this option to decode in the order specified by the edits.",
8197 OFFSET(advanced_editlist), AV_OPT_TYPE_BOOL, {.i64 = 1},
8199 {"ignore_chapters", "", OFFSET(ignore_chapters), AV_OPT_TYPE_BOOL, {.i64 = 0},
8202 "use mfra for fragment timestamps",
8203 OFFSET(use_mfra_for), AV_OPT_TYPE_INT, {.i64 = FF_MOV_FLAG_MFRA_AUTO},
8204 -1, FF_MOV_FLAG_MFRA_PTS, FLAGS,
8206 {"auto", "auto", 0, AV_OPT_TYPE_CONST, {.i64 = FF_MOV_FLAG_MFRA_AUTO}, 0, 0,
8207 FLAGS, "use_mfra_for" },
8208 {"dts", "dts", 0, AV_OPT_TYPE_CONST, {.i64 = FF_MOV_FLAG_MFRA_DTS}, 0, 0,
8209 FLAGS, "use_mfra_for" },
8210 {"pts", "pts", 0, AV_OPT_TYPE_CONST, {.i64 = FF_MOV_FLAG_MFRA_PTS}, 0, 0,
8211 FLAGS, "use_mfra_for" },
8212 { "export_all", "Export unrecognized metadata entries", OFFSET(export_all),
8213 AV_OPT_TYPE_BOOL, { .i64 = 0 }, 0, 1, .flags = FLAGS },
8214 { "export_xmp", "Export full XMP metadata", OFFSET(export_xmp),
8215 AV_OPT_TYPE_BOOL, { .i64 = 0 }, 0, 1, .flags = FLAGS },
8216 { "activation_bytes", "Secret bytes for Audible AAX files", OFFSET(activation_bytes),
8217 AV_OPT_TYPE_BINARY, .flags = AV_OPT_FLAG_DECODING_PARAM },
8218 { "audible_key", "AES-128 Key for Audible AAXC files", OFFSET(audible_key),
8219 AV_OPT_TYPE_BINARY, .flags = AV_OPT_FLAG_DECODING_PARAM },
8220 { "audible_iv", "AES-128 IV for Audible AAXC files", OFFSET(audible_iv),
8221 AV_OPT_TYPE_BINARY, .flags = AV_OPT_FLAG_DECODING_PARAM },
8222 { "audible_fixed_key", // extracted from libAAX_SDK.so and AAXSDKWin.dll files!
8223 "Fixed key used for handling Audible AAX files", OFFSET(audible_fixed_key),
8224 AV_OPT_TYPE_BINARY, {.str="77214d4b196a87cd520045fd20a51d67"},
8225 .flags = AV_OPT_FLAG_DECODING_PARAM },
8226 { "decryption_key", "The media decryption key (hex)", OFFSET(decryption_key), AV_OPT_TYPE_BINARY, .flags = AV_OPT_FLAG_DECODING_PARAM },
8227 { "enable_drefs", "Enable external track support.", OFFSET(enable_drefs), AV_OPT_TYPE_BOOL,
8228 {.i64 = 0}, 0, 1, FLAGS },
8233 static const AVClass mov_class = {
8234 .class_name = "mov,mp4,m4a,3gp,3g2,mj2",
8235 .item_name = av_default_item_name,
8236 .option = mov_options,
8237 .version = LIBAVUTIL_VERSION_INT,
8240 AVInputFormat ff_mov_demuxer = {
8241 .name = "mov,mp4,m4a,3gp,3g2,mj2",
8242 .long_name = NULL_IF_CONFIG_SMALL("QuickTime / MOV"),
8243 .priv_class = &mov_class,
8244 .priv_data_size = sizeof(MOVContext),
8245 .extensions = "mov,mp4,m4a,3gp,3g2,mj2,psp,m4b,ism,ismv,isma,f4v",
8246 .read_probe = mov_probe,
8247 .read_header = mov_read_header,
8248 .read_packet = mov_read_packet,
8249 .read_close = mov_read_close,
8250 .read_seek = mov_read_seek,
8251 .flags = AVFMT_NO_BYTE_SEEK | AVFMT_SEEK_TO_PTS,