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 static int mov_read_pasp(MOVContext *c, AVIOContext *pb, MOVAtom atom)
946 const int num = avio_rb32(pb);
947 const int den = avio_rb32(pb);
950 if (c->fc->nb_streams < 1)
952 st = c->fc->streams[c->fc->nb_streams-1];
954 if ((st->sample_aspect_ratio.den != 1 || st->sample_aspect_ratio.num) && // default
955 (den != st->sample_aspect_ratio.den || num != st->sample_aspect_ratio.num)) {
956 av_log(c->fc, AV_LOG_WARNING,
957 "sample aspect ratio already set to %d:%d, ignoring 'pasp' atom (%d:%d)\n",
958 st->sample_aspect_ratio.num, st->sample_aspect_ratio.den,
960 } else if (den != 0) {
961 av_reduce(&st->sample_aspect_ratio.num, &st->sample_aspect_ratio.den,
967 /* this atom contains actual media data */
968 static int mov_read_mdat(MOVContext *c, AVIOContext *pb, MOVAtom atom)
970 if (atom.size == 0) /* wrong one (MP4) */
973 return 0; /* now go for moov */
976 #define DRM_BLOB_SIZE 56
978 static int mov_read_adrm(MOVContext *c, AVIOContext *pb, MOVAtom atom)
980 uint8_t intermediate_key[20];
981 uint8_t intermediate_iv[20];
984 uint8_t file_checksum[20];
985 uint8_t calculated_checksum[20];
989 uint8_t *activation_bytes = c->activation_bytes;
990 uint8_t *fixed_key = c->audible_fixed_key;
994 sha = av_sha_alloc();
996 return AVERROR(ENOMEM);
997 av_free(c->aes_decrypt);
998 c->aes_decrypt = av_aes_alloc();
999 if (!c->aes_decrypt) {
1000 ret = AVERROR(ENOMEM);
1004 /* drm blob processing */
1005 avio_read(pb, output, 8); // go to offset 8, absolute position 0x251
1006 avio_read(pb, input, DRM_BLOB_SIZE);
1007 avio_read(pb, output, 4); // go to offset 4, absolute position 0x28d
1008 avio_read(pb, file_checksum, 20);
1010 av_log(c->fc, AV_LOG_INFO, "[aax] file checksum == "); // required by external tools
1011 for (i = 0; i < 20; i++)
1012 av_log(c->fc, AV_LOG_INFO, "%02x", file_checksum[i]);
1013 av_log(c->fc, AV_LOG_INFO, "\n");
1015 /* verify activation data */
1016 if (!activation_bytes) {
1017 av_log(c->fc, AV_LOG_WARNING, "[aax] activation_bytes option is missing!\n");
1018 ret = 0; /* allow ffprobe to continue working on .aax files */
1021 if (c->activation_bytes_size != 4) {
1022 av_log(c->fc, AV_LOG_FATAL, "[aax] activation_bytes value needs to be 4 bytes!\n");
1023 ret = AVERROR(EINVAL);
1027 /* verify fixed key */
1028 if (c->audible_fixed_key_size != 16) {
1029 av_log(c->fc, AV_LOG_FATAL, "[aax] audible_fixed_key value needs to be 16 bytes!\n");
1030 ret = AVERROR(EINVAL);
1034 /* AAX (and AAX+) key derivation */
1035 av_sha_init(sha, 160);
1036 av_sha_update(sha, fixed_key, 16);
1037 av_sha_update(sha, activation_bytes, 4);
1038 av_sha_final(sha, intermediate_key);
1039 av_sha_init(sha, 160);
1040 av_sha_update(sha, fixed_key, 16);
1041 av_sha_update(sha, intermediate_key, 20);
1042 av_sha_update(sha, activation_bytes, 4);
1043 av_sha_final(sha, intermediate_iv);
1044 av_sha_init(sha, 160);
1045 av_sha_update(sha, intermediate_key, 16);
1046 av_sha_update(sha, intermediate_iv, 16);
1047 av_sha_final(sha, calculated_checksum);
1048 if (memcmp(calculated_checksum, file_checksum, 20)) { // critical error
1049 av_log(c->fc, AV_LOG_ERROR, "[aax] mismatch in checksums!\n");
1050 ret = AVERROR_INVALIDDATA;
1053 av_aes_init(c->aes_decrypt, intermediate_key, 128, 1);
1054 av_aes_crypt(c->aes_decrypt, output, input, DRM_BLOB_SIZE >> 4, intermediate_iv, 1);
1055 for (i = 0; i < 4; i++) {
1056 // file data (in output) is stored in big-endian mode
1057 if (activation_bytes[i] != output[3 - i]) { // critical error
1058 av_log(c->fc, AV_LOG_ERROR, "[aax] error in drm blob decryption!\n");
1059 ret = AVERROR_INVALIDDATA;
1063 memcpy(c->file_key, output + 8, 16);
1064 memcpy(input, output + 26, 16);
1065 av_sha_init(sha, 160);
1066 av_sha_update(sha, input, 16);
1067 av_sha_update(sha, c->file_key, 16);
1068 av_sha_update(sha, fixed_key, 16);
1069 av_sha_final(sha, c->file_iv);
1077 static int mov_aaxc_crypto(MOVContext *c)
1079 if (c->audible_key_size != 16) {
1080 av_log(c->fc, AV_LOG_FATAL, "[aaxc] audible_key value needs to be 16 bytes!\n");
1081 return AVERROR(EINVAL);
1084 if (c->audible_iv_size != 16) {
1085 av_log(c->fc, AV_LOG_FATAL, "[aaxc] audible_iv value needs to be 16 bytes!\n");
1086 return AVERROR(EINVAL);
1089 c->aes_decrypt = av_aes_alloc();
1090 if (!c->aes_decrypt) {
1091 return AVERROR(ENOMEM);
1094 memcpy(c->file_key, c->audible_key, 16);
1095 memcpy(c->file_iv, c->audible_iv, 16);
1101 // Audible AAX (and AAX+) bytestream decryption
1102 static int aax_filter(uint8_t *input, int size, MOVContext *c)
1105 unsigned char iv[16];
1107 memcpy(iv, c->file_iv, 16); // iv is overwritten
1108 blocks = size >> 4; // trailing bytes are not encrypted!
1109 av_aes_init(c->aes_decrypt, c->file_key, 128, 1);
1110 av_aes_crypt(c->aes_decrypt, input, input, blocks, iv, 1);
1115 /* read major brand, minor version and compatible brands and store them as metadata */
1116 static int mov_read_ftyp(MOVContext *c, AVIOContext *pb, MOVAtom atom)
1119 int comp_brand_size;
1120 char* comp_brands_str;
1121 uint8_t type[5] = {0};
1122 int ret = ffio_read_size(pb, type, 4);
1126 if (strcmp(type, "qt "))
1128 av_log(c->fc, AV_LOG_DEBUG, "ISO: File Type Major Brand: %.4s\n",(char *)&type);
1129 av_dict_set(&c->fc->metadata, "major_brand", type, 0);
1130 minor_ver = avio_rb32(pb); /* minor version */
1131 av_dict_set_int(&c->fc->metadata, "minor_version", minor_ver, 0);
1133 comp_brand_size = atom.size - 8;
1134 if (comp_brand_size < 0 || comp_brand_size == INT_MAX)
1135 return AVERROR_INVALIDDATA;
1136 comp_brands_str = av_malloc(comp_brand_size + 1); /* Add null terminator */
1137 if (!comp_brands_str)
1138 return AVERROR(ENOMEM);
1140 ret = ffio_read_size(pb, comp_brands_str, comp_brand_size);
1142 av_freep(&comp_brands_str);
1145 comp_brands_str[comp_brand_size] = 0;
1146 av_dict_set(&c->fc->metadata, "compatible_brands",
1147 comp_brands_str, AV_DICT_DONT_STRDUP_VAL);
1149 // Logic for handling Audible's .aaxc files
1150 if (!strcmp(type, "aaxc")) {
1157 /* this atom should contain all header atoms */
1158 static int mov_read_moov(MOVContext *c, AVIOContext *pb, MOVAtom atom)
1162 if (c->found_moov) {
1163 av_log(c->fc, AV_LOG_WARNING, "Found duplicated MOOV Atom. Skipped it\n");
1164 avio_skip(pb, atom.size);
1168 if ((ret = mov_read_default(c, pb, atom)) < 0)
1170 /* we parsed the 'moov' atom, we can terminate the parsing as soon as we find the 'mdat' */
1171 /* so we don't parse the whole file if over a network */
1173 return 0; /* now go for mdat */
1176 static MOVFragmentStreamInfo * get_frag_stream_info(
1177 MOVFragmentIndex *frag_index,
1182 MOVFragmentIndexItem * item;
1184 if (index < 0 || index >= frag_index->nb_items)
1186 item = &frag_index->item[index];
1187 for (i = 0; i < item->nb_stream_info; i++)
1188 if (item->stream_info[i].id == id)
1189 return &item->stream_info[i];
1191 // This shouldn't happen
1195 static void set_frag_stream(MOVFragmentIndex *frag_index, int id)
1198 MOVFragmentIndexItem * item;
1200 if (frag_index->current < 0 ||
1201 frag_index->current >= frag_index->nb_items)
1204 item = &frag_index->item[frag_index->current];
1205 for (i = 0; i < item->nb_stream_info; i++)
1206 if (item->stream_info[i].id == id) {
1211 // id not found. This shouldn't happen.
1215 static MOVFragmentStreamInfo * get_current_frag_stream_info(
1216 MOVFragmentIndex *frag_index)
1218 MOVFragmentIndexItem *item;
1219 if (frag_index->current < 0 ||
1220 frag_index->current >= frag_index->nb_items)
1223 item = &frag_index->item[frag_index->current];
1224 if (item->current >= 0 && item->current < item->nb_stream_info)
1225 return &item->stream_info[item->current];
1227 // This shouldn't happen
1231 static int search_frag_moof_offset(MOVFragmentIndex *frag_index, int64_t offset)
1234 int64_t moof_offset;
1236 // Optimize for appending new entries
1237 if (!frag_index->nb_items ||
1238 frag_index->item[frag_index->nb_items - 1].moof_offset < offset)
1239 return frag_index->nb_items;
1242 b = frag_index->nb_items;
1246 moof_offset = frag_index->item[m].moof_offset;
1247 if (moof_offset >= offset)
1249 if (moof_offset <= offset)
1255 static int64_t get_stream_info_time(MOVFragmentStreamInfo * frag_stream_info)
1257 av_assert0(frag_stream_info);
1258 if (frag_stream_info->sidx_pts != AV_NOPTS_VALUE)
1259 return frag_stream_info->sidx_pts;
1260 if (frag_stream_info->first_tfra_pts != AV_NOPTS_VALUE)
1261 return frag_stream_info->first_tfra_pts;
1262 return frag_stream_info->tfdt_dts;
1265 static int64_t get_frag_time(MOVFragmentIndex *frag_index,
1266 int index, int track_id)
1268 MOVFragmentStreamInfo * frag_stream_info;
1272 if (track_id >= 0) {
1273 frag_stream_info = get_frag_stream_info(frag_index, index, track_id);
1274 if (frag_stream_info->sidx_pts != AV_NOPTS_VALUE)
1275 return frag_stream_info->sidx_pts;
1276 if (frag_stream_info->first_tfra_pts != AV_NOPTS_VALUE)
1277 return frag_stream_info->first_tfra_pts;
1278 return frag_stream_info->sidx_pts;
1281 for (i = 0; i < frag_index->item[index].nb_stream_info; i++) {
1282 frag_stream_info = &frag_index->item[index].stream_info[i];
1283 timestamp = get_stream_info_time(frag_stream_info);
1284 if (timestamp != AV_NOPTS_VALUE)
1287 return AV_NOPTS_VALUE;
1290 static int search_frag_timestamp(MOVFragmentIndex *frag_index,
1291 AVStream *st, int64_t timestamp)
1298 // If the stream is referenced by any sidx, limit the search
1299 // to fragments that referenced this stream in the sidx
1300 MOVStreamContext *sc = st->priv_data;
1306 b = frag_index->nb_items;
1309 m0 = m = (a + b) >> 1;
1312 (frag_time = get_frag_time(frag_index, m, id)) == AV_NOPTS_VALUE)
1315 if (m < b && frag_time <= timestamp)
1324 static int update_frag_index(MOVContext *c, int64_t offset)
1327 MOVFragmentIndexItem * item;
1328 MOVFragmentStreamInfo * frag_stream_info;
1330 // If moof_offset already exists in frag_index, return index to it
1331 index = search_frag_moof_offset(&c->frag_index, offset);
1332 if (index < c->frag_index.nb_items &&
1333 c->frag_index.item[index].moof_offset == offset)
1336 // offset is not yet in frag index.
1337 // Insert new item at index (sorted by moof offset)
1338 item = av_fast_realloc(c->frag_index.item,
1339 &c->frag_index.allocated_size,
1340 (c->frag_index.nb_items + 1) *
1341 sizeof(*c->frag_index.item));
1344 c->frag_index.item = item;
1346 frag_stream_info = av_realloc_array(NULL, c->fc->nb_streams,
1347 sizeof(*item->stream_info));
1348 if (!frag_stream_info)
1351 for (i = 0; i < c->fc->nb_streams; i++) {
1352 // Avoid building frag index if streams lack track id.
1353 if (c->fc->streams[i]->id < 0) {
1354 av_free(frag_stream_info);
1355 return AVERROR_INVALIDDATA;
1358 frag_stream_info[i].id = c->fc->streams[i]->id;
1359 frag_stream_info[i].sidx_pts = AV_NOPTS_VALUE;
1360 frag_stream_info[i].tfdt_dts = AV_NOPTS_VALUE;
1361 frag_stream_info[i].next_trun_dts = AV_NOPTS_VALUE;
1362 frag_stream_info[i].first_tfra_pts = AV_NOPTS_VALUE;
1363 frag_stream_info[i].index_entry = -1;
1364 frag_stream_info[i].encryption_index = NULL;
1367 if (index < c->frag_index.nb_items)
1368 memmove(c->frag_index.item + index + 1, c->frag_index.item + index,
1369 (c->frag_index.nb_items - index) * sizeof(*c->frag_index.item));
1371 item = &c->frag_index.item[index];
1372 item->headers_read = 0;
1374 item->nb_stream_info = c->fc->nb_streams;
1375 item->moof_offset = offset;
1376 item->stream_info = frag_stream_info;
1377 c->frag_index.nb_items++;
1382 static void fix_frag_index_entries(MOVFragmentIndex *frag_index, int index,
1383 int id, int entries)
1386 MOVFragmentStreamInfo * frag_stream_info;
1390 for (i = index; i < frag_index->nb_items; i++) {
1391 frag_stream_info = get_frag_stream_info(frag_index, i, id);
1392 if (frag_stream_info && frag_stream_info->index_entry >= 0)
1393 frag_stream_info->index_entry += entries;
1397 static int mov_read_moof(MOVContext *c, AVIOContext *pb, MOVAtom atom)
1399 // Set by mov_read_tfhd(). mov_read_trun() will reject files missing tfhd.
1400 c->fragment.found_tfhd = 0;
1402 if (!c->has_looked_for_mfra && c->use_mfra_for > 0) {
1403 c->has_looked_for_mfra = 1;
1404 if (pb->seekable & AVIO_SEEKABLE_NORMAL) {
1406 av_log(c->fc, AV_LOG_VERBOSE, "stream has moof boxes, will look "
1408 if ((ret = mov_read_mfra(c, pb)) < 0) {
1409 av_log(c->fc, AV_LOG_VERBOSE, "found a moof box but failed to "
1410 "read the mfra (may be a live ismv)\n");
1413 av_log(c->fc, AV_LOG_VERBOSE, "found a moof box but stream is not "
1414 "seekable, can not look for mfra\n");
1417 c->fragment.moof_offset = c->fragment.implicit_offset = avio_tell(pb) - 8;
1418 av_log(c->fc, AV_LOG_TRACE, "moof offset %"PRIx64"\n", c->fragment.moof_offset);
1419 c->frag_index.current = update_frag_index(c, c->fragment.moof_offset);
1420 return mov_read_default(c, pb, atom);
1423 static void mov_metadata_creation_time(AVDictionary **metadata, int64_t time, void *logctx)
1426 if (time >= 2082844800)
1427 time -= 2082844800; /* seconds between 1904-01-01 and Epoch */
1429 if ((int64_t)(time * 1000000ULL) / 1000000 != time) {
1430 av_log(logctx, AV_LOG_DEBUG, "creation_time is not representable\n");
1434 avpriv_dict_set_timestamp(metadata, "creation_time", time * 1000000);
1438 static int mov_read_mdhd(MOVContext *c, AVIOContext *pb, MOVAtom atom)
1441 MOVStreamContext *sc;
1443 char language[4] = {0};
1445 int64_t creation_time;
1447 if (c->fc->nb_streams < 1)
1449 st = c->fc->streams[c->fc->nb_streams-1];
1452 if (sc->time_scale) {
1453 av_log(c->fc, AV_LOG_ERROR, "Multiple mdhd?\n");
1454 return AVERROR_INVALIDDATA;
1457 version = avio_r8(pb);
1459 avpriv_request_sample(c->fc, "Version %d", version);
1460 return AVERROR_PATCHWELCOME;
1462 avio_rb24(pb); /* flags */
1464 creation_time = avio_rb64(pb);
1467 creation_time = avio_rb32(pb);
1468 avio_rb32(pb); /* modification time */
1470 mov_metadata_creation_time(&st->metadata, creation_time, c->fc);
1472 sc->time_scale = avio_rb32(pb);
1473 if (sc->time_scale <= 0) {
1474 av_log(c->fc, AV_LOG_ERROR, "Invalid mdhd time scale %d, defaulting to 1\n", sc->time_scale);
1477 st->duration = (version == 1) ? avio_rb64(pb) : avio_rb32(pb); /* duration */
1479 lang = avio_rb16(pb); /* language */
1480 if (ff_mov_lang_to_iso639(lang, language))
1481 av_dict_set(&st->metadata, "language", language, 0);
1482 avio_rb16(pb); /* quality */
1487 static int mov_read_mvhd(MOVContext *c, AVIOContext *pb, MOVAtom atom)
1490 int64_t creation_time;
1491 int version = avio_r8(pb); /* version */
1492 avio_rb24(pb); /* flags */
1495 creation_time = avio_rb64(pb);
1498 creation_time = avio_rb32(pb);
1499 avio_rb32(pb); /* modification time */
1501 mov_metadata_creation_time(&c->fc->metadata, creation_time, c->fc);
1502 c->time_scale = avio_rb32(pb); /* time scale */
1503 if (c->time_scale <= 0) {
1504 av_log(c->fc, AV_LOG_ERROR, "Invalid mvhd time scale %d, defaulting to 1\n", c->time_scale);
1507 av_log(c->fc, AV_LOG_TRACE, "time scale = %i\n", c->time_scale);
1509 c->duration = (version == 1) ? avio_rb64(pb) : avio_rb32(pb); /* duration */
1510 // set the AVFormatContext duration because the duration of individual tracks
1511 // may be inaccurate
1513 c->fc->duration = av_rescale(c->duration, AV_TIME_BASE, c->time_scale);
1514 avio_rb32(pb); /* preferred scale */
1516 avio_rb16(pb); /* preferred volume */
1518 avio_skip(pb, 10); /* reserved */
1520 /* movie display matrix, store it in main context and use it later on */
1521 for (i = 0; i < 3; i++) {
1522 c->movie_display_matrix[i][0] = avio_rb32(pb); // 16.16 fixed point
1523 c->movie_display_matrix[i][1] = avio_rb32(pb); // 16.16 fixed point
1524 c->movie_display_matrix[i][2] = avio_rb32(pb); // 2.30 fixed point
1527 avio_rb32(pb); /* preview time */
1528 avio_rb32(pb); /* preview duration */
1529 avio_rb32(pb); /* poster time */
1530 avio_rb32(pb); /* selection time */
1531 avio_rb32(pb); /* selection duration */
1532 avio_rb32(pb); /* current time */
1533 avio_rb32(pb); /* next track ID */
1538 static int mov_read_enda(MOVContext *c, AVIOContext *pb, MOVAtom atom)
1543 if (c->fc->nb_streams < 1)
1545 st = c->fc->streams[c->fc->nb_streams-1];
1547 little_endian = avio_rb16(pb) & 0xFF;
1548 av_log(c->fc, AV_LOG_TRACE, "enda %d\n", little_endian);
1549 if (little_endian == 1) {
1550 switch (st->codecpar->codec_id) {
1551 case AV_CODEC_ID_PCM_S24BE:
1552 st->codecpar->codec_id = AV_CODEC_ID_PCM_S24LE;
1554 case AV_CODEC_ID_PCM_S32BE:
1555 st->codecpar->codec_id = AV_CODEC_ID_PCM_S32LE;
1557 case AV_CODEC_ID_PCM_F32BE:
1558 st->codecpar->codec_id = AV_CODEC_ID_PCM_F32LE;
1560 case AV_CODEC_ID_PCM_F64BE:
1561 st->codecpar->codec_id = AV_CODEC_ID_PCM_F64LE;
1570 static int mov_read_colr(MOVContext *c, AVIOContext *pb, MOVAtom atom)
1573 uint8_t *icc_profile;
1574 char color_parameter_type[5] = { 0 };
1575 uint16_t color_primaries, color_trc, color_matrix;
1578 if (c->fc->nb_streams < 1)
1580 st = c->fc->streams[c->fc->nb_streams - 1];
1582 ret = ffio_read_size(pb, color_parameter_type, 4);
1585 if (strncmp(color_parameter_type, "nclx", 4) &&
1586 strncmp(color_parameter_type, "nclc", 4) &&
1587 strncmp(color_parameter_type, "prof", 4)) {
1588 av_log(c->fc, AV_LOG_WARNING, "unsupported color_parameter_type %s\n",
1589 color_parameter_type);
1593 if (!strncmp(color_parameter_type, "prof", 4)) {
1594 icc_profile = av_stream_new_side_data(st, AV_PKT_DATA_ICC_PROFILE, atom.size - 4);
1596 return AVERROR(ENOMEM);
1597 ret = ffio_read_size(pb, icc_profile, atom.size - 4);
1601 color_primaries = avio_rb16(pb);
1602 color_trc = avio_rb16(pb);
1603 color_matrix = avio_rb16(pb);
1605 av_log(c->fc, AV_LOG_TRACE,
1606 "%s: pri %d trc %d matrix %d",
1607 color_parameter_type, color_primaries, color_trc, color_matrix);
1609 if (!strncmp(color_parameter_type, "nclx", 4)) {
1610 uint8_t color_range = avio_r8(pb) >> 7;
1611 av_log(c->fc, AV_LOG_TRACE, " full %"PRIu8"", color_range);
1613 st->codecpar->color_range = AVCOL_RANGE_JPEG;
1615 st->codecpar->color_range = AVCOL_RANGE_MPEG;
1618 if (!av_color_primaries_name(color_primaries))
1619 color_primaries = AVCOL_PRI_UNSPECIFIED;
1620 if (!av_color_transfer_name(color_trc))
1621 color_trc = AVCOL_TRC_UNSPECIFIED;
1622 if (!av_color_space_name(color_matrix))
1623 color_matrix = AVCOL_SPC_UNSPECIFIED;
1625 st->codecpar->color_primaries = color_primaries;
1626 st->codecpar->color_trc = color_trc;
1627 st->codecpar->color_space = color_matrix;
1628 av_log(c->fc, AV_LOG_TRACE, "\n");
1633 static int mov_read_fiel(MOVContext *c, AVIOContext *pb, MOVAtom atom)
1636 unsigned mov_field_order;
1637 enum AVFieldOrder decoded_field_order = AV_FIELD_UNKNOWN;
1639 if (c->fc->nb_streams < 1) // will happen with jp2 files
1641 st = c->fc->streams[c->fc->nb_streams-1];
1643 return AVERROR_INVALIDDATA;
1644 mov_field_order = avio_rb16(pb);
1645 if ((mov_field_order & 0xFF00) == 0x0100)
1646 decoded_field_order = AV_FIELD_PROGRESSIVE;
1647 else if ((mov_field_order & 0xFF00) == 0x0200) {
1648 switch (mov_field_order & 0xFF) {
1649 case 0x01: decoded_field_order = AV_FIELD_TT;
1651 case 0x06: decoded_field_order = AV_FIELD_BB;
1653 case 0x09: decoded_field_order = AV_FIELD_TB;
1655 case 0x0E: decoded_field_order = AV_FIELD_BT;
1659 if (decoded_field_order == AV_FIELD_UNKNOWN && mov_field_order) {
1660 av_log(c->fc, AV_LOG_ERROR, "Unknown MOV field order 0x%04x\n", mov_field_order);
1662 st->codecpar->field_order = decoded_field_order;
1667 static int mov_realloc_extradata(AVCodecParameters *par, MOVAtom atom)
1670 uint64_t size = (uint64_t)par->extradata_size + atom.size + 8 + AV_INPUT_BUFFER_PADDING_SIZE;
1671 if (size > INT_MAX || (uint64_t)atom.size > INT_MAX)
1672 return AVERROR_INVALIDDATA;
1673 if ((err = av_reallocp(&par->extradata, size)) < 0) {
1674 par->extradata_size = 0;
1677 par->extradata_size = size - AV_INPUT_BUFFER_PADDING_SIZE;
1681 /* Read a whole atom into the extradata return the size of the atom read, possibly truncated if != atom.size */
1682 static int64_t mov_read_atom_into_extradata(MOVContext *c, AVIOContext *pb, MOVAtom atom,
1683 AVCodecParameters *par, uint8_t *buf)
1685 int64_t result = atom.size;
1688 AV_WB32(buf , atom.size + 8);
1689 AV_WL32(buf + 4, atom.type);
1690 err = ffio_read_size(pb, buf + 8, atom.size);
1692 par->extradata_size -= atom.size;
1694 } else if (err < atom.size) {
1695 av_log(c->fc, AV_LOG_WARNING, "truncated extradata\n");
1696 par->extradata_size -= atom.size - err;
1699 memset(buf + 8 + err, 0, AV_INPUT_BUFFER_PADDING_SIZE);
1703 /* FIXME modify QDM2/SVQ3/H.264 decoders to take full atom as extradata */
1704 static int mov_read_extradata(MOVContext *c, AVIOContext *pb, MOVAtom atom,
1705 enum AVCodecID codec_id)
1708 uint64_t original_size;
1711 if (c->fc->nb_streams < 1) // will happen with jp2 files
1713 st = c->fc->streams[c->fc->nb_streams-1];
1715 if (st->codecpar->codec_id != codec_id)
1716 return 0; /* unexpected codec_id - don't mess with extradata */
1718 original_size = st->codecpar->extradata_size;
1719 err = mov_realloc_extradata(st->codecpar, atom);
1723 err = mov_read_atom_into_extradata(c, pb, atom, st->codecpar, st->codecpar->extradata + original_size);
1726 return 0; // Note: this is the original behavior to ignore truncation.
1729 /* wrapper functions for reading ALAC/AVS/MJPEG/MJPEG2000 extradata atoms only for those codecs */
1730 static int mov_read_alac(MOVContext *c, AVIOContext *pb, MOVAtom atom)
1732 return mov_read_extradata(c, pb, atom, AV_CODEC_ID_ALAC);
1735 static int mov_read_avss(MOVContext *c, AVIOContext *pb, MOVAtom atom)
1737 return mov_read_extradata(c, pb, atom, AV_CODEC_ID_AVS);
1740 static int mov_read_jp2h(MOVContext *c, AVIOContext *pb, MOVAtom atom)
1742 return mov_read_extradata(c, pb, atom, AV_CODEC_ID_JPEG2000);
1745 static int mov_read_dpxe(MOVContext *c, AVIOContext *pb, MOVAtom atom)
1747 return mov_read_extradata(c, pb, atom, AV_CODEC_ID_R10K);
1750 static int mov_read_avid(MOVContext *c, AVIOContext *pb, MOVAtom atom)
1752 int ret = mov_read_extradata(c, pb, atom, AV_CODEC_ID_AVUI);
1754 ret = mov_read_extradata(c, pb, atom, AV_CODEC_ID_DNXHD);
1758 static int mov_read_targa_y216(MOVContext *c, AVIOContext *pb, MOVAtom atom)
1760 int ret = mov_read_extradata(c, pb, atom, AV_CODEC_ID_TARGA_Y216);
1762 if (!ret && c->fc->nb_streams >= 1) {
1763 AVCodecParameters *par = c->fc->streams[c->fc->nb_streams-1]->codecpar;
1764 if (par->extradata_size >= 40) {
1765 par->height = AV_RB16(&par->extradata[36]);
1766 par->width = AV_RB16(&par->extradata[38]);
1772 static int mov_read_ares(MOVContext *c, AVIOContext *pb, MOVAtom atom)
1774 if (c->fc->nb_streams >= 1) {
1775 AVCodecParameters *par = c->fc->streams[c->fc->nb_streams-1]->codecpar;
1776 if (par->codec_tag == MKTAG('A', 'V', 'i', 'n') &&
1777 par->codec_id == AV_CODEC_ID_H264 &&
1781 cid = avio_rb16(pb);
1782 /* For AVID AVCI50, force width of 1440 to be able to select the correct SPS and PPS */
1783 if (cid == 0xd4d || cid == 0xd4e)
1786 } else if ((par->codec_tag == MKTAG('A', 'V', 'd', '1') ||
1787 par->codec_tag == MKTAG('A', 'V', 'j', '2') ||
1788 par->codec_tag == MKTAG('A', 'V', 'd', 'n')) &&
1792 num = avio_rb32(pb);
1793 den = avio_rb32(pb);
1794 if (num <= 0 || den <= 0)
1796 switch (avio_rb32(pb)) {
1798 if (den >= INT_MAX / 2)
1802 c->fc->streams[c->fc->nb_streams-1]->internal->display_aspect_ratio.num = num;
1803 c->fc->streams[c->fc->nb_streams-1]->internal->display_aspect_ratio.den = den;
1810 return mov_read_avid(c, pb, atom);
1813 static int mov_read_aclr(MOVContext *c, AVIOContext *pb, MOVAtom atom)
1817 uint64_t original_size;
1818 if (c->fc->nb_streams >= 1) {
1819 AVCodecParameters *par = c->fc->streams[c->fc->nb_streams-1]->codecpar;
1820 if (par->codec_id == AV_CODEC_ID_H264)
1822 if (atom.size == 16) {
1823 original_size = par->extradata_size;
1824 ret = mov_realloc_extradata(par, atom);
1826 length = mov_read_atom_into_extradata(c, pb, atom, par, par->extradata + original_size);
1827 if (length == atom.size) {
1828 const uint8_t range_value = par->extradata[original_size + 19];
1829 switch (range_value) {
1831 par->color_range = AVCOL_RANGE_MPEG;
1834 par->color_range = AVCOL_RANGE_JPEG;
1837 av_log(c->fc, AV_LOG_WARNING, "ignored unknown aclr value (%d)\n", range_value);
1840 ff_dlog(c->fc, "color_range: %d\n", par->color_range);
1842 /* For some reason the whole atom was not added to the extradata */
1843 av_log(c->fc, AV_LOG_ERROR, "aclr not decoded - incomplete atom\n");
1846 av_log(c->fc, AV_LOG_ERROR, "aclr not decoded - unable to add atom to extradata\n");
1849 av_log(c->fc, AV_LOG_WARNING, "aclr not decoded - unexpected size %"PRId64"\n", atom.size);
1856 static int mov_read_svq3(MOVContext *c, AVIOContext *pb, MOVAtom atom)
1858 return mov_read_extradata(c, pb, atom, AV_CODEC_ID_SVQ3);
1861 static int mov_read_wave(MOVContext *c, AVIOContext *pb, MOVAtom atom)
1866 if (c->fc->nb_streams < 1)
1868 st = c->fc->streams[c->fc->nb_streams-1];
1870 if ((uint64_t)atom.size > (1<<30))
1871 return AVERROR_INVALIDDATA;
1873 if (st->codecpar->codec_id == AV_CODEC_ID_QDM2 ||
1874 st->codecpar->codec_id == AV_CODEC_ID_QDMC ||
1875 st->codecpar->codec_id == AV_CODEC_ID_SPEEX) {
1876 // pass all frma atom to codec, needed at least for QDMC and QDM2
1877 ret = ff_get_extradata(c->fc, st->codecpar, pb, atom.size);
1880 } else if (atom.size > 8) { /* to read frma, esds atoms */
1881 if (st->codecpar->codec_id == AV_CODEC_ID_ALAC && atom.size >= 24) {
1883 ret = ffio_ensure_seekback(pb, 8);
1886 buffer = avio_rb64(pb);
1888 if ( (buffer & 0xFFFFFFFF) == MKBETAG('f','r','m','a')
1889 && buffer >> 32 <= atom.size
1890 && buffer >> 32 >= 8) {
1893 } else if (!st->codecpar->extradata_size) {
1894 #define ALAC_EXTRADATA_SIZE 36
1895 st->codecpar->extradata = av_mallocz(ALAC_EXTRADATA_SIZE + AV_INPUT_BUFFER_PADDING_SIZE);
1896 if (!st->codecpar->extradata)
1897 return AVERROR(ENOMEM);
1898 st->codecpar->extradata_size = ALAC_EXTRADATA_SIZE;
1899 AV_WB32(st->codecpar->extradata , ALAC_EXTRADATA_SIZE);
1900 AV_WB32(st->codecpar->extradata + 4, MKTAG('a','l','a','c'));
1901 AV_WB64(st->codecpar->extradata + 12, buffer);
1902 avio_read(pb, st->codecpar->extradata + 20, 16);
1903 avio_skip(pb, atom.size - 24);
1907 if ((ret = mov_read_default(c, pb, atom)) < 0)
1910 avio_skip(pb, atom.size);
1915 * This function reads atom content and puts data in extradata without tag
1916 * nor size unlike mov_read_extradata.
1918 static int mov_read_glbl(MOVContext *c, AVIOContext *pb, MOVAtom atom)
1923 if (c->fc->nb_streams < 1)
1925 st = c->fc->streams[c->fc->nb_streams-1];
1927 if ((uint64_t)atom.size > (1<<30))
1928 return AVERROR_INVALIDDATA;
1930 if (atom.size >= 10) {
1931 // Broken files created by legacy versions of libavformat will
1932 // wrap a whole fiel atom inside of a glbl atom.
1933 unsigned size = avio_rb32(pb);
1934 unsigned type = avio_rl32(pb);
1935 avio_seek(pb, -8, SEEK_CUR);
1936 if (type == MKTAG('f','i','e','l') && size == atom.size)
1937 return mov_read_default(c, pb, atom);
1939 if (st->codecpar->extradata_size > 1 && st->codecpar->extradata) {
1940 av_log(c->fc, AV_LOG_WARNING, "ignoring multiple glbl\n");
1943 ret = ff_get_extradata(c->fc, st->codecpar, pb, atom.size);
1946 if (atom.type == MKTAG('h','v','c','C') && st->codecpar->codec_tag == MKTAG('d','v','h','1'))
1947 /* HEVC-based Dolby Vision derived from hvc1.
1948 Happens to match with an identifier
1949 previously utilized for DV. Thus, if we have
1950 the hvcC extradata box available as specified,
1951 set codec to HEVC */
1952 st->codecpar->codec_id = AV_CODEC_ID_HEVC;
1957 static int mov_read_dvc1(MOVContext *c, AVIOContext *pb, MOVAtom atom)
1960 uint8_t profile_level;
1963 if (c->fc->nb_streams < 1)
1965 st = c->fc->streams[c->fc->nb_streams-1];
1967 if (atom.size >= (1<<28) || atom.size < 7)
1968 return AVERROR_INVALIDDATA;
1970 profile_level = avio_r8(pb);
1971 if ((profile_level & 0xf0) != 0xc0)
1974 avio_seek(pb, 6, SEEK_CUR);
1975 ret = ff_get_extradata(c->fc, st->codecpar, pb, atom.size - 7);
1983 * An strf atom is a BITMAPINFOHEADER struct. This struct is 40 bytes itself,
1984 * but can have extradata appended at the end after the 40 bytes belonging
1987 static int mov_read_strf(MOVContext *c, AVIOContext *pb, MOVAtom atom)
1992 if (c->fc->nb_streams < 1)
1994 if (atom.size <= 40)
1996 st = c->fc->streams[c->fc->nb_streams-1];
1998 if ((uint64_t)atom.size > (1<<30))
1999 return AVERROR_INVALIDDATA;
2002 ret = ff_get_extradata(c->fc, st->codecpar, pb, atom.size - 40);
2009 static int mov_read_stco(MOVContext *c, AVIOContext *pb, MOVAtom atom)
2012 MOVStreamContext *sc;
2013 unsigned int i, entries;
2015 if (c->trak_index < 0) {
2016 av_log(c->fc, AV_LOG_WARNING, "STCO outside TRAK\n");
2019 if (c->fc->nb_streams < 1)
2021 st = c->fc->streams[c->fc->nb_streams-1];
2024 avio_r8(pb); /* version */
2025 avio_rb24(pb); /* flags */
2027 entries = avio_rb32(pb);
2032 if (sc->chunk_offsets) {
2033 av_log(c->fc, AV_LOG_WARNING, "Ignoring duplicated STCO atom\n");
2036 av_free(sc->chunk_offsets);
2037 sc->chunk_count = 0;
2038 sc->chunk_offsets = av_malloc_array(entries, sizeof(*sc->chunk_offsets));
2039 if (!sc->chunk_offsets)
2040 return AVERROR(ENOMEM);
2041 sc->chunk_count = entries;
2043 if (atom.type == MKTAG('s','t','c','o'))
2044 for (i = 0; i < entries && !pb->eof_reached; i++)
2045 sc->chunk_offsets[i] = avio_rb32(pb);
2046 else if (atom.type == MKTAG('c','o','6','4'))
2047 for (i = 0; i < entries && !pb->eof_reached; i++)
2048 sc->chunk_offsets[i] = avio_rb64(pb);
2050 return AVERROR_INVALIDDATA;
2052 sc->chunk_count = i;
2054 if (pb->eof_reached) {
2055 av_log(c->fc, AV_LOG_WARNING, "reached eof, corrupted STCO atom\n");
2062 static int mov_codec_id(AVStream *st, uint32_t format)
2064 int id = ff_codec_get_id(ff_codec_movaudio_tags, format);
2067 ((format & 0xFFFF) == 'm' + ('s' << 8) ||
2068 (format & 0xFFFF) == 'T' + ('S' << 8)))
2069 id = ff_codec_get_id(ff_codec_wav_tags, av_bswap32(format) & 0xFFFF);
2071 if (st->codecpar->codec_type != AVMEDIA_TYPE_VIDEO && id > 0) {
2072 st->codecpar->codec_type = AVMEDIA_TYPE_AUDIO;
2073 } else if (st->codecpar->codec_type != AVMEDIA_TYPE_AUDIO &&
2074 /* skip old ASF MPEG-4 tag */
2075 format && format != MKTAG('m','p','4','s')) {
2076 id = ff_codec_get_id(ff_codec_movvideo_tags, format);
2078 id = ff_codec_get_id(ff_codec_bmp_tags, format);
2080 st->codecpar->codec_type = AVMEDIA_TYPE_VIDEO;
2081 else if (st->codecpar->codec_type == AVMEDIA_TYPE_DATA ||
2082 (st->codecpar->codec_type == AVMEDIA_TYPE_SUBTITLE &&
2083 st->codecpar->codec_id == AV_CODEC_ID_NONE)) {
2084 id = ff_codec_get_id(ff_codec_movsubtitle_tags, format);
2086 st->codecpar->codec_type = AVMEDIA_TYPE_SUBTITLE;
2088 id = ff_codec_get_id(ff_codec_movdata_tags, format);
2092 st->codecpar->codec_tag = format;
2097 static void mov_parse_stsd_video(MOVContext *c, AVIOContext *pb,
2098 AVStream *st, MOVStreamContext *sc)
2100 uint8_t codec_name[32] = { 0 };
2105 /* The first 16 bytes of the video sample description are already
2106 * read in ff_mov_read_stsd_entries() */
2107 stsd_start = avio_tell(pb) - 16;
2109 avio_rb16(pb); /* version */
2110 avio_rb16(pb); /* revision level */
2111 id = avio_rl32(pb); /* vendor */
2112 av_dict_set(&st->metadata, "vendor_id", av_fourcc2str(id), 0);
2113 avio_rb32(pb); /* temporal quality */
2114 avio_rb32(pb); /* spatial quality */
2116 st->codecpar->width = avio_rb16(pb); /* width */
2117 st->codecpar->height = avio_rb16(pb); /* height */
2119 avio_rb32(pb); /* horiz resolution */
2120 avio_rb32(pb); /* vert resolution */
2121 avio_rb32(pb); /* data size, always 0 */
2122 avio_rb16(pb); /* frames per samples */
2124 len = avio_r8(pb); /* codec name, pascal string */
2127 mov_read_mac_string(c, pb, len, codec_name, sizeof(codec_name));
2129 avio_skip(pb, 31 - len);
2132 av_dict_set(&st->metadata, "encoder", codec_name, 0);
2134 /* codec_tag YV12 triggers an UV swap in rawdec.c */
2135 if (!strncmp(codec_name, "Planar Y'CbCr 8-bit 4:2:0", 25)) {
2136 st->codecpar->codec_tag = MKTAG('I', '4', '2', '0');
2137 st->codecpar->width &= ~1;
2138 st->codecpar->height &= ~1;
2140 /* Flash Media Server uses tag H.263 with Sorenson Spark */
2141 if (st->codecpar->codec_tag == MKTAG('H','2','6','3') &&
2142 !strncmp(codec_name, "Sorenson H263", 13))
2143 st->codecpar->codec_id = AV_CODEC_ID_FLV1;
2145 st->codecpar->bits_per_coded_sample = avio_rb16(pb); /* depth */
2147 avio_seek(pb, stsd_start, SEEK_SET);
2149 if (ff_get_qtpalette(st->codecpar->codec_id, pb, sc->palette)) {
2150 st->codecpar->bits_per_coded_sample &= 0x1F;
2151 sc->has_palette = 1;
2155 static void mov_parse_stsd_audio(MOVContext *c, AVIOContext *pb,
2156 AVStream *st, MOVStreamContext *sc)
2158 int bits_per_sample, flags;
2159 uint16_t version = avio_rb16(pb);
2161 AVDictionaryEntry *compatible_brands = av_dict_get(c->fc->metadata, "compatible_brands", NULL, AV_DICT_MATCH_CASE);
2163 avio_rb16(pb); /* revision level */
2164 id = avio_rl32(pb); /* vendor */
2165 av_dict_set(&st->metadata, "vendor_id", av_fourcc2str(id), 0);
2167 st->codecpar->channels = avio_rb16(pb); /* channel count */
2168 st->codecpar->bits_per_coded_sample = avio_rb16(pb); /* sample size */
2169 av_log(c->fc, AV_LOG_TRACE, "audio channels %d\n", st->codecpar->channels);
2171 sc->audio_cid = avio_rb16(pb);
2172 avio_rb16(pb); /* packet size = 0 */
2174 st->codecpar->sample_rate = ((avio_rb32(pb) >> 16));
2176 // Read QT version 1 fields. In version 0 these do not exist.
2177 av_log(c->fc, AV_LOG_TRACE, "version =%d, isom =%d\n", version, c->isom);
2179 (compatible_brands && strstr(compatible_brands->value, "qt ")) ||
2180 (sc->stsd_version == 0 && version > 0)) {
2182 sc->samples_per_frame = avio_rb32(pb);
2183 avio_rb32(pb); /* bytes per packet */
2184 sc->bytes_per_frame = avio_rb32(pb);
2185 avio_rb32(pb); /* bytes per sample */
2186 } else if (version == 2) {
2187 avio_rb32(pb); /* sizeof struct only */
2188 st->codecpar->sample_rate = av_int2double(avio_rb64(pb));
2189 st->codecpar->channels = avio_rb32(pb);
2190 avio_rb32(pb); /* always 0x7F000000 */
2191 st->codecpar->bits_per_coded_sample = avio_rb32(pb);
2193 flags = avio_rb32(pb); /* lpcm format specific flag */
2194 sc->bytes_per_frame = avio_rb32(pb);
2195 sc->samples_per_frame = avio_rb32(pb);
2196 if (st->codecpar->codec_tag == MKTAG('l','p','c','m'))
2197 st->codecpar->codec_id =
2198 ff_mov_get_lpcm_codec_id(st->codecpar->bits_per_coded_sample,
2201 if (version == 0 || (version == 1 && sc->audio_cid != -2)) {
2202 /* can't correctly handle variable sized packet as audio unit */
2203 switch (st->codecpar->codec_id) {
2204 case AV_CODEC_ID_MP2:
2205 case AV_CODEC_ID_MP3:
2206 st->need_parsing = AVSTREAM_PARSE_FULL;
2212 if (sc->format == 0) {
2213 if (st->codecpar->bits_per_coded_sample == 8)
2214 st->codecpar->codec_id = mov_codec_id(st, MKTAG('r','a','w',' '));
2215 else if (st->codecpar->bits_per_coded_sample == 16)
2216 st->codecpar->codec_id = mov_codec_id(st, MKTAG('t','w','o','s'));
2219 switch (st->codecpar->codec_id) {
2220 case AV_CODEC_ID_PCM_S8:
2221 case AV_CODEC_ID_PCM_U8:
2222 if (st->codecpar->bits_per_coded_sample == 16)
2223 st->codecpar->codec_id = AV_CODEC_ID_PCM_S16BE;
2225 case AV_CODEC_ID_PCM_S16LE:
2226 case AV_CODEC_ID_PCM_S16BE:
2227 if (st->codecpar->bits_per_coded_sample == 8)
2228 st->codecpar->codec_id = AV_CODEC_ID_PCM_S8;
2229 else if (st->codecpar->bits_per_coded_sample == 24)
2230 st->codecpar->codec_id =
2231 st->codecpar->codec_id == AV_CODEC_ID_PCM_S16BE ?
2232 AV_CODEC_ID_PCM_S24BE : AV_CODEC_ID_PCM_S24LE;
2233 else if (st->codecpar->bits_per_coded_sample == 32)
2234 st->codecpar->codec_id =
2235 st->codecpar->codec_id == AV_CODEC_ID_PCM_S16BE ?
2236 AV_CODEC_ID_PCM_S32BE : AV_CODEC_ID_PCM_S32LE;
2238 /* set values for old format before stsd version 1 appeared */
2239 case AV_CODEC_ID_MACE3:
2240 sc->samples_per_frame = 6;
2241 sc->bytes_per_frame = 2 * st->codecpar->channels;
2243 case AV_CODEC_ID_MACE6:
2244 sc->samples_per_frame = 6;
2245 sc->bytes_per_frame = 1 * st->codecpar->channels;
2247 case AV_CODEC_ID_ADPCM_IMA_QT:
2248 sc->samples_per_frame = 64;
2249 sc->bytes_per_frame = 34 * st->codecpar->channels;
2251 case AV_CODEC_ID_GSM:
2252 sc->samples_per_frame = 160;
2253 sc->bytes_per_frame = 33;
2259 bits_per_sample = av_get_bits_per_sample(st->codecpar->codec_id);
2260 if (bits_per_sample && (bits_per_sample >> 3) * (uint64_t)st->codecpar->channels <= INT_MAX) {
2261 st->codecpar->bits_per_coded_sample = bits_per_sample;
2262 sc->sample_size = (bits_per_sample >> 3) * st->codecpar->channels;
2266 static void mov_parse_stsd_subtitle(MOVContext *c, AVIOContext *pb,
2267 AVStream *st, MOVStreamContext *sc,
2270 // ttxt stsd contains display flags, justification, background
2271 // color, fonts, and default styles, so fake an atom to read it
2272 MOVAtom fake_atom = { .size = size };
2273 // mp4s contains a regular esds atom
2274 if (st->codecpar->codec_tag != AV_RL32("mp4s"))
2275 mov_read_glbl(c, pb, fake_atom);
2276 st->codecpar->width = sc->width;
2277 st->codecpar->height = sc->height;
2280 static uint32_t yuv_to_rgba(uint32_t ycbcr)
2285 y = (ycbcr >> 16) & 0xFF;
2286 cr = (ycbcr >> 8) & 0xFF;
2289 b = av_clip_uint8((1164 * (y - 16) + 2018 * (cb - 128)) / 1000);
2290 g = av_clip_uint8((1164 * (y - 16) - 813 * (cr - 128) - 391 * (cb - 128)) / 1000);
2291 r = av_clip_uint8((1164 * (y - 16) + 1596 * (cr - 128) ) / 1000);
2293 return (r << 16) | (g << 8) | b;
2296 static int mov_rewrite_dvd_sub_extradata(AVStream *st)
2298 char buf[256] = {0};
2299 uint8_t *src = st->codecpar->extradata;
2302 if (st->codecpar->extradata_size != 64)
2305 if (st->codecpar->width > 0 && st->codecpar->height > 0)
2306 snprintf(buf, sizeof(buf), "size: %dx%d\n",
2307 st->codecpar->width, st->codecpar->height);
2308 av_strlcat(buf, "palette: ", sizeof(buf));
2310 for (i = 0; i < 16; i++) {
2311 uint32_t yuv = AV_RB32(src + i * 4);
2312 uint32_t rgba = yuv_to_rgba(yuv);
2314 av_strlcatf(buf, sizeof(buf), "%06"PRIx32"%s", rgba, i != 15 ? ", " : "");
2317 if (av_strlcat(buf, "\n", sizeof(buf)) >= sizeof(buf))
2320 ret = ff_alloc_extradata(st->codecpar, strlen(buf));
2323 memcpy(st->codecpar->extradata, buf, st->codecpar->extradata_size);
2328 static int mov_parse_stsd_data(MOVContext *c, AVIOContext *pb,
2329 AVStream *st, MOVStreamContext *sc,
2334 if (st->codecpar->codec_tag == MKTAG('t','m','c','d')) {
2335 if ((int)size != size)
2336 return AVERROR(ENOMEM);
2338 ret = ff_get_extradata(c->fc, st->codecpar, pb, size);
2342 MOVStreamContext *tmcd_ctx = st->priv_data;
2344 val = AV_RB32(st->codecpar->extradata + 4);
2345 tmcd_ctx->tmcd_flags = val;
2346 st->avg_frame_rate.num = AV_RB32(st->codecpar->extradata + 8); /* timescale */
2347 st->avg_frame_rate.den = AV_RB32(st->codecpar->extradata + 12); /* frameDuration */
2348 #if FF_API_LAVF_AVCTX
2349 FF_DISABLE_DEPRECATION_WARNINGS
2350 st->codec->time_base = av_inv_q(st->avg_frame_rate);
2351 FF_ENABLE_DEPRECATION_WARNINGS
2354 uint32_t len = AV_RB32(st->codecpar->extradata + 18); /* name atom length */
2355 uint32_t format = AV_RB32(st->codecpar->extradata + 22);
2356 if (format == AV_RB32("name") && (int64_t)size >= (int64_t)len + 18) {
2357 uint16_t str_size = AV_RB16(st->codecpar->extradata + 26); /* string length */
2358 if (str_size > 0 && size >= (int)str_size + 30 &&
2359 st->codecpar->extradata[30] /* Don't add empty string */) {
2360 char *reel_name = av_malloc(str_size + 1);
2362 return AVERROR(ENOMEM);
2363 memcpy(reel_name, st->codecpar->extradata + 30, str_size);
2364 reel_name[str_size] = 0; /* Add null terminator */
2365 av_dict_set(&st->metadata, "reel_name", reel_name,
2366 AV_DICT_DONT_STRDUP_VAL);
2372 /* other codec type, just skip (rtp, mp4s ...) */
2373 avio_skip(pb, size);
2378 static int mov_finalize_stsd_codec(MOVContext *c, AVIOContext *pb,
2379 AVStream *st, MOVStreamContext *sc)
2381 if (st->codecpar->codec_type == AVMEDIA_TYPE_AUDIO &&
2382 !st->codecpar->sample_rate && sc->time_scale > 1)
2383 st->codecpar->sample_rate = sc->time_scale;
2385 /* special codec parameters handling */
2386 switch (st->codecpar->codec_id) {
2387 #if CONFIG_DV_DEMUXER
2388 case AV_CODEC_ID_DVAUDIO:
2389 c->dv_fctx = avformat_alloc_context();
2391 av_log(c->fc, AV_LOG_ERROR, "dv demux context alloc error\n");
2392 return AVERROR(ENOMEM);
2394 c->dv_demux = avpriv_dv_init_demux(c->dv_fctx);
2396 av_log(c->fc, AV_LOG_ERROR, "dv demux context init error\n");
2397 return AVERROR(ENOMEM);
2399 sc->dv_audio_container = 1;
2400 st->codecpar->codec_id = AV_CODEC_ID_PCM_S16LE;
2403 /* no ifdef since parameters are always those */
2404 case AV_CODEC_ID_QCELP:
2405 st->codecpar->channels = 1;
2406 // force sample rate for qcelp when not stored in mov
2407 if (st->codecpar->codec_tag != MKTAG('Q','c','l','p'))
2408 st->codecpar->sample_rate = 8000;
2409 // FIXME: Why is the following needed for some files?
2410 sc->samples_per_frame = 160;
2411 if (!sc->bytes_per_frame)
2412 sc->bytes_per_frame = 35;
2414 case AV_CODEC_ID_AMR_NB:
2415 st->codecpar->channels = 1;
2416 /* force sample rate for amr, stsd in 3gp does not store sample rate */
2417 st->codecpar->sample_rate = 8000;
2419 case AV_CODEC_ID_AMR_WB:
2420 st->codecpar->channels = 1;
2421 st->codecpar->sample_rate = 16000;
2423 case AV_CODEC_ID_MP2:
2424 case AV_CODEC_ID_MP3:
2425 /* force type after stsd for m1a hdlr */
2426 st->codecpar->codec_type = AVMEDIA_TYPE_AUDIO;
2428 case AV_CODEC_ID_GSM:
2429 case AV_CODEC_ID_ADPCM_MS:
2430 case AV_CODEC_ID_ADPCM_IMA_WAV:
2431 case AV_CODEC_ID_ILBC:
2432 case AV_CODEC_ID_MACE3:
2433 case AV_CODEC_ID_MACE6:
2434 case AV_CODEC_ID_QDM2:
2435 st->codecpar->block_align = sc->bytes_per_frame;
2437 case AV_CODEC_ID_ALAC:
2438 if (st->codecpar->extradata_size == 36) {
2439 st->codecpar->channels = AV_RB8 (st->codecpar->extradata + 21);
2440 st->codecpar->sample_rate = AV_RB32(st->codecpar->extradata + 32);
2443 case AV_CODEC_ID_AC3:
2444 case AV_CODEC_ID_EAC3:
2445 case AV_CODEC_ID_MPEG1VIDEO:
2446 case AV_CODEC_ID_VC1:
2447 case AV_CODEC_ID_VP8:
2448 case AV_CODEC_ID_VP9:
2449 st->need_parsing = AVSTREAM_PARSE_FULL;
2451 case AV_CODEC_ID_AV1:
2452 st->need_parsing = AVSTREAM_PARSE_HEADERS;
2460 static int mov_skip_multiple_stsd(MOVContext *c, AVIOContext *pb,
2461 int codec_tag, int format,
2464 int video_codec_id = ff_codec_get_id(ff_codec_movvideo_tags, format);
2467 (codec_tag != format &&
2468 // AVID 1:1 samples with differing data format and codec tag exist
2469 (codec_tag != AV_RL32("AV1x") || format != AV_RL32("AVup")) &&
2470 // prores is allowed to have differing data format and codec tag
2471 codec_tag != AV_RL32("apcn") && codec_tag != AV_RL32("apch") &&
2473 codec_tag != AV_RL32("dvpp") && codec_tag != AV_RL32("dvcp") &&
2474 (c->fc->video_codec_id ? video_codec_id != c->fc->video_codec_id
2475 : codec_tag != MKTAG('j','p','e','g')))) {
2476 /* Multiple fourcc, we skip JPEG. This is not correct, we should
2477 * export it as a separate AVStream but this needs a few changes
2478 * in the MOV demuxer, patch welcome. */
2480 av_log(c->fc, AV_LOG_WARNING, "multiple fourcc not supported\n");
2481 avio_skip(pb, size);
2488 int ff_mov_read_stsd_entries(MOVContext *c, AVIOContext *pb, int entries)
2491 MOVStreamContext *sc;
2492 int pseudo_stream_id;
2494 av_assert0 (c->fc->nb_streams >= 1);
2495 st = c->fc->streams[c->fc->nb_streams-1];
2498 for (pseudo_stream_id = 0;
2499 pseudo_stream_id < entries && !pb->eof_reached;
2500 pseudo_stream_id++) {
2501 //Parsing Sample description table
2503 int ret, dref_id = 1;
2504 MOVAtom a = { AV_RL32("stsd") };
2505 int64_t start_pos = avio_tell(pb);
2506 int64_t size = avio_rb32(pb); /* size */
2507 uint32_t format = avio_rl32(pb); /* data format */
2510 avio_rb32(pb); /* reserved */
2511 avio_rb16(pb); /* reserved */
2512 dref_id = avio_rb16(pb);
2513 } else if (size <= 7) {
2514 av_log(c->fc, AV_LOG_ERROR,
2515 "invalid size %"PRId64" in stsd\n", size);
2516 return AVERROR_INVALIDDATA;
2519 if (mov_skip_multiple_stsd(c, pb, st->codecpar->codec_tag, format,
2520 size - (avio_tell(pb) - start_pos))) {
2525 sc->pseudo_stream_id = st->codecpar->codec_tag ? -1 : pseudo_stream_id;
2526 sc->dref_id= dref_id;
2527 sc->format = format;
2529 id = mov_codec_id(st, format);
2531 av_log(c->fc, AV_LOG_TRACE,
2532 "size=%"PRId64" 4CC=%s codec_type=%d\n", size,
2533 av_fourcc2str(format), st->codecpar->codec_type);
2535 st->codecpar->codec_id = id;
2536 if (st->codecpar->codec_type==AVMEDIA_TYPE_VIDEO) {
2537 mov_parse_stsd_video(c, pb, st, sc);
2538 } else if (st->codecpar->codec_type==AVMEDIA_TYPE_AUDIO) {
2539 mov_parse_stsd_audio(c, pb, st, sc);
2540 if (st->codecpar->sample_rate < 0) {
2541 av_log(c->fc, AV_LOG_ERROR, "Invalid sample rate %d\n", st->codecpar->sample_rate);
2542 return AVERROR_INVALIDDATA;
2544 } else if (st->codecpar->codec_type==AVMEDIA_TYPE_SUBTITLE){
2545 mov_parse_stsd_subtitle(c, pb, st, sc,
2546 size - (avio_tell(pb) - start_pos));
2548 ret = mov_parse_stsd_data(c, pb, st, sc,
2549 size - (avio_tell(pb) - start_pos));
2553 /* this will read extra atoms at the end (wave, alac, damr, avcC, hvcC, SMI ...) */
2554 a.size = size - (avio_tell(pb) - start_pos);
2556 if ((ret = mov_read_default(c, pb, a)) < 0)
2558 } else if (a.size > 0)
2559 avio_skip(pb, a.size);
2561 if (sc->extradata && st->codecpar->extradata) {
2562 int extra_size = st->codecpar->extradata_size;
2564 /* Move the current stream extradata to the stream context one. */
2565 sc->extradata_size[pseudo_stream_id] = extra_size;
2566 sc->extradata[pseudo_stream_id] = st->codecpar->extradata;
2567 st->codecpar->extradata = NULL;
2568 st->codecpar->extradata_size = 0;
2573 if (pb->eof_reached) {
2574 av_log(c->fc, AV_LOG_WARNING, "reached eof, corrupted STSD atom\n");
2581 static int mov_read_stsd(MOVContext *c, AVIOContext *pb, MOVAtom atom)
2584 MOVStreamContext *sc;
2587 if (c->fc->nb_streams < 1)
2589 st = c->fc->streams[c->fc->nb_streams - 1];
2592 sc->stsd_version = avio_r8(pb);
2593 avio_rb24(pb); /* flags */
2594 entries = avio_rb32(pb);
2596 /* Each entry contains a size (4 bytes) and format (4 bytes). */
2597 if (entries <= 0 || entries > atom.size / 8 || entries > 1024) {
2598 av_log(c->fc, AV_LOG_ERROR, "invalid STSD entries %d\n", entries);
2599 return AVERROR_INVALIDDATA;
2602 if (sc->extradata) {
2603 av_log(c->fc, AV_LOG_ERROR,
2604 "Duplicate stsd found in this track.\n");
2605 return AVERROR_INVALIDDATA;
2608 /* Prepare space for hosting multiple extradata. */
2609 sc->extradata = av_mallocz_array(entries, sizeof(*sc->extradata));
2611 return AVERROR(ENOMEM);
2613 sc->extradata_size = av_mallocz_array(entries, sizeof(*sc->extradata_size));
2614 if (!sc->extradata_size) {
2615 ret = AVERROR(ENOMEM);
2619 ret = ff_mov_read_stsd_entries(c, pb, entries);
2623 /* Restore back the primary extradata. */
2624 av_freep(&st->codecpar->extradata);
2625 st->codecpar->extradata_size = sc->extradata_size[0];
2626 if (sc->extradata_size[0]) {
2627 st->codecpar->extradata = av_mallocz(sc->extradata_size[0] + AV_INPUT_BUFFER_PADDING_SIZE);
2628 if (!st->codecpar->extradata)
2629 return AVERROR(ENOMEM);
2630 memcpy(st->codecpar->extradata, sc->extradata[0], sc->extradata_size[0]);
2633 return mov_finalize_stsd_codec(c, pb, st, sc);
2635 if (sc->extradata) {
2637 for (j = 0; j < sc->stsd_count; j++)
2638 av_freep(&sc->extradata[j]);
2641 av_freep(&sc->extradata);
2642 av_freep(&sc->extradata_size);
2646 static int mov_read_stsc(MOVContext *c, AVIOContext *pb, MOVAtom atom)
2649 MOVStreamContext *sc;
2650 unsigned int i, entries;
2652 if (c->fc->nb_streams < 1)
2654 st = c->fc->streams[c->fc->nb_streams-1];
2657 avio_r8(pb); /* version */
2658 avio_rb24(pb); /* flags */
2660 entries = avio_rb32(pb);
2661 if ((uint64_t)entries * 12 + 4 > atom.size)
2662 return AVERROR_INVALIDDATA;
2664 av_log(c->fc, AV_LOG_TRACE, "track[%u].stsc.entries = %u\n", c->fc->nb_streams - 1, entries);
2668 if (sc->stsc_data) {
2669 av_log(c->fc, AV_LOG_WARNING, "Ignoring duplicated STSC atom\n");
2672 av_free(sc->stsc_data);
2674 sc->stsc_data = av_malloc_array(entries, sizeof(*sc->stsc_data));
2676 return AVERROR(ENOMEM);
2678 for (i = 0; i < entries && !pb->eof_reached; i++) {
2679 sc->stsc_data[i].first = avio_rb32(pb);
2680 sc->stsc_data[i].count = avio_rb32(pb);
2681 sc->stsc_data[i].id = avio_rb32(pb);
2685 for (i = sc->stsc_count - 1; i < UINT_MAX; i--) {
2686 int64_t first_min = i + 1;
2687 if ((i+1 < sc->stsc_count && sc->stsc_data[i].first >= sc->stsc_data[i+1].first) ||
2688 (i > 0 && sc->stsc_data[i].first <= sc->stsc_data[i-1].first) ||
2689 sc->stsc_data[i].first < first_min ||
2690 sc->stsc_data[i].count < 1 ||
2691 sc->stsc_data[i].id < 1) {
2692 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);
2693 if (i+1 >= sc->stsc_count) {
2694 if (sc->stsc_data[i].count == 0 && i > 0) {
2698 sc->stsc_data[i].first = FFMAX(sc->stsc_data[i].first, first_min);
2699 if (i > 0 && sc->stsc_data[i].first <= sc->stsc_data[i-1].first)
2700 sc->stsc_data[i].first = FFMIN(sc->stsc_data[i-1].first + 1LL, INT_MAX);
2701 sc->stsc_data[i].count = FFMAX(sc->stsc_data[i].count, 1);
2702 sc->stsc_data[i].id = FFMAX(sc->stsc_data[i].id, 1);
2705 av_assert0(sc->stsc_data[i+1].first >= 2);
2706 // We replace this entry by the next valid
2707 sc->stsc_data[i].first = sc->stsc_data[i+1].first - 1;
2708 sc->stsc_data[i].count = sc->stsc_data[i+1].count;
2709 sc->stsc_data[i].id = sc->stsc_data[i+1].id;
2713 if (pb->eof_reached) {
2714 av_log(c->fc, AV_LOG_WARNING, "reached eof, corrupted STSC atom\n");
2721 static inline int mov_stsc_index_valid(unsigned int index, unsigned int count)
2723 return index < count - 1;
2726 /* Compute the samples value for the stsc entry at the given index. */
2727 static inline int64_t mov_get_stsc_samples(MOVStreamContext *sc, unsigned int index)
2731 if (mov_stsc_index_valid(index, sc->stsc_count))
2732 chunk_count = sc->stsc_data[index + 1].first - sc->stsc_data[index].first;
2734 // Validation for stsc / stco happens earlier in mov_read_stsc + mov_read_trak.
2735 av_assert0(sc->stsc_data[index].first <= sc->chunk_count);
2736 chunk_count = sc->chunk_count - (sc->stsc_data[index].first - 1);
2739 return sc->stsc_data[index].count * (int64_t)chunk_count;
2742 static int mov_read_stps(MOVContext *c, AVIOContext *pb, MOVAtom atom)
2745 MOVStreamContext *sc;
2746 unsigned i, entries;
2748 if (c->fc->nb_streams < 1)
2750 st = c->fc->streams[c->fc->nb_streams-1];
2753 avio_rb32(pb); // version + flags
2755 entries = avio_rb32(pb);
2757 av_log(c->fc, AV_LOG_WARNING, "Duplicated STPS atom\n");
2758 av_free(sc->stps_data);
2760 sc->stps_data = av_malloc_array(entries, sizeof(*sc->stps_data));
2762 return AVERROR(ENOMEM);
2764 for (i = 0; i < entries && !pb->eof_reached; i++) {
2765 sc->stps_data[i] = avio_rb32(pb);
2770 if (pb->eof_reached) {
2771 av_log(c->fc, AV_LOG_WARNING, "reached eof, corrupted STPS atom\n");
2778 static int mov_read_stss(MOVContext *c, AVIOContext *pb, MOVAtom atom)
2781 MOVStreamContext *sc;
2782 unsigned int i, entries;
2784 if (c->fc->nb_streams < 1)
2786 st = c->fc->streams[c->fc->nb_streams-1];
2789 avio_r8(pb); /* version */
2790 avio_rb24(pb); /* flags */
2792 entries = avio_rb32(pb);
2794 av_log(c->fc, AV_LOG_TRACE, "keyframe_count = %u\n", entries);
2797 sc->keyframe_absent = 1;
2798 if (!st->need_parsing && st->codecpar->codec_type == AVMEDIA_TYPE_VIDEO)
2799 st->need_parsing = AVSTREAM_PARSE_HEADERS;
2803 av_log(c->fc, AV_LOG_WARNING, "Duplicated STSS atom\n");
2804 if (entries >= UINT_MAX / sizeof(int))
2805 return AVERROR_INVALIDDATA;
2806 av_freep(&sc->keyframes);
2807 sc->keyframe_count = 0;
2808 sc->keyframes = av_malloc_array(entries, sizeof(*sc->keyframes));
2810 return AVERROR(ENOMEM);
2812 for (i = 0; i < entries && !pb->eof_reached; i++) {
2813 sc->keyframes[i] = avio_rb32(pb);
2816 sc->keyframe_count = i;
2818 if (pb->eof_reached) {
2819 av_log(c->fc, AV_LOG_WARNING, "reached eof, corrupted STSS atom\n");
2826 static int mov_read_stsz(MOVContext *c, AVIOContext *pb, MOVAtom atom)
2829 MOVStreamContext *sc;
2830 unsigned int i, entries, sample_size, field_size, num_bytes;
2835 if (c->fc->nb_streams < 1)
2837 st = c->fc->streams[c->fc->nb_streams-1];
2840 avio_r8(pb); /* version */
2841 avio_rb24(pb); /* flags */
2843 if (atom.type == MKTAG('s','t','s','z')) {
2844 sample_size = avio_rb32(pb);
2845 if (!sc->sample_size) /* do not overwrite value computed in stsd */
2846 sc->sample_size = sample_size;
2847 sc->stsz_sample_size = sample_size;
2851 avio_rb24(pb); /* reserved */
2852 field_size = avio_r8(pb);
2854 entries = avio_rb32(pb);
2856 av_log(c->fc, AV_LOG_TRACE, "sample_size = %u sample_count = %u\n", sc->sample_size, entries);
2858 sc->sample_count = entries;
2862 if (field_size != 4 && field_size != 8 && field_size != 16 && field_size != 32) {
2863 av_log(c->fc, AV_LOG_ERROR, "Invalid sample field size %u\n", field_size);
2864 return AVERROR_INVALIDDATA;
2869 if (entries >= (UINT_MAX - 4) / field_size)
2870 return AVERROR_INVALIDDATA;
2871 if (sc->sample_sizes)
2872 av_log(c->fc, AV_LOG_WARNING, "Duplicated STSZ atom\n");
2873 av_free(sc->sample_sizes);
2874 sc->sample_count = 0;
2875 sc->sample_sizes = av_malloc_array(entries, sizeof(*sc->sample_sizes));
2876 if (!sc->sample_sizes)
2877 return AVERROR(ENOMEM);
2879 num_bytes = (entries*field_size+4)>>3;
2881 buf = av_malloc(num_bytes+AV_INPUT_BUFFER_PADDING_SIZE);
2883 av_freep(&sc->sample_sizes);
2884 return AVERROR(ENOMEM);
2887 ret = ffio_read_size(pb, buf, num_bytes);
2889 av_freep(&sc->sample_sizes);
2891 av_log(c->fc, AV_LOG_WARNING, "STSZ atom truncated\n");
2895 init_get_bits(&gb, buf, 8*num_bytes);
2897 for (i = 0; i < entries && !pb->eof_reached; i++) {
2898 sc->sample_sizes[i] = get_bits_long(&gb, field_size);
2899 if (sc->sample_sizes[i] < 0) {
2901 av_log(c->fc, AV_LOG_ERROR, "Invalid sample size %d\n", sc->sample_sizes[i]);
2902 return AVERROR_INVALIDDATA;
2904 sc->data_size += sc->sample_sizes[i];
2907 sc->sample_count = i;
2911 if (pb->eof_reached) {
2912 av_log(c->fc, AV_LOG_WARNING, "reached eof, corrupted STSZ atom\n");
2919 static int mov_read_stts(MOVContext *c, AVIOContext *pb, MOVAtom atom)
2922 MOVStreamContext *sc;
2923 unsigned int i, entries, alloc_size = 0;
2924 int64_t duration = 0;
2925 int64_t total_sample_count = 0;
2927 if (c->fc->nb_streams < 1)
2929 st = c->fc->streams[c->fc->nb_streams-1];
2932 avio_r8(pb); /* version */
2933 avio_rb24(pb); /* flags */
2934 entries = avio_rb32(pb);
2936 av_log(c->fc, AV_LOG_TRACE, "track[%u].stts.entries = %u\n",
2937 c->fc->nb_streams-1, entries);
2940 av_log(c->fc, AV_LOG_WARNING, "Duplicated STTS atom\n");
2941 av_freep(&sc->stts_data);
2943 if (entries >= INT_MAX / sizeof(*sc->stts_data))
2944 return AVERROR(ENOMEM);
2946 for (i = 0; i < entries && !pb->eof_reached; i++) {
2947 int sample_duration;
2948 unsigned int sample_count;
2949 unsigned int min_entries = FFMIN(FFMAX(i + 1, 1024 * 1024), entries);
2950 MOVStts *stts_data = av_fast_realloc(sc->stts_data, &alloc_size,
2951 min_entries * sizeof(*sc->stts_data));
2953 av_freep(&sc->stts_data);
2955 return AVERROR(ENOMEM);
2957 sc->stts_count = min_entries;
2958 sc->stts_data = stts_data;
2960 sample_count = avio_rb32(pb);
2961 sample_duration = avio_rb32(pb);
2963 sc->stts_data[i].count= sample_count;
2964 sc->stts_data[i].duration= sample_duration;
2966 av_log(c->fc, AV_LOG_TRACE, "sample_count=%d, sample_duration=%d\n",
2967 sample_count, sample_duration);
2969 duration+=(int64_t)sample_duration*(uint64_t)sample_count;
2970 total_sample_count+=sample_count;
2976 duration <= INT64_MAX - sc->duration_for_fps &&
2977 total_sample_count <= INT_MAX - sc->nb_frames_for_fps) {
2978 sc->duration_for_fps += duration;
2979 sc->nb_frames_for_fps += total_sample_count;
2982 if (pb->eof_reached) {
2983 av_log(c->fc, AV_LOG_WARNING, "reached eof, corrupted STTS atom\n");
2987 st->nb_frames= total_sample_count;
2989 st->duration= FFMIN(st->duration, duration);
2990 sc->track_end = duration;
2994 static int mov_read_sdtp(MOVContext *c, AVIOContext *pb, MOVAtom atom)
2997 MOVStreamContext *sc;
3000 if (c->fc->nb_streams < 1)
3002 st = c->fc->streams[c->fc->nb_streams - 1];
3005 avio_r8(pb); /* version */
3006 avio_rb24(pb); /* flags */
3007 entries = atom.size - 4;
3009 av_log(c->fc, AV_LOG_TRACE, "track[%u].sdtp.entries = %" PRId64 "\n",
3010 c->fc->nb_streams - 1, entries);
3013 av_log(c->fc, AV_LOG_WARNING, "Duplicated SDTP atom\n");
3014 av_freep(&sc->sdtp_data);
3017 sc->sdtp_data = av_malloc(entries);
3019 return AVERROR(ENOMEM);
3021 for (i = 0; i < entries && !pb->eof_reached; i++)
3022 sc->sdtp_data[i] = avio_r8(pb);
3028 static void mov_update_dts_shift(MOVStreamContext *sc, int duration, void *logctx)
3031 if (duration == INT_MIN) {
3032 av_log(logctx, AV_LOG_WARNING, "mov_update_dts_shift(): dts_shift set to %d\n", INT_MAX);
3035 sc->dts_shift = FFMAX(sc->dts_shift, -duration);
3039 static int mov_read_ctts(MOVContext *c, AVIOContext *pb, MOVAtom atom)
3042 MOVStreamContext *sc;
3043 unsigned int i, entries, ctts_count = 0;
3045 if (c->fc->nb_streams < 1)
3047 st = c->fc->streams[c->fc->nb_streams-1];
3050 avio_r8(pb); /* version */
3051 avio_rb24(pb); /* flags */
3052 entries = avio_rb32(pb);
3054 av_log(c->fc, AV_LOG_TRACE, "track[%u].ctts.entries = %u\n", c->fc->nb_streams - 1, entries);
3058 if (entries >= UINT_MAX / sizeof(*sc->ctts_data))
3059 return AVERROR_INVALIDDATA;
3060 av_freep(&sc->ctts_data);
3061 sc->ctts_data = av_fast_realloc(NULL, &sc->ctts_allocated_size, entries * sizeof(*sc->ctts_data));
3063 return AVERROR(ENOMEM);
3065 for (i = 0; i < entries && !pb->eof_reached; i++) {
3066 int count = avio_rb32(pb);
3067 int duration = avio_rb32(pb);
3070 av_log(c->fc, AV_LOG_TRACE,
3071 "ignoring CTTS entry with count=%d duration=%d\n",
3076 add_ctts_entry(&sc->ctts_data, &ctts_count, &sc->ctts_allocated_size,
3079 av_log(c->fc, AV_LOG_TRACE, "count=%d, duration=%d\n",
3082 if (FFNABS(duration) < -(1<<28) && i+2<entries) {
3083 av_log(c->fc, AV_LOG_WARNING, "CTTS invalid\n");
3084 av_freep(&sc->ctts_data);
3090 mov_update_dts_shift(sc, duration, c->fc);
3093 sc->ctts_count = ctts_count;
3095 if (pb->eof_reached) {
3096 av_log(c->fc, AV_LOG_WARNING, "reached eof, corrupted CTTS atom\n");
3100 av_log(c->fc, AV_LOG_TRACE, "dts shift %d\n", sc->dts_shift);
3105 static int mov_read_sbgp(MOVContext *c, AVIOContext *pb, MOVAtom atom)
3108 MOVStreamContext *sc;
3109 unsigned int i, entries;
3111 uint32_t grouping_type;
3113 if (c->fc->nb_streams < 1)
3115 st = c->fc->streams[c->fc->nb_streams-1];
3118 version = avio_r8(pb); /* version */
3119 avio_rb24(pb); /* flags */
3120 grouping_type = avio_rl32(pb);
3121 if (grouping_type != MKTAG( 'r','a','p',' '))
3122 return 0; /* only support 'rap ' grouping */
3124 avio_rb32(pb); /* grouping_type_parameter */
3126 entries = avio_rb32(pb);
3130 av_log(c->fc, AV_LOG_WARNING, "Duplicated SBGP atom\n");
3131 av_free(sc->rap_group);
3132 sc->rap_group_count = 0;
3133 sc->rap_group = av_malloc_array(entries, sizeof(*sc->rap_group));
3135 return AVERROR(ENOMEM);
3137 for (i = 0; i < entries && !pb->eof_reached; i++) {
3138 sc->rap_group[i].count = avio_rb32(pb); /* sample_count */
3139 sc->rap_group[i].index = avio_rb32(pb); /* group_description_index */
3142 sc->rap_group_count = i;
3144 if (pb->eof_reached) {
3145 av_log(c->fc, AV_LOG_WARNING, "reached eof, corrupted SBGP atom\n");
3153 * Get ith edit list entry (media time, duration).
3155 static int get_edit_list_entry(MOVContext *mov,
3156 const MOVStreamContext *msc,
3157 unsigned int edit_list_index,
3158 int64_t *edit_list_media_time,
3159 int64_t *edit_list_duration,
3160 int64_t global_timescale)
3162 if (edit_list_index == msc->elst_count) {
3165 *edit_list_media_time = msc->elst_data[edit_list_index].time;
3166 *edit_list_duration = msc->elst_data[edit_list_index].duration;
3168 /* duration is in global timescale units;convert to msc timescale */
3169 if (global_timescale == 0) {
3170 avpriv_request_sample(mov->fc, "Support for mvhd.timescale = 0 with editlists");
3173 *edit_list_duration = av_rescale(*edit_list_duration, msc->time_scale,
3179 * Find the closest previous frame to the timestamp_pts, in e_old index
3180 * entries. Searching for just any frame / just key frames can be controlled by
3181 * last argument 'flag'.
3182 * Note that if ctts_data is not NULL, we will always search for a key frame
3183 * irrespective of the value of 'flag'. If we don't find any keyframe, we will
3184 * return the first frame of the video.
3186 * Here the timestamp_pts is considered to be a presentation timestamp and
3187 * the timestamp of index entries are considered to be decoding timestamps.
3189 * Returns 0 if successful in finding a frame, else returns -1.
3190 * Places the found index corresponding output arg.
3192 * If ctts_old is not NULL, then refines the searched entry by searching
3193 * backwards from the found timestamp, to find the frame with correct PTS.
3195 * Places the found ctts_index and ctts_sample in corresponding output args.
3197 static int find_prev_closest_index(AVStream *st,
3198 AVIndexEntry *e_old,
3202 int64_t timestamp_pts,
3205 int64_t* ctts_index,
3206 int64_t* ctts_sample)
3208 MOVStreamContext *msc = st->priv_data;
3209 AVIndexEntry *e_keep = st->internal->index_entries;
3210 int nb_keep = st->internal->nb_index_entries;
3212 int64_t index_ctts_count;
3216 // If dts_shift > 0, then all the index timestamps will have to be offset by
3217 // at least dts_shift amount to obtain PTS.
3218 // Hence we decrement the searched timestamp_pts by dts_shift to find the closest index element.
3219 if (msc->dts_shift > 0) {
3220 timestamp_pts -= msc->dts_shift;
3223 st->internal->index_entries = e_old;
3224 st->internal->nb_index_entries = nb_old;
3225 *index = av_index_search_timestamp(st, timestamp_pts, flag | AVSEEK_FLAG_BACKWARD);
3227 // Keep going backwards in the index entries until the timestamp is the same.
3229 for (i = *index; i > 0 && e_old[i].timestamp == e_old[i - 1].timestamp;
3231 if ((flag & AVSEEK_FLAG_ANY) ||
3232 (e_old[i - 1].flags & AVINDEX_KEYFRAME)) {
3238 // If we have CTTS then refine the search, by searching backwards over PTS
3239 // computed by adding corresponding CTTS durations to index timestamps.
3240 if (ctts_data && *index >= 0) {
3241 av_assert0(ctts_index);
3242 av_assert0(ctts_sample);
3243 // Find out the ctts_index for the found frame.
3246 for (index_ctts_count = 0; index_ctts_count < *index; index_ctts_count++) {
3247 if (*ctts_index < ctts_count) {
3249 if (ctts_data[*ctts_index].count == *ctts_sample) {
3256 while (*index >= 0 && (*ctts_index) >= 0 && (*ctts_index) < ctts_count) {
3257 // Find a "key frame" with PTS <= timestamp_pts (So that we can decode B-frames correctly).
3258 // No need to add dts_shift to the timestamp here becase timestamp_pts has already been
3259 // compensated by dts_shift above.
3260 if ((e_old[*index].timestamp + ctts_data[*ctts_index].duration) <= timestamp_pts &&
3261 (e_old[*index].flags & AVINDEX_KEYFRAME)) {
3266 if (*ctts_sample == 0) {
3268 if (*ctts_index >= 0)
3269 *ctts_sample = ctts_data[*ctts_index].count - 1;
3276 /* restore AVStream state*/
3277 st->internal->index_entries = e_keep;
3278 st->internal->nb_index_entries = nb_keep;
3279 return *index >= 0 ? 0 : -1;
3283 * Add index entry with the given values, to the end of st->internal->index_entries.
3284 * Returns the new size st->internal->index_entries if successful, else returns -1.
3286 * This function is similar to ff_add_index_entry in libavformat/utils.c
3287 * except that here we are always unconditionally adding an index entry to
3288 * the end, instead of searching the entries list and skipping the add if
3289 * there is an existing entry with the same timestamp.
3290 * This is needed because the mov_fix_index calls this func with the same
3291 * unincremented timestamp for successive discarded frames.
3293 static int64_t add_index_entry(AVStream *st, int64_t pos, int64_t timestamp,
3294 int size, int distance, int flags)
3296 AVIndexEntry *entries, *ie;
3298 const size_t min_size_needed = (st->internal->nb_index_entries + 1) * sizeof(AVIndexEntry);
3300 // Double the allocation each time, to lower memory fragmentation.
3301 // Another difference from ff_add_index_entry function.
3302 const size_t requested_size =
3303 min_size_needed > st->internal->index_entries_allocated_size ?
3304 FFMAX(min_size_needed, 2 * st->internal->index_entries_allocated_size) :
3307 if (st->internal->nb_index_entries + 1U >= UINT_MAX / sizeof(AVIndexEntry))
3310 entries = av_fast_realloc(st->internal->index_entries,
3311 &st->internal->index_entries_allocated_size,
3316 st->internal->index_entries= entries;
3318 index= st->internal->nb_index_entries++;
3319 ie= &entries[index];
3322 ie->timestamp = timestamp;
3323 ie->min_distance= distance;
3330 * Rewrite timestamps of index entries in the range [end_index - frame_duration_buffer_size, end_index)
3331 * by subtracting end_ts successively by the amounts given in frame_duration_buffer.
3333 static void fix_index_entry_timestamps(AVStream* st, int end_index, int64_t end_ts,
3334 int64_t* frame_duration_buffer,
3335 int frame_duration_buffer_size) {
3337 av_assert0(end_index >= 0 && end_index <= st->internal->nb_index_entries);
3338 for (i = 0; i < frame_duration_buffer_size; i++) {
3339 end_ts -= frame_duration_buffer[frame_duration_buffer_size - 1 - i];
3340 st->internal->index_entries[end_index - 1 - i].timestamp = end_ts;
3345 * Append a new ctts entry to ctts_data.
3346 * Returns the new ctts_count if successful, else returns -1.
3348 static int64_t add_ctts_entry(MOVStts** ctts_data, unsigned int* ctts_count, unsigned int* allocated_size,
3349 int count, int duration)
3351 MOVStts *ctts_buf_new;
3352 const size_t min_size_needed = (*ctts_count + 1) * sizeof(MOVStts);
3353 const size_t requested_size =
3354 min_size_needed > *allocated_size ?
3355 FFMAX(min_size_needed, 2 * (*allocated_size)) :
3358 if ((unsigned)(*ctts_count) >= UINT_MAX / sizeof(MOVStts) - 1)
3361 ctts_buf_new = av_fast_realloc(*ctts_data, allocated_size, requested_size);
3366 *ctts_data = ctts_buf_new;
3368 ctts_buf_new[*ctts_count].count = count;
3369 ctts_buf_new[*ctts_count].duration = duration;
3371 *ctts_count = (*ctts_count) + 1;
3375 #define MAX_REORDER_DELAY 16
3376 static void mov_estimate_video_delay(MOVContext *c, AVStream* st)
3378 MOVStreamContext *msc = st->priv_data;
3381 int ctts_sample = 0;
3382 int64_t pts_buf[MAX_REORDER_DELAY + 1]; // Circular buffer to sort pts.
3384 int j, r, num_swaps;
3386 for (j = 0; j < MAX_REORDER_DELAY + 1; j++)
3387 pts_buf[j] = INT64_MIN;
3389 if (st->codecpar->video_delay <= 0 && msc->ctts_data &&
3390 st->codecpar->codec_id == AV_CODEC_ID_H264) {
3391 st->codecpar->video_delay = 0;
3392 for (ind = 0; ind < st->internal->nb_index_entries && ctts_ind < msc->ctts_count; ++ind) {
3393 // Point j to the last elem of the buffer and insert the current pts there.
3395 buf_start = (buf_start + 1);
3396 if (buf_start == MAX_REORDER_DELAY + 1)
3399 pts_buf[j] = st->internal->index_entries[ind].timestamp + msc->ctts_data[ctts_ind].duration;
3401 // The timestamps that are already in the sorted buffer, and are greater than the
3402 // current pts, are exactly the timestamps that need to be buffered to output PTS
3403 // in correct sorted order.
3404 // Hence the video delay (which is the buffer size used to sort DTS and output PTS),
3405 // can be computed as the maximum no. of swaps any particular timestamp needs to
3406 // go through, to keep this buffer in sorted order.
3408 while (j != buf_start) {
3410 if (r < 0) r = MAX_REORDER_DELAY;
3411 if (pts_buf[j] < pts_buf[r]) {
3412 FFSWAP(int64_t, pts_buf[j], pts_buf[r]);
3419 st->codecpar->video_delay = FFMAX(st->codecpar->video_delay, num_swaps);
3422 if (ctts_sample == msc->ctts_data[ctts_ind].count) {
3427 av_log(c->fc, AV_LOG_DEBUG, "Setting codecpar->delay to %d for stream st: %d\n",
3428 st->codecpar->video_delay, st->index);
3432 static void mov_current_sample_inc(MOVStreamContext *sc)
3434 sc->current_sample++;
3435 sc->current_index++;
3436 if (sc->index_ranges &&
3437 sc->current_index >= sc->current_index_range->end &&
3438 sc->current_index_range->end) {
3439 sc->current_index_range++;
3440 sc->current_index = sc->current_index_range->start;
3444 static void mov_current_sample_dec(MOVStreamContext *sc)
3446 sc->current_sample--;
3447 sc->current_index--;
3448 if (sc->index_ranges &&
3449 sc->current_index < sc->current_index_range->start &&
3450 sc->current_index_range > sc->index_ranges) {
3451 sc->current_index_range--;
3452 sc->current_index = sc->current_index_range->end - 1;
3456 static void mov_current_sample_set(MOVStreamContext *sc, int current_sample)
3460 sc->current_sample = current_sample;
3461 sc->current_index = current_sample;
3462 if (!sc->index_ranges) {
3466 for (sc->current_index_range = sc->index_ranges;
3467 sc->current_index_range->end;
3468 sc->current_index_range++) {
3469 range_size = sc->current_index_range->end - sc->current_index_range->start;
3470 if (range_size > current_sample) {
3471 sc->current_index = sc->current_index_range->start + current_sample;
3474 current_sample -= range_size;
3479 * Fix st->internal->index_entries, so that it contains only the entries (and the entries
3480 * which are needed to decode them) that fall in the edit list time ranges.
3481 * Also fixes the timestamps of the index entries to match the timeline
3482 * specified the edit lists.
3484 static void mov_fix_index(MOVContext *mov, AVStream *st)
3486 MOVStreamContext *msc = st->priv_data;
3487 AVIndexEntry *e_old = st->internal->index_entries;
3488 int nb_old = st->internal->nb_index_entries;
3489 const AVIndexEntry *e_old_end = e_old + nb_old;
3490 const AVIndexEntry *current = NULL;
3491 MOVStts *ctts_data_old = msc->ctts_data;
3492 int64_t ctts_index_old = 0;
3493 int64_t ctts_sample_old = 0;
3494 int64_t ctts_count_old = msc->ctts_count;
3495 int64_t edit_list_media_time = 0;
3496 int64_t edit_list_duration = 0;
3497 int64_t frame_duration = 0;
3498 int64_t edit_list_dts_counter = 0;
3499 int64_t edit_list_dts_entry_end = 0;
3500 int64_t edit_list_start_ctts_sample = 0;
3502 int64_t curr_ctts = 0;
3503 int64_t empty_edits_sum_duration = 0;
3504 int64_t edit_list_index = 0;
3507 int64_t start_dts = 0;
3508 int64_t edit_list_start_encountered = 0;
3509 int64_t search_timestamp = 0;
3510 int64_t* frame_duration_buffer = NULL;
3511 int num_discarded_begin = 0;
3512 int first_non_zero_audio_edit = -1;
3513 int packet_skip_samples = 0;
3514 MOVIndexRange *current_index_range;
3516 int found_keyframe_after_edit = 0;
3517 int found_non_empty_edit = 0;
3519 if (!msc->elst_data || msc->elst_count <= 0 || nb_old <= 0) {
3523 // allocate the index ranges array
3524 msc->index_ranges = av_malloc((msc->elst_count + 1) * sizeof(msc->index_ranges[0]));
3525 if (!msc->index_ranges) {
3526 av_log(mov->fc, AV_LOG_ERROR, "Cannot allocate index ranges buffer\n");
3529 msc->current_index_range = msc->index_ranges;
3530 current_index_range = msc->index_ranges - 1;
3532 // Clean AVStream from traces of old index
3533 st->internal->index_entries = NULL;
3534 st->internal->index_entries_allocated_size = 0;
3535 st->internal->nb_index_entries = 0;
3537 // Clean ctts fields of MOVStreamContext
3538 msc->ctts_data = NULL;
3539 msc->ctts_count = 0;
3540 msc->ctts_index = 0;
3541 msc->ctts_sample = 0;
3542 msc->ctts_allocated_size = 0;
3544 // Reinitialize min_corrected_pts so that it can be computed again.
3545 msc->min_corrected_pts = -1;
3547 // If the dts_shift is positive (in case of negative ctts values in mov),
3548 // then negate the DTS by dts_shift
3549 if (msc->dts_shift > 0) {
3550 edit_list_dts_entry_end -= msc->dts_shift;
3551 av_log(mov->fc, AV_LOG_DEBUG, "Shifting DTS by %d because of negative CTTS.\n", msc->dts_shift);
3554 start_dts = edit_list_dts_entry_end;
3556 while (get_edit_list_entry(mov, msc, edit_list_index, &edit_list_media_time,
3557 &edit_list_duration, mov->time_scale)) {
3558 av_log(mov->fc, AV_LOG_DEBUG, "Processing st: %d, edit list %"PRId64" - media time: %"PRId64", duration: %"PRId64"\n",
3559 st->index, edit_list_index, edit_list_media_time, edit_list_duration);
3561 edit_list_dts_counter = edit_list_dts_entry_end;
3562 edit_list_dts_entry_end += edit_list_duration;
3563 num_discarded_begin = 0;
3564 if (!found_non_empty_edit && edit_list_media_time == -1) {
3565 empty_edits_sum_duration += edit_list_duration;
3568 found_non_empty_edit = 1;
3570 // If we encounter a non-negative edit list reset the skip_samples/start_pad fields and set them
3571 // according to the edit list below.
3572 if (st->codecpar->codec_type == AVMEDIA_TYPE_AUDIO) {
3573 if (first_non_zero_audio_edit < 0) {
3574 first_non_zero_audio_edit = 1;
3576 first_non_zero_audio_edit = 0;
3579 if (first_non_zero_audio_edit > 0)
3580 st->internal->skip_samples = msc->start_pad = 0;
3583 // While reordering frame index according to edit list we must handle properly
3584 // the scenario when edit list entry starts from none key frame.
3585 // We find closest previous key frame and preserve it and consequent frames in index.
3586 // All frames which are outside edit list entry time boundaries will be dropped after decoding.
3587 search_timestamp = edit_list_media_time;
3588 if (st->codecpar->codec_type == AVMEDIA_TYPE_AUDIO) {
3589 // Audio decoders like AAC need need a decoder delay samples previous to the current sample,
3590 // to correctly decode this frame. Hence for audio we seek to a frame 1 sec. before the
3591 // edit_list_media_time to cover the decoder delay.
3592 search_timestamp = FFMAX(search_timestamp - msc->time_scale, e_old[0].timestamp);
3595 if (find_prev_closest_index(st, e_old, nb_old, ctts_data_old, ctts_count_old, search_timestamp, 0,
3596 &index, &ctts_index_old, &ctts_sample_old) < 0) {
3597 av_log(mov->fc, AV_LOG_WARNING,
3598 "st: %d edit list: %"PRId64" Missing key frame while searching for timestamp: %"PRId64"\n",
3599 st->index, edit_list_index, search_timestamp);
3600 if (find_prev_closest_index(st, e_old, nb_old, ctts_data_old, ctts_count_old, search_timestamp, AVSEEK_FLAG_ANY,
3601 &index, &ctts_index_old, &ctts_sample_old) < 0) {
3602 av_log(mov->fc, AV_LOG_WARNING,
3603 "st: %d edit list %"PRId64" Cannot find an index entry before timestamp: %"PRId64".\n",
3604 st->index, edit_list_index, search_timestamp);
3607 ctts_sample_old = 0;
3610 current = e_old + index;
3611 edit_list_start_ctts_sample = ctts_sample_old;
3613 // Iterate over index and arrange it according to edit list
3614 edit_list_start_encountered = 0;
3615 found_keyframe_after_edit = 0;
3616 for (; current < e_old_end; current++, index++) {
3617 // check if frame outside edit list mark it for discard
3618 frame_duration = (current + 1 < e_old_end) ?
3619 ((current + 1)->timestamp - current->timestamp) : edit_list_duration;
3621 flags = current->flags;
3623 // frames (pts) before or after edit list
3624 curr_cts = current->timestamp + msc->dts_shift;
3627 if (ctts_data_old && ctts_index_old < ctts_count_old) {
3628 curr_ctts = ctts_data_old[ctts_index_old].duration;
3629 av_log(mov->fc, AV_LOG_DEBUG, "stts: %"PRId64" ctts: %"PRId64", ctts_index: %"PRId64", ctts_count: %"PRId64"\n",
3630 curr_cts, curr_ctts, ctts_index_old, ctts_count_old);
3631 curr_cts += curr_ctts;
3633 if (ctts_sample_old == ctts_data_old[ctts_index_old].count) {
3634 if (add_ctts_entry(&msc->ctts_data, &msc->ctts_count,
3635 &msc->ctts_allocated_size,
3636 ctts_data_old[ctts_index_old].count - edit_list_start_ctts_sample,
3637 ctts_data_old[ctts_index_old].duration) == -1) {
3638 av_log(mov->fc, AV_LOG_ERROR, "Cannot add CTTS entry %"PRId64" - {%"PRId64", %d}\n",
3640 ctts_data_old[ctts_index_old].count - edit_list_start_ctts_sample,
3641 ctts_data_old[ctts_index_old].duration);
3645 ctts_sample_old = 0;
3646 edit_list_start_ctts_sample = 0;
3650 if (curr_cts < edit_list_media_time || curr_cts >= (edit_list_duration + edit_list_media_time)) {
3651 if (st->codecpar->codec_type == AVMEDIA_TYPE_AUDIO && st->codecpar->codec_id != AV_CODEC_ID_VORBIS &&
3652 curr_cts < edit_list_media_time && curr_cts + frame_duration > edit_list_media_time &&
3653 first_non_zero_audio_edit > 0) {
3654 packet_skip_samples = edit_list_media_time - curr_cts;
3655 st->internal->skip_samples += packet_skip_samples;
3657 // Shift the index entry timestamp by packet_skip_samples to be correct.
3658 edit_list_dts_counter -= packet_skip_samples;
3659 if (edit_list_start_encountered == 0) {
3660 edit_list_start_encountered = 1;
3661 // Make timestamps strictly monotonically increasing for audio, by rewriting timestamps for
3662 // discarded packets.
3663 if (frame_duration_buffer) {
3664 fix_index_entry_timestamps(st, st->internal->nb_index_entries, edit_list_dts_counter,
3665 frame_duration_buffer, num_discarded_begin);
3666 av_freep(&frame_duration_buffer);
3670 av_log(mov->fc, AV_LOG_DEBUG, "skip %d audio samples from curr_cts: %"PRId64"\n", packet_skip_samples, curr_cts);
3672 flags |= AVINDEX_DISCARD_FRAME;
3673 av_log(mov->fc, AV_LOG_DEBUG, "drop a frame at curr_cts: %"PRId64" @ %"PRId64"\n", curr_cts, index);
3675 if (edit_list_start_encountered == 0) {
3676 num_discarded_begin++;
3677 frame_duration_buffer = av_realloc(frame_duration_buffer,
3678 num_discarded_begin * sizeof(int64_t));
3679 if (!frame_duration_buffer) {
3680 av_log(mov->fc, AV_LOG_ERROR, "Cannot reallocate frame duration buffer\n");
3683 frame_duration_buffer[num_discarded_begin - 1] = frame_duration;
3685 // Increment skip_samples for the first non-zero audio edit list
3686 if (st->codecpar->codec_type == AVMEDIA_TYPE_AUDIO &&
3687 first_non_zero_audio_edit > 0 && st->codecpar->codec_id != AV_CODEC_ID_VORBIS) {
3688 st->internal->skip_samples += frame_duration;
3693 if (msc->min_corrected_pts < 0) {
3694 msc->min_corrected_pts = edit_list_dts_counter + curr_ctts + msc->dts_shift;
3696 msc->min_corrected_pts = FFMIN(msc->min_corrected_pts, edit_list_dts_counter + curr_ctts + msc->dts_shift);
3698 if (edit_list_start_encountered == 0) {
3699 edit_list_start_encountered = 1;
3700 // Make timestamps strictly monotonically increasing by rewriting timestamps for
3701 // discarded packets.
3702 if (frame_duration_buffer) {
3703 fix_index_entry_timestamps(st, st->internal->nb_index_entries, edit_list_dts_counter,
3704 frame_duration_buffer, num_discarded_begin);
3705 av_freep(&frame_duration_buffer);
3710 if (add_index_entry(st, current->pos, edit_list_dts_counter, current->size,
3711 current->min_distance, flags) == -1) {
3712 av_log(mov->fc, AV_LOG_ERROR, "Cannot add index entry\n");
3716 // Update the index ranges array
3717 if (current_index_range < msc->index_ranges || index != current_index_range->end) {
3718 current_index_range++;
3719 current_index_range->start = index;
3721 current_index_range->end = index + 1;
3723 // Only start incrementing DTS in frame_duration amounts, when we encounter a frame in edit list.
3724 if (edit_list_start_encountered > 0) {
3725 edit_list_dts_counter = edit_list_dts_counter + frame_duration;
3728 // Break when found first key frame after edit entry completion
3729 if ((curr_cts + frame_duration >= (edit_list_duration + edit_list_media_time)) &&
3730 ((flags & AVINDEX_KEYFRAME) || ((st->codecpar->codec_type == AVMEDIA_TYPE_AUDIO)))) {
3731 if (ctts_data_old) {
3732 // If we have CTTS and this is the first keyframe after edit elist,
3733 // wait for one more, because there might be trailing B-frames after this I-frame
3734 // that do belong to the edit.
3735 if (st->codecpar->codec_type != AVMEDIA_TYPE_AUDIO && found_keyframe_after_edit == 0) {
3736 found_keyframe_after_edit = 1;
3739 if (ctts_sample_old != 0) {
3740 if (add_ctts_entry(&msc->ctts_data, &msc->ctts_count,
3741 &msc->ctts_allocated_size,
3742 ctts_sample_old - edit_list_start_ctts_sample,
3743 ctts_data_old[ctts_index_old].duration) == -1) {
3744 av_log(mov->fc, AV_LOG_ERROR, "Cannot add CTTS entry %"PRId64" - {%"PRId64", %d}\n",
3745 ctts_index_old, ctts_sample_old - edit_list_start_ctts_sample,
3746 ctts_data_old[ctts_index_old].duration);
3755 // If there are empty edits, then msc->min_corrected_pts might be positive
3756 // intentionally. So we subtract the sum duration of emtpy edits here.
3757 msc->min_corrected_pts -= empty_edits_sum_duration;
3759 // If the minimum pts turns out to be greater than zero after fixing the index, then we subtract the
3760 // dts by that amount to make the first pts zero.
3761 if (st->codecpar->codec_type == AVMEDIA_TYPE_VIDEO) {
3762 if (msc->min_corrected_pts > 0) {
3763 av_log(mov->fc, AV_LOG_DEBUG, "Offset DTS by %"PRId64" to make first pts zero.\n", msc->min_corrected_pts);
3764 for (i = 0; i < st->internal->nb_index_entries; ++i) {
3765 st->internal->index_entries[i].timestamp -= msc->min_corrected_pts;
3769 // Start time should be equal to zero or the duration of any empty edits.
3770 st->start_time = empty_edits_sum_duration;
3772 // Update av stream length, if it ends up shorter than the track's media duration
3773 st->duration = FFMIN(st->duration, edit_list_dts_entry_end - start_dts);
3774 msc->start_pad = st->internal->skip_samples;
3776 // Free the old index and the old CTTS structures
3778 av_free(ctts_data_old);
3779 av_freep(&frame_duration_buffer);
3781 // Null terminate the index ranges array
3782 current_index_range++;
3783 current_index_range->start = 0;
3784 current_index_range->end = 0;
3785 msc->current_index = msc->index_ranges[0].start;
3788 static void mov_build_index(MOVContext *mov, AVStream *st)
3790 MOVStreamContext *sc = st->priv_data;
3791 int64_t current_offset;
3792 int64_t current_dts = 0;
3793 unsigned int stts_index = 0;
3794 unsigned int stsc_index = 0;
3795 unsigned int stss_index = 0;
3796 unsigned int stps_index = 0;
3798 uint64_t stream_size = 0;
3799 MOVStts *ctts_data_old = sc->ctts_data;
3800 unsigned int ctts_count_old = sc->ctts_count;
3802 if (sc->elst_count) {
3803 int i, edit_start_index = 0, multiple_edits = 0;
3804 int64_t empty_duration = 0; // empty duration of the first edit list entry
3805 int64_t start_time = 0; // start time of the media
3807 for (i = 0; i < sc->elst_count; i++) {
3808 const MOVElst *e = &sc->elst_data[i];
3809 if (i == 0 && e->time == -1) {
3810 /* if empty, the first entry is the start time of the stream
3811 * relative to the presentation itself */
3812 empty_duration = e->duration;
3813 edit_start_index = 1;
3814 } else if (i == edit_start_index && e->time >= 0) {
3815 start_time = e->time;
3821 if (multiple_edits && !mov->advanced_editlist)
3822 av_log(mov->fc, AV_LOG_WARNING, "multiple edit list entries, "
3823 "Use -advanced_editlist to correctly decode otherwise "
3824 "a/v desync might occur\n");
3826 /* adjust first dts according to edit list */
3827 if ((empty_duration || start_time) && mov->time_scale > 0) {
3829 empty_duration = av_rescale(empty_duration, sc->time_scale, mov->time_scale);
3830 sc->time_offset = start_time - empty_duration;
3831 sc->min_corrected_pts = start_time;
3832 if (!mov->advanced_editlist)
3833 current_dts = -sc->time_offset;
3836 if (!multiple_edits && !mov->advanced_editlist &&
3837 st->codecpar->codec_id == AV_CODEC_ID_AAC && start_time > 0)
3838 sc->start_pad = start_time;
3841 /* only use old uncompressed audio chunk demuxing when stts specifies it */
3842 if (!(st->codecpar->codec_type == AVMEDIA_TYPE_AUDIO &&
3843 sc->stts_count == 1 && sc->stts_data[0].duration == 1)) {
3844 unsigned int current_sample = 0;
3845 unsigned int stts_sample = 0;
3846 unsigned int sample_size;
3847 unsigned int distance = 0;
3848 unsigned int rap_group_index = 0;
3849 unsigned int rap_group_sample = 0;
3850 int64_t last_dts = 0;
3851 int64_t dts_correction = 0;
3852 int rap_group_present = sc->rap_group_count && sc->rap_group;
3853 int key_off = (sc->keyframe_count && sc->keyframes[0] > 0) || (sc->stps_count && sc->stps_data[0] > 0);
3855 current_dts -= sc->dts_shift;
3856 last_dts = current_dts;
3858 if (!sc->sample_count || st->internal->nb_index_entries)
3860 if (sc->sample_count >= UINT_MAX / sizeof(*st->internal->index_entries) - st->internal->nb_index_entries)
3862 if (av_reallocp_array(&st->internal->index_entries,
3863 st->internal->nb_index_entries + sc->sample_count,
3864 sizeof(*st->internal->index_entries)) < 0) {
3865 st->internal->nb_index_entries = 0;
3868 st->internal->index_entries_allocated_size = (st->internal->nb_index_entries + sc->sample_count) * sizeof(*st->internal->index_entries);
3870 if (ctts_data_old) {
3871 // Expand ctts entries such that we have a 1-1 mapping with samples
3872 if (sc->sample_count >= UINT_MAX / sizeof(*sc->ctts_data))
3875 sc->ctts_allocated_size = 0;
3876 sc->ctts_data = av_fast_realloc(NULL, &sc->ctts_allocated_size,
3877 sc->sample_count * sizeof(*sc->ctts_data));
3878 if (!sc->ctts_data) {
3879 av_free(ctts_data_old);
3883 memset((uint8_t*)(sc->ctts_data), 0, sc->ctts_allocated_size);
3885 for (i = 0; i < ctts_count_old &&
3886 sc->ctts_count < sc->sample_count; i++)
3887 for (j = 0; j < ctts_data_old[i].count &&
3888 sc->ctts_count < sc->sample_count; j++)
3889 add_ctts_entry(&sc->ctts_data, &sc->ctts_count,
3890 &sc->ctts_allocated_size, 1,
3891 ctts_data_old[i].duration);
3892 av_free(ctts_data_old);
3895 for (i = 0; i < sc->chunk_count; i++) {
3896 int64_t next_offset = i+1 < sc->chunk_count ? sc->chunk_offsets[i+1] : INT64_MAX;
3897 current_offset = sc->chunk_offsets[i];
3898 while (mov_stsc_index_valid(stsc_index, sc->stsc_count) &&
3899 i + 1 == sc->stsc_data[stsc_index + 1].first)
3902 if (next_offset > current_offset && sc->sample_size>0 && sc->sample_size < sc->stsz_sample_size &&
3903 sc->stsc_data[stsc_index].count * (int64_t)sc->stsz_sample_size > next_offset - current_offset) {
3904 av_log(mov->fc, AV_LOG_WARNING, "STSZ sample size %d invalid (too large), ignoring\n", sc->stsz_sample_size);
3905 sc->stsz_sample_size = sc->sample_size;
3907 if (sc->stsz_sample_size>0 && sc->stsz_sample_size < sc->sample_size) {
3908 av_log(mov->fc, AV_LOG_WARNING, "STSZ sample size %d invalid (too small), ignoring\n", sc->stsz_sample_size);
3909 sc->stsz_sample_size = sc->sample_size;
3912 for (j = 0; j < sc->stsc_data[stsc_index].count; j++) {
3914 if (current_sample >= sc->sample_count) {
3915 av_log(mov->fc, AV_LOG_ERROR, "wrong sample count\n");
3919 if (!sc->keyframe_absent && (!sc->keyframe_count || current_sample+key_off == sc->keyframes[stss_index])) {
3921 if (stss_index + 1 < sc->keyframe_count)
3923 } else if (sc->stps_count && current_sample+key_off == sc->stps_data[stps_index]) {
3925 if (stps_index + 1 < sc->stps_count)
3928 if (rap_group_present && rap_group_index < sc->rap_group_count) {
3929 if (sc->rap_group[rap_group_index].index > 0)
3931 if (++rap_group_sample == sc->rap_group[rap_group_index].count) {
3932 rap_group_sample = 0;
3936 if (sc->keyframe_absent
3938 && !rap_group_present
3939 && (st->codecpar->codec_type == AVMEDIA_TYPE_AUDIO || (i==0 && j==0)))
3943 sample_size = sc->stsz_sample_size > 0 ? sc->stsz_sample_size : sc->sample_sizes[current_sample];
3944 if (sc->pseudo_stream_id == -1 ||
3945 sc->stsc_data[stsc_index].id - 1 == sc->pseudo_stream_id) {
3947 if (sample_size > 0x3FFFFFFF) {
3948 av_log(mov->fc, AV_LOG_ERROR, "Sample size %u is too large\n", sample_size);
3951 e = &st->internal->index_entries[st->internal->nb_index_entries++];
3952 e->pos = current_offset;
3953 e->timestamp = current_dts;
3954 e->size = sample_size;
3955 e->min_distance = distance;
3956 e->flags = keyframe ? AVINDEX_KEYFRAME : 0;
3957 av_log(mov->fc, AV_LOG_TRACE, "AVIndex stream %d, sample %u, offset %"PRIx64", dts %"PRId64", "
3958 "size %u, distance %u, keyframe %d\n", st->index, current_sample,
3959 current_offset, current_dts, sample_size, distance, keyframe);
3960 if (st->codecpar->codec_type == AVMEDIA_TYPE_VIDEO && st->internal->nb_index_entries < 100)
3961 ff_rfps_add_frame(mov->fc, st, current_dts);
3964 current_offset += sample_size;
3965 stream_size += sample_size;
3967 /* A negative sample duration is invalid based on the spec,
3968 * but some samples need it to correct the DTS. */
3969 if (sc->stts_data[stts_index].duration < 0) {
3970 av_log(mov->fc, AV_LOG_WARNING,
3971 "Invalid SampleDelta %d in STTS, at %d st:%d\n",
3972 sc->stts_data[stts_index].duration, stts_index,
3974 dts_correction += sc->stts_data[stts_index].duration - 1;
3975 sc->stts_data[stts_index].duration = 1;
3977 current_dts += sc->stts_data[stts_index].duration;
3978 if (!dts_correction || current_dts + dts_correction > last_dts) {
3979 current_dts += dts_correction;
3982 /* Avoid creating non-monotonous DTS */
3983 dts_correction += current_dts - last_dts - 1;
3984 current_dts = last_dts + 1;
3986 last_dts = current_dts;
3990 if (stts_index + 1 < sc->stts_count && stts_sample == sc->stts_data[stts_index].count) {
3996 if (st->duration > 0)
3997 st->codecpar->bit_rate = stream_size*8*sc->time_scale/st->duration;
3999 unsigned chunk_samples, total = 0;
4001 if (!sc->chunk_count)
4004 // compute total chunk count
4005 for (i = 0; i < sc->stsc_count; i++) {
4006 unsigned count, chunk_count;
4008 chunk_samples = sc->stsc_data[i].count;
4009 if (i != sc->stsc_count - 1 &&
4010 sc->samples_per_frame && chunk_samples % sc->samples_per_frame) {
4011 av_log(mov->fc, AV_LOG_ERROR, "error unaligned chunk\n");
4015 if (sc->samples_per_frame >= 160) { // gsm
4016 count = chunk_samples / sc->samples_per_frame;
4017 } else if (sc->samples_per_frame > 1) {
4018 unsigned samples = (1024/sc->samples_per_frame)*sc->samples_per_frame;
4019 count = (chunk_samples+samples-1) / samples;
4021 count = (chunk_samples+1023) / 1024;
4024 if (mov_stsc_index_valid(i, sc->stsc_count))
4025 chunk_count = sc->stsc_data[i+1].first - sc->stsc_data[i].first;
4027 chunk_count = sc->chunk_count - (sc->stsc_data[i].first - 1);
4028 total += chunk_count * count;
4031 av_log(mov->fc, AV_LOG_TRACE, "chunk count %u\n", total);
4032 if (total >= UINT_MAX / sizeof(*st->internal->index_entries) - st->internal->nb_index_entries)
4034 if (av_reallocp_array(&st->internal->index_entries,
4035 st->internal->nb_index_entries + total,
4036 sizeof(*st->internal->index_entries)) < 0) {
4037 st->internal->nb_index_entries = 0;
4040 st->internal->index_entries_allocated_size = (st->internal->nb_index_entries + total) * sizeof(*st->internal->index_entries);
4043 for (i = 0; i < sc->chunk_count; i++) {
4044 current_offset = sc->chunk_offsets[i];
4045 if (mov_stsc_index_valid(stsc_index, sc->stsc_count) &&
4046 i + 1 == sc->stsc_data[stsc_index + 1].first)
4048 chunk_samples = sc->stsc_data[stsc_index].count;
4050 while (chunk_samples > 0) {
4052 unsigned size, samples;
4054 if (sc->samples_per_frame > 1 && !sc->bytes_per_frame) {
4055 avpriv_request_sample(mov->fc,
4056 "Zero bytes per frame, but %d samples per frame",
4057 sc->samples_per_frame);
4061 if (sc->samples_per_frame >= 160) { // gsm
4062 samples = sc->samples_per_frame;
4063 size = sc->bytes_per_frame;
4065 if (sc->samples_per_frame > 1) {
4066 samples = FFMIN((1024 / sc->samples_per_frame)*
4067 sc->samples_per_frame, chunk_samples);
4068 size = (samples / sc->samples_per_frame) * sc->bytes_per_frame;
4070 samples = FFMIN(1024, chunk_samples);
4071 size = samples * sc->sample_size;
4075 if (st->internal->nb_index_entries >= total) {
4076 av_log(mov->fc, AV_LOG_ERROR, "wrong chunk count %u\n", total);
4079 if (size > 0x3FFFFFFF) {
4080 av_log(mov->fc, AV_LOG_ERROR, "Sample size %u is too large\n", size);
4083 e = &st->internal->index_entries[st->internal->nb_index_entries++];
4084 e->pos = current_offset;
4085 e->timestamp = current_dts;
4087 e->min_distance = 0;
4088 e->flags = AVINDEX_KEYFRAME;
4089 av_log(mov->fc, AV_LOG_TRACE, "AVIndex stream %d, chunk %u, offset %"PRIx64", dts %"PRId64", "
4090 "size %u, duration %u\n", st->index, i, current_offset, current_dts,
4093 current_offset += size;
4094 current_dts += samples;
4095 chunk_samples -= samples;
4100 if (!mov->ignore_editlist && mov->advanced_editlist) {
4101 // Fix index according to edit lists.
4102 mov_fix_index(mov, st);
4105 // Update start time of the stream.
4106 if (st->start_time == AV_NOPTS_VALUE && st->codecpar->codec_type == AVMEDIA_TYPE_VIDEO && st->internal->nb_index_entries > 0) {
4107 st->start_time = st->internal->index_entries[0].timestamp + sc->dts_shift;
4108 if (sc->ctts_data) {
4109 st->start_time += sc->ctts_data[0].duration;
4113 mov_estimate_video_delay(mov, st);
4116 static int test_same_origin(const char *src, const char *ref) {
4126 av_url_split(src_proto, sizeof(src_proto), src_auth, sizeof(src_auth), src_host, sizeof(src_host), &src_port, NULL, 0, src);
4127 av_url_split(ref_proto, sizeof(ref_proto), ref_auth, sizeof(ref_auth), ref_host, sizeof(ref_host), &ref_port, NULL, 0, ref);
4129 if (strlen(src) == 0) {
4131 } else if (strlen(src_auth) + 1 >= sizeof(src_auth) ||
4132 strlen(ref_auth) + 1 >= sizeof(ref_auth) ||
4133 strlen(src_host) + 1 >= sizeof(src_host) ||
4134 strlen(ref_host) + 1 >= sizeof(ref_host)) {
4136 } else if (strcmp(src_proto, ref_proto) ||
4137 strcmp(src_auth, ref_auth) ||
4138 strcmp(src_host, ref_host) ||
4139 src_port != ref_port) {
4145 static int mov_open_dref(MOVContext *c, AVIOContext **pb, const char *src, MOVDref *ref)
4147 /* try relative path, we do not try the absolute because it can leak information about our
4148 system to an attacker */
4149 if (ref->nlvl_to > 0 && ref->nlvl_from > 0) {
4150 char filename[1025];
4151 const char *src_path;
4154 /* find a source dir */
4155 src_path = strrchr(src, '/');
4161 /* find a next level down to target */
4162 for (i = 0, l = strlen(ref->path) - 1; l >= 0; l--)
4163 if (ref->path[l] == '/') {
4164 if (i == ref->nlvl_to - 1)
4170 /* compose filename if next level down to target was found */
4171 if (i == ref->nlvl_to - 1 && src_path - src < sizeof(filename)) {
4172 memcpy(filename, src, src_path - src);
4173 filename[src_path - src] = 0;
4175 for (i = 1; i < ref->nlvl_from; i++)
4176 av_strlcat(filename, "../", sizeof(filename));
4178 av_strlcat(filename, ref->path + l + 1, sizeof(filename));
4179 if (!c->use_absolute_path) {
4180 int same_origin = test_same_origin(src, filename);
4183 av_log(c->fc, AV_LOG_ERROR,
4184 "Reference with mismatching origin, %s not tried for security reasons, "
4185 "set demuxer option use_absolute_path to allow it anyway\n",
4187 return AVERROR(ENOENT);
4190 if (strstr(ref->path + l + 1, "..") ||
4191 strstr(ref->path + l + 1, ":") ||
4192 (ref->nlvl_from > 1 && same_origin < 0) ||
4193 (filename[0] == '/' && src_path == src))
4194 return AVERROR(ENOENT);
4197 if (strlen(filename) + 1 == sizeof(filename))
4198 return AVERROR(ENOENT);
4199 if (!c->fc->io_open(c->fc, pb, filename, AVIO_FLAG_READ, NULL))
4202 } else if (c->use_absolute_path) {
4203 av_log(c->fc, AV_LOG_WARNING, "Using absolute path on user request, "
4204 "this is a possible security issue\n");
4205 if (!c->fc->io_open(c->fc, pb, ref->path, AVIO_FLAG_READ, NULL))
4208 av_log(c->fc, AV_LOG_ERROR,
4209 "Absolute path %s not tried for security reasons, "
4210 "set demuxer option use_absolute_path to allow absolute paths\n",
4214 return AVERROR(ENOENT);
4217 static void fix_timescale(MOVContext *c, MOVStreamContext *sc)
4219 if (sc->time_scale <= 0) {
4220 av_log(c->fc, AV_LOG_WARNING, "stream %d, timescale not set\n", sc->ffindex);
4221 sc->time_scale = c->time_scale;
4222 if (sc->time_scale <= 0)
4227 static int mov_read_trak(MOVContext *c, AVIOContext *pb, MOVAtom atom)
4230 MOVStreamContext *sc;
4233 st = avformat_new_stream(c->fc, NULL);
4234 if (!st) return AVERROR(ENOMEM);
4236 sc = av_mallocz(sizeof(MOVStreamContext));
4237 if (!sc) return AVERROR(ENOMEM);
4240 st->codecpar->codec_type = AVMEDIA_TYPE_DATA;
4241 sc->ffindex = st->index;
4242 c->trak_index = st->index;
4244 if ((ret = mov_read_default(c, pb, atom)) < 0)
4249 // Here stsc refers to a chunk not described in stco. This is technically invalid,
4250 // but we can overlook it (clearing stsc) whenever stts_count == 0 (indicating no samples).
4251 if (!sc->chunk_count && !sc->stts_count && sc->stsc_count) {
4253 av_freep(&sc->stsc_data);
4257 if ((sc->chunk_count && (!sc->stts_count || !sc->stsc_count ||
4258 (!sc->sample_size && !sc->sample_count))) ||
4259 (!sc->chunk_count && sc->sample_count)) {
4260 av_log(c->fc, AV_LOG_ERROR, "stream %d, missing mandatory atoms, broken header\n",
4264 if (sc->stsc_count && sc->stsc_data[ sc->stsc_count - 1 ].first > sc->chunk_count) {
4265 av_log(c->fc, AV_LOG_ERROR, "stream %d, contradictionary STSC and STCO\n",
4267 return AVERROR_INVALIDDATA;
4270 fix_timescale(c, sc);
4272 avpriv_set_pts_info(st, 64, 1, sc->time_scale);
4274 mov_build_index(c, st);
4276 if (sc->dref_id-1 < sc->drefs_count && sc->drefs[sc->dref_id-1].path) {
4277 MOVDref *dref = &sc->drefs[sc->dref_id - 1];
4278 if (c->enable_drefs) {
4279 if (mov_open_dref(c, &sc->pb, c->fc->url, dref) < 0)
4280 av_log(c->fc, AV_LOG_ERROR,
4281 "stream %d, error opening alias: path='%s', dir='%s', "
4282 "filename='%s', volume='%s', nlvl_from=%d, nlvl_to=%d\n",
4283 st->index, dref->path, dref->dir, dref->filename,
4284 dref->volume, dref->nlvl_from, dref->nlvl_to);
4286 av_log(c->fc, AV_LOG_WARNING,
4287 "Skipped opening external track: "
4288 "stream %d, alias: path='%s', dir='%s', "
4289 "filename='%s', volume='%s', nlvl_from=%d, nlvl_to=%d."
4290 "Set enable_drefs to allow this.\n",
4291 st->index, dref->path, dref->dir, dref->filename,
4292 dref->volume, dref->nlvl_from, dref->nlvl_to);
4296 sc->pb_is_copied = 1;
4299 if (st->codecpar->codec_type == AVMEDIA_TYPE_VIDEO) {
4300 if (!st->sample_aspect_ratio.num && st->codecpar->width && st->codecpar->height &&
4301 sc->height && sc->width &&
4302 (st->codecpar->width != sc->width || st->codecpar->height != sc->height)) {
4303 st->sample_aspect_ratio = av_d2q(((double)st->codecpar->height * sc->width) /
4304 ((double)st->codecpar->width * sc->height), INT_MAX);
4307 #if FF_API_R_FRAME_RATE
4308 if (sc->stts_count == 1 || (sc->stts_count == 2 && sc->stts_data[1].count == 1))
4309 av_reduce(&st->r_frame_rate.num, &st->r_frame_rate.den,
4310 sc->time_scale, sc->stts_data[0].duration, INT_MAX);
4314 // done for ai5q, ai52, ai55, ai1q, ai12 and ai15.
4315 if (!st->codecpar->extradata_size && st->codecpar->codec_id == AV_CODEC_ID_H264 &&
4316 TAG_IS_AVCI(st->codecpar->codec_tag)) {
4317 ret = ff_generate_avci_extradata(st);
4322 switch (st->codecpar->codec_id) {
4323 #if CONFIG_H261_DECODER
4324 case AV_CODEC_ID_H261:
4326 #if CONFIG_H263_DECODER
4327 case AV_CODEC_ID_H263:
4329 #if CONFIG_MPEG4_DECODER
4330 case AV_CODEC_ID_MPEG4:
4332 st->codecpar->width = 0; /* let decoder init width/height */
4333 st->codecpar->height= 0;
4337 // If the duration of the mp3 packets is not constant, then they could need a parser
4338 if (st->codecpar->codec_id == AV_CODEC_ID_MP3
4339 && sc->stts_count > 3
4340 && sc->stts_count*10 > st->nb_frames
4341 && sc->time_scale == st->codecpar->sample_rate) {
4342 st->need_parsing = AVSTREAM_PARSE_FULL;
4344 /* Do not need those anymore. */
4345 av_freep(&sc->chunk_offsets);
4346 av_freep(&sc->sample_sizes);
4347 av_freep(&sc->keyframes);
4348 av_freep(&sc->stts_data);
4349 av_freep(&sc->stps_data);
4350 av_freep(&sc->elst_data);
4351 av_freep(&sc->rap_group);
4356 static int mov_read_ilst(MOVContext *c, AVIOContext *pb, MOVAtom atom)
4359 c->itunes_metadata = 1;
4360 ret = mov_read_default(c, pb, atom);
4361 c->itunes_metadata = 0;
4365 static int mov_read_keys(MOVContext *c, AVIOContext *pb, MOVAtom atom)
4374 count = avio_rb32(pb);
4375 if (count > UINT_MAX / sizeof(*c->meta_keys) - 1) {
4376 av_log(c->fc, AV_LOG_ERROR,
4377 "The 'keys' atom with the invalid key count: %"PRIu32"\n", count);
4378 return AVERROR_INVALIDDATA;
4381 c->meta_keys_count = count + 1;
4382 c->meta_keys = av_mallocz(c->meta_keys_count * sizeof(*c->meta_keys));
4384 return AVERROR(ENOMEM);
4386 for (i = 1; i <= count; ++i) {
4387 uint32_t key_size = avio_rb32(pb);
4388 uint32_t type = avio_rl32(pb);
4390 av_log(c->fc, AV_LOG_ERROR,
4391 "The key# %"PRIu32" in meta has invalid size:"
4392 "%"PRIu32"\n", i, key_size);
4393 return AVERROR_INVALIDDATA;
4396 if (type != MKTAG('m','d','t','a')) {
4397 avio_skip(pb, key_size);
4399 c->meta_keys[i] = av_mallocz(key_size + 1);
4400 if (!c->meta_keys[i])
4401 return AVERROR(ENOMEM);
4402 avio_read(pb, c->meta_keys[i], key_size);
4408 static int mov_read_custom(MOVContext *c, AVIOContext *pb, MOVAtom atom)
4410 int64_t end = av_sat_add64(avio_tell(pb), atom.size);
4411 uint8_t *key = NULL, *val = NULL, *mean = NULL;
4415 MOVStreamContext *sc;
4417 if (c->fc->nb_streams < 1)
4419 st = c->fc->streams[c->fc->nb_streams-1];
4422 for (i = 0; i < 3; i++) {
4426 if (end - avio_tell(pb) <= 12)
4429 len = avio_rb32(pb);
4430 tag = avio_rl32(pb);
4431 avio_skip(pb, 4); // flags
4433 if (len < 12 || len - 12 > end - avio_tell(pb))
4437 if (tag == MKTAG('m', 'e', 'a', 'n'))
4439 else if (tag == MKTAG('n', 'a', 'm', 'e'))
4441 else if (tag == MKTAG('d', 'a', 't', 'a') && len > 4) {
4451 *p = av_malloc(len + 1);
4453 ret = AVERROR(ENOMEM);
4456 ret = ffio_read_size(pb, *p, len);
4464 if (mean && key && val) {
4465 if (strcmp(key, "iTunSMPB") == 0) {
4466 int priming, remainder, samples;
4467 if(sscanf(val, "%*X %X %X %X", &priming, &remainder, &samples) == 3){
4468 if(priming>0 && priming<16384)
4469 sc->start_pad = priming;
4472 if (strcmp(key, "cdec") != 0) {
4473 av_dict_set(&c->fc->metadata, key, val,
4474 AV_DICT_DONT_STRDUP_KEY | AV_DICT_DONT_STRDUP_VAL);
4478 av_log(c->fc, AV_LOG_VERBOSE,
4479 "Unhandled or malformed custom metadata of size %"PRId64"\n", atom.size);
4482 avio_seek(pb, end, SEEK_SET);
4489 static int mov_read_meta(MOVContext *c, AVIOContext *pb, MOVAtom atom)
4491 while (atom.size > 8) {
4495 tag = avio_rl32(pb);
4497 if (tag == MKTAG('h','d','l','r')) {
4498 avio_seek(pb, -8, SEEK_CUR);
4500 return mov_read_default(c, pb, atom);
4506 // return 1 when matrix is identity, 0 otherwise
4507 #define IS_MATRIX_IDENT(matrix) \
4508 ( (matrix)[0][0] == (1 << 16) && \
4509 (matrix)[1][1] == (1 << 16) && \
4510 (matrix)[2][2] == (1 << 30) && \
4511 !(matrix)[0][1] && !(matrix)[0][2] && \
4512 !(matrix)[1][0] && !(matrix)[1][2] && \
4513 !(matrix)[2][0] && !(matrix)[2][1])
4515 static int mov_read_tkhd(MOVContext *c, AVIOContext *pb, MOVAtom atom)
4520 int display_matrix[3][3];
4521 int res_display_matrix[3][3] = { { 0 } };
4523 MOVStreamContext *sc;
4527 if (c->fc->nb_streams < 1)
4529 st = c->fc->streams[c->fc->nb_streams-1];
4532 // Each stream (trak) should have exactly 1 tkhd. This catches bad files and
4533 // avoids corrupting AVStreams mapped to an earlier tkhd.
4535 return AVERROR_INVALIDDATA;
4537 version = avio_r8(pb);
4538 flags = avio_rb24(pb);
4539 st->disposition |= (flags & MOV_TKHD_FLAG_ENABLED) ? AV_DISPOSITION_DEFAULT : 0;
4545 avio_rb32(pb); /* creation time */
4546 avio_rb32(pb); /* modification time */
4548 st->id = (int)avio_rb32(pb); /* track id (NOT 0 !)*/
4549 avio_rb32(pb); /* reserved */
4551 /* highlevel (considering edits) duration in movie timebase */
4552 (version == 1) ? avio_rb64(pb) : avio_rb32(pb);
4553 avio_rb32(pb); /* reserved */
4554 avio_rb32(pb); /* reserved */
4556 avio_rb16(pb); /* layer */
4557 avio_rb16(pb); /* alternate group */
4558 avio_rb16(pb); /* volume */
4559 avio_rb16(pb); /* reserved */
4561 //read in the display matrix (outlined in ISO 14496-12, Section 6.2.2)
4562 // they're kept in fixed point format through all calculations
4563 // save u,v,z to store the whole matrix in the AV_PKT_DATA_DISPLAYMATRIX
4564 // side data, but the scale factor is not needed to calculate aspect ratio
4565 for (i = 0; i < 3; i++) {
4566 display_matrix[i][0] = avio_rb32(pb); // 16.16 fixed point
4567 display_matrix[i][1] = avio_rb32(pb); // 16.16 fixed point
4568 display_matrix[i][2] = avio_rb32(pb); // 2.30 fixed point
4571 width = avio_rb32(pb); // 16.16 fixed point track width
4572 height = avio_rb32(pb); // 16.16 fixed point track height
4573 sc->width = width >> 16;
4574 sc->height = height >> 16;
4576 // apply the moov display matrix (after the tkhd one)
4577 for (i = 0; i < 3; i++) {
4578 const int sh[3] = { 16, 16, 30 };
4579 for (j = 0; j < 3; j++) {
4580 for (e = 0; e < 3; e++) {
4581 res_display_matrix[i][j] +=
4582 ((int64_t) display_matrix[i][e] *
4583 c->movie_display_matrix[e][j]) >> sh[e];
4588 // save the matrix when it is not the default identity
4589 if (!IS_MATRIX_IDENT(res_display_matrix)) {
4592 av_freep(&sc->display_matrix);
4593 sc->display_matrix = av_malloc(sizeof(int32_t) * 9);
4594 if (!sc->display_matrix)
4595 return AVERROR(ENOMEM);
4597 for (i = 0; i < 3; i++)
4598 for (j = 0; j < 3; j++)
4599 sc->display_matrix[i * 3 + j] = res_display_matrix[i][j];
4601 #if FF_API_OLD_ROTATE_API
4602 rotate = av_display_rotation_get(sc->display_matrix);
4603 if (!isnan(rotate)) {
4604 char rotate_buf[64];
4606 if (rotate < 0) // for backward compatibility
4608 snprintf(rotate_buf, sizeof(rotate_buf), "%g", rotate);
4609 av_dict_set(&st->metadata, "rotate", rotate_buf, 0);
4614 // transform the display width/height according to the matrix
4615 // to keep the same scale, use [width height 1<<16]
4616 if (width && height && sc->display_matrix) {
4617 double disp_transform[2];
4619 for (i = 0; i < 2; i++)
4620 disp_transform[i] = hypot(sc->display_matrix[0 + i],
4621 sc->display_matrix[3 + i]);
4623 if (disp_transform[0] > 1 && disp_transform[1] > 1 &&
4624 disp_transform[0] < (1<<24) && disp_transform[1] < (1<<24) &&
4625 fabs((disp_transform[0] / disp_transform[1]) - 1.0) > 0.01)
4626 st->sample_aspect_ratio = av_d2q(
4627 disp_transform[0] / disp_transform[1],
4633 static int mov_read_tfhd(MOVContext *c, AVIOContext *pb, MOVAtom atom)
4635 MOVFragment *frag = &c->fragment;
4636 MOVTrackExt *trex = NULL;
4637 int flags, track_id, i;
4638 MOVFragmentStreamInfo * frag_stream_info;
4640 avio_r8(pb); /* version */
4641 flags = avio_rb24(pb);
4643 track_id = avio_rb32(pb);
4645 return AVERROR_INVALIDDATA;
4646 for (i = 0; i < c->trex_count; i++)
4647 if (c->trex_data[i].track_id == track_id) {
4648 trex = &c->trex_data[i];
4652 av_log(c->fc, AV_LOG_WARNING, "could not find corresponding trex (id %u)\n", track_id);
4655 c->fragment.found_tfhd = 1;
4656 frag->track_id = track_id;
4657 set_frag_stream(&c->frag_index, track_id);
4659 frag->base_data_offset = flags & MOV_TFHD_BASE_DATA_OFFSET ?
4660 avio_rb64(pb) : flags & MOV_TFHD_DEFAULT_BASE_IS_MOOF ?
4661 frag->moof_offset : frag->implicit_offset;
4662 frag->stsd_id = flags & MOV_TFHD_STSD_ID ? avio_rb32(pb) : trex->stsd_id;
4664 frag->duration = flags & MOV_TFHD_DEFAULT_DURATION ?
4665 avio_rb32(pb) : trex->duration;
4666 frag->size = flags & MOV_TFHD_DEFAULT_SIZE ?
4667 avio_rb32(pb) : trex->size;
4668 frag->flags = flags & MOV_TFHD_DEFAULT_FLAGS ?
4669 avio_rb32(pb) : trex->flags;
4670 av_log(c->fc, AV_LOG_TRACE, "frag flags 0x%x\n", frag->flags);
4672 frag_stream_info = get_current_frag_stream_info(&c->frag_index);
4673 if (frag_stream_info)
4674 frag_stream_info->next_trun_dts = AV_NOPTS_VALUE;
4679 static int mov_read_chap(MOVContext *c, AVIOContext *pb, MOVAtom atom)
4684 num = atom.size / 4;
4685 if (!(new_tracks = av_malloc_array(num, sizeof(int))))
4686 return AVERROR(ENOMEM);
4688 av_free(c->chapter_tracks);
4689 c->chapter_tracks = new_tracks;
4690 c->nb_chapter_tracks = num;
4692 for (i = 0; i < num && !pb->eof_reached; i++)
4693 c->chapter_tracks[i] = avio_rb32(pb);
4698 static int mov_read_trex(MOVContext *c, AVIOContext *pb, MOVAtom atom)
4703 if ((uint64_t)c->trex_count+1 >= UINT_MAX / sizeof(*c->trex_data))
4704 return AVERROR_INVALIDDATA;
4705 if ((err = av_reallocp_array(&c->trex_data, c->trex_count + 1,
4706 sizeof(*c->trex_data))) < 0) {
4711 c->fc->duration = AV_NOPTS_VALUE; // the duration from mvhd is not representing the whole file when fragments are used.
4713 trex = &c->trex_data[c->trex_count++];
4714 avio_r8(pb); /* version */
4715 avio_rb24(pb); /* flags */
4716 trex->track_id = avio_rb32(pb);
4717 trex->stsd_id = avio_rb32(pb);
4718 trex->duration = avio_rb32(pb);
4719 trex->size = avio_rb32(pb);
4720 trex->flags = avio_rb32(pb);
4724 static int mov_read_tfdt(MOVContext *c, AVIOContext *pb, MOVAtom atom)
4726 MOVFragment *frag = &c->fragment;
4727 AVStream *st = NULL;
4728 MOVStreamContext *sc;
4730 MOVFragmentStreamInfo * frag_stream_info;
4731 int64_t base_media_decode_time;
4733 for (i = 0; i < c->fc->nb_streams; i++) {
4734 if (c->fc->streams[i]->id == frag->track_id) {
4735 st = c->fc->streams[i];
4740 av_log(c->fc, AV_LOG_WARNING, "could not find corresponding track id %u\n", frag->track_id);
4744 if (sc->pseudo_stream_id + 1 != frag->stsd_id && sc->pseudo_stream_id != -1)
4746 version = avio_r8(pb);
4747 avio_rb24(pb); /* flags */
4749 base_media_decode_time = avio_rb64(pb);
4751 base_media_decode_time = avio_rb32(pb);
4754 frag_stream_info = get_current_frag_stream_info(&c->frag_index);
4755 if (frag_stream_info)
4756 frag_stream_info->tfdt_dts = base_media_decode_time;
4757 sc->track_end = base_media_decode_time;
4762 static int mov_read_trun(MOVContext *c, AVIOContext *pb, MOVAtom atom)
4764 MOVFragment *frag = &c->fragment;
4765 AVStream *st = NULL;
4766 MOVStreamContext *sc;
4769 int64_t dts, pts = AV_NOPTS_VALUE;
4770 int data_offset = 0;
4771 unsigned entries, first_sample_flags = frag->flags;
4772 int flags, distance, i;
4773 int64_t prev_dts = AV_NOPTS_VALUE;
4774 int next_frag_index = -1, index_entry_pos;
4775 size_t requested_size;
4776 size_t old_ctts_allocated_size;
4777 AVIndexEntry *new_entries;
4778 MOVFragmentStreamInfo * frag_stream_info;
4780 if (!frag->found_tfhd) {
4781 av_log(c->fc, AV_LOG_ERROR, "trun track id unknown, no tfhd was found\n");
4782 return AVERROR_INVALIDDATA;
4785 for (i = 0; i < c->fc->nb_streams; i++) {
4786 if (c->fc->streams[i]->id == frag->track_id) {
4787 st = c->fc->streams[i];
4792 av_log(c->fc, AV_LOG_WARNING, "could not find corresponding track id %u\n", frag->track_id);
4796 if (sc->pseudo_stream_id+1 != frag->stsd_id && sc->pseudo_stream_id != -1)
4799 // Find the next frag_index index that has a valid index_entry for
4800 // the current track_id.
4802 // A valid index_entry means the trun for the fragment was read
4803 // and it's samples are in index_entries at the given position.
4804 // New index entries will be inserted before the index_entry found.
4805 index_entry_pos = st->internal->nb_index_entries;
4806 for (i = c->frag_index.current + 1; i < c->frag_index.nb_items; i++) {
4807 frag_stream_info = get_frag_stream_info(&c->frag_index, i, frag->track_id);
4808 if (frag_stream_info && frag_stream_info->index_entry >= 0) {
4809 next_frag_index = i;
4810 index_entry_pos = frag_stream_info->index_entry;
4814 av_assert0(index_entry_pos <= st->internal->nb_index_entries);
4816 avio_r8(pb); /* version */
4817 flags = avio_rb24(pb);
4818 entries = avio_rb32(pb);
4819 av_log(c->fc, AV_LOG_TRACE, "flags 0x%x entries %u\n", flags, entries);
4821 if ((uint64_t)entries+sc->ctts_count >= UINT_MAX/sizeof(*sc->ctts_data))
4822 return AVERROR_INVALIDDATA;
4823 if (flags & MOV_TRUN_DATA_OFFSET) data_offset = avio_rb32(pb);
4824 if (flags & MOV_TRUN_FIRST_SAMPLE_FLAGS) first_sample_flags = avio_rb32(pb);
4826 frag_stream_info = get_current_frag_stream_info(&c->frag_index);
4827 if (frag_stream_info) {
4828 if (frag_stream_info->next_trun_dts != AV_NOPTS_VALUE) {
4829 dts = frag_stream_info->next_trun_dts - sc->time_offset;
4830 } else if (frag_stream_info->first_tfra_pts != AV_NOPTS_VALUE &&
4831 c->use_mfra_for == FF_MOV_FLAG_MFRA_PTS) {
4832 pts = frag_stream_info->first_tfra_pts;
4833 av_log(c->fc, AV_LOG_DEBUG, "found mfra time %"PRId64
4834 ", using it for pts\n", pts);
4835 } else if (frag_stream_info->first_tfra_pts != AV_NOPTS_VALUE &&
4836 c->use_mfra_for == FF_MOV_FLAG_MFRA_DTS) {
4837 dts = frag_stream_info->first_tfra_pts;
4838 av_log(c->fc, AV_LOG_DEBUG, "found mfra time %"PRId64
4839 ", using it for dts\n", pts);
4840 } else if (frag_stream_info->sidx_pts != AV_NOPTS_VALUE) {
4841 // FIXME: sidx earliest_presentation_time is *PTS*, s.b.
4842 // pts = frag_stream_info->sidx_pts;
4843 dts = frag_stream_info->sidx_pts - sc->time_offset;
4844 av_log(c->fc, AV_LOG_DEBUG, "found sidx time %"PRId64
4845 ", using it for pts\n", pts);
4846 } else if (frag_stream_info->tfdt_dts != AV_NOPTS_VALUE) {
4847 dts = frag_stream_info->tfdt_dts - sc->time_offset;
4848 av_log(c->fc, AV_LOG_DEBUG, "found tfdt time %"PRId64
4849 ", 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);
4856 dts = sc->track_end - sc->time_offset;
4857 av_log(c->fc, AV_LOG_DEBUG, "found track end time %"PRId64
4858 ", using it for dts\n", dts);
4860 offset = frag->base_data_offset + data_offset;
4862 av_log(c->fc, AV_LOG_TRACE, "first sample flags 0x%x\n", first_sample_flags);
4864 // realloc space for new index entries
4865 if((uint64_t)st->internal->nb_index_entries + entries >= UINT_MAX / sizeof(AVIndexEntry)) {
4866 entries = UINT_MAX / sizeof(AVIndexEntry) - st->internal->nb_index_entries;
4867 av_log(c->fc, AV_LOG_ERROR, "Failed to add index entry\n");
4872 requested_size = (st->internal->nb_index_entries + entries) * sizeof(AVIndexEntry);
4873 new_entries = av_fast_realloc(st->internal->index_entries,
4874 &st->internal->index_entries_allocated_size,
4877 return AVERROR(ENOMEM);
4878 st->internal->index_entries= new_entries;
4880 requested_size = (st->internal->nb_index_entries + entries) * sizeof(*sc->ctts_data);
4881 old_ctts_allocated_size = sc->ctts_allocated_size;
4882 ctts_data = av_fast_realloc(sc->ctts_data, &sc->ctts_allocated_size,
4885 return AVERROR(ENOMEM);
4886 sc->ctts_data = ctts_data;
4888 // In case there were samples without ctts entries, ensure they get
4889 // zero valued entries. This ensures clips which mix boxes with and
4890 // without ctts entries don't pickup uninitialized data.
4891 memset((uint8_t*)(sc->ctts_data) + old_ctts_allocated_size, 0,
4892 sc->ctts_allocated_size - old_ctts_allocated_size);
4894 if (index_entry_pos < st->internal->nb_index_entries) {
4895 // Make hole in index_entries and ctts_data for new samples
4896 memmove(st->internal->index_entries + index_entry_pos + entries,
4897 st->internal->index_entries + index_entry_pos,
4898 sizeof(*st->internal->index_entries) *
4899 (st->internal->nb_index_entries - index_entry_pos));
4900 memmove(sc->ctts_data + index_entry_pos + entries,
4901 sc->ctts_data + index_entry_pos,
4902 sizeof(*sc->ctts_data) * (sc->ctts_count - index_entry_pos));
4903 if (index_entry_pos < sc->current_sample) {
4904 sc->current_sample += entries;
4908 st->internal->nb_index_entries += entries;
4909 sc->ctts_count = st->internal->nb_index_entries;
4911 // Record the index_entry position in frag_index of this fragment
4912 if (frag_stream_info)
4913 frag_stream_info->index_entry = index_entry_pos;
4915 if (index_entry_pos > 0)
4916 prev_dts = st->internal->index_entries[index_entry_pos-1].timestamp;
4918 for (i = 0; i < entries && !pb->eof_reached; i++) {
4919 unsigned sample_size = frag->size;
4920 int sample_flags = i ? frag->flags : first_sample_flags;
4921 unsigned sample_duration = frag->duration;
4922 unsigned ctts_duration = 0;
4924 int index_entry_flags = 0;
4926 if (flags & MOV_TRUN_SAMPLE_DURATION) sample_duration = avio_rb32(pb);
4927 if (flags & MOV_TRUN_SAMPLE_SIZE) sample_size = avio_rb32(pb);
4928 if (flags & MOV_TRUN_SAMPLE_FLAGS) sample_flags = avio_rb32(pb);
4929 if (flags & MOV_TRUN_SAMPLE_CTS) ctts_duration = avio_rb32(pb);
4931 mov_update_dts_shift(sc, ctts_duration, c->fc);
4932 if (pts != AV_NOPTS_VALUE) {
4933 dts = pts - sc->dts_shift;
4934 if (flags & MOV_TRUN_SAMPLE_CTS) {
4935 dts -= ctts_duration;
4937 dts -= sc->time_offset;
4939 av_log(c->fc, AV_LOG_DEBUG,
4940 "pts %"PRId64" calculated dts %"PRId64
4941 " sc->dts_shift %d ctts.duration %d"
4942 " sc->time_offset %"PRId64
4943 " flags & MOV_TRUN_SAMPLE_CTS %d\n",
4945 sc->dts_shift, ctts_duration,
4946 sc->time_offset, flags & MOV_TRUN_SAMPLE_CTS);
4947 pts = AV_NOPTS_VALUE;
4950 if (st->codecpar->codec_type == AVMEDIA_TYPE_AUDIO)
4954 !(sample_flags & (MOV_FRAG_SAMPLE_FLAG_IS_NON_SYNC |
4955 MOV_FRAG_SAMPLE_FLAG_DEPENDS_YES));
4958 index_entry_flags |= AVINDEX_KEYFRAME;
4960 // Fragments can overlap in time. Discard overlapping frames after
4962 if (prev_dts >= dts)
4963 index_entry_flags |= AVINDEX_DISCARD_FRAME;
4965 st->internal->index_entries[index_entry_pos].pos = offset;
4966 st->internal->index_entries[index_entry_pos].timestamp = dts;
4967 st->internal->index_entries[index_entry_pos].size= sample_size;
4968 st->internal->index_entries[index_entry_pos].min_distance= distance;
4969 st->internal->index_entries[index_entry_pos].flags = index_entry_flags;
4971 sc->ctts_data[index_entry_pos].count = 1;
4972 sc->ctts_data[index_entry_pos].duration = ctts_duration;
4975 av_log(c->fc, AV_LOG_TRACE, "AVIndex stream %d, sample %d, offset %"PRIx64", dts %"PRId64", "
4976 "size %u, distance %d, keyframe %d\n", st->index,
4977 index_entry_pos, offset, dts, sample_size, distance, keyframe);
4979 dts += sample_duration;
4980 offset += sample_size;
4981 sc->data_size += sample_size;
4983 if (sample_duration <= INT64_MAX - sc->duration_for_fps &&
4984 1 <= INT_MAX - sc->nb_frames_for_fps
4986 sc->duration_for_fps += sample_duration;
4987 sc->nb_frames_for_fps ++;
4990 if (frag_stream_info)
4991 frag_stream_info->next_trun_dts = dts + sc->time_offset;
4993 // EOF found before reading all entries. Fix the hole this would
4994 // leave in index_entries and ctts_data
4995 int gap = entries - i;
4996 memmove(st->internal->index_entries + index_entry_pos,
4997 st->internal->index_entries + index_entry_pos + gap,
4998 sizeof(*st->internal->index_entries) *
4999 (st->internal->nb_index_entries - (index_entry_pos + gap)));
5000 memmove(sc->ctts_data + index_entry_pos,
5001 sc->ctts_data + index_entry_pos + gap,
5002 sizeof(*sc->ctts_data) *
5003 (sc->ctts_count - (index_entry_pos + gap)));
5005 st->internal->nb_index_entries -= gap;
5006 sc->ctts_count -= gap;
5007 if (index_entry_pos < sc->current_sample) {
5008 sc->current_sample -= gap;
5013 // The end of this new fragment may overlap in time with the start
5014 // of the next fragment in index_entries. Mark the samples in the next
5015 // fragment that overlap with AVINDEX_DISCARD_FRAME
5016 prev_dts = AV_NOPTS_VALUE;
5017 if (index_entry_pos > 0)
5018 prev_dts = st->internal->index_entries[index_entry_pos-1].timestamp;
5019 for (i = index_entry_pos; i < st->internal->nb_index_entries; i++) {
5020 if (prev_dts < st->internal->index_entries[i].timestamp)
5022 st->internal->index_entries[i].flags |= AVINDEX_DISCARD_FRAME;
5025 // If a hole was created to insert the new index_entries into,
5026 // the index_entry recorded for all subsequent moof must
5027 // be incremented by the number of entries inserted.
5028 fix_frag_index_entries(&c->frag_index, next_frag_index,
5029 frag->track_id, entries);
5031 if (pb->eof_reached) {
5032 av_log(c->fc, AV_LOG_WARNING, "reached eof, corrupted TRUN atom\n");
5036 frag->implicit_offset = offset;
5038 sc->track_end = dts + sc->time_offset;
5039 if (st->duration < sc->track_end)
5040 st->duration = sc->track_end;
5045 static int mov_read_sidx(MOVContext *c, AVIOContext *pb, MOVAtom atom)
5047 int64_t stream_size = avio_size(pb);
5048 int64_t offset = av_sat_add64(avio_tell(pb), atom.size), pts, timestamp;
5049 uint8_t version, is_complete;
5051 unsigned i, j, track_id, item_count;
5052 AVStream *st = NULL;
5053 AVStream *ref_st = NULL;
5054 MOVStreamContext *sc, *ref_sc = NULL;
5055 AVRational timescale;
5057 version = avio_r8(pb);
5059 avpriv_request_sample(c->fc, "sidx version %u", version);
5063 avio_rb24(pb); // flags
5065 track_id = avio_rb32(pb); // Reference ID
5066 for (i = 0; i < c->fc->nb_streams; i++) {
5067 if (c->fc->streams[i]->id == track_id) {
5068 st = c->fc->streams[i];
5073 av_log(c->fc, AV_LOG_WARNING, "could not find corresponding track id %d\n", track_id);
5079 timescale = av_make_q(1, avio_rb32(pb));
5081 if (timescale.den <= 0) {
5082 av_log(c->fc, AV_LOG_ERROR, "Invalid sidx timescale 1/%d\n", timescale.den);
5083 return AVERROR_INVALIDDATA;
5087 pts = avio_rb32(pb);
5088 offadd= avio_rb32(pb);
5090 pts = avio_rb64(pb);
5091 offadd= avio_rb64(pb);
5093 if (av_sat_add64(offset, offadd) != offset + (uint64_t)offadd)
5094 return AVERROR_INVALIDDATA;
5096 offset += (uint64_t)offadd;
5098 avio_rb16(pb); // reserved
5100 item_count = avio_rb16(pb);
5102 for (i = 0; i < item_count; i++) {
5104 MOVFragmentStreamInfo * frag_stream_info;
5105 uint32_t size = avio_rb32(pb);
5106 uint32_t duration = avio_rb32(pb);
5107 if (size & 0x80000000) {
5108 avpriv_request_sample(c->fc, "sidx reference_type 1");
5109 return AVERROR_PATCHWELCOME;
5111 avio_rb32(pb); // sap_flags
5112 timestamp = av_rescale_q(pts, timescale, st->time_base);
5114 index = update_frag_index(c, offset);
5115 frag_stream_info = get_frag_stream_info(&c->frag_index, index, track_id);
5116 if (frag_stream_info)
5117 frag_stream_info->sidx_pts = timestamp;
5119 if (av_sat_add64(offset, size) != offset + size)
5120 return AVERROR_INVALIDDATA;
5125 st->duration = sc->track_end = pts;
5129 // See if the remaining bytes are just an mfra which we can ignore.
5130 is_complete = offset == stream_size;
5131 if (!is_complete && (pb->seekable & AVIO_SEEKABLE_NORMAL)) {
5133 int64_t original_pos = avio_tell(pb);
5134 if (!c->have_read_mfra_size) {
5135 if ((ret = avio_seek(pb, stream_size - 4, SEEK_SET)) < 0)
5137 c->mfra_size = avio_rb32(pb);
5138 c->have_read_mfra_size = 1;
5139 if ((ret = avio_seek(pb, original_pos, SEEK_SET)) < 0)
5142 if (offset + c->mfra_size == stream_size)
5147 // Find first entry in fragment index that came from an sidx.
5148 // This will pretty much always be the first entry.
5149 for (i = 0; i < c->frag_index.nb_items; i++) {
5150 MOVFragmentIndexItem * item = &c->frag_index.item[i];
5151 for (j = 0; ref_st == NULL && j < item->nb_stream_info; j++) {
5152 MOVFragmentStreamInfo * si;
5153 si = &item->stream_info[j];
5154 if (si->sidx_pts != AV_NOPTS_VALUE) {
5155 ref_st = c->fc->streams[j];
5156 ref_sc = ref_st->priv_data;
5161 if (ref_st) for (i = 0; i < c->fc->nb_streams; i++) {
5162 st = c->fc->streams[i];
5164 if (!sc->has_sidx) {
5165 st->duration = sc->track_end = av_rescale(ref_st->duration, sc->time_scale, ref_sc->time_scale);
5169 c->frag_index.complete = 1;
5175 /* this atom should be null (from specs), but some buggy files put the 'moov' atom inside it... */
5176 /* like the files created with Adobe Premiere 5.0, for samples see */
5177 /* http://graphics.tudelft.nl/~wouter/publications/soundtests/ */
5178 static int mov_read_wide(MOVContext *c, AVIOContext *pb, MOVAtom atom)
5183 return 0; /* continue */
5184 if (avio_rb32(pb) != 0) { /* 0 sized mdat atom... use the 'wide' atom size */
5185 avio_skip(pb, atom.size - 4);
5188 atom.type = avio_rl32(pb);
5190 if (atom.type != MKTAG('m','d','a','t')) {
5191 avio_skip(pb, atom.size);
5194 err = mov_read_mdat(c, pb, atom);
5198 static int mov_read_cmov(MOVContext *c, AVIOContext *pb, MOVAtom atom)
5203 uint8_t *moov_data; /* uncompressed data */
5204 long cmov_len, moov_len;
5207 avio_rb32(pb); /* dcom atom */
5208 if (avio_rl32(pb) != MKTAG('d','c','o','m'))
5209 return AVERROR_INVALIDDATA;
5210 if (avio_rl32(pb) != MKTAG('z','l','i','b')) {
5211 av_log(c->fc, AV_LOG_ERROR, "unknown compression for cmov atom !\n");
5212 return AVERROR_INVALIDDATA;
5214 avio_rb32(pb); /* cmvd atom */
5215 if (avio_rl32(pb) != MKTAG('c','m','v','d'))
5216 return AVERROR_INVALIDDATA;
5217 moov_len = avio_rb32(pb); /* uncompressed size */
5218 cmov_len = atom.size - 6 * 4;
5220 cmov_data = av_malloc(cmov_len);
5222 return AVERROR(ENOMEM);
5223 moov_data = av_malloc(moov_len);
5226 return AVERROR(ENOMEM);
5228 ret = ffio_read_size(pb, cmov_data, cmov_len);
5230 goto free_and_return;
5232 ret = AVERROR_INVALIDDATA;
5233 if (uncompress (moov_data, (uLongf *) &moov_len, (const Bytef *)cmov_data, cmov_len) != Z_OK)
5234 goto free_and_return;
5235 if (ffio_init_context(&ctx, moov_data, moov_len, 0, NULL, NULL, NULL, NULL) != 0)
5236 goto free_and_return;
5237 ctx.seekable = AVIO_SEEKABLE_NORMAL;
5238 atom.type = MKTAG('m','o','o','v');
5239 atom.size = moov_len;
5240 ret = mov_read_default(c, &ctx, atom);
5246 av_log(c->fc, AV_LOG_ERROR, "this file requires zlib support compiled in\n");
5247 return AVERROR(ENOSYS);
5251 /* edit list atom */
5252 static int mov_read_elst(MOVContext *c, AVIOContext *pb, MOVAtom atom)
5254 MOVStreamContext *sc;
5255 int i, edit_count, version;
5256 int64_t elst_entry_size;
5258 if (c->fc->nb_streams < 1 || c->ignore_editlist)
5260 sc = c->fc->streams[c->fc->nb_streams-1]->priv_data;
5262 version = avio_r8(pb); /* version */
5263 avio_rb24(pb); /* flags */
5264 edit_count = avio_rb32(pb); /* entries */
5267 elst_entry_size = version == 1 ? 20 : 12;
5268 if (atom.size != edit_count * elst_entry_size) {
5269 if (c->fc->strict_std_compliance >= FF_COMPLIANCE_STRICT) {
5270 av_log(c->fc, AV_LOG_ERROR, "Invalid edit list entry_count: %d for elst atom of size: %"PRId64" bytes.\n",
5271 edit_count, atom.size + 8);
5272 return AVERROR_INVALIDDATA;
5274 edit_count = atom.size / elst_entry_size;
5275 if (edit_count * elst_entry_size != atom.size) {
5276 av_log(c->fc, AV_LOG_WARNING, "ELST atom of %"PRId64" bytes, bigger than %d entries.\n", atom.size, edit_count);
5284 av_log(c->fc, AV_LOG_WARNING, "Duplicated ELST atom\n");
5285 av_free(sc->elst_data);
5287 sc->elst_data = av_malloc_array(edit_count, sizeof(*sc->elst_data));
5289 return AVERROR(ENOMEM);
5291 av_log(c->fc, AV_LOG_TRACE, "track[%u].edit_count = %i\n", c->fc->nb_streams - 1, edit_count);
5292 for (i = 0; i < edit_count && atom.size > 0 && !pb->eof_reached; i++) {
5293 MOVElst *e = &sc->elst_data[i];
5296 e->duration = avio_rb64(pb);
5297 e->time = avio_rb64(pb);
5300 e->duration = avio_rb32(pb); /* segment duration */
5301 e->time = (int32_t)avio_rb32(pb); /* media time */
5304 e->rate = avio_rb32(pb) / 65536.0;
5306 av_log(c->fc, AV_LOG_TRACE, "duration=%"PRId64" time=%"PRId64" rate=%f\n",
5307 e->duration, e->time, e->rate);
5309 if (e->time < 0 && e->time != -1 &&
5310 c->fc->strict_std_compliance >= FF_COMPLIANCE_STRICT) {
5311 av_log(c->fc, AV_LOG_ERROR, "Track %d, edit %d: Invalid edit list media time=%"PRId64"\n",
5312 c->fc->nb_streams-1, i, e->time);
5313 return AVERROR_INVALIDDATA;
5321 static int mov_read_tmcd(MOVContext *c, AVIOContext *pb, MOVAtom atom)
5323 MOVStreamContext *sc;
5325 if (c->fc->nb_streams < 1)
5326 return AVERROR_INVALIDDATA;
5327 sc = c->fc->streams[c->fc->nb_streams - 1]->priv_data;
5328 sc->timecode_track = avio_rb32(pb);
5332 static int mov_read_av1c(MOVContext *c, AVIOContext *pb, MOVAtom atom)
5337 if (c->fc->nb_streams < 1)
5339 st = c->fc->streams[c->fc->nb_streams - 1];
5341 if (atom.size < 4) {
5342 av_log(c->fc, AV_LOG_ERROR, "Empty AV1 Codec Configuration Box\n");
5343 return AVERROR_INVALIDDATA;
5346 /* For now, propagate only the OBUs, if any. Once libavcodec is
5347 updated to handle isobmff style extradata this can be removed. */
5353 ret = ff_get_extradata(c->fc, st->codecpar, pb, atom.size - 4);
5360 static int mov_read_vpcc(MOVContext *c, AVIOContext *pb, MOVAtom atom)
5363 int version, color_range, color_primaries, color_trc, color_space;
5365 if (c->fc->nb_streams < 1)
5367 st = c->fc->streams[c->fc->nb_streams - 1];
5369 if (atom.size < 5) {
5370 av_log(c->fc, AV_LOG_ERROR, "Empty VP Codec Configuration box\n");
5371 return AVERROR_INVALIDDATA;
5374 version = avio_r8(pb);
5376 av_log(c->fc, AV_LOG_WARNING, "Unsupported VP Codec Configuration box version %d\n", version);
5379 avio_skip(pb, 3); /* flags */
5381 avio_skip(pb, 2); /* profile + level */
5382 color_range = avio_r8(pb); /* bitDepth, chromaSubsampling, videoFullRangeFlag */
5383 color_primaries = avio_r8(pb);
5384 color_trc = avio_r8(pb);
5385 color_space = avio_r8(pb);
5386 if (avio_rb16(pb)) /* codecIntializationDataSize */
5387 return AVERROR_INVALIDDATA;
5389 if (!av_color_primaries_name(color_primaries))
5390 color_primaries = AVCOL_PRI_UNSPECIFIED;
5391 if (!av_color_transfer_name(color_trc))
5392 color_trc = AVCOL_TRC_UNSPECIFIED;
5393 if (!av_color_space_name(color_space))
5394 color_space = AVCOL_SPC_UNSPECIFIED;
5396 st->codecpar->color_range = (color_range & 1) ? AVCOL_RANGE_JPEG : AVCOL_RANGE_MPEG;
5397 st->codecpar->color_primaries = color_primaries;
5398 st->codecpar->color_trc = color_trc;
5399 st->codecpar->color_space = color_space;
5404 static int mov_read_smdm(MOVContext *c, AVIOContext *pb, MOVAtom atom)
5406 MOVStreamContext *sc;
5409 if (c->fc->nb_streams < 1)
5410 return AVERROR_INVALIDDATA;
5412 sc = c->fc->streams[c->fc->nb_streams - 1]->priv_data;
5414 if (atom.size < 5) {
5415 av_log(c->fc, AV_LOG_ERROR, "Empty Mastering Display Metadata box\n");
5416 return AVERROR_INVALIDDATA;
5419 version = avio_r8(pb);
5421 av_log(c->fc, AV_LOG_WARNING, "Unsupported Mastering Display Metadata box version %d\n", version);
5424 avio_skip(pb, 3); /* flags */
5426 sc->mastering = av_mastering_display_metadata_alloc();
5428 return AVERROR(ENOMEM);
5430 for (i = 0; i < 3; i++) {
5431 sc->mastering->display_primaries[i][0] = av_make_q(avio_rb16(pb), 1 << 16);
5432 sc->mastering->display_primaries[i][1] = av_make_q(avio_rb16(pb), 1 << 16);
5434 sc->mastering->white_point[0] = av_make_q(avio_rb16(pb), 1 << 16);
5435 sc->mastering->white_point[1] = av_make_q(avio_rb16(pb), 1 << 16);
5437 sc->mastering->max_luminance = av_make_q(avio_rb32(pb), 1 << 8);
5438 sc->mastering->min_luminance = av_make_q(avio_rb32(pb), 1 << 14);
5440 sc->mastering->has_primaries = 1;
5441 sc->mastering->has_luminance = 1;
5446 static int mov_read_mdcv(MOVContext *c, AVIOContext *pb, MOVAtom atom)
5448 MOVStreamContext *sc;
5449 const int mapping[3] = {1, 2, 0};
5450 const int chroma_den = 50000;
5451 const int luma_den = 10000;
5454 if (c->fc->nb_streams < 1)
5455 return AVERROR_INVALIDDATA;
5457 sc = c->fc->streams[c->fc->nb_streams - 1]->priv_data;
5459 if (atom.size < 24) {
5460 av_log(c->fc, AV_LOG_ERROR, "Invalid Mastering Display Color Volume box\n");
5461 return AVERROR_INVALIDDATA;
5464 sc->mastering = av_mastering_display_metadata_alloc();
5466 return AVERROR(ENOMEM);
5468 for (i = 0; i < 3; i++) {
5469 const int j = mapping[i];
5470 sc->mastering->display_primaries[j][0] = av_make_q(avio_rb16(pb), chroma_den);
5471 sc->mastering->display_primaries[j][1] = av_make_q(avio_rb16(pb), chroma_den);
5473 sc->mastering->white_point[0] = av_make_q(avio_rb16(pb), chroma_den);
5474 sc->mastering->white_point[1] = av_make_q(avio_rb16(pb), chroma_den);
5476 sc->mastering->max_luminance = av_make_q(avio_rb32(pb), luma_den);
5477 sc->mastering->min_luminance = av_make_q(avio_rb32(pb), luma_den);
5479 sc->mastering->has_luminance = 1;
5480 sc->mastering->has_primaries = 1;
5485 static int mov_read_coll(MOVContext *c, AVIOContext *pb, MOVAtom atom)
5487 MOVStreamContext *sc;
5490 if (c->fc->nb_streams < 1)
5491 return AVERROR_INVALIDDATA;
5493 sc = c->fc->streams[c->fc->nb_streams - 1]->priv_data;
5495 if (atom.size < 5) {
5496 av_log(c->fc, AV_LOG_ERROR, "Empty Content Light Level box\n");
5497 return AVERROR_INVALIDDATA;
5500 version = avio_r8(pb);
5502 av_log(c->fc, AV_LOG_WARNING, "Unsupported Content Light Level box version %d\n", version);
5505 avio_skip(pb, 3); /* flags */
5507 sc->coll = av_content_light_metadata_alloc(&sc->coll_size);
5509 return AVERROR(ENOMEM);
5511 sc->coll->MaxCLL = avio_rb16(pb);
5512 sc->coll->MaxFALL = avio_rb16(pb);
5517 static int mov_read_clli(MOVContext *c, AVIOContext *pb, MOVAtom atom)
5519 MOVStreamContext *sc;
5521 if (c->fc->nb_streams < 1)
5522 return AVERROR_INVALIDDATA;
5524 sc = c->fc->streams[c->fc->nb_streams - 1]->priv_data;
5526 if (atom.size < 4) {
5527 av_log(c->fc, AV_LOG_ERROR, "Empty Content Light Level Info box\n");
5528 return AVERROR_INVALIDDATA;
5531 sc->coll = av_content_light_metadata_alloc(&sc->coll_size);
5533 return AVERROR(ENOMEM);
5535 sc->coll->MaxCLL = avio_rb16(pb);
5536 sc->coll->MaxFALL = avio_rb16(pb);
5541 static int mov_read_st3d(MOVContext *c, AVIOContext *pb, MOVAtom atom)
5544 MOVStreamContext *sc;
5545 enum AVStereo3DType type;
5548 if (c->fc->nb_streams < 1)
5551 st = c->fc->streams[c->fc->nb_streams - 1];
5554 if (atom.size < 5) {
5555 av_log(c->fc, AV_LOG_ERROR, "Empty stereoscopic video box\n");
5556 return AVERROR_INVALIDDATA;
5560 return AVERROR_INVALIDDATA;
5562 avio_skip(pb, 4); /* version + flags */
5567 type = AV_STEREO3D_2D;
5570 type = AV_STEREO3D_TOPBOTTOM;
5573 type = AV_STEREO3D_SIDEBYSIDE;
5576 av_log(c->fc, AV_LOG_WARNING, "Unknown st3d mode value %d\n", mode);
5580 sc->stereo3d = av_stereo3d_alloc();
5582 return AVERROR(ENOMEM);
5584 sc->stereo3d->type = type;
5588 static int mov_read_sv3d(MOVContext *c, AVIOContext *pb, MOVAtom atom)
5591 MOVStreamContext *sc;
5592 int size, version, layout;
5593 int32_t yaw, pitch, roll;
5594 uint32_t l = 0, t = 0, r = 0, b = 0;
5595 uint32_t tag, padding = 0;
5596 enum AVSphericalProjection projection;
5598 if (c->fc->nb_streams < 1)
5601 st = c->fc->streams[c->fc->nb_streams - 1];
5604 if (atom.size < 8) {
5605 av_log(c->fc, AV_LOG_ERROR, "Empty spherical video box\n");
5606 return AVERROR_INVALIDDATA;
5609 size = avio_rb32(pb);
5610 if (size <= 12 || size > atom.size)
5611 return AVERROR_INVALIDDATA;
5613 tag = avio_rl32(pb);
5614 if (tag != MKTAG('s','v','h','d')) {
5615 av_log(c->fc, AV_LOG_ERROR, "Missing spherical video header\n");
5618 version = avio_r8(pb);
5620 av_log(c->fc, AV_LOG_WARNING, "Unknown spherical version %d\n",
5624 avio_skip(pb, 3); /* flags */
5625 avio_skip(pb, size - 12); /* metadata_source */
5627 size = avio_rb32(pb);
5628 if (size > atom.size)
5629 return AVERROR_INVALIDDATA;
5631 tag = avio_rl32(pb);
5632 if (tag != MKTAG('p','r','o','j')) {
5633 av_log(c->fc, AV_LOG_ERROR, "Missing projection box\n");
5637 size = avio_rb32(pb);
5638 if (size > atom.size)
5639 return AVERROR_INVALIDDATA;
5641 tag = avio_rl32(pb);
5642 if (tag != MKTAG('p','r','h','d')) {
5643 av_log(c->fc, AV_LOG_ERROR, "Missing projection header box\n");
5646 version = avio_r8(pb);
5648 av_log(c->fc, AV_LOG_WARNING, "Unknown spherical version %d\n",
5652 avio_skip(pb, 3); /* flags */
5654 /* 16.16 fixed point */
5655 yaw = avio_rb32(pb);
5656 pitch = avio_rb32(pb);
5657 roll = avio_rb32(pb);
5659 size = avio_rb32(pb);
5660 if (size > atom.size)
5661 return AVERROR_INVALIDDATA;
5663 tag = avio_rl32(pb);
5664 version = avio_r8(pb);
5666 av_log(c->fc, AV_LOG_WARNING, "Unknown spherical version %d\n",
5670 avio_skip(pb, 3); /* flags */
5672 case MKTAG('c','b','m','p'):
5673 layout = avio_rb32(pb);
5675 av_log(c->fc, AV_LOG_WARNING,
5676 "Unsupported cubemap layout %d\n", layout);
5679 projection = AV_SPHERICAL_CUBEMAP;
5680 padding = avio_rb32(pb);
5682 case MKTAG('e','q','u','i'):
5688 if (b >= UINT_MAX - t || r >= UINT_MAX - l) {
5689 av_log(c->fc, AV_LOG_ERROR,
5690 "Invalid bounding rectangle coordinates "
5691 "%"PRIu32",%"PRIu32",%"PRIu32",%"PRIu32"\n", l, t, r, b);
5692 return AVERROR_INVALIDDATA;
5695 if (l || t || r || b)
5696 projection = AV_SPHERICAL_EQUIRECTANGULAR_TILE;
5698 projection = AV_SPHERICAL_EQUIRECTANGULAR;
5701 av_log(c->fc, AV_LOG_ERROR, "Unknown projection type: %s\n", av_fourcc2str(tag));
5705 sc->spherical = av_spherical_alloc(&sc->spherical_size);
5707 return AVERROR(ENOMEM);
5709 sc->spherical->projection = projection;
5711 sc->spherical->yaw = yaw;
5712 sc->spherical->pitch = pitch;
5713 sc->spherical->roll = roll;
5715 sc->spherical->padding = padding;
5717 sc->spherical->bound_left = l;
5718 sc->spherical->bound_top = t;
5719 sc->spherical->bound_right = r;
5720 sc->spherical->bound_bottom = b;
5725 static int mov_parse_uuid_spherical(MOVStreamContext *sc, AVIOContext *pb, size_t len)
5728 uint8_t *buffer = av_malloc(len + 1);
5732 return AVERROR(ENOMEM);
5735 ret = ffio_read_size(pb, buffer, len);
5739 /* Check for mandatory keys and values, try to support XML as best-effort */
5740 if (!sc->spherical &&
5741 av_stristr(buffer, "<GSpherical:StitchingSoftware>") &&
5742 (val = av_stristr(buffer, "<GSpherical:Spherical>")) &&
5743 av_stristr(val, "true") &&
5744 (val = av_stristr(buffer, "<GSpherical:Stitched>")) &&
5745 av_stristr(val, "true") &&
5746 (val = av_stristr(buffer, "<GSpherical:ProjectionType>")) &&
5747 av_stristr(val, "equirectangular")) {
5748 sc->spherical = av_spherical_alloc(&sc->spherical_size);
5752 sc->spherical->projection = AV_SPHERICAL_EQUIRECTANGULAR;
5754 if (av_stristr(buffer, "<GSpherical:StereoMode>") && !sc->stereo3d) {
5755 enum AVStereo3DType mode;
5757 if (av_stristr(buffer, "left-right"))
5758 mode = AV_STEREO3D_SIDEBYSIDE;
5759 else if (av_stristr(buffer, "top-bottom"))
5760 mode = AV_STEREO3D_TOPBOTTOM;
5762 mode = AV_STEREO3D_2D;
5764 sc->stereo3d = av_stereo3d_alloc();
5768 sc->stereo3d->type = mode;
5772 val = av_stristr(buffer, "<GSpherical:InitialViewHeadingDegrees>");
5774 sc->spherical->yaw = strtol(val, NULL, 10) * (1 << 16);
5775 val = av_stristr(buffer, "<GSpherical:InitialViewPitchDegrees>");
5777 sc->spherical->pitch = strtol(val, NULL, 10) * (1 << 16);
5778 val = av_stristr(buffer, "<GSpherical:InitialViewRollDegrees>");
5780 sc->spherical->roll = strtol(val, NULL, 10) * (1 << 16);
5788 static int mov_read_uuid(MOVContext *c, AVIOContext *pb, MOVAtom atom)
5791 MOVStreamContext *sc;
5794 static const uint8_t uuid_isml_manifest[] = {
5795 0xa5, 0xd4, 0x0b, 0x30, 0xe8, 0x14, 0x11, 0xdd,
5796 0xba, 0x2f, 0x08, 0x00, 0x20, 0x0c, 0x9a, 0x66
5798 static const uint8_t uuid_xmp[] = {
5799 0xbe, 0x7a, 0xcf, 0xcb, 0x97, 0xa9, 0x42, 0xe8,
5800 0x9c, 0x71, 0x99, 0x94, 0x91, 0xe3, 0xaf, 0xac
5802 static const uint8_t uuid_spherical[] = {
5803 0xff, 0xcc, 0x82, 0x63, 0xf8, 0x55, 0x4a, 0x93,
5804 0x88, 0x14, 0x58, 0x7a, 0x02, 0x52, 0x1f, 0xdd,
5807 if (atom.size < sizeof(uuid) || atom.size >= FFMIN(INT_MAX, SIZE_MAX))
5808 return AVERROR_INVALIDDATA;
5810 if (c->fc->nb_streams < 1)
5812 st = c->fc->streams[c->fc->nb_streams - 1];
5815 ret = ffio_read_size(pb, uuid, sizeof(uuid));
5818 if (!memcmp(uuid, uuid_isml_manifest, sizeof(uuid))) {
5819 uint8_t *buffer, *ptr;
5821 size_t len = atom.size - sizeof(uuid);
5824 return AVERROR_INVALIDDATA;
5826 ret = avio_skip(pb, 4); // zeroes
5829 buffer = av_mallocz(len + 1);
5831 return AVERROR(ENOMEM);
5833 ret = ffio_read_size(pb, buffer, len);
5840 while ((ptr = av_stristr(ptr, "systemBitrate=\""))) {
5841 ptr += sizeof("systemBitrate=\"") - 1;
5842 c->bitrates_count++;
5843 c->bitrates = av_realloc_f(c->bitrates, c->bitrates_count, sizeof(*c->bitrates));
5845 c->bitrates_count = 0;
5847 return AVERROR(ENOMEM);
5850 ret = strtol(ptr, &endptr, 10);
5851 if (ret < 0 || errno || *endptr != '"') {
5852 c->bitrates[c->bitrates_count - 1] = 0;
5854 c->bitrates[c->bitrates_count - 1] = ret;
5859 } else if (!memcmp(uuid, uuid_xmp, sizeof(uuid))) {
5861 size_t len = atom.size - sizeof(uuid);
5862 if (c->export_xmp) {
5863 buffer = av_mallocz(len + 1);
5865 return AVERROR(ENOMEM);
5867 ret = ffio_read_size(pb, buffer, len);
5873 av_dict_set(&c->fc->metadata, "xmp",
5874 buffer, AV_DICT_DONT_STRDUP_VAL);
5876 // skip all uuid atom, which makes it fast for long uuid-xmp file
5877 ret = avio_skip(pb, len);
5881 } else if (!memcmp(uuid, uuid_spherical, sizeof(uuid))) {
5882 size_t len = atom.size - sizeof(uuid);
5883 ret = mov_parse_uuid_spherical(sc, pb, len);
5887 av_log(c->fc, AV_LOG_WARNING, "Invalid spherical metadata found\n");
5893 static int mov_read_free(MOVContext *c, AVIOContext *pb, MOVAtom atom)
5896 uint8_t content[16];
5901 ret = avio_read(pb, content, FFMIN(sizeof(content), atom.size));
5907 && !memcmp(content, "Anevia\x1A\x1A", 8)
5908 && c->use_mfra_for == FF_MOV_FLAG_MFRA_AUTO) {
5909 c->use_mfra_for = FF_MOV_FLAG_MFRA_PTS;
5915 static int mov_read_frma(MOVContext *c, AVIOContext *pb, MOVAtom atom)
5917 uint32_t format = avio_rl32(pb);
5918 MOVStreamContext *sc;
5922 if (c->fc->nb_streams < 1)
5924 st = c->fc->streams[c->fc->nb_streams - 1];
5929 case MKTAG('e','n','c','v'): // encrypted video
5930 case MKTAG('e','n','c','a'): // encrypted audio
5931 id = mov_codec_id(st, format);
5932 if (st->codecpar->codec_id != AV_CODEC_ID_NONE &&
5933 st->codecpar->codec_id != id) {
5934 av_log(c->fc, AV_LOG_WARNING,
5935 "ignoring 'frma' atom of '%.4s', stream has codec id %d\n",
5936 (char*)&format, st->codecpar->codec_id);
5940 st->codecpar->codec_id = id;
5941 sc->format = format;
5945 if (format != sc->format) {
5946 av_log(c->fc, AV_LOG_WARNING,
5947 "ignoring 'frma' atom of '%.4s', stream format is '%.4s'\n",
5948 (char*)&format, (char*)&sc->format);
5957 * Gets the current encryption info and associated current stream context. If
5958 * we are parsing a track fragment, this will return the specific encryption
5959 * info for this fragment; otherwise this will return the global encryption
5960 * info for the current stream.
5962 static int get_current_encryption_info(MOVContext *c, MOVEncryptionIndex **encryption_index, MOVStreamContext **sc)
5964 MOVFragmentStreamInfo *frag_stream_info;
5968 frag_stream_info = get_current_frag_stream_info(&c->frag_index);
5969 if (frag_stream_info) {
5970 for (i = 0; i < c->fc->nb_streams; i++) {
5971 if (c->fc->streams[i]->id == frag_stream_info->id) {
5972 st = c->fc->streams[i];
5976 if (i == c->fc->nb_streams)
5978 *sc = st->priv_data;
5980 if (!frag_stream_info->encryption_index) {
5981 // If this stream isn't encrypted, don't create the index.
5982 if (!(*sc)->cenc.default_encrypted_sample)
5984 frag_stream_info->encryption_index = av_mallocz(sizeof(*frag_stream_info->encryption_index));
5985 if (!frag_stream_info->encryption_index)
5986 return AVERROR(ENOMEM);
5988 *encryption_index = frag_stream_info->encryption_index;
5991 // No current track fragment, using stream level encryption info.
5993 if (c->fc->nb_streams < 1)
5995 st = c->fc->streams[c->fc->nb_streams - 1];
5996 *sc = st->priv_data;
5998 if (!(*sc)->cenc.encryption_index) {
5999 // If this stream isn't encrypted, don't create the index.
6000 if (!(*sc)->cenc.default_encrypted_sample)
6002 (*sc)->cenc.encryption_index = av_mallocz(sizeof(*frag_stream_info->encryption_index));
6003 if (!(*sc)->cenc.encryption_index)
6004 return AVERROR(ENOMEM);
6007 *encryption_index = (*sc)->cenc.encryption_index;
6012 static int mov_read_sample_encryption_info(MOVContext *c, AVIOContext *pb, MOVStreamContext *sc, AVEncryptionInfo **sample, int use_subsamples)
6015 unsigned int subsample_count;
6016 AVSubsampleEncryptionInfo *subsamples;
6018 if (!sc->cenc.default_encrypted_sample) {
6019 av_log(c->fc, AV_LOG_ERROR, "Missing schm or tenc\n");
6020 return AVERROR_INVALIDDATA;
6023 *sample = av_encryption_info_clone(sc->cenc.default_encrypted_sample);
6025 return AVERROR(ENOMEM);
6027 if (sc->cenc.per_sample_iv_size != 0) {
6028 if ((ret = ffio_read_size(pb, (*sample)->iv, sc->cenc.per_sample_iv_size)) < 0) {
6029 av_log(c->fc, AV_LOG_ERROR, "failed to read the initialization vector\n");
6030 av_encryption_info_free(*sample);
6036 if (use_subsamples) {
6037 subsample_count = avio_rb16(pb);
6038 av_free((*sample)->subsamples);
6039 (*sample)->subsamples = av_mallocz_array(subsample_count, sizeof(*subsamples));
6040 if (!(*sample)->subsamples) {
6041 av_encryption_info_free(*sample);
6043 return AVERROR(ENOMEM);
6046 for (i = 0; i < subsample_count && !pb->eof_reached; i++) {
6047 (*sample)->subsamples[i].bytes_of_clear_data = avio_rb16(pb);
6048 (*sample)->subsamples[i].bytes_of_protected_data = avio_rb32(pb);
6051 if (pb->eof_reached) {
6052 av_log(c->fc, AV_LOG_ERROR, "hit EOF while reading sub-sample encryption info\n");
6053 av_encryption_info_free(*sample);
6055 return AVERROR_INVALIDDATA;
6057 (*sample)->subsample_count = subsample_count;
6063 static int mov_read_senc(MOVContext *c, AVIOContext *pb, MOVAtom atom)
6065 AVEncryptionInfo **encrypted_samples;
6066 MOVEncryptionIndex *encryption_index;
6067 MOVStreamContext *sc;
6068 int use_subsamples, ret;
6069 unsigned int sample_count, i, alloc_size = 0;
6071 ret = get_current_encryption_info(c, &encryption_index, &sc);
6075 if (encryption_index->nb_encrypted_samples) {
6076 // This can happen if we have both saio/saiz and senc atoms.
6077 av_log(c->fc, AV_LOG_DEBUG, "Ignoring duplicate encryption info in senc\n");
6081 avio_r8(pb); /* version */
6082 use_subsamples = avio_rb24(pb) & 0x02; /* flags */
6084 sample_count = avio_rb32(pb);
6085 if (sample_count >= INT_MAX / sizeof(*encrypted_samples))
6086 return AVERROR(ENOMEM);
6088 for (i = 0; i < sample_count; i++) {
6089 unsigned int min_samples = FFMIN(FFMAX(i + 1, 1024 * 1024), sample_count);
6090 encrypted_samples = av_fast_realloc(encryption_index->encrypted_samples, &alloc_size,
6091 min_samples * sizeof(*encrypted_samples));
6092 if (encrypted_samples) {
6093 encryption_index->encrypted_samples = encrypted_samples;
6095 ret = mov_read_sample_encryption_info(
6096 c, pb, sc, &encryption_index->encrypted_samples[i], use_subsamples);
6098 ret = AVERROR(ENOMEM);
6100 if (pb->eof_reached) {
6101 av_log(c->fc, AV_LOG_ERROR, "Hit EOF while reading senc\n");
6102 ret = AVERROR_INVALIDDATA;
6107 av_encryption_info_free(encryption_index->encrypted_samples[i - 1]);
6108 av_freep(&encryption_index->encrypted_samples);
6112 encryption_index->nb_encrypted_samples = sample_count;
6117 static int mov_parse_auxiliary_info(MOVContext *c, MOVStreamContext *sc, AVIOContext *pb, MOVEncryptionIndex *encryption_index)
6119 AVEncryptionInfo **sample, **encrypted_samples;
6121 size_t sample_count, sample_info_size, i;
6123 unsigned int alloc_size = 0;
6125 if (encryption_index->nb_encrypted_samples)
6127 sample_count = encryption_index->auxiliary_info_sample_count;
6128 if (encryption_index->auxiliary_offsets_count != 1) {
6129 av_log(c->fc, AV_LOG_ERROR, "Multiple auxiliary info chunks are not supported\n");
6130 return AVERROR_PATCHWELCOME;
6132 if (sample_count >= INT_MAX / sizeof(*encrypted_samples))
6133 return AVERROR(ENOMEM);
6135 prev_pos = avio_tell(pb);
6136 if (!(pb->seekable & AVIO_SEEKABLE_NORMAL) ||
6137 avio_seek(pb, encryption_index->auxiliary_offsets[0], SEEK_SET) != encryption_index->auxiliary_offsets[0]) {
6138 av_log(c->fc, AV_LOG_INFO, "Failed to seek for auxiliary info, will only parse senc atoms for encryption info\n");
6142 for (i = 0; i < sample_count && !pb->eof_reached; i++) {
6143 unsigned int min_samples = FFMIN(FFMAX(i + 1, 1024 * 1024), sample_count);
6144 encrypted_samples = av_fast_realloc(encryption_index->encrypted_samples, &alloc_size,
6145 min_samples * sizeof(*encrypted_samples));
6146 if (!encrypted_samples) {
6147 ret = AVERROR(ENOMEM);
6150 encryption_index->encrypted_samples = encrypted_samples;
6152 sample = &encryption_index->encrypted_samples[i];
6153 sample_info_size = encryption_index->auxiliary_info_default_size
6154 ? encryption_index->auxiliary_info_default_size
6155 : encryption_index->auxiliary_info_sizes[i];
6157 ret = mov_read_sample_encryption_info(c, pb, sc, sample, sample_info_size > sc->cenc.per_sample_iv_size);
6161 if (pb->eof_reached) {
6162 av_log(c->fc, AV_LOG_ERROR, "Hit EOF while reading auxiliary info\n");
6163 ret = AVERROR_INVALIDDATA;
6165 encryption_index->nb_encrypted_samples = sample_count;
6169 avio_seek(pb, prev_pos, SEEK_SET);
6171 for (; i > 0; i--) {
6172 av_encryption_info_free(encryption_index->encrypted_samples[i - 1]);
6174 av_freep(&encryption_index->encrypted_samples);
6180 * Tries to read the given number of bytes from the stream and puts it in a
6181 * newly allocated buffer. This reads in small chunks to avoid allocating large
6182 * memory if the file contains an invalid/malicious size value.
6184 static int mov_try_read_block(AVIOContext *pb, size_t size, uint8_t **data)
6186 const unsigned int block_size = 1024 * 1024;
6187 uint8_t *buffer = NULL;
6188 unsigned int alloc_size = 0, offset = 0;
6189 while (offset < size) {
6190 unsigned int new_size =
6191 alloc_size >= INT_MAX - block_size ? INT_MAX : alloc_size + block_size;
6192 uint8_t *new_buffer = av_fast_realloc(buffer, &alloc_size, new_size);
6193 unsigned int to_read = FFMIN(size, alloc_size) - offset;
6196 return AVERROR(ENOMEM);
6198 buffer = new_buffer;
6200 if (avio_read(pb, buffer + offset, to_read) != to_read) {
6202 return AVERROR_INVALIDDATA;
6211 static int mov_read_saiz(MOVContext *c, AVIOContext *pb, MOVAtom atom)
6213 MOVEncryptionIndex *encryption_index;
6214 MOVStreamContext *sc;
6216 unsigned int sample_count, aux_info_type, aux_info_param;
6218 ret = get_current_encryption_info(c, &encryption_index, &sc);
6222 if (encryption_index->nb_encrypted_samples) {
6223 // This can happen if we have both saio/saiz and senc atoms.
6224 av_log(c->fc, AV_LOG_DEBUG, "Ignoring duplicate encryption info in saiz\n");
6228 if (encryption_index->auxiliary_info_sample_count) {
6229 av_log(c->fc, AV_LOG_ERROR, "Duplicate saiz atom\n");
6230 return AVERROR_INVALIDDATA;
6233 avio_r8(pb); /* version */
6234 if (avio_rb24(pb) & 0x01) { /* flags */
6235 aux_info_type = avio_rb32(pb);
6236 aux_info_param = avio_rb32(pb);
6237 if (sc->cenc.default_encrypted_sample) {
6238 if (aux_info_type != sc->cenc.default_encrypted_sample->scheme) {
6239 av_log(c->fc, AV_LOG_DEBUG, "Ignoring saiz box with non-zero aux_info_type\n");
6242 if (aux_info_param != 0) {
6243 av_log(c->fc, AV_LOG_DEBUG, "Ignoring saiz box with non-zero aux_info_type_parameter\n");
6247 // Didn't see 'schm' or 'tenc', so this isn't encrypted.
6248 if ((aux_info_type == MKBETAG('c','e','n','c') ||
6249 aux_info_type == MKBETAG('c','e','n','s') ||
6250 aux_info_type == MKBETAG('c','b','c','1') ||
6251 aux_info_type == MKBETAG('c','b','c','s')) &&
6252 aux_info_param == 0) {
6253 av_log(c->fc, AV_LOG_ERROR, "Saw encrypted saiz without schm/tenc\n");
6254 return AVERROR_INVALIDDATA;
6259 } else if (!sc->cenc.default_encrypted_sample) {
6260 // Didn't see 'schm' or 'tenc', so this isn't encrypted.
6264 encryption_index->auxiliary_info_default_size = avio_r8(pb);
6265 sample_count = avio_rb32(pb);
6266 encryption_index->auxiliary_info_sample_count = sample_count;
6268 if (encryption_index->auxiliary_info_default_size == 0) {
6269 ret = mov_try_read_block(pb, sample_count, &encryption_index->auxiliary_info_sizes);
6271 av_log(c->fc, AV_LOG_ERROR, "Failed to read the auxiliary info\n");
6276 if (encryption_index->auxiliary_offsets_count) {
6277 return mov_parse_auxiliary_info(c, sc, pb, encryption_index);
6283 static int mov_read_saio(MOVContext *c, AVIOContext *pb, MOVAtom atom)
6285 uint64_t *auxiliary_offsets;
6286 MOVEncryptionIndex *encryption_index;
6287 MOVStreamContext *sc;
6289 unsigned int version, entry_count, aux_info_type, aux_info_param;
6290 unsigned int alloc_size = 0;
6292 ret = get_current_encryption_info(c, &encryption_index, &sc);
6296 if (encryption_index->nb_encrypted_samples) {
6297 // This can happen if we have both saio/saiz and senc atoms.
6298 av_log(c->fc, AV_LOG_DEBUG, "Ignoring duplicate encryption info in saio\n");
6302 if (encryption_index->auxiliary_offsets_count) {
6303 av_log(c->fc, AV_LOG_ERROR, "Duplicate saio atom\n");
6304 return AVERROR_INVALIDDATA;
6307 version = avio_r8(pb); /* version */
6308 if (avio_rb24(pb) & 0x01) { /* flags */
6309 aux_info_type = avio_rb32(pb);
6310 aux_info_param = avio_rb32(pb);
6311 if (sc->cenc.default_encrypted_sample) {
6312 if (aux_info_type != sc->cenc.default_encrypted_sample->scheme) {
6313 av_log(c->fc, AV_LOG_DEBUG, "Ignoring saio box with non-zero aux_info_type\n");
6316 if (aux_info_param != 0) {
6317 av_log(c->fc, AV_LOG_DEBUG, "Ignoring saio box with non-zero aux_info_type_parameter\n");
6321 // Didn't see 'schm' or 'tenc', so this isn't encrypted.
6322 if ((aux_info_type == MKBETAG('c','e','n','c') ||
6323 aux_info_type == MKBETAG('c','e','n','s') ||
6324 aux_info_type == MKBETAG('c','b','c','1') ||
6325 aux_info_type == MKBETAG('c','b','c','s')) &&
6326 aux_info_param == 0) {
6327 av_log(c->fc, AV_LOG_ERROR, "Saw encrypted saio without schm/tenc\n");
6328 return AVERROR_INVALIDDATA;
6333 } else if (!sc->cenc.default_encrypted_sample) {
6334 // Didn't see 'schm' or 'tenc', so this isn't encrypted.
6338 entry_count = avio_rb32(pb);
6339 if (entry_count >= INT_MAX / sizeof(*auxiliary_offsets))
6340 return AVERROR(ENOMEM);
6342 for (i = 0; i < entry_count && !pb->eof_reached; i++) {
6343 unsigned int min_offsets = FFMIN(FFMAX(i + 1, 1024), entry_count);
6344 auxiliary_offsets = av_fast_realloc(
6345 encryption_index->auxiliary_offsets, &alloc_size,
6346 min_offsets * sizeof(*auxiliary_offsets));
6347 if (!auxiliary_offsets) {
6348 av_freep(&encryption_index->auxiliary_offsets);
6349 return AVERROR(ENOMEM);
6351 encryption_index->auxiliary_offsets = auxiliary_offsets;
6354 encryption_index->auxiliary_offsets[i] = avio_rb32(pb);
6356 encryption_index->auxiliary_offsets[i] = avio_rb64(pb);
6358 if (c->frag_index.current >= 0) {
6359 encryption_index->auxiliary_offsets[i] += c->fragment.base_data_offset;
6363 if (pb->eof_reached) {
6364 av_log(c->fc, AV_LOG_ERROR, "Hit EOF while reading saio\n");
6365 av_freep(&encryption_index->auxiliary_offsets);
6366 return AVERROR_INVALIDDATA;
6369 encryption_index->auxiliary_offsets_count = entry_count;
6371 if (encryption_index->auxiliary_info_sample_count) {
6372 return mov_parse_auxiliary_info(c, sc, pb, encryption_index);
6378 static int mov_read_pssh(MOVContext *c, AVIOContext *pb, MOVAtom atom)
6380 AVEncryptionInitInfo *info, *old_init_info;
6383 uint8_t *side_data, *extra_data, *old_side_data;
6384 size_t side_data_size;
6385 buffer_size_t old_side_data_size;
6387 unsigned int version, kid_count, extra_data_size, alloc_size = 0;
6389 if (c->fc->nb_streams < 1)
6391 st = c->fc->streams[c->fc->nb_streams-1];
6393 version = avio_r8(pb); /* version */
6394 avio_rb24(pb); /* flags */
6396 info = av_encryption_init_info_alloc(/* system_id_size */ 16, /* num_key_ids */ 0,
6397 /* key_id_size */ 16, /* data_size */ 0);
6399 return AVERROR(ENOMEM);
6401 if ((ret = ffio_read_size(pb, info->system_id, 16)) < 0) {
6402 av_log(c->fc, AV_LOG_ERROR, "Failed to read the system id\n");
6407 kid_count = avio_rb32(pb);
6408 if (kid_count >= INT_MAX / sizeof(*key_ids)) {
6409 ret = AVERROR(ENOMEM);
6413 for (unsigned int i = 0; i < kid_count && !pb->eof_reached; i++) {
6414 unsigned int min_kid_count = FFMIN(FFMAX(i + 1, 1024), kid_count);
6415 key_ids = av_fast_realloc(info->key_ids, &alloc_size,
6416 min_kid_count * sizeof(*key_ids));
6418 ret = AVERROR(ENOMEM);
6421 info->key_ids = key_ids;
6423 info->key_ids[i] = av_mallocz(16);
6424 if (!info->key_ids[i]) {
6425 ret = AVERROR(ENOMEM);
6428 info->num_key_ids = i + 1;
6430 if ((ret = ffio_read_size(pb, info->key_ids[i], 16)) < 0) {
6431 av_log(c->fc, AV_LOG_ERROR, "Failed to read the key id\n");
6436 if (pb->eof_reached) {
6437 av_log(c->fc, AV_LOG_ERROR, "Hit EOF while reading pssh\n");
6438 ret = AVERROR_INVALIDDATA;
6443 extra_data_size = avio_rb32(pb);
6444 ret = mov_try_read_block(pb, extra_data_size, &extra_data);
6448 av_freep(&info->data); // malloc(0) may still allocate something.
6449 info->data = extra_data;
6450 info->data_size = extra_data_size;
6452 // If there is existing initialization data, append to the list.
6453 old_side_data = av_stream_get_side_data(st, AV_PKT_DATA_ENCRYPTION_INIT_INFO, &old_side_data_size);
6454 if (old_side_data) {
6455 old_init_info = av_encryption_init_info_get_side_data(old_side_data, old_side_data_size);
6456 if (old_init_info) {
6457 // Append to the end of the list.
6458 for (AVEncryptionInitInfo *cur = old_init_info;; cur = cur->next) {
6464 info = old_init_info;
6466 // Assume existing side-data will be valid, so the only error we could get is OOM.
6467 ret = AVERROR(ENOMEM);
6472 side_data = av_encryption_init_info_add_side_data(info, &side_data_size);
6474 ret = AVERROR(ENOMEM);
6477 ret = av_stream_add_side_data(st, AV_PKT_DATA_ENCRYPTION_INIT_INFO,
6478 side_data, side_data_size);
6483 av_encryption_init_info_free(info);
6487 static int mov_read_schm(MOVContext *c, AVIOContext *pb, MOVAtom atom)
6490 MOVStreamContext *sc;
6492 if (c->fc->nb_streams < 1)
6494 st = c->fc->streams[c->fc->nb_streams-1];
6497 if (sc->pseudo_stream_id != 0) {
6498 av_log(c->fc, AV_LOG_ERROR, "schm boxes are only supported in first sample descriptor\n");
6499 return AVERROR_PATCHWELCOME;
6503 return AVERROR_INVALIDDATA;
6505 avio_rb32(pb); /* version and flags */
6507 if (!sc->cenc.default_encrypted_sample) {
6508 sc->cenc.default_encrypted_sample = av_encryption_info_alloc(0, 16, 16);
6509 if (!sc->cenc.default_encrypted_sample) {
6510 return AVERROR(ENOMEM);
6514 sc->cenc.default_encrypted_sample->scheme = avio_rb32(pb);
6518 static int mov_read_tenc(MOVContext *c, AVIOContext *pb, MOVAtom atom)
6521 MOVStreamContext *sc;
6522 unsigned int version, pattern, is_protected, iv_size;
6524 if (c->fc->nb_streams < 1)
6526 st = c->fc->streams[c->fc->nb_streams-1];
6529 if (sc->pseudo_stream_id != 0) {
6530 av_log(c->fc, AV_LOG_ERROR, "tenc atom are only supported in first sample descriptor\n");
6531 return AVERROR_PATCHWELCOME;
6534 if (!sc->cenc.default_encrypted_sample) {
6535 sc->cenc.default_encrypted_sample = av_encryption_info_alloc(0, 16, 16);
6536 if (!sc->cenc.default_encrypted_sample) {
6537 return AVERROR(ENOMEM);
6542 return AVERROR_INVALIDDATA;
6544 version = avio_r8(pb); /* version */
6545 avio_rb24(pb); /* flags */
6547 avio_r8(pb); /* reserved */
6548 pattern = avio_r8(pb);
6551 sc->cenc.default_encrypted_sample->crypt_byte_block = pattern >> 4;
6552 sc->cenc.default_encrypted_sample->skip_byte_block = pattern & 0xf;
6555 is_protected = avio_r8(pb);
6556 if (is_protected && !sc->cenc.encryption_index) {
6557 // The whole stream should be by-default encrypted.
6558 sc->cenc.encryption_index = av_mallocz(sizeof(MOVEncryptionIndex));
6559 if (!sc->cenc.encryption_index)
6560 return AVERROR(ENOMEM);
6562 sc->cenc.per_sample_iv_size = avio_r8(pb);
6563 if (sc->cenc.per_sample_iv_size != 0 && sc->cenc.per_sample_iv_size != 8 &&
6564 sc->cenc.per_sample_iv_size != 16) {
6565 av_log(c->fc, AV_LOG_ERROR, "invalid per-sample IV size value\n");
6566 return AVERROR_INVALIDDATA;
6568 if (avio_read(pb, sc->cenc.default_encrypted_sample->key_id, 16) != 16) {
6569 av_log(c->fc, AV_LOG_ERROR, "failed to read the default key ID\n");
6570 return AVERROR_INVALIDDATA;
6573 if (is_protected && !sc->cenc.per_sample_iv_size) {
6574 iv_size = avio_r8(pb);
6575 if (iv_size != 8 && iv_size != 16) {
6576 av_log(c->fc, AV_LOG_ERROR, "invalid default_constant_IV_size in tenc atom\n");
6577 return AVERROR_INVALIDDATA;
6580 if (avio_read(pb, sc->cenc.default_encrypted_sample->iv, iv_size) != iv_size) {
6581 av_log(c->fc, AV_LOG_ERROR, "failed to read the default IV\n");
6582 return AVERROR_INVALIDDATA;
6589 static int mov_read_dfla(MOVContext *c, AVIOContext *pb, MOVAtom atom)
6592 int last, type, size, ret;
6595 if (c->fc->nb_streams < 1)
6597 st = c->fc->streams[c->fc->nb_streams-1];
6599 if ((uint64_t)atom.size > (1<<30) || atom.size < 42)
6600 return AVERROR_INVALIDDATA;
6602 /* Check FlacSpecificBox version. */
6603 if (avio_r8(pb) != 0)
6604 return AVERROR_INVALIDDATA;
6606 avio_rb24(pb); /* Flags */
6608 avio_read(pb, buf, sizeof(buf));
6609 flac_parse_block_header(buf, &last, &type, &size);
6611 if (type != FLAC_METADATA_TYPE_STREAMINFO || size != FLAC_STREAMINFO_SIZE) {
6612 av_log(c->fc, AV_LOG_ERROR, "STREAMINFO must be first FLACMetadataBlock\n");
6613 return AVERROR_INVALIDDATA;
6616 ret = ff_get_extradata(c->fc, st->codecpar, pb, size);
6621 av_log(c->fc, AV_LOG_WARNING, "non-STREAMINFO FLACMetadataBlock(s) ignored\n");
6626 static int cenc_decrypt(MOVContext *c, MOVStreamContext *sc, AVEncryptionInfo *sample, uint8_t *input, int size)
6630 if (sample->scheme != MKBETAG('c','e','n','c') || sample->crypt_byte_block != 0 || sample->skip_byte_block != 0) {
6631 av_log(c->fc, AV_LOG_ERROR, "Only the 'cenc' encryption scheme is supported\n");
6632 return AVERROR_PATCHWELCOME;
6635 if (!sc->cenc.aes_ctr) {
6636 /* initialize the cipher */
6637 sc->cenc.aes_ctr = av_aes_ctr_alloc();
6638 if (!sc->cenc.aes_ctr) {
6639 return AVERROR(ENOMEM);
6642 ret = av_aes_ctr_init(sc->cenc.aes_ctr, c->decryption_key);
6648 av_aes_ctr_set_full_iv(sc->cenc.aes_ctr, sample->iv);
6650 if (!sample->subsample_count) {
6651 /* decrypt the whole packet */
6652 av_aes_ctr_crypt(sc->cenc.aes_ctr, input, input, size);
6656 for (i = 0; i < sample->subsample_count; i++) {
6657 if (sample->subsamples[i].bytes_of_clear_data + sample->subsamples[i].bytes_of_protected_data > size) {
6658 av_log(c->fc, AV_LOG_ERROR, "subsample size exceeds the packet size left\n");
6659 return AVERROR_INVALIDDATA;
6662 /* skip the clear bytes */
6663 input += sample->subsamples[i].bytes_of_clear_data;
6664 size -= sample->subsamples[i].bytes_of_clear_data;
6666 /* decrypt the encrypted bytes */
6667 av_aes_ctr_crypt(sc->cenc.aes_ctr, input, input, sample->subsamples[i].bytes_of_protected_data);
6668 input += sample->subsamples[i].bytes_of_protected_data;
6669 size -= sample->subsamples[i].bytes_of_protected_data;
6673 av_log(c->fc, AV_LOG_ERROR, "leftover packet bytes after subsample processing\n");
6674 return AVERROR_INVALIDDATA;
6680 static int cenc_filter(MOVContext *mov, AVStream* st, MOVStreamContext *sc, AVPacket *pkt, int current_index)
6682 MOVFragmentStreamInfo *frag_stream_info;
6683 MOVEncryptionIndex *encryption_index;
6684 AVEncryptionInfo *encrypted_sample;
6685 int encrypted_index, ret;
6687 frag_stream_info = get_frag_stream_info(&mov->frag_index, mov->frag_index.current, st->id);
6688 encrypted_index = current_index;
6689 encryption_index = NULL;
6690 if (frag_stream_info) {
6691 // Note this only supports encryption info in the first sample descriptor.
6692 if (mov->fragment.stsd_id == 1) {
6693 if (frag_stream_info->encryption_index) {
6694 encrypted_index = current_index - frag_stream_info->index_entry;
6695 encryption_index = frag_stream_info->encryption_index;
6697 encryption_index = sc->cenc.encryption_index;
6701 encryption_index = sc->cenc.encryption_index;
6704 if (encryption_index) {
6705 if (encryption_index->auxiliary_info_sample_count &&
6706 !encryption_index->nb_encrypted_samples) {
6707 av_log(mov->fc, AV_LOG_ERROR, "saiz atom found without saio\n");
6708 return AVERROR_INVALIDDATA;
6710 if (encryption_index->auxiliary_offsets_count &&
6711 !encryption_index->nb_encrypted_samples) {
6712 av_log(mov->fc, AV_LOG_ERROR, "saio atom found without saiz\n");
6713 return AVERROR_INVALIDDATA;
6716 if (!encryption_index->nb_encrypted_samples) {
6717 // Full-sample encryption with default settings.
6718 encrypted_sample = sc->cenc.default_encrypted_sample;
6719 } else if (encrypted_index >= 0 && encrypted_index < encryption_index->nb_encrypted_samples) {
6720 // Per-sample setting override.
6721 encrypted_sample = encryption_index->encrypted_samples[encrypted_index];
6723 av_log(mov->fc, AV_LOG_ERROR, "Incorrect number of samples in encryption info\n");
6724 return AVERROR_INVALIDDATA;
6727 if (mov->decryption_key) {
6728 return cenc_decrypt(mov, sc, encrypted_sample, pkt->data, pkt->size);
6731 uint8_t *side_data = av_encryption_info_add_side_data(encrypted_sample, &size);
6733 return AVERROR(ENOMEM);
6734 ret = av_packet_add_side_data(pkt, AV_PKT_DATA_ENCRYPTION_INFO, side_data, size);
6744 static int mov_read_dops(MOVContext *c, AVIOContext *pb, MOVAtom atom)
6746 const int OPUS_SEEK_PREROLL_MS = 80;
6752 if (c->fc->nb_streams < 1)
6754 st = c->fc->streams[c->fc->nb_streams-1];
6756 if ((uint64_t)atom.size > (1<<30) || atom.size < 11)
6757 return AVERROR_INVALIDDATA;
6759 /* Check OpusSpecificBox version. */
6760 if (avio_r8(pb) != 0) {
6761 av_log(c->fc, AV_LOG_ERROR, "unsupported OpusSpecificBox version\n");
6762 return AVERROR_INVALIDDATA;
6765 /* OpusSpecificBox size plus magic for Ogg OpusHead header. */
6766 size = atom.size + 8;
6768 if ((ret = ff_alloc_extradata(st->codecpar, size)) < 0)
6771 AV_WL32(st->codecpar->extradata, MKTAG('O','p','u','s'));
6772 AV_WL32(st->codecpar->extradata + 4, MKTAG('H','e','a','d'));
6773 AV_WB8(st->codecpar->extradata + 8, 1); /* OpusHead version */
6774 avio_read(pb, st->codecpar->extradata + 9, size - 9);
6776 /* OpusSpecificBox is stored in big-endian, but OpusHead is
6777 little-endian; aside from the preceeding magic and version they're
6778 otherwise currently identical. Data after output gain at offset 16
6779 doesn't need to be bytewapped. */
6780 pre_skip = AV_RB16(st->codecpar->extradata + 10);
6781 AV_WL16(st->codecpar->extradata + 10, pre_skip);
6782 AV_WL32(st->codecpar->extradata + 12, AV_RB32(st->codecpar->extradata + 12));
6783 AV_WL16(st->codecpar->extradata + 16, AV_RB16(st->codecpar->extradata + 16));
6785 st->codecpar->initial_padding = pre_skip;
6786 st->codecpar->seek_preroll = av_rescale_q(OPUS_SEEK_PREROLL_MS,
6787 (AVRational){1, 1000},
6788 (AVRational){1, 48000});
6793 static int mov_read_dmlp(MOVContext *c, AVIOContext *pb, MOVAtom atom)
6796 unsigned format_info;
6797 int channel_assignment, channel_assignment1, channel_assignment2;
6800 if (c->fc->nb_streams < 1)
6802 st = c->fc->streams[c->fc->nb_streams-1];
6805 return AVERROR_INVALIDDATA;
6807 format_info = avio_rb32(pb);
6809 ratebits = (format_info >> 28) & 0xF;
6810 channel_assignment1 = (format_info >> 15) & 0x1F;
6811 channel_assignment2 = format_info & 0x1FFF;
6812 if (channel_assignment2)
6813 channel_assignment = channel_assignment2;
6815 channel_assignment = channel_assignment1;
6817 st->codecpar->frame_size = 40 << (ratebits & 0x7);
6818 st->codecpar->sample_rate = mlp_samplerate(ratebits);
6819 st->codecpar->channels = truehd_channels(channel_assignment);
6820 st->codecpar->channel_layout = truehd_layout(channel_assignment);
6825 static int mov_read_dvcc_dvvc(MOVContext *c, AVIOContext *pb, MOVAtom atom)
6829 AVDOVIDecoderConfigurationRecord *dovi;
6833 if (c->fc->nb_streams < 1)
6835 st = c->fc->streams[c->fc->nb_streams-1];
6837 if ((uint64_t)atom.size > (1<<30) || atom.size < 4)
6838 return AVERROR_INVALIDDATA;
6840 dovi = av_dovi_alloc(&dovi_size);
6842 return AVERROR(ENOMEM);
6844 dovi->dv_version_major = avio_r8(pb);
6845 dovi->dv_version_minor = avio_r8(pb);
6847 buf = avio_rb16(pb);
6848 dovi->dv_profile = (buf >> 9) & 0x7f; // 7 bits
6849 dovi->dv_level = (buf >> 3) & 0x3f; // 6 bits
6850 dovi->rpu_present_flag = (buf >> 2) & 0x01; // 1 bit
6851 dovi->el_present_flag = (buf >> 1) & 0x01; // 1 bit
6852 dovi->bl_present_flag = buf & 0x01; // 1 bit
6853 if (atom.size >= 24) { // 4 + 4 + 4 * 4
6855 dovi->dv_bl_signal_compatibility_id = (buf >> 4) & 0x0f; // 4 bits
6857 // 0 stands for None
6858 // Dolby Vision V1.2.93 profiles and levels
6859 dovi->dv_bl_signal_compatibility_id = 0;
6862 ret = av_stream_add_side_data(st, AV_PKT_DATA_DOVI_CONF,
6863 (uint8_t *)dovi, dovi_size);
6869 av_log(c, AV_LOG_TRACE, "DOVI in dvcC/dvvC box, version: %d.%d, profile: %d, level: %d, "
6870 "rpu flag: %d, el flag: %d, bl flag: %d, compatibility id: %d\n",
6871 dovi->dv_version_major, dovi->dv_version_minor,
6872 dovi->dv_profile, dovi->dv_level,
6873 dovi->rpu_present_flag,
6874 dovi->el_present_flag,
6875 dovi->bl_present_flag,
6876 dovi->dv_bl_signal_compatibility_id
6882 static const MOVParseTableEntry mov_default_parse_table[] = {
6883 { MKTAG('A','C','L','R'), mov_read_aclr },
6884 { MKTAG('A','P','R','G'), mov_read_avid },
6885 { MKTAG('A','A','L','P'), mov_read_avid },
6886 { MKTAG('A','R','E','S'), mov_read_ares },
6887 { MKTAG('a','v','s','s'), mov_read_avss },
6888 { MKTAG('a','v','1','C'), mov_read_av1c },
6889 { MKTAG('c','h','p','l'), mov_read_chpl },
6890 { MKTAG('c','o','6','4'), mov_read_stco },
6891 { MKTAG('c','o','l','r'), mov_read_colr },
6892 { MKTAG('c','t','t','s'), mov_read_ctts }, /* composition time to sample */
6893 { MKTAG('d','i','n','f'), mov_read_default },
6894 { MKTAG('D','p','x','E'), mov_read_dpxe },
6895 { MKTAG('d','r','e','f'), mov_read_dref },
6896 { MKTAG('e','d','t','s'), mov_read_default },
6897 { MKTAG('e','l','s','t'), mov_read_elst },
6898 { MKTAG('e','n','d','a'), mov_read_enda },
6899 { MKTAG('f','i','e','l'), mov_read_fiel },
6900 { MKTAG('a','d','r','m'), mov_read_adrm },
6901 { MKTAG('f','t','y','p'), mov_read_ftyp },
6902 { MKTAG('g','l','b','l'), mov_read_glbl },
6903 { MKTAG('h','d','l','r'), mov_read_hdlr },
6904 { MKTAG('i','l','s','t'), mov_read_ilst },
6905 { MKTAG('j','p','2','h'), mov_read_jp2h },
6906 { MKTAG('m','d','a','t'), mov_read_mdat },
6907 { MKTAG('m','d','h','d'), mov_read_mdhd },
6908 { MKTAG('m','d','i','a'), mov_read_default },
6909 { MKTAG('m','e','t','a'), mov_read_meta },
6910 { MKTAG('m','i','n','f'), mov_read_default },
6911 { MKTAG('m','o','o','f'), mov_read_moof },
6912 { MKTAG('m','o','o','v'), mov_read_moov },
6913 { MKTAG('m','v','e','x'), mov_read_default },
6914 { MKTAG('m','v','h','d'), mov_read_mvhd },
6915 { MKTAG('S','M','I',' '), mov_read_svq3 },
6916 { MKTAG('a','l','a','c'), mov_read_alac }, /* alac specific atom */
6917 { MKTAG('a','v','c','C'), mov_read_glbl },
6918 { MKTAG('p','a','s','p'), mov_read_pasp },
6919 { MKTAG('s','i','d','x'), mov_read_sidx },
6920 { MKTAG('s','t','b','l'), mov_read_default },
6921 { MKTAG('s','t','c','o'), mov_read_stco },
6922 { MKTAG('s','t','p','s'), mov_read_stps },
6923 { MKTAG('s','t','r','f'), mov_read_strf },
6924 { MKTAG('s','t','s','c'), mov_read_stsc },
6925 { MKTAG('s','t','s','d'), mov_read_stsd }, /* sample description */
6926 { MKTAG('s','t','s','s'), mov_read_stss }, /* sync sample */
6927 { MKTAG('s','t','s','z'), mov_read_stsz }, /* sample size */
6928 { MKTAG('s','t','t','s'), mov_read_stts },
6929 { MKTAG('s','t','z','2'), mov_read_stsz }, /* compact sample size */
6930 { MKTAG('s','d','t','p'), mov_read_sdtp }, /* independent and disposable samples */
6931 { MKTAG('t','k','h','d'), mov_read_tkhd }, /* track header */
6932 { MKTAG('t','f','d','t'), mov_read_tfdt },
6933 { MKTAG('t','f','h','d'), mov_read_tfhd }, /* track fragment header */
6934 { MKTAG('t','r','a','k'), mov_read_trak },
6935 { MKTAG('t','r','a','f'), mov_read_default },
6936 { MKTAG('t','r','e','f'), mov_read_default },
6937 { MKTAG('t','m','c','d'), mov_read_tmcd },
6938 { MKTAG('c','h','a','p'), mov_read_chap },
6939 { MKTAG('t','r','e','x'), mov_read_trex },
6940 { MKTAG('t','r','u','n'), mov_read_trun },
6941 { MKTAG('u','d','t','a'), mov_read_default },
6942 { MKTAG('w','a','v','e'), mov_read_wave },
6943 { MKTAG('e','s','d','s'), mov_read_esds },
6944 { MKTAG('d','a','c','3'), mov_read_dac3 }, /* AC-3 info */
6945 { MKTAG('d','e','c','3'), mov_read_dec3 }, /* EAC-3 info */
6946 { MKTAG('d','d','t','s'), mov_read_ddts }, /* DTS audio descriptor */
6947 { MKTAG('w','i','d','e'), mov_read_wide }, /* place holder */
6948 { MKTAG('w','f','e','x'), mov_read_wfex },
6949 { MKTAG('c','m','o','v'), mov_read_cmov },
6950 { MKTAG('c','h','a','n'), mov_read_chan }, /* channel layout */
6951 { MKTAG('d','v','c','1'), mov_read_dvc1 },
6952 { MKTAG('s','b','g','p'), mov_read_sbgp },
6953 { MKTAG('h','v','c','C'), mov_read_glbl },
6954 { MKTAG('u','u','i','d'), mov_read_uuid },
6955 { MKTAG('C','i','n', 0x8e), mov_read_targa_y216 },
6956 { MKTAG('f','r','e','e'), mov_read_free },
6957 { MKTAG('-','-','-','-'), mov_read_custom },
6958 { MKTAG('s','i','n','f'), mov_read_default },
6959 { MKTAG('f','r','m','a'), mov_read_frma },
6960 { MKTAG('s','e','n','c'), mov_read_senc },
6961 { MKTAG('s','a','i','z'), mov_read_saiz },
6962 { MKTAG('s','a','i','o'), mov_read_saio },
6963 { MKTAG('p','s','s','h'), mov_read_pssh },
6964 { MKTAG('s','c','h','m'), mov_read_schm },
6965 { MKTAG('s','c','h','i'), mov_read_default },
6966 { MKTAG('t','e','n','c'), mov_read_tenc },
6967 { MKTAG('d','f','L','a'), mov_read_dfla },
6968 { MKTAG('s','t','3','d'), mov_read_st3d }, /* stereoscopic 3D video box */
6969 { MKTAG('s','v','3','d'), mov_read_sv3d }, /* spherical video box */
6970 { MKTAG('d','O','p','s'), mov_read_dops },
6971 { MKTAG('d','m','l','p'), mov_read_dmlp },
6972 { MKTAG('S','m','D','m'), mov_read_smdm },
6973 { MKTAG('C','o','L','L'), mov_read_coll },
6974 { MKTAG('v','p','c','C'), mov_read_vpcc },
6975 { MKTAG('m','d','c','v'), mov_read_mdcv },
6976 { MKTAG('c','l','l','i'), mov_read_clli },
6977 { MKTAG('d','v','c','C'), mov_read_dvcc_dvvc },
6978 { MKTAG('d','v','v','C'), mov_read_dvcc_dvvc },
6982 static int mov_read_default(MOVContext *c, AVIOContext *pb, MOVAtom atom)
6984 int64_t total_size = 0;
6988 if (c->atom_depth > 10) {
6989 av_log(c->fc, AV_LOG_ERROR, "Atoms too deeply nested\n");
6990 return AVERROR_INVALIDDATA;
6995 atom.size = INT64_MAX;
6996 while (total_size <= atom.size - 8 && !avio_feof(pb)) {
6997 int (*parse)(MOVContext*, AVIOContext*, MOVAtom) = NULL;
7000 if (atom.size >= 8) {
7001 a.size = avio_rb32(pb);
7002 a.type = avio_rl32(pb);
7003 if (((a.type == MKTAG('f','r','e','e') && c->moov_retry) ||
7004 a.type == MKTAG('h','o','o','v')) &&
7006 c->fc->strict_std_compliance < FF_COMPLIANCE_STRICT) {
7009 type = avio_rl32(pb);
7012 avio_seek(pb, -8, SEEK_CUR);
7013 if (type == MKTAG('m','v','h','d') ||
7014 type == MKTAG('c','m','o','v')) {
7015 av_log(c->fc, AV_LOG_ERROR, "Detected moov in a free or hoov atom.\n");
7016 a.type = MKTAG('m','o','o','v');
7019 if (atom.type != MKTAG('r','o','o','t') &&
7020 atom.type != MKTAG('m','o','o','v')) {
7021 if (a.type == MKTAG('t','r','a','k') ||
7022 a.type == MKTAG('m','d','a','t')) {
7023 av_log(c->fc, AV_LOG_ERROR, "Broken file, trak/mdat not at top-level\n");
7030 if (a.size == 1 && total_size + 8 <= atom.size) { /* 64 bit extended size */
7031 a.size = avio_rb64(pb) - 8;
7035 av_log(c->fc, AV_LOG_TRACE, "type:'%s' parent:'%s' sz: %"PRId64" %"PRId64" %"PRId64"\n",
7036 av_fourcc2str(a.type), av_fourcc2str(atom.type), a.size, total_size, atom.size);
7038 a.size = atom.size - total_size + 8;
7043 a.size = FFMIN(a.size, atom.size - total_size);
7045 for (i = 0; mov_default_parse_table[i].type; i++)
7046 if (mov_default_parse_table[i].type == a.type) {
7047 parse = mov_default_parse_table[i].parse;
7051 // container is user data
7052 if (!parse && (atom.type == MKTAG('u','d','t','a') ||
7053 atom.type == MKTAG('i','l','s','t')))
7054 parse = mov_read_udta_string;
7056 // Supports parsing the QuickTime Metadata Keys.
7057 // https://developer.apple.com/library/mac/documentation/QuickTime/QTFF/Metadata/Metadata.html
7058 if (!parse && c->found_hdlr_mdta &&
7059 atom.type == MKTAG('m','e','t','a') &&
7060 a.type == MKTAG('k','e','y','s') &&
7061 c->meta_keys_count == 0) {
7062 parse = mov_read_keys;
7065 if (!parse) { /* skip leaf atoms data */
7066 avio_skip(pb, a.size);
7068 int64_t start_pos = avio_tell(pb);
7070 int err = parse(c, pb, a);
7075 if (c->found_moov && c->found_mdat && a.size <= INT64_MAX - start_pos &&
7076 ((!(pb->seekable & AVIO_SEEKABLE_NORMAL) || c->fc->flags & AVFMT_FLAG_IGNIDX || c->frag_index.complete) ||
7077 start_pos + a.size == avio_size(pb))) {
7078 if (!(pb->seekable & AVIO_SEEKABLE_NORMAL) || c->fc->flags & AVFMT_FLAG_IGNIDX || c->frag_index.complete)
7079 c->next_root_atom = start_pos + a.size;
7083 left = a.size - avio_tell(pb) + start_pos;
7084 if (left > 0) /* skip garbage at atom end */
7085 avio_skip(pb, left);
7086 else if (left < 0) {
7087 av_log(c->fc, AV_LOG_WARNING,
7088 "overread end of atom '%s' by %"PRId64" bytes\n",
7089 av_fourcc2str(a.type), -left);
7090 avio_seek(pb, left, SEEK_CUR);
7094 total_size += a.size;
7097 if (total_size < atom.size && atom.size < 0x7ffff)
7098 avio_skip(pb, atom.size - total_size);
7104 static int mov_probe(const AVProbeData *p)
7109 int moov_offset = -1;
7111 /* check file header */
7116 /* ignore invalid offset */
7117 if ((offset + 8ULL) > (unsigned int)p->buf_size)
7119 size = AV_RB32(p->buf + offset);
7120 if (size == 1 && offset + 16 <= (unsigned int)p->buf_size) {
7121 size = AV_RB64(p->buf+offset + 8);
7123 } else if (size == 0) {
7124 size = p->buf_size - offset;
7126 if (size < minsize) {
7130 tag = AV_RL32(p->buf + offset + 4);
7132 /* check for obvious tags */
7133 case MKTAG('m','o','o','v'):
7134 moov_offset = offset + 4;
7135 case MKTAG('m','d','a','t'):
7136 case MKTAG('p','n','o','t'): /* detect movs with preview pics like ew.mov and april.mov */
7137 case MKTAG('u','d','t','a'): /* Packet Video PVAuthor adds this and a lot of more junk */
7138 case MKTAG('f','t','y','p'):
7139 if (tag == MKTAG('f','t','y','p') &&
7140 ( AV_RL32(p->buf + offset + 8) == MKTAG('j','p','2',' ')
7141 || AV_RL32(p->buf + offset + 8) == MKTAG('j','p','x',' ')
7143 score = FFMAX(score, 5);
7145 score = AVPROBE_SCORE_MAX;
7148 /* those are more common words, so rate then a bit less */
7149 case MKTAG('e','d','i','w'): /* xdcam files have reverted first tags */
7150 case MKTAG('w','i','d','e'):
7151 case MKTAG('f','r','e','e'):
7152 case MKTAG('j','u','n','k'):
7153 case MKTAG('p','i','c','t'):
7154 score = FFMAX(score, AVPROBE_SCORE_MAX - 5);
7156 case MKTAG(0x82,0x82,0x7f,0x7d):
7157 case MKTAG('s','k','i','p'):
7158 case MKTAG('u','u','i','d'):
7159 case MKTAG('p','r','f','l'):
7160 /* if we only find those cause probedata is too small at least rate them */
7161 score = FFMAX(score, AVPROBE_SCORE_EXTENSION);
7164 if (size > INT64_MAX - offset)
7168 if (score > AVPROBE_SCORE_MAX - 50 && moov_offset != -1) {
7169 /* moov atom in the header - we should make sure that this is not a
7170 * MOV-packed MPEG-PS */
7171 offset = moov_offset;
7173 while (offset < (p->buf_size - 16)) { /* Sufficient space */
7174 /* We found an actual hdlr atom */
7175 if (AV_RL32(p->buf + offset ) == MKTAG('h','d','l','r') &&
7176 AV_RL32(p->buf + offset + 8) == MKTAG('m','h','l','r') &&
7177 AV_RL32(p->buf + offset + 12) == MKTAG('M','P','E','G')) {
7178 av_log(NULL, AV_LOG_WARNING, "Found media data tag MPEG indicating this is a MOV-packed MPEG-PS.\n");
7179 /* We found a media handler reference atom describing an
7180 * MPEG-PS-in-MOV, return a
7181 * low score to force expanding the probe window until
7182 * mpegps_probe finds what it needs */
7194 // must be done after parsing all trak because there's no order requirement
7195 static void mov_read_chapters(AVFormatContext *s)
7197 MOVContext *mov = s->priv_data;
7199 MOVStreamContext *sc;
7204 for (j = 0; j < mov->nb_chapter_tracks; j++) {
7205 chapter_track = mov->chapter_tracks[j];
7207 for (i = 0; i < s->nb_streams; i++)
7208 if (s->streams[i]->id == chapter_track) {
7213 av_log(s, AV_LOG_ERROR, "Referenced QT chapter track not found\n");
7218 cur_pos = avio_tell(sc->pb);
7220 if (st->codecpar->codec_type == AVMEDIA_TYPE_VIDEO) {
7221 st->disposition |= AV_DISPOSITION_ATTACHED_PIC | AV_DISPOSITION_TIMED_THUMBNAILS;
7222 if (st->internal->nb_index_entries) {
7223 // Retrieve the first frame, if possible
7224 AVIndexEntry *sample = &st->internal->index_entries[0];
7225 if (avio_seek(sc->pb, sample->pos, SEEK_SET) != sample->pos) {
7226 av_log(s, AV_LOG_ERROR, "Failed to retrieve first frame\n");
7230 if (ff_add_attached_pic(s, st, sc->pb, NULL, sample->size) < 0)
7234 st->codecpar->codec_type = AVMEDIA_TYPE_DATA;
7235 st->codecpar->codec_id = AV_CODEC_ID_BIN_DATA;
7236 st->discard = AVDISCARD_ALL;
7237 for (i = 0; i < st->internal->nb_index_entries; i++) {
7238 AVIndexEntry *sample = &st->internal->index_entries[i];
7239 int64_t end = i+1 < st->internal->nb_index_entries ? st->internal->index_entries[i+1].timestamp : st->duration;
7244 if (end < sample->timestamp) {
7245 av_log(s, AV_LOG_WARNING, "ignoring stream duration which is shorter than chapters\n");
7246 end = AV_NOPTS_VALUE;
7249 if (avio_seek(sc->pb, sample->pos, SEEK_SET) != sample->pos) {
7250 av_log(s, AV_LOG_ERROR, "Chapter %d not found in file\n", i);
7254 // the first two bytes are the length of the title
7255 len = avio_rb16(sc->pb);
7256 if (len > sample->size-2)
7258 title_len = 2*len + 1;
7259 if (!(title = av_mallocz(title_len)))
7262 // The samples could theoretically be in any encoding if there's an encd
7263 // atom following, but in practice are only utf-8 or utf-16, distinguished
7264 // instead by the presence of a BOM
7268 ch = avio_rb16(sc->pb);
7270 avio_get_str16be(sc->pb, len, title, title_len);
7271 else if (ch == 0xfffe)
7272 avio_get_str16le(sc->pb, len, title, title_len);
7275 if (len == 1 || len == 2)
7278 avio_get_str(sc->pb, INT_MAX, title + 2, len - 1);
7282 avpriv_new_chapter(s, i, st->time_base, sample->timestamp, end, title);
7287 avio_seek(sc->pb, cur_pos, SEEK_SET);
7291 static int parse_timecode_in_framenum_format(AVFormatContext *s, AVStream *st,
7292 uint32_t value, int flags)
7295 char buf[AV_TIMECODE_STR_SIZE];
7296 AVRational rate = st->avg_frame_rate;
7297 int ret = av_timecode_init(&tc, rate, flags, 0, s);
7300 av_dict_set(&st->metadata, "timecode",
7301 av_timecode_make_string(&tc, buf, value), 0);
7305 static int mov_read_rtmd_track(AVFormatContext *s, AVStream *st)
7307 MOVStreamContext *sc = st->priv_data;
7308 char buf[AV_TIMECODE_STR_SIZE];
7309 int64_t cur_pos = avio_tell(sc->pb);
7310 int hh, mm, ss, ff, drop;
7312 if (!st->internal->nb_index_entries)
7315 avio_seek(sc->pb, st->internal->index_entries->pos, SEEK_SET);
7316 avio_skip(s->pb, 13);
7317 hh = avio_r8(s->pb);
7318 mm = avio_r8(s->pb);
7319 ss = avio_r8(s->pb);
7320 drop = avio_r8(s->pb);
7321 ff = avio_r8(s->pb);
7322 snprintf(buf, AV_TIMECODE_STR_SIZE, "%02d:%02d:%02d%c%02d",
7323 hh, mm, ss, drop ? ';' : ':', ff);
7324 av_dict_set(&st->metadata, "timecode", buf, 0);
7326 avio_seek(sc->pb, cur_pos, SEEK_SET);
7330 static int mov_read_timecode_track(AVFormatContext *s, AVStream *st)
7332 MOVStreamContext *sc = st->priv_data;
7334 int64_t cur_pos = avio_tell(sc->pb);
7337 if (!st->internal->nb_index_entries)
7340 avio_seek(sc->pb, st->internal->index_entries->pos, SEEK_SET);
7341 value = avio_rb32(s->pb);
7343 if (sc->tmcd_flags & 0x0001) flags |= AV_TIMECODE_FLAG_DROPFRAME;
7344 if (sc->tmcd_flags & 0x0002) flags |= AV_TIMECODE_FLAG_24HOURSMAX;
7345 if (sc->tmcd_flags & 0x0004) flags |= AV_TIMECODE_FLAG_ALLOWNEGATIVE;
7347 /* Assume Counter flag is set to 1 in tmcd track (even though it is likely
7348 * not the case) and thus assume "frame number format" instead of QT one.
7349 * No sample with tmcd track can be found with a QT timecode at the moment,
7350 * despite what the tmcd track "suggests" (Counter flag set to 0 means QT
7352 parse_timecode_in_framenum_format(s, st, value, flags);
7354 avio_seek(sc->pb, cur_pos, SEEK_SET);
7358 static void mov_free_encryption_index(MOVEncryptionIndex **index) {
7360 if (!index || !*index) return;
7361 for (i = 0; i < (*index)->nb_encrypted_samples; i++) {
7362 av_encryption_info_free((*index)->encrypted_samples[i]);
7364 av_freep(&(*index)->encrypted_samples);
7365 av_freep(&(*index)->auxiliary_info_sizes);
7366 av_freep(&(*index)->auxiliary_offsets);
7370 static int mov_read_close(AVFormatContext *s)
7372 MOVContext *mov = s->priv_data;
7375 for (i = 0; i < s->nb_streams; i++) {
7376 AVStream *st = s->streams[i];
7377 MOVStreamContext *sc = st->priv_data;
7382 av_freep(&sc->ctts_data);
7383 for (j = 0; j < sc->drefs_count; j++) {
7384 av_freep(&sc->drefs[j].path);
7385 av_freep(&sc->drefs[j].dir);
7387 av_freep(&sc->drefs);
7389 sc->drefs_count = 0;
7391 if (!sc->pb_is_copied)
7392 ff_format_io_close(s, &sc->pb);
7395 av_freep(&sc->chunk_offsets);
7396 av_freep(&sc->stsc_data);
7397 av_freep(&sc->sample_sizes);
7398 av_freep(&sc->keyframes);
7399 av_freep(&sc->stts_data);
7400 av_freep(&sc->sdtp_data);
7401 av_freep(&sc->stps_data);
7402 av_freep(&sc->elst_data);
7403 av_freep(&sc->rap_group);
7404 av_freep(&sc->display_matrix);
7405 av_freep(&sc->index_ranges);
7408 for (j = 0; j < sc->stsd_count; j++)
7409 av_free(sc->extradata[j]);
7410 av_freep(&sc->extradata);
7411 av_freep(&sc->extradata_size);
7413 mov_free_encryption_index(&sc->cenc.encryption_index);
7414 av_encryption_info_free(sc->cenc.default_encrypted_sample);
7415 av_aes_ctr_free(sc->cenc.aes_ctr);
7417 av_freep(&sc->stereo3d);
7418 av_freep(&sc->spherical);
7419 av_freep(&sc->mastering);
7420 av_freep(&sc->coll);
7423 av_freep(&mov->dv_demux);
7424 avformat_free_context(mov->dv_fctx);
7425 mov->dv_fctx = NULL;
7427 if (mov->meta_keys) {
7428 for (i = 1; i < mov->meta_keys_count; i++) {
7429 av_freep(&mov->meta_keys[i]);
7431 av_freep(&mov->meta_keys);
7434 av_freep(&mov->trex_data);
7435 av_freep(&mov->bitrates);
7437 for (i = 0; i < mov->frag_index.nb_items; i++) {
7438 MOVFragmentStreamInfo *frag = mov->frag_index.item[i].stream_info;
7439 for (j = 0; j < mov->frag_index.item[i].nb_stream_info; j++) {
7440 mov_free_encryption_index(&frag[j].encryption_index);
7442 av_freep(&mov->frag_index.item[i].stream_info);
7444 av_freep(&mov->frag_index.item);
7446 av_freep(&mov->aes_decrypt);
7447 av_freep(&mov->chapter_tracks);
7452 static int tmcd_is_referenced(AVFormatContext *s, int tmcd_id)
7456 for (i = 0; i < s->nb_streams; i++) {
7457 AVStream *st = s->streams[i];
7458 MOVStreamContext *sc = st->priv_data;
7460 if (st->codecpar->codec_type == AVMEDIA_TYPE_VIDEO &&
7461 sc->timecode_track == tmcd_id)
7467 /* look for a tmcd track not referenced by any video track, and export it globally */
7468 static void export_orphan_timecode(AVFormatContext *s)
7472 for (i = 0; i < s->nb_streams; i++) {
7473 AVStream *st = s->streams[i];
7475 if (st->codecpar->codec_tag == MKTAG('t','m','c','d') &&
7476 !tmcd_is_referenced(s, i + 1)) {
7477 AVDictionaryEntry *tcr = av_dict_get(st->metadata, "timecode", NULL, 0);
7479 av_dict_set(&s->metadata, "timecode", tcr->value, 0);
7486 static int read_tfra(MOVContext *mov, AVIOContext *f)
7488 int version, fieldlength, i, j;
7489 int64_t pos = avio_tell(f);
7490 uint32_t size = avio_rb32(f);
7491 unsigned track_id, item_count;
7493 if (avio_rb32(f) != MKBETAG('t', 'f', 'r', 'a')) {
7496 av_log(mov->fc, AV_LOG_VERBOSE, "found tfra\n");
7498 version = avio_r8(f);
7500 track_id = avio_rb32(f);
7501 fieldlength = avio_rb32(f);
7502 item_count = avio_rb32(f);
7503 for (i = 0; i < item_count; i++) {
7504 int64_t time, offset;
7506 MOVFragmentStreamInfo * frag_stream_info;
7509 return AVERROR_INVALIDDATA;
7513 time = avio_rb64(f);
7514 offset = avio_rb64(f);
7516 time = avio_rb32(f);
7517 offset = avio_rb32(f);
7520 // The first sample of each stream in a fragment is always a random
7521 // access sample. So it's entry in the tfra can be used as the
7522 // initial PTS of the fragment.
7523 index = update_frag_index(mov, offset);
7524 frag_stream_info = get_frag_stream_info(&mov->frag_index, index, track_id);
7525 if (frag_stream_info &&
7526 frag_stream_info->first_tfra_pts == AV_NOPTS_VALUE)
7527 frag_stream_info->first_tfra_pts = time;
7529 for (j = 0; j < ((fieldlength >> 4) & 3) + 1; j++)
7531 for (j = 0; j < ((fieldlength >> 2) & 3) + 1; j++)
7533 for (j = 0; j < ((fieldlength >> 0) & 3) + 1; j++)
7537 avio_seek(f, pos + size, SEEK_SET);
7541 static int mov_read_mfra(MOVContext *c, AVIOContext *f)
7543 int64_t stream_size = avio_size(f);
7544 int64_t original_pos = avio_tell(f);
7547 if ((seek_ret = avio_seek(f, stream_size - 4, SEEK_SET)) < 0) {
7551 c->mfra_size = avio_rb32(f);
7552 c->have_read_mfra_size = 1;
7553 if (!c->mfra_size || c->mfra_size > stream_size) {
7554 av_log(c->fc, AV_LOG_DEBUG, "doesn't look like mfra (unreasonable size)\n");
7557 if ((seek_ret = avio_seek(f, -((int64_t) c->mfra_size), SEEK_CUR)) < 0) {
7561 if (avio_rb32(f) != c->mfra_size) {
7562 av_log(c->fc, AV_LOG_DEBUG, "doesn't look like mfra (size mismatch)\n");
7565 if (avio_rb32(f) != MKBETAG('m', 'f', 'r', 'a')) {
7566 av_log(c->fc, AV_LOG_DEBUG, "doesn't look like mfra (tag mismatch)\n");
7569 av_log(c->fc, AV_LOG_VERBOSE, "stream has mfra\n");
7571 ret = read_tfra(c, f);
7576 c->frag_index.complete = 1;
7578 seek_ret = avio_seek(f, original_pos, SEEK_SET);
7580 av_log(c->fc, AV_LOG_ERROR,
7581 "failed to seek back after looking for mfra\n");
7587 static int mov_read_header(AVFormatContext *s)
7589 MOVContext *mov = s->priv_data;
7590 AVIOContext *pb = s->pb;
7592 MOVAtom atom = { AV_RL32("root") };
7595 if (mov->decryption_key_len != 0 && mov->decryption_key_len != AES_CTR_KEY_SIZE) {
7596 av_log(s, AV_LOG_ERROR, "Invalid decryption key len %d expected %d\n",
7597 mov->decryption_key_len, AES_CTR_KEY_SIZE);
7598 return AVERROR(EINVAL);
7602 mov->trak_index = -1;
7603 /* .mov and .mp4 aren't streamable anyway (only progressive download if moov is before mdat) */
7604 if (pb->seekable & AVIO_SEEKABLE_NORMAL)
7605 atom.size = avio_size(pb);
7607 atom.size = INT64_MAX;
7609 /* check MOV header */
7611 if (mov->moov_retry)
7612 avio_seek(pb, 0, SEEK_SET);
7613 if ((err = mov_read_default(mov, pb, atom)) < 0) {
7614 av_log(s, AV_LOG_ERROR, "error reading header\n");
7617 } while ((pb->seekable & AVIO_SEEKABLE_NORMAL) && !mov->found_moov && !mov->moov_retry++);
7618 if (!mov->found_moov) {
7619 av_log(s, AV_LOG_ERROR, "moov atom not found\n");
7620 err = AVERROR_INVALIDDATA;
7623 av_log(mov->fc, AV_LOG_TRACE, "on_parse_exit_offset=%"PRId64"\n", avio_tell(pb));
7625 if (pb->seekable & AVIO_SEEKABLE_NORMAL) {
7626 if (mov->nb_chapter_tracks > 0 && !mov->ignore_chapters)
7627 mov_read_chapters(s);
7628 for (i = 0; i < s->nb_streams; i++)
7629 if (s->streams[i]->codecpar->codec_tag == AV_RL32("tmcd")) {
7630 mov_read_timecode_track(s, s->streams[i]);
7631 } else if (s->streams[i]->codecpar->codec_tag == AV_RL32("rtmd")) {
7632 mov_read_rtmd_track(s, s->streams[i]);
7636 /* copy timecode metadata from tmcd tracks to the related video streams */
7637 for (i = 0; i < s->nb_streams; i++) {
7638 AVStream *st = s->streams[i];
7639 MOVStreamContext *sc = st->priv_data;
7640 if (sc->timecode_track > 0) {
7641 AVDictionaryEntry *tcr;
7642 int tmcd_st_id = -1;
7644 for (j = 0; j < s->nb_streams; j++)
7645 if (s->streams[j]->id == sc->timecode_track)
7648 if (tmcd_st_id < 0 || tmcd_st_id == i)
7650 tcr = av_dict_get(s->streams[tmcd_st_id]->metadata, "timecode", NULL, 0);
7652 av_dict_set(&st->metadata, "timecode", tcr->value, 0);
7655 export_orphan_timecode(s);
7657 for (i = 0; i < s->nb_streams; i++) {
7658 AVStream *st = s->streams[i];
7659 MOVStreamContext *sc = st->priv_data;
7660 fix_timescale(mov, sc);
7661 if (st->codecpar->codec_type == AVMEDIA_TYPE_AUDIO &&
7662 st->codecpar->codec_id == AV_CODEC_ID_AAC) {
7663 st->internal->skip_samples = sc->start_pad;
7665 if (st->codecpar->codec_type == AVMEDIA_TYPE_VIDEO && sc->nb_frames_for_fps > 0 && sc->duration_for_fps > 0)
7666 av_reduce(&st->avg_frame_rate.num, &st->avg_frame_rate.den,
7667 sc->time_scale*(int64_t)sc->nb_frames_for_fps, sc->duration_for_fps, INT_MAX);
7668 if (st->codecpar->codec_type == AVMEDIA_TYPE_SUBTITLE) {
7669 if (st->codecpar->width <= 0 || st->codecpar->height <= 0) {
7670 st->codecpar->width = sc->width;
7671 st->codecpar->height = sc->height;
7673 if (st->codecpar->codec_id == AV_CODEC_ID_DVD_SUBTITLE) {
7674 if ((err = mov_rewrite_dvd_sub_extradata(st)) < 0)
7678 if (mov->handbrake_version &&
7679 mov->handbrake_version <= 1000000*0 + 1000*10 + 2 && // 0.10.2
7680 st->codecpar->codec_id == AV_CODEC_ID_MP3) {
7681 av_log(s, AV_LOG_VERBOSE, "Forcing full parsing for mp3 stream\n");
7682 st->need_parsing = AVSTREAM_PARSE_FULL;
7686 if (mov->trex_data) {
7687 for (i = 0; i < s->nb_streams; i++) {
7688 AVStream *st = s->streams[i];
7689 MOVStreamContext *sc = st->priv_data;
7690 if (st->duration > 0) {
7691 if (sc->data_size > INT64_MAX / sc->time_scale / 8) {
7692 av_log(s, AV_LOG_ERROR, "Overflow during bit rate calculation %"PRId64" * 8 * %d\n",
7693 sc->data_size, sc->time_scale);
7694 err = AVERROR_INVALIDDATA;
7697 st->codecpar->bit_rate = sc->data_size * 8 * sc->time_scale / st->duration;
7702 if (mov->use_mfra_for > 0) {
7703 for (i = 0; i < s->nb_streams; i++) {
7704 AVStream *st = s->streams[i];
7705 MOVStreamContext *sc = st->priv_data;
7706 if (sc->duration_for_fps > 0) {
7707 if (sc->data_size > INT64_MAX / sc->time_scale / 8) {
7708 av_log(s, AV_LOG_ERROR, "Overflow during bit rate calculation %"PRId64" * 8 * %d\n",
7709 sc->data_size, sc->time_scale);
7710 err = AVERROR_INVALIDDATA;
7713 st->codecpar->bit_rate = sc->data_size * 8 * sc->time_scale /
7714 sc->duration_for_fps;
7719 for (i = 0; i < mov->bitrates_count && i < s->nb_streams; i++) {
7720 if (mov->bitrates[i]) {
7721 s->streams[i]->codecpar->bit_rate = mov->bitrates[i];
7725 ff_rfps_calculate(s);
7727 for (i = 0; i < s->nb_streams; i++) {
7728 AVStream *st = s->streams[i];
7729 MOVStreamContext *sc = st->priv_data;
7731 switch (st->codecpar->codec_type) {
7732 case AVMEDIA_TYPE_AUDIO:
7733 err = ff_replaygain_export(st, s->metadata);
7737 case AVMEDIA_TYPE_VIDEO:
7738 if (sc->display_matrix) {
7739 err = av_stream_add_side_data(st, AV_PKT_DATA_DISPLAYMATRIX, (uint8_t*)sc->display_matrix,
7740 sizeof(int32_t) * 9);
7744 sc->display_matrix = NULL;
7747 err = av_stream_add_side_data(st, AV_PKT_DATA_STEREO3D,
7748 (uint8_t *)sc->stereo3d,
7749 sizeof(*sc->stereo3d));
7753 sc->stereo3d = NULL;
7755 if (sc->spherical) {
7756 err = av_stream_add_side_data(st, AV_PKT_DATA_SPHERICAL,
7757 (uint8_t *)sc->spherical,
7758 sc->spherical_size);
7762 sc->spherical = NULL;
7764 if (sc->mastering) {
7765 err = av_stream_add_side_data(st, AV_PKT_DATA_MASTERING_DISPLAY_METADATA,
7766 (uint8_t *)sc->mastering,
7767 sizeof(*sc->mastering));
7771 sc->mastering = NULL;
7774 err = av_stream_add_side_data(st, AV_PKT_DATA_CONTENT_LIGHT_LEVEL,
7775 (uint8_t *)sc->coll,
7785 ff_configure_buffers_for_index(s, AV_TIME_BASE);
7787 for (i = 0; i < mov->frag_index.nb_items; i++)
7788 if (mov->frag_index.item[i].moof_offset <= mov->fragment.moof_offset)
7789 mov->frag_index.item[i].headers_read = 1;
7797 static AVIndexEntry *mov_find_next_sample(AVFormatContext *s, AVStream **st)
7799 AVIndexEntry *sample = NULL;
7800 int64_t best_dts = INT64_MAX;
7802 for (i = 0; i < s->nb_streams; i++) {
7803 AVStream *avst = s->streams[i];
7804 MOVStreamContext *msc = avst->priv_data;
7805 if (msc->pb && msc->current_sample < avst->internal->nb_index_entries) {
7806 AVIndexEntry *current_sample = &avst->internal->index_entries[msc->current_sample];
7807 int64_t dts = av_rescale(current_sample->timestamp, AV_TIME_BASE, msc->time_scale);
7808 av_log(s, AV_LOG_TRACE, "stream %d, sample %d, dts %"PRId64"\n", i, msc->current_sample, dts);
7809 if (!sample || (!(s->pb->seekable & AVIO_SEEKABLE_NORMAL) && current_sample->pos < sample->pos) ||
7810 ((s->pb->seekable & AVIO_SEEKABLE_NORMAL) &&
7811 ((msc->pb != s->pb && dts < best_dts) || (msc->pb == s->pb && dts != AV_NOPTS_VALUE &&
7812 ((FFABS(best_dts - dts) <= AV_TIME_BASE && current_sample->pos < sample->pos) ||
7813 (FFABS(best_dts - dts) > AV_TIME_BASE && dts < best_dts)))))) {
7814 sample = current_sample;
7823 static int should_retry(AVIOContext *pb, int error_code) {
7824 if (error_code == AVERROR_EOF || avio_feof(pb))
7830 static int mov_switch_root(AVFormatContext *s, int64_t target, int index)
7833 MOVContext *mov = s->priv_data;
7835 if (index >= 0 && index < mov->frag_index.nb_items)
7836 target = mov->frag_index.item[index].moof_offset;
7837 if (avio_seek(s->pb, target, SEEK_SET) != target) {
7838 av_log(mov->fc, AV_LOG_ERROR, "root atom offset 0x%"PRIx64": partial file\n", target);
7839 return AVERROR_INVALIDDATA;
7842 mov->next_root_atom = 0;
7843 if (index < 0 || index >= mov->frag_index.nb_items)
7844 index = search_frag_moof_offset(&mov->frag_index, target);
7845 if (index < mov->frag_index.nb_items &&
7846 mov->frag_index.item[index].moof_offset == target) {
7847 if (index + 1 < mov->frag_index.nb_items)
7848 mov->next_root_atom = mov->frag_index.item[index + 1].moof_offset;
7849 if (mov->frag_index.item[index].headers_read)
7851 mov->frag_index.item[index].headers_read = 1;
7854 mov->found_mdat = 0;
7856 ret = mov_read_default(mov, s->pb, (MOVAtom){ AV_RL32("root"), INT64_MAX });
7859 if (avio_feof(s->pb))
7861 av_log(s, AV_LOG_TRACE, "read fragments, offset 0x%"PRIx64"\n", avio_tell(s->pb));
7866 static int mov_change_extradata(MOVStreamContext *sc, AVPacket *pkt)
7868 uint8_t *side, *extradata;
7871 /* Save the current index. */
7872 sc->last_stsd_index = sc->stsc_data[sc->stsc_index].id - 1;
7874 /* Notify the decoder that extradata changed. */
7875 extradata_size = sc->extradata_size[sc->last_stsd_index];
7876 extradata = sc->extradata[sc->last_stsd_index];
7877 if (extradata_size > 0 && extradata) {
7878 side = av_packet_new_side_data(pkt,
7879 AV_PKT_DATA_NEW_EXTRADATA,
7882 return AVERROR(ENOMEM);
7883 memcpy(side, extradata, extradata_size);
7889 static int get_eia608_packet(AVIOContext *pb, AVPacket *pkt, int size)
7894 return AVERROR_INVALIDDATA;
7895 new_size = ((size - 8) / 2) * 3;
7896 ret = av_new_packet(pkt, new_size);
7901 for (int j = 0; j < new_size; j += 3) {
7902 pkt->data[j] = 0xFC;
7903 pkt->data[j+1] = avio_r8(pb);
7904 pkt->data[j+2] = avio_r8(pb);
7910 static int mov_read_packet(AVFormatContext *s, AVPacket *pkt)
7912 MOVContext *mov = s->priv_data;
7913 MOVStreamContext *sc;
7914 AVIndexEntry *sample;
7915 AVStream *st = NULL;
7916 int64_t current_index;
7920 sample = mov_find_next_sample(s, &st);
7921 if (!sample || (mov->next_root_atom && sample->pos > mov->next_root_atom)) {
7922 if (!mov->next_root_atom)
7924 if ((ret = mov_switch_root(s, mov->next_root_atom, -1)) < 0)
7929 /* must be done just before reading, to avoid infinite loop on sample */
7930 current_index = sc->current_index;
7931 mov_current_sample_inc(sc);
7933 if (mov->next_root_atom) {
7934 sample->pos = FFMIN(sample->pos, mov->next_root_atom);
7935 sample->size = FFMIN(sample->size, (mov->next_root_atom - sample->pos));
7938 if (st->discard != AVDISCARD_ALL) {
7939 int64_t ret64 = avio_seek(sc->pb, sample->pos, SEEK_SET);
7940 if (ret64 != sample->pos) {
7941 av_log(mov->fc, AV_LOG_ERROR, "stream %d, offset 0x%"PRIx64": partial file\n",
7942 sc->ffindex, sample->pos);
7943 if (should_retry(sc->pb, ret64)) {
7944 mov_current_sample_dec(sc);
7945 } else if (ret64 < 0) {
7948 return AVERROR_INVALIDDATA;
7951 if (st->discard == AVDISCARD_NONKEY && !(sample->flags & AVINDEX_KEYFRAME)) {
7952 av_log(mov->fc, AV_LOG_DEBUG, "Nonkey frame from stream %d discarded due to AVDISCARD_NONKEY\n", sc->ffindex);
7956 if (st->codecpar->codec_id == AV_CODEC_ID_EIA_608 && sample->size > 8)
7957 ret = get_eia608_packet(sc->pb, pkt, sample->size);
7959 ret = av_get_packet(sc->pb, pkt, sample->size);
7961 if (should_retry(sc->pb, ret)) {
7962 mov_current_sample_dec(sc);
7966 #if CONFIG_DV_DEMUXER
7967 if (mov->dv_demux && sc->dv_audio_container) {
7968 AVBufferRef *buf = pkt->buf;
7969 ret = avpriv_dv_produce_packet(mov->dv_demux, pkt, pkt->data, pkt->size, pkt->pos);
7971 av_packet_unref(pkt);
7974 ret = avpriv_dv_get_packet(mov->dv_demux, pkt);
7979 if (sc->has_palette) {
7982 pal = av_packet_new_side_data(pkt, AV_PKT_DATA_PALETTE, AVPALETTE_SIZE);
7984 av_log(mov->fc, AV_LOG_ERROR, "Cannot append palette to packet\n");
7986 memcpy(pal, sc->palette, AVPALETTE_SIZE);
7987 sc->has_palette = 0;
7990 if (st->codecpar->codec_id == AV_CODEC_ID_MP3 && !st->need_parsing && pkt->size > 4) {
7991 if (ff_mpa_check_header(AV_RB32(pkt->data)) < 0)
7992 st->need_parsing = AVSTREAM_PARSE_FULL;
7996 pkt->stream_index = sc->ffindex;
7997 pkt->dts = sample->timestamp;
7998 if (sample->flags & AVINDEX_DISCARD_FRAME) {
7999 pkt->flags |= AV_PKT_FLAG_DISCARD;
8001 if (sc->ctts_data && sc->ctts_index < sc->ctts_count) {
8002 pkt->pts = pkt->dts + sc->dts_shift + sc->ctts_data[sc->ctts_index].duration;
8003 /* update ctts context */
8005 if (sc->ctts_index < sc->ctts_count &&
8006 sc->ctts_data[sc->ctts_index].count == sc->ctts_sample) {
8008 sc->ctts_sample = 0;
8011 int64_t next_dts = (sc->current_sample < st->internal->nb_index_entries) ?
8012 st->internal->index_entries[sc->current_sample].timestamp : st->duration;
8014 if (next_dts >= pkt->dts)
8015 pkt->duration = next_dts - pkt->dts;
8016 pkt->pts = pkt->dts;
8018 if (st->discard == AVDISCARD_ALL)
8020 if (sc->sdtp_data && sc->current_sample <= sc->sdtp_count) {
8021 uint8_t sample_flags = sc->sdtp_data[sc->current_sample - 1];
8022 uint8_t sample_is_depended_on = (sample_flags >> 2) & 0x3;
8023 pkt->flags |= sample_is_depended_on == MOV_SAMPLE_DEPENDENCY_NO ? AV_PKT_FLAG_DISPOSABLE : 0;
8025 pkt->flags |= sample->flags & AVINDEX_KEYFRAME ? AV_PKT_FLAG_KEY : 0;
8026 pkt->pos = sample->pos;
8028 /* Multiple stsd handling. */
8029 if (sc->stsc_data) {
8030 /* Keep track of the stsc index for the given sample, then check
8031 * if the stsd index is different from the last used one. */
8033 if (mov_stsc_index_valid(sc->stsc_index, sc->stsc_count) &&
8034 mov_get_stsc_samples(sc, sc->stsc_index) == sc->stsc_sample) {
8036 sc->stsc_sample = 0;
8037 /* Do not check indexes after a switch. */
8038 } else if (sc->stsc_data[sc->stsc_index].id > 0 &&
8039 sc->stsc_data[sc->stsc_index].id - 1 < sc->stsd_count &&
8040 sc->stsc_data[sc->stsc_index].id - 1 != sc->last_stsd_index) {
8041 ret = mov_change_extradata(sc, pkt);
8048 aax_filter(pkt->data, pkt->size, mov);
8050 ret = cenc_filter(mov, st, sc, pkt, current_index);
8058 static int mov_seek_fragment(AVFormatContext *s, AVStream *st, int64_t timestamp)
8060 MOVContext *mov = s->priv_data;
8063 if (!mov->frag_index.complete)
8066 index = search_frag_timestamp(&mov->frag_index, st, timestamp);
8069 if (!mov->frag_index.item[index].headers_read)
8070 return mov_switch_root(s, -1, index);
8071 if (index + 1 < mov->frag_index.nb_items)
8072 mov->next_root_atom = mov->frag_index.item[index + 1].moof_offset;
8077 static int mov_seek_stream(AVFormatContext *s, AVStream *st, int64_t timestamp, int flags)
8079 MOVStreamContext *sc = st->priv_data;
8080 int sample, time_sample, ret;
8083 // Here we consider timestamp to be PTS, hence try to offset it so that we
8084 // can search over the DTS timeline.
8085 timestamp -= (sc->min_corrected_pts + sc->dts_shift);
8087 ret = mov_seek_fragment(s, st, timestamp);
8091 sample = av_index_search_timestamp(st, timestamp, flags);
8092 av_log(s, AV_LOG_TRACE, "stream %d, timestamp %"PRId64", sample %d\n", st->index, timestamp, sample);
8093 if (sample < 0 && st->internal->nb_index_entries && timestamp < st->internal->index_entries[0].timestamp)
8095 if (sample < 0) /* not sure what to do */
8096 return AVERROR_INVALIDDATA;
8097 mov_current_sample_set(sc, sample);
8098 av_log(s, AV_LOG_TRACE, "stream %d, found sample %d\n", st->index, sc->current_sample);
8099 /* adjust ctts index */
8100 if (sc->ctts_data) {
8102 for (i = 0; i < sc->ctts_count; i++) {
8103 int next = time_sample + sc->ctts_data[i].count;
8104 if (next > sc->current_sample) {
8106 sc->ctts_sample = sc->current_sample - time_sample;
8113 /* adjust stsd index */
8114 if (sc->chunk_count) {
8116 for (i = 0; i < sc->stsc_count; i++) {
8117 int64_t next = time_sample + mov_get_stsc_samples(sc, i);
8118 if (next > sc->current_sample) {
8120 sc->stsc_sample = sc->current_sample - time_sample;
8123 av_assert0(next == (int)next);
8131 static int64_t mov_get_skip_samples(AVStream *st, int sample)
8133 MOVStreamContext *sc = st->priv_data;
8134 int64_t first_ts = st->internal->index_entries[0].timestamp;
8135 int64_t ts = st->internal->index_entries[sample].timestamp;
8138 if (st->codecpar->codec_type != AVMEDIA_TYPE_AUDIO)
8141 /* compute skip samples according to stream start_pad, seek ts and first ts */
8142 off = av_rescale_q(ts - first_ts, st->time_base,
8143 (AVRational){1, st->codecpar->sample_rate});
8144 return FFMAX(sc->start_pad - off, 0);
8147 static int mov_read_seek(AVFormatContext *s, int stream_index, int64_t sample_time, int flags)
8149 MOVContext *mc = s->priv_data;
8154 if (stream_index >= s->nb_streams)
8155 return AVERROR_INVALIDDATA;
8157 st = s->streams[stream_index];
8158 sample = mov_seek_stream(s, st, sample_time, flags);
8162 if (mc->seek_individually) {
8163 /* adjust seek timestamp to found sample timestamp */
8164 int64_t seek_timestamp = st->internal->index_entries[sample].timestamp;
8165 st->internal->skip_samples = mov_get_skip_samples(st, sample);
8167 for (i = 0; i < s->nb_streams; i++) {
8171 if (stream_index == i)
8174 timestamp = av_rescale_q(seek_timestamp, s->streams[stream_index]->time_base, st->time_base);
8175 sample = mov_seek_stream(s, st, timestamp, flags);
8177 st->internal->skip_samples = mov_get_skip_samples(st, sample);
8180 for (i = 0; i < s->nb_streams; i++) {
8181 MOVStreamContext *sc;
8184 mov_current_sample_set(sc, 0);
8187 MOVStreamContext *sc;
8188 AVIndexEntry *entry = mov_find_next_sample(s, &st);
8190 return AVERROR_INVALIDDATA;
8192 if (sc->ffindex == stream_index && sc->current_sample == sample)
8194 mov_current_sample_inc(sc);
8200 #define OFFSET(x) offsetof(MOVContext, x)
8201 #define FLAGS AV_OPT_FLAG_VIDEO_PARAM | AV_OPT_FLAG_DECODING_PARAM
8202 static const AVOption mov_options[] = {
8203 {"use_absolute_path",
8204 "allow using absolute path when opening alias, this is a possible security issue",
8205 OFFSET(use_absolute_path), AV_OPT_TYPE_BOOL, {.i64 = 0},
8207 {"seek_streams_individually",
8208 "Seek each stream individually to the closest point",
8209 OFFSET(seek_individually), AV_OPT_TYPE_BOOL, { .i64 = 1 },
8211 {"ignore_editlist", "Ignore the edit list atom.", OFFSET(ignore_editlist), AV_OPT_TYPE_BOOL, {.i64 = 0},
8213 {"advanced_editlist",
8214 "Modify the AVIndex according to the editlists. Use this option to decode in the order specified by the edits.",
8215 OFFSET(advanced_editlist), AV_OPT_TYPE_BOOL, {.i64 = 1},
8217 {"ignore_chapters", "", OFFSET(ignore_chapters), AV_OPT_TYPE_BOOL, {.i64 = 0},
8220 "use mfra for fragment timestamps",
8221 OFFSET(use_mfra_for), AV_OPT_TYPE_INT, {.i64 = FF_MOV_FLAG_MFRA_AUTO},
8222 -1, FF_MOV_FLAG_MFRA_PTS, FLAGS,
8224 {"auto", "auto", 0, AV_OPT_TYPE_CONST, {.i64 = FF_MOV_FLAG_MFRA_AUTO}, 0, 0,
8225 FLAGS, "use_mfra_for" },
8226 {"dts", "dts", 0, AV_OPT_TYPE_CONST, {.i64 = FF_MOV_FLAG_MFRA_DTS}, 0, 0,
8227 FLAGS, "use_mfra_for" },
8228 {"pts", "pts", 0, AV_OPT_TYPE_CONST, {.i64 = FF_MOV_FLAG_MFRA_PTS}, 0, 0,
8229 FLAGS, "use_mfra_for" },
8230 { "export_all", "Export unrecognized metadata entries", OFFSET(export_all),
8231 AV_OPT_TYPE_BOOL, { .i64 = 0 }, 0, 1, .flags = FLAGS },
8232 { "export_xmp", "Export full XMP metadata", OFFSET(export_xmp),
8233 AV_OPT_TYPE_BOOL, { .i64 = 0 }, 0, 1, .flags = FLAGS },
8234 { "activation_bytes", "Secret bytes for Audible AAX files", OFFSET(activation_bytes),
8235 AV_OPT_TYPE_BINARY, .flags = AV_OPT_FLAG_DECODING_PARAM },
8236 { "audible_key", "AES-128 Key for Audible AAXC files", OFFSET(audible_key),
8237 AV_OPT_TYPE_BINARY, .flags = AV_OPT_FLAG_DECODING_PARAM },
8238 { "audible_iv", "AES-128 IV for Audible AAXC files", OFFSET(audible_iv),
8239 AV_OPT_TYPE_BINARY, .flags = AV_OPT_FLAG_DECODING_PARAM },
8240 { "audible_fixed_key", // extracted from libAAX_SDK.so and AAXSDKWin.dll files!
8241 "Fixed key used for handling Audible AAX files", OFFSET(audible_fixed_key),
8242 AV_OPT_TYPE_BINARY, {.str="77214d4b196a87cd520045fd20a51d67"},
8243 .flags = AV_OPT_FLAG_DECODING_PARAM },
8244 { "decryption_key", "The media decryption key (hex)", OFFSET(decryption_key), AV_OPT_TYPE_BINARY, .flags = AV_OPT_FLAG_DECODING_PARAM },
8245 { "enable_drefs", "Enable external track support.", OFFSET(enable_drefs), AV_OPT_TYPE_BOOL,
8246 {.i64 = 0}, 0, 1, FLAGS },
8251 static const AVClass mov_class = {
8252 .class_name = "mov,mp4,m4a,3gp,3g2,mj2",
8253 .item_name = av_default_item_name,
8254 .option = mov_options,
8255 .version = LIBAVUTIL_VERSION_INT,
8258 AVInputFormat ff_mov_demuxer = {
8259 .name = "mov,mp4,m4a,3gp,3g2,mj2",
8260 .long_name = NULL_IF_CONFIG_SMALL("QuickTime / MOV"),
8261 .priv_class = &mov_class,
8262 .priv_data_size = sizeof(MOVContext),
8263 .extensions = "mov,mp4,m4a,3gp,3g2,mj2,psp,m4b,ism,ismv,isma,f4v",
8264 .read_probe = mov_probe,
8265 .read_header = mov_read_header,
8266 .read_packet = mov_read_packet,
8267 .read_close = mov_read_close,
8268 .read_seek = mov_read_seek,
8269 .flags = AVFMT_NO_BYTE_SEEK | AVFMT_SEEK_TO_PTS,