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)) {
4587 av_freep(&sc->display_matrix);
4588 sc->display_matrix = av_malloc(sizeof(int32_t) * 9);
4589 if (!sc->display_matrix)
4590 return AVERROR(ENOMEM);
4592 for (i = 0; i < 3; i++)
4593 for (j = 0; j < 3; j++)
4594 sc->display_matrix[i * 3 + j] = res_display_matrix[i][j];
4596 #if FF_API_OLD_ROTATE_API
4597 rotate = av_display_rotation_get(sc->display_matrix);
4598 if (!isnan(rotate)) {
4599 char rotate_buf[64];
4601 if (rotate < 0) // for backward compatibility
4603 snprintf(rotate_buf, sizeof(rotate_buf), "%g", rotate);
4604 av_dict_set(&st->metadata, "rotate", rotate_buf, 0);
4609 // transform the display width/height according to the matrix
4610 // to keep the same scale, use [width height 1<<16]
4611 if (width && height && sc->display_matrix) {
4612 double disp_transform[2];
4614 for (i = 0; i < 2; i++)
4615 disp_transform[i] = hypot(sc->display_matrix[0 + i],
4616 sc->display_matrix[3 + i]);
4618 if (disp_transform[0] > 1 && disp_transform[1] > 1 &&
4619 disp_transform[0] < (1<<24) && disp_transform[1] < (1<<24) &&
4620 fabs((disp_transform[0] / disp_transform[1]) - 1.0) > 0.01)
4621 st->sample_aspect_ratio = av_d2q(
4622 disp_transform[0] / disp_transform[1],
4628 static int mov_read_tfhd(MOVContext *c, AVIOContext *pb, MOVAtom atom)
4630 MOVFragment *frag = &c->fragment;
4631 MOVTrackExt *trex = NULL;
4632 int flags, track_id, i;
4633 MOVFragmentStreamInfo * frag_stream_info;
4635 avio_r8(pb); /* version */
4636 flags = avio_rb24(pb);
4638 track_id = avio_rb32(pb);
4640 return AVERROR_INVALIDDATA;
4641 for (i = 0; i < c->trex_count; i++)
4642 if (c->trex_data[i].track_id == track_id) {
4643 trex = &c->trex_data[i];
4647 av_log(c->fc, AV_LOG_WARNING, "could not find corresponding trex (id %u)\n", track_id);
4650 c->fragment.found_tfhd = 1;
4651 frag->track_id = track_id;
4652 set_frag_stream(&c->frag_index, track_id);
4654 frag->base_data_offset = flags & MOV_TFHD_BASE_DATA_OFFSET ?
4655 avio_rb64(pb) : flags & MOV_TFHD_DEFAULT_BASE_IS_MOOF ?
4656 frag->moof_offset : frag->implicit_offset;
4657 frag->stsd_id = flags & MOV_TFHD_STSD_ID ? avio_rb32(pb) : trex->stsd_id;
4659 frag->duration = flags & MOV_TFHD_DEFAULT_DURATION ?
4660 avio_rb32(pb) : trex->duration;
4661 frag->size = flags & MOV_TFHD_DEFAULT_SIZE ?
4662 avio_rb32(pb) : trex->size;
4663 frag->flags = flags & MOV_TFHD_DEFAULT_FLAGS ?
4664 avio_rb32(pb) : trex->flags;
4665 av_log(c->fc, AV_LOG_TRACE, "frag flags 0x%x\n", frag->flags);
4667 frag_stream_info = get_current_frag_stream_info(&c->frag_index);
4668 if (frag_stream_info)
4669 frag_stream_info->next_trun_dts = AV_NOPTS_VALUE;
4674 static int mov_read_chap(MOVContext *c, AVIOContext *pb, MOVAtom atom)
4679 num = atom.size / 4;
4680 if (!(new_tracks = av_malloc_array(num, sizeof(int))))
4681 return AVERROR(ENOMEM);
4683 av_free(c->chapter_tracks);
4684 c->chapter_tracks = new_tracks;
4685 c->nb_chapter_tracks = num;
4687 for (i = 0; i < num && !pb->eof_reached; i++)
4688 c->chapter_tracks[i] = avio_rb32(pb);
4693 static int mov_read_trex(MOVContext *c, AVIOContext *pb, MOVAtom atom)
4698 if ((uint64_t)c->trex_count+1 >= UINT_MAX / sizeof(*c->trex_data))
4699 return AVERROR_INVALIDDATA;
4700 if ((err = av_reallocp_array(&c->trex_data, c->trex_count + 1,
4701 sizeof(*c->trex_data))) < 0) {
4706 c->fc->duration = AV_NOPTS_VALUE; // the duration from mvhd is not representing the whole file when fragments are used.
4708 trex = &c->trex_data[c->trex_count++];
4709 avio_r8(pb); /* version */
4710 avio_rb24(pb); /* flags */
4711 trex->track_id = avio_rb32(pb);
4712 trex->stsd_id = avio_rb32(pb);
4713 trex->duration = avio_rb32(pb);
4714 trex->size = avio_rb32(pb);
4715 trex->flags = avio_rb32(pb);
4719 static int mov_read_tfdt(MOVContext *c, AVIOContext *pb, MOVAtom atom)
4721 MOVFragment *frag = &c->fragment;
4722 AVStream *st = NULL;
4723 MOVStreamContext *sc;
4725 MOVFragmentStreamInfo * frag_stream_info;
4726 int64_t base_media_decode_time;
4728 for (i = 0; i < c->fc->nb_streams; i++) {
4729 if (c->fc->streams[i]->id == frag->track_id) {
4730 st = c->fc->streams[i];
4735 av_log(c->fc, AV_LOG_WARNING, "could not find corresponding track id %u\n", frag->track_id);
4739 if (sc->pseudo_stream_id + 1 != frag->stsd_id && sc->pseudo_stream_id != -1)
4741 version = avio_r8(pb);
4742 avio_rb24(pb); /* flags */
4744 base_media_decode_time = avio_rb64(pb);
4746 base_media_decode_time = avio_rb32(pb);
4749 frag_stream_info = get_current_frag_stream_info(&c->frag_index);
4750 if (frag_stream_info)
4751 frag_stream_info->tfdt_dts = base_media_decode_time;
4752 sc->track_end = base_media_decode_time;
4757 static int mov_read_trun(MOVContext *c, AVIOContext *pb, MOVAtom atom)
4759 MOVFragment *frag = &c->fragment;
4760 AVStream *st = NULL;
4761 MOVStreamContext *sc;
4764 int64_t dts, pts = AV_NOPTS_VALUE;
4765 int data_offset = 0;
4766 unsigned entries, first_sample_flags = frag->flags;
4767 int flags, distance, i;
4768 int64_t prev_dts = AV_NOPTS_VALUE;
4769 int next_frag_index = -1, index_entry_pos;
4770 size_t requested_size;
4771 size_t old_ctts_allocated_size;
4772 AVIndexEntry *new_entries;
4773 MOVFragmentStreamInfo * frag_stream_info;
4775 if (!frag->found_tfhd) {
4776 av_log(c->fc, AV_LOG_ERROR, "trun track id unknown, no tfhd was found\n");
4777 return AVERROR_INVALIDDATA;
4780 for (i = 0; i < c->fc->nb_streams; i++) {
4781 if (c->fc->streams[i]->id == frag->track_id) {
4782 st = c->fc->streams[i];
4787 av_log(c->fc, AV_LOG_WARNING, "could not find corresponding track id %u\n", frag->track_id);
4791 if (sc->pseudo_stream_id+1 != frag->stsd_id && sc->pseudo_stream_id != -1)
4794 // Find the next frag_index index that has a valid index_entry for
4795 // the current track_id.
4797 // A valid index_entry means the trun for the fragment was read
4798 // and it's samples are in index_entries at the given position.
4799 // New index entries will be inserted before the index_entry found.
4800 index_entry_pos = st->internal->nb_index_entries;
4801 for (i = c->frag_index.current + 1; i < c->frag_index.nb_items; i++) {
4802 frag_stream_info = get_frag_stream_info(&c->frag_index, i, frag->track_id);
4803 if (frag_stream_info && frag_stream_info->index_entry >= 0) {
4804 next_frag_index = i;
4805 index_entry_pos = frag_stream_info->index_entry;
4809 av_assert0(index_entry_pos <= st->internal->nb_index_entries);
4811 avio_r8(pb); /* version */
4812 flags = avio_rb24(pb);
4813 entries = avio_rb32(pb);
4814 av_log(c->fc, AV_LOG_TRACE, "flags 0x%x entries %u\n", flags, entries);
4816 if ((uint64_t)entries+sc->ctts_count >= UINT_MAX/sizeof(*sc->ctts_data))
4817 return AVERROR_INVALIDDATA;
4818 if (flags & MOV_TRUN_DATA_OFFSET) data_offset = avio_rb32(pb);
4819 if (flags & MOV_TRUN_FIRST_SAMPLE_FLAGS) first_sample_flags = avio_rb32(pb);
4821 frag_stream_info = get_current_frag_stream_info(&c->frag_index);
4822 if (frag_stream_info) {
4823 if (frag_stream_info->next_trun_dts != AV_NOPTS_VALUE) {
4824 dts = frag_stream_info->next_trun_dts - sc->time_offset;
4825 } else if (frag_stream_info->first_tfra_pts != AV_NOPTS_VALUE &&
4826 c->use_mfra_for == FF_MOV_FLAG_MFRA_PTS) {
4827 pts = frag_stream_info->first_tfra_pts;
4828 av_log(c->fc, AV_LOG_DEBUG, "found mfra time %"PRId64
4829 ", using it for pts\n", pts);
4830 } else if (frag_stream_info->first_tfra_pts != AV_NOPTS_VALUE &&
4831 c->use_mfra_for == FF_MOV_FLAG_MFRA_DTS) {
4832 dts = frag_stream_info->first_tfra_pts;
4833 av_log(c->fc, AV_LOG_DEBUG, "found mfra time %"PRId64
4834 ", using it for dts\n", pts);
4835 } else if (frag_stream_info->sidx_pts != AV_NOPTS_VALUE) {
4836 // FIXME: sidx earliest_presentation_time is *PTS*, s.b.
4837 // pts = frag_stream_info->sidx_pts;
4838 dts = frag_stream_info->sidx_pts - sc->time_offset;
4839 av_log(c->fc, AV_LOG_DEBUG, "found sidx time %"PRId64
4840 ", using it for pts\n", pts);
4841 } else if (frag_stream_info->tfdt_dts != AV_NOPTS_VALUE) {
4842 dts = frag_stream_info->tfdt_dts - sc->time_offset;
4843 av_log(c->fc, AV_LOG_DEBUG, "found tfdt time %"PRId64
4844 ", using it for dts\n", dts);
4846 dts = sc->track_end - sc->time_offset;
4847 av_log(c->fc, AV_LOG_DEBUG, "found track end time %"PRId64
4848 ", using it for dts\n", dts);
4851 dts = sc->track_end - sc->time_offset;
4852 av_log(c->fc, AV_LOG_DEBUG, "found track end time %"PRId64
4853 ", using it for dts\n", dts);
4855 offset = frag->base_data_offset + data_offset;
4857 av_log(c->fc, AV_LOG_TRACE, "first sample flags 0x%x\n", first_sample_flags);
4859 // realloc space for new index entries
4860 if((uint64_t)st->internal->nb_index_entries + entries >= UINT_MAX / sizeof(AVIndexEntry)) {
4861 entries = UINT_MAX / sizeof(AVIndexEntry) - st->internal->nb_index_entries;
4862 av_log(c->fc, AV_LOG_ERROR, "Failed to add index entry\n");
4867 requested_size = (st->internal->nb_index_entries + entries) * sizeof(AVIndexEntry);
4868 new_entries = av_fast_realloc(st->internal->index_entries,
4869 &st->internal->index_entries_allocated_size,
4872 return AVERROR(ENOMEM);
4873 st->internal->index_entries= new_entries;
4875 requested_size = (st->internal->nb_index_entries + entries) * sizeof(*sc->ctts_data);
4876 old_ctts_allocated_size = sc->ctts_allocated_size;
4877 ctts_data = av_fast_realloc(sc->ctts_data, &sc->ctts_allocated_size,
4880 return AVERROR(ENOMEM);
4881 sc->ctts_data = ctts_data;
4883 // In case there were samples without ctts entries, ensure they get
4884 // zero valued entries. This ensures clips which mix boxes with and
4885 // without ctts entries don't pickup uninitialized data.
4886 memset((uint8_t*)(sc->ctts_data) + old_ctts_allocated_size, 0,
4887 sc->ctts_allocated_size - old_ctts_allocated_size);
4889 if (index_entry_pos < st->internal->nb_index_entries) {
4890 // Make hole in index_entries and ctts_data for new samples
4891 memmove(st->internal->index_entries + index_entry_pos + entries,
4892 st->internal->index_entries + index_entry_pos,
4893 sizeof(*st->internal->index_entries) *
4894 (st->internal->nb_index_entries - index_entry_pos));
4895 memmove(sc->ctts_data + index_entry_pos + entries,
4896 sc->ctts_data + index_entry_pos,
4897 sizeof(*sc->ctts_data) * (sc->ctts_count - index_entry_pos));
4898 if (index_entry_pos < sc->current_sample) {
4899 sc->current_sample += entries;
4903 st->internal->nb_index_entries += entries;
4904 sc->ctts_count = st->internal->nb_index_entries;
4906 // Record the index_entry position in frag_index of this fragment
4907 if (frag_stream_info)
4908 frag_stream_info->index_entry = index_entry_pos;
4910 if (index_entry_pos > 0)
4911 prev_dts = st->internal->index_entries[index_entry_pos-1].timestamp;
4913 for (i = 0; i < entries && !pb->eof_reached; i++) {
4914 unsigned sample_size = frag->size;
4915 int sample_flags = i ? frag->flags : first_sample_flags;
4916 unsigned sample_duration = frag->duration;
4917 unsigned ctts_duration = 0;
4919 int index_entry_flags = 0;
4921 if (flags & MOV_TRUN_SAMPLE_DURATION) sample_duration = avio_rb32(pb);
4922 if (flags & MOV_TRUN_SAMPLE_SIZE) sample_size = avio_rb32(pb);
4923 if (flags & MOV_TRUN_SAMPLE_FLAGS) sample_flags = avio_rb32(pb);
4924 if (flags & MOV_TRUN_SAMPLE_CTS) ctts_duration = avio_rb32(pb);
4926 mov_update_dts_shift(sc, ctts_duration, c->fc);
4927 if (pts != AV_NOPTS_VALUE) {
4928 dts = pts - sc->dts_shift;
4929 if (flags & MOV_TRUN_SAMPLE_CTS) {
4930 dts -= ctts_duration;
4932 dts -= sc->time_offset;
4934 av_log(c->fc, AV_LOG_DEBUG,
4935 "pts %"PRId64" calculated dts %"PRId64
4936 " sc->dts_shift %d ctts.duration %d"
4937 " sc->time_offset %"PRId64
4938 " flags & MOV_TRUN_SAMPLE_CTS %d\n",
4940 sc->dts_shift, ctts_duration,
4941 sc->time_offset, flags & MOV_TRUN_SAMPLE_CTS);
4942 pts = AV_NOPTS_VALUE;
4945 if (st->codecpar->codec_type == AVMEDIA_TYPE_AUDIO)
4949 !(sample_flags & (MOV_FRAG_SAMPLE_FLAG_IS_NON_SYNC |
4950 MOV_FRAG_SAMPLE_FLAG_DEPENDS_YES));
4953 index_entry_flags |= AVINDEX_KEYFRAME;
4955 // Fragments can overlap in time. Discard overlapping frames after
4957 if (prev_dts >= dts)
4958 index_entry_flags |= AVINDEX_DISCARD_FRAME;
4960 st->internal->index_entries[index_entry_pos].pos = offset;
4961 st->internal->index_entries[index_entry_pos].timestamp = dts;
4962 st->internal->index_entries[index_entry_pos].size= sample_size;
4963 st->internal->index_entries[index_entry_pos].min_distance= distance;
4964 st->internal->index_entries[index_entry_pos].flags = index_entry_flags;
4966 sc->ctts_data[index_entry_pos].count = 1;
4967 sc->ctts_data[index_entry_pos].duration = ctts_duration;
4970 av_log(c->fc, AV_LOG_TRACE, "AVIndex stream %d, sample %d, offset %"PRIx64", dts %"PRId64", "
4971 "size %u, distance %d, keyframe %d\n", st->index,
4972 index_entry_pos, offset, dts, sample_size, distance, keyframe);
4974 dts += sample_duration;
4975 offset += sample_size;
4976 sc->data_size += sample_size;
4978 if (sample_duration <= INT64_MAX - sc->duration_for_fps &&
4979 1 <= INT_MAX - sc->nb_frames_for_fps
4981 sc->duration_for_fps += sample_duration;
4982 sc->nb_frames_for_fps ++;
4985 if (frag_stream_info)
4986 frag_stream_info->next_trun_dts = dts + sc->time_offset;
4988 // EOF found before reading all entries. Fix the hole this would
4989 // leave in index_entries and ctts_data
4990 int gap = entries - i;
4991 memmove(st->internal->index_entries + index_entry_pos,
4992 st->internal->index_entries + index_entry_pos + gap,
4993 sizeof(*st->internal->index_entries) *
4994 (st->internal->nb_index_entries - (index_entry_pos + gap)));
4995 memmove(sc->ctts_data + index_entry_pos,
4996 sc->ctts_data + index_entry_pos + gap,
4997 sizeof(*sc->ctts_data) *
4998 (sc->ctts_count - (index_entry_pos + gap)));
5000 st->internal->nb_index_entries -= gap;
5001 sc->ctts_count -= gap;
5002 if (index_entry_pos < sc->current_sample) {
5003 sc->current_sample -= gap;
5008 // The end of this new fragment may overlap in time with the start
5009 // of the next fragment in index_entries. Mark the samples in the next
5010 // fragment that overlap with AVINDEX_DISCARD_FRAME
5011 prev_dts = AV_NOPTS_VALUE;
5012 if (index_entry_pos > 0)
5013 prev_dts = st->internal->index_entries[index_entry_pos-1].timestamp;
5014 for (i = index_entry_pos; i < st->internal->nb_index_entries; i++) {
5015 if (prev_dts < st->internal->index_entries[i].timestamp)
5017 st->internal->index_entries[i].flags |= AVINDEX_DISCARD_FRAME;
5020 // If a hole was created to insert the new index_entries into,
5021 // the index_entry recorded for all subsequent moof must
5022 // be incremented by the number of entries inserted.
5023 fix_frag_index_entries(&c->frag_index, next_frag_index,
5024 frag->track_id, entries);
5026 if (pb->eof_reached) {
5027 av_log(c->fc, AV_LOG_WARNING, "reached eof, corrupted TRUN atom\n");
5031 frag->implicit_offset = offset;
5033 sc->track_end = dts + sc->time_offset;
5034 if (st->duration < sc->track_end)
5035 st->duration = sc->track_end;
5040 static int mov_read_sidx(MOVContext *c, AVIOContext *pb, MOVAtom atom)
5042 int64_t stream_size = avio_size(pb);
5043 int64_t offset = av_sat_add64(avio_tell(pb), atom.size), pts, timestamp;
5044 uint8_t version, is_complete;
5046 unsigned i, j, track_id, item_count;
5047 AVStream *st = NULL;
5048 AVStream *ref_st = NULL;
5049 MOVStreamContext *sc, *ref_sc = NULL;
5050 AVRational timescale;
5052 version = avio_r8(pb);
5054 avpriv_request_sample(c->fc, "sidx version %u", version);
5058 avio_rb24(pb); // flags
5060 track_id = avio_rb32(pb); // Reference ID
5061 for (i = 0; i < c->fc->nb_streams; i++) {
5062 if (c->fc->streams[i]->id == track_id) {
5063 st = c->fc->streams[i];
5068 av_log(c->fc, AV_LOG_WARNING, "could not find corresponding track id %d\n", track_id);
5074 timescale = av_make_q(1, avio_rb32(pb));
5076 if (timescale.den <= 0) {
5077 av_log(c->fc, AV_LOG_ERROR, "Invalid sidx timescale 1/%d\n", timescale.den);
5078 return AVERROR_INVALIDDATA;
5082 pts = avio_rb32(pb);
5083 offadd= avio_rb32(pb);
5085 pts = avio_rb64(pb);
5086 offadd= avio_rb64(pb);
5088 if (av_sat_add64(offset, offadd) != offset + (uint64_t)offadd)
5089 return AVERROR_INVALIDDATA;
5091 offset += (uint64_t)offadd;
5093 avio_rb16(pb); // reserved
5095 item_count = avio_rb16(pb);
5097 for (i = 0; i < item_count; i++) {
5099 MOVFragmentStreamInfo * frag_stream_info;
5100 uint32_t size = avio_rb32(pb);
5101 uint32_t duration = avio_rb32(pb);
5102 if (size & 0x80000000) {
5103 avpriv_request_sample(c->fc, "sidx reference_type 1");
5104 return AVERROR_PATCHWELCOME;
5106 avio_rb32(pb); // sap_flags
5107 timestamp = av_rescale_q(pts, timescale, st->time_base);
5109 index = update_frag_index(c, offset);
5110 frag_stream_info = get_frag_stream_info(&c->frag_index, index, track_id);
5111 if (frag_stream_info)
5112 frag_stream_info->sidx_pts = timestamp;
5114 if (av_sat_add64(offset, size) != offset + size)
5115 return AVERROR_INVALIDDATA;
5120 st->duration = sc->track_end = pts;
5124 // See if the remaining bytes are just an mfra which we can ignore.
5125 is_complete = offset == stream_size;
5126 if (!is_complete && (pb->seekable & AVIO_SEEKABLE_NORMAL)) {
5128 int64_t original_pos = avio_tell(pb);
5129 if (!c->have_read_mfra_size) {
5130 if ((ret = avio_seek(pb, stream_size - 4, SEEK_SET)) < 0)
5132 c->mfra_size = avio_rb32(pb);
5133 c->have_read_mfra_size = 1;
5134 if ((ret = avio_seek(pb, original_pos, SEEK_SET)) < 0)
5137 if (offset + c->mfra_size == stream_size)
5142 // Find first entry in fragment index that came from an sidx.
5143 // This will pretty much always be the first entry.
5144 for (i = 0; i < c->frag_index.nb_items; i++) {
5145 MOVFragmentIndexItem * item = &c->frag_index.item[i];
5146 for (j = 0; ref_st == NULL && j < item->nb_stream_info; j++) {
5147 MOVFragmentStreamInfo * si;
5148 si = &item->stream_info[j];
5149 if (si->sidx_pts != AV_NOPTS_VALUE) {
5150 ref_st = c->fc->streams[j];
5151 ref_sc = ref_st->priv_data;
5156 if (ref_st) for (i = 0; i < c->fc->nb_streams; i++) {
5157 st = c->fc->streams[i];
5159 if (!sc->has_sidx) {
5160 st->duration = sc->track_end = av_rescale(ref_st->duration, sc->time_scale, ref_sc->time_scale);
5164 c->frag_index.complete = 1;
5170 /* this atom should be null (from specs), but some buggy files put the 'moov' atom inside it... */
5171 /* like the files created with Adobe Premiere 5.0, for samples see */
5172 /* http://graphics.tudelft.nl/~wouter/publications/soundtests/ */
5173 static int mov_read_wide(MOVContext *c, AVIOContext *pb, MOVAtom atom)
5178 return 0; /* continue */
5179 if (avio_rb32(pb) != 0) { /* 0 sized mdat atom... use the 'wide' atom size */
5180 avio_skip(pb, atom.size - 4);
5183 atom.type = avio_rl32(pb);
5185 if (atom.type != MKTAG('m','d','a','t')) {
5186 avio_skip(pb, atom.size);
5189 err = mov_read_mdat(c, pb, atom);
5193 static int mov_read_cmov(MOVContext *c, AVIOContext *pb, MOVAtom atom)
5198 uint8_t *moov_data; /* uncompressed data */
5199 long cmov_len, moov_len;
5202 avio_rb32(pb); /* dcom atom */
5203 if (avio_rl32(pb) != MKTAG('d','c','o','m'))
5204 return AVERROR_INVALIDDATA;
5205 if (avio_rl32(pb) != MKTAG('z','l','i','b')) {
5206 av_log(c->fc, AV_LOG_ERROR, "unknown compression for cmov atom !\n");
5207 return AVERROR_INVALIDDATA;
5209 avio_rb32(pb); /* cmvd atom */
5210 if (avio_rl32(pb) != MKTAG('c','m','v','d'))
5211 return AVERROR_INVALIDDATA;
5212 moov_len = avio_rb32(pb); /* uncompressed size */
5213 cmov_len = atom.size - 6 * 4;
5215 cmov_data = av_malloc(cmov_len);
5217 return AVERROR(ENOMEM);
5218 moov_data = av_malloc(moov_len);
5221 return AVERROR(ENOMEM);
5223 ret = ffio_read_size(pb, cmov_data, cmov_len);
5225 goto free_and_return;
5227 ret = AVERROR_INVALIDDATA;
5228 if (uncompress (moov_data, (uLongf *) &moov_len, (const Bytef *)cmov_data, cmov_len) != Z_OK)
5229 goto free_and_return;
5230 if (ffio_init_context(&ctx, moov_data, moov_len, 0, NULL, NULL, NULL, NULL) != 0)
5231 goto free_and_return;
5232 ctx.seekable = AVIO_SEEKABLE_NORMAL;
5233 atom.type = MKTAG('m','o','o','v');
5234 atom.size = moov_len;
5235 ret = mov_read_default(c, &ctx, atom);
5241 av_log(c->fc, AV_LOG_ERROR, "this file requires zlib support compiled in\n");
5242 return AVERROR(ENOSYS);
5246 /* edit list atom */
5247 static int mov_read_elst(MOVContext *c, AVIOContext *pb, MOVAtom atom)
5249 MOVStreamContext *sc;
5250 int i, edit_count, version;
5251 int64_t elst_entry_size;
5253 if (c->fc->nb_streams < 1 || c->ignore_editlist)
5255 sc = c->fc->streams[c->fc->nb_streams-1]->priv_data;
5257 version = avio_r8(pb); /* version */
5258 avio_rb24(pb); /* flags */
5259 edit_count = avio_rb32(pb); /* entries */
5262 elst_entry_size = version == 1 ? 20 : 12;
5263 if (atom.size != edit_count * elst_entry_size) {
5264 if (c->fc->strict_std_compliance >= FF_COMPLIANCE_STRICT) {
5265 av_log(c->fc, AV_LOG_ERROR, "Invalid edit list entry_count: %d for elst atom of size: %"PRId64" bytes.\n",
5266 edit_count, atom.size + 8);
5267 return AVERROR_INVALIDDATA;
5269 edit_count = atom.size / elst_entry_size;
5270 if (edit_count * elst_entry_size != atom.size) {
5271 av_log(c->fc, AV_LOG_WARNING, "ELST atom of %"PRId64" bytes, bigger than %d entries.\n", atom.size, edit_count);
5279 av_log(c->fc, AV_LOG_WARNING, "Duplicated ELST atom\n");
5280 av_free(sc->elst_data);
5282 sc->elst_data = av_malloc_array(edit_count, sizeof(*sc->elst_data));
5284 return AVERROR(ENOMEM);
5286 av_log(c->fc, AV_LOG_TRACE, "track[%u].edit_count = %i\n", c->fc->nb_streams - 1, edit_count);
5287 for (i = 0; i < edit_count && atom.size > 0 && !pb->eof_reached; i++) {
5288 MOVElst *e = &sc->elst_data[i];
5291 e->duration = avio_rb64(pb);
5292 e->time = avio_rb64(pb);
5295 e->duration = avio_rb32(pb); /* segment duration */
5296 e->time = (int32_t)avio_rb32(pb); /* media time */
5299 e->rate = avio_rb32(pb) / 65536.0;
5301 av_log(c->fc, AV_LOG_TRACE, "duration=%"PRId64" time=%"PRId64" rate=%f\n",
5302 e->duration, e->time, e->rate);
5304 if (e->time < 0 && e->time != -1 &&
5305 c->fc->strict_std_compliance >= FF_COMPLIANCE_STRICT) {
5306 av_log(c->fc, AV_LOG_ERROR, "Track %d, edit %d: Invalid edit list media time=%"PRId64"\n",
5307 c->fc->nb_streams-1, i, e->time);
5308 return AVERROR_INVALIDDATA;
5316 static int mov_read_tmcd(MOVContext *c, AVIOContext *pb, MOVAtom atom)
5318 MOVStreamContext *sc;
5320 if (c->fc->nb_streams < 1)
5321 return AVERROR_INVALIDDATA;
5322 sc = c->fc->streams[c->fc->nb_streams - 1]->priv_data;
5323 sc->timecode_track = avio_rb32(pb);
5327 static int mov_read_av1c(MOVContext *c, AVIOContext *pb, MOVAtom atom)
5332 if (c->fc->nb_streams < 1)
5334 st = c->fc->streams[c->fc->nb_streams - 1];
5336 if (atom.size < 4) {
5337 av_log(c->fc, AV_LOG_ERROR, "Empty AV1 Codec Configuration Box\n");
5338 return AVERROR_INVALIDDATA;
5341 /* For now, propagate only the OBUs, if any. Once libavcodec is
5342 updated to handle isobmff style extradata this can be removed. */
5348 ret = ff_get_extradata(c->fc, st->codecpar, pb, atom.size - 4);
5355 static int mov_read_vpcc(MOVContext *c, AVIOContext *pb, MOVAtom atom)
5358 int version, color_range, color_primaries, color_trc, color_space;
5360 if (c->fc->nb_streams < 1)
5362 st = c->fc->streams[c->fc->nb_streams - 1];
5364 if (atom.size < 5) {
5365 av_log(c->fc, AV_LOG_ERROR, "Empty VP Codec Configuration box\n");
5366 return AVERROR_INVALIDDATA;
5369 version = avio_r8(pb);
5371 av_log(c->fc, AV_LOG_WARNING, "Unsupported VP Codec Configuration box version %d\n", version);
5374 avio_skip(pb, 3); /* flags */
5376 avio_skip(pb, 2); /* profile + level */
5377 color_range = avio_r8(pb); /* bitDepth, chromaSubsampling, videoFullRangeFlag */
5378 color_primaries = avio_r8(pb);
5379 color_trc = avio_r8(pb);
5380 color_space = avio_r8(pb);
5381 if (avio_rb16(pb)) /* codecIntializationDataSize */
5382 return AVERROR_INVALIDDATA;
5384 if (!av_color_primaries_name(color_primaries))
5385 color_primaries = AVCOL_PRI_UNSPECIFIED;
5386 if (!av_color_transfer_name(color_trc))
5387 color_trc = AVCOL_TRC_UNSPECIFIED;
5388 if (!av_color_space_name(color_space))
5389 color_space = AVCOL_SPC_UNSPECIFIED;
5391 st->codecpar->color_range = (color_range & 1) ? AVCOL_RANGE_JPEG : AVCOL_RANGE_MPEG;
5392 st->codecpar->color_primaries = color_primaries;
5393 st->codecpar->color_trc = color_trc;
5394 st->codecpar->color_space = color_space;
5399 static int mov_read_smdm(MOVContext *c, AVIOContext *pb, MOVAtom atom)
5401 MOVStreamContext *sc;
5404 if (c->fc->nb_streams < 1)
5405 return AVERROR_INVALIDDATA;
5407 sc = c->fc->streams[c->fc->nb_streams - 1]->priv_data;
5409 if (atom.size < 5) {
5410 av_log(c->fc, AV_LOG_ERROR, "Empty Mastering Display Metadata box\n");
5411 return AVERROR_INVALIDDATA;
5414 version = avio_r8(pb);
5416 av_log(c->fc, AV_LOG_WARNING, "Unsupported Mastering Display Metadata box version %d\n", version);
5419 avio_skip(pb, 3); /* flags */
5421 sc->mastering = av_mastering_display_metadata_alloc();
5423 return AVERROR(ENOMEM);
5425 for (i = 0; i < 3; i++) {
5426 sc->mastering->display_primaries[i][0] = av_make_q(avio_rb16(pb), 1 << 16);
5427 sc->mastering->display_primaries[i][1] = av_make_q(avio_rb16(pb), 1 << 16);
5429 sc->mastering->white_point[0] = av_make_q(avio_rb16(pb), 1 << 16);
5430 sc->mastering->white_point[1] = av_make_q(avio_rb16(pb), 1 << 16);
5432 sc->mastering->max_luminance = av_make_q(avio_rb32(pb), 1 << 8);
5433 sc->mastering->min_luminance = av_make_q(avio_rb32(pb), 1 << 14);
5435 sc->mastering->has_primaries = 1;
5436 sc->mastering->has_luminance = 1;
5441 static int mov_read_mdcv(MOVContext *c, AVIOContext *pb, MOVAtom atom)
5443 MOVStreamContext *sc;
5444 const int mapping[3] = {1, 2, 0};
5445 const int chroma_den = 50000;
5446 const int luma_den = 10000;
5449 if (c->fc->nb_streams < 1)
5450 return AVERROR_INVALIDDATA;
5452 sc = c->fc->streams[c->fc->nb_streams - 1]->priv_data;
5454 if (atom.size < 24) {
5455 av_log(c->fc, AV_LOG_ERROR, "Invalid Mastering Display Color Volume box\n");
5456 return AVERROR_INVALIDDATA;
5459 sc->mastering = av_mastering_display_metadata_alloc();
5461 return AVERROR(ENOMEM);
5463 for (i = 0; i < 3; i++) {
5464 const int j = mapping[i];
5465 sc->mastering->display_primaries[j][0] = av_make_q(avio_rb16(pb), chroma_den);
5466 sc->mastering->display_primaries[j][1] = av_make_q(avio_rb16(pb), chroma_den);
5468 sc->mastering->white_point[0] = av_make_q(avio_rb16(pb), chroma_den);
5469 sc->mastering->white_point[1] = av_make_q(avio_rb16(pb), chroma_den);
5471 sc->mastering->max_luminance = av_make_q(avio_rb32(pb), luma_den);
5472 sc->mastering->min_luminance = av_make_q(avio_rb32(pb), luma_den);
5474 sc->mastering->has_luminance = 1;
5475 sc->mastering->has_primaries = 1;
5480 static int mov_read_coll(MOVContext *c, AVIOContext *pb, MOVAtom atom)
5482 MOVStreamContext *sc;
5485 if (c->fc->nb_streams < 1)
5486 return AVERROR_INVALIDDATA;
5488 sc = c->fc->streams[c->fc->nb_streams - 1]->priv_data;
5490 if (atom.size < 5) {
5491 av_log(c->fc, AV_LOG_ERROR, "Empty Content Light Level box\n");
5492 return AVERROR_INVALIDDATA;
5495 version = avio_r8(pb);
5497 av_log(c->fc, AV_LOG_WARNING, "Unsupported Content Light Level box version %d\n", version);
5500 avio_skip(pb, 3); /* flags */
5502 sc->coll = av_content_light_metadata_alloc(&sc->coll_size);
5504 return AVERROR(ENOMEM);
5506 sc->coll->MaxCLL = avio_rb16(pb);
5507 sc->coll->MaxFALL = avio_rb16(pb);
5512 static int mov_read_clli(MOVContext *c, AVIOContext *pb, MOVAtom atom)
5514 MOVStreamContext *sc;
5516 if (c->fc->nb_streams < 1)
5517 return AVERROR_INVALIDDATA;
5519 sc = c->fc->streams[c->fc->nb_streams - 1]->priv_data;
5521 if (atom.size < 4) {
5522 av_log(c->fc, AV_LOG_ERROR, "Empty Content Light Level Info box\n");
5523 return AVERROR_INVALIDDATA;
5526 sc->coll = av_content_light_metadata_alloc(&sc->coll_size);
5528 return AVERROR(ENOMEM);
5530 sc->coll->MaxCLL = avio_rb16(pb);
5531 sc->coll->MaxFALL = avio_rb16(pb);
5536 static int mov_read_st3d(MOVContext *c, AVIOContext *pb, MOVAtom atom)
5539 MOVStreamContext *sc;
5540 enum AVStereo3DType type;
5543 if (c->fc->nb_streams < 1)
5546 st = c->fc->streams[c->fc->nb_streams - 1];
5549 if (atom.size < 5) {
5550 av_log(c->fc, AV_LOG_ERROR, "Empty stereoscopic video box\n");
5551 return AVERROR_INVALIDDATA;
5555 return AVERROR_INVALIDDATA;
5557 avio_skip(pb, 4); /* version + flags */
5562 type = AV_STEREO3D_2D;
5565 type = AV_STEREO3D_TOPBOTTOM;
5568 type = AV_STEREO3D_SIDEBYSIDE;
5571 av_log(c->fc, AV_LOG_WARNING, "Unknown st3d mode value %d\n", mode);
5575 sc->stereo3d = av_stereo3d_alloc();
5577 return AVERROR(ENOMEM);
5579 sc->stereo3d->type = type;
5583 static int mov_read_sv3d(MOVContext *c, AVIOContext *pb, MOVAtom atom)
5586 MOVStreamContext *sc;
5587 int size, version, layout;
5588 int32_t yaw, pitch, roll;
5589 uint32_t l = 0, t = 0, r = 0, b = 0;
5590 uint32_t tag, padding = 0;
5591 enum AVSphericalProjection projection;
5593 if (c->fc->nb_streams < 1)
5596 st = c->fc->streams[c->fc->nb_streams - 1];
5599 if (atom.size < 8) {
5600 av_log(c->fc, AV_LOG_ERROR, "Empty spherical video box\n");
5601 return AVERROR_INVALIDDATA;
5604 size = avio_rb32(pb);
5605 if (size <= 12 || size > atom.size)
5606 return AVERROR_INVALIDDATA;
5608 tag = avio_rl32(pb);
5609 if (tag != MKTAG('s','v','h','d')) {
5610 av_log(c->fc, AV_LOG_ERROR, "Missing spherical video header\n");
5613 version = avio_r8(pb);
5615 av_log(c->fc, AV_LOG_WARNING, "Unknown spherical version %d\n",
5619 avio_skip(pb, 3); /* flags */
5620 avio_skip(pb, size - 12); /* metadata_source */
5622 size = avio_rb32(pb);
5623 if (size > atom.size)
5624 return AVERROR_INVALIDDATA;
5626 tag = avio_rl32(pb);
5627 if (tag != MKTAG('p','r','o','j')) {
5628 av_log(c->fc, AV_LOG_ERROR, "Missing projection box\n");
5632 size = avio_rb32(pb);
5633 if (size > atom.size)
5634 return AVERROR_INVALIDDATA;
5636 tag = avio_rl32(pb);
5637 if (tag != MKTAG('p','r','h','d')) {
5638 av_log(c->fc, AV_LOG_ERROR, "Missing projection header box\n");
5641 version = avio_r8(pb);
5643 av_log(c->fc, AV_LOG_WARNING, "Unknown spherical version %d\n",
5647 avio_skip(pb, 3); /* flags */
5649 /* 16.16 fixed point */
5650 yaw = avio_rb32(pb);
5651 pitch = avio_rb32(pb);
5652 roll = avio_rb32(pb);
5654 size = avio_rb32(pb);
5655 if (size > atom.size)
5656 return AVERROR_INVALIDDATA;
5658 tag = avio_rl32(pb);
5659 version = avio_r8(pb);
5661 av_log(c->fc, AV_LOG_WARNING, "Unknown spherical version %d\n",
5665 avio_skip(pb, 3); /* flags */
5667 case MKTAG('c','b','m','p'):
5668 layout = avio_rb32(pb);
5670 av_log(c->fc, AV_LOG_WARNING,
5671 "Unsupported cubemap layout %d\n", layout);
5674 projection = AV_SPHERICAL_CUBEMAP;
5675 padding = avio_rb32(pb);
5677 case MKTAG('e','q','u','i'):
5683 if (b >= UINT_MAX - t || r >= UINT_MAX - l) {
5684 av_log(c->fc, AV_LOG_ERROR,
5685 "Invalid bounding rectangle coordinates "
5686 "%"PRIu32",%"PRIu32",%"PRIu32",%"PRIu32"\n", l, t, r, b);
5687 return AVERROR_INVALIDDATA;
5690 if (l || t || r || b)
5691 projection = AV_SPHERICAL_EQUIRECTANGULAR_TILE;
5693 projection = AV_SPHERICAL_EQUIRECTANGULAR;
5696 av_log(c->fc, AV_LOG_ERROR, "Unknown projection type: %s\n", av_fourcc2str(tag));
5700 sc->spherical = av_spherical_alloc(&sc->spherical_size);
5702 return AVERROR(ENOMEM);
5704 sc->spherical->projection = projection;
5706 sc->spherical->yaw = yaw;
5707 sc->spherical->pitch = pitch;
5708 sc->spherical->roll = roll;
5710 sc->spherical->padding = padding;
5712 sc->spherical->bound_left = l;
5713 sc->spherical->bound_top = t;
5714 sc->spherical->bound_right = r;
5715 sc->spherical->bound_bottom = b;
5720 static int mov_parse_uuid_spherical(MOVStreamContext *sc, AVIOContext *pb, size_t len)
5723 uint8_t *buffer = av_malloc(len + 1);
5727 return AVERROR(ENOMEM);
5730 ret = ffio_read_size(pb, buffer, len);
5734 /* Check for mandatory keys and values, try to support XML as best-effort */
5735 if (!sc->spherical &&
5736 av_stristr(buffer, "<GSpherical:StitchingSoftware>") &&
5737 (val = av_stristr(buffer, "<GSpherical:Spherical>")) &&
5738 av_stristr(val, "true") &&
5739 (val = av_stristr(buffer, "<GSpherical:Stitched>")) &&
5740 av_stristr(val, "true") &&
5741 (val = av_stristr(buffer, "<GSpherical:ProjectionType>")) &&
5742 av_stristr(val, "equirectangular")) {
5743 sc->spherical = av_spherical_alloc(&sc->spherical_size);
5747 sc->spherical->projection = AV_SPHERICAL_EQUIRECTANGULAR;
5749 if (av_stristr(buffer, "<GSpherical:StereoMode>") && !sc->stereo3d) {
5750 enum AVStereo3DType mode;
5752 if (av_stristr(buffer, "left-right"))
5753 mode = AV_STEREO3D_SIDEBYSIDE;
5754 else if (av_stristr(buffer, "top-bottom"))
5755 mode = AV_STEREO3D_TOPBOTTOM;
5757 mode = AV_STEREO3D_2D;
5759 sc->stereo3d = av_stereo3d_alloc();
5763 sc->stereo3d->type = mode;
5767 val = av_stristr(buffer, "<GSpherical:InitialViewHeadingDegrees>");
5769 sc->spherical->yaw = strtol(val, NULL, 10) * (1 << 16);
5770 val = av_stristr(buffer, "<GSpherical:InitialViewPitchDegrees>");
5772 sc->spherical->pitch = strtol(val, NULL, 10) * (1 << 16);
5773 val = av_stristr(buffer, "<GSpherical:InitialViewRollDegrees>");
5775 sc->spherical->roll = strtol(val, NULL, 10) * (1 << 16);
5783 static int mov_read_uuid(MOVContext *c, AVIOContext *pb, MOVAtom atom)
5786 MOVStreamContext *sc;
5789 static const uint8_t uuid_isml_manifest[] = {
5790 0xa5, 0xd4, 0x0b, 0x30, 0xe8, 0x14, 0x11, 0xdd,
5791 0xba, 0x2f, 0x08, 0x00, 0x20, 0x0c, 0x9a, 0x66
5793 static const uint8_t uuid_xmp[] = {
5794 0xbe, 0x7a, 0xcf, 0xcb, 0x97, 0xa9, 0x42, 0xe8,
5795 0x9c, 0x71, 0x99, 0x94, 0x91, 0xe3, 0xaf, 0xac
5797 static const uint8_t uuid_spherical[] = {
5798 0xff, 0xcc, 0x82, 0x63, 0xf8, 0x55, 0x4a, 0x93,
5799 0x88, 0x14, 0x58, 0x7a, 0x02, 0x52, 0x1f, 0xdd,
5802 if (atom.size < sizeof(uuid) || atom.size >= FFMIN(INT_MAX, SIZE_MAX))
5803 return AVERROR_INVALIDDATA;
5805 if (c->fc->nb_streams < 1)
5807 st = c->fc->streams[c->fc->nb_streams - 1];
5810 ret = ffio_read_size(pb, uuid, sizeof(uuid));
5813 if (!memcmp(uuid, uuid_isml_manifest, sizeof(uuid))) {
5814 uint8_t *buffer, *ptr;
5816 size_t len = atom.size - sizeof(uuid);
5819 return AVERROR_INVALIDDATA;
5821 ret = avio_skip(pb, 4); // zeroes
5824 buffer = av_mallocz(len + 1);
5826 return AVERROR(ENOMEM);
5828 ret = ffio_read_size(pb, buffer, len);
5835 while ((ptr = av_stristr(ptr, "systemBitrate=\""))) {
5836 ptr += sizeof("systemBitrate=\"") - 1;
5837 c->bitrates_count++;
5838 c->bitrates = av_realloc_f(c->bitrates, c->bitrates_count, sizeof(*c->bitrates));
5840 c->bitrates_count = 0;
5842 return AVERROR(ENOMEM);
5845 ret = strtol(ptr, &endptr, 10);
5846 if (ret < 0 || errno || *endptr != '"') {
5847 c->bitrates[c->bitrates_count - 1] = 0;
5849 c->bitrates[c->bitrates_count - 1] = ret;
5854 } else if (!memcmp(uuid, uuid_xmp, sizeof(uuid))) {
5856 size_t len = atom.size - sizeof(uuid);
5857 if (c->export_xmp) {
5858 buffer = av_mallocz(len + 1);
5860 return AVERROR(ENOMEM);
5862 ret = ffio_read_size(pb, buffer, len);
5868 av_dict_set(&c->fc->metadata, "xmp",
5869 buffer, AV_DICT_DONT_STRDUP_VAL);
5871 // skip all uuid atom, which makes it fast for long uuid-xmp file
5872 ret = avio_skip(pb, len);
5876 } else if (!memcmp(uuid, uuid_spherical, sizeof(uuid))) {
5877 size_t len = atom.size - sizeof(uuid);
5878 ret = mov_parse_uuid_spherical(sc, pb, len);
5882 av_log(c->fc, AV_LOG_WARNING, "Invalid spherical metadata found\n");
5888 static int mov_read_free(MOVContext *c, AVIOContext *pb, MOVAtom atom)
5891 uint8_t content[16];
5896 ret = avio_read(pb, content, FFMIN(sizeof(content), atom.size));
5902 && !memcmp(content, "Anevia\x1A\x1A", 8)
5903 && c->use_mfra_for == FF_MOV_FLAG_MFRA_AUTO) {
5904 c->use_mfra_for = FF_MOV_FLAG_MFRA_PTS;
5910 static int mov_read_frma(MOVContext *c, AVIOContext *pb, MOVAtom atom)
5912 uint32_t format = avio_rl32(pb);
5913 MOVStreamContext *sc;
5917 if (c->fc->nb_streams < 1)
5919 st = c->fc->streams[c->fc->nb_streams - 1];
5924 case MKTAG('e','n','c','v'): // encrypted video
5925 case MKTAG('e','n','c','a'): // encrypted audio
5926 id = mov_codec_id(st, format);
5927 if (st->codecpar->codec_id != AV_CODEC_ID_NONE &&
5928 st->codecpar->codec_id != id) {
5929 av_log(c->fc, AV_LOG_WARNING,
5930 "ignoring 'frma' atom of '%.4s', stream has codec id %d\n",
5931 (char*)&format, st->codecpar->codec_id);
5935 st->codecpar->codec_id = id;
5936 sc->format = format;
5940 if (format != sc->format) {
5941 av_log(c->fc, AV_LOG_WARNING,
5942 "ignoring 'frma' atom of '%.4s', stream format is '%.4s'\n",
5943 (char*)&format, (char*)&sc->format);
5952 * Gets the current encryption info and associated current stream context. If
5953 * we are parsing a track fragment, this will return the specific encryption
5954 * info for this fragment; otherwise this will return the global encryption
5955 * info for the current stream.
5957 static int get_current_encryption_info(MOVContext *c, MOVEncryptionIndex **encryption_index, MOVStreamContext **sc)
5959 MOVFragmentStreamInfo *frag_stream_info;
5963 frag_stream_info = get_current_frag_stream_info(&c->frag_index);
5964 if (frag_stream_info) {
5965 for (i = 0; i < c->fc->nb_streams; i++) {
5966 if (c->fc->streams[i]->id == frag_stream_info->id) {
5967 st = c->fc->streams[i];
5971 if (i == c->fc->nb_streams)
5973 *sc = st->priv_data;
5975 if (!frag_stream_info->encryption_index) {
5976 // If this stream isn't encrypted, don't create the index.
5977 if (!(*sc)->cenc.default_encrypted_sample)
5979 frag_stream_info->encryption_index = av_mallocz(sizeof(*frag_stream_info->encryption_index));
5980 if (!frag_stream_info->encryption_index)
5981 return AVERROR(ENOMEM);
5983 *encryption_index = frag_stream_info->encryption_index;
5986 // No current track fragment, using stream level encryption info.
5988 if (c->fc->nb_streams < 1)
5990 st = c->fc->streams[c->fc->nb_streams - 1];
5991 *sc = st->priv_data;
5993 if (!(*sc)->cenc.encryption_index) {
5994 // If this stream isn't encrypted, don't create the index.
5995 if (!(*sc)->cenc.default_encrypted_sample)
5997 (*sc)->cenc.encryption_index = av_mallocz(sizeof(*frag_stream_info->encryption_index));
5998 if (!(*sc)->cenc.encryption_index)
5999 return AVERROR(ENOMEM);
6002 *encryption_index = (*sc)->cenc.encryption_index;
6007 static int mov_read_sample_encryption_info(MOVContext *c, AVIOContext *pb, MOVStreamContext *sc, AVEncryptionInfo **sample, int use_subsamples)
6010 unsigned int subsample_count;
6011 AVSubsampleEncryptionInfo *subsamples;
6013 if (!sc->cenc.default_encrypted_sample) {
6014 av_log(c->fc, AV_LOG_ERROR, "Missing schm or tenc\n");
6015 return AVERROR_INVALIDDATA;
6018 *sample = av_encryption_info_clone(sc->cenc.default_encrypted_sample);
6020 return AVERROR(ENOMEM);
6022 if (sc->cenc.per_sample_iv_size != 0) {
6023 if ((ret = ffio_read_size(pb, (*sample)->iv, sc->cenc.per_sample_iv_size)) < 0) {
6024 av_log(c->fc, AV_LOG_ERROR, "failed to read the initialization vector\n");
6025 av_encryption_info_free(*sample);
6031 if (use_subsamples) {
6032 subsample_count = avio_rb16(pb);
6033 av_free((*sample)->subsamples);
6034 (*sample)->subsamples = av_mallocz_array(subsample_count, sizeof(*subsamples));
6035 if (!(*sample)->subsamples) {
6036 av_encryption_info_free(*sample);
6038 return AVERROR(ENOMEM);
6041 for (i = 0; i < subsample_count && !pb->eof_reached; i++) {
6042 (*sample)->subsamples[i].bytes_of_clear_data = avio_rb16(pb);
6043 (*sample)->subsamples[i].bytes_of_protected_data = avio_rb32(pb);
6046 if (pb->eof_reached) {
6047 av_log(c->fc, AV_LOG_ERROR, "hit EOF while reading sub-sample encryption info\n");
6048 av_encryption_info_free(*sample);
6050 return AVERROR_INVALIDDATA;
6052 (*sample)->subsample_count = subsample_count;
6058 static int mov_read_senc(MOVContext *c, AVIOContext *pb, MOVAtom atom)
6060 AVEncryptionInfo **encrypted_samples;
6061 MOVEncryptionIndex *encryption_index;
6062 MOVStreamContext *sc;
6063 int use_subsamples, ret;
6064 unsigned int sample_count, i, alloc_size = 0;
6066 ret = get_current_encryption_info(c, &encryption_index, &sc);
6070 if (encryption_index->nb_encrypted_samples) {
6071 // This can happen if we have both saio/saiz and senc atoms.
6072 av_log(c->fc, AV_LOG_DEBUG, "Ignoring duplicate encryption info in senc\n");
6076 avio_r8(pb); /* version */
6077 use_subsamples = avio_rb24(pb) & 0x02; /* flags */
6079 sample_count = avio_rb32(pb);
6080 if (sample_count >= INT_MAX / sizeof(*encrypted_samples))
6081 return AVERROR(ENOMEM);
6083 for (i = 0; i < sample_count; i++) {
6084 unsigned int min_samples = FFMIN(FFMAX(i + 1, 1024 * 1024), sample_count);
6085 encrypted_samples = av_fast_realloc(encryption_index->encrypted_samples, &alloc_size,
6086 min_samples * sizeof(*encrypted_samples));
6087 if (encrypted_samples) {
6088 encryption_index->encrypted_samples = encrypted_samples;
6090 ret = mov_read_sample_encryption_info(
6091 c, pb, sc, &encryption_index->encrypted_samples[i], use_subsamples);
6093 ret = AVERROR(ENOMEM);
6095 if (pb->eof_reached) {
6096 av_log(c->fc, AV_LOG_ERROR, "Hit EOF while reading senc\n");
6097 ret = AVERROR_INVALIDDATA;
6102 av_encryption_info_free(encryption_index->encrypted_samples[i - 1]);
6103 av_freep(&encryption_index->encrypted_samples);
6107 encryption_index->nb_encrypted_samples = sample_count;
6112 static int mov_parse_auxiliary_info(MOVContext *c, MOVStreamContext *sc, AVIOContext *pb, MOVEncryptionIndex *encryption_index)
6114 AVEncryptionInfo **sample, **encrypted_samples;
6116 size_t sample_count, sample_info_size, i;
6118 unsigned int alloc_size = 0;
6120 if (encryption_index->nb_encrypted_samples)
6122 sample_count = encryption_index->auxiliary_info_sample_count;
6123 if (encryption_index->auxiliary_offsets_count != 1) {
6124 av_log(c->fc, AV_LOG_ERROR, "Multiple auxiliary info chunks are not supported\n");
6125 return AVERROR_PATCHWELCOME;
6127 if (sample_count >= INT_MAX / sizeof(*encrypted_samples))
6128 return AVERROR(ENOMEM);
6130 prev_pos = avio_tell(pb);
6131 if (!(pb->seekable & AVIO_SEEKABLE_NORMAL) ||
6132 avio_seek(pb, encryption_index->auxiliary_offsets[0], SEEK_SET) != encryption_index->auxiliary_offsets[0]) {
6133 av_log(c->fc, AV_LOG_INFO, "Failed to seek for auxiliary info, will only parse senc atoms for encryption info\n");
6137 for (i = 0; i < sample_count && !pb->eof_reached; i++) {
6138 unsigned int min_samples = FFMIN(FFMAX(i + 1, 1024 * 1024), sample_count);
6139 encrypted_samples = av_fast_realloc(encryption_index->encrypted_samples, &alloc_size,
6140 min_samples * sizeof(*encrypted_samples));
6141 if (!encrypted_samples) {
6142 ret = AVERROR(ENOMEM);
6145 encryption_index->encrypted_samples = encrypted_samples;
6147 sample = &encryption_index->encrypted_samples[i];
6148 sample_info_size = encryption_index->auxiliary_info_default_size
6149 ? encryption_index->auxiliary_info_default_size
6150 : encryption_index->auxiliary_info_sizes[i];
6152 ret = mov_read_sample_encryption_info(c, pb, sc, sample, sample_info_size > sc->cenc.per_sample_iv_size);
6156 if (pb->eof_reached) {
6157 av_log(c->fc, AV_LOG_ERROR, "Hit EOF while reading auxiliary info\n");
6158 ret = AVERROR_INVALIDDATA;
6160 encryption_index->nb_encrypted_samples = sample_count;
6164 avio_seek(pb, prev_pos, SEEK_SET);
6166 for (; i > 0; i--) {
6167 av_encryption_info_free(encryption_index->encrypted_samples[i - 1]);
6169 av_freep(&encryption_index->encrypted_samples);
6175 * Tries to read the given number of bytes from the stream and puts it in a
6176 * newly allocated buffer. This reads in small chunks to avoid allocating large
6177 * memory if the file contains an invalid/malicious size value.
6179 static int mov_try_read_block(AVIOContext *pb, size_t size, uint8_t **data)
6181 const unsigned int block_size = 1024 * 1024;
6182 uint8_t *buffer = NULL;
6183 unsigned int alloc_size = 0, offset = 0;
6184 while (offset < size) {
6185 unsigned int new_size =
6186 alloc_size >= INT_MAX - block_size ? INT_MAX : alloc_size + block_size;
6187 uint8_t *new_buffer = av_fast_realloc(buffer, &alloc_size, new_size);
6188 unsigned int to_read = FFMIN(size, alloc_size) - offset;
6191 return AVERROR(ENOMEM);
6193 buffer = new_buffer;
6195 if (avio_read(pb, buffer + offset, to_read) != to_read) {
6197 return AVERROR_INVALIDDATA;
6206 static int mov_read_saiz(MOVContext *c, AVIOContext *pb, MOVAtom atom)
6208 MOVEncryptionIndex *encryption_index;
6209 MOVStreamContext *sc;
6211 unsigned int sample_count, aux_info_type, aux_info_param;
6213 ret = get_current_encryption_info(c, &encryption_index, &sc);
6217 if (encryption_index->nb_encrypted_samples) {
6218 // This can happen if we have both saio/saiz and senc atoms.
6219 av_log(c->fc, AV_LOG_DEBUG, "Ignoring duplicate encryption info in saiz\n");
6223 if (encryption_index->auxiliary_info_sample_count) {
6224 av_log(c->fc, AV_LOG_ERROR, "Duplicate saiz atom\n");
6225 return AVERROR_INVALIDDATA;
6228 avio_r8(pb); /* version */
6229 if (avio_rb24(pb) & 0x01) { /* flags */
6230 aux_info_type = avio_rb32(pb);
6231 aux_info_param = avio_rb32(pb);
6232 if (sc->cenc.default_encrypted_sample) {
6233 if (aux_info_type != sc->cenc.default_encrypted_sample->scheme) {
6234 av_log(c->fc, AV_LOG_DEBUG, "Ignoring saiz box with non-zero aux_info_type\n");
6237 if (aux_info_param != 0) {
6238 av_log(c->fc, AV_LOG_DEBUG, "Ignoring saiz box with non-zero aux_info_type_parameter\n");
6242 // Didn't see 'schm' or 'tenc', so this isn't encrypted.
6243 if ((aux_info_type == MKBETAG('c','e','n','c') ||
6244 aux_info_type == MKBETAG('c','e','n','s') ||
6245 aux_info_type == MKBETAG('c','b','c','1') ||
6246 aux_info_type == MKBETAG('c','b','c','s')) &&
6247 aux_info_param == 0) {
6248 av_log(c->fc, AV_LOG_ERROR, "Saw encrypted saiz without schm/tenc\n");
6249 return AVERROR_INVALIDDATA;
6254 } else if (!sc->cenc.default_encrypted_sample) {
6255 // Didn't see 'schm' or 'tenc', so this isn't encrypted.
6259 encryption_index->auxiliary_info_default_size = avio_r8(pb);
6260 sample_count = avio_rb32(pb);
6261 encryption_index->auxiliary_info_sample_count = sample_count;
6263 if (encryption_index->auxiliary_info_default_size == 0) {
6264 ret = mov_try_read_block(pb, sample_count, &encryption_index->auxiliary_info_sizes);
6266 av_log(c->fc, AV_LOG_ERROR, "Failed to read the auxiliary info\n");
6271 if (encryption_index->auxiliary_offsets_count) {
6272 return mov_parse_auxiliary_info(c, sc, pb, encryption_index);
6278 static int mov_read_saio(MOVContext *c, AVIOContext *pb, MOVAtom atom)
6280 uint64_t *auxiliary_offsets;
6281 MOVEncryptionIndex *encryption_index;
6282 MOVStreamContext *sc;
6284 unsigned int version, entry_count, aux_info_type, aux_info_param;
6285 unsigned int alloc_size = 0;
6287 ret = get_current_encryption_info(c, &encryption_index, &sc);
6291 if (encryption_index->nb_encrypted_samples) {
6292 // This can happen if we have both saio/saiz and senc atoms.
6293 av_log(c->fc, AV_LOG_DEBUG, "Ignoring duplicate encryption info in saio\n");
6297 if (encryption_index->auxiliary_offsets_count) {
6298 av_log(c->fc, AV_LOG_ERROR, "Duplicate saio atom\n");
6299 return AVERROR_INVALIDDATA;
6302 version = avio_r8(pb); /* version */
6303 if (avio_rb24(pb) & 0x01) { /* flags */
6304 aux_info_type = avio_rb32(pb);
6305 aux_info_param = avio_rb32(pb);
6306 if (sc->cenc.default_encrypted_sample) {
6307 if (aux_info_type != sc->cenc.default_encrypted_sample->scheme) {
6308 av_log(c->fc, AV_LOG_DEBUG, "Ignoring saio box with non-zero aux_info_type\n");
6311 if (aux_info_param != 0) {
6312 av_log(c->fc, AV_LOG_DEBUG, "Ignoring saio box with non-zero aux_info_type_parameter\n");
6316 // Didn't see 'schm' or 'tenc', so this isn't encrypted.
6317 if ((aux_info_type == MKBETAG('c','e','n','c') ||
6318 aux_info_type == MKBETAG('c','e','n','s') ||
6319 aux_info_type == MKBETAG('c','b','c','1') ||
6320 aux_info_type == MKBETAG('c','b','c','s')) &&
6321 aux_info_param == 0) {
6322 av_log(c->fc, AV_LOG_ERROR, "Saw encrypted saio without schm/tenc\n");
6323 return AVERROR_INVALIDDATA;
6328 } else if (!sc->cenc.default_encrypted_sample) {
6329 // Didn't see 'schm' or 'tenc', so this isn't encrypted.
6333 entry_count = avio_rb32(pb);
6334 if (entry_count >= INT_MAX / sizeof(*auxiliary_offsets))
6335 return AVERROR(ENOMEM);
6337 for (i = 0; i < entry_count && !pb->eof_reached; i++) {
6338 unsigned int min_offsets = FFMIN(FFMAX(i + 1, 1024), entry_count);
6339 auxiliary_offsets = av_fast_realloc(
6340 encryption_index->auxiliary_offsets, &alloc_size,
6341 min_offsets * sizeof(*auxiliary_offsets));
6342 if (!auxiliary_offsets) {
6343 av_freep(&encryption_index->auxiliary_offsets);
6344 return AVERROR(ENOMEM);
6346 encryption_index->auxiliary_offsets = auxiliary_offsets;
6349 encryption_index->auxiliary_offsets[i] = avio_rb32(pb);
6351 encryption_index->auxiliary_offsets[i] = avio_rb64(pb);
6353 if (c->frag_index.current >= 0) {
6354 encryption_index->auxiliary_offsets[i] += c->fragment.base_data_offset;
6358 if (pb->eof_reached) {
6359 av_log(c->fc, AV_LOG_ERROR, "Hit EOF while reading saio\n");
6360 av_freep(&encryption_index->auxiliary_offsets);
6361 return AVERROR_INVALIDDATA;
6364 encryption_index->auxiliary_offsets_count = entry_count;
6366 if (encryption_index->auxiliary_info_sample_count) {
6367 return mov_parse_auxiliary_info(c, sc, pb, encryption_index);
6373 static int mov_read_pssh(MOVContext *c, AVIOContext *pb, MOVAtom atom)
6375 AVEncryptionInitInfo *info, *old_init_info;
6378 uint8_t *side_data, *extra_data, *old_side_data;
6379 size_t side_data_size;
6380 buffer_size_t old_side_data_size;
6382 unsigned int version, kid_count, extra_data_size, alloc_size = 0;
6384 if (c->fc->nb_streams < 1)
6386 st = c->fc->streams[c->fc->nb_streams-1];
6388 version = avio_r8(pb); /* version */
6389 avio_rb24(pb); /* flags */
6391 info = av_encryption_init_info_alloc(/* system_id_size */ 16, /* num_key_ids */ 0,
6392 /* key_id_size */ 16, /* data_size */ 0);
6394 return AVERROR(ENOMEM);
6396 if ((ret = ffio_read_size(pb, info->system_id, 16)) < 0) {
6397 av_log(c->fc, AV_LOG_ERROR, "Failed to read the system id\n");
6402 kid_count = avio_rb32(pb);
6403 if (kid_count >= INT_MAX / sizeof(*key_ids)) {
6404 ret = AVERROR(ENOMEM);
6408 for (unsigned int i = 0; i < kid_count && !pb->eof_reached; i++) {
6409 unsigned int min_kid_count = FFMIN(FFMAX(i + 1, 1024), kid_count);
6410 key_ids = av_fast_realloc(info->key_ids, &alloc_size,
6411 min_kid_count * sizeof(*key_ids));
6413 ret = AVERROR(ENOMEM);
6416 info->key_ids = key_ids;
6418 info->key_ids[i] = av_mallocz(16);
6419 if (!info->key_ids[i]) {
6420 ret = AVERROR(ENOMEM);
6423 info->num_key_ids = i + 1;
6425 if ((ret = ffio_read_size(pb, info->key_ids[i], 16)) < 0) {
6426 av_log(c->fc, AV_LOG_ERROR, "Failed to read the key id\n");
6431 if (pb->eof_reached) {
6432 av_log(c->fc, AV_LOG_ERROR, "Hit EOF while reading pssh\n");
6433 ret = AVERROR_INVALIDDATA;
6438 extra_data_size = avio_rb32(pb);
6439 ret = mov_try_read_block(pb, extra_data_size, &extra_data);
6443 av_freep(&info->data); // malloc(0) may still allocate something.
6444 info->data = extra_data;
6445 info->data_size = extra_data_size;
6447 // If there is existing initialization data, append to the list.
6448 old_side_data = av_stream_get_side_data(st, AV_PKT_DATA_ENCRYPTION_INIT_INFO, &old_side_data_size);
6449 if (old_side_data) {
6450 old_init_info = av_encryption_init_info_get_side_data(old_side_data, old_side_data_size);
6451 if (old_init_info) {
6452 // Append to the end of the list.
6453 for (AVEncryptionInitInfo *cur = old_init_info;; cur = cur->next) {
6459 info = old_init_info;
6461 // Assume existing side-data will be valid, so the only error we could get is OOM.
6462 ret = AVERROR(ENOMEM);
6467 side_data = av_encryption_init_info_add_side_data(info, &side_data_size);
6469 ret = AVERROR(ENOMEM);
6472 ret = av_stream_add_side_data(st, AV_PKT_DATA_ENCRYPTION_INIT_INFO,
6473 side_data, side_data_size);
6478 av_encryption_init_info_free(info);
6482 static int mov_read_schm(MOVContext *c, AVIOContext *pb, MOVAtom atom)
6485 MOVStreamContext *sc;
6487 if (c->fc->nb_streams < 1)
6489 st = c->fc->streams[c->fc->nb_streams-1];
6492 if (sc->pseudo_stream_id != 0) {
6493 av_log(c->fc, AV_LOG_ERROR, "schm boxes are only supported in first sample descriptor\n");
6494 return AVERROR_PATCHWELCOME;
6498 return AVERROR_INVALIDDATA;
6500 avio_rb32(pb); /* version and flags */
6502 if (!sc->cenc.default_encrypted_sample) {
6503 sc->cenc.default_encrypted_sample = av_encryption_info_alloc(0, 16, 16);
6504 if (!sc->cenc.default_encrypted_sample) {
6505 return AVERROR(ENOMEM);
6509 sc->cenc.default_encrypted_sample->scheme = avio_rb32(pb);
6513 static int mov_read_tenc(MOVContext *c, AVIOContext *pb, MOVAtom atom)
6516 MOVStreamContext *sc;
6517 unsigned int version, pattern, is_protected, iv_size;
6519 if (c->fc->nb_streams < 1)
6521 st = c->fc->streams[c->fc->nb_streams-1];
6524 if (sc->pseudo_stream_id != 0) {
6525 av_log(c->fc, AV_LOG_ERROR, "tenc atom are only supported in first sample descriptor\n");
6526 return AVERROR_PATCHWELCOME;
6529 if (!sc->cenc.default_encrypted_sample) {
6530 sc->cenc.default_encrypted_sample = av_encryption_info_alloc(0, 16, 16);
6531 if (!sc->cenc.default_encrypted_sample) {
6532 return AVERROR(ENOMEM);
6537 return AVERROR_INVALIDDATA;
6539 version = avio_r8(pb); /* version */
6540 avio_rb24(pb); /* flags */
6542 avio_r8(pb); /* reserved */
6543 pattern = avio_r8(pb);
6546 sc->cenc.default_encrypted_sample->crypt_byte_block = pattern >> 4;
6547 sc->cenc.default_encrypted_sample->skip_byte_block = pattern & 0xf;
6550 is_protected = avio_r8(pb);
6551 if (is_protected && !sc->cenc.encryption_index) {
6552 // The whole stream should be by-default encrypted.
6553 sc->cenc.encryption_index = av_mallocz(sizeof(MOVEncryptionIndex));
6554 if (!sc->cenc.encryption_index)
6555 return AVERROR(ENOMEM);
6557 sc->cenc.per_sample_iv_size = avio_r8(pb);
6558 if (sc->cenc.per_sample_iv_size != 0 && sc->cenc.per_sample_iv_size != 8 &&
6559 sc->cenc.per_sample_iv_size != 16) {
6560 av_log(c->fc, AV_LOG_ERROR, "invalid per-sample IV size value\n");
6561 return AVERROR_INVALIDDATA;
6563 if (avio_read(pb, sc->cenc.default_encrypted_sample->key_id, 16) != 16) {
6564 av_log(c->fc, AV_LOG_ERROR, "failed to read the default key ID\n");
6565 return AVERROR_INVALIDDATA;
6568 if (is_protected && !sc->cenc.per_sample_iv_size) {
6569 iv_size = avio_r8(pb);
6570 if (iv_size != 8 && iv_size != 16) {
6571 av_log(c->fc, AV_LOG_ERROR, "invalid default_constant_IV_size in tenc atom\n");
6572 return AVERROR_INVALIDDATA;
6575 if (avio_read(pb, sc->cenc.default_encrypted_sample->iv, iv_size) != iv_size) {
6576 av_log(c->fc, AV_LOG_ERROR, "failed to read the default IV\n");
6577 return AVERROR_INVALIDDATA;
6584 static int mov_read_dfla(MOVContext *c, AVIOContext *pb, MOVAtom atom)
6587 int last, type, size, ret;
6590 if (c->fc->nb_streams < 1)
6592 st = c->fc->streams[c->fc->nb_streams-1];
6594 if ((uint64_t)atom.size > (1<<30) || atom.size < 42)
6595 return AVERROR_INVALIDDATA;
6597 /* Check FlacSpecificBox version. */
6598 if (avio_r8(pb) != 0)
6599 return AVERROR_INVALIDDATA;
6601 avio_rb24(pb); /* Flags */
6603 avio_read(pb, buf, sizeof(buf));
6604 flac_parse_block_header(buf, &last, &type, &size);
6606 if (type != FLAC_METADATA_TYPE_STREAMINFO || size != FLAC_STREAMINFO_SIZE) {
6607 av_log(c->fc, AV_LOG_ERROR, "STREAMINFO must be first FLACMetadataBlock\n");
6608 return AVERROR_INVALIDDATA;
6611 ret = ff_get_extradata(c->fc, st->codecpar, pb, size);
6616 av_log(c->fc, AV_LOG_WARNING, "non-STREAMINFO FLACMetadataBlock(s) ignored\n");
6621 static int cenc_decrypt(MOVContext *c, MOVStreamContext *sc, AVEncryptionInfo *sample, uint8_t *input, int size)
6625 if (sample->scheme != MKBETAG('c','e','n','c') || sample->crypt_byte_block != 0 || sample->skip_byte_block != 0) {
6626 av_log(c->fc, AV_LOG_ERROR, "Only the 'cenc' encryption scheme is supported\n");
6627 return AVERROR_PATCHWELCOME;
6630 if (!sc->cenc.aes_ctr) {
6631 /* initialize the cipher */
6632 sc->cenc.aes_ctr = av_aes_ctr_alloc();
6633 if (!sc->cenc.aes_ctr) {
6634 return AVERROR(ENOMEM);
6637 ret = av_aes_ctr_init(sc->cenc.aes_ctr, c->decryption_key);
6643 av_aes_ctr_set_full_iv(sc->cenc.aes_ctr, sample->iv);
6645 if (!sample->subsample_count) {
6646 /* decrypt the whole packet */
6647 av_aes_ctr_crypt(sc->cenc.aes_ctr, input, input, size);
6651 for (i = 0; i < sample->subsample_count; i++) {
6652 if (sample->subsamples[i].bytes_of_clear_data + sample->subsamples[i].bytes_of_protected_data > size) {
6653 av_log(c->fc, AV_LOG_ERROR, "subsample size exceeds the packet size left\n");
6654 return AVERROR_INVALIDDATA;
6657 /* skip the clear bytes */
6658 input += sample->subsamples[i].bytes_of_clear_data;
6659 size -= sample->subsamples[i].bytes_of_clear_data;
6661 /* decrypt the encrypted bytes */
6662 av_aes_ctr_crypt(sc->cenc.aes_ctr, input, input, sample->subsamples[i].bytes_of_protected_data);
6663 input += sample->subsamples[i].bytes_of_protected_data;
6664 size -= sample->subsamples[i].bytes_of_protected_data;
6668 av_log(c->fc, AV_LOG_ERROR, "leftover packet bytes after subsample processing\n");
6669 return AVERROR_INVALIDDATA;
6675 static int cenc_filter(MOVContext *mov, AVStream* st, MOVStreamContext *sc, AVPacket *pkt, int current_index)
6677 MOVFragmentStreamInfo *frag_stream_info;
6678 MOVEncryptionIndex *encryption_index;
6679 AVEncryptionInfo *encrypted_sample;
6680 int encrypted_index, ret;
6682 frag_stream_info = get_frag_stream_info(&mov->frag_index, mov->frag_index.current, st->id);
6683 encrypted_index = current_index;
6684 encryption_index = NULL;
6685 if (frag_stream_info) {
6686 // Note this only supports encryption info in the first sample descriptor.
6687 if (mov->fragment.stsd_id == 1) {
6688 if (frag_stream_info->encryption_index) {
6689 encrypted_index = current_index - frag_stream_info->index_entry;
6690 encryption_index = frag_stream_info->encryption_index;
6692 encryption_index = sc->cenc.encryption_index;
6696 encryption_index = sc->cenc.encryption_index;
6699 if (encryption_index) {
6700 if (encryption_index->auxiliary_info_sample_count &&
6701 !encryption_index->nb_encrypted_samples) {
6702 av_log(mov->fc, AV_LOG_ERROR, "saiz atom found without saio\n");
6703 return AVERROR_INVALIDDATA;
6705 if (encryption_index->auxiliary_offsets_count &&
6706 !encryption_index->nb_encrypted_samples) {
6707 av_log(mov->fc, AV_LOG_ERROR, "saio atom found without saiz\n");
6708 return AVERROR_INVALIDDATA;
6711 if (!encryption_index->nb_encrypted_samples) {
6712 // Full-sample encryption with default settings.
6713 encrypted_sample = sc->cenc.default_encrypted_sample;
6714 } else if (encrypted_index >= 0 && encrypted_index < encryption_index->nb_encrypted_samples) {
6715 // Per-sample setting override.
6716 encrypted_sample = encryption_index->encrypted_samples[encrypted_index];
6718 av_log(mov->fc, AV_LOG_ERROR, "Incorrect number of samples in encryption info\n");
6719 return AVERROR_INVALIDDATA;
6722 if (mov->decryption_key) {
6723 return cenc_decrypt(mov, sc, encrypted_sample, pkt->data, pkt->size);
6726 uint8_t *side_data = av_encryption_info_add_side_data(encrypted_sample, &size);
6728 return AVERROR(ENOMEM);
6729 ret = av_packet_add_side_data(pkt, AV_PKT_DATA_ENCRYPTION_INFO, side_data, size);
6739 static int mov_read_dops(MOVContext *c, AVIOContext *pb, MOVAtom atom)
6741 const int OPUS_SEEK_PREROLL_MS = 80;
6747 if (c->fc->nb_streams < 1)
6749 st = c->fc->streams[c->fc->nb_streams-1];
6751 if ((uint64_t)atom.size > (1<<30) || atom.size < 11)
6752 return AVERROR_INVALIDDATA;
6754 /* Check OpusSpecificBox version. */
6755 if (avio_r8(pb) != 0) {
6756 av_log(c->fc, AV_LOG_ERROR, "unsupported OpusSpecificBox version\n");
6757 return AVERROR_INVALIDDATA;
6760 /* OpusSpecificBox size plus magic for Ogg OpusHead header. */
6761 size = atom.size + 8;
6763 if ((ret = ff_alloc_extradata(st->codecpar, size)) < 0)
6766 AV_WL32(st->codecpar->extradata, MKTAG('O','p','u','s'));
6767 AV_WL32(st->codecpar->extradata + 4, MKTAG('H','e','a','d'));
6768 AV_WB8(st->codecpar->extradata + 8, 1); /* OpusHead version */
6769 avio_read(pb, st->codecpar->extradata + 9, size - 9);
6771 /* OpusSpecificBox is stored in big-endian, but OpusHead is
6772 little-endian; aside from the preceeding magic and version they're
6773 otherwise currently identical. Data after output gain at offset 16
6774 doesn't need to be bytewapped. */
6775 pre_skip = AV_RB16(st->codecpar->extradata + 10);
6776 AV_WL16(st->codecpar->extradata + 10, pre_skip);
6777 AV_WL32(st->codecpar->extradata + 12, AV_RB32(st->codecpar->extradata + 12));
6778 AV_WL16(st->codecpar->extradata + 16, AV_RB16(st->codecpar->extradata + 16));
6780 st->codecpar->initial_padding = pre_skip;
6781 st->codecpar->seek_preroll = av_rescale_q(OPUS_SEEK_PREROLL_MS,
6782 (AVRational){1, 1000},
6783 (AVRational){1, 48000});
6788 static int mov_read_dmlp(MOVContext *c, AVIOContext *pb, MOVAtom atom)
6791 unsigned format_info;
6792 int channel_assignment, channel_assignment1, channel_assignment2;
6795 if (c->fc->nb_streams < 1)
6797 st = c->fc->streams[c->fc->nb_streams-1];
6800 return AVERROR_INVALIDDATA;
6802 format_info = avio_rb32(pb);
6804 ratebits = (format_info >> 28) & 0xF;
6805 channel_assignment1 = (format_info >> 15) & 0x1F;
6806 channel_assignment2 = format_info & 0x1FFF;
6807 if (channel_assignment2)
6808 channel_assignment = channel_assignment2;
6810 channel_assignment = channel_assignment1;
6812 st->codecpar->frame_size = 40 << (ratebits & 0x7);
6813 st->codecpar->sample_rate = mlp_samplerate(ratebits);
6814 st->codecpar->channels = truehd_channels(channel_assignment);
6815 st->codecpar->channel_layout = truehd_layout(channel_assignment);
6820 static int mov_read_dvcc_dvvc(MOVContext *c, AVIOContext *pb, MOVAtom atom)
6824 AVDOVIDecoderConfigurationRecord *dovi;
6828 if (c->fc->nb_streams < 1)
6830 st = c->fc->streams[c->fc->nb_streams-1];
6832 if ((uint64_t)atom.size > (1<<30) || atom.size < 4)
6833 return AVERROR_INVALIDDATA;
6835 dovi = av_dovi_alloc(&dovi_size);
6837 return AVERROR(ENOMEM);
6839 dovi->dv_version_major = avio_r8(pb);
6840 dovi->dv_version_minor = avio_r8(pb);
6842 buf = avio_rb16(pb);
6843 dovi->dv_profile = (buf >> 9) & 0x7f; // 7 bits
6844 dovi->dv_level = (buf >> 3) & 0x3f; // 6 bits
6845 dovi->rpu_present_flag = (buf >> 2) & 0x01; // 1 bit
6846 dovi->el_present_flag = (buf >> 1) & 0x01; // 1 bit
6847 dovi->bl_present_flag = buf & 0x01; // 1 bit
6848 if (atom.size >= 24) { // 4 + 4 + 4 * 4
6850 dovi->dv_bl_signal_compatibility_id = (buf >> 4) & 0x0f; // 4 bits
6852 // 0 stands for None
6853 // Dolby Vision V1.2.93 profiles and levels
6854 dovi->dv_bl_signal_compatibility_id = 0;
6857 ret = av_stream_add_side_data(st, AV_PKT_DATA_DOVI_CONF,
6858 (uint8_t *)dovi, dovi_size);
6864 av_log(c, AV_LOG_TRACE, "DOVI in dvcC/dvvC box, version: %d.%d, profile: %d, level: %d, "
6865 "rpu flag: %d, el flag: %d, bl flag: %d, compatibility id: %d\n",
6866 dovi->dv_version_major, dovi->dv_version_minor,
6867 dovi->dv_profile, dovi->dv_level,
6868 dovi->rpu_present_flag,
6869 dovi->el_present_flag,
6870 dovi->bl_present_flag,
6871 dovi->dv_bl_signal_compatibility_id
6877 static const MOVParseTableEntry mov_default_parse_table[] = {
6878 { MKTAG('A','C','L','R'), mov_read_aclr },
6879 { MKTAG('A','P','R','G'), mov_read_avid },
6880 { MKTAG('A','A','L','P'), mov_read_avid },
6881 { MKTAG('A','R','E','S'), mov_read_ares },
6882 { MKTAG('a','v','s','s'), mov_read_avss },
6883 { MKTAG('a','v','1','C'), mov_read_av1c },
6884 { MKTAG('c','h','p','l'), mov_read_chpl },
6885 { MKTAG('c','o','6','4'), mov_read_stco },
6886 { MKTAG('c','o','l','r'), mov_read_colr },
6887 { MKTAG('c','t','t','s'), mov_read_ctts }, /* composition time to sample */
6888 { MKTAG('d','i','n','f'), mov_read_default },
6889 { MKTAG('D','p','x','E'), mov_read_dpxe },
6890 { MKTAG('d','r','e','f'), mov_read_dref },
6891 { MKTAG('e','d','t','s'), mov_read_default },
6892 { MKTAG('e','l','s','t'), mov_read_elst },
6893 { MKTAG('e','n','d','a'), mov_read_enda },
6894 { MKTAG('f','i','e','l'), mov_read_fiel },
6895 { MKTAG('a','d','r','m'), mov_read_adrm },
6896 { MKTAG('f','t','y','p'), mov_read_ftyp },
6897 { MKTAG('g','l','b','l'), mov_read_glbl },
6898 { MKTAG('h','d','l','r'), mov_read_hdlr },
6899 { MKTAG('i','l','s','t'), mov_read_ilst },
6900 { MKTAG('j','p','2','h'), mov_read_jp2h },
6901 { MKTAG('m','d','a','t'), mov_read_mdat },
6902 { MKTAG('m','d','h','d'), mov_read_mdhd },
6903 { MKTAG('m','d','i','a'), mov_read_default },
6904 { MKTAG('m','e','t','a'), mov_read_meta },
6905 { MKTAG('m','i','n','f'), mov_read_default },
6906 { MKTAG('m','o','o','f'), mov_read_moof },
6907 { MKTAG('m','o','o','v'), mov_read_moov },
6908 { MKTAG('m','v','e','x'), mov_read_default },
6909 { MKTAG('m','v','h','d'), mov_read_mvhd },
6910 { MKTAG('S','M','I',' '), mov_read_svq3 },
6911 { MKTAG('a','l','a','c'), mov_read_alac }, /* alac specific atom */
6912 { MKTAG('a','v','c','C'), mov_read_glbl },
6913 { MKTAG('p','a','s','p'), mov_read_pasp },
6914 { MKTAG('s','i','d','x'), mov_read_sidx },
6915 { MKTAG('s','t','b','l'), mov_read_default },
6916 { MKTAG('s','t','c','o'), mov_read_stco },
6917 { MKTAG('s','t','p','s'), mov_read_stps },
6918 { MKTAG('s','t','r','f'), mov_read_strf },
6919 { MKTAG('s','t','s','c'), mov_read_stsc },
6920 { MKTAG('s','t','s','d'), mov_read_stsd }, /* sample description */
6921 { MKTAG('s','t','s','s'), mov_read_stss }, /* sync sample */
6922 { MKTAG('s','t','s','z'), mov_read_stsz }, /* sample size */
6923 { MKTAG('s','t','t','s'), mov_read_stts },
6924 { MKTAG('s','t','z','2'), mov_read_stsz }, /* compact sample size */
6925 { MKTAG('s','d','t','p'), mov_read_sdtp }, /* independent and disposable samples */
6926 { MKTAG('t','k','h','d'), mov_read_tkhd }, /* track header */
6927 { MKTAG('t','f','d','t'), mov_read_tfdt },
6928 { MKTAG('t','f','h','d'), mov_read_tfhd }, /* track fragment header */
6929 { MKTAG('t','r','a','k'), mov_read_trak },
6930 { MKTAG('t','r','a','f'), mov_read_default },
6931 { MKTAG('t','r','e','f'), mov_read_default },
6932 { MKTAG('t','m','c','d'), mov_read_tmcd },
6933 { MKTAG('c','h','a','p'), mov_read_chap },
6934 { MKTAG('t','r','e','x'), mov_read_trex },
6935 { MKTAG('t','r','u','n'), mov_read_trun },
6936 { MKTAG('u','d','t','a'), mov_read_default },
6937 { MKTAG('w','a','v','e'), mov_read_wave },
6938 { MKTAG('e','s','d','s'), mov_read_esds },
6939 { MKTAG('d','a','c','3'), mov_read_dac3 }, /* AC-3 info */
6940 { MKTAG('d','e','c','3'), mov_read_dec3 }, /* EAC-3 info */
6941 { MKTAG('d','d','t','s'), mov_read_ddts }, /* DTS audio descriptor */
6942 { MKTAG('w','i','d','e'), mov_read_wide }, /* place holder */
6943 { MKTAG('w','f','e','x'), mov_read_wfex },
6944 { MKTAG('c','m','o','v'), mov_read_cmov },
6945 { MKTAG('c','h','a','n'), mov_read_chan }, /* channel layout */
6946 { MKTAG('d','v','c','1'), mov_read_dvc1 },
6947 { MKTAG('s','b','g','p'), mov_read_sbgp },
6948 { MKTAG('h','v','c','C'), mov_read_glbl },
6949 { MKTAG('u','u','i','d'), mov_read_uuid },
6950 { MKTAG('C','i','n', 0x8e), mov_read_targa_y216 },
6951 { MKTAG('f','r','e','e'), mov_read_free },
6952 { MKTAG('-','-','-','-'), mov_read_custom },
6953 { MKTAG('s','i','n','f'), mov_read_default },
6954 { MKTAG('f','r','m','a'), mov_read_frma },
6955 { MKTAG('s','e','n','c'), mov_read_senc },
6956 { MKTAG('s','a','i','z'), mov_read_saiz },
6957 { MKTAG('s','a','i','o'), mov_read_saio },
6958 { MKTAG('p','s','s','h'), mov_read_pssh },
6959 { MKTAG('s','c','h','m'), mov_read_schm },
6960 { MKTAG('s','c','h','i'), mov_read_default },
6961 { MKTAG('t','e','n','c'), mov_read_tenc },
6962 { MKTAG('d','f','L','a'), mov_read_dfla },
6963 { MKTAG('s','t','3','d'), mov_read_st3d }, /* stereoscopic 3D video box */
6964 { MKTAG('s','v','3','d'), mov_read_sv3d }, /* spherical video box */
6965 { MKTAG('d','O','p','s'), mov_read_dops },
6966 { MKTAG('d','m','l','p'), mov_read_dmlp },
6967 { MKTAG('S','m','D','m'), mov_read_smdm },
6968 { MKTAG('C','o','L','L'), mov_read_coll },
6969 { MKTAG('v','p','c','C'), mov_read_vpcc },
6970 { MKTAG('m','d','c','v'), mov_read_mdcv },
6971 { MKTAG('c','l','l','i'), mov_read_clli },
6972 { MKTAG('d','v','c','C'), mov_read_dvcc_dvvc },
6973 { MKTAG('d','v','v','C'), mov_read_dvcc_dvvc },
6977 static int mov_read_default(MOVContext *c, AVIOContext *pb, MOVAtom atom)
6979 int64_t total_size = 0;
6983 if (c->atom_depth > 10) {
6984 av_log(c->fc, AV_LOG_ERROR, "Atoms too deeply nested\n");
6985 return AVERROR_INVALIDDATA;
6990 atom.size = INT64_MAX;
6991 while (total_size <= atom.size - 8 && !avio_feof(pb)) {
6992 int (*parse)(MOVContext*, AVIOContext*, MOVAtom) = NULL;
6995 if (atom.size >= 8) {
6996 a.size = avio_rb32(pb);
6997 a.type = avio_rl32(pb);
6998 if (((a.type == MKTAG('f','r','e','e') && c->moov_retry) ||
6999 a.type == MKTAG('h','o','o','v')) &&
7001 c->fc->strict_std_compliance < FF_COMPLIANCE_STRICT) {
7004 type = avio_rl32(pb);
7007 avio_seek(pb, -8, SEEK_CUR);
7008 if (type == MKTAG('m','v','h','d') ||
7009 type == MKTAG('c','m','o','v')) {
7010 av_log(c->fc, AV_LOG_ERROR, "Detected moov in a free or hoov atom.\n");
7011 a.type = MKTAG('m','o','o','v');
7014 if (atom.type != MKTAG('r','o','o','t') &&
7015 atom.type != MKTAG('m','o','o','v')) {
7016 if (a.type == MKTAG('t','r','a','k') ||
7017 a.type == MKTAG('m','d','a','t')) {
7018 av_log(c->fc, AV_LOG_ERROR, "Broken file, trak/mdat not at top-level\n");
7025 if (a.size == 1 && total_size + 8 <= atom.size) { /* 64 bit extended size */
7026 a.size = avio_rb64(pb) - 8;
7030 av_log(c->fc, AV_LOG_TRACE, "type:'%s' parent:'%s' sz: %"PRId64" %"PRId64" %"PRId64"\n",
7031 av_fourcc2str(a.type), av_fourcc2str(atom.type), a.size, total_size, atom.size);
7033 a.size = atom.size - total_size + 8;
7038 a.size = FFMIN(a.size, atom.size - total_size);
7040 for (i = 0; mov_default_parse_table[i].type; i++)
7041 if (mov_default_parse_table[i].type == a.type) {
7042 parse = mov_default_parse_table[i].parse;
7046 // container is user data
7047 if (!parse && (atom.type == MKTAG('u','d','t','a') ||
7048 atom.type == MKTAG('i','l','s','t')))
7049 parse = mov_read_udta_string;
7051 // Supports parsing the QuickTime Metadata Keys.
7052 // https://developer.apple.com/library/mac/documentation/QuickTime/QTFF/Metadata/Metadata.html
7053 if (!parse && c->found_hdlr_mdta &&
7054 atom.type == MKTAG('m','e','t','a') &&
7055 a.type == MKTAG('k','e','y','s') &&
7056 c->meta_keys_count == 0) {
7057 parse = mov_read_keys;
7060 if (!parse) { /* skip leaf atoms data */
7061 avio_skip(pb, a.size);
7063 int64_t start_pos = avio_tell(pb);
7065 int err = parse(c, pb, a);
7070 if (c->found_moov && c->found_mdat && a.size <= INT64_MAX - start_pos &&
7071 ((!(pb->seekable & AVIO_SEEKABLE_NORMAL) || c->fc->flags & AVFMT_FLAG_IGNIDX || c->frag_index.complete) ||
7072 start_pos + a.size == avio_size(pb))) {
7073 if (!(pb->seekable & AVIO_SEEKABLE_NORMAL) || c->fc->flags & AVFMT_FLAG_IGNIDX || c->frag_index.complete)
7074 c->next_root_atom = start_pos + a.size;
7078 left = a.size - avio_tell(pb) + start_pos;
7079 if (left > 0) /* skip garbage at atom end */
7080 avio_skip(pb, left);
7081 else if (left < 0) {
7082 av_log(c->fc, AV_LOG_WARNING,
7083 "overread end of atom '%s' by %"PRId64" bytes\n",
7084 av_fourcc2str(a.type), -left);
7085 avio_seek(pb, left, SEEK_CUR);
7089 total_size += a.size;
7092 if (total_size < atom.size && atom.size < 0x7ffff)
7093 avio_skip(pb, atom.size - total_size);
7099 static int mov_probe(const AVProbeData *p)
7104 int moov_offset = -1;
7106 /* check file header */
7111 /* ignore invalid offset */
7112 if ((offset + 8ULL) > (unsigned int)p->buf_size)
7114 size = AV_RB32(p->buf + offset);
7115 if (size == 1 && offset + 16 <= (unsigned int)p->buf_size) {
7116 size = AV_RB64(p->buf+offset + 8);
7118 } else if (size == 0) {
7119 size = p->buf_size - offset;
7121 if (size < minsize) {
7125 tag = AV_RL32(p->buf + offset + 4);
7127 /* check for obvious tags */
7128 case MKTAG('m','o','o','v'):
7129 moov_offset = offset + 4;
7130 case MKTAG('m','d','a','t'):
7131 case MKTAG('p','n','o','t'): /* detect movs with preview pics like ew.mov and april.mov */
7132 case MKTAG('u','d','t','a'): /* Packet Video PVAuthor adds this and a lot of more junk */
7133 case MKTAG('f','t','y','p'):
7134 if (tag == MKTAG('f','t','y','p') &&
7135 ( AV_RL32(p->buf + offset + 8) == MKTAG('j','p','2',' ')
7136 || AV_RL32(p->buf + offset + 8) == MKTAG('j','p','x',' ')
7138 score = FFMAX(score, 5);
7140 score = AVPROBE_SCORE_MAX;
7143 /* those are more common words, so rate then a bit less */
7144 case MKTAG('e','d','i','w'): /* xdcam files have reverted first tags */
7145 case MKTAG('w','i','d','e'):
7146 case MKTAG('f','r','e','e'):
7147 case MKTAG('j','u','n','k'):
7148 case MKTAG('p','i','c','t'):
7149 score = FFMAX(score, AVPROBE_SCORE_MAX - 5);
7151 case MKTAG(0x82,0x82,0x7f,0x7d):
7152 case MKTAG('s','k','i','p'):
7153 case MKTAG('u','u','i','d'):
7154 case MKTAG('p','r','f','l'):
7155 /* if we only find those cause probedata is too small at least rate them */
7156 score = FFMAX(score, AVPROBE_SCORE_EXTENSION);
7159 if (size > INT64_MAX - offset)
7163 if (score > AVPROBE_SCORE_MAX - 50 && moov_offset != -1) {
7164 /* moov atom in the header - we should make sure that this is not a
7165 * MOV-packed MPEG-PS */
7166 offset = moov_offset;
7168 while (offset < (p->buf_size - 16)) { /* Sufficient space */
7169 /* We found an actual hdlr atom */
7170 if (AV_RL32(p->buf + offset ) == MKTAG('h','d','l','r') &&
7171 AV_RL32(p->buf + offset + 8) == MKTAG('m','h','l','r') &&
7172 AV_RL32(p->buf + offset + 12) == MKTAG('M','P','E','G')) {
7173 av_log(NULL, AV_LOG_WARNING, "Found media data tag MPEG indicating this is a MOV-packed MPEG-PS.\n");
7174 /* We found a media handler reference atom describing an
7175 * MPEG-PS-in-MOV, return a
7176 * low score to force expanding the probe window until
7177 * mpegps_probe finds what it needs */
7189 // must be done after parsing all trak because there's no order requirement
7190 static void mov_read_chapters(AVFormatContext *s)
7192 MOVContext *mov = s->priv_data;
7194 MOVStreamContext *sc;
7199 for (j = 0; j < mov->nb_chapter_tracks; j++) {
7200 chapter_track = mov->chapter_tracks[j];
7202 for (i = 0; i < s->nb_streams; i++)
7203 if (s->streams[i]->id == chapter_track) {
7208 av_log(s, AV_LOG_ERROR, "Referenced QT chapter track not found\n");
7213 cur_pos = avio_tell(sc->pb);
7215 if (st->codecpar->codec_type == AVMEDIA_TYPE_VIDEO) {
7216 st->disposition |= AV_DISPOSITION_ATTACHED_PIC | AV_DISPOSITION_TIMED_THUMBNAILS;
7217 if (st->internal->nb_index_entries) {
7218 // Retrieve the first frame, if possible
7219 AVIndexEntry *sample = &st->internal->index_entries[0];
7220 if (avio_seek(sc->pb, sample->pos, SEEK_SET) != sample->pos) {
7221 av_log(s, AV_LOG_ERROR, "Failed to retrieve first frame\n");
7225 if (ff_add_attached_pic(s, st, sc->pb, NULL, sample->size) < 0)
7229 st->codecpar->codec_type = AVMEDIA_TYPE_DATA;
7230 st->codecpar->codec_id = AV_CODEC_ID_BIN_DATA;
7231 st->discard = AVDISCARD_ALL;
7232 for (i = 0; i < st->internal->nb_index_entries; i++) {
7233 AVIndexEntry *sample = &st->internal->index_entries[i];
7234 int64_t end = i+1 < st->internal->nb_index_entries ? st->internal->index_entries[i+1].timestamp : st->duration;
7239 if (end < sample->timestamp) {
7240 av_log(s, AV_LOG_WARNING, "ignoring stream duration which is shorter than chapters\n");
7241 end = AV_NOPTS_VALUE;
7244 if (avio_seek(sc->pb, sample->pos, SEEK_SET) != sample->pos) {
7245 av_log(s, AV_LOG_ERROR, "Chapter %d not found in file\n", i);
7249 // the first two bytes are the length of the title
7250 len = avio_rb16(sc->pb);
7251 if (len > sample->size-2)
7253 title_len = 2*len + 1;
7254 if (!(title = av_mallocz(title_len)))
7257 // The samples could theoretically be in any encoding if there's an encd
7258 // atom following, but in practice are only utf-8 or utf-16, distinguished
7259 // instead by the presence of a BOM
7263 ch = avio_rb16(sc->pb);
7265 avio_get_str16be(sc->pb, len, title, title_len);
7266 else if (ch == 0xfffe)
7267 avio_get_str16le(sc->pb, len, title, title_len);
7270 if (len == 1 || len == 2)
7273 avio_get_str(sc->pb, INT_MAX, title + 2, len - 1);
7277 avpriv_new_chapter(s, i, st->time_base, sample->timestamp, end, title);
7282 avio_seek(sc->pb, cur_pos, SEEK_SET);
7286 static int parse_timecode_in_framenum_format(AVFormatContext *s, AVStream *st,
7287 uint32_t value, int flags)
7290 char buf[AV_TIMECODE_STR_SIZE];
7291 AVRational rate = st->avg_frame_rate;
7292 int ret = av_timecode_init(&tc, rate, flags, 0, s);
7295 av_dict_set(&st->metadata, "timecode",
7296 av_timecode_make_string(&tc, buf, value), 0);
7300 static int mov_read_rtmd_track(AVFormatContext *s, AVStream *st)
7302 MOVStreamContext *sc = st->priv_data;
7303 char buf[AV_TIMECODE_STR_SIZE];
7304 int64_t cur_pos = avio_tell(sc->pb);
7305 int hh, mm, ss, ff, drop;
7307 if (!st->internal->nb_index_entries)
7310 avio_seek(sc->pb, st->internal->index_entries->pos, SEEK_SET);
7311 avio_skip(s->pb, 13);
7312 hh = avio_r8(s->pb);
7313 mm = avio_r8(s->pb);
7314 ss = avio_r8(s->pb);
7315 drop = avio_r8(s->pb);
7316 ff = avio_r8(s->pb);
7317 snprintf(buf, AV_TIMECODE_STR_SIZE, "%02d:%02d:%02d%c%02d",
7318 hh, mm, ss, drop ? ';' : ':', ff);
7319 av_dict_set(&st->metadata, "timecode", buf, 0);
7321 avio_seek(sc->pb, cur_pos, SEEK_SET);
7325 static int mov_read_timecode_track(AVFormatContext *s, AVStream *st)
7327 MOVStreamContext *sc = st->priv_data;
7329 int64_t cur_pos = avio_tell(sc->pb);
7332 if (!st->internal->nb_index_entries)
7335 avio_seek(sc->pb, st->internal->index_entries->pos, SEEK_SET);
7336 value = avio_rb32(s->pb);
7338 if (sc->tmcd_flags & 0x0001) flags |= AV_TIMECODE_FLAG_DROPFRAME;
7339 if (sc->tmcd_flags & 0x0002) flags |= AV_TIMECODE_FLAG_24HOURSMAX;
7340 if (sc->tmcd_flags & 0x0004) flags |= AV_TIMECODE_FLAG_ALLOWNEGATIVE;
7342 /* Assume Counter flag is set to 1 in tmcd track (even though it is likely
7343 * not the case) and thus assume "frame number format" instead of QT one.
7344 * No sample with tmcd track can be found with a QT timecode at the moment,
7345 * despite what the tmcd track "suggests" (Counter flag set to 0 means QT
7347 parse_timecode_in_framenum_format(s, st, value, flags);
7349 avio_seek(sc->pb, cur_pos, SEEK_SET);
7353 static void mov_free_encryption_index(MOVEncryptionIndex **index) {
7355 if (!index || !*index) return;
7356 for (i = 0; i < (*index)->nb_encrypted_samples; i++) {
7357 av_encryption_info_free((*index)->encrypted_samples[i]);
7359 av_freep(&(*index)->encrypted_samples);
7360 av_freep(&(*index)->auxiliary_info_sizes);
7361 av_freep(&(*index)->auxiliary_offsets);
7365 static int mov_read_close(AVFormatContext *s)
7367 MOVContext *mov = s->priv_data;
7370 for (i = 0; i < s->nb_streams; i++) {
7371 AVStream *st = s->streams[i];
7372 MOVStreamContext *sc = st->priv_data;
7377 av_freep(&sc->ctts_data);
7378 for (j = 0; j < sc->drefs_count; j++) {
7379 av_freep(&sc->drefs[j].path);
7380 av_freep(&sc->drefs[j].dir);
7382 av_freep(&sc->drefs);
7384 sc->drefs_count = 0;
7386 if (!sc->pb_is_copied)
7387 ff_format_io_close(s, &sc->pb);
7390 av_freep(&sc->chunk_offsets);
7391 av_freep(&sc->stsc_data);
7392 av_freep(&sc->sample_sizes);
7393 av_freep(&sc->keyframes);
7394 av_freep(&sc->stts_data);
7395 av_freep(&sc->sdtp_data);
7396 av_freep(&sc->stps_data);
7397 av_freep(&sc->elst_data);
7398 av_freep(&sc->rap_group);
7399 av_freep(&sc->display_matrix);
7400 av_freep(&sc->index_ranges);
7403 for (j = 0; j < sc->stsd_count; j++)
7404 av_free(sc->extradata[j]);
7405 av_freep(&sc->extradata);
7406 av_freep(&sc->extradata_size);
7408 mov_free_encryption_index(&sc->cenc.encryption_index);
7409 av_encryption_info_free(sc->cenc.default_encrypted_sample);
7410 av_aes_ctr_free(sc->cenc.aes_ctr);
7412 av_freep(&sc->stereo3d);
7413 av_freep(&sc->spherical);
7414 av_freep(&sc->mastering);
7415 av_freep(&sc->coll);
7418 av_freep(&mov->dv_demux);
7419 avformat_free_context(mov->dv_fctx);
7420 mov->dv_fctx = NULL;
7422 if (mov->meta_keys) {
7423 for (i = 1; i < mov->meta_keys_count; i++) {
7424 av_freep(&mov->meta_keys[i]);
7426 av_freep(&mov->meta_keys);
7429 av_freep(&mov->trex_data);
7430 av_freep(&mov->bitrates);
7432 for (i = 0; i < mov->frag_index.nb_items; i++) {
7433 MOVFragmentStreamInfo *frag = mov->frag_index.item[i].stream_info;
7434 for (j = 0; j < mov->frag_index.item[i].nb_stream_info; j++) {
7435 mov_free_encryption_index(&frag[j].encryption_index);
7437 av_freep(&mov->frag_index.item[i].stream_info);
7439 av_freep(&mov->frag_index.item);
7441 av_freep(&mov->aes_decrypt);
7442 av_freep(&mov->chapter_tracks);
7447 static int tmcd_is_referenced(AVFormatContext *s, int tmcd_id)
7451 for (i = 0; i < s->nb_streams; i++) {
7452 AVStream *st = s->streams[i];
7453 MOVStreamContext *sc = st->priv_data;
7455 if (st->codecpar->codec_type == AVMEDIA_TYPE_VIDEO &&
7456 sc->timecode_track == tmcd_id)
7462 /* look for a tmcd track not referenced by any video track, and export it globally */
7463 static void export_orphan_timecode(AVFormatContext *s)
7467 for (i = 0; i < s->nb_streams; i++) {
7468 AVStream *st = s->streams[i];
7470 if (st->codecpar->codec_tag == MKTAG('t','m','c','d') &&
7471 !tmcd_is_referenced(s, i + 1)) {
7472 AVDictionaryEntry *tcr = av_dict_get(st->metadata, "timecode", NULL, 0);
7474 av_dict_set(&s->metadata, "timecode", tcr->value, 0);
7481 static int read_tfra(MOVContext *mov, AVIOContext *f)
7483 int version, fieldlength, i, j;
7484 int64_t pos = avio_tell(f);
7485 uint32_t size = avio_rb32(f);
7486 unsigned track_id, item_count;
7488 if (avio_rb32(f) != MKBETAG('t', 'f', 'r', 'a')) {
7491 av_log(mov->fc, AV_LOG_VERBOSE, "found tfra\n");
7493 version = avio_r8(f);
7495 track_id = avio_rb32(f);
7496 fieldlength = avio_rb32(f);
7497 item_count = avio_rb32(f);
7498 for (i = 0; i < item_count; i++) {
7499 int64_t time, offset;
7501 MOVFragmentStreamInfo * frag_stream_info;
7504 return AVERROR_INVALIDDATA;
7508 time = avio_rb64(f);
7509 offset = avio_rb64(f);
7511 time = avio_rb32(f);
7512 offset = avio_rb32(f);
7515 // The first sample of each stream in a fragment is always a random
7516 // access sample. So it's entry in the tfra can be used as the
7517 // initial PTS of the fragment.
7518 index = update_frag_index(mov, offset);
7519 frag_stream_info = get_frag_stream_info(&mov->frag_index, index, track_id);
7520 if (frag_stream_info &&
7521 frag_stream_info->first_tfra_pts == AV_NOPTS_VALUE)
7522 frag_stream_info->first_tfra_pts = time;
7524 for (j = 0; j < ((fieldlength >> 4) & 3) + 1; j++)
7526 for (j = 0; j < ((fieldlength >> 2) & 3) + 1; j++)
7528 for (j = 0; j < ((fieldlength >> 0) & 3) + 1; j++)
7532 avio_seek(f, pos + size, SEEK_SET);
7536 static int mov_read_mfra(MOVContext *c, AVIOContext *f)
7538 int64_t stream_size = avio_size(f);
7539 int64_t original_pos = avio_tell(f);
7542 if ((seek_ret = avio_seek(f, stream_size - 4, SEEK_SET)) < 0) {
7546 c->mfra_size = avio_rb32(f);
7547 c->have_read_mfra_size = 1;
7548 if (!c->mfra_size || c->mfra_size > stream_size) {
7549 av_log(c->fc, AV_LOG_DEBUG, "doesn't look like mfra (unreasonable size)\n");
7552 if ((seek_ret = avio_seek(f, -((int64_t) c->mfra_size), SEEK_CUR)) < 0) {
7556 if (avio_rb32(f) != c->mfra_size) {
7557 av_log(c->fc, AV_LOG_DEBUG, "doesn't look like mfra (size mismatch)\n");
7560 if (avio_rb32(f) != MKBETAG('m', 'f', 'r', 'a')) {
7561 av_log(c->fc, AV_LOG_DEBUG, "doesn't look like mfra (tag mismatch)\n");
7564 av_log(c->fc, AV_LOG_VERBOSE, "stream has mfra\n");
7566 ret = read_tfra(c, f);
7571 c->frag_index.complete = 1;
7573 seek_ret = avio_seek(f, original_pos, SEEK_SET);
7575 av_log(c->fc, AV_LOG_ERROR,
7576 "failed to seek back after looking for mfra\n");
7582 static int mov_read_header(AVFormatContext *s)
7584 MOVContext *mov = s->priv_data;
7585 AVIOContext *pb = s->pb;
7587 MOVAtom atom = { AV_RL32("root") };
7590 if (mov->decryption_key_len != 0 && mov->decryption_key_len != AES_CTR_KEY_SIZE) {
7591 av_log(s, AV_LOG_ERROR, "Invalid decryption key len %d expected %d\n",
7592 mov->decryption_key_len, AES_CTR_KEY_SIZE);
7593 return AVERROR(EINVAL);
7597 mov->trak_index = -1;
7598 /* .mov and .mp4 aren't streamable anyway (only progressive download if moov is before mdat) */
7599 if (pb->seekable & AVIO_SEEKABLE_NORMAL)
7600 atom.size = avio_size(pb);
7602 atom.size = INT64_MAX;
7604 /* check MOV header */
7606 if (mov->moov_retry)
7607 avio_seek(pb, 0, SEEK_SET);
7608 if ((err = mov_read_default(mov, pb, atom)) < 0) {
7609 av_log(s, AV_LOG_ERROR, "error reading header\n");
7612 } while ((pb->seekable & AVIO_SEEKABLE_NORMAL) && !mov->found_moov && !mov->moov_retry++);
7613 if (!mov->found_moov) {
7614 av_log(s, AV_LOG_ERROR, "moov atom not found\n");
7615 err = AVERROR_INVALIDDATA;
7618 av_log(mov->fc, AV_LOG_TRACE, "on_parse_exit_offset=%"PRId64"\n", avio_tell(pb));
7620 if (pb->seekable & AVIO_SEEKABLE_NORMAL) {
7621 if (mov->nb_chapter_tracks > 0 && !mov->ignore_chapters)
7622 mov_read_chapters(s);
7623 for (i = 0; i < s->nb_streams; i++)
7624 if (s->streams[i]->codecpar->codec_tag == AV_RL32("tmcd")) {
7625 mov_read_timecode_track(s, s->streams[i]);
7626 } else if (s->streams[i]->codecpar->codec_tag == AV_RL32("rtmd")) {
7627 mov_read_rtmd_track(s, s->streams[i]);
7631 /* copy timecode metadata from tmcd tracks to the related video streams */
7632 for (i = 0; i < s->nb_streams; i++) {
7633 AVStream *st = s->streams[i];
7634 MOVStreamContext *sc = st->priv_data;
7635 if (sc->timecode_track > 0) {
7636 AVDictionaryEntry *tcr;
7637 int tmcd_st_id = -1;
7639 for (j = 0; j < s->nb_streams; j++)
7640 if (s->streams[j]->id == sc->timecode_track)
7643 if (tmcd_st_id < 0 || tmcd_st_id == i)
7645 tcr = av_dict_get(s->streams[tmcd_st_id]->metadata, "timecode", NULL, 0);
7647 av_dict_set(&st->metadata, "timecode", tcr->value, 0);
7650 export_orphan_timecode(s);
7652 for (i = 0; i < s->nb_streams; i++) {
7653 AVStream *st = s->streams[i];
7654 MOVStreamContext *sc = st->priv_data;
7655 fix_timescale(mov, sc);
7656 if (st->codecpar->codec_type == AVMEDIA_TYPE_AUDIO &&
7657 st->codecpar->codec_id == AV_CODEC_ID_AAC) {
7658 st->internal->skip_samples = sc->start_pad;
7660 if (st->codecpar->codec_type == AVMEDIA_TYPE_VIDEO && sc->nb_frames_for_fps > 0 && sc->duration_for_fps > 0)
7661 av_reduce(&st->avg_frame_rate.num, &st->avg_frame_rate.den,
7662 sc->time_scale*(int64_t)sc->nb_frames_for_fps, sc->duration_for_fps, INT_MAX);
7663 if (st->codecpar->codec_type == AVMEDIA_TYPE_SUBTITLE) {
7664 if (st->codecpar->width <= 0 || st->codecpar->height <= 0) {
7665 st->codecpar->width = sc->width;
7666 st->codecpar->height = sc->height;
7668 if (st->codecpar->codec_id == AV_CODEC_ID_DVD_SUBTITLE) {
7669 if ((err = mov_rewrite_dvd_sub_extradata(st)) < 0)
7673 if (mov->handbrake_version &&
7674 mov->handbrake_version <= 1000000*0 + 1000*10 + 2 && // 0.10.2
7675 st->codecpar->codec_id == AV_CODEC_ID_MP3) {
7676 av_log(s, AV_LOG_VERBOSE, "Forcing full parsing for mp3 stream\n");
7677 st->need_parsing = AVSTREAM_PARSE_FULL;
7681 if (mov->trex_data) {
7682 for (i = 0; i < s->nb_streams; i++) {
7683 AVStream *st = s->streams[i];
7684 MOVStreamContext *sc = st->priv_data;
7685 if (st->duration > 0) {
7686 if (sc->data_size > INT64_MAX / sc->time_scale / 8) {
7687 av_log(s, AV_LOG_ERROR, "Overflow during bit rate calculation %"PRId64" * 8 * %d\n",
7688 sc->data_size, sc->time_scale);
7689 err = AVERROR_INVALIDDATA;
7692 st->codecpar->bit_rate = sc->data_size * 8 * sc->time_scale / st->duration;
7697 if (mov->use_mfra_for > 0) {
7698 for (i = 0; i < s->nb_streams; i++) {
7699 AVStream *st = s->streams[i];
7700 MOVStreamContext *sc = st->priv_data;
7701 if (sc->duration_for_fps > 0) {
7702 if (sc->data_size > INT64_MAX / sc->time_scale / 8) {
7703 av_log(s, AV_LOG_ERROR, "Overflow during bit rate calculation %"PRId64" * 8 * %d\n",
7704 sc->data_size, sc->time_scale);
7705 err = AVERROR_INVALIDDATA;
7708 st->codecpar->bit_rate = sc->data_size * 8 * sc->time_scale /
7709 sc->duration_for_fps;
7714 for (i = 0; i < mov->bitrates_count && i < s->nb_streams; i++) {
7715 if (mov->bitrates[i]) {
7716 s->streams[i]->codecpar->bit_rate = mov->bitrates[i];
7720 ff_rfps_calculate(s);
7722 for (i = 0; i < s->nb_streams; i++) {
7723 AVStream *st = s->streams[i];
7724 MOVStreamContext *sc = st->priv_data;
7726 switch (st->codecpar->codec_type) {
7727 case AVMEDIA_TYPE_AUDIO:
7728 err = ff_replaygain_export(st, s->metadata);
7732 case AVMEDIA_TYPE_VIDEO:
7733 if (sc->display_matrix) {
7734 err = av_stream_add_side_data(st, AV_PKT_DATA_DISPLAYMATRIX, (uint8_t*)sc->display_matrix,
7735 sizeof(int32_t) * 9);
7739 sc->display_matrix = NULL;
7742 err = av_stream_add_side_data(st, AV_PKT_DATA_STEREO3D,
7743 (uint8_t *)sc->stereo3d,
7744 sizeof(*sc->stereo3d));
7748 sc->stereo3d = NULL;
7750 if (sc->spherical) {
7751 err = av_stream_add_side_data(st, AV_PKT_DATA_SPHERICAL,
7752 (uint8_t *)sc->spherical,
7753 sc->spherical_size);
7757 sc->spherical = NULL;
7759 if (sc->mastering) {
7760 err = av_stream_add_side_data(st, AV_PKT_DATA_MASTERING_DISPLAY_METADATA,
7761 (uint8_t *)sc->mastering,
7762 sizeof(*sc->mastering));
7766 sc->mastering = NULL;
7769 err = av_stream_add_side_data(st, AV_PKT_DATA_CONTENT_LIGHT_LEVEL,
7770 (uint8_t *)sc->coll,
7780 ff_configure_buffers_for_index(s, AV_TIME_BASE);
7782 for (i = 0; i < mov->frag_index.nb_items; i++)
7783 if (mov->frag_index.item[i].moof_offset <= mov->fragment.moof_offset)
7784 mov->frag_index.item[i].headers_read = 1;
7792 static AVIndexEntry *mov_find_next_sample(AVFormatContext *s, AVStream **st)
7794 AVIndexEntry *sample = NULL;
7795 int64_t best_dts = INT64_MAX;
7797 for (i = 0; i < s->nb_streams; i++) {
7798 AVStream *avst = s->streams[i];
7799 MOVStreamContext *msc = avst->priv_data;
7800 if (msc->pb && msc->current_sample < avst->internal->nb_index_entries) {
7801 AVIndexEntry *current_sample = &avst->internal->index_entries[msc->current_sample];
7802 int64_t dts = av_rescale(current_sample->timestamp, AV_TIME_BASE, msc->time_scale);
7803 av_log(s, AV_LOG_TRACE, "stream %d, sample %d, dts %"PRId64"\n", i, msc->current_sample, dts);
7804 if (!sample || (!(s->pb->seekable & AVIO_SEEKABLE_NORMAL) && current_sample->pos < sample->pos) ||
7805 ((s->pb->seekable & AVIO_SEEKABLE_NORMAL) &&
7806 ((msc->pb != s->pb && dts < best_dts) || (msc->pb == s->pb && dts != AV_NOPTS_VALUE &&
7807 ((FFABS(best_dts - dts) <= AV_TIME_BASE && current_sample->pos < sample->pos) ||
7808 (FFABS(best_dts - dts) > AV_TIME_BASE && dts < best_dts)))))) {
7809 sample = current_sample;
7818 static int should_retry(AVIOContext *pb, int error_code) {
7819 if (error_code == AVERROR_EOF || avio_feof(pb))
7825 static int mov_switch_root(AVFormatContext *s, int64_t target, int index)
7828 MOVContext *mov = s->priv_data;
7830 if (index >= 0 && index < mov->frag_index.nb_items)
7831 target = mov->frag_index.item[index].moof_offset;
7832 if (avio_seek(s->pb, target, SEEK_SET) != target) {
7833 av_log(mov->fc, AV_LOG_ERROR, "root atom offset 0x%"PRIx64": partial file\n", target);
7834 return AVERROR_INVALIDDATA;
7837 mov->next_root_atom = 0;
7838 if (index < 0 || index >= mov->frag_index.nb_items)
7839 index = search_frag_moof_offset(&mov->frag_index, target);
7840 if (index < mov->frag_index.nb_items &&
7841 mov->frag_index.item[index].moof_offset == target) {
7842 if (index + 1 < mov->frag_index.nb_items)
7843 mov->next_root_atom = mov->frag_index.item[index + 1].moof_offset;
7844 if (mov->frag_index.item[index].headers_read)
7846 mov->frag_index.item[index].headers_read = 1;
7849 mov->found_mdat = 0;
7851 ret = mov_read_default(mov, s->pb, (MOVAtom){ AV_RL32("root"), INT64_MAX });
7854 if (avio_feof(s->pb))
7856 av_log(s, AV_LOG_TRACE, "read fragments, offset 0x%"PRIx64"\n", avio_tell(s->pb));
7861 static int mov_change_extradata(MOVStreamContext *sc, AVPacket *pkt)
7863 uint8_t *side, *extradata;
7866 /* Save the current index. */
7867 sc->last_stsd_index = sc->stsc_data[sc->stsc_index].id - 1;
7869 /* Notify the decoder that extradata changed. */
7870 extradata_size = sc->extradata_size[sc->last_stsd_index];
7871 extradata = sc->extradata[sc->last_stsd_index];
7872 if (extradata_size > 0 && extradata) {
7873 side = av_packet_new_side_data(pkt,
7874 AV_PKT_DATA_NEW_EXTRADATA,
7877 return AVERROR(ENOMEM);
7878 memcpy(side, extradata, extradata_size);
7884 static int get_eia608_packet(AVIOContext *pb, AVPacket *pkt, int size)
7889 return AVERROR_INVALIDDATA;
7890 new_size = ((size - 8) / 2) * 3;
7891 ret = av_new_packet(pkt, new_size);
7896 for (int j = 0; j < new_size; j += 3) {
7897 pkt->data[j] = 0xFC;
7898 pkt->data[j+1] = avio_r8(pb);
7899 pkt->data[j+2] = avio_r8(pb);
7905 static int mov_read_packet(AVFormatContext *s, AVPacket *pkt)
7907 MOVContext *mov = s->priv_data;
7908 MOVStreamContext *sc;
7909 AVIndexEntry *sample;
7910 AVStream *st = NULL;
7911 int64_t current_index;
7915 sample = mov_find_next_sample(s, &st);
7916 if (!sample || (mov->next_root_atom && sample->pos > mov->next_root_atom)) {
7917 if (!mov->next_root_atom)
7919 if ((ret = mov_switch_root(s, mov->next_root_atom, -1)) < 0)
7924 /* must be done just before reading, to avoid infinite loop on sample */
7925 current_index = sc->current_index;
7926 mov_current_sample_inc(sc);
7928 if (mov->next_root_atom) {
7929 sample->pos = FFMIN(sample->pos, mov->next_root_atom);
7930 sample->size = FFMIN(sample->size, (mov->next_root_atom - sample->pos));
7933 if (st->discard != AVDISCARD_ALL) {
7934 int64_t ret64 = avio_seek(sc->pb, sample->pos, SEEK_SET);
7935 if (ret64 != sample->pos) {
7936 av_log(mov->fc, AV_LOG_ERROR, "stream %d, offset 0x%"PRIx64": partial file\n",
7937 sc->ffindex, sample->pos);
7938 if (should_retry(sc->pb, ret64)) {
7939 mov_current_sample_dec(sc);
7940 } else if (ret64 < 0) {
7943 return AVERROR_INVALIDDATA;
7946 if (st->discard == AVDISCARD_NONKEY && !(sample->flags & AVINDEX_KEYFRAME)) {
7947 av_log(mov->fc, AV_LOG_DEBUG, "Nonkey frame from stream %d discarded due to AVDISCARD_NONKEY\n", sc->ffindex);
7951 if (st->codecpar->codec_id == AV_CODEC_ID_EIA_608 && sample->size > 8)
7952 ret = get_eia608_packet(sc->pb, pkt, sample->size);
7954 ret = av_get_packet(sc->pb, pkt, sample->size);
7956 if (should_retry(sc->pb, ret)) {
7957 mov_current_sample_dec(sc);
7961 #if CONFIG_DV_DEMUXER
7962 if (mov->dv_demux && sc->dv_audio_container) {
7963 AVBufferRef *buf = pkt->buf;
7964 ret = avpriv_dv_produce_packet(mov->dv_demux, pkt, pkt->data, pkt->size, pkt->pos);
7966 av_packet_unref(pkt);
7969 ret = avpriv_dv_get_packet(mov->dv_demux, pkt);
7974 if (sc->has_palette) {
7977 pal = av_packet_new_side_data(pkt, AV_PKT_DATA_PALETTE, AVPALETTE_SIZE);
7979 av_log(mov->fc, AV_LOG_ERROR, "Cannot append palette to packet\n");
7981 memcpy(pal, sc->palette, AVPALETTE_SIZE);
7982 sc->has_palette = 0;
7985 if (st->codecpar->codec_id == AV_CODEC_ID_MP3 && !st->need_parsing && pkt->size > 4) {
7986 if (ff_mpa_check_header(AV_RB32(pkt->data)) < 0)
7987 st->need_parsing = AVSTREAM_PARSE_FULL;
7991 pkt->stream_index = sc->ffindex;
7992 pkt->dts = sample->timestamp;
7993 if (sample->flags & AVINDEX_DISCARD_FRAME) {
7994 pkt->flags |= AV_PKT_FLAG_DISCARD;
7996 if (sc->ctts_data && sc->ctts_index < sc->ctts_count) {
7997 pkt->pts = pkt->dts + sc->dts_shift + sc->ctts_data[sc->ctts_index].duration;
7998 /* update ctts context */
8000 if (sc->ctts_index < sc->ctts_count &&
8001 sc->ctts_data[sc->ctts_index].count == sc->ctts_sample) {
8003 sc->ctts_sample = 0;
8006 int64_t next_dts = (sc->current_sample < st->internal->nb_index_entries) ?
8007 st->internal->index_entries[sc->current_sample].timestamp : st->duration;
8009 if (next_dts >= pkt->dts)
8010 pkt->duration = next_dts - pkt->dts;
8011 pkt->pts = pkt->dts;
8013 if (st->discard == AVDISCARD_ALL)
8015 if (sc->sdtp_data && sc->current_sample <= sc->sdtp_count) {
8016 uint8_t sample_flags = sc->sdtp_data[sc->current_sample - 1];
8017 uint8_t sample_is_depended_on = (sample_flags >> 2) & 0x3;
8018 pkt->flags |= sample_is_depended_on == MOV_SAMPLE_DEPENDENCY_NO ? AV_PKT_FLAG_DISPOSABLE : 0;
8020 pkt->flags |= sample->flags & AVINDEX_KEYFRAME ? AV_PKT_FLAG_KEY : 0;
8021 pkt->pos = sample->pos;
8023 /* Multiple stsd handling. */
8024 if (sc->stsc_data) {
8025 /* Keep track of the stsc index for the given sample, then check
8026 * if the stsd index is different from the last used one. */
8028 if (mov_stsc_index_valid(sc->stsc_index, sc->stsc_count) &&
8029 mov_get_stsc_samples(sc, sc->stsc_index) == sc->stsc_sample) {
8031 sc->stsc_sample = 0;
8032 /* Do not check indexes after a switch. */
8033 } else if (sc->stsc_data[sc->stsc_index].id > 0 &&
8034 sc->stsc_data[sc->stsc_index].id - 1 < sc->stsd_count &&
8035 sc->stsc_data[sc->stsc_index].id - 1 != sc->last_stsd_index) {
8036 ret = mov_change_extradata(sc, pkt);
8043 aax_filter(pkt->data, pkt->size, mov);
8045 ret = cenc_filter(mov, st, sc, pkt, current_index);
8053 static int mov_seek_fragment(AVFormatContext *s, AVStream *st, int64_t timestamp)
8055 MOVContext *mov = s->priv_data;
8058 if (!mov->frag_index.complete)
8061 index = search_frag_timestamp(&mov->frag_index, st, timestamp);
8064 if (!mov->frag_index.item[index].headers_read)
8065 return mov_switch_root(s, -1, index);
8066 if (index + 1 < mov->frag_index.nb_items)
8067 mov->next_root_atom = mov->frag_index.item[index + 1].moof_offset;
8072 static int mov_seek_stream(AVFormatContext *s, AVStream *st, int64_t timestamp, int flags)
8074 MOVStreamContext *sc = st->priv_data;
8075 int sample, time_sample, ret;
8078 // Here we consider timestamp to be PTS, hence try to offset it so that we
8079 // can search over the DTS timeline.
8080 timestamp -= (sc->min_corrected_pts + sc->dts_shift);
8082 ret = mov_seek_fragment(s, st, timestamp);
8086 sample = av_index_search_timestamp(st, timestamp, flags);
8087 av_log(s, AV_LOG_TRACE, "stream %d, timestamp %"PRId64", sample %d\n", st->index, timestamp, sample);
8088 if (sample < 0 && st->internal->nb_index_entries && timestamp < st->internal->index_entries[0].timestamp)
8090 if (sample < 0) /* not sure what to do */
8091 return AVERROR_INVALIDDATA;
8092 mov_current_sample_set(sc, sample);
8093 av_log(s, AV_LOG_TRACE, "stream %d, found sample %d\n", st->index, sc->current_sample);
8094 /* adjust ctts index */
8095 if (sc->ctts_data) {
8097 for (i = 0; i < sc->ctts_count; i++) {
8098 int next = time_sample + sc->ctts_data[i].count;
8099 if (next > sc->current_sample) {
8101 sc->ctts_sample = sc->current_sample - time_sample;
8108 /* adjust stsd index */
8109 if (sc->chunk_count) {
8111 for (i = 0; i < sc->stsc_count; i++) {
8112 int64_t next = time_sample + mov_get_stsc_samples(sc, i);
8113 if (next > sc->current_sample) {
8115 sc->stsc_sample = sc->current_sample - time_sample;
8118 av_assert0(next == (int)next);
8126 static int64_t mov_get_skip_samples(AVStream *st, int sample)
8128 MOVStreamContext *sc = st->priv_data;
8129 int64_t first_ts = st->internal->index_entries[0].timestamp;
8130 int64_t ts = st->internal->index_entries[sample].timestamp;
8133 if (st->codecpar->codec_type != AVMEDIA_TYPE_AUDIO)
8136 /* compute skip samples according to stream start_pad, seek ts and first ts */
8137 off = av_rescale_q(ts - first_ts, st->time_base,
8138 (AVRational){1, st->codecpar->sample_rate});
8139 return FFMAX(sc->start_pad - off, 0);
8142 static int mov_read_seek(AVFormatContext *s, int stream_index, int64_t sample_time, int flags)
8144 MOVContext *mc = s->priv_data;
8149 if (stream_index >= s->nb_streams)
8150 return AVERROR_INVALIDDATA;
8152 st = s->streams[stream_index];
8153 sample = mov_seek_stream(s, st, sample_time, flags);
8157 if (mc->seek_individually) {
8158 /* adjust seek timestamp to found sample timestamp */
8159 int64_t seek_timestamp = st->internal->index_entries[sample].timestamp;
8160 st->internal->skip_samples = mov_get_skip_samples(st, sample);
8162 for (i = 0; i < s->nb_streams; i++) {
8166 if (stream_index == i)
8169 timestamp = av_rescale_q(seek_timestamp, s->streams[stream_index]->time_base, st->time_base);
8170 sample = mov_seek_stream(s, st, timestamp, flags);
8172 st->internal->skip_samples = mov_get_skip_samples(st, sample);
8175 for (i = 0; i < s->nb_streams; i++) {
8176 MOVStreamContext *sc;
8179 mov_current_sample_set(sc, 0);
8182 MOVStreamContext *sc;
8183 AVIndexEntry *entry = mov_find_next_sample(s, &st);
8185 return AVERROR_INVALIDDATA;
8187 if (sc->ffindex == stream_index && sc->current_sample == sample)
8189 mov_current_sample_inc(sc);
8195 #define OFFSET(x) offsetof(MOVContext, x)
8196 #define FLAGS AV_OPT_FLAG_VIDEO_PARAM | AV_OPT_FLAG_DECODING_PARAM
8197 static const AVOption mov_options[] = {
8198 {"use_absolute_path",
8199 "allow using absolute path when opening alias, this is a possible security issue",
8200 OFFSET(use_absolute_path), AV_OPT_TYPE_BOOL, {.i64 = 0},
8202 {"seek_streams_individually",
8203 "Seek each stream individually to the closest point",
8204 OFFSET(seek_individually), AV_OPT_TYPE_BOOL, { .i64 = 1 },
8206 {"ignore_editlist", "Ignore the edit list atom.", OFFSET(ignore_editlist), AV_OPT_TYPE_BOOL, {.i64 = 0},
8208 {"advanced_editlist",
8209 "Modify the AVIndex according to the editlists. Use this option to decode in the order specified by the edits.",
8210 OFFSET(advanced_editlist), AV_OPT_TYPE_BOOL, {.i64 = 1},
8212 {"ignore_chapters", "", OFFSET(ignore_chapters), AV_OPT_TYPE_BOOL, {.i64 = 0},
8215 "use mfra for fragment timestamps",
8216 OFFSET(use_mfra_for), AV_OPT_TYPE_INT, {.i64 = FF_MOV_FLAG_MFRA_AUTO},
8217 -1, FF_MOV_FLAG_MFRA_PTS, FLAGS,
8219 {"auto", "auto", 0, AV_OPT_TYPE_CONST, {.i64 = FF_MOV_FLAG_MFRA_AUTO}, 0, 0,
8220 FLAGS, "use_mfra_for" },
8221 {"dts", "dts", 0, AV_OPT_TYPE_CONST, {.i64 = FF_MOV_FLAG_MFRA_DTS}, 0, 0,
8222 FLAGS, "use_mfra_for" },
8223 {"pts", "pts", 0, AV_OPT_TYPE_CONST, {.i64 = FF_MOV_FLAG_MFRA_PTS}, 0, 0,
8224 FLAGS, "use_mfra_for" },
8225 { "export_all", "Export unrecognized metadata entries", OFFSET(export_all),
8226 AV_OPT_TYPE_BOOL, { .i64 = 0 }, 0, 1, .flags = FLAGS },
8227 { "export_xmp", "Export full XMP metadata", OFFSET(export_xmp),
8228 AV_OPT_TYPE_BOOL, { .i64 = 0 }, 0, 1, .flags = FLAGS },
8229 { "activation_bytes", "Secret bytes for Audible AAX files", OFFSET(activation_bytes),
8230 AV_OPT_TYPE_BINARY, .flags = AV_OPT_FLAG_DECODING_PARAM },
8231 { "audible_key", "AES-128 Key for Audible AAXC files", OFFSET(audible_key),
8232 AV_OPT_TYPE_BINARY, .flags = AV_OPT_FLAG_DECODING_PARAM },
8233 { "audible_iv", "AES-128 IV for Audible AAXC files", OFFSET(audible_iv),
8234 AV_OPT_TYPE_BINARY, .flags = AV_OPT_FLAG_DECODING_PARAM },
8235 { "audible_fixed_key", // extracted from libAAX_SDK.so and AAXSDKWin.dll files!
8236 "Fixed key used for handling Audible AAX files", OFFSET(audible_fixed_key),
8237 AV_OPT_TYPE_BINARY, {.str="77214d4b196a87cd520045fd20a51d67"},
8238 .flags = AV_OPT_FLAG_DECODING_PARAM },
8239 { "decryption_key", "The media decryption key (hex)", OFFSET(decryption_key), AV_OPT_TYPE_BINARY, .flags = AV_OPT_FLAG_DECODING_PARAM },
8240 { "enable_drefs", "Enable external track support.", OFFSET(enable_drefs), AV_OPT_TYPE_BOOL,
8241 {.i64 = 0}, 0, 1, FLAGS },
8246 static const AVClass mov_class = {
8247 .class_name = "mov,mp4,m4a,3gp,3g2,mj2",
8248 .item_name = av_default_item_name,
8249 .option = mov_options,
8250 .version = LIBAVUTIL_VERSION_INT,
8253 AVInputFormat ff_mov_demuxer = {
8254 .name = "mov,mp4,m4a,3gp,3g2,mj2",
8255 .long_name = NULL_IF_CONFIG_SMALL("QuickTime / MOV"),
8256 .priv_class = &mov_class,
8257 .priv_data_size = sizeof(MOVContext),
8258 .extensions = "mov,mp4,m4a,3gp,3g2,mj2,psp,m4b,ism,ismv,isma,f4v",
8259 .read_probe = mov_probe,
8260 .read_header = mov_read_header,
8261 .read_packet = mov_read_packet,
8262 .read_close = mov_read_close,
8263 .read_seek = mov_read_seek,
8264 .flags = AVFMT_NO_BYTE_SEEK | AVFMT_SEEK_TO_PTS,