3 * Copyright (c) 2001 Fabrice Bellard
4 * Copyright (c) 2009 Baptiste Coudurier <baptiste dot coudurier at gmail dot com>
6 * first version by Francois Revol <revol@free.fr>
7 * seek function by Gael Chardon <gael.dev@4now.net>
9 * This file is part of FFmpeg.
11 * FFmpeg is free software; you can redistribute it and/or
12 * modify it under the terms of the GNU Lesser General Public
13 * License as published by the Free Software Foundation; either
14 * version 2.1 of the License, or (at your option) any later version.
16 * FFmpeg is distributed in the hope that it will be useful,
17 * but WITHOUT ANY WARRANTY; without even the implied warranty of
18 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
19 * Lesser General Public License for more details.
21 * You should have received a copy of the GNU Lesser General Public
22 * License along with FFmpeg; if not, write to the Free Software
23 * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
30 #include "libavutil/attributes.h"
31 #include "libavutil/channel_layout.h"
32 #include "libavutil/internal.h"
33 #include "libavutil/intreadwrite.h"
34 #include "libavutil/intfloat.h"
35 #include "libavutil/mathematics.h"
36 #include "libavutil/time_internal.h"
37 #include "libavutil/avassert.h"
38 #include "libavutil/avstring.h"
39 #include "libavutil/dict.h"
40 #include "libavutil/display.h"
41 #include "libavutil/opt.h"
42 #include "libavutil/aes.h"
43 #include "libavutil/aes_ctr.h"
44 #include "libavutil/pixdesc.h"
45 #include "libavutil/sha.h"
46 #include "libavutil/spherical.h"
47 #include "libavutil/stereo3d.h"
48 #include "libavutil/timecode.h"
49 #include "libavutil/dovi_meta.h"
50 #include "libavcodec/ac3tab.h"
51 #include "libavcodec/flac.h"
52 #include "libavcodec/mpegaudiodecheader.h"
53 #include "libavcodec/mlp_parse.h"
56 #include "avio_internal.h"
59 #include "libavcodec/get_bits.h"
62 #include "replaygain.h"
68 #include "qtpalette.h"
70 /* those functions parse an atom */
71 /* links atom IDs to parse functions */
72 typedef struct MOVParseTableEntry {
74 int (*parse)(MOVContext *ctx, AVIOContext *pb, MOVAtom atom);
77 static int mov_read_default(MOVContext *c, AVIOContext *pb, MOVAtom atom);
78 static int mov_read_mfra(MOVContext *c, AVIOContext *f);
79 static int64_t add_ctts_entry(MOVStts** ctts_data, unsigned int* ctts_count, unsigned int* allocated_size,
80 int count, int duration);
82 static int mov_metadata_track_or_disc_number(MOVContext *c, AVIOContext *pb,
83 unsigned len, const char *key)
87 short current, total = 0;
88 avio_rb16(pb); // unknown
89 current = avio_rb16(pb);
91 total = avio_rb16(pb);
93 snprintf(buf, sizeof(buf), "%d", current);
95 snprintf(buf, sizeof(buf), "%d/%d", current, total);
96 c->fc->event_flags |= AVFMT_EVENT_FLAG_METADATA_UPDATED;
97 av_dict_set(&c->fc->metadata, key, buf, 0);
102 static int mov_metadata_int8_bypass_padding(MOVContext *c, AVIOContext *pb,
103 unsigned len, const char *key)
105 /* bypass padding bytes */
110 c->fc->event_flags |= AVFMT_EVENT_FLAG_METADATA_UPDATED;
111 av_dict_set_int(&c->fc->metadata, key, avio_r8(pb), 0);
116 static int mov_metadata_int8_no_padding(MOVContext *c, AVIOContext *pb,
117 unsigned len, const char *key)
119 c->fc->event_flags |= AVFMT_EVENT_FLAG_METADATA_UPDATED;
120 av_dict_set_int(&c->fc->metadata, key, avio_r8(pb), 0);
125 static int mov_metadata_gnre(MOVContext *c, AVIOContext *pb,
126 unsigned len, const char *key)
130 avio_r8(pb); // unknown
133 if (genre < 1 || genre > ID3v1_GENRE_MAX)
135 c->fc->event_flags |= AVFMT_EVENT_FLAG_METADATA_UPDATED;
136 av_dict_set(&c->fc->metadata, key, ff_id3v1_genre_str[genre-1], 0);
141 static const uint32_t mac_to_unicode[128] = {
142 0x00C4,0x00C5,0x00C7,0x00C9,0x00D1,0x00D6,0x00DC,0x00E1,
143 0x00E0,0x00E2,0x00E4,0x00E3,0x00E5,0x00E7,0x00E9,0x00E8,
144 0x00EA,0x00EB,0x00ED,0x00EC,0x00EE,0x00EF,0x00F1,0x00F3,
145 0x00F2,0x00F4,0x00F6,0x00F5,0x00FA,0x00F9,0x00FB,0x00FC,
146 0x2020,0x00B0,0x00A2,0x00A3,0x00A7,0x2022,0x00B6,0x00DF,
147 0x00AE,0x00A9,0x2122,0x00B4,0x00A8,0x2260,0x00C6,0x00D8,
148 0x221E,0x00B1,0x2264,0x2265,0x00A5,0x00B5,0x2202,0x2211,
149 0x220F,0x03C0,0x222B,0x00AA,0x00BA,0x03A9,0x00E6,0x00F8,
150 0x00BF,0x00A1,0x00AC,0x221A,0x0192,0x2248,0x2206,0x00AB,
151 0x00BB,0x2026,0x00A0,0x00C0,0x00C3,0x00D5,0x0152,0x0153,
152 0x2013,0x2014,0x201C,0x201D,0x2018,0x2019,0x00F7,0x25CA,
153 0x00FF,0x0178,0x2044,0x20AC,0x2039,0x203A,0xFB01,0xFB02,
154 0x2021,0x00B7,0x201A,0x201E,0x2030,0x00C2,0x00CA,0x00C1,
155 0x00CB,0x00C8,0x00CD,0x00CE,0x00CF,0x00CC,0x00D3,0x00D4,
156 0xF8FF,0x00D2,0x00DA,0x00DB,0x00D9,0x0131,0x02C6,0x02DC,
157 0x00AF,0x02D8,0x02D9,0x02DA,0x00B8,0x02DD,0x02DB,0x02C7,
160 static int mov_read_mac_string(MOVContext *c, AVIOContext *pb, int len,
161 char *dst, int dstlen)
164 char *end = dst+dstlen-1;
167 for (i = 0; i < len; i++) {
168 uint8_t t, c = avio_r8(pb);
176 PUT_UTF8(mac_to_unicode[c-0x80], t, if (p < end) *p++ = t;);
182 static int mov_read_covr(MOVContext *c, AVIOContext *pb, int type, int len)
185 MOVStreamContext *sc;
190 case 0xd: id = AV_CODEC_ID_MJPEG; break;
191 case 0xe: id = AV_CODEC_ID_PNG; break;
192 case 0x1b: id = AV_CODEC_ID_BMP; break;
194 av_log(c->fc, AV_LOG_WARNING, "Unknown cover type: 0x%x.\n", type);
199 sc = av_mallocz(sizeof(*sc));
201 return AVERROR(ENOMEM);
202 ret = ff_add_attached_pic(c->fc, NULL, pb, NULL, len);
207 st = c->fc->streams[c->fc->nb_streams - 1];
210 if (st->attached_pic.size >= 8 && id != AV_CODEC_ID_BMP) {
211 if (AV_RB64(st->attached_pic.data) == 0x89504e470d0a1a0a) {
212 id = AV_CODEC_ID_PNG;
214 id = AV_CODEC_ID_MJPEG;
217 st->codecpar->codec_id = id;
223 static int mov_metadata_loci(MOVContext *c, AVIOContext *pb, unsigned len)
225 char language[4] = { 0 };
226 char buf[200], place[100];
227 uint16_t langcode = 0;
228 double longitude, latitude, altitude;
229 const char *key = "location";
231 if (len < 4 + 2 + 1 + 1 + 4 + 4 + 4) {
232 av_log(c->fc, AV_LOG_ERROR, "loci too short\n");
233 return AVERROR_INVALIDDATA;
236 avio_skip(pb, 4); // version+flags
237 langcode = avio_rb16(pb);
238 ff_mov_lang_to_iso639(langcode, language);
241 len -= avio_get_str(pb, len, place, sizeof(place));
243 av_log(c->fc, AV_LOG_ERROR, "place name too long\n");
244 return AVERROR_INVALIDDATA;
246 avio_skip(pb, 1); // role
250 av_log(c->fc, AV_LOG_ERROR,
251 "loci too short (%u bytes left, need at least %d)\n", len, 12);
252 return AVERROR_INVALIDDATA;
254 longitude = ((int32_t) avio_rb32(pb)) / (float) (1 << 16);
255 latitude = ((int32_t) avio_rb32(pb)) / (float) (1 << 16);
256 altitude = ((int32_t) avio_rb32(pb)) / (float) (1 << 16);
258 // Try to output in the same format as the ?xyz field
259 snprintf(buf, sizeof(buf), "%+08.4f%+09.4f", latitude, longitude);
261 av_strlcatf(buf, sizeof(buf), "%+f", altitude);
262 av_strlcatf(buf, sizeof(buf), "/%s", place);
264 if (*language && strcmp(language, "und")) {
266 snprintf(key2, sizeof(key2), "%s-%s", key, language);
267 av_dict_set(&c->fc->metadata, key2, buf, 0);
269 c->fc->event_flags |= AVFMT_EVENT_FLAG_METADATA_UPDATED;
270 return av_dict_set(&c->fc->metadata, key, buf, 0);
273 static int mov_metadata_hmmt(MOVContext *c, AVIOContext *pb, unsigned len)
279 if (c->ignore_chapters)
282 n_hmmt = avio_rb32(pb);
283 if (n_hmmt > len / 4)
284 return AVERROR_INVALIDDATA;
285 for (i = 0; i < n_hmmt && !pb->eof_reached; i++) {
286 int moment_time = avio_rb32(pb);
287 avpriv_new_chapter(c->fc, i, av_make_q(1, 1000), moment_time, AV_NOPTS_VALUE, NULL);
292 static int mov_read_udta_string(MOVContext *c, AVIOContext *pb, MOVAtom atom)
294 char tmp_key[AV_FOURCC_MAX_STRING_SIZE] = {0};
295 char key2[32], language[4] = {0};
297 const char *key = NULL;
298 uint16_t langcode = 0;
299 uint32_t data_type = 0, str_size, str_size_alloc;
300 int (*parse)(MOVContext*, AVIOContext*, unsigned, const char*) = NULL;
305 case MKTAG( '@','P','R','M'): key = "premiere_version"; raw = 1; break;
306 case MKTAG( '@','P','R','Q'): key = "quicktime_version"; raw = 1; break;
307 case MKTAG( 'X','M','P','_'):
308 if (c->export_xmp) { key = "xmp"; raw = 1; } break;
309 case MKTAG( 'a','A','R','T'): key = "album_artist"; break;
310 case MKTAG( 'a','k','I','D'): key = "account_type";
311 parse = mov_metadata_int8_no_padding; break;
312 case MKTAG( 'a','p','I','D'): key = "account_id"; break;
313 case MKTAG( 'c','a','t','g'): key = "category"; break;
314 case MKTAG( 'c','p','i','l'): key = "compilation";
315 parse = mov_metadata_int8_no_padding; break;
316 case MKTAG( 'c','p','r','t'): key = "copyright"; break;
317 case MKTAG( 'd','e','s','c'): key = "description"; break;
318 case MKTAG( 'd','i','s','k'): key = "disc";
319 parse = mov_metadata_track_or_disc_number; break;
320 case MKTAG( 'e','g','i','d'): key = "episode_uid";
321 parse = mov_metadata_int8_no_padding; break;
322 case MKTAG( 'F','I','R','M'): key = "firmware"; raw = 1; break;
323 case MKTAG( 'g','n','r','e'): key = "genre";
324 parse = mov_metadata_gnre; break;
325 case MKTAG( 'h','d','v','d'): key = "hd_video";
326 parse = mov_metadata_int8_no_padding; break;
327 case MKTAG( 'H','M','M','T'):
328 return mov_metadata_hmmt(c, pb, atom.size);
329 case MKTAG( 'k','e','y','w'): key = "keywords"; break;
330 case MKTAG( 'l','d','e','s'): key = "synopsis"; break;
331 case MKTAG( 'l','o','c','i'):
332 return mov_metadata_loci(c, pb, atom.size);
333 case MKTAG( 'm','a','n','u'): key = "make"; break;
334 case MKTAG( 'm','o','d','l'): key = "model"; break;
335 case MKTAG( 'p','c','s','t'): key = "podcast";
336 parse = mov_metadata_int8_no_padding; break;
337 case MKTAG( 'p','g','a','p'): key = "gapless_playback";
338 parse = mov_metadata_int8_no_padding; break;
339 case MKTAG( 'p','u','r','d'): key = "purchase_date"; break;
340 case MKTAG( 'r','t','n','g'): key = "rating";
341 parse = mov_metadata_int8_no_padding; break;
342 case MKTAG( 's','o','a','a'): key = "sort_album_artist"; break;
343 case MKTAG( 's','o','a','l'): key = "sort_album"; break;
344 case MKTAG( 's','o','a','r'): key = "sort_artist"; break;
345 case MKTAG( 's','o','c','o'): key = "sort_composer"; break;
346 case MKTAG( 's','o','n','m'): key = "sort_name"; break;
347 case MKTAG( 's','o','s','n'): key = "sort_show"; break;
348 case MKTAG( 's','t','i','k'): key = "media_type";
349 parse = mov_metadata_int8_no_padding; break;
350 case MKTAG( 't','r','k','n'): key = "track";
351 parse = mov_metadata_track_or_disc_number; break;
352 case MKTAG( 't','v','e','n'): key = "episode_id"; break;
353 case MKTAG( 't','v','e','s'): key = "episode_sort";
354 parse = mov_metadata_int8_bypass_padding; break;
355 case MKTAG( 't','v','n','n'): key = "network"; break;
356 case MKTAG( 't','v','s','h'): key = "show"; break;
357 case MKTAG( 't','v','s','n'): key = "season_number";
358 parse = mov_metadata_int8_bypass_padding; break;
359 case MKTAG(0xa9,'A','R','T'): key = "artist"; break;
360 case MKTAG(0xa9,'P','R','D'): key = "producer"; break;
361 case MKTAG(0xa9,'a','l','b'): key = "album"; break;
362 case MKTAG(0xa9,'a','u','t'): key = "artist"; break;
363 case MKTAG(0xa9,'c','h','p'): key = "chapter"; break;
364 case MKTAG(0xa9,'c','m','t'): key = "comment"; break;
365 case MKTAG(0xa9,'c','o','m'): key = "composer"; break;
366 case MKTAG(0xa9,'c','p','y'): key = "copyright"; break;
367 case MKTAG(0xa9,'d','a','y'): key = "date"; break;
368 case MKTAG(0xa9,'d','i','r'): key = "director"; break;
369 case MKTAG(0xa9,'d','i','s'): key = "disclaimer"; break;
370 case MKTAG(0xa9,'e','d','1'): key = "edit_date"; break;
371 case MKTAG(0xa9,'e','n','c'): key = "encoder"; break;
372 case MKTAG(0xa9,'f','m','t'): key = "original_format"; break;
373 case MKTAG(0xa9,'g','e','n'): key = "genre"; break;
374 case MKTAG(0xa9,'g','r','p'): key = "grouping"; break;
375 case MKTAG(0xa9,'h','s','t'): key = "host_computer"; break;
376 case MKTAG(0xa9,'i','n','f'): key = "comment"; break;
377 case MKTAG(0xa9,'l','y','r'): key = "lyrics"; break;
378 case MKTAG(0xa9,'m','a','k'): key = "make"; break;
379 case MKTAG(0xa9,'m','o','d'): key = "model"; break;
380 case MKTAG(0xa9,'n','a','m'): key = "title"; break;
381 case MKTAG(0xa9,'o','p','e'): key = "original_artist"; break;
382 case MKTAG(0xa9,'p','r','d'): key = "producer"; break;
383 case MKTAG(0xa9,'p','r','f'): key = "performers"; break;
384 case MKTAG(0xa9,'r','e','q'): key = "playback_requirements"; break;
385 case MKTAG(0xa9,'s','r','c'): key = "original_source"; break;
386 case MKTAG(0xa9,'s','t','3'): key = "subtitle"; break;
387 case MKTAG(0xa9,'s','w','r'): key = "encoder"; break;
388 case MKTAG(0xa9,'t','o','o'): key = "encoder"; break;
389 case MKTAG(0xa9,'t','r','k'): key = "track"; break;
390 case MKTAG(0xa9,'u','r','l'): key = "URL"; break;
391 case MKTAG(0xa9,'w','r','n'): key = "warning"; break;
392 case MKTAG(0xa9,'w','r','t'): key = "composer"; break;
393 case MKTAG(0xa9,'x','y','z'): key = "location"; break;
396 if (c->itunes_metadata && atom.size > 8) {
397 int data_size = avio_rb32(pb);
398 int tag = avio_rl32(pb);
399 if (tag == MKTAG('d','a','t','a') && data_size <= atom.size && data_size >= 16) {
400 data_type = avio_rb32(pb); // type
401 avio_rb32(pb); // unknown
402 str_size = data_size - 16;
405 if (atom.type == MKTAG('c', 'o', 'v', 'r')) {
406 int ret = mov_read_covr(c, pb, data_type, str_size);
408 av_log(c->fc, AV_LOG_ERROR, "Error parsing cover art.\n");
411 atom.size -= str_size;
415 } else if (!key && c->found_hdlr_mdta && c->meta_keys) {
416 uint32_t index = AV_RB32(&atom.type);
417 if (index < c->meta_keys_count && index > 0) {
418 key = c->meta_keys[index];
420 av_log(c->fc, AV_LOG_WARNING,
421 "The index of 'data' is out of range: %"PRId32" < 1 or >= %d.\n",
422 index, c->meta_keys_count);
426 } else if (atom.size > 4 && key && !c->itunes_metadata && !raw) {
427 str_size = avio_rb16(pb); // string length
428 if (str_size > atom.size) {
430 avio_seek(pb, -2, SEEK_CUR);
431 av_log(c->fc, AV_LOG_WARNING, "UDTA parsing failed retrying raw\n");
434 langcode = avio_rb16(pb);
435 ff_mov_lang_to_iso639(langcode, language);
438 str_size = atom.size;
440 if (c->export_all && !key) {
441 key = av_fourcc_make_string(tmp_key, atom.type);
446 if (atom.size < 0 || str_size >= INT_MAX/2)
447 return AVERROR_INVALIDDATA;
449 // Allocates enough space if data_type is a int32 or float32 number, otherwise
450 // worst-case requirement for output string in case of utf8 coded input
451 num = (data_type >= 21 && data_type <= 23);
452 str_size_alloc = (num ? 512 : (raw ? str_size : str_size * 2)) + 1;
453 str = av_mallocz(str_size_alloc);
455 return AVERROR(ENOMEM);
458 parse(c, pb, str_size, key);
460 if (!raw && (data_type == 3 || (data_type == 0 && (langcode < 0x400 || langcode == 0x7fff)))) { // MAC Encoded
461 mov_read_mac_string(c, pb, str_size, str, str_size_alloc);
462 } else if (data_type == 21) { // BE signed integer, variable size
465 val = (int8_t)avio_r8(pb);
466 else if (str_size == 2)
467 val = (int16_t)avio_rb16(pb);
468 else if (str_size == 3)
469 val = ((int32_t)(avio_rb24(pb)<<8))>>8;
470 else if (str_size == 4)
471 val = (int32_t)avio_rb32(pb);
472 if (snprintf(str, str_size_alloc, "%d", val) >= str_size_alloc) {
473 av_log(c->fc, AV_LOG_ERROR,
474 "Failed to store the number (%d) in string.\n", val);
476 return AVERROR_INVALIDDATA;
478 } else if (data_type == 22) { // BE unsigned integer, variable size
479 unsigned int val = 0;
482 else if (str_size == 2)
484 else if (str_size == 3)
486 else if (str_size == 4)
488 if (snprintf(str, str_size_alloc, "%u", val) >= str_size_alloc) {
489 av_log(c->fc, AV_LOG_ERROR,
490 "Failed to store the number (%u) in string.\n", val);
492 return AVERROR_INVALIDDATA;
494 } else if (data_type == 23 && str_size >= 4) { // BE float32
495 float val = av_int2float(avio_rb32(pb));
496 if (snprintf(str, str_size_alloc, "%f", val) >= str_size_alloc) {
497 av_log(c->fc, AV_LOG_ERROR,
498 "Failed to store the float32 number (%f) in string.\n", val);
500 return AVERROR_INVALIDDATA;
503 int ret = ffio_read_size(pb, str, str_size);
510 c->fc->event_flags |= AVFMT_EVENT_FLAG_METADATA_UPDATED;
511 av_dict_set(&c->fc->metadata, key, str, 0);
512 if (*language && strcmp(language, "und")) {
513 snprintf(key2, sizeof(key2), "%s-%s", key, language);
514 av_dict_set(&c->fc->metadata, key2, str, 0);
516 if (!strcmp(key, "encoder")) {
517 int major, minor, micro;
518 if (sscanf(str, "HandBrake %d.%d.%d", &major, &minor, µ) == 3) {
519 c->handbrake_version = 1000000*major + 1000*minor + micro;
528 static int mov_read_chpl(MOVContext *c, AVIOContext *pb, MOVAtom atom)
531 int i, nb_chapters, str_len, version;
535 if (c->ignore_chapters)
538 if ((atom.size -= 5) < 0)
541 version = avio_r8(pb);
544 avio_rb32(pb); // ???
545 nb_chapters = avio_r8(pb);
547 for (i = 0; i < nb_chapters; i++) {
551 start = avio_rb64(pb);
552 str_len = avio_r8(pb);
554 if ((atom.size -= 9+str_len) < 0)
557 ret = ffio_read_size(pb, str, str_len);
561 avpriv_new_chapter(c->fc, i, (AVRational){1,10000000}, start, AV_NOPTS_VALUE, str);
566 #define MIN_DATA_ENTRY_BOX_SIZE 12
567 static int mov_read_dref(MOVContext *c, AVIOContext *pb, MOVAtom atom)
570 MOVStreamContext *sc;
573 if (c->fc->nb_streams < 1)
575 st = c->fc->streams[c->fc->nb_streams-1];
578 avio_rb32(pb); // version + flags
579 entries = avio_rb32(pb);
581 entries > (atom.size - 1) / MIN_DATA_ENTRY_BOX_SIZE + 1 ||
582 entries >= UINT_MAX / sizeof(*sc->drefs))
583 return AVERROR_INVALIDDATA;
585 for (i = 0; i < sc->drefs_count; i++) {
586 MOVDref *dref = &sc->drefs[i];
587 av_freep(&dref->path);
588 av_freep(&dref->dir);
592 sc->drefs = av_mallocz(entries * sizeof(*sc->drefs));
594 return AVERROR(ENOMEM);
595 sc->drefs_count = entries;
597 for (i = 0; i < entries; i++) {
598 MOVDref *dref = &sc->drefs[i];
599 uint32_t size = avio_rb32(pb);
600 int64_t next = avio_tell(pb) + size - 4;
603 return AVERROR_INVALIDDATA;
605 dref->type = avio_rl32(pb);
606 avio_rb32(pb); // version + flags
608 if (dref->type == MKTAG('a','l','i','s') && size > 150) {
609 /* macintosh alias record */
610 uint16_t volume_len, len;
616 volume_len = avio_r8(pb);
617 volume_len = FFMIN(volume_len, 27);
618 ret = ffio_read_size(pb, dref->volume, 27);
621 dref->volume[volume_len] = 0;
622 av_log(c->fc, AV_LOG_DEBUG, "volume %s, len %d\n", dref->volume, volume_len);
627 len = FFMIN(len, 63);
628 ret = ffio_read_size(pb, dref->filename, 63);
631 dref->filename[len] = 0;
632 av_log(c->fc, AV_LOG_DEBUG, "filename %s, len %d\n", dref->filename, len);
636 /* read next level up_from_alias/down_to_target */
637 dref->nlvl_from = avio_rb16(pb);
638 dref->nlvl_to = avio_rb16(pb);
639 av_log(c->fc, AV_LOG_DEBUG, "nlvl from %d, nlvl to %d\n",
640 dref->nlvl_from, dref->nlvl_to);
644 for (type = 0; type != -1 && avio_tell(pb) < next; ) {
647 type = avio_rb16(pb);
649 av_log(c->fc, AV_LOG_DEBUG, "type %d, len %d\n", type, len);
652 if (type == 2) { // absolute path
654 dref->path = av_mallocz(len+1);
656 return AVERROR(ENOMEM);
658 ret = ffio_read_size(pb, dref->path, len);
660 av_freep(&dref->path);
663 if (len > volume_len && !strncmp(dref->path, dref->volume, volume_len)) {
665 memmove(dref->path, dref->path+volume_len, len);
668 // trim string of any ending zeros
669 for (j = len - 1; j >= 0; j--) {
670 if (dref->path[j] == 0)
675 for (j = 0; j < len; j++)
676 if (dref->path[j] == ':' || dref->path[j] == 0)
678 av_log(c->fc, AV_LOG_DEBUG, "path %s\n", dref->path);
679 } else if (type == 0) { // directory name
681 dref->dir = av_malloc(len+1);
683 return AVERROR(ENOMEM);
685 ret = ffio_read_size(pb, dref->dir, len);
687 av_freep(&dref->dir);
691 for (j = 0; j < len; j++)
692 if (dref->dir[j] == ':')
694 av_log(c->fc, AV_LOG_DEBUG, "dir %s\n", dref->dir);
699 av_log(c->fc, AV_LOG_DEBUG, "Unknown dref type 0x%08"PRIx32" size %"PRIu32"\n",
704 avio_seek(pb, next, SEEK_SET);
709 static int mov_read_hdlr(MOVContext *c, AVIOContext *pb, MOVAtom atom)
718 avio_r8(pb); /* version */
719 avio_rb24(pb); /* flags */
722 ctype = avio_rl32(pb);
723 type = avio_rl32(pb); /* component subtype */
725 av_log(c->fc, AV_LOG_TRACE, "ctype=%s\n", av_fourcc2str(ctype));
726 av_log(c->fc, AV_LOG_TRACE, "stype=%s\n", av_fourcc2str(type));
728 if (c->trak_index < 0) { // meta not inside a trak
729 if (type == MKTAG('m','d','t','a')) {
730 c->found_hdlr_mdta = 1;
735 st = c->fc->streams[c->fc->nb_streams-1];
737 if (type == MKTAG('v','i','d','e'))
738 st->codecpar->codec_type = AVMEDIA_TYPE_VIDEO;
739 else if (type == MKTAG('s','o','u','n'))
740 st->codecpar->codec_type = AVMEDIA_TYPE_AUDIO;
741 else if (type == MKTAG('m','1','a',' '))
742 st->codecpar->codec_id = AV_CODEC_ID_MP2;
743 else if ((type == MKTAG('s','u','b','p')) || (type == MKTAG('c','l','c','p')))
744 st->codecpar->codec_type = AVMEDIA_TYPE_SUBTITLE;
746 avio_rb32(pb); /* component manufacture */
747 avio_rb32(pb); /* component flags */
748 avio_rb32(pb); /* component flags mask */
750 title_size = atom.size - 24;
751 if (title_size > 0) {
752 if (title_size > FFMIN(INT_MAX, SIZE_MAX-1))
753 return AVERROR_INVALIDDATA;
754 title_str = av_malloc(title_size + 1); /* Add null terminator */
756 return AVERROR(ENOMEM);
758 ret = ffio_read_size(pb, title_str, title_size);
760 av_freep(&title_str);
763 title_str[title_size] = 0;
765 int off = (!c->isom && title_str[0] == title_size - 1);
766 // flag added so as to not set stream handler name if already set from mdia->hdlr
767 av_dict_set(&st->metadata, "handler_name", title_str + off, AV_DICT_DONT_OVERWRITE);
769 av_freep(&title_str);
775 static int mov_read_esds(MOVContext *c, AVIOContext *pb, MOVAtom atom)
777 return ff_mov_read_esds(c->fc, pb);
780 static int mov_read_dac3(MOVContext *c, AVIOContext *pb, MOVAtom atom)
783 enum AVAudioServiceType *ast;
784 int ac3info, acmod, lfeon, bsmod;
786 if (c->fc->nb_streams < 1)
788 st = c->fc->streams[c->fc->nb_streams-1];
790 ast = (enum AVAudioServiceType*)av_stream_new_side_data(st, AV_PKT_DATA_AUDIO_SERVICE_TYPE,
793 return AVERROR(ENOMEM);
795 ac3info = avio_rb24(pb);
796 bsmod = (ac3info >> 14) & 0x7;
797 acmod = (ac3info >> 11) & 0x7;
798 lfeon = (ac3info >> 10) & 0x1;
799 st->codecpar->channels = ((int[]){2,1,2,3,3,4,4,5})[acmod] + lfeon;
800 st->codecpar->channel_layout = avpriv_ac3_channel_layout_tab[acmod];
802 st->codecpar->channel_layout |= AV_CH_LOW_FREQUENCY;
804 if (st->codecpar->channels > 1 && bsmod == 0x7)
805 *ast = AV_AUDIO_SERVICE_TYPE_KARAOKE;
807 #if FF_API_LAVF_AVCTX
808 FF_DISABLE_DEPRECATION_WARNINGS
809 st->codec->audio_service_type = *ast;
810 FF_ENABLE_DEPRECATION_WARNINGS
816 static int mov_read_dec3(MOVContext *c, AVIOContext *pb, MOVAtom atom)
819 enum AVAudioServiceType *ast;
820 int eac3info, acmod, lfeon, bsmod;
822 if (c->fc->nb_streams < 1)
824 st = c->fc->streams[c->fc->nb_streams-1];
826 ast = (enum AVAudioServiceType*)av_stream_new_side_data(st, AV_PKT_DATA_AUDIO_SERVICE_TYPE,
829 return AVERROR(ENOMEM);
831 /* No need to parse fields for additional independent substreams and its
832 * associated dependent substreams since libavcodec's E-AC-3 decoder
833 * does not support them yet. */
834 avio_rb16(pb); /* data_rate and num_ind_sub */
835 eac3info = avio_rb24(pb);
836 bsmod = (eac3info >> 12) & 0x1f;
837 acmod = (eac3info >> 9) & 0x7;
838 lfeon = (eac3info >> 8) & 0x1;
839 st->codecpar->channel_layout = avpriv_ac3_channel_layout_tab[acmod];
841 st->codecpar->channel_layout |= AV_CH_LOW_FREQUENCY;
842 st->codecpar->channels = av_get_channel_layout_nb_channels(st->codecpar->channel_layout);
844 if (st->codecpar->channels > 1 && bsmod == 0x7)
845 *ast = AV_AUDIO_SERVICE_TYPE_KARAOKE;
847 #if FF_API_LAVF_AVCTX
848 FF_DISABLE_DEPRECATION_WARNINGS
849 st->codec->audio_service_type = *ast;
850 FF_ENABLE_DEPRECATION_WARNINGS
856 static int mov_read_ddts(MOVContext *c, AVIOContext *pb, MOVAtom atom)
859 uint8_t buf[DDTS_SIZE + AV_INPUT_BUFFER_PADDING_SIZE];
861 uint32_t frame_duration_code = 0;
862 uint32_t channel_layout_code = 0;
866 if ((ret = ffio_read_size(pb, buf, DDTS_SIZE)) < 0)
869 init_get_bits(&gb, buf, 8 * DDTS_SIZE);
871 if (c->fc->nb_streams < 1) {
874 st = c->fc->streams[c->fc->nb_streams-1];
876 st->codecpar->sample_rate = get_bits_long(&gb, 32);
877 if (st->codecpar->sample_rate <= 0) {
878 av_log(c->fc, AV_LOG_ERROR, "Invalid sample rate %d\n", st->codecpar->sample_rate);
879 return AVERROR_INVALIDDATA;
881 skip_bits_long(&gb, 32); /* max bitrate */
882 st->codecpar->bit_rate = get_bits_long(&gb, 32);
883 st->codecpar->bits_per_coded_sample = get_bits(&gb, 8);
884 frame_duration_code = get_bits(&gb, 2);
885 skip_bits(&gb, 30); /* various fields */
886 channel_layout_code = get_bits(&gb, 16);
888 st->codecpar->frame_size =
889 (frame_duration_code == 0) ? 512 :
890 (frame_duration_code == 1) ? 1024 :
891 (frame_duration_code == 2) ? 2048 :
892 (frame_duration_code == 3) ? 4096 : 0;
894 if (channel_layout_code > 0xff) {
895 av_log(c->fc, AV_LOG_WARNING, "Unsupported DTS audio channel layout\n");
897 st->codecpar->channel_layout =
898 ((channel_layout_code & 0x1) ? AV_CH_FRONT_CENTER : 0) |
899 ((channel_layout_code & 0x2) ? AV_CH_FRONT_LEFT : 0) |
900 ((channel_layout_code & 0x2) ? AV_CH_FRONT_RIGHT : 0) |
901 ((channel_layout_code & 0x4) ? AV_CH_SIDE_LEFT : 0) |
902 ((channel_layout_code & 0x4) ? AV_CH_SIDE_RIGHT : 0) |
903 ((channel_layout_code & 0x8) ? AV_CH_LOW_FREQUENCY : 0);
905 st->codecpar->channels = av_get_channel_layout_nb_channels(st->codecpar->channel_layout);
910 static int mov_read_chan(MOVContext *c, AVIOContext *pb, MOVAtom atom)
914 if (c->fc->nb_streams < 1)
916 st = c->fc->streams[c->fc->nb_streams-1];
921 /* skip version and flags */
924 ff_mov_read_chan(c->fc, pb, st, atom.size - 4);
929 static int mov_read_wfex(MOVContext *c, AVIOContext *pb, MOVAtom atom)
934 if (c->fc->nb_streams < 1)
936 st = c->fc->streams[c->fc->nb_streams-1];
938 if ((ret = ff_get_wav_header(c->fc, pb, st->codecpar, atom.size, 0)) < 0)
939 av_log(c->fc, AV_LOG_WARNING, "get_wav_header failed\n");
944 /* This atom overrides any previously set aspect ratio */
945 static int mov_read_pasp(MOVContext *c, AVIOContext *pb, MOVAtom atom)
947 const int num = avio_rb32(pb);
948 const int den = avio_rb32(pb);
951 if (c->fc->nb_streams < 1)
953 st = c->fc->streams[c->fc->nb_streams-1];
956 av_reduce(&st->sample_aspect_ratio.num, &st->sample_aspect_ratio.den,
962 /* this atom contains actual media data */
963 static int mov_read_mdat(MOVContext *c, AVIOContext *pb, MOVAtom atom)
965 if (atom.size == 0) /* wrong one (MP4) */
968 return 0; /* now go for moov */
971 #define DRM_BLOB_SIZE 56
973 static int mov_read_adrm(MOVContext *c, AVIOContext *pb, MOVAtom atom)
975 uint8_t intermediate_key[20];
976 uint8_t intermediate_iv[20];
979 uint8_t file_checksum[20];
980 uint8_t calculated_checksum[20];
984 uint8_t *activation_bytes = c->activation_bytes;
985 uint8_t *fixed_key = c->audible_fixed_key;
989 sha = av_sha_alloc();
991 return AVERROR(ENOMEM);
992 av_free(c->aes_decrypt);
993 c->aes_decrypt = av_aes_alloc();
994 if (!c->aes_decrypt) {
995 ret = AVERROR(ENOMEM);
999 /* drm blob processing */
1000 avio_read(pb, output, 8); // go to offset 8, absolute position 0x251
1001 avio_read(pb, input, DRM_BLOB_SIZE);
1002 avio_read(pb, output, 4); // go to offset 4, absolute position 0x28d
1003 avio_read(pb, file_checksum, 20);
1005 av_log(c->fc, AV_LOG_INFO, "[aax] file checksum == "); // required by external tools
1006 for (i = 0; i < 20; i++)
1007 av_log(c->fc, AV_LOG_INFO, "%02x", file_checksum[i]);
1008 av_log(c->fc, AV_LOG_INFO, "\n");
1010 /* verify activation data */
1011 if (!activation_bytes) {
1012 av_log(c->fc, AV_LOG_WARNING, "[aax] activation_bytes option is missing!\n");
1013 ret = 0; /* allow ffprobe to continue working on .aax files */
1016 if (c->activation_bytes_size != 4) {
1017 av_log(c->fc, AV_LOG_FATAL, "[aax] activation_bytes value needs to be 4 bytes!\n");
1018 ret = AVERROR(EINVAL);
1022 /* verify fixed key */
1023 if (c->audible_fixed_key_size != 16) {
1024 av_log(c->fc, AV_LOG_FATAL, "[aax] audible_fixed_key value needs to be 16 bytes!\n");
1025 ret = AVERROR(EINVAL);
1029 /* AAX (and AAX+) key derivation */
1030 av_sha_init(sha, 160);
1031 av_sha_update(sha, fixed_key, 16);
1032 av_sha_update(sha, activation_bytes, 4);
1033 av_sha_final(sha, intermediate_key);
1034 av_sha_init(sha, 160);
1035 av_sha_update(sha, fixed_key, 16);
1036 av_sha_update(sha, intermediate_key, 20);
1037 av_sha_update(sha, activation_bytes, 4);
1038 av_sha_final(sha, intermediate_iv);
1039 av_sha_init(sha, 160);
1040 av_sha_update(sha, intermediate_key, 16);
1041 av_sha_update(sha, intermediate_iv, 16);
1042 av_sha_final(sha, calculated_checksum);
1043 if (memcmp(calculated_checksum, file_checksum, 20)) { // critical error
1044 av_log(c->fc, AV_LOG_ERROR, "[aax] mismatch in checksums!\n");
1045 ret = AVERROR_INVALIDDATA;
1048 av_aes_init(c->aes_decrypt, intermediate_key, 128, 1);
1049 av_aes_crypt(c->aes_decrypt, output, input, DRM_BLOB_SIZE >> 4, intermediate_iv, 1);
1050 for (i = 0; i < 4; i++) {
1051 // file data (in output) is stored in big-endian mode
1052 if (activation_bytes[i] != output[3 - i]) { // critical error
1053 av_log(c->fc, AV_LOG_ERROR, "[aax] error in drm blob decryption!\n");
1054 ret = AVERROR_INVALIDDATA;
1058 memcpy(c->file_key, output + 8, 16);
1059 memcpy(input, output + 26, 16);
1060 av_sha_init(sha, 160);
1061 av_sha_update(sha, input, 16);
1062 av_sha_update(sha, c->file_key, 16);
1063 av_sha_update(sha, fixed_key, 16);
1064 av_sha_final(sha, c->file_iv);
1072 static int mov_aaxc_crypto(MOVContext *c)
1074 if (c->audible_key_size != 16) {
1075 av_log(c->fc, AV_LOG_FATAL, "[aaxc] audible_key value needs to be 16 bytes!\n");
1076 return AVERROR(EINVAL);
1079 if (c->audible_iv_size != 16) {
1080 av_log(c->fc, AV_LOG_FATAL, "[aaxc] audible_iv value needs to be 16 bytes!\n");
1081 return AVERROR(EINVAL);
1084 c->aes_decrypt = av_aes_alloc();
1085 if (!c->aes_decrypt) {
1086 return AVERROR(ENOMEM);
1089 memcpy(c->file_key, c->audible_key, 16);
1090 memcpy(c->file_iv, c->audible_iv, 16);
1096 // Audible AAX (and AAX+) bytestream decryption
1097 static int aax_filter(uint8_t *input, int size, MOVContext *c)
1100 unsigned char iv[16];
1102 memcpy(iv, c->file_iv, 16); // iv is overwritten
1103 blocks = size >> 4; // trailing bytes are not encrypted!
1104 av_aes_init(c->aes_decrypt, c->file_key, 128, 1);
1105 av_aes_crypt(c->aes_decrypt, input, input, blocks, iv, 1);
1110 /* read major brand, minor version and compatible brands and store them as metadata */
1111 static int mov_read_ftyp(MOVContext *c, AVIOContext *pb, MOVAtom atom)
1114 int comp_brand_size;
1115 char* comp_brands_str;
1116 uint8_t type[5] = {0};
1117 int ret = ffio_read_size(pb, type, 4);
1121 if (strcmp(type, "qt "))
1123 av_log(c->fc, AV_LOG_DEBUG, "ISO: File Type Major Brand: %.4s\n",(char *)&type);
1124 av_dict_set(&c->fc->metadata, "major_brand", type, 0);
1125 minor_ver = avio_rb32(pb); /* minor version */
1126 av_dict_set_int(&c->fc->metadata, "minor_version", minor_ver, 0);
1128 comp_brand_size = atom.size - 8;
1129 if (comp_brand_size < 0 || comp_brand_size == INT_MAX)
1130 return AVERROR_INVALIDDATA;
1131 comp_brands_str = av_malloc(comp_brand_size + 1); /* Add null terminator */
1132 if (!comp_brands_str)
1133 return AVERROR(ENOMEM);
1135 ret = ffio_read_size(pb, comp_brands_str, comp_brand_size);
1137 av_freep(&comp_brands_str);
1140 comp_brands_str[comp_brand_size] = 0;
1141 av_dict_set(&c->fc->metadata, "compatible_brands",
1142 comp_brands_str, AV_DICT_DONT_STRDUP_VAL);
1144 // Logic for handling Audible's .aaxc files
1145 if (!strcmp(type, "aaxc")) {
1152 /* this atom should contain all header atoms */
1153 static int mov_read_moov(MOVContext *c, AVIOContext *pb, MOVAtom atom)
1157 if (c->found_moov) {
1158 av_log(c->fc, AV_LOG_WARNING, "Found duplicated MOOV Atom. Skipped it\n");
1159 avio_skip(pb, atom.size);
1163 if ((ret = mov_read_default(c, pb, atom)) < 0)
1165 /* we parsed the 'moov' atom, we can terminate the parsing as soon as we find the 'mdat' */
1166 /* so we don't parse the whole file if over a network */
1168 return 0; /* now go for mdat */
1171 static MOVFragmentStreamInfo * get_frag_stream_info(
1172 MOVFragmentIndex *frag_index,
1177 MOVFragmentIndexItem * item;
1179 if (index < 0 || index >= frag_index->nb_items)
1181 item = &frag_index->item[index];
1182 for (i = 0; i < item->nb_stream_info; i++)
1183 if (item->stream_info[i].id == id)
1184 return &item->stream_info[i];
1186 // This shouldn't happen
1190 static void set_frag_stream(MOVFragmentIndex *frag_index, int id)
1193 MOVFragmentIndexItem * item;
1195 if (frag_index->current < 0 ||
1196 frag_index->current >= frag_index->nb_items)
1199 item = &frag_index->item[frag_index->current];
1200 for (i = 0; i < item->nb_stream_info; i++)
1201 if (item->stream_info[i].id == id) {
1206 // id not found. This shouldn't happen.
1210 static MOVFragmentStreamInfo * get_current_frag_stream_info(
1211 MOVFragmentIndex *frag_index)
1213 MOVFragmentIndexItem *item;
1214 if (frag_index->current < 0 ||
1215 frag_index->current >= frag_index->nb_items)
1218 item = &frag_index->item[frag_index->current];
1219 if (item->current >= 0 && item->current < item->nb_stream_info)
1220 return &item->stream_info[item->current];
1222 // This shouldn't happen
1226 static int search_frag_moof_offset(MOVFragmentIndex *frag_index, int64_t offset)
1229 int64_t moof_offset;
1231 // Optimize for appending new entries
1232 if (!frag_index->nb_items ||
1233 frag_index->item[frag_index->nb_items - 1].moof_offset < offset)
1234 return frag_index->nb_items;
1237 b = frag_index->nb_items;
1241 moof_offset = frag_index->item[m].moof_offset;
1242 if (moof_offset >= offset)
1244 if (moof_offset <= offset)
1250 static int64_t get_stream_info_time(MOVFragmentStreamInfo * frag_stream_info)
1252 av_assert0(frag_stream_info);
1253 if (frag_stream_info->sidx_pts != AV_NOPTS_VALUE)
1254 return frag_stream_info->sidx_pts;
1255 if (frag_stream_info->first_tfra_pts != AV_NOPTS_VALUE)
1256 return frag_stream_info->first_tfra_pts;
1257 return frag_stream_info->tfdt_dts;
1260 static int64_t get_frag_time(MOVFragmentIndex *frag_index,
1261 int index, int track_id)
1263 MOVFragmentStreamInfo * frag_stream_info;
1267 if (track_id >= 0) {
1268 frag_stream_info = get_frag_stream_info(frag_index, index, track_id);
1269 if (frag_stream_info->sidx_pts != AV_NOPTS_VALUE)
1270 return frag_stream_info->sidx_pts;
1271 if (frag_stream_info->first_tfra_pts != AV_NOPTS_VALUE)
1272 return frag_stream_info->first_tfra_pts;
1273 return frag_stream_info->sidx_pts;
1276 for (i = 0; i < frag_index->item[index].nb_stream_info; i++) {
1277 frag_stream_info = &frag_index->item[index].stream_info[i];
1278 timestamp = get_stream_info_time(frag_stream_info);
1279 if (timestamp != AV_NOPTS_VALUE)
1282 return AV_NOPTS_VALUE;
1285 static int search_frag_timestamp(MOVFragmentIndex *frag_index,
1286 AVStream *st, int64_t timestamp)
1293 // If the stream is referenced by any sidx, limit the search
1294 // to fragments that referenced this stream in the sidx
1295 MOVStreamContext *sc = st->priv_data;
1301 b = frag_index->nb_items;
1304 m0 = m = (a + b) >> 1;
1307 (frag_time = get_frag_time(frag_index, m, id)) == AV_NOPTS_VALUE)
1310 if (m < b && frag_time <= timestamp)
1319 static int update_frag_index(MOVContext *c, int64_t offset)
1322 MOVFragmentIndexItem * item;
1323 MOVFragmentStreamInfo * frag_stream_info;
1325 // If moof_offset already exists in frag_index, return index to it
1326 index = search_frag_moof_offset(&c->frag_index, offset);
1327 if (index < c->frag_index.nb_items &&
1328 c->frag_index.item[index].moof_offset == offset)
1331 // offset is not yet in frag index.
1332 // Insert new item at index (sorted by moof offset)
1333 item = av_fast_realloc(c->frag_index.item,
1334 &c->frag_index.allocated_size,
1335 (c->frag_index.nb_items + 1) *
1336 sizeof(*c->frag_index.item));
1339 c->frag_index.item = item;
1341 frag_stream_info = av_realloc_array(NULL, c->fc->nb_streams,
1342 sizeof(*item->stream_info));
1343 if (!frag_stream_info)
1346 for (i = 0; i < c->fc->nb_streams; i++) {
1347 // Avoid building frag index if streams lack track id.
1348 if (c->fc->streams[i]->id < 0) {
1349 av_free(frag_stream_info);
1350 return AVERROR_INVALIDDATA;
1353 frag_stream_info[i].id = c->fc->streams[i]->id;
1354 frag_stream_info[i].sidx_pts = AV_NOPTS_VALUE;
1355 frag_stream_info[i].tfdt_dts = AV_NOPTS_VALUE;
1356 frag_stream_info[i].next_trun_dts = AV_NOPTS_VALUE;
1357 frag_stream_info[i].first_tfra_pts = AV_NOPTS_VALUE;
1358 frag_stream_info[i].index_entry = -1;
1359 frag_stream_info[i].encryption_index = NULL;
1362 if (index < c->frag_index.nb_items)
1363 memmove(c->frag_index.item + index + 1, c->frag_index.item + index,
1364 (c->frag_index.nb_items - index) * sizeof(*c->frag_index.item));
1366 item = &c->frag_index.item[index];
1367 item->headers_read = 0;
1369 item->nb_stream_info = c->fc->nb_streams;
1370 item->moof_offset = offset;
1371 item->stream_info = frag_stream_info;
1372 c->frag_index.nb_items++;
1377 static void fix_frag_index_entries(MOVFragmentIndex *frag_index, int index,
1378 int id, int entries)
1381 MOVFragmentStreamInfo * frag_stream_info;
1385 for (i = index; i < frag_index->nb_items; i++) {
1386 frag_stream_info = get_frag_stream_info(frag_index, i, id);
1387 if (frag_stream_info && frag_stream_info->index_entry >= 0)
1388 frag_stream_info->index_entry += entries;
1392 static int mov_read_moof(MOVContext *c, AVIOContext *pb, MOVAtom atom)
1394 // Set by mov_read_tfhd(). mov_read_trun() will reject files missing tfhd.
1395 c->fragment.found_tfhd = 0;
1397 if (!c->has_looked_for_mfra && c->use_mfra_for > 0) {
1398 c->has_looked_for_mfra = 1;
1399 if (pb->seekable & AVIO_SEEKABLE_NORMAL) {
1401 av_log(c->fc, AV_LOG_VERBOSE, "stream has moof boxes, will look "
1403 if ((ret = mov_read_mfra(c, pb)) < 0) {
1404 av_log(c->fc, AV_LOG_VERBOSE, "found a moof box but failed to "
1405 "read the mfra (may be a live ismv)\n");
1408 av_log(c->fc, AV_LOG_VERBOSE, "found a moof box but stream is not "
1409 "seekable, can not look for mfra\n");
1412 c->fragment.moof_offset = c->fragment.implicit_offset = avio_tell(pb) - 8;
1413 av_log(c->fc, AV_LOG_TRACE, "moof offset %"PRIx64"\n", c->fragment.moof_offset);
1414 c->frag_index.current = update_frag_index(c, c->fragment.moof_offset);
1415 return mov_read_default(c, pb, atom);
1418 static void mov_metadata_creation_time(AVDictionary **metadata, int64_t time, void *logctx)
1421 if (time >= 2082844800)
1422 time -= 2082844800; /* seconds between 1904-01-01 and Epoch */
1424 if ((int64_t)(time * 1000000ULL) / 1000000 != time) {
1425 av_log(logctx, AV_LOG_DEBUG, "creation_time is not representable\n");
1429 avpriv_dict_set_timestamp(metadata, "creation_time", time * 1000000);
1433 static int mov_read_mdhd(MOVContext *c, AVIOContext *pb, MOVAtom atom)
1436 MOVStreamContext *sc;
1438 char language[4] = {0};
1440 int64_t creation_time;
1442 if (c->fc->nb_streams < 1)
1444 st = c->fc->streams[c->fc->nb_streams-1];
1447 if (sc->time_scale) {
1448 av_log(c->fc, AV_LOG_ERROR, "Multiple mdhd?\n");
1449 return AVERROR_INVALIDDATA;
1452 version = avio_r8(pb);
1454 avpriv_request_sample(c->fc, "Version %d", version);
1455 return AVERROR_PATCHWELCOME;
1457 avio_rb24(pb); /* flags */
1459 creation_time = avio_rb64(pb);
1462 creation_time = avio_rb32(pb);
1463 avio_rb32(pb); /* modification time */
1465 mov_metadata_creation_time(&st->metadata, creation_time, c->fc);
1467 sc->time_scale = avio_rb32(pb);
1468 if (sc->time_scale <= 0) {
1469 av_log(c->fc, AV_LOG_ERROR, "Invalid mdhd time scale %d, defaulting to 1\n", sc->time_scale);
1472 st->duration = (version == 1) ? avio_rb64(pb) : avio_rb32(pb); /* duration */
1474 lang = avio_rb16(pb); /* language */
1475 if (ff_mov_lang_to_iso639(lang, language))
1476 av_dict_set(&st->metadata, "language", language, 0);
1477 avio_rb16(pb); /* quality */
1482 static int mov_read_mvhd(MOVContext *c, AVIOContext *pb, MOVAtom atom)
1485 int64_t creation_time;
1486 int version = avio_r8(pb); /* version */
1487 avio_rb24(pb); /* flags */
1490 creation_time = avio_rb64(pb);
1493 creation_time = avio_rb32(pb);
1494 avio_rb32(pb); /* modification time */
1496 mov_metadata_creation_time(&c->fc->metadata, creation_time, c->fc);
1497 c->time_scale = avio_rb32(pb); /* time scale */
1498 if (c->time_scale <= 0) {
1499 av_log(c->fc, AV_LOG_ERROR, "Invalid mvhd time scale %d, defaulting to 1\n", c->time_scale);
1502 av_log(c->fc, AV_LOG_TRACE, "time scale = %i\n", c->time_scale);
1504 c->duration = (version == 1) ? avio_rb64(pb) : avio_rb32(pb); /* duration */
1505 // set the AVFormatContext duration because the duration of individual tracks
1506 // may be inaccurate
1508 c->fc->duration = av_rescale(c->duration, AV_TIME_BASE, c->time_scale);
1509 avio_rb32(pb); /* preferred scale */
1511 avio_rb16(pb); /* preferred volume */
1513 avio_skip(pb, 10); /* reserved */
1515 /* movie display matrix, store it in main context and use it later on */
1516 for (i = 0; i < 3; i++) {
1517 c->movie_display_matrix[i][0] = avio_rb32(pb); // 16.16 fixed point
1518 c->movie_display_matrix[i][1] = avio_rb32(pb); // 16.16 fixed point
1519 c->movie_display_matrix[i][2] = avio_rb32(pb); // 2.30 fixed point
1522 avio_rb32(pb); /* preview time */
1523 avio_rb32(pb); /* preview duration */
1524 avio_rb32(pb); /* poster time */
1525 avio_rb32(pb); /* selection time */
1526 avio_rb32(pb); /* selection duration */
1527 avio_rb32(pb); /* current time */
1528 avio_rb32(pb); /* next track ID */
1533 static int mov_read_enda(MOVContext *c, AVIOContext *pb, MOVAtom atom)
1538 if (c->fc->nb_streams < 1)
1540 st = c->fc->streams[c->fc->nb_streams-1];
1542 little_endian = avio_rb16(pb) & 0xFF;
1543 av_log(c->fc, AV_LOG_TRACE, "enda %d\n", little_endian);
1544 if (little_endian == 1) {
1545 switch (st->codecpar->codec_id) {
1546 case AV_CODEC_ID_PCM_S24BE:
1547 st->codecpar->codec_id = AV_CODEC_ID_PCM_S24LE;
1549 case AV_CODEC_ID_PCM_S32BE:
1550 st->codecpar->codec_id = AV_CODEC_ID_PCM_S32LE;
1552 case AV_CODEC_ID_PCM_F32BE:
1553 st->codecpar->codec_id = AV_CODEC_ID_PCM_F32LE;
1555 case AV_CODEC_ID_PCM_F64BE:
1556 st->codecpar->codec_id = AV_CODEC_ID_PCM_F64LE;
1565 static int mov_read_colr(MOVContext *c, AVIOContext *pb, MOVAtom atom)
1568 uint8_t *icc_profile;
1569 char color_parameter_type[5] = { 0 };
1570 uint16_t color_primaries, color_trc, color_matrix;
1573 if (c->fc->nb_streams < 1)
1575 st = c->fc->streams[c->fc->nb_streams - 1];
1577 ret = ffio_read_size(pb, color_parameter_type, 4);
1580 if (strncmp(color_parameter_type, "nclx", 4) &&
1581 strncmp(color_parameter_type, "nclc", 4) &&
1582 strncmp(color_parameter_type, "prof", 4)) {
1583 av_log(c->fc, AV_LOG_WARNING, "unsupported color_parameter_type %s\n",
1584 color_parameter_type);
1588 if (!strncmp(color_parameter_type, "prof", 4)) {
1589 icc_profile = av_stream_new_side_data(st, AV_PKT_DATA_ICC_PROFILE, atom.size - 4);
1591 return AVERROR(ENOMEM);
1592 ret = ffio_read_size(pb, icc_profile, atom.size - 4);
1596 color_primaries = avio_rb16(pb);
1597 color_trc = avio_rb16(pb);
1598 color_matrix = avio_rb16(pb);
1600 av_log(c->fc, AV_LOG_TRACE,
1601 "%s: pri %d trc %d matrix %d",
1602 color_parameter_type, color_primaries, color_trc, color_matrix);
1604 if (!strncmp(color_parameter_type, "nclx", 4)) {
1605 uint8_t color_range = avio_r8(pb) >> 7;
1606 av_log(c->fc, AV_LOG_TRACE, " full %"PRIu8"", color_range);
1608 st->codecpar->color_range = AVCOL_RANGE_JPEG;
1610 st->codecpar->color_range = AVCOL_RANGE_MPEG;
1613 if (!av_color_primaries_name(color_primaries))
1614 color_primaries = AVCOL_PRI_UNSPECIFIED;
1615 if (!av_color_transfer_name(color_trc))
1616 color_trc = AVCOL_TRC_UNSPECIFIED;
1617 if (!av_color_space_name(color_matrix))
1618 color_matrix = AVCOL_SPC_UNSPECIFIED;
1620 st->codecpar->color_primaries = color_primaries;
1621 st->codecpar->color_trc = color_trc;
1622 st->codecpar->color_space = color_matrix;
1623 av_log(c->fc, AV_LOG_TRACE, "\n");
1628 static int mov_read_fiel(MOVContext *c, AVIOContext *pb, MOVAtom atom)
1631 unsigned mov_field_order;
1632 enum AVFieldOrder decoded_field_order = AV_FIELD_UNKNOWN;
1634 if (c->fc->nb_streams < 1) // will happen with jp2 files
1636 st = c->fc->streams[c->fc->nb_streams-1];
1638 return AVERROR_INVALIDDATA;
1639 mov_field_order = avio_rb16(pb);
1640 if ((mov_field_order & 0xFF00) == 0x0100)
1641 decoded_field_order = AV_FIELD_PROGRESSIVE;
1642 else if ((mov_field_order & 0xFF00) == 0x0200) {
1643 switch (mov_field_order & 0xFF) {
1644 case 0x01: decoded_field_order = AV_FIELD_TT;
1646 case 0x06: decoded_field_order = AV_FIELD_BB;
1648 case 0x09: decoded_field_order = AV_FIELD_TB;
1650 case 0x0E: decoded_field_order = AV_FIELD_BT;
1654 if (decoded_field_order == AV_FIELD_UNKNOWN && mov_field_order) {
1655 av_log(c->fc, AV_LOG_ERROR, "Unknown MOV field order 0x%04x\n", mov_field_order);
1657 st->codecpar->field_order = decoded_field_order;
1662 static int mov_realloc_extradata(AVCodecParameters *par, MOVAtom atom)
1665 uint64_t size = (uint64_t)par->extradata_size + atom.size + 8 + AV_INPUT_BUFFER_PADDING_SIZE;
1666 if (size > INT_MAX || (uint64_t)atom.size > INT_MAX)
1667 return AVERROR_INVALIDDATA;
1668 if ((err = av_reallocp(&par->extradata, size)) < 0) {
1669 par->extradata_size = 0;
1672 par->extradata_size = size - AV_INPUT_BUFFER_PADDING_SIZE;
1676 /* Read a whole atom into the extradata return the size of the atom read, possibly truncated if != atom.size */
1677 static int64_t mov_read_atom_into_extradata(MOVContext *c, AVIOContext *pb, MOVAtom atom,
1678 AVCodecParameters *par, uint8_t *buf)
1680 int64_t result = atom.size;
1683 AV_WB32(buf , atom.size + 8);
1684 AV_WL32(buf + 4, atom.type);
1685 err = ffio_read_size(pb, buf + 8, atom.size);
1687 par->extradata_size -= atom.size;
1689 } else if (err < atom.size) {
1690 av_log(c->fc, AV_LOG_WARNING, "truncated extradata\n");
1691 par->extradata_size -= atom.size - err;
1694 memset(buf + 8 + err, 0, AV_INPUT_BUFFER_PADDING_SIZE);
1698 /* FIXME modify QDM2/SVQ3/H.264 decoders to take full atom as extradata */
1699 static int mov_read_extradata(MOVContext *c, AVIOContext *pb, MOVAtom atom,
1700 enum AVCodecID codec_id)
1703 uint64_t original_size;
1706 if (c->fc->nb_streams < 1) // will happen with jp2 files
1708 st = c->fc->streams[c->fc->nb_streams-1];
1710 if (st->codecpar->codec_id != codec_id)
1711 return 0; /* unexpected codec_id - don't mess with extradata */
1713 original_size = st->codecpar->extradata_size;
1714 err = mov_realloc_extradata(st->codecpar, atom);
1718 err = mov_read_atom_into_extradata(c, pb, atom, st->codecpar, st->codecpar->extradata + original_size);
1721 return 0; // Note: this is the original behavior to ignore truncation.
1724 /* wrapper functions for reading ALAC/AVS/MJPEG/MJPEG2000 extradata atoms only for those codecs */
1725 static int mov_read_alac(MOVContext *c, AVIOContext *pb, MOVAtom atom)
1727 return mov_read_extradata(c, pb, atom, AV_CODEC_ID_ALAC);
1730 static int mov_read_avss(MOVContext *c, AVIOContext *pb, MOVAtom atom)
1732 return mov_read_extradata(c, pb, atom, AV_CODEC_ID_AVS);
1735 static int mov_read_jp2h(MOVContext *c, AVIOContext *pb, MOVAtom atom)
1737 return mov_read_extradata(c, pb, atom, AV_CODEC_ID_JPEG2000);
1740 static int mov_read_dpxe(MOVContext *c, AVIOContext *pb, MOVAtom atom)
1742 return mov_read_extradata(c, pb, atom, AV_CODEC_ID_R10K);
1745 static int mov_read_avid(MOVContext *c, AVIOContext *pb, MOVAtom atom)
1747 int ret = mov_read_extradata(c, pb, atom, AV_CODEC_ID_AVUI);
1749 ret = mov_read_extradata(c, pb, atom, AV_CODEC_ID_DNXHD);
1753 static int mov_read_targa_y216(MOVContext *c, AVIOContext *pb, MOVAtom atom)
1755 int ret = mov_read_extradata(c, pb, atom, AV_CODEC_ID_TARGA_Y216);
1757 if (!ret && c->fc->nb_streams >= 1) {
1758 AVCodecParameters *par = c->fc->streams[c->fc->nb_streams-1]->codecpar;
1759 if (par->extradata_size >= 40) {
1760 par->height = AV_RB16(&par->extradata[36]);
1761 par->width = AV_RB16(&par->extradata[38]);
1767 static int mov_read_ares(MOVContext *c, AVIOContext *pb, MOVAtom atom)
1769 if (c->fc->nb_streams >= 1) {
1770 AVCodecParameters *par = c->fc->streams[c->fc->nb_streams-1]->codecpar;
1771 if (par->codec_tag == MKTAG('A', 'V', 'i', 'n') &&
1772 par->codec_id == AV_CODEC_ID_H264 &&
1776 cid = avio_rb16(pb);
1777 /* For AVID AVCI50, force width of 1440 to be able to select the correct SPS and PPS */
1778 if (cid == 0xd4d || cid == 0xd4e)
1781 } else if ((par->codec_tag == MKTAG('A', 'V', 'd', '1') ||
1782 par->codec_tag == MKTAG('A', 'V', 'j', '2') ||
1783 par->codec_tag == MKTAG('A', 'V', 'd', 'n')) &&
1787 num = avio_rb32(pb);
1788 den = avio_rb32(pb);
1789 if (num <= 0 || den <= 0)
1791 switch (avio_rb32(pb)) {
1793 if (den >= INT_MAX / 2)
1797 c->fc->streams[c->fc->nb_streams-1]->internal->display_aspect_ratio.num = num;
1798 c->fc->streams[c->fc->nb_streams-1]->internal->display_aspect_ratio.den = den;
1805 return mov_read_avid(c, pb, atom);
1808 static int mov_read_aclr(MOVContext *c, AVIOContext *pb, MOVAtom atom)
1812 uint64_t original_size;
1813 if (c->fc->nb_streams >= 1) {
1814 AVCodecParameters *par = c->fc->streams[c->fc->nb_streams-1]->codecpar;
1815 if (par->codec_id == AV_CODEC_ID_H264)
1817 if (atom.size == 16) {
1818 original_size = par->extradata_size;
1819 ret = mov_realloc_extradata(par, atom);
1821 length = mov_read_atom_into_extradata(c, pb, atom, par, par->extradata + original_size);
1822 if (length == atom.size) {
1823 const uint8_t range_value = par->extradata[original_size + 19];
1824 switch (range_value) {
1826 par->color_range = AVCOL_RANGE_MPEG;
1829 par->color_range = AVCOL_RANGE_JPEG;
1832 av_log(c->fc, AV_LOG_WARNING, "ignored unknown aclr value (%d)\n", range_value);
1835 ff_dlog(c->fc, "color_range: %d\n", par->color_range);
1837 /* For some reason the whole atom was not added to the extradata */
1838 av_log(c->fc, AV_LOG_ERROR, "aclr not decoded - incomplete atom\n");
1841 av_log(c->fc, AV_LOG_ERROR, "aclr not decoded - unable to add atom to extradata\n");
1844 av_log(c->fc, AV_LOG_WARNING, "aclr not decoded - unexpected size %"PRId64"\n", atom.size);
1851 static int mov_read_svq3(MOVContext *c, AVIOContext *pb, MOVAtom atom)
1853 return mov_read_extradata(c, pb, atom, AV_CODEC_ID_SVQ3);
1856 static int mov_read_wave(MOVContext *c, AVIOContext *pb, MOVAtom atom)
1861 if (c->fc->nb_streams < 1)
1863 st = c->fc->streams[c->fc->nb_streams-1];
1865 if ((uint64_t)atom.size > (1<<30))
1866 return AVERROR_INVALIDDATA;
1868 if (st->codecpar->codec_id == AV_CODEC_ID_QDM2 ||
1869 st->codecpar->codec_id == AV_CODEC_ID_QDMC ||
1870 st->codecpar->codec_id == AV_CODEC_ID_SPEEX) {
1871 // pass all frma atom to codec, needed at least for QDMC and QDM2
1872 ret = ff_get_extradata(c->fc, st->codecpar, pb, atom.size);
1875 } else if (atom.size > 8) { /* to read frma, esds atoms */
1876 if (st->codecpar->codec_id == AV_CODEC_ID_ALAC && atom.size >= 24) {
1878 ret = ffio_ensure_seekback(pb, 8);
1881 buffer = avio_rb64(pb);
1883 if ( (buffer & 0xFFFFFFFF) == MKBETAG('f','r','m','a')
1884 && buffer >> 32 <= atom.size
1885 && buffer >> 32 >= 8) {
1888 } else if (!st->codecpar->extradata_size) {
1889 #define ALAC_EXTRADATA_SIZE 36
1890 st->codecpar->extradata = av_mallocz(ALAC_EXTRADATA_SIZE + AV_INPUT_BUFFER_PADDING_SIZE);
1891 if (!st->codecpar->extradata)
1892 return AVERROR(ENOMEM);
1893 st->codecpar->extradata_size = ALAC_EXTRADATA_SIZE;
1894 AV_WB32(st->codecpar->extradata , ALAC_EXTRADATA_SIZE);
1895 AV_WB32(st->codecpar->extradata + 4, MKTAG('a','l','a','c'));
1896 AV_WB64(st->codecpar->extradata + 12, buffer);
1897 avio_read(pb, st->codecpar->extradata + 20, 16);
1898 avio_skip(pb, atom.size - 24);
1902 if ((ret = mov_read_default(c, pb, atom)) < 0)
1905 avio_skip(pb, atom.size);
1910 * This function reads atom content and puts data in extradata without tag
1911 * nor size unlike mov_read_extradata.
1913 static int mov_read_glbl(MOVContext *c, AVIOContext *pb, MOVAtom atom)
1918 if (c->fc->nb_streams < 1)
1920 st = c->fc->streams[c->fc->nb_streams-1];
1922 if ((uint64_t)atom.size > (1<<30))
1923 return AVERROR_INVALIDDATA;
1925 if (atom.size >= 10) {
1926 // Broken files created by legacy versions of libavformat will
1927 // wrap a whole fiel atom inside of a glbl atom.
1928 unsigned size = avio_rb32(pb);
1929 unsigned type = avio_rl32(pb);
1930 avio_seek(pb, -8, SEEK_CUR);
1931 if (type == MKTAG('f','i','e','l') && size == atom.size)
1932 return mov_read_default(c, pb, atom);
1934 if (st->codecpar->extradata_size > 1 && st->codecpar->extradata) {
1935 av_log(c->fc, AV_LOG_WARNING, "ignoring multiple glbl\n");
1938 ret = ff_get_extradata(c->fc, st->codecpar, pb, atom.size);
1941 if (atom.type == MKTAG('h','v','c','C') && st->codecpar->codec_tag == MKTAG('d','v','h','1'))
1942 /* HEVC-based Dolby Vision derived from hvc1.
1943 Happens to match with an identifier
1944 previously utilized for DV. Thus, if we have
1945 the hvcC extradata box available as specified,
1946 set codec to HEVC */
1947 st->codecpar->codec_id = AV_CODEC_ID_HEVC;
1952 static int mov_read_dvc1(MOVContext *c, AVIOContext *pb, MOVAtom atom)
1955 uint8_t profile_level;
1958 if (c->fc->nb_streams < 1)
1960 st = c->fc->streams[c->fc->nb_streams-1];
1962 if (atom.size >= (1<<28) || atom.size < 7)
1963 return AVERROR_INVALIDDATA;
1965 profile_level = avio_r8(pb);
1966 if ((profile_level & 0xf0) != 0xc0)
1969 avio_seek(pb, 6, SEEK_CUR);
1970 ret = ff_get_extradata(c->fc, st->codecpar, pb, atom.size - 7);
1978 * An strf atom is a BITMAPINFOHEADER struct. This struct is 40 bytes itself,
1979 * but can have extradata appended at the end after the 40 bytes belonging
1982 static int mov_read_strf(MOVContext *c, AVIOContext *pb, MOVAtom atom)
1987 if (c->fc->nb_streams < 1)
1989 if (atom.size <= 40)
1991 st = c->fc->streams[c->fc->nb_streams-1];
1993 if ((uint64_t)atom.size > (1<<30))
1994 return AVERROR_INVALIDDATA;
1997 ret = ff_get_extradata(c->fc, st->codecpar, pb, atom.size - 40);
2004 static int mov_read_stco(MOVContext *c, AVIOContext *pb, MOVAtom atom)
2007 MOVStreamContext *sc;
2008 unsigned int i, entries;
2010 if (c->trak_index < 0) {
2011 av_log(c->fc, AV_LOG_WARNING, "STCO outside TRAK\n");
2014 if (c->fc->nb_streams < 1)
2016 st = c->fc->streams[c->fc->nb_streams-1];
2019 avio_r8(pb); /* version */
2020 avio_rb24(pb); /* flags */
2022 entries = avio_rb32(pb);
2027 if (sc->chunk_offsets) {
2028 av_log(c->fc, AV_LOG_WARNING, "Ignoring duplicated STCO atom\n");
2031 av_free(sc->chunk_offsets);
2032 sc->chunk_count = 0;
2033 sc->chunk_offsets = av_malloc_array(entries, sizeof(*sc->chunk_offsets));
2034 if (!sc->chunk_offsets)
2035 return AVERROR(ENOMEM);
2036 sc->chunk_count = entries;
2038 if (atom.type == MKTAG('s','t','c','o'))
2039 for (i = 0; i < entries && !pb->eof_reached; i++)
2040 sc->chunk_offsets[i] = avio_rb32(pb);
2041 else if (atom.type == MKTAG('c','o','6','4'))
2042 for (i = 0; i < entries && !pb->eof_reached; i++)
2043 sc->chunk_offsets[i] = avio_rb64(pb);
2045 return AVERROR_INVALIDDATA;
2047 sc->chunk_count = i;
2049 if (pb->eof_reached) {
2050 av_log(c->fc, AV_LOG_WARNING, "reached eof, corrupted STCO atom\n");
2057 static int mov_codec_id(AVStream *st, uint32_t format)
2059 int id = ff_codec_get_id(ff_codec_movaudio_tags, format);
2062 ((format & 0xFFFF) == 'm' + ('s' << 8) ||
2063 (format & 0xFFFF) == 'T' + ('S' << 8)))
2064 id = ff_codec_get_id(ff_codec_wav_tags, av_bswap32(format) & 0xFFFF);
2066 if (st->codecpar->codec_type != AVMEDIA_TYPE_VIDEO && id > 0) {
2067 st->codecpar->codec_type = AVMEDIA_TYPE_AUDIO;
2068 } else if (st->codecpar->codec_type != AVMEDIA_TYPE_AUDIO &&
2069 /* skip old ASF MPEG-4 tag */
2070 format && format != MKTAG('m','p','4','s')) {
2071 id = ff_codec_get_id(ff_codec_movvideo_tags, format);
2073 id = ff_codec_get_id(ff_codec_bmp_tags, format);
2075 st->codecpar->codec_type = AVMEDIA_TYPE_VIDEO;
2076 else if (st->codecpar->codec_type == AVMEDIA_TYPE_DATA ||
2077 (st->codecpar->codec_type == AVMEDIA_TYPE_SUBTITLE &&
2078 st->codecpar->codec_id == AV_CODEC_ID_NONE)) {
2079 id = ff_codec_get_id(ff_codec_movsubtitle_tags, format);
2081 st->codecpar->codec_type = AVMEDIA_TYPE_SUBTITLE;
2083 id = ff_codec_get_id(ff_codec_movdata_tags, format);
2087 st->codecpar->codec_tag = format;
2092 static void mov_parse_stsd_video(MOVContext *c, AVIOContext *pb,
2093 AVStream *st, MOVStreamContext *sc)
2095 uint8_t codec_name[32] = { 0 };
2100 /* The first 16 bytes of the video sample description are already
2101 * read in ff_mov_read_stsd_entries() */
2102 stsd_start = avio_tell(pb) - 16;
2104 avio_rb16(pb); /* version */
2105 avio_rb16(pb); /* revision level */
2106 id = avio_rl32(pb); /* vendor */
2107 av_dict_set(&st->metadata, "vendor_id", av_fourcc2str(id), 0);
2108 avio_rb32(pb); /* temporal quality */
2109 avio_rb32(pb); /* spatial quality */
2111 st->codecpar->width = avio_rb16(pb); /* width */
2112 st->codecpar->height = avio_rb16(pb); /* height */
2114 avio_rb32(pb); /* horiz resolution */
2115 avio_rb32(pb); /* vert resolution */
2116 avio_rb32(pb); /* data size, always 0 */
2117 avio_rb16(pb); /* frames per samples */
2119 len = avio_r8(pb); /* codec name, pascal string */
2122 mov_read_mac_string(c, pb, len, codec_name, sizeof(codec_name));
2124 avio_skip(pb, 31 - len);
2127 av_dict_set(&st->metadata, "encoder", codec_name, 0);
2129 /* codec_tag YV12 triggers an UV swap in rawdec.c */
2130 if (!strncmp(codec_name, "Planar Y'CbCr 8-bit 4:2:0", 25)) {
2131 st->codecpar->codec_tag = MKTAG('I', '4', '2', '0');
2132 st->codecpar->width &= ~1;
2133 st->codecpar->height &= ~1;
2135 /* Flash Media Server uses tag H.263 with Sorenson Spark */
2136 if (st->codecpar->codec_tag == MKTAG('H','2','6','3') &&
2137 !strncmp(codec_name, "Sorenson H263", 13))
2138 st->codecpar->codec_id = AV_CODEC_ID_FLV1;
2140 st->codecpar->bits_per_coded_sample = avio_rb16(pb); /* depth */
2142 avio_seek(pb, stsd_start, SEEK_SET);
2144 if (ff_get_qtpalette(st->codecpar->codec_id, pb, sc->palette)) {
2145 st->codecpar->bits_per_coded_sample &= 0x1F;
2146 sc->has_palette = 1;
2150 static void mov_parse_stsd_audio(MOVContext *c, AVIOContext *pb,
2151 AVStream *st, MOVStreamContext *sc)
2153 int bits_per_sample, flags;
2154 uint16_t version = avio_rb16(pb);
2156 AVDictionaryEntry *compatible_brands = av_dict_get(c->fc->metadata, "compatible_brands", NULL, AV_DICT_MATCH_CASE);
2158 avio_rb16(pb); /* revision level */
2159 id = avio_rl32(pb); /* vendor */
2160 av_dict_set(&st->metadata, "vendor_id", av_fourcc2str(id), 0);
2162 st->codecpar->channels = avio_rb16(pb); /* channel count */
2163 st->codecpar->bits_per_coded_sample = avio_rb16(pb); /* sample size */
2164 av_log(c->fc, AV_LOG_TRACE, "audio channels %d\n", st->codecpar->channels);
2166 sc->audio_cid = avio_rb16(pb);
2167 avio_rb16(pb); /* packet size = 0 */
2169 st->codecpar->sample_rate = ((avio_rb32(pb) >> 16));
2171 // Read QT version 1 fields. In version 0 these do not exist.
2172 av_log(c->fc, AV_LOG_TRACE, "version =%d, isom =%d\n", version, c->isom);
2174 (compatible_brands && strstr(compatible_brands->value, "qt ")) ||
2175 (sc->stsd_version == 0 && version > 0)) {
2177 sc->samples_per_frame = avio_rb32(pb);
2178 avio_rb32(pb); /* bytes per packet */
2179 sc->bytes_per_frame = avio_rb32(pb);
2180 avio_rb32(pb); /* bytes per sample */
2181 } else if (version == 2) {
2182 avio_rb32(pb); /* sizeof struct only */
2183 st->codecpar->sample_rate = av_int2double(avio_rb64(pb));
2184 st->codecpar->channels = avio_rb32(pb);
2185 avio_rb32(pb); /* always 0x7F000000 */
2186 st->codecpar->bits_per_coded_sample = avio_rb32(pb);
2188 flags = avio_rb32(pb); /* lpcm format specific flag */
2189 sc->bytes_per_frame = avio_rb32(pb);
2190 sc->samples_per_frame = avio_rb32(pb);
2191 if (st->codecpar->codec_tag == MKTAG('l','p','c','m'))
2192 st->codecpar->codec_id =
2193 ff_mov_get_lpcm_codec_id(st->codecpar->bits_per_coded_sample,
2196 if (version == 0 || (version == 1 && sc->audio_cid != -2)) {
2197 /* can't correctly handle variable sized packet as audio unit */
2198 switch (st->codecpar->codec_id) {
2199 case AV_CODEC_ID_MP2:
2200 case AV_CODEC_ID_MP3:
2201 st->need_parsing = AVSTREAM_PARSE_FULL;
2207 if (sc->format == 0) {
2208 if (st->codecpar->bits_per_coded_sample == 8)
2209 st->codecpar->codec_id = mov_codec_id(st, MKTAG('r','a','w',' '));
2210 else if (st->codecpar->bits_per_coded_sample == 16)
2211 st->codecpar->codec_id = mov_codec_id(st, MKTAG('t','w','o','s'));
2214 switch (st->codecpar->codec_id) {
2215 case AV_CODEC_ID_PCM_S8:
2216 case AV_CODEC_ID_PCM_U8:
2217 if (st->codecpar->bits_per_coded_sample == 16)
2218 st->codecpar->codec_id = AV_CODEC_ID_PCM_S16BE;
2220 case AV_CODEC_ID_PCM_S16LE:
2221 case AV_CODEC_ID_PCM_S16BE:
2222 if (st->codecpar->bits_per_coded_sample == 8)
2223 st->codecpar->codec_id = AV_CODEC_ID_PCM_S8;
2224 else if (st->codecpar->bits_per_coded_sample == 24)
2225 st->codecpar->codec_id =
2226 st->codecpar->codec_id == AV_CODEC_ID_PCM_S16BE ?
2227 AV_CODEC_ID_PCM_S24BE : AV_CODEC_ID_PCM_S24LE;
2228 else if (st->codecpar->bits_per_coded_sample == 32)
2229 st->codecpar->codec_id =
2230 st->codecpar->codec_id == AV_CODEC_ID_PCM_S16BE ?
2231 AV_CODEC_ID_PCM_S32BE : AV_CODEC_ID_PCM_S32LE;
2233 /* set values for old format before stsd version 1 appeared */
2234 case AV_CODEC_ID_MACE3:
2235 sc->samples_per_frame = 6;
2236 sc->bytes_per_frame = 2 * st->codecpar->channels;
2238 case AV_CODEC_ID_MACE6:
2239 sc->samples_per_frame = 6;
2240 sc->bytes_per_frame = 1 * st->codecpar->channels;
2242 case AV_CODEC_ID_ADPCM_IMA_QT:
2243 sc->samples_per_frame = 64;
2244 sc->bytes_per_frame = 34 * st->codecpar->channels;
2246 case AV_CODEC_ID_GSM:
2247 sc->samples_per_frame = 160;
2248 sc->bytes_per_frame = 33;
2254 bits_per_sample = av_get_bits_per_sample(st->codecpar->codec_id);
2255 if (bits_per_sample && (bits_per_sample >> 3) * (uint64_t)st->codecpar->channels <= INT_MAX) {
2256 st->codecpar->bits_per_coded_sample = bits_per_sample;
2257 sc->sample_size = (bits_per_sample >> 3) * st->codecpar->channels;
2261 static void mov_parse_stsd_subtitle(MOVContext *c, AVIOContext *pb,
2262 AVStream *st, MOVStreamContext *sc,
2265 // ttxt stsd contains display flags, justification, background
2266 // color, fonts, and default styles, so fake an atom to read it
2267 MOVAtom fake_atom = { .size = size };
2268 // mp4s contains a regular esds atom
2269 if (st->codecpar->codec_tag != AV_RL32("mp4s"))
2270 mov_read_glbl(c, pb, fake_atom);
2271 st->codecpar->width = sc->width;
2272 st->codecpar->height = sc->height;
2275 static uint32_t yuv_to_rgba(uint32_t ycbcr)
2280 y = (ycbcr >> 16) & 0xFF;
2281 cr = (ycbcr >> 8) & 0xFF;
2284 b = av_clip_uint8((1164 * (y - 16) + 2018 * (cb - 128)) / 1000);
2285 g = av_clip_uint8((1164 * (y - 16) - 813 * (cr - 128) - 391 * (cb - 128)) / 1000);
2286 r = av_clip_uint8((1164 * (y - 16) + 1596 * (cr - 128) ) / 1000);
2288 return (r << 16) | (g << 8) | b;
2291 static int mov_rewrite_dvd_sub_extradata(AVStream *st)
2293 char buf[256] = {0};
2294 uint8_t *src = st->codecpar->extradata;
2297 if (st->codecpar->extradata_size != 64)
2300 if (st->codecpar->width > 0 && st->codecpar->height > 0)
2301 snprintf(buf, sizeof(buf), "size: %dx%d\n",
2302 st->codecpar->width, st->codecpar->height);
2303 av_strlcat(buf, "palette: ", sizeof(buf));
2305 for (i = 0; i < 16; i++) {
2306 uint32_t yuv = AV_RB32(src + i * 4);
2307 uint32_t rgba = yuv_to_rgba(yuv);
2309 av_strlcatf(buf, sizeof(buf), "%06"PRIx32"%s", rgba, i != 15 ? ", " : "");
2312 if (av_strlcat(buf, "\n", sizeof(buf)) >= sizeof(buf))
2315 ret = ff_alloc_extradata(st->codecpar, strlen(buf));
2318 memcpy(st->codecpar->extradata, buf, st->codecpar->extradata_size);
2323 static int mov_parse_stsd_data(MOVContext *c, AVIOContext *pb,
2324 AVStream *st, MOVStreamContext *sc,
2329 if (st->codecpar->codec_tag == MKTAG('t','m','c','d')) {
2330 if ((int)size != size)
2331 return AVERROR(ENOMEM);
2333 ret = ff_get_extradata(c->fc, st->codecpar, pb, size);
2337 MOVStreamContext *tmcd_ctx = st->priv_data;
2339 val = AV_RB32(st->codecpar->extradata + 4);
2340 tmcd_ctx->tmcd_flags = val;
2341 st->avg_frame_rate.num = AV_RB32(st->codecpar->extradata + 8); /* timescale */
2342 st->avg_frame_rate.den = AV_RB32(st->codecpar->extradata + 12); /* frameDuration */
2343 #if FF_API_LAVF_AVCTX
2344 FF_DISABLE_DEPRECATION_WARNINGS
2345 st->codec->time_base = av_inv_q(st->avg_frame_rate);
2346 FF_ENABLE_DEPRECATION_WARNINGS
2349 uint32_t len = AV_RB32(st->codecpar->extradata + 18); /* name atom length */
2350 uint32_t format = AV_RB32(st->codecpar->extradata + 22);
2351 if (format == AV_RB32("name") && (int64_t)size >= (int64_t)len + 18) {
2352 uint16_t str_size = AV_RB16(st->codecpar->extradata + 26); /* string length */
2353 if (str_size > 0 && size >= (int)str_size + 30 &&
2354 st->codecpar->extradata[30] /* Don't add empty string */) {
2355 char *reel_name = av_malloc(str_size + 1);
2357 return AVERROR(ENOMEM);
2358 memcpy(reel_name, st->codecpar->extradata + 30, str_size);
2359 reel_name[str_size] = 0; /* Add null terminator */
2360 av_dict_set(&st->metadata, "reel_name", reel_name,
2361 AV_DICT_DONT_STRDUP_VAL);
2367 /* other codec type, just skip (rtp, mp4s ...) */
2368 avio_skip(pb, size);
2373 static int mov_finalize_stsd_codec(MOVContext *c, AVIOContext *pb,
2374 AVStream *st, MOVStreamContext *sc)
2376 if (st->codecpar->codec_type == AVMEDIA_TYPE_AUDIO &&
2377 !st->codecpar->sample_rate && sc->time_scale > 1)
2378 st->codecpar->sample_rate = sc->time_scale;
2380 /* special codec parameters handling */
2381 switch (st->codecpar->codec_id) {
2382 #if CONFIG_DV_DEMUXER
2383 case AV_CODEC_ID_DVAUDIO:
2384 c->dv_fctx = avformat_alloc_context();
2386 av_log(c->fc, AV_LOG_ERROR, "dv demux context alloc error\n");
2387 return AVERROR(ENOMEM);
2389 c->dv_demux = avpriv_dv_init_demux(c->dv_fctx);
2391 av_log(c->fc, AV_LOG_ERROR, "dv demux context init error\n");
2392 return AVERROR(ENOMEM);
2394 sc->dv_audio_container = 1;
2395 st->codecpar->codec_id = AV_CODEC_ID_PCM_S16LE;
2398 /* no ifdef since parameters are always those */
2399 case AV_CODEC_ID_QCELP:
2400 st->codecpar->channels = 1;
2401 // force sample rate for qcelp when not stored in mov
2402 if (st->codecpar->codec_tag != MKTAG('Q','c','l','p'))
2403 st->codecpar->sample_rate = 8000;
2404 // FIXME: Why is the following needed for some files?
2405 sc->samples_per_frame = 160;
2406 if (!sc->bytes_per_frame)
2407 sc->bytes_per_frame = 35;
2409 case AV_CODEC_ID_AMR_NB:
2410 st->codecpar->channels = 1;
2411 /* force sample rate for amr, stsd in 3gp does not store sample rate */
2412 st->codecpar->sample_rate = 8000;
2414 case AV_CODEC_ID_AMR_WB:
2415 st->codecpar->channels = 1;
2416 st->codecpar->sample_rate = 16000;
2418 case AV_CODEC_ID_MP2:
2419 case AV_CODEC_ID_MP3:
2420 /* force type after stsd for m1a hdlr */
2421 st->codecpar->codec_type = AVMEDIA_TYPE_AUDIO;
2423 case AV_CODEC_ID_GSM:
2424 case AV_CODEC_ID_ADPCM_MS:
2425 case AV_CODEC_ID_ADPCM_IMA_WAV:
2426 case AV_CODEC_ID_ILBC:
2427 case AV_CODEC_ID_MACE3:
2428 case AV_CODEC_ID_MACE6:
2429 case AV_CODEC_ID_QDM2:
2430 st->codecpar->block_align = sc->bytes_per_frame;
2432 case AV_CODEC_ID_ALAC:
2433 if (st->codecpar->extradata_size == 36) {
2434 st->codecpar->channels = AV_RB8 (st->codecpar->extradata + 21);
2435 st->codecpar->sample_rate = AV_RB32(st->codecpar->extradata + 32);
2438 case AV_CODEC_ID_AC3:
2439 case AV_CODEC_ID_EAC3:
2440 case AV_CODEC_ID_MPEG1VIDEO:
2441 case AV_CODEC_ID_VC1:
2442 case AV_CODEC_ID_VP8:
2443 case AV_CODEC_ID_VP9:
2444 st->need_parsing = AVSTREAM_PARSE_FULL;
2446 case AV_CODEC_ID_AV1:
2447 st->need_parsing = AVSTREAM_PARSE_HEADERS;
2455 static int mov_skip_multiple_stsd(MOVContext *c, AVIOContext *pb,
2456 int codec_tag, int format,
2459 int video_codec_id = ff_codec_get_id(ff_codec_movvideo_tags, format);
2462 (codec_tag != format &&
2463 // AVID 1:1 samples with differing data format and codec tag exist
2464 (codec_tag != AV_RL32("AV1x") || format != AV_RL32("AVup")) &&
2465 // prores is allowed to have differing data format and codec tag
2466 codec_tag != AV_RL32("apcn") && codec_tag != AV_RL32("apch") &&
2468 codec_tag != AV_RL32("dvpp") && codec_tag != AV_RL32("dvcp") &&
2469 (c->fc->video_codec_id ? video_codec_id != c->fc->video_codec_id
2470 : codec_tag != MKTAG('j','p','e','g')))) {
2471 /* Multiple fourcc, we skip JPEG. This is not correct, we should
2472 * export it as a separate AVStream but this needs a few changes
2473 * in the MOV demuxer, patch welcome. */
2475 av_log(c->fc, AV_LOG_WARNING, "multiple fourcc not supported\n");
2476 avio_skip(pb, size);
2483 int ff_mov_read_stsd_entries(MOVContext *c, AVIOContext *pb, int entries)
2486 MOVStreamContext *sc;
2487 int pseudo_stream_id;
2489 av_assert0 (c->fc->nb_streams >= 1);
2490 st = c->fc->streams[c->fc->nb_streams-1];
2493 for (pseudo_stream_id = 0;
2494 pseudo_stream_id < entries && !pb->eof_reached;
2495 pseudo_stream_id++) {
2496 //Parsing Sample description table
2498 int ret, dref_id = 1;
2499 MOVAtom a = { AV_RL32("stsd") };
2500 int64_t start_pos = avio_tell(pb);
2501 int64_t size = avio_rb32(pb); /* size */
2502 uint32_t format = avio_rl32(pb); /* data format */
2505 avio_rb32(pb); /* reserved */
2506 avio_rb16(pb); /* reserved */
2507 dref_id = avio_rb16(pb);
2508 } else if (size <= 7) {
2509 av_log(c->fc, AV_LOG_ERROR,
2510 "invalid size %"PRId64" in stsd\n", size);
2511 return AVERROR_INVALIDDATA;
2514 if (mov_skip_multiple_stsd(c, pb, st->codecpar->codec_tag, format,
2515 size - (avio_tell(pb) - start_pos))) {
2520 sc->pseudo_stream_id = st->codecpar->codec_tag ? -1 : pseudo_stream_id;
2521 sc->dref_id= dref_id;
2522 sc->format = format;
2524 id = mov_codec_id(st, format);
2526 av_log(c->fc, AV_LOG_TRACE,
2527 "size=%"PRId64" 4CC=%s codec_type=%d\n", size,
2528 av_fourcc2str(format), st->codecpar->codec_type);
2530 st->codecpar->codec_id = id;
2531 if (st->codecpar->codec_type==AVMEDIA_TYPE_VIDEO) {
2532 mov_parse_stsd_video(c, pb, st, sc);
2533 } else if (st->codecpar->codec_type==AVMEDIA_TYPE_AUDIO) {
2534 mov_parse_stsd_audio(c, pb, st, sc);
2535 if (st->codecpar->sample_rate < 0) {
2536 av_log(c->fc, AV_LOG_ERROR, "Invalid sample rate %d\n", st->codecpar->sample_rate);
2537 return AVERROR_INVALIDDATA;
2539 } else if (st->codecpar->codec_type==AVMEDIA_TYPE_SUBTITLE){
2540 mov_parse_stsd_subtitle(c, pb, st, sc,
2541 size - (avio_tell(pb) - start_pos));
2543 ret = mov_parse_stsd_data(c, pb, st, sc,
2544 size - (avio_tell(pb) - start_pos));
2548 /* this will read extra atoms at the end (wave, alac, damr, avcC, hvcC, SMI ...) */
2549 a.size = size - (avio_tell(pb) - start_pos);
2551 if ((ret = mov_read_default(c, pb, a)) < 0)
2553 } else if (a.size > 0)
2554 avio_skip(pb, a.size);
2556 if (sc->extradata && st->codecpar->extradata) {
2557 int extra_size = st->codecpar->extradata_size;
2559 /* Move the current stream extradata to the stream context one. */
2560 sc->extradata_size[pseudo_stream_id] = extra_size;
2561 sc->extradata[pseudo_stream_id] = st->codecpar->extradata;
2562 st->codecpar->extradata = NULL;
2563 st->codecpar->extradata_size = 0;
2568 if (pb->eof_reached) {
2569 av_log(c->fc, AV_LOG_WARNING, "reached eof, corrupted STSD atom\n");
2576 static int mov_read_stsd(MOVContext *c, AVIOContext *pb, MOVAtom atom)
2579 MOVStreamContext *sc;
2582 if (c->fc->nb_streams < 1)
2584 st = c->fc->streams[c->fc->nb_streams - 1];
2587 sc->stsd_version = avio_r8(pb);
2588 avio_rb24(pb); /* flags */
2589 entries = avio_rb32(pb);
2591 /* Each entry contains a size (4 bytes) and format (4 bytes). */
2592 if (entries <= 0 || entries > atom.size / 8 || entries > 1024) {
2593 av_log(c->fc, AV_LOG_ERROR, "invalid STSD entries %d\n", entries);
2594 return AVERROR_INVALIDDATA;
2597 if (sc->extradata) {
2598 av_log(c->fc, AV_LOG_ERROR,
2599 "Duplicate stsd found in this track.\n");
2600 return AVERROR_INVALIDDATA;
2603 /* Prepare space for hosting multiple extradata. */
2604 sc->extradata = av_mallocz_array(entries, sizeof(*sc->extradata));
2606 return AVERROR(ENOMEM);
2608 sc->extradata_size = av_mallocz_array(entries, sizeof(*sc->extradata_size));
2609 if (!sc->extradata_size) {
2610 ret = AVERROR(ENOMEM);
2614 ret = ff_mov_read_stsd_entries(c, pb, entries);
2618 /* Restore back the primary extradata. */
2619 av_freep(&st->codecpar->extradata);
2620 st->codecpar->extradata_size = sc->extradata_size[0];
2621 if (sc->extradata_size[0]) {
2622 st->codecpar->extradata = av_mallocz(sc->extradata_size[0] + AV_INPUT_BUFFER_PADDING_SIZE);
2623 if (!st->codecpar->extradata)
2624 return AVERROR(ENOMEM);
2625 memcpy(st->codecpar->extradata, sc->extradata[0], sc->extradata_size[0]);
2628 return mov_finalize_stsd_codec(c, pb, st, sc);
2630 if (sc->extradata) {
2632 for (j = 0; j < sc->stsd_count; j++)
2633 av_freep(&sc->extradata[j]);
2636 av_freep(&sc->extradata);
2637 av_freep(&sc->extradata_size);
2641 static int mov_read_stsc(MOVContext *c, AVIOContext *pb, MOVAtom atom)
2644 MOVStreamContext *sc;
2645 unsigned int i, entries;
2647 if (c->fc->nb_streams < 1)
2649 st = c->fc->streams[c->fc->nb_streams-1];
2652 avio_r8(pb); /* version */
2653 avio_rb24(pb); /* flags */
2655 entries = avio_rb32(pb);
2656 if ((uint64_t)entries * 12 + 4 > atom.size)
2657 return AVERROR_INVALIDDATA;
2659 av_log(c->fc, AV_LOG_TRACE, "track[%u].stsc.entries = %u\n", c->fc->nb_streams - 1, entries);
2663 if (sc->stsc_data) {
2664 av_log(c->fc, AV_LOG_WARNING, "Ignoring duplicated STSC atom\n");
2667 av_free(sc->stsc_data);
2669 sc->stsc_data = av_malloc_array(entries, sizeof(*sc->stsc_data));
2671 return AVERROR(ENOMEM);
2673 for (i = 0; i < entries && !pb->eof_reached; i++) {
2674 sc->stsc_data[i].first = avio_rb32(pb);
2675 sc->stsc_data[i].count = avio_rb32(pb);
2676 sc->stsc_data[i].id = avio_rb32(pb);
2680 for (i = sc->stsc_count - 1; i < UINT_MAX; i--) {
2681 int64_t first_min = i + 1;
2682 if ((i+1 < sc->stsc_count && sc->stsc_data[i].first >= sc->stsc_data[i+1].first) ||
2683 (i > 0 && sc->stsc_data[i].first <= sc->stsc_data[i-1].first) ||
2684 sc->stsc_data[i].first < first_min ||
2685 sc->stsc_data[i].count < 1 ||
2686 sc->stsc_data[i].id < 1) {
2687 av_log(c->fc, AV_LOG_WARNING, "STSC entry %d is invalid (first=%d count=%d id=%d)\n", i, sc->stsc_data[i].first, sc->stsc_data[i].count, sc->stsc_data[i].id);
2688 if (i+1 >= sc->stsc_count) {
2689 if (sc->stsc_data[i].count == 0 && i > 0) {
2693 sc->stsc_data[i].first = FFMAX(sc->stsc_data[i].first, first_min);
2694 if (i > 0 && sc->stsc_data[i].first <= sc->stsc_data[i-1].first)
2695 sc->stsc_data[i].first = FFMIN(sc->stsc_data[i-1].first + 1LL, INT_MAX);
2696 sc->stsc_data[i].count = FFMAX(sc->stsc_data[i].count, 1);
2697 sc->stsc_data[i].id = FFMAX(sc->stsc_data[i].id, 1);
2700 av_assert0(sc->stsc_data[i+1].first >= 2);
2701 // We replace this entry by the next valid
2702 sc->stsc_data[i].first = sc->stsc_data[i+1].first - 1;
2703 sc->stsc_data[i].count = sc->stsc_data[i+1].count;
2704 sc->stsc_data[i].id = sc->stsc_data[i+1].id;
2708 if (pb->eof_reached) {
2709 av_log(c->fc, AV_LOG_WARNING, "reached eof, corrupted STSC atom\n");
2716 static inline int mov_stsc_index_valid(unsigned int index, unsigned int count)
2718 return index < count - 1;
2721 /* Compute the samples value for the stsc entry at the given index. */
2722 static inline int64_t mov_get_stsc_samples(MOVStreamContext *sc, unsigned int index)
2726 if (mov_stsc_index_valid(index, sc->stsc_count))
2727 chunk_count = sc->stsc_data[index + 1].first - sc->stsc_data[index].first;
2729 // Validation for stsc / stco happens earlier in mov_read_stsc + mov_read_trak.
2730 av_assert0(sc->stsc_data[index].first <= sc->chunk_count);
2731 chunk_count = sc->chunk_count - (sc->stsc_data[index].first - 1);
2734 return sc->stsc_data[index].count * (int64_t)chunk_count;
2737 static int mov_read_stps(MOVContext *c, AVIOContext *pb, MOVAtom atom)
2740 MOVStreamContext *sc;
2741 unsigned i, entries;
2743 if (c->fc->nb_streams < 1)
2745 st = c->fc->streams[c->fc->nb_streams-1];
2748 avio_rb32(pb); // version + flags
2750 entries = avio_rb32(pb);
2752 av_log(c->fc, AV_LOG_WARNING, "Duplicated STPS atom\n");
2753 av_free(sc->stps_data);
2755 sc->stps_data = av_malloc_array(entries, sizeof(*sc->stps_data));
2757 return AVERROR(ENOMEM);
2759 for (i = 0; i < entries && !pb->eof_reached; i++) {
2760 sc->stps_data[i] = avio_rb32(pb);
2765 if (pb->eof_reached) {
2766 av_log(c->fc, AV_LOG_WARNING, "reached eof, corrupted STPS atom\n");
2773 static int mov_read_stss(MOVContext *c, AVIOContext *pb, MOVAtom atom)
2776 MOVStreamContext *sc;
2777 unsigned int i, entries;
2779 if (c->fc->nb_streams < 1)
2781 st = c->fc->streams[c->fc->nb_streams-1];
2784 avio_r8(pb); /* version */
2785 avio_rb24(pb); /* flags */
2787 entries = avio_rb32(pb);
2789 av_log(c->fc, AV_LOG_TRACE, "keyframe_count = %u\n", entries);
2792 sc->keyframe_absent = 1;
2793 if (!st->need_parsing && st->codecpar->codec_type == AVMEDIA_TYPE_VIDEO)
2794 st->need_parsing = AVSTREAM_PARSE_HEADERS;
2798 av_log(c->fc, AV_LOG_WARNING, "Duplicated STSS atom\n");
2799 if (entries >= UINT_MAX / sizeof(int))
2800 return AVERROR_INVALIDDATA;
2801 av_freep(&sc->keyframes);
2802 sc->keyframe_count = 0;
2803 sc->keyframes = av_malloc_array(entries, sizeof(*sc->keyframes));
2805 return AVERROR(ENOMEM);
2807 for (i = 0; i < entries && !pb->eof_reached; i++) {
2808 sc->keyframes[i] = avio_rb32(pb);
2811 sc->keyframe_count = i;
2813 if (pb->eof_reached) {
2814 av_log(c->fc, AV_LOG_WARNING, "reached eof, corrupted STSS atom\n");
2821 static int mov_read_stsz(MOVContext *c, AVIOContext *pb, MOVAtom atom)
2824 MOVStreamContext *sc;
2825 unsigned int i, entries, sample_size, field_size, num_bytes;
2830 if (c->fc->nb_streams < 1)
2832 st = c->fc->streams[c->fc->nb_streams-1];
2835 avio_r8(pb); /* version */
2836 avio_rb24(pb); /* flags */
2838 if (atom.type == MKTAG('s','t','s','z')) {
2839 sample_size = avio_rb32(pb);
2840 if (!sc->sample_size) /* do not overwrite value computed in stsd */
2841 sc->sample_size = sample_size;
2842 sc->stsz_sample_size = sample_size;
2846 avio_rb24(pb); /* reserved */
2847 field_size = avio_r8(pb);
2849 entries = avio_rb32(pb);
2851 av_log(c->fc, AV_LOG_TRACE, "sample_size = %u sample_count = %u\n", sc->sample_size, entries);
2853 sc->sample_count = entries;
2857 if (field_size != 4 && field_size != 8 && field_size != 16 && field_size != 32) {
2858 av_log(c->fc, AV_LOG_ERROR, "Invalid sample field size %u\n", field_size);
2859 return AVERROR_INVALIDDATA;
2864 if (entries >= (UINT_MAX - 4) / field_size)
2865 return AVERROR_INVALIDDATA;
2866 if (sc->sample_sizes)
2867 av_log(c->fc, AV_LOG_WARNING, "Duplicated STSZ atom\n");
2868 av_free(sc->sample_sizes);
2869 sc->sample_count = 0;
2870 sc->sample_sizes = av_malloc_array(entries, sizeof(*sc->sample_sizes));
2871 if (!sc->sample_sizes)
2872 return AVERROR(ENOMEM);
2874 num_bytes = (entries*field_size+4)>>3;
2876 buf = av_malloc(num_bytes+AV_INPUT_BUFFER_PADDING_SIZE);
2878 av_freep(&sc->sample_sizes);
2879 return AVERROR(ENOMEM);
2882 ret = ffio_read_size(pb, buf, num_bytes);
2884 av_freep(&sc->sample_sizes);
2886 av_log(c->fc, AV_LOG_WARNING, "STSZ atom truncated\n");
2890 init_get_bits(&gb, buf, 8*num_bytes);
2892 for (i = 0; i < entries && !pb->eof_reached; i++) {
2893 sc->sample_sizes[i] = get_bits_long(&gb, field_size);
2894 if (sc->sample_sizes[i] < 0) {
2896 av_log(c->fc, AV_LOG_ERROR, "Invalid sample size %d\n", sc->sample_sizes[i]);
2897 return AVERROR_INVALIDDATA;
2899 sc->data_size += sc->sample_sizes[i];
2902 sc->sample_count = i;
2906 if (pb->eof_reached) {
2907 av_log(c->fc, AV_LOG_WARNING, "reached eof, corrupted STSZ atom\n");
2914 static int mov_read_stts(MOVContext *c, AVIOContext *pb, MOVAtom atom)
2917 MOVStreamContext *sc;
2918 unsigned int i, entries, alloc_size = 0;
2919 int64_t duration = 0;
2920 int64_t total_sample_count = 0;
2922 if (c->fc->nb_streams < 1)
2924 st = c->fc->streams[c->fc->nb_streams-1];
2927 avio_r8(pb); /* version */
2928 avio_rb24(pb); /* flags */
2929 entries = avio_rb32(pb);
2931 av_log(c->fc, AV_LOG_TRACE, "track[%u].stts.entries = %u\n",
2932 c->fc->nb_streams-1, entries);
2935 av_log(c->fc, AV_LOG_WARNING, "Duplicated STTS atom\n");
2936 av_freep(&sc->stts_data);
2938 if (entries >= INT_MAX / sizeof(*sc->stts_data))
2939 return AVERROR(ENOMEM);
2941 for (i = 0; i < entries && !pb->eof_reached; i++) {
2942 int sample_duration;
2943 unsigned int sample_count;
2944 unsigned int min_entries = FFMIN(FFMAX(i + 1, 1024 * 1024), entries);
2945 MOVStts *stts_data = av_fast_realloc(sc->stts_data, &alloc_size,
2946 min_entries * sizeof(*sc->stts_data));
2948 av_freep(&sc->stts_data);
2950 return AVERROR(ENOMEM);
2952 sc->stts_count = min_entries;
2953 sc->stts_data = stts_data;
2955 sample_count = avio_rb32(pb);
2956 sample_duration = avio_rb32(pb);
2958 sc->stts_data[i].count= sample_count;
2959 sc->stts_data[i].duration= sample_duration;
2961 av_log(c->fc, AV_LOG_TRACE, "sample_count=%d, sample_duration=%d\n",
2962 sample_count, sample_duration);
2964 duration+=(int64_t)sample_duration*(uint64_t)sample_count;
2965 total_sample_count+=sample_count;
2971 duration <= INT64_MAX - sc->duration_for_fps &&
2972 total_sample_count <= INT_MAX - sc->nb_frames_for_fps) {
2973 sc->duration_for_fps += duration;
2974 sc->nb_frames_for_fps += total_sample_count;
2977 if (pb->eof_reached) {
2978 av_log(c->fc, AV_LOG_WARNING, "reached eof, corrupted STTS atom\n");
2982 st->nb_frames= total_sample_count;
2984 st->duration= FFMIN(st->duration, duration);
2985 sc->track_end = duration;
2989 static int mov_read_sdtp(MOVContext *c, AVIOContext *pb, MOVAtom atom)
2992 MOVStreamContext *sc;
2995 if (c->fc->nb_streams < 1)
2997 st = c->fc->streams[c->fc->nb_streams - 1];
3000 avio_r8(pb); /* version */
3001 avio_rb24(pb); /* flags */
3002 entries = atom.size - 4;
3004 av_log(c->fc, AV_LOG_TRACE, "track[%u].sdtp.entries = %" PRId64 "\n",
3005 c->fc->nb_streams - 1, entries);
3008 av_log(c->fc, AV_LOG_WARNING, "Duplicated SDTP atom\n");
3009 av_freep(&sc->sdtp_data);
3012 sc->sdtp_data = av_malloc(entries);
3014 return AVERROR(ENOMEM);
3016 for (i = 0; i < entries && !pb->eof_reached; i++)
3017 sc->sdtp_data[i] = avio_r8(pb);
3023 static void mov_update_dts_shift(MOVStreamContext *sc, int duration, void *logctx)
3026 if (duration == INT_MIN) {
3027 av_log(logctx, AV_LOG_WARNING, "mov_update_dts_shift(): dts_shift set to %d\n", INT_MAX);
3030 sc->dts_shift = FFMAX(sc->dts_shift, -duration);
3034 static int mov_read_ctts(MOVContext *c, AVIOContext *pb, MOVAtom atom)
3037 MOVStreamContext *sc;
3038 unsigned int i, entries, ctts_count = 0;
3040 if (c->fc->nb_streams < 1)
3042 st = c->fc->streams[c->fc->nb_streams-1];
3045 avio_r8(pb); /* version */
3046 avio_rb24(pb); /* flags */
3047 entries = avio_rb32(pb);
3049 av_log(c->fc, AV_LOG_TRACE, "track[%u].ctts.entries = %u\n", c->fc->nb_streams - 1, entries);
3053 if (entries >= UINT_MAX / sizeof(*sc->ctts_data))
3054 return AVERROR_INVALIDDATA;
3055 av_freep(&sc->ctts_data);
3056 sc->ctts_data = av_fast_realloc(NULL, &sc->ctts_allocated_size, entries * sizeof(*sc->ctts_data));
3058 return AVERROR(ENOMEM);
3060 for (i = 0; i < entries && !pb->eof_reached; i++) {
3061 int count = avio_rb32(pb);
3062 int duration = avio_rb32(pb);
3065 av_log(c->fc, AV_LOG_TRACE,
3066 "ignoring CTTS entry with count=%d duration=%d\n",
3071 add_ctts_entry(&sc->ctts_data, &ctts_count, &sc->ctts_allocated_size,
3074 av_log(c->fc, AV_LOG_TRACE, "count=%d, duration=%d\n",
3077 if (FFNABS(duration) < -(1<<28) && i+2<entries) {
3078 av_log(c->fc, AV_LOG_WARNING, "CTTS invalid\n");
3079 av_freep(&sc->ctts_data);
3085 mov_update_dts_shift(sc, duration, c->fc);
3088 sc->ctts_count = ctts_count;
3090 if (pb->eof_reached) {
3091 av_log(c->fc, AV_LOG_WARNING, "reached eof, corrupted CTTS atom\n");
3095 av_log(c->fc, AV_LOG_TRACE, "dts shift %d\n", sc->dts_shift);
3100 static int mov_read_sbgp(MOVContext *c, AVIOContext *pb, MOVAtom atom)
3103 MOVStreamContext *sc;
3104 unsigned int i, entries;
3106 uint32_t grouping_type;
3108 if (c->fc->nb_streams < 1)
3110 st = c->fc->streams[c->fc->nb_streams-1];
3113 version = avio_r8(pb); /* version */
3114 avio_rb24(pb); /* flags */
3115 grouping_type = avio_rl32(pb);
3116 if (grouping_type != MKTAG( 'r','a','p',' '))
3117 return 0; /* only support 'rap ' grouping */
3119 avio_rb32(pb); /* grouping_type_parameter */
3121 entries = avio_rb32(pb);
3125 av_log(c->fc, AV_LOG_WARNING, "Duplicated SBGP atom\n");
3126 av_free(sc->rap_group);
3127 sc->rap_group_count = 0;
3128 sc->rap_group = av_malloc_array(entries, sizeof(*sc->rap_group));
3130 return AVERROR(ENOMEM);
3132 for (i = 0; i < entries && !pb->eof_reached; i++) {
3133 sc->rap_group[i].count = avio_rb32(pb); /* sample_count */
3134 sc->rap_group[i].index = avio_rb32(pb); /* group_description_index */
3137 sc->rap_group_count = i;
3139 if (pb->eof_reached) {
3140 av_log(c->fc, AV_LOG_WARNING, "reached eof, corrupted SBGP atom\n");
3148 * Get ith edit list entry (media time, duration).
3150 static int get_edit_list_entry(MOVContext *mov,
3151 const MOVStreamContext *msc,
3152 unsigned int edit_list_index,
3153 int64_t *edit_list_media_time,
3154 int64_t *edit_list_duration,
3155 int64_t global_timescale)
3157 if (edit_list_index == msc->elst_count) {
3160 *edit_list_media_time = msc->elst_data[edit_list_index].time;
3161 *edit_list_duration = msc->elst_data[edit_list_index].duration;
3163 /* duration is in global timescale units;convert to msc timescale */
3164 if (global_timescale == 0) {
3165 avpriv_request_sample(mov->fc, "Support for mvhd.timescale = 0 with editlists");
3168 *edit_list_duration = av_rescale(*edit_list_duration, msc->time_scale,
3174 * Find the closest previous frame to the timestamp_pts, in e_old index
3175 * entries. Searching for just any frame / just key frames can be controlled by
3176 * last argument 'flag'.
3177 * Note that if ctts_data is not NULL, we will always search for a key frame
3178 * irrespective of the value of 'flag'. If we don't find any keyframe, we will
3179 * return the first frame of the video.
3181 * Here the timestamp_pts is considered to be a presentation timestamp and
3182 * the timestamp of index entries are considered to be decoding timestamps.
3184 * Returns 0 if successful in finding a frame, else returns -1.
3185 * Places the found index corresponding output arg.
3187 * If ctts_old is not NULL, then refines the searched entry by searching
3188 * backwards from the found timestamp, to find the frame with correct PTS.
3190 * Places the found ctts_index and ctts_sample in corresponding output args.
3192 static int find_prev_closest_index(AVStream *st,
3193 AVIndexEntry *e_old,
3197 int64_t timestamp_pts,
3200 int64_t* ctts_index,
3201 int64_t* ctts_sample)
3203 MOVStreamContext *msc = st->priv_data;
3204 AVIndexEntry *e_keep = st->internal->index_entries;
3205 int nb_keep = st->internal->nb_index_entries;
3207 int64_t index_ctts_count;
3211 // If dts_shift > 0, then all the index timestamps will have to be offset by
3212 // at least dts_shift amount to obtain PTS.
3213 // Hence we decrement the searched timestamp_pts by dts_shift to find the closest index element.
3214 if (msc->dts_shift > 0) {
3215 timestamp_pts -= msc->dts_shift;
3218 st->internal->index_entries = e_old;
3219 st->internal->nb_index_entries = nb_old;
3220 *index = av_index_search_timestamp(st, timestamp_pts, flag | AVSEEK_FLAG_BACKWARD);
3222 // Keep going backwards in the index entries until the timestamp is the same.
3224 for (i = *index; i > 0 && e_old[i].timestamp == e_old[i - 1].timestamp;
3226 if ((flag & AVSEEK_FLAG_ANY) ||
3227 (e_old[i - 1].flags & AVINDEX_KEYFRAME)) {
3233 // If we have CTTS then refine the search, by searching backwards over PTS
3234 // computed by adding corresponding CTTS durations to index timestamps.
3235 if (ctts_data && *index >= 0) {
3236 av_assert0(ctts_index);
3237 av_assert0(ctts_sample);
3238 // Find out the ctts_index for the found frame.
3241 for (index_ctts_count = 0; index_ctts_count < *index; index_ctts_count++) {
3242 if (*ctts_index < ctts_count) {
3244 if (ctts_data[*ctts_index].count == *ctts_sample) {
3251 while (*index >= 0 && (*ctts_index) >= 0 && (*ctts_index) < ctts_count) {
3252 // Find a "key frame" with PTS <= timestamp_pts (So that we can decode B-frames correctly).
3253 // No need to add dts_shift to the timestamp here becase timestamp_pts has already been
3254 // compensated by dts_shift above.
3255 if ((e_old[*index].timestamp + ctts_data[*ctts_index].duration) <= timestamp_pts &&
3256 (e_old[*index].flags & AVINDEX_KEYFRAME)) {
3261 if (*ctts_sample == 0) {
3263 if (*ctts_index >= 0)
3264 *ctts_sample = ctts_data[*ctts_index].count - 1;
3271 /* restore AVStream state*/
3272 st->internal->index_entries = e_keep;
3273 st->internal->nb_index_entries = nb_keep;
3274 return *index >= 0 ? 0 : -1;
3278 * Add index entry with the given values, to the end of st->internal->index_entries.
3279 * Returns the new size st->internal->index_entries if successful, else returns -1.
3281 * This function is similar to ff_add_index_entry in libavformat/utils.c
3282 * except that here we are always unconditionally adding an index entry to
3283 * the end, instead of searching the entries list and skipping the add if
3284 * there is an existing entry with the same timestamp.
3285 * This is needed because the mov_fix_index calls this func with the same
3286 * unincremented timestamp for successive discarded frames.
3288 static int64_t add_index_entry(AVStream *st, int64_t pos, int64_t timestamp,
3289 int size, int distance, int flags)
3291 AVIndexEntry *entries, *ie;
3293 const size_t min_size_needed = (st->internal->nb_index_entries + 1) * sizeof(AVIndexEntry);
3295 // Double the allocation each time, to lower memory fragmentation.
3296 // Another difference from ff_add_index_entry function.
3297 const size_t requested_size =
3298 min_size_needed > st->internal->index_entries_allocated_size ?
3299 FFMAX(min_size_needed, 2 * st->internal->index_entries_allocated_size) :
3302 if (st->internal->nb_index_entries + 1U >= UINT_MAX / sizeof(AVIndexEntry))
3305 entries = av_fast_realloc(st->internal->index_entries,
3306 &st->internal->index_entries_allocated_size,
3311 st->internal->index_entries= entries;
3313 index= st->internal->nb_index_entries++;
3314 ie= &entries[index];
3317 ie->timestamp = timestamp;
3318 ie->min_distance= distance;
3325 * Rewrite timestamps of index entries in the range [end_index - frame_duration_buffer_size, end_index)
3326 * by subtracting end_ts successively by the amounts given in frame_duration_buffer.
3328 static void fix_index_entry_timestamps(AVStream* st, int end_index, int64_t end_ts,
3329 int64_t* frame_duration_buffer,
3330 int frame_duration_buffer_size) {
3332 av_assert0(end_index >= 0 && end_index <= st->internal->nb_index_entries);
3333 for (i = 0; i < frame_duration_buffer_size; i++) {
3334 end_ts -= frame_duration_buffer[frame_duration_buffer_size - 1 - i];
3335 st->internal->index_entries[end_index - 1 - i].timestamp = end_ts;
3340 * Append a new ctts entry to ctts_data.
3341 * Returns the new ctts_count if successful, else returns -1.
3343 static int64_t add_ctts_entry(MOVStts** ctts_data, unsigned int* ctts_count, unsigned int* allocated_size,
3344 int count, int duration)
3346 MOVStts *ctts_buf_new;
3347 const size_t min_size_needed = (*ctts_count + 1) * sizeof(MOVStts);
3348 const size_t requested_size =
3349 min_size_needed > *allocated_size ?
3350 FFMAX(min_size_needed, 2 * (*allocated_size)) :
3353 if ((unsigned)(*ctts_count) >= UINT_MAX / sizeof(MOVStts) - 1)
3356 ctts_buf_new = av_fast_realloc(*ctts_data, allocated_size, requested_size);
3361 *ctts_data = ctts_buf_new;
3363 ctts_buf_new[*ctts_count].count = count;
3364 ctts_buf_new[*ctts_count].duration = duration;
3366 *ctts_count = (*ctts_count) + 1;
3370 #define MAX_REORDER_DELAY 16
3371 static void mov_estimate_video_delay(MOVContext *c, AVStream* st)
3373 MOVStreamContext *msc = st->priv_data;
3376 int ctts_sample = 0;
3377 int64_t pts_buf[MAX_REORDER_DELAY + 1]; // Circular buffer to sort pts.
3379 int j, r, num_swaps;
3381 for (j = 0; j < MAX_REORDER_DELAY + 1; j++)
3382 pts_buf[j] = INT64_MIN;
3384 if (st->codecpar->video_delay <= 0 && msc->ctts_data &&
3385 st->codecpar->codec_id == AV_CODEC_ID_H264) {
3386 st->codecpar->video_delay = 0;
3387 for (ind = 0; ind < st->internal->nb_index_entries && ctts_ind < msc->ctts_count; ++ind) {
3388 // Point j to the last elem of the buffer and insert the current pts there.
3390 buf_start = (buf_start + 1);
3391 if (buf_start == MAX_REORDER_DELAY + 1)
3394 pts_buf[j] = st->internal->index_entries[ind].timestamp + msc->ctts_data[ctts_ind].duration;
3396 // The timestamps that are already in the sorted buffer, and are greater than the
3397 // current pts, are exactly the timestamps that need to be buffered to output PTS
3398 // in correct sorted order.
3399 // Hence the video delay (which is the buffer size used to sort DTS and output PTS),
3400 // can be computed as the maximum no. of swaps any particular timestamp needs to
3401 // go through, to keep this buffer in sorted order.
3403 while (j != buf_start) {
3405 if (r < 0) r = MAX_REORDER_DELAY;
3406 if (pts_buf[j] < pts_buf[r]) {
3407 FFSWAP(int64_t, pts_buf[j], pts_buf[r]);
3414 st->codecpar->video_delay = FFMAX(st->codecpar->video_delay, num_swaps);
3417 if (ctts_sample == msc->ctts_data[ctts_ind].count) {
3422 av_log(c->fc, AV_LOG_DEBUG, "Setting codecpar->delay to %d for stream st: %d\n",
3423 st->codecpar->video_delay, st->index);
3427 static void mov_current_sample_inc(MOVStreamContext *sc)
3429 sc->current_sample++;
3430 sc->current_index++;
3431 if (sc->index_ranges &&
3432 sc->current_index >= sc->current_index_range->end &&
3433 sc->current_index_range->end) {
3434 sc->current_index_range++;
3435 sc->current_index = sc->current_index_range->start;
3439 static void mov_current_sample_dec(MOVStreamContext *sc)
3441 sc->current_sample--;
3442 sc->current_index--;
3443 if (sc->index_ranges &&
3444 sc->current_index < sc->current_index_range->start &&
3445 sc->current_index_range > sc->index_ranges) {
3446 sc->current_index_range--;
3447 sc->current_index = sc->current_index_range->end - 1;
3451 static void mov_current_sample_set(MOVStreamContext *sc, int current_sample)
3455 sc->current_sample = current_sample;
3456 sc->current_index = current_sample;
3457 if (!sc->index_ranges) {
3461 for (sc->current_index_range = sc->index_ranges;
3462 sc->current_index_range->end;
3463 sc->current_index_range++) {
3464 range_size = sc->current_index_range->end - sc->current_index_range->start;
3465 if (range_size > current_sample) {
3466 sc->current_index = sc->current_index_range->start + current_sample;
3469 current_sample -= range_size;
3474 * Fix st->internal->index_entries, so that it contains only the entries (and the entries
3475 * which are needed to decode them) that fall in the edit list time ranges.
3476 * Also fixes the timestamps of the index entries to match the timeline
3477 * specified the edit lists.
3479 static void mov_fix_index(MOVContext *mov, AVStream *st)
3481 MOVStreamContext *msc = st->priv_data;
3482 AVIndexEntry *e_old = st->internal->index_entries;
3483 int nb_old = st->internal->nb_index_entries;
3484 const AVIndexEntry *e_old_end = e_old + nb_old;
3485 const AVIndexEntry *current = NULL;
3486 MOVStts *ctts_data_old = msc->ctts_data;
3487 int64_t ctts_index_old = 0;
3488 int64_t ctts_sample_old = 0;
3489 int64_t ctts_count_old = msc->ctts_count;
3490 int64_t edit_list_media_time = 0;
3491 int64_t edit_list_duration = 0;
3492 int64_t frame_duration = 0;
3493 int64_t edit_list_dts_counter = 0;
3494 int64_t edit_list_dts_entry_end = 0;
3495 int64_t edit_list_start_ctts_sample = 0;
3497 int64_t curr_ctts = 0;
3498 int64_t empty_edits_sum_duration = 0;
3499 int64_t edit_list_index = 0;
3502 int64_t start_dts = 0;
3503 int64_t edit_list_start_encountered = 0;
3504 int64_t search_timestamp = 0;
3505 int64_t* frame_duration_buffer = NULL;
3506 int num_discarded_begin = 0;
3507 int first_non_zero_audio_edit = -1;
3508 int packet_skip_samples = 0;
3509 MOVIndexRange *current_index_range;
3511 int found_keyframe_after_edit = 0;
3512 int found_non_empty_edit = 0;
3514 if (!msc->elst_data || msc->elst_count <= 0 || nb_old <= 0) {
3518 // allocate the index ranges array
3519 msc->index_ranges = av_malloc((msc->elst_count + 1) * sizeof(msc->index_ranges[0]));
3520 if (!msc->index_ranges) {
3521 av_log(mov->fc, AV_LOG_ERROR, "Cannot allocate index ranges buffer\n");
3524 msc->current_index_range = msc->index_ranges;
3525 current_index_range = msc->index_ranges - 1;
3527 // Clean AVStream from traces of old index
3528 st->internal->index_entries = NULL;
3529 st->internal->index_entries_allocated_size = 0;
3530 st->internal->nb_index_entries = 0;
3532 // Clean ctts fields of MOVStreamContext
3533 msc->ctts_data = NULL;
3534 msc->ctts_count = 0;
3535 msc->ctts_index = 0;
3536 msc->ctts_sample = 0;
3537 msc->ctts_allocated_size = 0;
3539 // Reinitialize min_corrected_pts so that it can be computed again.
3540 msc->min_corrected_pts = -1;
3542 // If the dts_shift is positive (in case of negative ctts values in mov),
3543 // then negate the DTS by dts_shift
3544 if (msc->dts_shift > 0) {
3545 edit_list_dts_entry_end -= msc->dts_shift;
3546 av_log(mov->fc, AV_LOG_DEBUG, "Shifting DTS by %d because of negative CTTS.\n", msc->dts_shift);
3549 start_dts = edit_list_dts_entry_end;
3551 while (get_edit_list_entry(mov, msc, edit_list_index, &edit_list_media_time,
3552 &edit_list_duration, mov->time_scale)) {
3553 av_log(mov->fc, AV_LOG_DEBUG, "Processing st: %d, edit list %"PRId64" - media time: %"PRId64", duration: %"PRId64"\n",
3554 st->index, edit_list_index, edit_list_media_time, edit_list_duration);
3556 edit_list_dts_counter = edit_list_dts_entry_end;
3557 edit_list_dts_entry_end += edit_list_duration;
3558 num_discarded_begin = 0;
3559 if (!found_non_empty_edit && edit_list_media_time == -1) {
3560 empty_edits_sum_duration += edit_list_duration;
3563 found_non_empty_edit = 1;
3565 // If we encounter a non-negative edit list reset the skip_samples/start_pad fields and set them
3566 // according to the edit list below.
3567 if (st->codecpar->codec_type == AVMEDIA_TYPE_AUDIO) {
3568 if (first_non_zero_audio_edit < 0) {
3569 first_non_zero_audio_edit = 1;
3571 first_non_zero_audio_edit = 0;
3574 if (first_non_zero_audio_edit > 0)
3575 st->internal->skip_samples = msc->start_pad = 0;
3578 // While reordering frame index according to edit list we must handle properly
3579 // the scenario when edit list entry starts from none key frame.
3580 // We find closest previous key frame and preserve it and consequent frames in index.
3581 // All frames which are outside edit list entry time boundaries will be dropped after decoding.
3582 search_timestamp = edit_list_media_time;
3583 if (st->codecpar->codec_type == AVMEDIA_TYPE_AUDIO) {
3584 // Audio decoders like AAC need need a decoder delay samples previous to the current sample,
3585 // to correctly decode this frame. Hence for audio we seek to a frame 1 sec. before the
3586 // edit_list_media_time to cover the decoder delay.
3587 search_timestamp = FFMAX(search_timestamp - msc->time_scale, e_old[0].timestamp);
3590 if (find_prev_closest_index(st, e_old, nb_old, ctts_data_old, ctts_count_old, search_timestamp, 0,
3591 &index, &ctts_index_old, &ctts_sample_old) < 0) {
3592 av_log(mov->fc, AV_LOG_WARNING,
3593 "st: %d edit list: %"PRId64" Missing key frame while searching for timestamp: %"PRId64"\n",
3594 st->index, edit_list_index, search_timestamp);
3595 if (find_prev_closest_index(st, e_old, nb_old, ctts_data_old, ctts_count_old, search_timestamp, AVSEEK_FLAG_ANY,
3596 &index, &ctts_index_old, &ctts_sample_old) < 0) {
3597 av_log(mov->fc, AV_LOG_WARNING,
3598 "st: %d edit list %"PRId64" Cannot find an index entry before timestamp: %"PRId64".\n",
3599 st->index, edit_list_index, search_timestamp);
3602 ctts_sample_old = 0;
3605 current = e_old + index;
3606 edit_list_start_ctts_sample = ctts_sample_old;
3608 // Iterate over index and arrange it according to edit list
3609 edit_list_start_encountered = 0;
3610 found_keyframe_after_edit = 0;
3611 for (; current < e_old_end; current++, index++) {
3612 // check if frame outside edit list mark it for discard
3613 frame_duration = (current + 1 < e_old_end) ?
3614 ((current + 1)->timestamp - current->timestamp) : edit_list_duration;
3616 flags = current->flags;
3618 // frames (pts) before or after edit list
3619 curr_cts = current->timestamp + msc->dts_shift;
3622 if (ctts_data_old && ctts_index_old < ctts_count_old) {
3623 curr_ctts = ctts_data_old[ctts_index_old].duration;
3624 av_log(mov->fc, AV_LOG_DEBUG, "stts: %"PRId64" ctts: %"PRId64", ctts_index: %"PRId64", ctts_count: %"PRId64"\n",
3625 curr_cts, curr_ctts, ctts_index_old, ctts_count_old);
3626 curr_cts += curr_ctts;
3628 if (ctts_sample_old == ctts_data_old[ctts_index_old].count) {
3629 if (add_ctts_entry(&msc->ctts_data, &msc->ctts_count,
3630 &msc->ctts_allocated_size,
3631 ctts_data_old[ctts_index_old].count - edit_list_start_ctts_sample,
3632 ctts_data_old[ctts_index_old].duration) == -1) {
3633 av_log(mov->fc, AV_LOG_ERROR, "Cannot add CTTS entry %"PRId64" - {%"PRId64", %d}\n",
3635 ctts_data_old[ctts_index_old].count - edit_list_start_ctts_sample,
3636 ctts_data_old[ctts_index_old].duration);
3640 ctts_sample_old = 0;
3641 edit_list_start_ctts_sample = 0;
3645 if (curr_cts < edit_list_media_time || curr_cts >= (edit_list_duration + edit_list_media_time)) {
3646 if (st->codecpar->codec_type == AVMEDIA_TYPE_AUDIO && st->codecpar->codec_id != AV_CODEC_ID_VORBIS &&
3647 curr_cts < edit_list_media_time && curr_cts + frame_duration > edit_list_media_time &&
3648 first_non_zero_audio_edit > 0) {
3649 packet_skip_samples = edit_list_media_time - curr_cts;
3650 st->internal->skip_samples += packet_skip_samples;
3652 // Shift the index entry timestamp by packet_skip_samples to be correct.
3653 edit_list_dts_counter -= packet_skip_samples;
3654 if (edit_list_start_encountered == 0) {
3655 edit_list_start_encountered = 1;
3656 // Make timestamps strictly monotonically increasing for audio, by rewriting timestamps for
3657 // discarded packets.
3658 if (frame_duration_buffer) {
3659 fix_index_entry_timestamps(st, st->internal->nb_index_entries, edit_list_dts_counter,
3660 frame_duration_buffer, num_discarded_begin);
3661 av_freep(&frame_duration_buffer);
3665 av_log(mov->fc, AV_LOG_DEBUG, "skip %d audio samples from curr_cts: %"PRId64"\n", packet_skip_samples, curr_cts);
3667 flags |= AVINDEX_DISCARD_FRAME;
3668 av_log(mov->fc, AV_LOG_DEBUG, "drop a frame at curr_cts: %"PRId64" @ %"PRId64"\n", curr_cts, index);
3670 if (edit_list_start_encountered == 0) {
3671 num_discarded_begin++;
3672 frame_duration_buffer = av_realloc(frame_duration_buffer,
3673 num_discarded_begin * sizeof(int64_t));
3674 if (!frame_duration_buffer) {
3675 av_log(mov->fc, AV_LOG_ERROR, "Cannot reallocate frame duration buffer\n");
3678 frame_duration_buffer[num_discarded_begin - 1] = frame_duration;
3680 // Increment skip_samples for the first non-zero audio edit list
3681 if (st->codecpar->codec_type == AVMEDIA_TYPE_AUDIO &&
3682 first_non_zero_audio_edit > 0 && st->codecpar->codec_id != AV_CODEC_ID_VORBIS) {
3683 st->internal->skip_samples += frame_duration;
3688 if (msc->min_corrected_pts < 0) {
3689 msc->min_corrected_pts = edit_list_dts_counter + curr_ctts + msc->dts_shift;
3691 msc->min_corrected_pts = FFMIN(msc->min_corrected_pts, edit_list_dts_counter + curr_ctts + msc->dts_shift);
3693 if (edit_list_start_encountered == 0) {
3694 edit_list_start_encountered = 1;
3695 // Make timestamps strictly monotonically increasing by rewriting timestamps for
3696 // discarded packets.
3697 if (frame_duration_buffer) {
3698 fix_index_entry_timestamps(st, st->internal->nb_index_entries, edit_list_dts_counter,
3699 frame_duration_buffer, num_discarded_begin);
3700 av_freep(&frame_duration_buffer);
3705 if (add_index_entry(st, current->pos, edit_list_dts_counter, current->size,
3706 current->min_distance, flags) == -1) {
3707 av_log(mov->fc, AV_LOG_ERROR, "Cannot add index entry\n");
3711 // Update the index ranges array
3712 if (current_index_range < msc->index_ranges || index != current_index_range->end) {
3713 current_index_range++;
3714 current_index_range->start = index;
3716 current_index_range->end = index + 1;
3718 // Only start incrementing DTS in frame_duration amounts, when we encounter a frame in edit list.
3719 if (edit_list_start_encountered > 0) {
3720 edit_list_dts_counter = edit_list_dts_counter + frame_duration;
3723 // Break when found first key frame after edit entry completion
3724 if ((curr_cts + frame_duration >= (edit_list_duration + edit_list_media_time)) &&
3725 ((flags & AVINDEX_KEYFRAME) || ((st->codecpar->codec_type == AVMEDIA_TYPE_AUDIO)))) {
3726 if (ctts_data_old) {
3727 // If we have CTTS and this is the first keyframe after edit elist,
3728 // wait for one more, because there might be trailing B-frames after this I-frame
3729 // that do belong to the edit.
3730 if (st->codecpar->codec_type != AVMEDIA_TYPE_AUDIO && found_keyframe_after_edit == 0) {
3731 found_keyframe_after_edit = 1;
3734 if (ctts_sample_old != 0) {
3735 if (add_ctts_entry(&msc->ctts_data, &msc->ctts_count,
3736 &msc->ctts_allocated_size,
3737 ctts_sample_old - edit_list_start_ctts_sample,
3738 ctts_data_old[ctts_index_old].duration) == -1) {
3739 av_log(mov->fc, AV_LOG_ERROR, "Cannot add CTTS entry %"PRId64" - {%"PRId64", %d}\n",
3740 ctts_index_old, ctts_sample_old - edit_list_start_ctts_sample,
3741 ctts_data_old[ctts_index_old].duration);
3750 // If there are empty edits, then msc->min_corrected_pts might be positive
3751 // intentionally. So we subtract the sum duration of emtpy edits here.
3752 msc->min_corrected_pts -= empty_edits_sum_duration;
3754 // If the minimum pts turns out to be greater than zero after fixing the index, then we subtract the
3755 // dts by that amount to make the first pts zero.
3756 if (st->codecpar->codec_type == AVMEDIA_TYPE_VIDEO) {
3757 if (msc->min_corrected_pts > 0) {
3758 av_log(mov->fc, AV_LOG_DEBUG, "Offset DTS by %"PRId64" to make first pts zero.\n", msc->min_corrected_pts);
3759 for (i = 0; i < st->internal->nb_index_entries; ++i) {
3760 st->internal->index_entries[i].timestamp -= msc->min_corrected_pts;
3764 // Start time should be equal to zero or the duration of any empty edits.
3765 st->start_time = empty_edits_sum_duration;
3767 // Update av stream length, if it ends up shorter than the track's media duration
3768 st->duration = FFMIN(st->duration, edit_list_dts_entry_end - start_dts);
3769 msc->start_pad = st->internal->skip_samples;
3771 // Free the old index and the old CTTS structures
3773 av_free(ctts_data_old);
3774 av_freep(&frame_duration_buffer);
3776 // Null terminate the index ranges array
3777 current_index_range++;
3778 current_index_range->start = 0;
3779 current_index_range->end = 0;
3780 msc->current_index = msc->index_ranges[0].start;
3783 static void mov_build_index(MOVContext *mov, AVStream *st)
3785 MOVStreamContext *sc = st->priv_data;
3786 int64_t current_offset;
3787 int64_t current_dts = 0;
3788 unsigned int stts_index = 0;
3789 unsigned int stsc_index = 0;
3790 unsigned int stss_index = 0;
3791 unsigned int stps_index = 0;
3793 uint64_t stream_size = 0;
3794 MOVStts *ctts_data_old = sc->ctts_data;
3795 unsigned int ctts_count_old = sc->ctts_count;
3797 if (sc->elst_count) {
3798 int i, edit_start_index = 0, multiple_edits = 0;
3799 int64_t empty_duration = 0; // empty duration of the first edit list entry
3800 int64_t start_time = 0; // start time of the media
3802 for (i = 0; i < sc->elst_count; i++) {
3803 const MOVElst *e = &sc->elst_data[i];
3804 if (i == 0 && e->time == -1) {
3805 /* if empty, the first entry is the start time of the stream
3806 * relative to the presentation itself */
3807 empty_duration = e->duration;
3808 edit_start_index = 1;
3809 } else if (i == edit_start_index && e->time >= 0) {
3810 start_time = e->time;
3816 if (multiple_edits && !mov->advanced_editlist)
3817 av_log(mov->fc, AV_LOG_WARNING, "multiple edit list entries, "
3818 "Use -advanced_editlist to correctly decode otherwise "
3819 "a/v desync might occur\n");
3821 /* adjust first dts according to edit list */
3822 if ((empty_duration || start_time) && mov->time_scale > 0) {
3824 empty_duration = av_rescale(empty_duration, sc->time_scale, mov->time_scale);
3825 sc->time_offset = start_time - empty_duration;
3826 sc->min_corrected_pts = start_time;
3827 if (!mov->advanced_editlist)
3828 current_dts = -sc->time_offset;
3831 if (!multiple_edits && !mov->advanced_editlist &&
3832 st->codecpar->codec_id == AV_CODEC_ID_AAC && start_time > 0)
3833 sc->start_pad = start_time;
3836 /* only use old uncompressed audio chunk demuxing when stts specifies it */
3837 if (!(st->codecpar->codec_type == AVMEDIA_TYPE_AUDIO &&
3838 sc->stts_count == 1 && sc->stts_data[0].duration == 1)) {
3839 unsigned int current_sample = 0;
3840 unsigned int stts_sample = 0;
3841 unsigned int sample_size;
3842 unsigned int distance = 0;
3843 unsigned int rap_group_index = 0;
3844 unsigned int rap_group_sample = 0;
3845 int64_t last_dts = 0;
3846 int64_t dts_correction = 0;
3847 int rap_group_present = sc->rap_group_count && sc->rap_group;
3848 int key_off = (sc->keyframe_count && sc->keyframes[0] > 0) || (sc->stps_count && sc->stps_data[0] > 0);
3850 current_dts -= sc->dts_shift;
3851 last_dts = current_dts;
3853 if (!sc->sample_count || st->internal->nb_index_entries)
3855 if (sc->sample_count >= UINT_MAX / sizeof(*st->internal->index_entries) - st->internal->nb_index_entries)
3857 if (av_reallocp_array(&st->internal->index_entries,
3858 st->internal->nb_index_entries + sc->sample_count,
3859 sizeof(*st->internal->index_entries)) < 0) {
3860 st->internal->nb_index_entries = 0;
3863 st->internal->index_entries_allocated_size = (st->internal->nb_index_entries + sc->sample_count) * sizeof(*st->internal->index_entries);
3865 if (ctts_data_old) {
3866 // Expand ctts entries such that we have a 1-1 mapping with samples
3867 if (sc->sample_count >= UINT_MAX / sizeof(*sc->ctts_data))
3870 sc->ctts_allocated_size = 0;
3871 sc->ctts_data = av_fast_realloc(NULL, &sc->ctts_allocated_size,
3872 sc->sample_count * sizeof(*sc->ctts_data));
3873 if (!sc->ctts_data) {
3874 av_free(ctts_data_old);
3878 memset((uint8_t*)(sc->ctts_data), 0, sc->ctts_allocated_size);
3880 for (i = 0; i < ctts_count_old &&
3881 sc->ctts_count < sc->sample_count; i++)
3882 for (j = 0; j < ctts_data_old[i].count &&
3883 sc->ctts_count < sc->sample_count; j++)
3884 add_ctts_entry(&sc->ctts_data, &sc->ctts_count,
3885 &sc->ctts_allocated_size, 1,
3886 ctts_data_old[i].duration);
3887 av_free(ctts_data_old);
3890 for (i = 0; i < sc->chunk_count; i++) {
3891 int64_t next_offset = i+1 < sc->chunk_count ? sc->chunk_offsets[i+1] : INT64_MAX;
3892 current_offset = sc->chunk_offsets[i];
3893 while (mov_stsc_index_valid(stsc_index, sc->stsc_count) &&
3894 i + 1 == sc->stsc_data[stsc_index + 1].first)
3897 if (next_offset > current_offset && sc->sample_size>0 && sc->sample_size < sc->stsz_sample_size &&
3898 sc->stsc_data[stsc_index].count * (int64_t)sc->stsz_sample_size > next_offset - current_offset) {
3899 av_log(mov->fc, AV_LOG_WARNING, "STSZ sample size %d invalid (too large), ignoring\n", sc->stsz_sample_size);
3900 sc->stsz_sample_size = sc->sample_size;
3902 if (sc->stsz_sample_size>0 && sc->stsz_sample_size < sc->sample_size) {
3903 av_log(mov->fc, AV_LOG_WARNING, "STSZ sample size %d invalid (too small), ignoring\n", sc->stsz_sample_size);
3904 sc->stsz_sample_size = sc->sample_size;
3907 for (j = 0; j < sc->stsc_data[stsc_index].count; j++) {
3909 if (current_sample >= sc->sample_count) {
3910 av_log(mov->fc, AV_LOG_ERROR, "wrong sample count\n");
3914 if (!sc->keyframe_absent && (!sc->keyframe_count || current_sample+key_off == sc->keyframes[stss_index])) {
3916 if (stss_index + 1 < sc->keyframe_count)
3918 } else if (sc->stps_count && current_sample+key_off == sc->stps_data[stps_index]) {
3920 if (stps_index + 1 < sc->stps_count)
3923 if (rap_group_present && rap_group_index < sc->rap_group_count) {
3924 if (sc->rap_group[rap_group_index].index > 0)
3926 if (++rap_group_sample == sc->rap_group[rap_group_index].count) {
3927 rap_group_sample = 0;
3931 if (sc->keyframe_absent
3933 && !rap_group_present
3934 && (st->codecpar->codec_type == AVMEDIA_TYPE_AUDIO || (i==0 && j==0)))
3938 sample_size = sc->stsz_sample_size > 0 ? sc->stsz_sample_size : sc->sample_sizes[current_sample];
3939 if (sc->pseudo_stream_id == -1 ||
3940 sc->stsc_data[stsc_index].id - 1 == sc->pseudo_stream_id) {
3942 if (sample_size > 0x3FFFFFFF) {
3943 av_log(mov->fc, AV_LOG_ERROR, "Sample size %u is too large\n", sample_size);
3946 e = &st->internal->index_entries[st->internal->nb_index_entries++];
3947 e->pos = current_offset;
3948 e->timestamp = current_dts;
3949 e->size = sample_size;
3950 e->min_distance = distance;
3951 e->flags = keyframe ? AVINDEX_KEYFRAME : 0;
3952 av_log(mov->fc, AV_LOG_TRACE, "AVIndex stream %d, sample %u, offset %"PRIx64", dts %"PRId64", "
3953 "size %u, distance %u, keyframe %d\n", st->index, current_sample,
3954 current_offset, current_dts, sample_size, distance, keyframe);
3955 if (st->codecpar->codec_type == AVMEDIA_TYPE_VIDEO && st->internal->nb_index_entries < 100)
3956 ff_rfps_add_frame(mov->fc, st, current_dts);
3959 current_offset += sample_size;
3960 stream_size += sample_size;
3962 /* A negative sample duration is invalid based on the spec,
3963 * but some samples need it to correct the DTS. */
3964 if (sc->stts_data[stts_index].duration < 0) {
3965 av_log(mov->fc, AV_LOG_WARNING,
3966 "Invalid SampleDelta %d in STTS, at %d st:%d\n",
3967 sc->stts_data[stts_index].duration, stts_index,
3969 dts_correction += sc->stts_data[stts_index].duration - 1;
3970 sc->stts_data[stts_index].duration = 1;
3972 current_dts += sc->stts_data[stts_index].duration;
3973 if (!dts_correction || current_dts + dts_correction > last_dts) {
3974 current_dts += dts_correction;
3977 /* Avoid creating non-monotonous DTS */
3978 dts_correction += current_dts - last_dts - 1;
3979 current_dts = last_dts + 1;
3981 last_dts = current_dts;
3985 if (stts_index + 1 < sc->stts_count && stts_sample == sc->stts_data[stts_index].count) {
3991 if (st->duration > 0)
3992 st->codecpar->bit_rate = stream_size*8*sc->time_scale/st->duration;
3994 unsigned chunk_samples, total = 0;
3996 if (!sc->chunk_count)
3999 // compute total chunk count
4000 for (i = 0; i < sc->stsc_count; i++) {
4001 unsigned count, chunk_count;
4003 chunk_samples = sc->stsc_data[i].count;
4004 if (i != sc->stsc_count - 1 &&
4005 sc->samples_per_frame && chunk_samples % sc->samples_per_frame) {
4006 av_log(mov->fc, AV_LOG_ERROR, "error unaligned chunk\n");
4010 if (sc->samples_per_frame >= 160) { // gsm
4011 count = chunk_samples / sc->samples_per_frame;
4012 } else if (sc->samples_per_frame > 1) {
4013 unsigned samples = (1024/sc->samples_per_frame)*sc->samples_per_frame;
4014 count = (chunk_samples+samples-1) / samples;
4016 count = (chunk_samples+1023) / 1024;
4019 if (mov_stsc_index_valid(i, sc->stsc_count))
4020 chunk_count = sc->stsc_data[i+1].first - sc->stsc_data[i].first;
4022 chunk_count = sc->chunk_count - (sc->stsc_data[i].first - 1);
4023 total += chunk_count * count;
4026 av_log(mov->fc, AV_LOG_TRACE, "chunk count %u\n", total);
4027 if (total >= UINT_MAX / sizeof(*st->internal->index_entries) - st->internal->nb_index_entries)
4029 if (av_reallocp_array(&st->internal->index_entries,
4030 st->internal->nb_index_entries + total,
4031 sizeof(*st->internal->index_entries)) < 0) {
4032 st->internal->nb_index_entries = 0;
4035 st->internal->index_entries_allocated_size = (st->internal->nb_index_entries + total) * sizeof(*st->internal->index_entries);
4038 for (i = 0; i < sc->chunk_count; i++) {
4039 current_offset = sc->chunk_offsets[i];
4040 if (mov_stsc_index_valid(stsc_index, sc->stsc_count) &&
4041 i + 1 == sc->stsc_data[stsc_index + 1].first)
4043 chunk_samples = sc->stsc_data[stsc_index].count;
4045 while (chunk_samples > 0) {
4047 unsigned size, samples;
4049 if (sc->samples_per_frame > 1 && !sc->bytes_per_frame) {
4050 avpriv_request_sample(mov->fc,
4051 "Zero bytes per frame, but %d samples per frame",
4052 sc->samples_per_frame);
4056 if (sc->samples_per_frame >= 160) { // gsm
4057 samples = sc->samples_per_frame;
4058 size = sc->bytes_per_frame;
4060 if (sc->samples_per_frame > 1) {
4061 samples = FFMIN((1024 / sc->samples_per_frame)*
4062 sc->samples_per_frame, chunk_samples);
4063 size = (samples / sc->samples_per_frame) * sc->bytes_per_frame;
4065 samples = FFMIN(1024, chunk_samples);
4066 size = samples * sc->sample_size;
4070 if (st->internal->nb_index_entries >= total) {
4071 av_log(mov->fc, AV_LOG_ERROR, "wrong chunk count %u\n", total);
4074 if (size > 0x3FFFFFFF) {
4075 av_log(mov->fc, AV_LOG_ERROR, "Sample size %u is too large\n", size);
4078 e = &st->internal->index_entries[st->internal->nb_index_entries++];
4079 e->pos = current_offset;
4080 e->timestamp = current_dts;
4082 e->min_distance = 0;
4083 e->flags = AVINDEX_KEYFRAME;
4084 av_log(mov->fc, AV_LOG_TRACE, "AVIndex stream %d, chunk %u, offset %"PRIx64", dts %"PRId64", "
4085 "size %u, duration %u\n", st->index, i, current_offset, current_dts,
4088 current_offset += size;
4089 current_dts += samples;
4090 chunk_samples -= samples;
4095 if (!mov->ignore_editlist && mov->advanced_editlist) {
4096 // Fix index according to edit lists.
4097 mov_fix_index(mov, st);
4100 // Update start time of the stream.
4101 if (st->start_time == AV_NOPTS_VALUE && st->codecpar->codec_type == AVMEDIA_TYPE_VIDEO && st->internal->nb_index_entries > 0) {
4102 st->start_time = st->internal->index_entries[0].timestamp + sc->dts_shift;
4103 if (sc->ctts_data) {
4104 st->start_time += sc->ctts_data[0].duration;
4108 mov_estimate_video_delay(mov, st);
4111 static int test_same_origin(const char *src, const char *ref) {
4121 av_url_split(src_proto, sizeof(src_proto), src_auth, sizeof(src_auth), src_host, sizeof(src_host), &src_port, NULL, 0, src);
4122 av_url_split(ref_proto, sizeof(ref_proto), ref_auth, sizeof(ref_auth), ref_host, sizeof(ref_host), &ref_port, NULL, 0, ref);
4124 if (strlen(src) == 0) {
4126 } else if (strlen(src_auth) + 1 >= sizeof(src_auth) ||
4127 strlen(ref_auth) + 1 >= sizeof(ref_auth) ||
4128 strlen(src_host) + 1 >= sizeof(src_host) ||
4129 strlen(ref_host) + 1 >= sizeof(ref_host)) {
4131 } else if (strcmp(src_proto, ref_proto) ||
4132 strcmp(src_auth, ref_auth) ||
4133 strcmp(src_host, ref_host) ||
4134 src_port != ref_port) {
4140 static int mov_open_dref(MOVContext *c, AVIOContext **pb, const char *src, MOVDref *ref)
4142 /* try relative path, we do not try the absolute because it can leak information about our
4143 system to an attacker */
4144 if (ref->nlvl_to > 0 && ref->nlvl_from > 0) {
4145 char filename[1025];
4146 const char *src_path;
4149 /* find a source dir */
4150 src_path = strrchr(src, '/');
4156 /* find a next level down to target */
4157 for (i = 0, l = strlen(ref->path) - 1; l >= 0; l--)
4158 if (ref->path[l] == '/') {
4159 if (i == ref->nlvl_to - 1)
4165 /* compose filename if next level down to target was found */
4166 if (i == ref->nlvl_to - 1 && src_path - src < sizeof(filename)) {
4167 memcpy(filename, src, src_path - src);
4168 filename[src_path - src] = 0;
4170 for (i = 1; i < ref->nlvl_from; i++)
4171 av_strlcat(filename, "../", sizeof(filename));
4173 av_strlcat(filename, ref->path + l + 1, sizeof(filename));
4174 if (!c->use_absolute_path) {
4175 int same_origin = test_same_origin(src, filename);
4178 av_log(c->fc, AV_LOG_ERROR,
4179 "Reference with mismatching origin, %s not tried for security reasons, "
4180 "set demuxer option use_absolute_path to allow it anyway\n",
4182 return AVERROR(ENOENT);
4185 if (strstr(ref->path + l + 1, "..") ||
4186 strstr(ref->path + l + 1, ":") ||
4187 (ref->nlvl_from > 1 && same_origin < 0) ||
4188 (filename[0] == '/' && src_path == src))
4189 return AVERROR(ENOENT);
4192 if (strlen(filename) + 1 == sizeof(filename))
4193 return AVERROR(ENOENT);
4194 if (!c->fc->io_open(c->fc, pb, filename, AVIO_FLAG_READ, NULL))
4197 } else if (c->use_absolute_path) {
4198 av_log(c->fc, AV_LOG_WARNING, "Using absolute path on user request, "
4199 "this is a possible security issue\n");
4200 if (!c->fc->io_open(c->fc, pb, ref->path, AVIO_FLAG_READ, NULL))
4203 av_log(c->fc, AV_LOG_ERROR,
4204 "Absolute path %s not tried for security reasons, "
4205 "set demuxer option use_absolute_path to allow absolute paths\n",
4209 return AVERROR(ENOENT);
4212 static void fix_timescale(MOVContext *c, MOVStreamContext *sc)
4214 if (sc->time_scale <= 0) {
4215 av_log(c->fc, AV_LOG_WARNING, "stream %d, timescale not set\n", sc->ffindex);
4216 sc->time_scale = c->time_scale;
4217 if (sc->time_scale <= 0)
4222 static int mov_read_trak(MOVContext *c, AVIOContext *pb, MOVAtom atom)
4225 MOVStreamContext *sc;
4228 st = avformat_new_stream(c->fc, NULL);
4229 if (!st) return AVERROR(ENOMEM);
4231 sc = av_mallocz(sizeof(MOVStreamContext));
4232 if (!sc) return AVERROR(ENOMEM);
4235 st->codecpar->codec_type = AVMEDIA_TYPE_DATA;
4236 sc->ffindex = st->index;
4237 c->trak_index = st->index;
4239 if ((ret = mov_read_default(c, pb, atom)) < 0)
4244 // Here stsc refers to a chunk not described in stco. This is technically invalid,
4245 // but we can overlook it (clearing stsc) whenever stts_count == 0 (indicating no samples).
4246 if (!sc->chunk_count && !sc->stts_count && sc->stsc_count) {
4248 av_freep(&sc->stsc_data);
4252 if ((sc->chunk_count && (!sc->stts_count || !sc->stsc_count ||
4253 (!sc->sample_size && !sc->sample_count))) ||
4254 (!sc->chunk_count && sc->sample_count)) {
4255 av_log(c->fc, AV_LOG_ERROR, "stream %d, missing mandatory atoms, broken header\n",
4259 if (sc->stsc_count && sc->stsc_data[ sc->stsc_count - 1 ].first > sc->chunk_count) {
4260 av_log(c->fc, AV_LOG_ERROR, "stream %d, contradictionary STSC and STCO\n",
4262 return AVERROR_INVALIDDATA;
4265 fix_timescale(c, sc);
4267 avpriv_set_pts_info(st, 64, 1, sc->time_scale);
4269 mov_build_index(c, st);
4271 if (sc->dref_id-1 < sc->drefs_count && sc->drefs[sc->dref_id-1].path) {
4272 MOVDref *dref = &sc->drefs[sc->dref_id - 1];
4273 if (c->enable_drefs) {
4274 if (mov_open_dref(c, &sc->pb, c->fc->url, dref) < 0)
4275 av_log(c->fc, AV_LOG_ERROR,
4276 "stream %d, error opening alias: path='%s', dir='%s', "
4277 "filename='%s', volume='%s', nlvl_from=%d, nlvl_to=%d\n",
4278 st->index, dref->path, dref->dir, dref->filename,
4279 dref->volume, dref->nlvl_from, dref->nlvl_to);
4281 av_log(c->fc, AV_LOG_WARNING,
4282 "Skipped opening external track: "
4283 "stream %d, alias: path='%s', dir='%s', "
4284 "filename='%s', volume='%s', nlvl_from=%d, nlvl_to=%d."
4285 "Set enable_drefs to allow this.\n",
4286 st->index, dref->path, dref->dir, dref->filename,
4287 dref->volume, dref->nlvl_from, dref->nlvl_to);
4291 sc->pb_is_copied = 1;
4294 if (st->codecpar->codec_type == AVMEDIA_TYPE_VIDEO) {
4295 if (!st->sample_aspect_ratio.num && st->codecpar->width && st->codecpar->height &&
4296 sc->height && sc->width &&
4297 (st->codecpar->width != sc->width || st->codecpar->height != sc->height)) {
4298 st->sample_aspect_ratio = av_d2q(((double)st->codecpar->height * sc->width) /
4299 ((double)st->codecpar->width * sc->height), INT_MAX);
4302 #if FF_API_R_FRAME_RATE
4303 if (sc->stts_count == 1 || (sc->stts_count == 2 && sc->stts_data[1].count == 1))
4304 av_reduce(&st->r_frame_rate.num, &st->r_frame_rate.den,
4305 sc->time_scale, sc->stts_data[0].duration, INT_MAX);
4309 // done for ai5q, ai52, ai55, ai1q, ai12 and ai15.
4310 if (!st->codecpar->extradata_size && st->codecpar->codec_id == AV_CODEC_ID_H264 &&
4311 TAG_IS_AVCI(st->codecpar->codec_tag)) {
4312 ret = ff_generate_avci_extradata(st);
4317 switch (st->codecpar->codec_id) {
4318 #if CONFIG_H261_DECODER
4319 case AV_CODEC_ID_H261:
4321 #if CONFIG_H263_DECODER
4322 case AV_CODEC_ID_H263:
4324 #if CONFIG_MPEG4_DECODER
4325 case AV_CODEC_ID_MPEG4:
4327 st->codecpar->width = 0; /* let decoder init width/height */
4328 st->codecpar->height= 0;
4332 // If the duration of the mp3 packets is not constant, then they could need a parser
4333 if (st->codecpar->codec_id == AV_CODEC_ID_MP3
4334 && sc->stts_count > 3
4335 && sc->stts_count*10 > st->nb_frames
4336 && sc->time_scale == st->codecpar->sample_rate) {
4337 st->need_parsing = AVSTREAM_PARSE_FULL;
4339 /* Do not need those anymore. */
4340 av_freep(&sc->chunk_offsets);
4341 av_freep(&sc->sample_sizes);
4342 av_freep(&sc->keyframes);
4343 av_freep(&sc->stts_data);
4344 av_freep(&sc->stps_data);
4345 av_freep(&sc->elst_data);
4346 av_freep(&sc->rap_group);
4351 static int mov_read_ilst(MOVContext *c, AVIOContext *pb, MOVAtom atom)
4354 c->itunes_metadata = 1;
4355 ret = mov_read_default(c, pb, atom);
4356 c->itunes_metadata = 0;
4360 static int mov_read_keys(MOVContext *c, AVIOContext *pb, MOVAtom atom)
4369 count = avio_rb32(pb);
4370 if (count > UINT_MAX / sizeof(*c->meta_keys) - 1) {
4371 av_log(c->fc, AV_LOG_ERROR,
4372 "The 'keys' atom with the invalid key count: %"PRIu32"\n", count);
4373 return AVERROR_INVALIDDATA;
4376 c->meta_keys_count = count + 1;
4377 c->meta_keys = av_mallocz(c->meta_keys_count * sizeof(*c->meta_keys));
4379 return AVERROR(ENOMEM);
4381 for (i = 1; i <= count; ++i) {
4382 uint32_t key_size = avio_rb32(pb);
4383 uint32_t type = avio_rl32(pb);
4385 av_log(c->fc, AV_LOG_ERROR,
4386 "The key# %"PRIu32" in meta has invalid size:"
4387 "%"PRIu32"\n", i, key_size);
4388 return AVERROR_INVALIDDATA;
4391 if (type != MKTAG('m','d','t','a')) {
4392 avio_skip(pb, key_size);
4394 c->meta_keys[i] = av_mallocz(key_size + 1);
4395 if (!c->meta_keys[i])
4396 return AVERROR(ENOMEM);
4397 avio_read(pb, c->meta_keys[i], key_size);
4403 static int mov_read_custom(MOVContext *c, AVIOContext *pb, MOVAtom atom)
4405 int64_t end = av_sat_add64(avio_tell(pb), atom.size);
4406 uint8_t *key = NULL, *val = NULL, *mean = NULL;
4410 MOVStreamContext *sc;
4412 if (c->fc->nb_streams < 1)
4414 st = c->fc->streams[c->fc->nb_streams-1];
4417 for (i = 0; i < 3; i++) {
4421 if (end - avio_tell(pb) <= 12)
4424 len = avio_rb32(pb);
4425 tag = avio_rl32(pb);
4426 avio_skip(pb, 4); // flags
4428 if (len < 12 || len - 12 > end - avio_tell(pb))
4432 if (tag == MKTAG('m', 'e', 'a', 'n'))
4434 else if (tag == MKTAG('n', 'a', 'm', 'e'))
4436 else if (tag == MKTAG('d', 'a', 't', 'a') && len > 4) {
4446 *p = av_malloc(len + 1);
4448 ret = AVERROR(ENOMEM);
4451 ret = ffio_read_size(pb, *p, len);
4459 if (mean && key && val) {
4460 if (strcmp(key, "iTunSMPB") == 0) {
4461 int priming, remainder, samples;
4462 if(sscanf(val, "%*X %X %X %X", &priming, &remainder, &samples) == 3){
4463 if(priming>0 && priming<16384)
4464 sc->start_pad = priming;
4467 if (strcmp(key, "cdec") != 0) {
4468 av_dict_set(&c->fc->metadata, key, val,
4469 AV_DICT_DONT_STRDUP_KEY | AV_DICT_DONT_STRDUP_VAL);
4473 av_log(c->fc, AV_LOG_VERBOSE,
4474 "Unhandled or malformed custom metadata of size %"PRId64"\n", atom.size);
4477 avio_seek(pb, end, SEEK_SET);
4484 static int mov_read_meta(MOVContext *c, AVIOContext *pb, MOVAtom atom)
4486 while (atom.size > 8) {
4490 tag = avio_rl32(pb);
4492 if (tag == MKTAG('h','d','l','r')) {
4493 avio_seek(pb, -8, SEEK_CUR);
4495 return mov_read_default(c, pb, atom);
4501 // return 1 when matrix is identity, 0 otherwise
4502 #define IS_MATRIX_IDENT(matrix) \
4503 ( (matrix)[0][0] == (1 << 16) && \
4504 (matrix)[1][1] == (1 << 16) && \
4505 (matrix)[2][2] == (1 << 30) && \
4506 !(matrix)[0][1] && !(matrix)[0][2] && \
4507 !(matrix)[1][0] && !(matrix)[1][2] && \
4508 !(matrix)[2][0] && !(matrix)[2][1])
4510 static int mov_read_tkhd(MOVContext *c, AVIOContext *pb, MOVAtom atom)
4515 int display_matrix[3][3];
4516 int res_display_matrix[3][3] = { { 0 } };
4518 MOVStreamContext *sc;
4522 if (c->fc->nb_streams < 1)
4524 st = c->fc->streams[c->fc->nb_streams-1];
4527 // Each stream (trak) should have exactly 1 tkhd. This catches bad files and
4528 // avoids corrupting AVStreams mapped to an earlier tkhd.
4530 return AVERROR_INVALIDDATA;
4532 version = avio_r8(pb);
4533 flags = avio_rb24(pb);
4534 st->disposition |= (flags & MOV_TKHD_FLAG_ENABLED) ? AV_DISPOSITION_DEFAULT : 0;
4540 avio_rb32(pb); /* creation time */
4541 avio_rb32(pb); /* modification time */
4543 st->id = (int)avio_rb32(pb); /* track id (NOT 0 !)*/
4544 avio_rb32(pb); /* reserved */
4546 /* highlevel (considering edits) duration in movie timebase */
4547 (version == 1) ? avio_rb64(pb) : avio_rb32(pb);
4548 avio_rb32(pb); /* reserved */
4549 avio_rb32(pb); /* reserved */
4551 avio_rb16(pb); /* layer */
4552 avio_rb16(pb); /* alternate group */
4553 avio_rb16(pb); /* volume */
4554 avio_rb16(pb); /* reserved */
4556 //read in the display matrix (outlined in ISO 14496-12, Section 6.2.2)
4557 // they're kept in fixed point format through all calculations
4558 // save u,v,z to store the whole matrix in the AV_PKT_DATA_DISPLAYMATRIX
4559 // side data, but the scale factor is not needed to calculate aspect ratio
4560 for (i = 0; i < 3; i++) {
4561 display_matrix[i][0] = avio_rb32(pb); // 16.16 fixed point
4562 display_matrix[i][1] = avio_rb32(pb); // 16.16 fixed point
4563 display_matrix[i][2] = avio_rb32(pb); // 2.30 fixed point
4566 width = avio_rb32(pb); // 16.16 fixed point track width
4567 height = avio_rb32(pb); // 16.16 fixed point track height
4568 sc->width = width >> 16;
4569 sc->height = height >> 16;
4571 // apply the moov display matrix (after the tkhd one)
4572 for (i = 0; i < 3; i++) {
4573 const int sh[3] = { 16, 16, 30 };
4574 for (j = 0; j < 3; j++) {
4575 for (e = 0; e < 3; e++) {
4576 res_display_matrix[i][j] +=
4577 ((int64_t) display_matrix[i][e] *
4578 c->movie_display_matrix[e][j]) >> sh[e];
4583 // save the matrix when it is not the default identity
4584 if (!IS_MATRIX_IDENT(res_display_matrix)) {
4587 av_freep(&sc->display_matrix);
4588 sc->display_matrix = av_malloc(sizeof(int32_t) * 9);
4589 if (!sc->display_matrix)
4590 return AVERROR(ENOMEM);
4592 for (i = 0; i < 3; i++)
4593 for (j = 0; j < 3; j++)
4594 sc->display_matrix[i * 3 + j] = res_display_matrix[i][j];
4596 #if FF_API_OLD_ROTATE_API
4597 rotate = av_display_rotation_get(sc->display_matrix);
4598 if (!isnan(rotate)) {
4599 char rotate_buf[64];
4601 if (rotate < 0) // for backward compatibility
4603 snprintf(rotate_buf, sizeof(rotate_buf), "%g", rotate);
4604 av_dict_set(&st->metadata, "rotate", rotate_buf, 0);
4609 // transform the display width/height according to the matrix
4610 // to keep the same scale, use [width height 1<<16]
4611 if (width && height && sc->display_matrix) {
4612 double disp_transform[2];
4614 for (i = 0; i < 2; i++)
4615 disp_transform[i] = hypot(sc->display_matrix[0 + i],
4616 sc->display_matrix[3 + i]);
4618 if (disp_transform[0] > 1 && disp_transform[1] > 1 &&
4619 disp_transform[0] < (1<<24) && disp_transform[1] < (1<<24) &&
4620 fabs((disp_transform[0] / disp_transform[1]) - 1.0) > 0.01)
4621 st->sample_aspect_ratio = av_d2q(
4622 disp_transform[0] / disp_transform[1],
4628 static int mov_read_tfhd(MOVContext *c, AVIOContext *pb, MOVAtom atom)
4630 MOVFragment *frag = &c->fragment;
4631 MOVTrackExt *trex = NULL;
4632 int flags, track_id, i;
4633 MOVFragmentStreamInfo * frag_stream_info;
4635 avio_r8(pb); /* version */
4636 flags = avio_rb24(pb);
4638 track_id = avio_rb32(pb);
4640 return AVERROR_INVALIDDATA;
4641 for (i = 0; i < c->trex_count; i++)
4642 if (c->trex_data[i].track_id == track_id) {
4643 trex = &c->trex_data[i];
4647 av_log(c->fc, AV_LOG_WARNING, "could not find corresponding trex (id %u)\n", track_id);
4650 c->fragment.found_tfhd = 1;
4651 frag->track_id = track_id;
4652 set_frag_stream(&c->frag_index, track_id);
4654 frag->base_data_offset = flags & MOV_TFHD_BASE_DATA_OFFSET ?
4655 avio_rb64(pb) : flags & MOV_TFHD_DEFAULT_BASE_IS_MOOF ?
4656 frag->moof_offset : frag->implicit_offset;
4657 frag->stsd_id = flags & MOV_TFHD_STSD_ID ? avio_rb32(pb) : trex->stsd_id;
4659 frag->duration = flags & MOV_TFHD_DEFAULT_DURATION ?
4660 avio_rb32(pb) : trex->duration;
4661 frag->size = flags & MOV_TFHD_DEFAULT_SIZE ?
4662 avio_rb32(pb) : trex->size;
4663 frag->flags = flags & MOV_TFHD_DEFAULT_FLAGS ?
4664 avio_rb32(pb) : trex->flags;
4665 av_log(c->fc, AV_LOG_TRACE, "frag flags 0x%x\n", frag->flags);
4667 frag_stream_info = get_current_frag_stream_info(&c->frag_index);
4668 if (frag_stream_info)
4669 frag_stream_info->next_trun_dts = AV_NOPTS_VALUE;
4674 static int mov_read_chap(MOVContext *c, AVIOContext *pb, MOVAtom atom)
4679 num = atom.size / 4;
4680 if (!(new_tracks = av_malloc_array(num, sizeof(int))))
4681 return AVERROR(ENOMEM);
4683 av_free(c->chapter_tracks);
4684 c->chapter_tracks = new_tracks;
4685 c->nb_chapter_tracks = num;
4687 for (i = 0; i < num && !pb->eof_reached; i++)
4688 c->chapter_tracks[i] = avio_rb32(pb);
4693 static int mov_read_trex(MOVContext *c, AVIOContext *pb, MOVAtom atom)
4698 if ((uint64_t)c->trex_count+1 >= UINT_MAX / sizeof(*c->trex_data))
4699 return AVERROR_INVALIDDATA;
4700 if ((err = av_reallocp_array(&c->trex_data, c->trex_count + 1,
4701 sizeof(*c->trex_data))) < 0) {
4706 c->fc->duration = AV_NOPTS_VALUE; // the duration from mvhd is not representing the whole file when fragments are used.
4708 trex = &c->trex_data[c->trex_count++];
4709 avio_r8(pb); /* version */
4710 avio_rb24(pb); /* flags */
4711 trex->track_id = avio_rb32(pb);
4712 trex->stsd_id = avio_rb32(pb);
4713 trex->duration = avio_rb32(pb);
4714 trex->size = avio_rb32(pb);
4715 trex->flags = avio_rb32(pb);
4719 static int mov_read_tfdt(MOVContext *c, AVIOContext *pb, MOVAtom atom)
4721 MOVFragment *frag = &c->fragment;
4722 AVStream *st = NULL;
4723 MOVStreamContext *sc;
4725 MOVFragmentStreamInfo * frag_stream_info;
4726 int64_t base_media_decode_time;
4728 for (i = 0; i < c->fc->nb_streams; i++) {
4729 if (c->fc->streams[i]->id == frag->track_id) {
4730 st = c->fc->streams[i];
4735 av_log(c->fc, AV_LOG_WARNING, "could not find corresponding track id %u\n", frag->track_id);
4739 if (sc->pseudo_stream_id + 1 != frag->stsd_id && sc->pseudo_stream_id != -1)
4741 version = avio_r8(pb);
4742 avio_rb24(pb); /* flags */
4744 base_media_decode_time = avio_rb64(pb);
4746 base_media_decode_time = avio_rb32(pb);
4749 frag_stream_info = get_current_frag_stream_info(&c->frag_index);
4750 if (frag_stream_info)
4751 frag_stream_info->tfdt_dts = base_media_decode_time;
4752 sc->track_end = base_media_decode_time;
4757 static int mov_read_trun(MOVContext *c, AVIOContext *pb, MOVAtom atom)
4759 MOVFragment *frag = &c->fragment;
4760 AVStream *st = NULL;
4761 MOVStreamContext *sc;
4764 int64_t dts, pts = AV_NOPTS_VALUE;
4765 int data_offset = 0;
4766 unsigned entries, first_sample_flags = frag->flags;
4767 int flags, distance, i;
4768 int64_t prev_dts = AV_NOPTS_VALUE;
4769 int next_frag_index = -1, index_entry_pos;
4770 size_t requested_size;
4771 size_t old_ctts_allocated_size;
4772 AVIndexEntry *new_entries;
4773 MOVFragmentStreamInfo * frag_stream_info;
4775 if (!frag->found_tfhd) {
4776 av_log(c->fc, AV_LOG_ERROR, "trun track id unknown, no tfhd was found\n");
4777 return AVERROR_INVALIDDATA;
4780 for (i = 0; i < c->fc->nb_streams; i++) {
4781 if (c->fc->streams[i]->id == frag->track_id) {
4782 st = c->fc->streams[i];
4787 av_log(c->fc, AV_LOG_WARNING, "could not find corresponding track id %u\n", frag->track_id);
4791 if (sc->pseudo_stream_id+1 != frag->stsd_id && sc->pseudo_stream_id != -1)
4794 // Find the next frag_index index that has a valid index_entry for
4795 // the current track_id.
4797 // A valid index_entry means the trun for the fragment was read
4798 // and it's samples are in index_entries at the given position.
4799 // New index entries will be inserted before the index_entry found.
4800 index_entry_pos = st->internal->nb_index_entries;
4801 for (i = c->frag_index.current + 1; i < c->frag_index.nb_items; i++) {
4802 frag_stream_info = get_frag_stream_info(&c->frag_index, i, frag->track_id);
4803 if (frag_stream_info && frag_stream_info->index_entry >= 0) {
4804 next_frag_index = i;
4805 index_entry_pos = frag_stream_info->index_entry;
4809 av_assert0(index_entry_pos <= st->internal->nb_index_entries);
4811 avio_r8(pb); /* version */
4812 flags = avio_rb24(pb);
4813 entries = avio_rb32(pb);
4814 av_log(c->fc, AV_LOG_TRACE, "flags 0x%x entries %u\n", flags, entries);
4816 if ((uint64_t)entries+sc->ctts_count >= UINT_MAX/sizeof(*sc->ctts_data))
4817 return AVERROR_INVALIDDATA;
4818 if (flags & MOV_TRUN_DATA_OFFSET) data_offset = avio_rb32(pb);
4819 if (flags & MOV_TRUN_FIRST_SAMPLE_FLAGS) first_sample_flags = avio_rb32(pb);
4821 frag_stream_info = get_current_frag_stream_info(&c->frag_index);
4822 if (frag_stream_info) {
4823 if (frag_stream_info->next_trun_dts != AV_NOPTS_VALUE) {
4824 dts = frag_stream_info->next_trun_dts - sc->time_offset;
4825 } else if (frag_stream_info->first_tfra_pts != AV_NOPTS_VALUE &&
4826 c->use_mfra_for == FF_MOV_FLAG_MFRA_PTS) {
4827 pts = frag_stream_info->first_tfra_pts;
4828 av_log(c->fc, AV_LOG_DEBUG, "found mfra time %"PRId64
4829 ", using it for pts\n", pts);
4830 } else if (frag_stream_info->first_tfra_pts != AV_NOPTS_VALUE &&
4831 c->use_mfra_for == FF_MOV_FLAG_MFRA_DTS) {
4832 dts = frag_stream_info->first_tfra_pts;
4833 av_log(c->fc, AV_LOG_DEBUG, "found mfra time %"PRId64
4834 ", using it for dts\n", pts);
4835 } else if (frag_stream_info->sidx_pts != AV_NOPTS_VALUE) {
4836 // FIXME: sidx earliest_presentation_time is *PTS*, s.b.
4837 // pts = frag_stream_info->sidx_pts;
4838 dts = frag_stream_info->sidx_pts - sc->time_offset;
4839 av_log(c->fc, AV_LOG_DEBUG, "found sidx time %"PRId64
4840 ", using it for pts\n", pts);
4841 } else if (frag_stream_info->tfdt_dts != AV_NOPTS_VALUE) {
4842 dts = frag_stream_info->tfdt_dts - sc->time_offset;
4843 av_log(c->fc, AV_LOG_DEBUG, "found tfdt time %"PRId64
4844 ", using it for dts\n", dts);
4846 dts = sc->track_end - sc->time_offset;
4847 av_log(c->fc, AV_LOG_DEBUG, "found track end time %"PRId64
4848 ", using it for dts\n", dts);
4851 dts = sc->track_end - sc->time_offset;
4852 av_log(c->fc, AV_LOG_DEBUG, "found track end time %"PRId64
4853 ", using it for dts\n", dts);
4855 offset = frag->base_data_offset + data_offset;
4857 av_log(c->fc, AV_LOG_TRACE, "first sample flags 0x%x\n", first_sample_flags);
4859 // realloc space for new index entries
4860 if((uint64_t)st->internal->nb_index_entries + entries >= UINT_MAX / sizeof(AVIndexEntry)) {
4861 entries = UINT_MAX / sizeof(AVIndexEntry) - st->internal->nb_index_entries;
4862 av_log(c->fc, AV_LOG_ERROR, "Failed to add index entry\n");
4867 requested_size = (st->internal->nb_index_entries + entries) * sizeof(AVIndexEntry);
4868 new_entries = av_fast_realloc(st->internal->index_entries,
4869 &st->internal->index_entries_allocated_size,
4872 return AVERROR(ENOMEM);
4873 st->internal->index_entries= new_entries;
4875 requested_size = (st->internal->nb_index_entries + entries) * sizeof(*sc->ctts_data);
4876 old_ctts_allocated_size = sc->ctts_allocated_size;
4877 ctts_data = av_fast_realloc(sc->ctts_data, &sc->ctts_allocated_size,
4880 return AVERROR(ENOMEM);
4881 sc->ctts_data = ctts_data;
4883 // In case there were samples without ctts entries, ensure they get
4884 // zero valued entries. This ensures clips which mix boxes with and
4885 // without ctts entries don't pickup uninitialized data.
4886 memset((uint8_t*)(sc->ctts_data) + old_ctts_allocated_size, 0,
4887 sc->ctts_allocated_size - old_ctts_allocated_size);
4889 if (index_entry_pos < st->internal->nb_index_entries) {
4890 // Make hole in index_entries and ctts_data for new samples
4891 memmove(st->internal->index_entries + index_entry_pos + entries,
4892 st->internal->index_entries + index_entry_pos,
4893 sizeof(*st->internal->index_entries) *
4894 (st->internal->nb_index_entries - index_entry_pos));
4895 memmove(sc->ctts_data + index_entry_pos + entries,
4896 sc->ctts_data + index_entry_pos,
4897 sizeof(*sc->ctts_data) * (sc->ctts_count - index_entry_pos));
4898 if (index_entry_pos < sc->current_sample) {
4899 sc->current_sample += entries;
4903 st->internal->nb_index_entries += entries;
4904 sc->ctts_count = st->internal->nb_index_entries;
4906 // Record the index_entry position in frag_index of this fragment
4907 if (frag_stream_info)
4908 frag_stream_info->index_entry = index_entry_pos;
4910 if (index_entry_pos > 0)
4911 prev_dts = st->internal->index_entries[index_entry_pos-1].timestamp;
4913 for (i = 0; i < entries && !pb->eof_reached; i++) {
4914 unsigned sample_size = frag->size;
4915 int sample_flags = i ? frag->flags : first_sample_flags;
4916 unsigned sample_duration = frag->duration;
4917 unsigned ctts_duration = 0;
4919 int index_entry_flags = 0;
4921 if (flags & MOV_TRUN_SAMPLE_DURATION) sample_duration = avio_rb32(pb);
4922 if (flags & MOV_TRUN_SAMPLE_SIZE) sample_size = avio_rb32(pb);
4923 if (flags & MOV_TRUN_SAMPLE_FLAGS) sample_flags = avio_rb32(pb);
4924 if (flags & MOV_TRUN_SAMPLE_CTS) ctts_duration = avio_rb32(pb);
4926 mov_update_dts_shift(sc, ctts_duration, c->fc);
4927 if (pts != AV_NOPTS_VALUE) {
4928 dts = pts - sc->dts_shift;
4929 if (flags & MOV_TRUN_SAMPLE_CTS) {
4930 dts -= ctts_duration;
4932 dts -= sc->time_offset;
4934 av_log(c->fc, AV_LOG_DEBUG,
4935 "pts %"PRId64" calculated dts %"PRId64
4936 " sc->dts_shift %d ctts.duration %d"
4937 " sc->time_offset %"PRId64
4938 " flags & MOV_TRUN_SAMPLE_CTS %d\n",
4940 sc->dts_shift, ctts_duration,
4941 sc->time_offset, flags & MOV_TRUN_SAMPLE_CTS);
4942 pts = AV_NOPTS_VALUE;
4945 if (st->codecpar->codec_type == AVMEDIA_TYPE_AUDIO)
4949 !(sample_flags & (MOV_FRAG_SAMPLE_FLAG_IS_NON_SYNC |
4950 MOV_FRAG_SAMPLE_FLAG_DEPENDS_YES));
4953 index_entry_flags |= AVINDEX_KEYFRAME;
4955 // Fragments can overlap in time. Discard overlapping frames after
4957 if (prev_dts >= dts)
4958 index_entry_flags |= AVINDEX_DISCARD_FRAME;
4960 st->internal->index_entries[index_entry_pos].pos = offset;
4961 st->internal->index_entries[index_entry_pos].timestamp = dts;
4962 st->internal->index_entries[index_entry_pos].size= sample_size;
4963 st->internal->index_entries[index_entry_pos].min_distance= distance;
4964 st->internal->index_entries[index_entry_pos].flags = index_entry_flags;
4966 sc->ctts_data[index_entry_pos].count = 1;
4967 sc->ctts_data[index_entry_pos].duration = ctts_duration;
4970 av_log(c->fc, AV_LOG_TRACE, "AVIndex stream %d, sample %d, offset %"PRIx64", dts %"PRId64", "
4971 "size %u, distance %d, keyframe %d\n", st->index,
4972 index_entry_pos, offset, dts, sample_size, distance, keyframe);
4974 dts += sample_duration;
4975 offset += sample_size;
4976 sc->data_size += sample_size;
4978 if (sample_duration <= INT64_MAX - sc->duration_for_fps &&
4979 1 <= INT_MAX - sc->nb_frames_for_fps
4981 sc->duration_for_fps += sample_duration;
4982 sc->nb_frames_for_fps ++;
4985 if (frag_stream_info)
4986 frag_stream_info->next_trun_dts = dts + sc->time_offset;
4988 // EOF found before reading all entries. Fix the hole this would
4989 // leave in index_entries and ctts_data
4990 int gap = entries - i;
4991 memmove(st->internal->index_entries + index_entry_pos,
4992 st->internal->index_entries + index_entry_pos + gap,
4993 sizeof(*st->internal->index_entries) *
4994 (st->internal->nb_index_entries - (index_entry_pos + gap)));
4995 memmove(sc->ctts_data + index_entry_pos,
4996 sc->ctts_data + index_entry_pos + gap,
4997 sizeof(*sc->ctts_data) *
4998 (sc->ctts_count - (index_entry_pos + gap)));
5000 st->internal->nb_index_entries -= gap;
5001 sc->ctts_count -= gap;
5002 if (index_entry_pos < sc->current_sample) {
5003 sc->current_sample -= gap;
5008 // The end of this new fragment may overlap in time with the start
5009 // of the next fragment in index_entries. Mark the samples in the next
5010 // fragment that overlap with AVINDEX_DISCARD_FRAME
5011 prev_dts = AV_NOPTS_VALUE;
5012 if (index_entry_pos > 0)
5013 prev_dts = st->internal->index_entries[index_entry_pos-1].timestamp;
5014 for (i = index_entry_pos; i < st->internal->nb_index_entries; i++) {
5015 if (prev_dts < st->internal->index_entries[i].timestamp)
5017 st->internal->index_entries[i].flags |= AVINDEX_DISCARD_FRAME;
5020 // If a hole was created to insert the new index_entries into,
5021 // the index_entry recorded for all subsequent moof must
5022 // be incremented by the number of entries inserted.
5023 fix_frag_index_entries(&c->frag_index, next_frag_index,
5024 frag->track_id, entries);
5026 if (pb->eof_reached) {
5027 av_log(c->fc, AV_LOG_WARNING, "reached eof, corrupted TRUN atom\n");
5031 frag->implicit_offset = offset;
5033 sc->track_end = dts + sc->time_offset;
5034 if (st->duration < sc->track_end)
5035 st->duration = sc->track_end;
5040 static int mov_read_sidx(MOVContext *c, AVIOContext *pb, MOVAtom atom)
5042 int64_t stream_size = avio_size(pb);
5043 int64_t offset = av_sat_add64(avio_tell(pb), atom.size), pts, timestamp;
5044 uint8_t version, is_complete;
5046 unsigned i, j, track_id, item_count;
5047 AVStream *st = NULL;
5048 AVStream *ref_st = NULL;
5049 MOVStreamContext *sc, *ref_sc = NULL;
5050 AVRational timescale;
5052 version = avio_r8(pb);
5054 avpriv_request_sample(c->fc, "sidx version %u", version);
5058 avio_rb24(pb); // flags
5060 track_id = avio_rb32(pb); // Reference ID
5061 for (i = 0; i < c->fc->nb_streams; i++) {
5062 if (c->fc->streams[i]->id == track_id) {
5063 st = c->fc->streams[i];
5068 av_log(c->fc, AV_LOG_WARNING, "could not find corresponding track id %d\n", track_id);
5074 timescale = av_make_q(1, avio_rb32(pb));
5076 if (timescale.den <= 0) {
5077 av_log(c->fc, AV_LOG_ERROR, "Invalid sidx timescale 1/%d\n", timescale.den);
5078 return AVERROR_INVALIDDATA;
5082 pts = avio_rb32(pb);
5083 offadd= avio_rb32(pb);
5085 pts = avio_rb64(pb);
5086 offadd= avio_rb64(pb);
5088 if (av_sat_add64(offset, offadd) != offset + (uint64_t)offadd)
5089 return AVERROR_INVALIDDATA;
5091 offset += (uint64_t)offadd;
5093 avio_rb16(pb); // reserved
5095 item_count = avio_rb16(pb);
5097 for (i = 0; i < item_count; i++) {
5099 MOVFragmentStreamInfo * frag_stream_info;
5100 uint32_t size = avio_rb32(pb);
5101 uint32_t duration = avio_rb32(pb);
5102 if (size & 0x80000000) {
5103 avpriv_request_sample(c->fc, "sidx reference_type 1");
5104 return AVERROR_PATCHWELCOME;
5106 avio_rb32(pb); // sap_flags
5107 timestamp = av_rescale_q(pts, timescale, st->time_base);
5109 index = update_frag_index(c, offset);
5110 frag_stream_info = get_frag_stream_info(&c->frag_index, index, track_id);
5111 if (frag_stream_info)
5112 frag_stream_info->sidx_pts = timestamp;
5114 if (av_sat_add64(offset, size) != offset + size ||
5115 av_sat_add64(pts, duration) != pts + (uint64_t)duration
5117 return AVERROR_INVALIDDATA;
5122 st->duration = sc->track_end = pts;
5126 // See if the remaining bytes are just an mfra which we can ignore.
5127 is_complete = offset == stream_size;
5128 if (!is_complete && (pb->seekable & AVIO_SEEKABLE_NORMAL)) {
5130 int64_t original_pos = avio_tell(pb);
5131 if (!c->have_read_mfra_size) {
5132 if ((ret = avio_seek(pb, stream_size - 4, SEEK_SET)) < 0)
5134 c->mfra_size = avio_rb32(pb);
5135 c->have_read_mfra_size = 1;
5136 if ((ret = avio_seek(pb, original_pos, SEEK_SET)) < 0)
5139 if (offset + c->mfra_size == stream_size)
5144 // Find first entry in fragment index that came from an sidx.
5145 // This will pretty much always be the first entry.
5146 for (i = 0; i < c->frag_index.nb_items; i++) {
5147 MOVFragmentIndexItem * item = &c->frag_index.item[i];
5148 for (j = 0; ref_st == NULL && j < item->nb_stream_info; j++) {
5149 MOVFragmentStreamInfo * si;
5150 si = &item->stream_info[j];
5151 if (si->sidx_pts != AV_NOPTS_VALUE) {
5152 ref_st = c->fc->streams[j];
5153 ref_sc = ref_st->priv_data;
5158 if (ref_st) for (i = 0; i < c->fc->nb_streams; i++) {
5159 st = c->fc->streams[i];
5161 if (!sc->has_sidx) {
5162 st->duration = sc->track_end = av_rescale(ref_st->duration, sc->time_scale, ref_sc->time_scale);
5166 c->frag_index.complete = 1;
5172 /* this atom should be null (from specs), but some buggy files put the 'moov' atom inside it... */
5173 /* like the files created with Adobe Premiere 5.0, for samples see */
5174 /* http://graphics.tudelft.nl/~wouter/publications/soundtests/ */
5175 static int mov_read_wide(MOVContext *c, AVIOContext *pb, MOVAtom atom)
5180 return 0; /* continue */
5181 if (avio_rb32(pb) != 0) { /* 0 sized mdat atom... use the 'wide' atom size */
5182 avio_skip(pb, atom.size - 4);
5185 atom.type = avio_rl32(pb);
5187 if (atom.type != MKTAG('m','d','a','t')) {
5188 avio_skip(pb, atom.size);
5191 err = mov_read_mdat(c, pb, atom);
5195 static int mov_read_cmov(MOVContext *c, AVIOContext *pb, MOVAtom atom)
5200 uint8_t *moov_data; /* uncompressed data */
5201 long cmov_len, moov_len;
5204 avio_rb32(pb); /* dcom atom */
5205 if (avio_rl32(pb) != MKTAG('d','c','o','m'))
5206 return AVERROR_INVALIDDATA;
5207 if (avio_rl32(pb) != MKTAG('z','l','i','b')) {
5208 av_log(c->fc, AV_LOG_ERROR, "unknown compression for cmov atom !\n");
5209 return AVERROR_INVALIDDATA;
5211 avio_rb32(pb); /* cmvd atom */
5212 if (avio_rl32(pb) != MKTAG('c','m','v','d'))
5213 return AVERROR_INVALIDDATA;
5214 moov_len = avio_rb32(pb); /* uncompressed size */
5215 cmov_len = atom.size - 6 * 4;
5217 cmov_data = av_malloc(cmov_len);
5219 return AVERROR(ENOMEM);
5220 moov_data = av_malloc(moov_len);
5223 return AVERROR(ENOMEM);
5225 ret = ffio_read_size(pb, cmov_data, cmov_len);
5227 goto free_and_return;
5229 ret = AVERROR_INVALIDDATA;
5230 if (uncompress (moov_data, (uLongf *) &moov_len, (const Bytef *)cmov_data, cmov_len) != Z_OK)
5231 goto free_and_return;
5232 if (ffio_init_context(&ctx, moov_data, moov_len, 0, NULL, NULL, NULL, NULL) != 0)
5233 goto free_and_return;
5234 ctx.seekable = AVIO_SEEKABLE_NORMAL;
5235 atom.type = MKTAG('m','o','o','v');
5236 atom.size = moov_len;
5237 ret = mov_read_default(c, &ctx, atom);
5243 av_log(c->fc, AV_LOG_ERROR, "this file requires zlib support compiled in\n");
5244 return AVERROR(ENOSYS);
5248 /* edit list atom */
5249 static int mov_read_elst(MOVContext *c, AVIOContext *pb, MOVAtom atom)
5251 MOVStreamContext *sc;
5252 int i, edit_count, version;
5253 int64_t elst_entry_size;
5255 if (c->fc->nb_streams < 1 || c->ignore_editlist)
5257 sc = c->fc->streams[c->fc->nb_streams-1]->priv_data;
5259 version = avio_r8(pb); /* version */
5260 avio_rb24(pb); /* flags */
5261 edit_count = avio_rb32(pb); /* entries */
5264 elst_entry_size = version == 1 ? 20 : 12;
5265 if (atom.size != edit_count * elst_entry_size) {
5266 if (c->fc->strict_std_compliance >= FF_COMPLIANCE_STRICT) {
5267 av_log(c->fc, AV_LOG_ERROR, "Invalid edit list entry_count: %d for elst atom of size: %"PRId64" bytes.\n",
5268 edit_count, atom.size + 8);
5269 return AVERROR_INVALIDDATA;
5271 edit_count = atom.size / elst_entry_size;
5272 if (edit_count * elst_entry_size != atom.size) {
5273 av_log(c->fc, AV_LOG_WARNING, "ELST atom of %"PRId64" bytes, bigger than %d entries.\n", atom.size, edit_count);
5281 av_log(c->fc, AV_LOG_WARNING, "Duplicated ELST atom\n");
5282 av_free(sc->elst_data);
5284 sc->elst_data = av_malloc_array(edit_count, sizeof(*sc->elst_data));
5286 return AVERROR(ENOMEM);
5288 av_log(c->fc, AV_LOG_TRACE, "track[%u].edit_count = %i\n", c->fc->nb_streams - 1, edit_count);
5289 for (i = 0; i < edit_count && atom.size > 0 && !pb->eof_reached; i++) {
5290 MOVElst *e = &sc->elst_data[i];
5293 e->duration = avio_rb64(pb);
5294 e->time = avio_rb64(pb);
5297 e->duration = avio_rb32(pb); /* segment duration */
5298 e->time = (int32_t)avio_rb32(pb); /* media time */
5301 e->rate = avio_rb32(pb) / 65536.0;
5303 av_log(c->fc, AV_LOG_TRACE, "duration=%"PRId64" time=%"PRId64" rate=%f\n",
5304 e->duration, e->time, e->rate);
5306 if (e->time < 0 && e->time != -1 &&
5307 c->fc->strict_std_compliance >= FF_COMPLIANCE_STRICT) {
5308 av_log(c->fc, AV_LOG_ERROR, "Track %d, edit %d: Invalid edit list media time=%"PRId64"\n",
5309 c->fc->nb_streams-1, i, e->time);
5310 return AVERROR_INVALIDDATA;
5318 static int mov_read_tmcd(MOVContext *c, AVIOContext *pb, MOVAtom atom)
5320 MOVStreamContext *sc;
5322 if (c->fc->nb_streams < 1)
5323 return AVERROR_INVALIDDATA;
5324 sc = c->fc->streams[c->fc->nb_streams - 1]->priv_data;
5325 sc->timecode_track = avio_rb32(pb);
5329 static int mov_read_av1c(MOVContext *c, AVIOContext *pb, MOVAtom atom)
5334 if (c->fc->nb_streams < 1)
5336 st = c->fc->streams[c->fc->nb_streams - 1];
5338 if (atom.size < 4) {
5339 av_log(c->fc, AV_LOG_ERROR, "Empty AV1 Codec Configuration Box\n");
5340 return AVERROR_INVALIDDATA;
5343 /* For now, propagate only the OBUs, if any. Once libavcodec is
5344 updated to handle isobmff style extradata this can be removed. */
5350 ret = ff_get_extradata(c->fc, st->codecpar, pb, atom.size - 4);
5357 static int mov_read_vpcc(MOVContext *c, AVIOContext *pb, MOVAtom atom)
5360 int version, color_range, color_primaries, color_trc, color_space;
5362 if (c->fc->nb_streams < 1)
5364 st = c->fc->streams[c->fc->nb_streams - 1];
5366 if (atom.size < 5) {
5367 av_log(c->fc, AV_LOG_ERROR, "Empty VP Codec Configuration box\n");
5368 return AVERROR_INVALIDDATA;
5371 version = avio_r8(pb);
5373 av_log(c->fc, AV_LOG_WARNING, "Unsupported VP Codec Configuration box version %d\n", version);
5376 avio_skip(pb, 3); /* flags */
5378 avio_skip(pb, 2); /* profile + level */
5379 color_range = avio_r8(pb); /* bitDepth, chromaSubsampling, videoFullRangeFlag */
5380 color_primaries = avio_r8(pb);
5381 color_trc = avio_r8(pb);
5382 color_space = avio_r8(pb);
5383 if (avio_rb16(pb)) /* codecIntializationDataSize */
5384 return AVERROR_INVALIDDATA;
5386 if (!av_color_primaries_name(color_primaries))
5387 color_primaries = AVCOL_PRI_UNSPECIFIED;
5388 if (!av_color_transfer_name(color_trc))
5389 color_trc = AVCOL_TRC_UNSPECIFIED;
5390 if (!av_color_space_name(color_space))
5391 color_space = AVCOL_SPC_UNSPECIFIED;
5393 st->codecpar->color_range = (color_range & 1) ? AVCOL_RANGE_JPEG : AVCOL_RANGE_MPEG;
5394 st->codecpar->color_primaries = color_primaries;
5395 st->codecpar->color_trc = color_trc;
5396 st->codecpar->color_space = color_space;
5401 static int mov_read_smdm(MOVContext *c, AVIOContext *pb, MOVAtom atom)
5403 MOVStreamContext *sc;
5406 if (c->fc->nb_streams < 1)
5407 return AVERROR_INVALIDDATA;
5409 sc = c->fc->streams[c->fc->nb_streams - 1]->priv_data;
5411 if (atom.size < 5) {
5412 av_log(c->fc, AV_LOG_ERROR, "Empty Mastering Display Metadata box\n");
5413 return AVERROR_INVALIDDATA;
5416 version = avio_r8(pb);
5418 av_log(c->fc, AV_LOG_WARNING, "Unsupported Mastering Display Metadata box version %d\n", version);
5421 avio_skip(pb, 3); /* flags */
5423 sc->mastering = av_mastering_display_metadata_alloc();
5425 return AVERROR(ENOMEM);
5427 for (i = 0; i < 3; i++) {
5428 sc->mastering->display_primaries[i][0] = av_make_q(avio_rb16(pb), 1 << 16);
5429 sc->mastering->display_primaries[i][1] = av_make_q(avio_rb16(pb), 1 << 16);
5431 sc->mastering->white_point[0] = av_make_q(avio_rb16(pb), 1 << 16);
5432 sc->mastering->white_point[1] = av_make_q(avio_rb16(pb), 1 << 16);
5434 sc->mastering->max_luminance = av_make_q(avio_rb32(pb), 1 << 8);
5435 sc->mastering->min_luminance = av_make_q(avio_rb32(pb), 1 << 14);
5437 sc->mastering->has_primaries = 1;
5438 sc->mastering->has_luminance = 1;
5443 static int mov_read_mdcv(MOVContext *c, AVIOContext *pb, MOVAtom atom)
5445 MOVStreamContext *sc;
5446 const int mapping[3] = {1, 2, 0};
5447 const int chroma_den = 50000;
5448 const int luma_den = 10000;
5451 if (c->fc->nb_streams < 1)
5452 return AVERROR_INVALIDDATA;
5454 sc = c->fc->streams[c->fc->nb_streams - 1]->priv_data;
5456 if (atom.size < 24) {
5457 av_log(c->fc, AV_LOG_ERROR, "Invalid Mastering Display Color Volume box\n");
5458 return AVERROR_INVALIDDATA;
5461 sc->mastering = av_mastering_display_metadata_alloc();
5463 return AVERROR(ENOMEM);
5465 for (i = 0; i < 3; i++) {
5466 const int j = mapping[i];
5467 sc->mastering->display_primaries[j][0] = av_make_q(avio_rb16(pb), chroma_den);
5468 sc->mastering->display_primaries[j][1] = av_make_q(avio_rb16(pb), chroma_den);
5470 sc->mastering->white_point[0] = av_make_q(avio_rb16(pb), chroma_den);
5471 sc->mastering->white_point[1] = av_make_q(avio_rb16(pb), chroma_den);
5473 sc->mastering->max_luminance = av_make_q(avio_rb32(pb), luma_den);
5474 sc->mastering->min_luminance = av_make_q(avio_rb32(pb), luma_den);
5476 sc->mastering->has_luminance = 1;
5477 sc->mastering->has_primaries = 1;
5482 static int mov_read_coll(MOVContext *c, AVIOContext *pb, MOVAtom atom)
5484 MOVStreamContext *sc;
5487 if (c->fc->nb_streams < 1)
5488 return AVERROR_INVALIDDATA;
5490 sc = c->fc->streams[c->fc->nb_streams - 1]->priv_data;
5492 if (atom.size < 5) {
5493 av_log(c->fc, AV_LOG_ERROR, "Empty Content Light Level box\n");
5494 return AVERROR_INVALIDDATA;
5497 version = avio_r8(pb);
5499 av_log(c->fc, AV_LOG_WARNING, "Unsupported Content Light Level box version %d\n", version);
5502 avio_skip(pb, 3); /* flags */
5504 sc->coll = av_content_light_metadata_alloc(&sc->coll_size);
5506 return AVERROR(ENOMEM);
5508 sc->coll->MaxCLL = avio_rb16(pb);
5509 sc->coll->MaxFALL = avio_rb16(pb);
5514 static int mov_read_clli(MOVContext *c, AVIOContext *pb, MOVAtom atom)
5516 MOVStreamContext *sc;
5518 if (c->fc->nb_streams < 1)
5519 return AVERROR_INVALIDDATA;
5521 sc = c->fc->streams[c->fc->nb_streams - 1]->priv_data;
5523 if (atom.size < 4) {
5524 av_log(c->fc, AV_LOG_ERROR, "Empty Content Light Level Info box\n");
5525 return AVERROR_INVALIDDATA;
5528 sc->coll = av_content_light_metadata_alloc(&sc->coll_size);
5530 return AVERROR(ENOMEM);
5532 sc->coll->MaxCLL = avio_rb16(pb);
5533 sc->coll->MaxFALL = avio_rb16(pb);
5538 static int mov_read_st3d(MOVContext *c, AVIOContext *pb, MOVAtom atom)
5541 MOVStreamContext *sc;
5542 enum AVStereo3DType type;
5545 if (c->fc->nb_streams < 1)
5548 st = c->fc->streams[c->fc->nb_streams - 1];
5551 if (atom.size < 5) {
5552 av_log(c->fc, AV_LOG_ERROR, "Empty stereoscopic video box\n");
5553 return AVERROR_INVALIDDATA;
5557 return AVERROR_INVALIDDATA;
5559 avio_skip(pb, 4); /* version + flags */
5564 type = AV_STEREO3D_2D;
5567 type = AV_STEREO3D_TOPBOTTOM;
5570 type = AV_STEREO3D_SIDEBYSIDE;
5573 av_log(c->fc, AV_LOG_WARNING, "Unknown st3d mode value %d\n", mode);
5577 sc->stereo3d = av_stereo3d_alloc();
5579 return AVERROR(ENOMEM);
5581 sc->stereo3d->type = type;
5585 static int mov_read_sv3d(MOVContext *c, AVIOContext *pb, MOVAtom atom)
5588 MOVStreamContext *sc;
5589 int size, version, layout;
5590 int32_t yaw, pitch, roll;
5591 uint32_t l = 0, t = 0, r = 0, b = 0;
5592 uint32_t tag, padding = 0;
5593 enum AVSphericalProjection projection;
5595 if (c->fc->nb_streams < 1)
5598 st = c->fc->streams[c->fc->nb_streams - 1];
5601 if (atom.size < 8) {
5602 av_log(c->fc, AV_LOG_ERROR, "Empty spherical video box\n");
5603 return AVERROR_INVALIDDATA;
5606 size = avio_rb32(pb);
5607 if (size <= 12 || size > atom.size)
5608 return AVERROR_INVALIDDATA;
5610 tag = avio_rl32(pb);
5611 if (tag != MKTAG('s','v','h','d')) {
5612 av_log(c->fc, AV_LOG_ERROR, "Missing spherical video header\n");
5615 version = avio_r8(pb);
5617 av_log(c->fc, AV_LOG_WARNING, "Unknown spherical version %d\n",
5621 avio_skip(pb, 3); /* flags */
5622 avio_skip(pb, size - 12); /* metadata_source */
5624 size = avio_rb32(pb);
5625 if (size > atom.size)
5626 return AVERROR_INVALIDDATA;
5628 tag = avio_rl32(pb);
5629 if (tag != MKTAG('p','r','o','j')) {
5630 av_log(c->fc, AV_LOG_ERROR, "Missing projection box\n");
5634 size = avio_rb32(pb);
5635 if (size > atom.size)
5636 return AVERROR_INVALIDDATA;
5638 tag = avio_rl32(pb);
5639 if (tag != MKTAG('p','r','h','d')) {
5640 av_log(c->fc, AV_LOG_ERROR, "Missing projection header box\n");
5643 version = avio_r8(pb);
5645 av_log(c->fc, AV_LOG_WARNING, "Unknown spherical version %d\n",
5649 avio_skip(pb, 3); /* flags */
5651 /* 16.16 fixed point */
5652 yaw = avio_rb32(pb);
5653 pitch = avio_rb32(pb);
5654 roll = avio_rb32(pb);
5656 size = avio_rb32(pb);
5657 if (size > atom.size)
5658 return AVERROR_INVALIDDATA;
5660 tag = avio_rl32(pb);
5661 version = avio_r8(pb);
5663 av_log(c->fc, AV_LOG_WARNING, "Unknown spherical version %d\n",
5667 avio_skip(pb, 3); /* flags */
5669 case MKTAG('c','b','m','p'):
5670 layout = avio_rb32(pb);
5672 av_log(c->fc, AV_LOG_WARNING,
5673 "Unsupported cubemap layout %d\n", layout);
5676 projection = AV_SPHERICAL_CUBEMAP;
5677 padding = avio_rb32(pb);
5679 case MKTAG('e','q','u','i'):
5685 if (b >= UINT_MAX - t || r >= UINT_MAX - l) {
5686 av_log(c->fc, AV_LOG_ERROR,
5687 "Invalid bounding rectangle coordinates "
5688 "%"PRIu32",%"PRIu32",%"PRIu32",%"PRIu32"\n", l, t, r, b);
5689 return AVERROR_INVALIDDATA;
5692 if (l || t || r || b)
5693 projection = AV_SPHERICAL_EQUIRECTANGULAR_TILE;
5695 projection = AV_SPHERICAL_EQUIRECTANGULAR;
5698 av_log(c->fc, AV_LOG_ERROR, "Unknown projection type: %s\n", av_fourcc2str(tag));
5702 sc->spherical = av_spherical_alloc(&sc->spherical_size);
5704 return AVERROR(ENOMEM);
5706 sc->spherical->projection = projection;
5708 sc->spherical->yaw = yaw;
5709 sc->spherical->pitch = pitch;
5710 sc->spherical->roll = roll;
5712 sc->spherical->padding = padding;
5714 sc->spherical->bound_left = l;
5715 sc->spherical->bound_top = t;
5716 sc->spherical->bound_right = r;
5717 sc->spherical->bound_bottom = b;
5722 static int mov_parse_uuid_spherical(MOVStreamContext *sc, AVIOContext *pb, size_t len)
5725 uint8_t *buffer = av_malloc(len + 1);
5729 return AVERROR(ENOMEM);
5732 ret = ffio_read_size(pb, buffer, len);
5736 /* Check for mandatory keys and values, try to support XML as best-effort */
5737 if (!sc->spherical &&
5738 av_stristr(buffer, "<GSpherical:StitchingSoftware>") &&
5739 (val = av_stristr(buffer, "<GSpherical:Spherical>")) &&
5740 av_stristr(val, "true") &&
5741 (val = av_stristr(buffer, "<GSpherical:Stitched>")) &&
5742 av_stristr(val, "true") &&
5743 (val = av_stristr(buffer, "<GSpherical:ProjectionType>")) &&
5744 av_stristr(val, "equirectangular")) {
5745 sc->spherical = av_spherical_alloc(&sc->spherical_size);
5749 sc->spherical->projection = AV_SPHERICAL_EQUIRECTANGULAR;
5751 if (av_stristr(buffer, "<GSpherical:StereoMode>") && !sc->stereo3d) {
5752 enum AVStereo3DType mode;
5754 if (av_stristr(buffer, "left-right"))
5755 mode = AV_STEREO3D_SIDEBYSIDE;
5756 else if (av_stristr(buffer, "top-bottom"))
5757 mode = AV_STEREO3D_TOPBOTTOM;
5759 mode = AV_STEREO3D_2D;
5761 sc->stereo3d = av_stereo3d_alloc();
5765 sc->stereo3d->type = mode;
5769 val = av_stristr(buffer, "<GSpherical:InitialViewHeadingDegrees>");
5771 sc->spherical->yaw = strtol(val, NULL, 10) * (1 << 16);
5772 val = av_stristr(buffer, "<GSpherical:InitialViewPitchDegrees>");
5774 sc->spherical->pitch = strtol(val, NULL, 10) * (1 << 16);
5775 val = av_stristr(buffer, "<GSpherical:InitialViewRollDegrees>");
5777 sc->spherical->roll = strtol(val, NULL, 10) * (1 << 16);
5785 static int mov_read_uuid(MOVContext *c, AVIOContext *pb, MOVAtom atom)
5788 MOVStreamContext *sc;
5791 static const uint8_t uuid_isml_manifest[] = {
5792 0xa5, 0xd4, 0x0b, 0x30, 0xe8, 0x14, 0x11, 0xdd,
5793 0xba, 0x2f, 0x08, 0x00, 0x20, 0x0c, 0x9a, 0x66
5795 static const uint8_t uuid_xmp[] = {
5796 0xbe, 0x7a, 0xcf, 0xcb, 0x97, 0xa9, 0x42, 0xe8,
5797 0x9c, 0x71, 0x99, 0x94, 0x91, 0xe3, 0xaf, 0xac
5799 static const uint8_t uuid_spherical[] = {
5800 0xff, 0xcc, 0x82, 0x63, 0xf8, 0x55, 0x4a, 0x93,
5801 0x88, 0x14, 0x58, 0x7a, 0x02, 0x52, 0x1f, 0xdd,
5804 if (atom.size < sizeof(uuid) || atom.size >= FFMIN(INT_MAX, SIZE_MAX))
5805 return AVERROR_INVALIDDATA;
5807 if (c->fc->nb_streams < 1)
5809 st = c->fc->streams[c->fc->nb_streams - 1];
5812 ret = ffio_read_size(pb, uuid, sizeof(uuid));
5815 if (!memcmp(uuid, uuid_isml_manifest, sizeof(uuid))) {
5816 uint8_t *buffer, *ptr;
5818 size_t len = atom.size - sizeof(uuid);
5821 return AVERROR_INVALIDDATA;
5823 ret = avio_skip(pb, 4); // zeroes
5826 buffer = av_mallocz(len + 1);
5828 return AVERROR(ENOMEM);
5830 ret = ffio_read_size(pb, buffer, len);
5837 while ((ptr = av_stristr(ptr, "systemBitrate=\""))) {
5838 ptr += sizeof("systemBitrate=\"") - 1;
5839 c->bitrates_count++;
5840 c->bitrates = av_realloc_f(c->bitrates, c->bitrates_count, sizeof(*c->bitrates));
5842 c->bitrates_count = 0;
5844 return AVERROR(ENOMEM);
5847 ret = strtol(ptr, &endptr, 10);
5848 if (ret < 0 || errno || *endptr != '"') {
5849 c->bitrates[c->bitrates_count - 1] = 0;
5851 c->bitrates[c->bitrates_count - 1] = ret;
5856 } else if (!memcmp(uuid, uuid_xmp, sizeof(uuid))) {
5858 size_t len = atom.size - sizeof(uuid);
5859 if (c->export_xmp) {
5860 buffer = av_mallocz(len + 1);
5862 return AVERROR(ENOMEM);
5864 ret = ffio_read_size(pb, buffer, len);
5870 av_dict_set(&c->fc->metadata, "xmp",
5871 buffer, AV_DICT_DONT_STRDUP_VAL);
5873 // skip all uuid atom, which makes it fast for long uuid-xmp file
5874 ret = avio_skip(pb, len);
5878 } else if (!memcmp(uuid, uuid_spherical, sizeof(uuid))) {
5879 size_t len = atom.size - sizeof(uuid);
5880 ret = mov_parse_uuid_spherical(sc, pb, len);
5884 av_log(c->fc, AV_LOG_WARNING, "Invalid spherical metadata found\n");
5890 static int mov_read_free(MOVContext *c, AVIOContext *pb, MOVAtom atom)
5893 uint8_t content[16];
5898 ret = avio_read(pb, content, FFMIN(sizeof(content), atom.size));
5904 && !memcmp(content, "Anevia\x1A\x1A", 8)
5905 && c->use_mfra_for == FF_MOV_FLAG_MFRA_AUTO) {
5906 c->use_mfra_for = FF_MOV_FLAG_MFRA_PTS;
5912 static int mov_read_frma(MOVContext *c, AVIOContext *pb, MOVAtom atom)
5914 uint32_t format = avio_rl32(pb);
5915 MOVStreamContext *sc;
5919 if (c->fc->nb_streams < 1)
5921 st = c->fc->streams[c->fc->nb_streams - 1];
5926 case MKTAG('e','n','c','v'): // encrypted video
5927 case MKTAG('e','n','c','a'): // encrypted audio
5928 id = mov_codec_id(st, format);
5929 if (st->codecpar->codec_id != AV_CODEC_ID_NONE &&
5930 st->codecpar->codec_id != id) {
5931 av_log(c->fc, AV_LOG_WARNING,
5932 "ignoring 'frma' atom of '%.4s', stream has codec id %d\n",
5933 (char*)&format, st->codecpar->codec_id);
5937 st->codecpar->codec_id = id;
5938 sc->format = format;
5942 if (format != sc->format) {
5943 av_log(c->fc, AV_LOG_WARNING,
5944 "ignoring 'frma' atom of '%.4s', stream format is '%.4s'\n",
5945 (char*)&format, (char*)&sc->format);
5954 * Gets the current encryption info and associated current stream context. If
5955 * we are parsing a track fragment, this will return the specific encryption
5956 * info for this fragment; otherwise this will return the global encryption
5957 * info for the current stream.
5959 static int get_current_encryption_info(MOVContext *c, MOVEncryptionIndex **encryption_index, MOVStreamContext **sc)
5961 MOVFragmentStreamInfo *frag_stream_info;
5965 frag_stream_info = get_current_frag_stream_info(&c->frag_index);
5966 if (frag_stream_info) {
5967 for (i = 0; i < c->fc->nb_streams; i++) {
5968 if (c->fc->streams[i]->id == frag_stream_info->id) {
5969 st = c->fc->streams[i];
5973 if (i == c->fc->nb_streams)
5975 *sc = st->priv_data;
5977 if (!frag_stream_info->encryption_index) {
5978 // If this stream isn't encrypted, don't create the index.
5979 if (!(*sc)->cenc.default_encrypted_sample)
5981 frag_stream_info->encryption_index = av_mallocz(sizeof(*frag_stream_info->encryption_index));
5982 if (!frag_stream_info->encryption_index)
5983 return AVERROR(ENOMEM);
5985 *encryption_index = frag_stream_info->encryption_index;
5988 // No current track fragment, using stream level encryption info.
5990 if (c->fc->nb_streams < 1)
5992 st = c->fc->streams[c->fc->nb_streams - 1];
5993 *sc = st->priv_data;
5995 if (!(*sc)->cenc.encryption_index) {
5996 // If this stream isn't encrypted, don't create the index.
5997 if (!(*sc)->cenc.default_encrypted_sample)
5999 (*sc)->cenc.encryption_index = av_mallocz(sizeof(*frag_stream_info->encryption_index));
6000 if (!(*sc)->cenc.encryption_index)
6001 return AVERROR(ENOMEM);
6004 *encryption_index = (*sc)->cenc.encryption_index;
6009 static int mov_read_sample_encryption_info(MOVContext *c, AVIOContext *pb, MOVStreamContext *sc, AVEncryptionInfo **sample, int use_subsamples)
6012 unsigned int subsample_count;
6013 AVSubsampleEncryptionInfo *subsamples;
6015 if (!sc->cenc.default_encrypted_sample) {
6016 av_log(c->fc, AV_LOG_ERROR, "Missing schm or tenc\n");
6017 return AVERROR_INVALIDDATA;
6020 *sample = av_encryption_info_clone(sc->cenc.default_encrypted_sample);
6022 return AVERROR(ENOMEM);
6024 if (sc->cenc.per_sample_iv_size != 0) {
6025 if ((ret = ffio_read_size(pb, (*sample)->iv, sc->cenc.per_sample_iv_size)) < 0) {
6026 av_log(c->fc, AV_LOG_ERROR, "failed to read the initialization vector\n");
6027 av_encryption_info_free(*sample);
6033 if (use_subsamples) {
6034 subsample_count = avio_rb16(pb);
6035 av_free((*sample)->subsamples);
6036 (*sample)->subsamples = av_mallocz_array(subsample_count, sizeof(*subsamples));
6037 if (!(*sample)->subsamples) {
6038 av_encryption_info_free(*sample);
6040 return AVERROR(ENOMEM);
6043 for (i = 0; i < subsample_count && !pb->eof_reached; i++) {
6044 (*sample)->subsamples[i].bytes_of_clear_data = avio_rb16(pb);
6045 (*sample)->subsamples[i].bytes_of_protected_data = avio_rb32(pb);
6048 if (pb->eof_reached) {
6049 av_log(c->fc, AV_LOG_ERROR, "hit EOF while reading sub-sample encryption info\n");
6050 av_encryption_info_free(*sample);
6052 return AVERROR_INVALIDDATA;
6054 (*sample)->subsample_count = subsample_count;
6060 static int mov_read_senc(MOVContext *c, AVIOContext *pb, MOVAtom atom)
6062 AVEncryptionInfo **encrypted_samples;
6063 MOVEncryptionIndex *encryption_index;
6064 MOVStreamContext *sc;
6065 int use_subsamples, ret;
6066 unsigned int sample_count, i, alloc_size = 0;
6068 ret = get_current_encryption_info(c, &encryption_index, &sc);
6072 if (encryption_index->nb_encrypted_samples) {
6073 // This can happen if we have both saio/saiz and senc atoms.
6074 av_log(c->fc, AV_LOG_DEBUG, "Ignoring duplicate encryption info in senc\n");
6078 avio_r8(pb); /* version */
6079 use_subsamples = avio_rb24(pb) & 0x02; /* flags */
6081 sample_count = avio_rb32(pb);
6082 if (sample_count >= INT_MAX / sizeof(*encrypted_samples))
6083 return AVERROR(ENOMEM);
6085 for (i = 0; i < sample_count; i++) {
6086 unsigned int min_samples = FFMIN(FFMAX(i + 1, 1024 * 1024), sample_count);
6087 encrypted_samples = av_fast_realloc(encryption_index->encrypted_samples, &alloc_size,
6088 min_samples * sizeof(*encrypted_samples));
6089 if (encrypted_samples) {
6090 encryption_index->encrypted_samples = encrypted_samples;
6092 ret = mov_read_sample_encryption_info(
6093 c, pb, sc, &encryption_index->encrypted_samples[i], use_subsamples);
6095 ret = AVERROR(ENOMEM);
6097 if (pb->eof_reached) {
6098 av_log(c->fc, AV_LOG_ERROR, "Hit EOF while reading senc\n");
6099 ret = AVERROR_INVALIDDATA;
6104 av_encryption_info_free(encryption_index->encrypted_samples[i - 1]);
6105 av_freep(&encryption_index->encrypted_samples);
6109 encryption_index->nb_encrypted_samples = sample_count;
6114 static int mov_parse_auxiliary_info(MOVContext *c, MOVStreamContext *sc, AVIOContext *pb, MOVEncryptionIndex *encryption_index)
6116 AVEncryptionInfo **sample, **encrypted_samples;
6118 size_t sample_count, sample_info_size, i;
6120 unsigned int alloc_size = 0;
6122 if (encryption_index->nb_encrypted_samples)
6124 sample_count = encryption_index->auxiliary_info_sample_count;
6125 if (encryption_index->auxiliary_offsets_count != 1) {
6126 av_log(c->fc, AV_LOG_ERROR, "Multiple auxiliary info chunks are not supported\n");
6127 return AVERROR_PATCHWELCOME;
6129 if (sample_count >= INT_MAX / sizeof(*encrypted_samples))
6130 return AVERROR(ENOMEM);
6132 prev_pos = avio_tell(pb);
6133 if (!(pb->seekable & AVIO_SEEKABLE_NORMAL) ||
6134 avio_seek(pb, encryption_index->auxiliary_offsets[0], SEEK_SET) != encryption_index->auxiliary_offsets[0]) {
6135 av_log(c->fc, AV_LOG_INFO, "Failed to seek for auxiliary info, will only parse senc atoms for encryption info\n");
6139 for (i = 0; i < sample_count && !pb->eof_reached; i++) {
6140 unsigned int min_samples = FFMIN(FFMAX(i + 1, 1024 * 1024), sample_count);
6141 encrypted_samples = av_fast_realloc(encryption_index->encrypted_samples, &alloc_size,
6142 min_samples * sizeof(*encrypted_samples));
6143 if (!encrypted_samples) {
6144 ret = AVERROR(ENOMEM);
6147 encryption_index->encrypted_samples = encrypted_samples;
6149 sample = &encryption_index->encrypted_samples[i];
6150 sample_info_size = encryption_index->auxiliary_info_default_size
6151 ? encryption_index->auxiliary_info_default_size
6152 : encryption_index->auxiliary_info_sizes[i];
6154 ret = mov_read_sample_encryption_info(c, pb, sc, sample, sample_info_size > sc->cenc.per_sample_iv_size);
6158 if (pb->eof_reached) {
6159 av_log(c->fc, AV_LOG_ERROR, "Hit EOF while reading auxiliary info\n");
6160 ret = AVERROR_INVALIDDATA;
6162 encryption_index->nb_encrypted_samples = sample_count;
6166 avio_seek(pb, prev_pos, SEEK_SET);
6168 for (; i > 0; i--) {
6169 av_encryption_info_free(encryption_index->encrypted_samples[i - 1]);
6171 av_freep(&encryption_index->encrypted_samples);
6177 * Tries to read the given number of bytes from the stream and puts it in a
6178 * newly allocated buffer. This reads in small chunks to avoid allocating large
6179 * memory if the file contains an invalid/malicious size value.
6181 static int mov_try_read_block(AVIOContext *pb, size_t size, uint8_t **data)
6183 const unsigned int block_size = 1024 * 1024;
6184 uint8_t *buffer = NULL;
6185 unsigned int alloc_size = 0, offset = 0;
6186 while (offset < size) {
6187 unsigned int new_size =
6188 alloc_size >= INT_MAX - block_size ? INT_MAX : alloc_size + block_size;
6189 uint8_t *new_buffer = av_fast_realloc(buffer, &alloc_size, new_size);
6190 unsigned int to_read = FFMIN(size, alloc_size) - offset;
6193 return AVERROR(ENOMEM);
6195 buffer = new_buffer;
6197 if (avio_read(pb, buffer + offset, to_read) != to_read) {
6199 return AVERROR_INVALIDDATA;
6208 static int mov_read_saiz(MOVContext *c, AVIOContext *pb, MOVAtom atom)
6210 MOVEncryptionIndex *encryption_index;
6211 MOVStreamContext *sc;
6213 unsigned int sample_count, aux_info_type, aux_info_param;
6215 ret = get_current_encryption_info(c, &encryption_index, &sc);
6219 if (encryption_index->nb_encrypted_samples) {
6220 // This can happen if we have both saio/saiz and senc atoms.
6221 av_log(c->fc, AV_LOG_DEBUG, "Ignoring duplicate encryption info in saiz\n");
6225 if (encryption_index->auxiliary_info_sample_count) {
6226 av_log(c->fc, AV_LOG_ERROR, "Duplicate saiz atom\n");
6227 return AVERROR_INVALIDDATA;
6230 avio_r8(pb); /* version */
6231 if (avio_rb24(pb) & 0x01) { /* flags */
6232 aux_info_type = avio_rb32(pb);
6233 aux_info_param = avio_rb32(pb);
6234 if (sc->cenc.default_encrypted_sample) {
6235 if (aux_info_type != sc->cenc.default_encrypted_sample->scheme) {
6236 av_log(c->fc, AV_LOG_DEBUG, "Ignoring saiz box with non-zero aux_info_type\n");
6239 if (aux_info_param != 0) {
6240 av_log(c->fc, AV_LOG_DEBUG, "Ignoring saiz box with non-zero aux_info_type_parameter\n");
6244 // Didn't see 'schm' or 'tenc', so this isn't encrypted.
6245 if ((aux_info_type == MKBETAG('c','e','n','c') ||
6246 aux_info_type == MKBETAG('c','e','n','s') ||
6247 aux_info_type == MKBETAG('c','b','c','1') ||
6248 aux_info_type == MKBETAG('c','b','c','s')) &&
6249 aux_info_param == 0) {
6250 av_log(c->fc, AV_LOG_ERROR, "Saw encrypted saiz without schm/tenc\n");
6251 return AVERROR_INVALIDDATA;
6256 } else if (!sc->cenc.default_encrypted_sample) {
6257 // Didn't see 'schm' or 'tenc', so this isn't encrypted.
6261 encryption_index->auxiliary_info_default_size = avio_r8(pb);
6262 sample_count = avio_rb32(pb);
6263 encryption_index->auxiliary_info_sample_count = sample_count;
6265 if (encryption_index->auxiliary_info_default_size == 0) {
6266 ret = mov_try_read_block(pb, sample_count, &encryption_index->auxiliary_info_sizes);
6268 av_log(c->fc, AV_LOG_ERROR, "Failed to read the auxiliary info\n");
6273 if (encryption_index->auxiliary_offsets_count) {
6274 return mov_parse_auxiliary_info(c, sc, pb, encryption_index);
6280 static int mov_read_saio(MOVContext *c, AVIOContext *pb, MOVAtom atom)
6282 uint64_t *auxiliary_offsets;
6283 MOVEncryptionIndex *encryption_index;
6284 MOVStreamContext *sc;
6286 unsigned int version, entry_count, aux_info_type, aux_info_param;
6287 unsigned int alloc_size = 0;
6289 ret = get_current_encryption_info(c, &encryption_index, &sc);
6293 if (encryption_index->nb_encrypted_samples) {
6294 // This can happen if we have both saio/saiz and senc atoms.
6295 av_log(c->fc, AV_LOG_DEBUG, "Ignoring duplicate encryption info in saio\n");
6299 if (encryption_index->auxiliary_offsets_count) {
6300 av_log(c->fc, AV_LOG_ERROR, "Duplicate saio atom\n");
6301 return AVERROR_INVALIDDATA;
6304 version = avio_r8(pb); /* version */
6305 if (avio_rb24(pb) & 0x01) { /* flags */
6306 aux_info_type = avio_rb32(pb);
6307 aux_info_param = avio_rb32(pb);
6308 if (sc->cenc.default_encrypted_sample) {
6309 if (aux_info_type != sc->cenc.default_encrypted_sample->scheme) {
6310 av_log(c->fc, AV_LOG_DEBUG, "Ignoring saio box with non-zero aux_info_type\n");
6313 if (aux_info_param != 0) {
6314 av_log(c->fc, AV_LOG_DEBUG, "Ignoring saio box with non-zero aux_info_type_parameter\n");
6318 // Didn't see 'schm' or 'tenc', so this isn't encrypted.
6319 if ((aux_info_type == MKBETAG('c','e','n','c') ||
6320 aux_info_type == MKBETAG('c','e','n','s') ||
6321 aux_info_type == MKBETAG('c','b','c','1') ||
6322 aux_info_type == MKBETAG('c','b','c','s')) &&
6323 aux_info_param == 0) {
6324 av_log(c->fc, AV_LOG_ERROR, "Saw encrypted saio without schm/tenc\n");
6325 return AVERROR_INVALIDDATA;
6330 } else if (!sc->cenc.default_encrypted_sample) {
6331 // Didn't see 'schm' or 'tenc', so this isn't encrypted.
6335 entry_count = avio_rb32(pb);
6336 if (entry_count >= INT_MAX / sizeof(*auxiliary_offsets))
6337 return AVERROR(ENOMEM);
6339 for (i = 0; i < entry_count && !pb->eof_reached; i++) {
6340 unsigned int min_offsets = FFMIN(FFMAX(i + 1, 1024), entry_count);
6341 auxiliary_offsets = av_fast_realloc(
6342 encryption_index->auxiliary_offsets, &alloc_size,
6343 min_offsets * sizeof(*auxiliary_offsets));
6344 if (!auxiliary_offsets) {
6345 av_freep(&encryption_index->auxiliary_offsets);
6346 return AVERROR(ENOMEM);
6348 encryption_index->auxiliary_offsets = auxiliary_offsets;
6351 encryption_index->auxiliary_offsets[i] = avio_rb32(pb);
6353 encryption_index->auxiliary_offsets[i] = avio_rb64(pb);
6355 if (c->frag_index.current >= 0) {
6356 encryption_index->auxiliary_offsets[i] += c->fragment.base_data_offset;
6360 if (pb->eof_reached) {
6361 av_log(c->fc, AV_LOG_ERROR, "Hit EOF while reading saio\n");
6362 av_freep(&encryption_index->auxiliary_offsets);
6363 return AVERROR_INVALIDDATA;
6366 encryption_index->auxiliary_offsets_count = entry_count;
6368 if (encryption_index->auxiliary_info_sample_count) {
6369 return mov_parse_auxiliary_info(c, sc, pb, encryption_index);
6375 static int mov_read_pssh(MOVContext *c, AVIOContext *pb, MOVAtom atom)
6377 AVEncryptionInitInfo *info, *old_init_info;
6380 uint8_t *side_data, *extra_data, *old_side_data;
6381 size_t side_data_size;
6382 buffer_size_t old_side_data_size;
6384 unsigned int version, kid_count, extra_data_size, alloc_size = 0;
6386 if (c->fc->nb_streams < 1)
6388 st = c->fc->streams[c->fc->nb_streams-1];
6390 version = avio_r8(pb); /* version */
6391 avio_rb24(pb); /* flags */
6393 info = av_encryption_init_info_alloc(/* system_id_size */ 16, /* num_key_ids */ 0,
6394 /* key_id_size */ 16, /* data_size */ 0);
6396 return AVERROR(ENOMEM);
6398 if ((ret = ffio_read_size(pb, info->system_id, 16)) < 0) {
6399 av_log(c->fc, AV_LOG_ERROR, "Failed to read the system id\n");
6404 kid_count = avio_rb32(pb);
6405 if (kid_count >= INT_MAX / sizeof(*key_ids)) {
6406 ret = AVERROR(ENOMEM);
6410 for (unsigned int i = 0; i < kid_count && !pb->eof_reached; i++) {
6411 unsigned int min_kid_count = FFMIN(FFMAX(i + 1, 1024), kid_count);
6412 key_ids = av_fast_realloc(info->key_ids, &alloc_size,
6413 min_kid_count * sizeof(*key_ids));
6415 ret = AVERROR(ENOMEM);
6418 info->key_ids = key_ids;
6420 info->key_ids[i] = av_mallocz(16);
6421 if (!info->key_ids[i]) {
6422 ret = AVERROR(ENOMEM);
6425 info->num_key_ids = i + 1;
6427 if ((ret = ffio_read_size(pb, info->key_ids[i], 16)) < 0) {
6428 av_log(c->fc, AV_LOG_ERROR, "Failed to read the key id\n");
6433 if (pb->eof_reached) {
6434 av_log(c->fc, AV_LOG_ERROR, "Hit EOF while reading pssh\n");
6435 ret = AVERROR_INVALIDDATA;
6440 extra_data_size = avio_rb32(pb);
6441 ret = mov_try_read_block(pb, extra_data_size, &extra_data);
6445 av_freep(&info->data); // malloc(0) may still allocate something.
6446 info->data = extra_data;
6447 info->data_size = extra_data_size;
6449 // If there is existing initialization data, append to the list.
6450 old_side_data = av_stream_get_side_data(st, AV_PKT_DATA_ENCRYPTION_INIT_INFO, &old_side_data_size);
6451 if (old_side_data) {
6452 old_init_info = av_encryption_init_info_get_side_data(old_side_data, old_side_data_size);
6453 if (old_init_info) {
6454 // Append to the end of the list.
6455 for (AVEncryptionInitInfo *cur = old_init_info;; cur = cur->next) {
6461 info = old_init_info;
6463 // Assume existing side-data will be valid, so the only error we could get is OOM.
6464 ret = AVERROR(ENOMEM);
6469 side_data = av_encryption_init_info_add_side_data(info, &side_data_size);
6471 ret = AVERROR(ENOMEM);
6474 ret = av_stream_add_side_data(st, AV_PKT_DATA_ENCRYPTION_INIT_INFO,
6475 side_data, side_data_size);
6480 av_encryption_init_info_free(info);
6484 static int mov_read_schm(MOVContext *c, AVIOContext *pb, MOVAtom atom)
6487 MOVStreamContext *sc;
6489 if (c->fc->nb_streams < 1)
6491 st = c->fc->streams[c->fc->nb_streams-1];
6494 if (sc->pseudo_stream_id != 0) {
6495 av_log(c->fc, AV_LOG_ERROR, "schm boxes are only supported in first sample descriptor\n");
6496 return AVERROR_PATCHWELCOME;
6500 return AVERROR_INVALIDDATA;
6502 avio_rb32(pb); /* version and flags */
6504 if (!sc->cenc.default_encrypted_sample) {
6505 sc->cenc.default_encrypted_sample = av_encryption_info_alloc(0, 16, 16);
6506 if (!sc->cenc.default_encrypted_sample) {
6507 return AVERROR(ENOMEM);
6511 sc->cenc.default_encrypted_sample->scheme = avio_rb32(pb);
6515 static int mov_read_tenc(MOVContext *c, AVIOContext *pb, MOVAtom atom)
6518 MOVStreamContext *sc;
6519 unsigned int version, pattern, is_protected, iv_size;
6521 if (c->fc->nb_streams < 1)
6523 st = c->fc->streams[c->fc->nb_streams-1];
6526 if (sc->pseudo_stream_id != 0) {
6527 av_log(c->fc, AV_LOG_ERROR, "tenc atom are only supported in first sample descriptor\n");
6528 return AVERROR_PATCHWELCOME;
6531 if (!sc->cenc.default_encrypted_sample) {
6532 sc->cenc.default_encrypted_sample = av_encryption_info_alloc(0, 16, 16);
6533 if (!sc->cenc.default_encrypted_sample) {
6534 return AVERROR(ENOMEM);
6539 return AVERROR_INVALIDDATA;
6541 version = avio_r8(pb); /* version */
6542 avio_rb24(pb); /* flags */
6544 avio_r8(pb); /* reserved */
6545 pattern = avio_r8(pb);
6548 sc->cenc.default_encrypted_sample->crypt_byte_block = pattern >> 4;
6549 sc->cenc.default_encrypted_sample->skip_byte_block = pattern & 0xf;
6552 is_protected = avio_r8(pb);
6553 if (is_protected && !sc->cenc.encryption_index) {
6554 // The whole stream should be by-default encrypted.
6555 sc->cenc.encryption_index = av_mallocz(sizeof(MOVEncryptionIndex));
6556 if (!sc->cenc.encryption_index)
6557 return AVERROR(ENOMEM);
6559 sc->cenc.per_sample_iv_size = avio_r8(pb);
6560 if (sc->cenc.per_sample_iv_size != 0 && sc->cenc.per_sample_iv_size != 8 &&
6561 sc->cenc.per_sample_iv_size != 16) {
6562 av_log(c->fc, AV_LOG_ERROR, "invalid per-sample IV size value\n");
6563 return AVERROR_INVALIDDATA;
6565 if (avio_read(pb, sc->cenc.default_encrypted_sample->key_id, 16) != 16) {
6566 av_log(c->fc, AV_LOG_ERROR, "failed to read the default key ID\n");
6567 return AVERROR_INVALIDDATA;
6570 if (is_protected && !sc->cenc.per_sample_iv_size) {
6571 iv_size = avio_r8(pb);
6572 if (iv_size != 8 && iv_size != 16) {
6573 av_log(c->fc, AV_LOG_ERROR, "invalid default_constant_IV_size in tenc atom\n");
6574 return AVERROR_INVALIDDATA;
6577 if (avio_read(pb, sc->cenc.default_encrypted_sample->iv, iv_size) != iv_size) {
6578 av_log(c->fc, AV_LOG_ERROR, "failed to read the default IV\n");
6579 return AVERROR_INVALIDDATA;
6586 static int mov_read_dfla(MOVContext *c, AVIOContext *pb, MOVAtom atom)
6589 int last, type, size, ret;
6592 if (c->fc->nb_streams < 1)
6594 st = c->fc->streams[c->fc->nb_streams-1];
6596 if ((uint64_t)atom.size > (1<<30) || atom.size < 42)
6597 return AVERROR_INVALIDDATA;
6599 /* Check FlacSpecificBox version. */
6600 if (avio_r8(pb) != 0)
6601 return AVERROR_INVALIDDATA;
6603 avio_rb24(pb); /* Flags */
6605 avio_read(pb, buf, sizeof(buf));
6606 flac_parse_block_header(buf, &last, &type, &size);
6608 if (type != FLAC_METADATA_TYPE_STREAMINFO || size != FLAC_STREAMINFO_SIZE) {
6609 av_log(c->fc, AV_LOG_ERROR, "STREAMINFO must be first FLACMetadataBlock\n");
6610 return AVERROR_INVALIDDATA;
6613 ret = ff_get_extradata(c->fc, st->codecpar, pb, size);
6618 av_log(c->fc, AV_LOG_WARNING, "non-STREAMINFO FLACMetadataBlock(s) ignored\n");
6623 static int cenc_decrypt(MOVContext *c, MOVStreamContext *sc, AVEncryptionInfo *sample, uint8_t *input, int size)
6627 if (sample->scheme != MKBETAG('c','e','n','c') || sample->crypt_byte_block != 0 || sample->skip_byte_block != 0) {
6628 av_log(c->fc, AV_LOG_ERROR, "Only the 'cenc' encryption scheme is supported\n");
6629 return AVERROR_PATCHWELCOME;
6632 if (!sc->cenc.aes_ctr) {
6633 /* initialize the cipher */
6634 sc->cenc.aes_ctr = av_aes_ctr_alloc();
6635 if (!sc->cenc.aes_ctr) {
6636 return AVERROR(ENOMEM);
6639 ret = av_aes_ctr_init(sc->cenc.aes_ctr, c->decryption_key);
6645 av_aes_ctr_set_full_iv(sc->cenc.aes_ctr, sample->iv);
6647 if (!sample->subsample_count) {
6648 /* decrypt the whole packet */
6649 av_aes_ctr_crypt(sc->cenc.aes_ctr, input, input, size);
6653 for (i = 0; i < sample->subsample_count; i++) {
6654 if (sample->subsamples[i].bytes_of_clear_data + sample->subsamples[i].bytes_of_protected_data > size) {
6655 av_log(c->fc, AV_LOG_ERROR, "subsample size exceeds the packet size left\n");
6656 return AVERROR_INVALIDDATA;
6659 /* skip the clear bytes */
6660 input += sample->subsamples[i].bytes_of_clear_data;
6661 size -= sample->subsamples[i].bytes_of_clear_data;
6663 /* decrypt the encrypted bytes */
6664 av_aes_ctr_crypt(sc->cenc.aes_ctr, input, input, sample->subsamples[i].bytes_of_protected_data);
6665 input += sample->subsamples[i].bytes_of_protected_data;
6666 size -= sample->subsamples[i].bytes_of_protected_data;
6670 av_log(c->fc, AV_LOG_ERROR, "leftover packet bytes after subsample processing\n");
6671 return AVERROR_INVALIDDATA;
6677 static int cenc_filter(MOVContext *mov, AVStream* st, MOVStreamContext *sc, AVPacket *pkt, int current_index)
6679 MOVFragmentStreamInfo *frag_stream_info;
6680 MOVEncryptionIndex *encryption_index;
6681 AVEncryptionInfo *encrypted_sample;
6682 int encrypted_index, ret;
6684 frag_stream_info = get_frag_stream_info(&mov->frag_index, mov->frag_index.current, st->id);
6685 encrypted_index = current_index;
6686 encryption_index = NULL;
6687 if (frag_stream_info) {
6688 // Note this only supports encryption info in the first sample descriptor.
6689 if (mov->fragment.stsd_id == 1) {
6690 if (frag_stream_info->encryption_index) {
6691 encrypted_index = current_index - frag_stream_info->index_entry;
6692 encryption_index = frag_stream_info->encryption_index;
6694 encryption_index = sc->cenc.encryption_index;
6698 encryption_index = sc->cenc.encryption_index;
6701 if (encryption_index) {
6702 if (encryption_index->auxiliary_info_sample_count &&
6703 !encryption_index->nb_encrypted_samples) {
6704 av_log(mov->fc, AV_LOG_ERROR, "saiz atom found without saio\n");
6705 return AVERROR_INVALIDDATA;
6707 if (encryption_index->auxiliary_offsets_count &&
6708 !encryption_index->nb_encrypted_samples) {
6709 av_log(mov->fc, AV_LOG_ERROR, "saio atom found without saiz\n");
6710 return AVERROR_INVALIDDATA;
6713 if (!encryption_index->nb_encrypted_samples) {
6714 // Full-sample encryption with default settings.
6715 encrypted_sample = sc->cenc.default_encrypted_sample;
6716 } else if (encrypted_index >= 0 && encrypted_index < encryption_index->nb_encrypted_samples) {
6717 // Per-sample setting override.
6718 encrypted_sample = encryption_index->encrypted_samples[encrypted_index];
6720 av_log(mov->fc, AV_LOG_ERROR, "Incorrect number of samples in encryption info\n");
6721 return AVERROR_INVALIDDATA;
6724 if (mov->decryption_key) {
6725 return cenc_decrypt(mov, sc, encrypted_sample, pkt->data, pkt->size);
6728 uint8_t *side_data = av_encryption_info_add_side_data(encrypted_sample, &size);
6730 return AVERROR(ENOMEM);
6731 ret = av_packet_add_side_data(pkt, AV_PKT_DATA_ENCRYPTION_INFO, side_data, size);
6741 static int mov_read_dops(MOVContext *c, AVIOContext *pb, MOVAtom atom)
6743 const int OPUS_SEEK_PREROLL_MS = 80;
6749 if (c->fc->nb_streams < 1)
6751 st = c->fc->streams[c->fc->nb_streams-1];
6753 if ((uint64_t)atom.size > (1<<30) || atom.size < 11)
6754 return AVERROR_INVALIDDATA;
6756 /* Check OpusSpecificBox version. */
6757 if (avio_r8(pb) != 0) {
6758 av_log(c->fc, AV_LOG_ERROR, "unsupported OpusSpecificBox version\n");
6759 return AVERROR_INVALIDDATA;
6762 /* OpusSpecificBox size plus magic for Ogg OpusHead header. */
6763 size = atom.size + 8;
6765 if ((ret = ff_alloc_extradata(st->codecpar, size)) < 0)
6768 AV_WL32(st->codecpar->extradata, MKTAG('O','p','u','s'));
6769 AV_WL32(st->codecpar->extradata + 4, MKTAG('H','e','a','d'));
6770 AV_WB8(st->codecpar->extradata + 8, 1); /* OpusHead version */
6771 avio_read(pb, st->codecpar->extradata + 9, size - 9);
6773 /* OpusSpecificBox is stored in big-endian, but OpusHead is
6774 little-endian; aside from the preceeding magic and version they're
6775 otherwise currently identical. Data after output gain at offset 16
6776 doesn't need to be bytewapped. */
6777 pre_skip = AV_RB16(st->codecpar->extradata + 10);
6778 AV_WL16(st->codecpar->extradata + 10, pre_skip);
6779 AV_WL32(st->codecpar->extradata + 12, AV_RB32(st->codecpar->extradata + 12));
6780 AV_WL16(st->codecpar->extradata + 16, AV_RB16(st->codecpar->extradata + 16));
6782 st->codecpar->initial_padding = pre_skip;
6783 st->codecpar->seek_preroll = av_rescale_q(OPUS_SEEK_PREROLL_MS,
6784 (AVRational){1, 1000},
6785 (AVRational){1, 48000});
6790 static int mov_read_dmlp(MOVContext *c, AVIOContext *pb, MOVAtom atom)
6793 unsigned format_info;
6794 int channel_assignment, channel_assignment1, channel_assignment2;
6797 if (c->fc->nb_streams < 1)
6799 st = c->fc->streams[c->fc->nb_streams-1];
6802 return AVERROR_INVALIDDATA;
6804 format_info = avio_rb32(pb);
6806 ratebits = (format_info >> 28) & 0xF;
6807 channel_assignment1 = (format_info >> 15) & 0x1F;
6808 channel_assignment2 = format_info & 0x1FFF;
6809 if (channel_assignment2)
6810 channel_assignment = channel_assignment2;
6812 channel_assignment = channel_assignment1;
6814 st->codecpar->frame_size = 40 << (ratebits & 0x7);
6815 st->codecpar->sample_rate = mlp_samplerate(ratebits);
6816 st->codecpar->channels = truehd_channels(channel_assignment);
6817 st->codecpar->channel_layout = truehd_layout(channel_assignment);
6822 static int mov_read_dvcc_dvvc(MOVContext *c, AVIOContext *pb, MOVAtom atom)
6826 AVDOVIDecoderConfigurationRecord *dovi;
6830 if (c->fc->nb_streams < 1)
6832 st = c->fc->streams[c->fc->nb_streams-1];
6834 if ((uint64_t)atom.size > (1<<30) || atom.size < 4)
6835 return AVERROR_INVALIDDATA;
6837 dovi = av_dovi_alloc(&dovi_size);
6839 return AVERROR(ENOMEM);
6841 dovi->dv_version_major = avio_r8(pb);
6842 dovi->dv_version_minor = avio_r8(pb);
6844 buf = avio_rb16(pb);
6845 dovi->dv_profile = (buf >> 9) & 0x7f; // 7 bits
6846 dovi->dv_level = (buf >> 3) & 0x3f; // 6 bits
6847 dovi->rpu_present_flag = (buf >> 2) & 0x01; // 1 bit
6848 dovi->el_present_flag = (buf >> 1) & 0x01; // 1 bit
6849 dovi->bl_present_flag = buf & 0x01; // 1 bit
6850 if (atom.size >= 24) { // 4 + 4 + 4 * 4
6852 dovi->dv_bl_signal_compatibility_id = (buf >> 4) & 0x0f; // 4 bits
6854 // 0 stands for None
6855 // Dolby Vision V1.2.93 profiles and levels
6856 dovi->dv_bl_signal_compatibility_id = 0;
6859 ret = av_stream_add_side_data(st, AV_PKT_DATA_DOVI_CONF,
6860 (uint8_t *)dovi, dovi_size);
6866 av_log(c, AV_LOG_TRACE, "DOVI in dvcC/dvvC box, version: %d.%d, profile: %d, level: %d, "
6867 "rpu flag: %d, el flag: %d, bl flag: %d, compatibility id: %d\n",
6868 dovi->dv_version_major, dovi->dv_version_minor,
6869 dovi->dv_profile, dovi->dv_level,
6870 dovi->rpu_present_flag,
6871 dovi->el_present_flag,
6872 dovi->bl_present_flag,
6873 dovi->dv_bl_signal_compatibility_id
6879 static const MOVParseTableEntry mov_default_parse_table[] = {
6880 { MKTAG('A','C','L','R'), mov_read_aclr },
6881 { MKTAG('A','P','R','G'), mov_read_avid },
6882 { MKTAG('A','A','L','P'), mov_read_avid },
6883 { MKTAG('A','R','E','S'), mov_read_ares },
6884 { MKTAG('a','v','s','s'), mov_read_avss },
6885 { MKTAG('a','v','1','C'), mov_read_av1c },
6886 { MKTAG('c','h','p','l'), mov_read_chpl },
6887 { MKTAG('c','o','6','4'), mov_read_stco },
6888 { MKTAG('c','o','l','r'), mov_read_colr },
6889 { MKTAG('c','t','t','s'), mov_read_ctts }, /* composition time to sample */
6890 { MKTAG('d','i','n','f'), mov_read_default },
6891 { MKTAG('D','p','x','E'), mov_read_dpxe },
6892 { MKTAG('d','r','e','f'), mov_read_dref },
6893 { MKTAG('e','d','t','s'), mov_read_default },
6894 { MKTAG('e','l','s','t'), mov_read_elst },
6895 { MKTAG('e','n','d','a'), mov_read_enda },
6896 { MKTAG('f','i','e','l'), mov_read_fiel },
6897 { MKTAG('a','d','r','m'), mov_read_adrm },
6898 { MKTAG('f','t','y','p'), mov_read_ftyp },
6899 { MKTAG('g','l','b','l'), mov_read_glbl },
6900 { MKTAG('h','d','l','r'), mov_read_hdlr },
6901 { MKTAG('i','l','s','t'), mov_read_ilst },
6902 { MKTAG('j','p','2','h'), mov_read_jp2h },
6903 { MKTAG('m','d','a','t'), mov_read_mdat },
6904 { MKTAG('m','d','h','d'), mov_read_mdhd },
6905 { MKTAG('m','d','i','a'), mov_read_default },
6906 { MKTAG('m','e','t','a'), mov_read_meta },
6907 { MKTAG('m','i','n','f'), mov_read_default },
6908 { MKTAG('m','o','o','f'), mov_read_moof },
6909 { MKTAG('m','o','o','v'), mov_read_moov },
6910 { MKTAG('m','v','e','x'), mov_read_default },
6911 { MKTAG('m','v','h','d'), mov_read_mvhd },
6912 { MKTAG('S','M','I',' '), mov_read_svq3 },
6913 { MKTAG('a','l','a','c'), mov_read_alac }, /* alac specific atom */
6914 { MKTAG('a','v','c','C'), mov_read_glbl },
6915 { MKTAG('p','a','s','p'), mov_read_pasp },
6916 { MKTAG('s','i','d','x'), mov_read_sidx },
6917 { MKTAG('s','t','b','l'), mov_read_default },
6918 { MKTAG('s','t','c','o'), mov_read_stco },
6919 { MKTAG('s','t','p','s'), mov_read_stps },
6920 { MKTAG('s','t','r','f'), mov_read_strf },
6921 { MKTAG('s','t','s','c'), mov_read_stsc },
6922 { MKTAG('s','t','s','d'), mov_read_stsd }, /* sample description */
6923 { MKTAG('s','t','s','s'), mov_read_stss }, /* sync sample */
6924 { MKTAG('s','t','s','z'), mov_read_stsz }, /* sample size */
6925 { MKTAG('s','t','t','s'), mov_read_stts },
6926 { MKTAG('s','t','z','2'), mov_read_stsz }, /* compact sample size */
6927 { MKTAG('s','d','t','p'), mov_read_sdtp }, /* independent and disposable samples */
6928 { MKTAG('t','k','h','d'), mov_read_tkhd }, /* track header */
6929 { MKTAG('t','f','d','t'), mov_read_tfdt },
6930 { MKTAG('t','f','h','d'), mov_read_tfhd }, /* track fragment header */
6931 { MKTAG('t','r','a','k'), mov_read_trak },
6932 { MKTAG('t','r','a','f'), mov_read_default },
6933 { MKTAG('t','r','e','f'), mov_read_default },
6934 { MKTAG('t','m','c','d'), mov_read_tmcd },
6935 { MKTAG('c','h','a','p'), mov_read_chap },
6936 { MKTAG('t','r','e','x'), mov_read_trex },
6937 { MKTAG('t','r','u','n'), mov_read_trun },
6938 { MKTAG('u','d','t','a'), mov_read_default },
6939 { MKTAG('w','a','v','e'), mov_read_wave },
6940 { MKTAG('e','s','d','s'), mov_read_esds },
6941 { MKTAG('d','a','c','3'), mov_read_dac3 }, /* AC-3 info */
6942 { MKTAG('d','e','c','3'), mov_read_dec3 }, /* EAC-3 info */
6943 { MKTAG('d','d','t','s'), mov_read_ddts }, /* DTS audio descriptor */
6944 { MKTAG('w','i','d','e'), mov_read_wide }, /* place holder */
6945 { MKTAG('w','f','e','x'), mov_read_wfex },
6946 { MKTAG('c','m','o','v'), mov_read_cmov },
6947 { MKTAG('c','h','a','n'), mov_read_chan }, /* channel layout */
6948 { MKTAG('d','v','c','1'), mov_read_dvc1 },
6949 { MKTAG('s','b','g','p'), mov_read_sbgp },
6950 { MKTAG('h','v','c','C'), mov_read_glbl },
6951 { MKTAG('u','u','i','d'), mov_read_uuid },
6952 { MKTAG('C','i','n', 0x8e), mov_read_targa_y216 },
6953 { MKTAG('f','r','e','e'), mov_read_free },
6954 { MKTAG('-','-','-','-'), mov_read_custom },
6955 { MKTAG('s','i','n','f'), mov_read_default },
6956 { MKTAG('f','r','m','a'), mov_read_frma },
6957 { MKTAG('s','e','n','c'), mov_read_senc },
6958 { MKTAG('s','a','i','z'), mov_read_saiz },
6959 { MKTAG('s','a','i','o'), mov_read_saio },
6960 { MKTAG('p','s','s','h'), mov_read_pssh },
6961 { MKTAG('s','c','h','m'), mov_read_schm },
6962 { MKTAG('s','c','h','i'), mov_read_default },
6963 { MKTAG('t','e','n','c'), mov_read_tenc },
6964 { MKTAG('d','f','L','a'), mov_read_dfla },
6965 { MKTAG('s','t','3','d'), mov_read_st3d }, /* stereoscopic 3D video box */
6966 { MKTAG('s','v','3','d'), mov_read_sv3d }, /* spherical video box */
6967 { MKTAG('d','O','p','s'), mov_read_dops },
6968 { MKTAG('d','m','l','p'), mov_read_dmlp },
6969 { MKTAG('S','m','D','m'), mov_read_smdm },
6970 { MKTAG('C','o','L','L'), mov_read_coll },
6971 { MKTAG('v','p','c','C'), mov_read_vpcc },
6972 { MKTAG('m','d','c','v'), mov_read_mdcv },
6973 { MKTAG('c','l','l','i'), mov_read_clli },
6974 { MKTAG('d','v','c','C'), mov_read_dvcc_dvvc },
6975 { MKTAG('d','v','v','C'), mov_read_dvcc_dvvc },
6979 static int mov_read_default(MOVContext *c, AVIOContext *pb, MOVAtom atom)
6981 int64_t total_size = 0;
6985 if (c->atom_depth > 10) {
6986 av_log(c->fc, AV_LOG_ERROR, "Atoms too deeply nested\n");
6987 return AVERROR_INVALIDDATA;
6992 atom.size = INT64_MAX;
6993 while (total_size <= atom.size - 8 && !avio_feof(pb)) {
6994 int (*parse)(MOVContext*, AVIOContext*, MOVAtom) = NULL;
6997 if (atom.size >= 8) {
6998 a.size = avio_rb32(pb);
6999 a.type = avio_rl32(pb);
7000 if (((a.type == MKTAG('f','r','e','e') && c->moov_retry) ||
7001 a.type == MKTAG('h','o','o','v')) &&
7003 c->fc->strict_std_compliance < FF_COMPLIANCE_STRICT) {
7006 type = avio_rl32(pb);
7009 avio_seek(pb, -8, SEEK_CUR);
7010 if (type == MKTAG('m','v','h','d') ||
7011 type == MKTAG('c','m','o','v')) {
7012 av_log(c->fc, AV_LOG_ERROR, "Detected moov in a free or hoov atom.\n");
7013 a.type = MKTAG('m','o','o','v');
7016 if (atom.type != MKTAG('r','o','o','t') &&
7017 atom.type != MKTAG('m','o','o','v')) {
7018 if (a.type == MKTAG('t','r','a','k') ||
7019 a.type == MKTAG('m','d','a','t')) {
7020 av_log(c->fc, AV_LOG_ERROR, "Broken file, trak/mdat not at top-level\n");
7027 if (a.size == 1 && total_size + 8 <= atom.size) { /* 64 bit extended size */
7028 a.size = avio_rb64(pb) - 8;
7032 av_log(c->fc, AV_LOG_TRACE, "type:'%s' parent:'%s' sz: %"PRId64" %"PRId64" %"PRId64"\n",
7033 av_fourcc2str(a.type), av_fourcc2str(atom.type), a.size, total_size, atom.size);
7035 a.size = atom.size - total_size + 8;
7040 a.size = FFMIN(a.size, atom.size - total_size);
7042 for (i = 0; mov_default_parse_table[i].type; i++)
7043 if (mov_default_parse_table[i].type == a.type) {
7044 parse = mov_default_parse_table[i].parse;
7048 // container is user data
7049 if (!parse && (atom.type == MKTAG('u','d','t','a') ||
7050 atom.type == MKTAG('i','l','s','t')))
7051 parse = mov_read_udta_string;
7053 // Supports parsing the QuickTime Metadata Keys.
7054 // https://developer.apple.com/library/mac/documentation/QuickTime/QTFF/Metadata/Metadata.html
7055 if (!parse && c->found_hdlr_mdta &&
7056 atom.type == MKTAG('m','e','t','a') &&
7057 a.type == MKTAG('k','e','y','s') &&
7058 c->meta_keys_count == 0) {
7059 parse = mov_read_keys;
7062 if (!parse) { /* skip leaf atoms data */
7063 avio_skip(pb, a.size);
7065 int64_t start_pos = avio_tell(pb);
7067 int err = parse(c, pb, a);
7072 if (c->found_moov && c->found_mdat && a.size <= INT64_MAX - start_pos &&
7073 ((!(pb->seekable & AVIO_SEEKABLE_NORMAL) || c->fc->flags & AVFMT_FLAG_IGNIDX || c->frag_index.complete) ||
7074 start_pos + a.size == avio_size(pb))) {
7075 if (!(pb->seekable & AVIO_SEEKABLE_NORMAL) || c->fc->flags & AVFMT_FLAG_IGNIDX || c->frag_index.complete)
7076 c->next_root_atom = start_pos + a.size;
7080 left = a.size - avio_tell(pb) + start_pos;
7081 if (left > 0) /* skip garbage at atom end */
7082 avio_skip(pb, left);
7083 else if (left < 0) {
7084 av_log(c->fc, AV_LOG_WARNING,
7085 "overread end of atom '%s' by %"PRId64" bytes\n",
7086 av_fourcc2str(a.type), -left);
7087 avio_seek(pb, left, SEEK_CUR);
7091 total_size += a.size;
7094 if (total_size < atom.size && atom.size < 0x7ffff)
7095 avio_skip(pb, atom.size - total_size);
7101 static int mov_probe(const AVProbeData *p)
7106 int moov_offset = -1;
7108 /* check file header */
7113 /* ignore invalid offset */
7114 if ((offset + 8ULL) > (unsigned int)p->buf_size)
7116 size = AV_RB32(p->buf + offset);
7117 if (size == 1 && offset + 16 <= (unsigned int)p->buf_size) {
7118 size = AV_RB64(p->buf+offset + 8);
7120 } else if (size == 0) {
7121 size = p->buf_size - offset;
7123 if (size < minsize) {
7127 tag = AV_RL32(p->buf + offset + 4);
7129 /* check for obvious tags */
7130 case MKTAG('m','o','o','v'):
7131 moov_offset = offset + 4;
7132 case MKTAG('m','d','a','t'):
7133 case MKTAG('p','n','o','t'): /* detect movs with preview pics like ew.mov and april.mov */
7134 case MKTAG('u','d','t','a'): /* Packet Video PVAuthor adds this and a lot of more junk */
7135 case MKTAG('f','t','y','p'):
7136 if (tag == MKTAG('f','t','y','p') &&
7137 ( AV_RL32(p->buf + offset + 8) == MKTAG('j','p','2',' ')
7138 || AV_RL32(p->buf + offset + 8) == MKTAG('j','p','x',' ')
7140 score = FFMAX(score, 5);
7142 score = AVPROBE_SCORE_MAX;
7145 /* those are more common words, so rate then a bit less */
7146 case MKTAG('e','d','i','w'): /* xdcam files have reverted first tags */
7147 case MKTAG('w','i','d','e'):
7148 case MKTAG('f','r','e','e'):
7149 case MKTAG('j','u','n','k'):
7150 case MKTAG('p','i','c','t'):
7151 score = FFMAX(score, AVPROBE_SCORE_MAX - 5);
7153 case MKTAG(0x82,0x82,0x7f,0x7d):
7154 case MKTAG('s','k','i','p'):
7155 case MKTAG('u','u','i','d'):
7156 case MKTAG('p','r','f','l'):
7157 /* if we only find those cause probedata is too small at least rate them */
7158 score = FFMAX(score, AVPROBE_SCORE_EXTENSION);
7161 if (size > INT64_MAX - offset)
7165 if (score > AVPROBE_SCORE_MAX - 50 && moov_offset != -1) {
7166 /* moov atom in the header - we should make sure that this is not a
7167 * MOV-packed MPEG-PS */
7168 offset = moov_offset;
7170 while (offset < (p->buf_size - 16)) { /* Sufficient space */
7171 /* We found an actual hdlr atom */
7172 if (AV_RL32(p->buf + offset ) == MKTAG('h','d','l','r') &&
7173 AV_RL32(p->buf + offset + 8) == MKTAG('m','h','l','r') &&
7174 AV_RL32(p->buf + offset + 12) == MKTAG('M','P','E','G')) {
7175 av_log(NULL, AV_LOG_WARNING, "Found media data tag MPEG indicating this is a MOV-packed MPEG-PS.\n");
7176 /* We found a media handler reference atom describing an
7177 * MPEG-PS-in-MOV, return a
7178 * low score to force expanding the probe window until
7179 * mpegps_probe finds what it needs */
7191 // must be done after parsing all trak because there's no order requirement
7192 static void mov_read_chapters(AVFormatContext *s)
7194 MOVContext *mov = s->priv_data;
7196 MOVStreamContext *sc;
7201 for (j = 0; j < mov->nb_chapter_tracks; j++) {
7202 chapter_track = mov->chapter_tracks[j];
7204 for (i = 0; i < s->nb_streams; i++)
7205 if (s->streams[i]->id == chapter_track) {
7210 av_log(s, AV_LOG_ERROR, "Referenced QT chapter track not found\n");
7215 cur_pos = avio_tell(sc->pb);
7217 if (st->codecpar->codec_type == AVMEDIA_TYPE_VIDEO) {
7218 st->disposition |= AV_DISPOSITION_ATTACHED_PIC | AV_DISPOSITION_TIMED_THUMBNAILS;
7219 if (st->internal->nb_index_entries) {
7220 // Retrieve the first frame, if possible
7221 AVIndexEntry *sample = &st->internal->index_entries[0];
7222 if (avio_seek(sc->pb, sample->pos, SEEK_SET) != sample->pos) {
7223 av_log(s, AV_LOG_ERROR, "Failed to retrieve first frame\n");
7227 if (ff_add_attached_pic(s, st, sc->pb, NULL, sample->size) < 0)
7231 st->codecpar->codec_type = AVMEDIA_TYPE_DATA;
7232 st->codecpar->codec_id = AV_CODEC_ID_BIN_DATA;
7233 st->discard = AVDISCARD_ALL;
7234 for (i = 0; i < st->internal->nb_index_entries; i++) {
7235 AVIndexEntry *sample = &st->internal->index_entries[i];
7236 int64_t end = i+1 < st->internal->nb_index_entries ? st->internal->index_entries[i+1].timestamp : st->duration;
7241 if (end < sample->timestamp) {
7242 av_log(s, AV_LOG_WARNING, "ignoring stream duration which is shorter than chapters\n");
7243 end = AV_NOPTS_VALUE;
7246 if (avio_seek(sc->pb, sample->pos, SEEK_SET) != sample->pos) {
7247 av_log(s, AV_LOG_ERROR, "Chapter %d not found in file\n", i);
7251 // the first two bytes are the length of the title
7252 len = avio_rb16(sc->pb);
7253 if (len > sample->size-2)
7255 title_len = 2*len + 1;
7256 if (!(title = av_mallocz(title_len)))
7259 // The samples could theoretically be in any encoding if there's an encd
7260 // atom following, but in practice are only utf-8 or utf-16, distinguished
7261 // instead by the presence of a BOM
7265 ch = avio_rb16(sc->pb);
7267 avio_get_str16be(sc->pb, len, title, title_len);
7268 else if (ch == 0xfffe)
7269 avio_get_str16le(sc->pb, len, title, title_len);
7272 if (len == 1 || len == 2)
7275 avio_get_str(sc->pb, INT_MAX, title + 2, len - 1);
7279 avpriv_new_chapter(s, i, st->time_base, sample->timestamp, end, title);
7284 avio_seek(sc->pb, cur_pos, SEEK_SET);
7288 static int parse_timecode_in_framenum_format(AVFormatContext *s, AVStream *st,
7289 uint32_t value, int flags)
7292 char buf[AV_TIMECODE_STR_SIZE];
7293 AVRational rate = st->avg_frame_rate;
7294 int ret = av_timecode_init(&tc, rate, flags, 0, s);
7297 av_dict_set(&st->metadata, "timecode",
7298 av_timecode_make_string(&tc, buf, value), 0);
7302 static int mov_read_rtmd_track(AVFormatContext *s, AVStream *st)
7304 MOVStreamContext *sc = st->priv_data;
7305 char buf[AV_TIMECODE_STR_SIZE];
7306 int64_t cur_pos = avio_tell(sc->pb);
7307 int hh, mm, ss, ff, drop;
7309 if (!st->internal->nb_index_entries)
7312 avio_seek(sc->pb, st->internal->index_entries->pos, SEEK_SET);
7313 avio_skip(s->pb, 13);
7314 hh = avio_r8(s->pb);
7315 mm = avio_r8(s->pb);
7316 ss = avio_r8(s->pb);
7317 drop = avio_r8(s->pb);
7318 ff = avio_r8(s->pb);
7319 snprintf(buf, AV_TIMECODE_STR_SIZE, "%02d:%02d:%02d%c%02d",
7320 hh, mm, ss, drop ? ';' : ':', ff);
7321 av_dict_set(&st->metadata, "timecode", buf, 0);
7323 avio_seek(sc->pb, cur_pos, SEEK_SET);
7327 static int mov_read_timecode_track(AVFormatContext *s, AVStream *st)
7329 MOVStreamContext *sc = st->priv_data;
7331 int64_t cur_pos = avio_tell(sc->pb);
7334 if (!st->internal->nb_index_entries)
7337 avio_seek(sc->pb, st->internal->index_entries->pos, SEEK_SET);
7338 value = avio_rb32(s->pb);
7340 if (sc->tmcd_flags & 0x0001) flags |= AV_TIMECODE_FLAG_DROPFRAME;
7341 if (sc->tmcd_flags & 0x0002) flags |= AV_TIMECODE_FLAG_24HOURSMAX;
7342 if (sc->tmcd_flags & 0x0004) flags |= AV_TIMECODE_FLAG_ALLOWNEGATIVE;
7344 /* Assume Counter flag is set to 1 in tmcd track (even though it is likely
7345 * not the case) and thus assume "frame number format" instead of QT one.
7346 * No sample with tmcd track can be found with a QT timecode at the moment,
7347 * despite what the tmcd track "suggests" (Counter flag set to 0 means QT
7349 parse_timecode_in_framenum_format(s, st, value, flags);
7351 avio_seek(sc->pb, cur_pos, SEEK_SET);
7355 static void mov_free_encryption_index(MOVEncryptionIndex **index) {
7357 if (!index || !*index) return;
7358 for (i = 0; i < (*index)->nb_encrypted_samples; i++) {
7359 av_encryption_info_free((*index)->encrypted_samples[i]);
7361 av_freep(&(*index)->encrypted_samples);
7362 av_freep(&(*index)->auxiliary_info_sizes);
7363 av_freep(&(*index)->auxiliary_offsets);
7367 static int mov_read_close(AVFormatContext *s)
7369 MOVContext *mov = s->priv_data;
7372 for (i = 0; i < s->nb_streams; i++) {
7373 AVStream *st = s->streams[i];
7374 MOVStreamContext *sc = st->priv_data;
7379 av_freep(&sc->ctts_data);
7380 for (j = 0; j < sc->drefs_count; j++) {
7381 av_freep(&sc->drefs[j].path);
7382 av_freep(&sc->drefs[j].dir);
7384 av_freep(&sc->drefs);
7386 sc->drefs_count = 0;
7388 if (!sc->pb_is_copied)
7389 ff_format_io_close(s, &sc->pb);
7392 av_freep(&sc->chunk_offsets);
7393 av_freep(&sc->stsc_data);
7394 av_freep(&sc->sample_sizes);
7395 av_freep(&sc->keyframes);
7396 av_freep(&sc->stts_data);
7397 av_freep(&sc->sdtp_data);
7398 av_freep(&sc->stps_data);
7399 av_freep(&sc->elst_data);
7400 av_freep(&sc->rap_group);
7401 av_freep(&sc->display_matrix);
7402 av_freep(&sc->index_ranges);
7405 for (j = 0; j < sc->stsd_count; j++)
7406 av_free(sc->extradata[j]);
7407 av_freep(&sc->extradata);
7408 av_freep(&sc->extradata_size);
7410 mov_free_encryption_index(&sc->cenc.encryption_index);
7411 av_encryption_info_free(sc->cenc.default_encrypted_sample);
7412 av_aes_ctr_free(sc->cenc.aes_ctr);
7414 av_freep(&sc->stereo3d);
7415 av_freep(&sc->spherical);
7416 av_freep(&sc->mastering);
7417 av_freep(&sc->coll);
7420 av_freep(&mov->dv_demux);
7421 avformat_free_context(mov->dv_fctx);
7422 mov->dv_fctx = NULL;
7424 if (mov->meta_keys) {
7425 for (i = 1; i < mov->meta_keys_count; i++) {
7426 av_freep(&mov->meta_keys[i]);
7428 av_freep(&mov->meta_keys);
7431 av_freep(&mov->trex_data);
7432 av_freep(&mov->bitrates);
7434 for (i = 0; i < mov->frag_index.nb_items; i++) {
7435 MOVFragmentStreamInfo *frag = mov->frag_index.item[i].stream_info;
7436 for (j = 0; j < mov->frag_index.item[i].nb_stream_info; j++) {
7437 mov_free_encryption_index(&frag[j].encryption_index);
7439 av_freep(&mov->frag_index.item[i].stream_info);
7441 av_freep(&mov->frag_index.item);
7443 av_freep(&mov->aes_decrypt);
7444 av_freep(&mov->chapter_tracks);
7449 static int tmcd_is_referenced(AVFormatContext *s, int tmcd_id)
7453 for (i = 0; i < s->nb_streams; i++) {
7454 AVStream *st = s->streams[i];
7455 MOVStreamContext *sc = st->priv_data;
7457 if (st->codecpar->codec_type == AVMEDIA_TYPE_VIDEO &&
7458 sc->timecode_track == tmcd_id)
7464 /* look for a tmcd track not referenced by any video track, and export it globally */
7465 static void export_orphan_timecode(AVFormatContext *s)
7469 for (i = 0; i < s->nb_streams; i++) {
7470 AVStream *st = s->streams[i];
7472 if (st->codecpar->codec_tag == MKTAG('t','m','c','d') &&
7473 !tmcd_is_referenced(s, i + 1)) {
7474 AVDictionaryEntry *tcr = av_dict_get(st->metadata, "timecode", NULL, 0);
7476 av_dict_set(&s->metadata, "timecode", tcr->value, 0);
7483 static int read_tfra(MOVContext *mov, AVIOContext *f)
7485 int version, fieldlength, i, j;
7486 int64_t pos = avio_tell(f);
7487 uint32_t size = avio_rb32(f);
7488 unsigned track_id, item_count;
7490 if (avio_rb32(f) != MKBETAG('t', 'f', 'r', 'a')) {
7493 av_log(mov->fc, AV_LOG_VERBOSE, "found tfra\n");
7495 version = avio_r8(f);
7497 track_id = avio_rb32(f);
7498 fieldlength = avio_rb32(f);
7499 item_count = avio_rb32(f);
7500 for (i = 0; i < item_count; i++) {
7501 int64_t time, offset;
7503 MOVFragmentStreamInfo * frag_stream_info;
7506 return AVERROR_INVALIDDATA;
7510 time = avio_rb64(f);
7511 offset = avio_rb64(f);
7513 time = avio_rb32(f);
7514 offset = avio_rb32(f);
7517 // The first sample of each stream in a fragment is always a random
7518 // access sample. So it's entry in the tfra can be used as the
7519 // initial PTS of the fragment.
7520 index = update_frag_index(mov, offset);
7521 frag_stream_info = get_frag_stream_info(&mov->frag_index, index, track_id);
7522 if (frag_stream_info &&
7523 frag_stream_info->first_tfra_pts == AV_NOPTS_VALUE)
7524 frag_stream_info->first_tfra_pts = time;
7526 for (j = 0; j < ((fieldlength >> 4) & 3) + 1; j++)
7528 for (j = 0; j < ((fieldlength >> 2) & 3) + 1; j++)
7530 for (j = 0; j < ((fieldlength >> 0) & 3) + 1; j++)
7534 avio_seek(f, pos + size, SEEK_SET);
7538 static int mov_read_mfra(MOVContext *c, AVIOContext *f)
7540 int64_t stream_size = avio_size(f);
7541 int64_t original_pos = avio_tell(f);
7544 if ((seek_ret = avio_seek(f, stream_size - 4, SEEK_SET)) < 0) {
7548 c->mfra_size = avio_rb32(f);
7549 c->have_read_mfra_size = 1;
7550 if (!c->mfra_size || c->mfra_size > stream_size) {
7551 av_log(c->fc, AV_LOG_DEBUG, "doesn't look like mfra (unreasonable size)\n");
7554 if ((seek_ret = avio_seek(f, -((int64_t) c->mfra_size), SEEK_CUR)) < 0) {
7558 if (avio_rb32(f) != c->mfra_size) {
7559 av_log(c->fc, AV_LOG_DEBUG, "doesn't look like mfra (size mismatch)\n");
7562 if (avio_rb32(f) != MKBETAG('m', 'f', 'r', 'a')) {
7563 av_log(c->fc, AV_LOG_DEBUG, "doesn't look like mfra (tag mismatch)\n");
7566 av_log(c->fc, AV_LOG_VERBOSE, "stream has mfra\n");
7568 ret = read_tfra(c, f);
7573 c->frag_index.complete = 1;
7575 seek_ret = avio_seek(f, original_pos, SEEK_SET);
7577 av_log(c->fc, AV_LOG_ERROR,
7578 "failed to seek back after looking for mfra\n");
7584 static int mov_read_header(AVFormatContext *s)
7586 MOVContext *mov = s->priv_data;
7587 AVIOContext *pb = s->pb;
7589 MOVAtom atom = { AV_RL32("root") };
7592 if (mov->decryption_key_len != 0 && mov->decryption_key_len != AES_CTR_KEY_SIZE) {
7593 av_log(s, AV_LOG_ERROR, "Invalid decryption key len %d expected %d\n",
7594 mov->decryption_key_len, AES_CTR_KEY_SIZE);
7595 return AVERROR(EINVAL);
7599 mov->trak_index = -1;
7600 /* .mov and .mp4 aren't streamable anyway (only progressive download if moov is before mdat) */
7601 if (pb->seekable & AVIO_SEEKABLE_NORMAL)
7602 atom.size = avio_size(pb);
7604 atom.size = INT64_MAX;
7606 /* check MOV header */
7608 if (mov->moov_retry)
7609 avio_seek(pb, 0, SEEK_SET);
7610 if ((err = mov_read_default(mov, pb, atom)) < 0) {
7611 av_log(s, AV_LOG_ERROR, "error reading header\n");
7614 } while ((pb->seekable & AVIO_SEEKABLE_NORMAL) && !mov->found_moov && !mov->moov_retry++);
7615 if (!mov->found_moov) {
7616 av_log(s, AV_LOG_ERROR, "moov atom not found\n");
7617 err = AVERROR_INVALIDDATA;
7620 av_log(mov->fc, AV_LOG_TRACE, "on_parse_exit_offset=%"PRId64"\n", avio_tell(pb));
7622 if (pb->seekable & AVIO_SEEKABLE_NORMAL) {
7623 if (mov->nb_chapter_tracks > 0 && !mov->ignore_chapters)
7624 mov_read_chapters(s);
7625 for (i = 0; i < s->nb_streams; i++)
7626 if (s->streams[i]->codecpar->codec_tag == AV_RL32("tmcd")) {
7627 mov_read_timecode_track(s, s->streams[i]);
7628 } else if (s->streams[i]->codecpar->codec_tag == AV_RL32("rtmd")) {
7629 mov_read_rtmd_track(s, s->streams[i]);
7633 /* copy timecode metadata from tmcd tracks to the related video streams */
7634 for (i = 0; i < s->nb_streams; i++) {
7635 AVStream *st = s->streams[i];
7636 MOVStreamContext *sc = st->priv_data;
7637 if (sc->timecode_track > 0) {
7638 AVDictionaryEntry *tcr;
7639 int tmcd_st_id = -1;
7641 for (j = 0; j < s->nb_streams; j++)
7642 if (s->streams[j]->id == sc->timecode_track)
7645 if (tmcd_st_id < 0 || tmcd_st_id == i)
7647 tcr = av_dict_get(s->streams[tmcd_st_id]->metadata, "timecode", NULL, 0);
7649 av_dict_set(&st->metadata, "timecode", tcr->value, 0);
7652 export_orphan_timecode(s);
7654 for (i = 0; i < s->nb_streams; i++) {
7655 AVStream *st = s->streams[i];
7656 MOVStreamContext *sc = st->priv_data;
7657 fix_timescale(mov, sc);
7658 if (st->codecpar->codec_type == AVMEDIA_TYPE_AUDIO &&
7659 st->codecpar->codec_id == AV_CODEC_ID_AAC) {
7660 st->internal->skip_samples = sc->start_pad;
7662 if (st->codecpar->codec_type == AVMEDIA_TYPE_VIDEO && sc->nb_frames_for_fps > 0 && sc->duration_for_fps > 0)
7663 av_reduce(&st->avg_frame_rate.num, &st->avg_frame_rate.den,
7664 sc->time_scale*(int64_t)sc->nb_frames_for_fps, sc->duration_for_fps, INT_MAX);
7665 if (st->codecpar->codec_type == AVMEDIA_TYPE_SUBTITLE) {
7666 if (st->codecpar->width <= 0 || st->codecpar->height <= 0) {
7667 st->codecpar->width = sc->width;
7668 st->codecpar->height = sc->height;
7670 if (st->codecpar->codec_id == AV_CODEC_ID_DVD_SUBTITLE) {
7671 if ((err = mov_rewrite_dvd_sub_extradata(st)) < 0)
7675 if (mov->handbrake_version &&
7676 mov->handbrake_version <= 1000000*0 + 1000*10 + 2 && // 0.10.2
7677 st->codecpar->codec_id == AV_CODEC_ID_MP3) {
7678 av_log(s, AV_LOG_VERBOSE, "Forcing full parsing for mp3 stream\n");
7679 st->need_parsing = AVSTREAM_PARSE_FULL;
7683 if (mov->trex_data) {
7684 for (i = 0; i < s->nb_streams; i++) {
7685 AVStream *st = s->streams[i];
7686 MOVStreamContext *sc = st->priv_data;
7687 if (st->duration > 0) {
7688 if (sc->data_size > INT64_MAX / sc->time_scale / 8) {
7689 av_log(s, AV_LOG_ERROR, "Overflow during bit rate calculation %"PRId64" * 8 * %d\n",
7690 sc->data_size, sc->time_scale);
7691 err = AVERROR_INVALIDDATA;
7694 st->codecpar->bit_rate = sc->data_size * 8 * sc->time_scale / st->duration;
7699 if (mov->use_mfra_for > 0) {
7700 for (i = 0; i < s->nb_streams; i++) {
7701 AVStream *st = s->streams[i];
7702 MOVStreamContext *sc = st->priv_data;
7703 if (sc->duration_for_fps > 0) {
7704 if (sc->data_size > INT64_MAX / sc->time_scale / 8) {
7705 av_log(s, AV_LOG_ERROR, "Overflow during bit rate calculation %"PRId64" * 8 * %d\n",
7706 sc->data_size, sc->time_scale);
7707 err = AVERROR_INVALIDDATA;
7710 st->codecpar->bit_rate = sc->data_size * 8 * sc->time_scale /
7711 sc->duration_for_fps;
7716 for (i = 0; i < mov->bitrates_count && i < s->nb_streams; i++) {
7717 if (mov->bitrates[i]) {
7718 s->streams[i]->codecpar->bit_rate = mov->bitrates[i];
7722 ff_rfps_calculate(s);
7724 for (i = 0; i < s->nb_streams; i++) {
7725 AVStream *st = s->streams[i];
7726 MOVStreamContext *sc = st->priv_data;
7728 switch (st->codecpar->codec_type) {
7729 case AVMEDIA_TYPE_AUDIO:
7730 err = ff_replaygain_export(st, s->metadata);
7734 case AVMEDIA_TYPE_VIDEO:
7735 if (sc->display_matrix) {
7736 err = av_stream_add_side_data(st, AV_PKT_DATA_DISPLAYMATRIX, (uint8_t*)sc->display_matrix,
7737 sizeof(int32_t) * 9);
7741 sc->display_matrix = NULL;
7744 err = av_stream_add_side_data(st, AV_PKT_DATA_STEREO3D,
7745 (uint8_t *)sc->stereo3d,
7746 sizeof(*sc->stereo3d));
7750 sc->stereo3d = NULL;
7752 if (sc->spherical) {
7753 err = av_stream_add_side_data(st, AV_PKT_DATA_SPHERICAL,
7754 (uint8_t *)sc->spherical,
7755 sc->spherical_size);
7759 sc->spherical = NULL;
7761 if (sc->mastering) {
7762 err = av_stream_add_side_data(st, AV_PKT_DATA_MASTERING_DISPLAY_METADATA,
7763 (uint8_t *)sc->mastering,
7764 sizeof(*sc->mastering));
7768 sc->mastering = NULL;
7771 err = av_stream_add_side_data(st, AV_PKT_DATA_CONTENT_LIGHT_LEVEL,
7772 (uint8_t *)sc->coll,
7782 ff_configure_buffers_for_index(s, AV_TIME_BASE);
7784 for (i = 0; i < mov->frag_index.nb_items; i++)
7785 if (mov->frag_index.item[i].moof_offset <= mov->fragment.moof_offset)
7786 mov->frag_index.item[i].headers_read = 1;
7794 static AVIndexEntry *mov_find_next_sample(AVFormatContext *s, AVStream **st)
7796 AVIndexEntry *sample = NULL;
7797 int64_t best_dts = INT64_MAX;
7799 for (i = 0; i < s->nb_streams; i++) {
7800 AVStream *avst = s->streams[i];
7801 MOVStreamContext *msc = avst->priv_data;
7802 if (msc->pb && msc->current_sample < avst->internal->nb_index_entries) {
7803 AVIndexEntry *current_sample = &avst->internal->index_entries[msc->current_sample];
7804 int64_t dts = av_rescale(current_sample->timestamp, AV_TIME_BASE, msc->time_scale);
7805 av_log(s, AV_LOG_TRACE, "stream %d, sample %d, dts %"PRId64"\n", i, msc->current_sample, dts);
7806 if (!sample || (!(s->pb->seekable & AVIO_SEEKABLE_NORMAL) && current_sample->pos < sample->pos) ||
7807 ((s->pb->seekable & AVIO_SEEKABLE_NORMAL) &&
7808 ((msc->pb != s->pb && dts < best_dts) || (msc->pb == s->pb && dts != AV_NOPTS_VALUE &&
7809 ((FFABS(best_dts - dts) <= AV_TIME_BASE && current_sample->pos < sample->pos) ||
7810 (FFABS(best_dts - dts) > AV_TIME_BASE && dts < best_dts)))))) {
7811 sample = current_sample;
7820 static int should_retry(AVIOContext *pb, int error_code) {
7821 if (error_code == AVERROR_EOF || avio_feof(pb))
7827 static int mov_switch_root(AVFormatContext *s, int64_t target, int index)
7830 MOVContext *mov = s->priv_data;
7832 if (index >= 0 && index < mov->frag_index.nb_items)
7833 target = mov->frag_index.item[index].moof_offset;
7834 if (avio_seek(s->pb, target, SEEK_SET) != target) {
7835 av_log(mov->fc, AV_LOG_ERROR, "root atom offset 0x%"PRIx64": partial file\n", target);
7836 return AVERROR_INVALIDDATA;
7839 mov->next_root_atom = 0;
7840 if (index < 0 || index >= mov->frag_index.nb_items)
7841 index = search_frag_moof_offset(&mov->frag_index, target);
7842 if (index < mov->frag_index.nb_items &&
7843 mov->frag_index.item[index].moof_offset == target) {
7844 if (index + 1 < mov->frag_index.nb_items)
7845 mov->next_root_atom = mov->frag_index.item[index + 1].moof_offset;
7846 if (mov->frag_index.item[index].headers_read)
7848 mov->frag_index.item[index].headers_read = 1;
7851 mov->found_mdat = 0;
7853 ret = mov_read_default(mov, s->pb, (MOVAtom){ AV_RL32("root"), INT64_MAX });
7856 if (avio_feof(s->pb))
7858 av_log(s, AV_LOG_TRACE, "read fragments, offset 0x%"PRIx64"\n", avio_tell(s->pb));
7863 static int mov_change_extradata(MOVStreamContext *sc, AVPacket *pkt)
7865 uint8_t *side, *extradata;
7868 /* Save the current index. */
7869 sc->last_stsd_index = sc->stsc_data[sc->stsc_index].id - 1;
7871 /* Notify the decoder that extradata changed. */
7872 extradata_size = sc->extradata_size[sc->last_stsd_index];
7873 extradata = sc->extradata[sc->last_stsd_index];
7874 if (extradata_size > 0 && extradata) {
7875 side = av_packet_new_side_data(pkt,
7876 AV_PKT_DATA_NEW_EXTRADATA,
7879 return AVERROR(ENOMEM);
7880 memcpy(side, extradata, extradata_size);
7886 static int get_eia608_packet(AVIOContext *pb, AVPacket *pkt, int size)
7891 return AVERROR_INVALIDDATA;
7892 new_size = ((size - 8) / 2) * 3;
7893 ret = av_new_packet(pkt, new_size);
7898 for (int j = 0; j < new_size; j += 3) {
7899 pkt->data[j] = 0xFC;
7900 pkt->data[j+1] = avio_r8(pb);
7901 pkt->data[j+2] = avio_r8(pb);
7907 static int mov_read_packet(AVFormatContext *s, AVPacket *pkt)
7909 MOVContext *mov = s->priv_data;
7910 MOVStreamContext *sc;
7911 AVIndexEntry *sample;
7912 AVStream *st = NULL;
7913 int64_t current_index;
7917 sample = mov_find_next_sample(s, &st);
7918 if (!sample || (mov->next_root_atom && sample->pos > mov->next_root_atom)) {
7919 if (!mov->next_root_atom)
7921 if ((ret = mov_switch_root(s, mov->next_root_atom, -1)) < 0)
7926 /* must be done just before reading, to avoid infinite loop on sample */
7927 current_index = sc->current_index;
7928 mov_current_sample_inc(sc);
7930 if (mov->next_root_atom) {
7931 sample->pos = FFMIN(sample->pos, mov->next_root_atom);
7932 sample->size = FFMIN(sample->size, (mov->next_root_atom - sample->pos));
7935 if (st->discard != AVDISCARD_ALL) {
7936 int64_t ret64 = avio_seek(sc->pb, sample->pos, SEEK_SET);
7937 if (ret64 != sample->pos) {
7938 av_log(mov->fc, AV_LOG_ERROR, "stream %d, offset 0x%"PRIx64": partial file\n",
7939 sc->ffindex, sample->pos);
7940 if (should_retry(sc->pb, ret64)) {
7941 mov_current_sample_dec(sc);
7942 } else if (ret64 < 0) {
7945 return AVERROR_INVALIDDATA;
7948 if (st->discard == AVDISCARD_NONKEY && !(sample->flags & AVINDEX_KEYFRAME)) {
7949 av_log(mov->fc, AV_LOG_DEBUG, "Nonkey frame from stream %d discarded due to AVDISCARD_NONKEY\n", sc->ffindex);
7953 if (st->codecpar->codec_id == AV_CODEC_ID_EIA_608 && sample->size > 8)
7954 ret = get_eia608_packet(sc->pb, pkt, sample->size);
7956 ret = av_get_packet(sc->pb, pkt, sample->size);
7958 if (should_retry(sc->pb, ret)) {
7959 mov_current_sample_dec(sc);
7963 #if CONFIG_DV_DEMUXER
7964 if (mov->dv_demux && sc->dv_audio_container) {
7965 AVBufferRef *buf = pkt->buf;
7966 ret = avpriv_dv_produce_packet(mov->dv_demux, pkt, pkt->data, pkt->size, pkt->pos);
7968 av_packet_unref(pkt);
7971 ret = avpriv_dv_get_packet(mov->dv_demux, pkt);
7976 if (sc->has_palette) {
7979 pal = av_packet_new_side_data(pkt, AV_PKT_DATA_PALETTE, AVPALETTE_SIZE);
7981 av_log(mov->fc, AV_LOG_ERROR, "Cannot append palette to packet\n");
7983 memcpy(pal, sc->palette, AVPALETTE_SIZE);
7984 sc->has_palette = 0;
7987 if (st->codecpar->codec_id == AV_CODEC_ID_MP3 && !st->need_parsing && pkt->size > 4) {
7988 if (ff_mpa_check_header(AV_RB32(pkt->data)) < 0)
7989 st->need_parsing = AVSTREAM_PARSE_FULL;
7993 pkt->stream_index = sc->ffindex;
7994 pkt->dts = sample->timestamp;
7995 if (sample->flags & AVINDEX_DISCARD_FRAME) {
7996 pkt->flags |= AV_PKT_FLAG_DISCARD;
7998 if (sc->ctts_data && sc->ctts_index < sc->ctts_count) {
7999 pkt->pts = pkt->dts + sc->dts_shift + sc->ctts_data[sc->ctts_index].duration;
8000 /* update ctts context */
8002 if (sc->ctts_index < sc->ctts_count &&
8003 sc->ctts_data[sc->ctts_index].count == sc->ctts_sample) {
8005 sc->ctts_sample = 0;
8008 int64_t next_dts = (sc->current_sample < st->internal->nb_index_entries) ?
8009 st->internal->index_entries[sc->current_sample].timestamp : st->duration;
8011 if (next_dts >= pkt->dts)
8012 pkt->duration = next_dts - pkt->dts;
8013 pkt->pts = pkt->dts;
8015 if (st->discard == AVDISCARD_ALL)
8017 if (sc->sdtp_data && sc->current_sample <= sc->sdtp_count) {
8018 uint8_t sample_flags = sc->sdtp_data[sc->current_sample - 1];
8019 uint8_t sample_is_depended_on = (sample_flags >> 2) & 0x3;
8020 pkt->flags |= sample_is_depended_on == MOV_SAMPLE_DEPENDENCY_NO ? AV_PKT_FLAG_DISPOSABLE : 0;
8022 pkt->flags |= sample->flags & AVINDEX_KEYFRAME ? AV_PKT_FLAG_KEY : 0;
8023 pkt->pos = sample->pos;
8025 /* Multiple stsd handling. */
8026 if (sc->stsc_data) {
8027 /* Keep track of the stsc index for the given sample, then check
8028 * if the stsd index is different from the last used one. */
8030 if (mov_stsc_index_valid(sc->stsc_index, sc->stsc_count) &&
8031 mov_get_stsc_samples(sc, sc->stsc_index) == sc->stsc_sample) {
8033 sc->stsc_sample = 0;
8034 /* Do not check indexes after a switch. */
8035 } else if (sc->stsc_data[sc->stsc_index].id > 0 &&
8036 sc->stsc_data[sc->stsc_index].id - 1 < sc->stsd_count &&
8037 sc->stsc_data[sc->stsc_index].id - 1 != sc->last_stsd_index) {
8038 ret = mov_change_extradata(sc, pkt);
8045 aax_filter(pkt->data, pkt->size, mov);
8047 ret = cenc_filter(mov, st, sc, pkt, current_index);
8055 static int mov_seek_fragment(AVFormatContext *s, AVStream *st, int64_t timestamp)
8057 MOVContext *mov = s->priv_data;
8060 if (!mov->frag_index.complete)
8063 index = search_frag_timestamp(&mov->frag_index, st, timestamp);
8066 if (!mov->frag_index.item[index].headers_read)
8067 return mov_switch_root(s, -1, index);
8068 if (index + 1 < mov->frag_index.nb_items)
8069 mov->next_root_atom = mov->frag_index.item[index + 1].moof_offset;
8074 static int mov_seek_stream(AVFormatContext *s, AVStream *st, int64_t timestamp, int flags)
8076 MOVStreamContext *sc = st->priv_data;
8077 int sample, time_sample, ret;
8080 // Here we consider timestamp to be PTS, hence try to offset it so that we
8081 // can search over the DTS timeline.
8082 timestamp -= (sc->min_corrected_pts + sc->dts_shift);
8084 ret = mov_seek_fragment(s, st, timestamp);
8088 sample = av_index_search_timestamp(st, timestamp, flags);
8089 av_log(s, AV_LOG_TRACE, "stream %d, timestamp %"PRId64", sample %d\n", st->index, timestamp, sample);
8090 if (sample < 0 && st->internal->nb_index_entries && timestamp < st->internal->index_entries[0].timestamp)
8092 if (sample < 0) /* not sure what to do */
8093 return AVERROR_INVALIDDATA;
8094 mov_current_sample_set(sc, sample);
8095 av_log(s, AV_LOG_TRACE, "stream %d, found sample %d\n", st->index, sc->current_sample);
8096 /* adjust ctts index */
8097 if (sc->ctts_data) {
8099 for (i = 0; i < sc->ctts_count; i++) {
8100 int next = time_sample + sc->ctts_data[i].count;
8101 if (next > sc->current_sample) {
8103 sc->ctts_sample = sc->current_sample - time_sample;
8110 /* adjust stsd index */
8111 if (sc->chunk_count) {
8113 for (i = 0; i < sc->stsc_count; i++) {
8114 int64_t next = time_sample + mov_get_stsc_samples(sc, i);
8115 if (next > sc->current_sample) {
8117 sc->stsc_sample = sc->current_sample - time_sample;
8120 av_assert0(next == (int)next);
8128 static int64_t mov_get_skip_samples(AVStream *st, int sample)
8130 MOVStreamContext *sc = st->priv_data;
8131 int64_t first_ts = st->internal->index_entries[0].timestamp;
8132 int64_t ts = st->internal->index_entries[sample].timestamp;
8135 if (st->codecpar->codec_type != AVMEDIA_TYPE_AUDIO)
8138 /* compute skip samples according to stream start_pad, seek ts and first ts */
8139 off = av_rescale_q(ts - first_ts, st->time_base,
8140 (AVRational){1, st->codecpar->sample_rate});
8141 return FFMAX(sc->start_pad - off, 0);
8144 static int mov_read_seek(AVFormatContext *s, int stream_index, int64_t sample_time, int flags)
8146 MOVContext *mc = s->priv_data;
8151 if (stream_index >= s->nb_streams)
8152 return AVERROR_INVALIDDATA;
8154 st = s->streams[stream_index];
8155 sample = mov_seek_stream(s, st, sample_time, flags);
8159 if (mc->seek_individually) {
8160 /* adjust seek timestamp to found sample timestamp */
8161 int64_t seek_timestamp = st->internal->index_entries[sample].timestamp;
8162 st->internal->skip_samples = mov_get_skip_samples(st, sample);
8164 for (i = 0; i < s->nb_streams; i++) {
8168 if (stream_index == i)
8171 timestamp = av_rescale_q(seek_timestamp, s->streams[stream_index]->time_base, st->time_base);
8172 sample = mov_seek_stream(s, st, timestamp, flags);
8174 st->internal->skip_samples = mov_get_skip_samples(st, sample);
8177 for (i = 0; i < s->nb_streams; i++) {
8178 MOVStreamContext *sc;
8181 mov_current_sample_set(sc, 0);
8184 MOVStreamContext *sc;
8185 AVIndexEntry *entry = mov_find_next_sample(s, &st);
8187 return AVERROR_INVALIDDATA;
8189 if (sc->ffindex == stream_index && sc->current_sample == sample)
8191 mov_current_sample_inc(sc);
8197 #define OFFSET(x) offsetof(MOVContext, x)
8198 #define FLAGS AV_OPT_FLAG_VIDEO_PARAM | AV_OPT_FLAG_DECODING_PARAM
8199 static const AVOption mov_options[] = {
8200 {"use_absolute_path",
8201 "allow using absolute path when opening alias, this is a possible security issue",
8202 OFFSET(use_absolute_path), AV_OPT_TYPE_BOOL, {.i64 = 0},
8204 {"seek_streams_individually",
8205 "Seek each stream individually to the closest point",
8206 OFFSET(seek_individually), AV_OPT_TYPE_BOOL, { .i64 = 1 },
8208 {"ignore_editlist", "Ignore the edit list atom.", OFFSET(ignore_editlist), AV_OPT_TYPE_BOOL, {.i64 = 0},
8210 {"advanced_editlist",
8211 "Modify the AVIndex according to the editlists. Use this option to decode in the order specified by the edits.",
8212 OFFSET(advanced_editlist), AV_OPT_TYPE_BOOL, {.i64 = 1},
8214 {"ignore_chapters", "", OFFSET(ignore_chapters), AV_OPT_TYPE_BOOL, {.i64 = 0},
8217 "use mfra for fragment timestamps",
8218 OFFSET(use_mfra_for), AV_OPT_TYPE_INT, {.i64 = FF_MOV_FLAG_MFRA_AUTO},
8219 -1, FF_MOV_FLAG_MFRA_PTS, FLAGS,
8221 {"auto", "auto", 0, AV_OPT_TYPE_CONST, {.i64 = FF_MOV_FLAG_MFRA_AUTO}, 0, 0,
8222 FLAGS, "use_mfra_for" },
8223 {"dts", "dts", 0, AV_OPT_TYPE_CONST, {.i64 = FF_MOV_FLAG_MFRA_DTS}, 0, 0,
8224 FLAGS, "use_mfra_for" },
8225 {"pts", "pts", 0, AV_OPT_TYPE_CONST, {.i64 = FF_MOV_FLAG_MFRA_PTS}, 0, 0,
8226 FLAGS, "use_mfra_for" },
8227 { "export_all", "Export unrecognized metadata entries", OFFSET(export_all),
8228 AV_OPT_TYPE_BOOL, { .i64 = 0 }, 0, 1, .flags = FLAGS },
8229 { "export_xmp", "Export full XMP metadata", OFFSET(export_xmp),
8230 AV_OPT_TYPE_BOOL, { .i64 = 0 }, 0, 1, .flags = FLAGS },
8231 { "activation_bytes", "Secret bytes for Audible AAX files", OFFSET(activation_bytes),
8232 AV_OPT_TYPE_BINARY, .flags = AV_OPT_FLAG_DECODING_PARAM },
8233 { "audible_key", "AES-128 Key for Audible AAXC files", OFFSET(audible_key),
8234 AV_OPT_TYPE_BINARY, .flags = AV_OPT_FLAG_DECODING_PARAM },
8235 { "audible_iv", "AES-128 IV for Audible AAXC files", OFFSET(audible_iv),
8236 AV_OPT_TYPE_BINARY, .flags = AV_OPT_FLAG_DECODING_PARAM },
8237 { "audible_fixed_key", // extracted from libAAX_SDK.so and AAXSDKWin.dll files!
8238 "Fixed key used for handling Audible AAX files", OFFSET(audible_fixed_key),
8239 AV_OPT_TYPE_BINARY, {.str="77214d4b196a87cd520045fd20a51d67"},
8240 .flags = AV_OPT_FLAG_DECODING_PARAM },
8241 { "decryption_key", "The media decryption key (hex)", OFFSET(decryption_key), AV_OPT_TYPE_BINARY, .flags = AV_OPT_FLAG_DECODING_PARAM },
8242 { "enable_drefs", "Enable external track support.", OFFSET(enable_drefs), AV_OPT_TYPE_BOOL,
8243 {.i64 = 0}, 0, 1, FLAGS },
8248 static const AVClass mov_class = {
8249 .class_name = "mov,mp4,m4a,3gp,3g2,mj2",
8250 .item_name = av_default_item_name,
8251 .option = mov_options,
8252 .version = LIBAVUTIL_VERSION_INT,
8255 AVInputFormat ff_mov_demuxer = {
8256 .name = "mov,mp4,m4a,3gp,3g2,mj2",
8257 .long_name = NULL_IF_CONFIG_SMALL("QuickTime / MOV"),
8258 .priv_class = &mov_class,
8259 .priv_data_size = sizeof(MOVContext),
8260 .extensions = "mov,mp4,m4a,3gp,3g2,mj2,psp,m4b,ism,ismv,isma,f4v",
8261 .read_probe = mov_probe,
8262 .read_header = mov_read_header,
8263 .read_packet = mov_read_packet,
8264 .read_close = mov_read_close,
8265 .read_seek = mov_read_seek,
8266 .flags = AVFMT_NO_BYTE_SEEK | AVFMT_SEEK_TO_PTS,