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 st = avformat_new_stream(c->fc, NULL);
201 return AVERROR(ENOMEM);
202 sc = av_mallocz(sizeof(*sc));
204 return AVERROR(ENOMEM);
207 ret = av_get_packet(pb, &st->attached_pic, len);
211 if (st->attached_pic.size >= 8 && id != AV_CODEC_ID_BMP) {
212 if (AV_RB64(st->attached_pic.data) == 0x89504e470d0a1a0a) {
213 id = AV_CODEC_ID_PNG;
215 id = AV_CODEC_ID_MJPEG;
219 st->disposition |= AV_DISPOSITION_ATTACHED_PIC;
221 st->attached_pic.stream_index = st->index;
222 st->attached_pic.flags |= AV_PKT_FLAG_KEY;
224 st->codecpar->codec_type = AVMEDIA_TYPE_VIDEO;
225 st->codecpar->codec_id = id;
231 static int mov_metadata_loci(MOVContext *c, AVIOContext *pb, unsigned len)
233 char language[4] = { 0 };
234 char buf[200], place[100];
235 uint16_t langcode = 0;
236 double longitude, latitude, altitude;
237 const char *key = "location";
239 if (len < 4 + 2 + 1 + 1 + 4 + 4 + 4) {
240 av_log(c->fc, AV_LOG_ERROR, "loci too short\n");
241 return AVERROR_INVALIDDATA;
244 avio_skip(pb, 4); // version+flags
245 langcode = avio_rb16(pb);
246 ff_mov_lang_to_iso639(langcode, language);
249 len -= avio_get_str(pb, len, place, sizeof(place));
251 av_log(c->fc, AV_LOG_ERROR, "place name too long\n");
252 return AVERROR_INVALIDDATA;
254 avio_skip(pb, 1); // role
258 av_log(c->fc, AV_LOG_ERROR,
259 "loci too short (%u bytes left, need at least %d)\n", len, 12);
260 return AVERROR_INVALIDDATA;
262 longitude = ((int32_t) avio_rb32(pb)) / (float) (1 << 16);
263 latitude = ((int32_t) avio_rb32(pb)) / (float) (1 << 16);
264 altitude = ((int32_t) avio_rb32(pb)) / (float) (1 << 16);
266 // Try to output in the same format as the ?xyz field
267 snprintf(buf, sizeof(buf), "%+08.4f%+09.4f", latitude, longitude);
269 av_strlcatf(buf, sizeof(buf), "%+f", altitude);
270 av_strlcatf(buf, sizeof(buf), "/%s", place);
272 if (*language && strcmp(language, "und")) {
274 snprintf(key2, sizeof(key2), "%s-%s", key, language);
275 av_dict_set(&c->fc->metadata, key2, buf, 0);
277 c->fc->event_flags |= AVFMT_EVENT_FLAG_METADATA_UPDATED;
278 return av_dict_set(&c->fc->metadata, key, buf, 0);
281 static int mov_metadata_hmmt(MOVContext *c, AVIOContext *pb, unsigned len)
287 if (c->ignore_chapters)
290 n_hmmt = avio_rb32(pb);
291 for (i = 0; i < n_hmmt && !pb->eof_reached; i++) {
292 int moment_time = avio_rb32(pb);
293 avpriv_new_chapter(c->fc, i, av_make_q(1, 1000), moment_time, AV_NOPTS_VALUE, NULL);
298 static int mov_read_udta_string(MOVContext *c, AVIOContext *pb, MOVAtom atom)
300 char tmp_key[AV_FOURCC_MAX_STRING_SIZE] = {0};
301 char key2[32], language[4] = {0};
303 const char *key = NULL;
304 uint16_t langcode = 0;
305 uint32_t data_type = 0, str_size, str_size_alloc;
306 int (*parse)(MOVContext*, AVIOContext*, unsigned, const char*) = NULL;
311 case MKTAG( '@','P','R','M'): key = "premiere_version"; raw = 1; break;
312 case MKTAG( '@','P','R','Q'): key = "quicktime_version"; raw = 1; break;
313 case MKTAG( 'X','M','P','_'):
314 if (c->export_xmp) { key = "xmp"; raw = 1; } break;
315 case MKTAG( 'a','A','R','T'): key = "album_artist"; break;
316 case MKTAG( 'a','k','I','D'): key = "account_type";
317 parse = mov_metadata_int8_no_padding; break;
318 case MKTAG( 'a','p','I','D'): key = "account_id"; break;
319 case MKTAG( 'c','a','t','g'): key = "category"; break;
320 case MKTAG( 'c','p','i','l'): key = "compilation";
321 parse = mov_metadata_int8_no_padding; break;
322 case MKTAG( 'c','p','r','t'): key = "copyright"; break;
323 case MKTAG( 'd','e','s','c'): key = "description"; break;
324 case MKTAG( 'd','i','s','k'): key = "disc";
325 parse = mov_metadata_track_or_disc_number; break;
326 case MKTAG( 'e','g','i','d'): key = "episode_uid";
327 parse = mov_metadata_int8_no_padding; break;
328 case MKTAG( 'F','I','R','M'): key = "firmware"; raw = 1; break;
329 case MKTAG( 'g','n','r','e'): key = "genre";
330 parse = mov_metadata_gnre; break;
331 case MKTAG( 'h','d','v','d'): key = "hd_video";
332 parse = mov_metadata_int8_no_padding; break;
333 case MKTAG( 'H','M','M','T'):
334 return mov_metadata_hmmt(c, pb, atom.size);
335 case MKTAG( 'k','e','y','w'): key = "keywords"; break;
336 case MKTAG( 'l','d','e','s'): key = "synopsis"; break;
337 case MKTAG( 'l','o','c','i'):
338 return mov_metadata_loci(c, pb, atom.size);
339 case MKTAG( 'm','a','n','u'): key = "make"; break;
340 case MKTAG( 'm','o','d','l'): key = "model"; break;
341 case MKTAG( 'p','c','s','t'): key = "podcast";
342 parse = mov_metadata_int8_no_padding; break;
343 case MKTAG( 'p','g','a','p'): key = "gapless_playback";
344 parse = mov_metadata_int8_no_padding; break;
345 case MKTAG( 'p','u','r','d'): key = "purchase_date"; break;
346 case MKTAG( 'r','t','n','g'): key = "rating";
347 parse = mov_metadata_int8_no_padding; break;
348 case MKTAG( 's','o','a','a'): key = "sort_album_artist"; break;
349 case MKTAG( 's','o','a','l'): key = "sort_album"; break;
350 case MKTAG( 's','o','a','r'): key = "sort_artist"; break;
351 case MKTAG( 's','o','c','o'): key = "sort_composer"; break;
352 case MKTAG( 's','o','n','m'): key = "sort_name"; break;
353 case MKTAG( 's','o','s','n'): key = "sort_show"; break;
354 case MKTAG( 's','t','i','k'): key = "media_type";
355 parse = mov_metadata_int8_no_padding; break;
356 case MKTAG( 't','r','k','n'): key = "track";
357 parse = mov_metadata_track_or_disc_number; break;
358 case MKTAG( 't','v','e','n'): key = "episode_id"; break;
359 case MKTAG( 't','v','e','s'): key = "episode_sort";
360 parse = mov_metadata_int8_bypass_padding; break;
361 case MKTAG( 't','v','n','n'): key = "network"; break;
362 case MKTAG( 't','v','s','h'): key = "show"; break;
363 case MKTAG( 't','v','s','n'): key = "season_number";
364 parse = mov_metadata_int8_bypass_padding; break;
365 case MKTAG(0xa9,'A','R','T'): key = "artist"; break;
366 case MKTAG(0xa9,'P','R','D'): key = "producer"; break;
367 case MKTAG(0xa9,'a','l','b'): key = "album"; break;
368 case MKTAG(0xa9,'a','u','t'): key = "artist"; break;
369 case MKTAG(0xa9,'c','h','p'): key = "chapter"; break;
370 case MKTAG(0xa9,'c','m','t'): key = "comment"; break;
371 case MKTAG(0xa9,'c','o','m'): key = "composer"; break;
372 case MKTAG(0xa9,'c','p','y'): key = "copyright"; break;
373 case MKTAG(0xa9,'d','a','y'): key = "date"; break;
374 case MKTAG(0xa9,'d','i','r'): key = "director"; break;
375 case MKTAG(0xa9,'d','i','s'): key = "disclaimer"; break;
376 case MKTAG(0xa9,'e','d','1'): key = "edit_date"; break;
377 case MKTAG(0xa9,'e','n','c'): key = "encoder"; break;
378 case MKTAG(0xa9,'f','m','t'): key = "original_format"; break;
379 case MKTAG(0xa9,'g','e','n'): key = "genre"; break;
380 case MKTAG(0xa9,'g','r','p'): key = "grouping"; break;
381 case MKTAG(0xa9,'h','s','t'): key = "host_computer"; break;
382 case MKTAG(0xa9,'i','n','f'): key = "comment"; break;
383 case MKTAG(0xa9,'l','y','r'): key = "lyrics"; break;
384 case MKTAG(0xa9,'m','a','k'): key = "make"; break;
385 case MKTAG(0xa9,'m','o','d'): key = "model"; break;
386 case MKTAG(0xa9,'n','a','m'): key = "title"; break;
387 case MKTAG(0xa9,'o','p','e'): key = "original_artist"; break;
388 case MKTAG(0xa9,'p','r','d'): key = "producer"; break;
389 case MKTAG(0xa9,'p','r','f'): key = "performers"; break;
390 case MKTAG(0xa9,'r','e','q'): key = "playback_requirements"; break;
391 case MKTAG(0xa9,'s','r','c'): key = "original_source"; break;
392 case MKTAG(0xa9,'s','t','3'): key = "subtitle"; break;
393 case MKTAG(0xa9,'s','w','r'): key = "encoder"; break;
394 case MKTAG(0xa9,'t','o','o'): key = "encoder"; break;
395 case MKTAG(0xa9,'t','r','k'): key = "track"; break;
396 case MKTAG(0xa9,'u','r','l'): key = "URL"; break;
397 case MKTAG(0xa9,'w','r','n'): key = "warning"; break;
398 case MKTAG(0xa9,'w','r','t'): key = "composer"; break;
399 case MKTAG(0xa9,'x','y','z'): key = "location"; break;
402 if (c->itunes_metadata && atom.size > 8) {
403 int data_size = avio_rb32(pb);
404 int tag = avio_rl32(pb);
405 if (tag == MKTAG('d','a','t','a') && data_size <= atom.size) {
406 data_type = avio_rb32(pb); // type
407 avio_rb32(pb); // unknown
408 str_size = data_size - 16;
411 if (atom.type == MKTAG('c', 'o', 'v', 'r')) {
412 int ret = mov_read_covr(c, pb, data_type, str_size);
414 av_log(c->fc, AV_LOG_ERROR, "Error parsing cover art.\n");
417 atom.size -= str_size;
421 } else if (!key && c->found_hdlr_mdta && c->meta_keys) {
422 uint32_t index = AV_RB32(&atom.type);
423 if (index < c->meta_keys_count && index > 0) {
424 key = c->meta_keys[index];
426 av_log(c->fc, AV_LOG_WARNING,
427 "The index of 'data' is out of range: %"PRId32" < 1 or >= %d.\n",
428 index, c->meta_keys_count);
432 } else if (atom.size > 4 && key && !c->itunes_metadata && !raw) {
433 str_size = avio_rb16(pb); // string length
434 if (str_size > atom.size) {
436 avio_seek(pb, -2, SEEK_CUR);
437 av_log(c->fc, AV_LOG_WARNING, "UDTA parsing failed retrying raw\n");
440 langcode = avio_rb16(pb);
441 ff_mov_lang_to_iso639(langcode, language);
444 str_size = atom.size;
446 if (c->export_all && !key) {
447 key = av_fourcc_make_string(tmp_key, atom.type);
452 if (atom.size < 0 || str_size >= INT_MAX/2)
453 return AVERROR_INVALIDDATA;
455 // Allocates enough space if data_type is a int32 or float32 number, otherwise
456 // worst-case requirement for output string in case of utf8 coded input
457 num = (data_type >= 21 && data_type <= 23);
458 str_size_alloc = (num ? 512 : (raw ? str_size : str_size * 2)) + 1;
459 str = av_mallocz(str_size_alloc);
461 return AVERROR(ENOMEM);
464 parse(c, pb, str_size, key);
466 if (!raw && (data_type == 3 || (data_type == 0 && (langcode < 0x400 || langcode == 0x7fff)))) { // MAC Encoded
467 mov_read_mac_string(c, pb, str_size, str, str_size_alloc);
468 } else if (data_type == 21) { // BE signed integer, variable size
471 val = (int8_t)avio_r8(pb);
472 else if (str_size == 2)
473 val = (int16_t)avio_rb16(pb);
474 else if (str_size == 3)
475 val = ((int32_t)(avio_rb24(pb)<<8))>>8;
476 else if (str_size == 4)
477 val = (int32_t)avio_rb32(pb);
478 if (snprintf(str, str_size_alloc, "%d", val) >= str_size_alloc) {
479 av_log(c->fc, AV_LOG_ERROR,
480 "Failed to store the number (%d) in string.\n", val);
482 return AVERROR_INVALIDDATA;
484 } else if (data_type == 22) { // BE unsigned integer, variable size
485 unsigned int val = 0;
488 else if (str_size == 2)
490 else if (str_size == 3)
492 else if (str_size == 4)
494 if (snprintf(str, str_size_alloc, "%u", val) >= str_size_alloc) {
495 av_log(c->fc, AV_LOG_ERROR,
496 "Failed to store the number (%u) in string.\n", val);
498 return AVERROR_INVALIDDATA;
500 } else if (data_type == 23 && str_size >= 4) { // BE float32
501 float val = av_int2float(avio_rb32(pb));
502 if (snprintf(str, str_size_alloc, "%f", val) >= str_size_alloc) {
503 av_log(c->fc, AV_LOG_ERROR,
504 "Failed to store the float32 number (%f) in string.\n", val);
506 return AVERROR_INVALIDDATA;
509 int ret = ffio_read_size(pb, str, str_size);
516 c->fc->event_flags |= AVFMT_EVENT_FLAG_METADATA_UPDATED;
517 av_dict_set(&c->fc->metadata, key, str, 0);
518 if (*language && strcmp(language, "und")) {
519 snprintf(key2, sizeof(key2), "%s-%s", key, language);
520 av_dict_set(&c->fc->metadata, key2, str, 0);
522 if (!strcmp(key, "encoder")) {
523 int major, minor, micro;
524 if (sscanf(str, "HandBrake %d.%d.%d", &major, &minor, µ) == 3) {
525 c->handbrake_version = 1000000*major + 1000*minor + micro;
534 static int mov_read_chpl(MOVContext *c, AVIOContext *pb, MOVAtom atom)
537 int i, nb_chapters, str_len, version;
541 if (c->ignore_chapters)
544 if ((atom.size -= 5) < 0)
547 version = avio_r8(pb);
550 avio_rb32(pb); // ???
551 nb_chapters = avio_r8(pb);
553 for (i = 0; i < nb_chapters; i++) {
557 start = avio_rb64(pb);
558 str_len = avio_r8(pb);
560 if ((atom.size -= 9+str_len) < 0)
563 ret = ffio_read_size(pb, str, str_len);
567 avpriv_new_chapter(c->fc, i, (AVRational){1,10000000}, start, AV_NOPTS_VALUE, str);
572 #define MIN_DATA_ENTRY_BOX_SIZE 12
573 static int mov_read_dref(MOVContext *c, AVIOContext *pb, MOVAtom atom)
576 MOVStreamContext *sc;
579 if (c->fc->nb_streams < 1)
581 st = c->fc->streams[c->fc->nb_streams-1];
584 avio_rb32(pb); // version + flags
585 entries = avio_rb32(pb);
587 entries > (atom.size - 1) / MIN_DATA_ENTRY_BOX_SIZE + 1 ||
588 entries >= UINT_MAX / sizeof(*sc->drefs))
589 return AVERROR_INVALIDDATA;
591 for (i = 0; i < sc->drefs_count; i++) {
592 MOVDref *dref = &sc->drefs[i];
593 av_freep(&dref->path);
594 av_freep(&dref->dir);
598 sc->drefs = av_mallocz(entries * sizeof(*sc->drefs));
600 return AVERROR(ENOMEM);
601 sc->drefs_count = entries;
603 for (i = 0; i < entries; i++) {
604 MOVDref *dref = &sc->drefs[i];
605 uint32_t size = avio_rb32(pb);
606 int64_t next = avio_tell(pb) + size - 4;
609 return AVERROR_INVALIDDATA;
611 dref->type = avio_rl32(pb);
612 avio_rb32(pb); // version + flags
614 if (dref->type == MKTAG('a','l','i','s') && size > 150) {
615 /* macintosh alias record */
616 uint16_t volume_len, len;
622 volume_len = avio_r8(pb);
623 volume_len = FFMIN(volume_len, 27);
624 ret = ffio_read_size(pb, dref->volume, 27);
627 dref->volume[volume_len] = 0;
628 av_log(c->fc, AV_LOG_DEBUG, "volume %s, len %d\n", dref->volume, volume_len);
633 len = FFMIN(len, 63);
634 ret = ffio_read_size(pb, dref->filename, 63);
637 dref->filename[len] = 0;
638 av_log(c->fc, AV_LOG_DEBUG, "filename %s, len %d\n", dref->filename, len);
642 /* read next level up_from_alias/down_to_target */
643 dref->nlvl_from = avio_rb16(pb);
644 dref->nlvl_to = avio_rb16(pb);
645 av_log(c->fc, AV_LOG_DEBUG, "nlvl from %d, nlvl to %d\n",
646 dref->nlvl_from, dref->nlvl_to);
650 for (type = 0; type != -1 && avio_tell(pb) < next; ) {
653 type = avio_rb16(pb);
655 av_log(c->fc, AV_LOG_DEBUG, "type %d, len %d\n", type, len);
658 if (type == 2) { // absolute path
660 dref->path = av_mallocz(len+1);
662 return AVERROR(ENOMEM);
664 ret = ffio_read_size(pb, dref->path, len);
666 av_freep(&dref->path);
669 if (len > volume_len && !strncmp(dref->path, dref->volume, volume_len)) {
671 memmove(dref->path, dref->path+volume_len, len);
674 // trim string of any ending zeros
675 for (j = len - 1; j >= 0; j--) {
676 if (dref->path[j] == 0)
681 for (j = 0; j < len; j++)
682 if (dref->path[j] == ':' || dref->path[j] == 0)
684 av_log(c->fc, AV_LOG_DEBUG, "path %s\n", dref->path);
685 } else if (type == 0) { // directory name
687 dref->dir = av_malloc(len+1);
689 return AVERROR(ENOMEM);
691 ret = ffio_read_size(pb, dref->dir, len);
693 av_freep(&dref->dir);
697 for (j = 0; j < len; j++)
698 if (dref->dir[j] == ':')
700 av_log(c->fc, AV_LOG_DEBUG, "dir %s\n", dref->dir);
705 av_log(c->fc, AV_LOG_DEBUG, "Unknown dref type 0x%08"PRIx32" size %"PRIu32"\n",
710 avio_seek(pb, next, SEEK_SET);
715 static int mov_read_hdlr(MOVContext *c, AVIOContext *pb, MOVAtom atom)
724 avio_r8(pb); /* version */
725 avio_rb24(pb); /* flags */
728 ctype = avio_rl32(pb);
729 type = avio_rl32(pb); /* component subtype */
731 av_log(c->fc, AV_LOG_TRACE, "ctype=%s\n", av_fourcc2str(ctype));
732 av_log(c->fc, AV_LOG_TRACE, "stype=%s\n", av_fourcc2str(type));
734 if (c->trak_index < 0) { // meta not inside a trak
735 if (type == MKTAG('m','d','t','a')) {
736 c->found_hdlr_mdta = 1;
741 st = c->fc->streams[c->fc->nb_streams-1];
743 if (type == MKTAG('v','i','d','e'))
744 st->codecpar->codec_type = AVMEDIA_TYPE_VIDEO;
745 else if (type == MKTAG('s','o','u','n'))
746 st->codecpar->codec_type = AVMEDIA_TYPE_AUDIO;
747 else if (type == MKTAG('m','1','a',' '))
748 st->codecpar->codec_id = AV_CODEC_ID_MP2;
749 else if ((type == MKTAG('s','u','b','p')) || (type == MKTAG('c','l','c','p')))
750 st->codecpar->codec_type = AVMEDIA_TYPE_SUBTITLE;
752 avio_rb32(pb); /* component manufacture */
753 avio_rb32(pb); /* component flags */
754 avio_rb32(pb); /* component flags mask */
756 title_size = atom.size - 24;
757 if (title_size > 0) {
758 if (title_size > FFMIN(INT_MAX, SIZE_MAX-1))
759 return AVERROR_INVALIDDATA;
760 title_str = av_malloc(title_size + 1); /* Add null terminator */
762 return AVERROR(ENOMEM);
764 ret = ffio_read_size(pb, title_str, title_size);
766 av_freep(&title_str);
769 title_str[title_size] = 0;
771 int off = (!c->isom && title_str[0] == title_size - 1);
772 // flag added so as to not set stream handler name if already set from mdia->hdlr
773 av_dict_set(&st->metadata, "handler_name", title_str + off, AV_DICT_DONT_OVERWRITE);
775 av_freep(&title_str);
781 static int mov_read_esds(MOVContext *c, AVIOContext *pb, MOVAtom atom)
783 return ff_mov_read_esds(c->fc, pb);
786 static int mov_read_dac3(MOVContext *c, AVIOContext *pb, MOVAtom atom)
789 enum AVAudioServiceType *ast;
790 int ac3info, acmod, lfeon, bsmod;
792 if (c->fc->nb_streams < 1)
794 st = c->fc->streams[c->fc->nb_streams-1];
796 ast = (enum AVAudioServiceType*)av_stream_new_side_data(st, AV_PKT_DATA_AUDIO_SERVICE_TYPE,
799 return AVERROR(ENOMEM);
801 ac3info = avio_rb24(pb);
802 bsmod = (ac3info >> 14) & 0x7;
803 acmod = (ac3info >> 11) & 0x7;
804 lfeon = (ac3info >> 10) & 0x1;
805 st->codecpar->channels = ((int[]){2,1,2,3,3,4,4,5})[acmod] + lfeon;
806 st->codecpar->channel_layout = avpriv_ac3_channel_layout_tab[acmod];
808 st->codecpar->channel_layout |= AV_CH_LOW_FREQUENCY;
810 if (st->codecpar->channels > 1 && bsmod == 0x7)
811 *ast = AV_AUDIO_SERVICE_TYPE_KARAOKE;
813 #if FF_API_LAVF_AVCTX
814 FF_DISABLE_DEPRECATION_WARNINGS
815 st->codec->audio_service_type = *ast;
816 FF_ENABLE_DEPRECATION_WARNINGS
822 static int mov_read_dec3(MOVContext *c, AVIOContext *pb, MOVAtom atom)
825 enum AVAudioServiceType *ast;
826 int eac3info, acmod, lfeon, bsmod;
828 if (c->fc->nb_streams < 1)
830 st = c->fc->streams[c->fc->nb_streams-1];
832 ast = (enum AVAudioServiceType*)av_stream_new_side_data(st, AV_PKT_DATA_AUDIO_SERVICE_TYPE,
835 return AVERROR(ENOMEM);
837 /* No need to parse fields for additional independent substreams and its
838 * associated dependent substreams since libavcodec's E-AC-3 decoder
839 * does not support them yet. */
840 avio_rb16(pb); /* data_rate and num_ind_sub */
841 eac3info = avio_rb24(pb);
842 bsmod = (eac3info >> 12) & 0x1f;
843 acmod = (eac3info >> 9) & 0x7;
844 lfeon = (eac3info >> 8) & 0x1;
845 st->codecpar->channel_layout = avpriv_ac3_channel_layout_tab[acmod];
847 st->codecpar->channel_layout |= AV_CH_LOW_FREQUENCY;
848 st->codecpar->channels = av_get_channel_layout_nb_channels(st->codecpar->channel_layout);
850 if (st->codecpar->channels > 1 && bsmod == 0x7)
851 *ast = AV_AUDIO_SERVICE_TYPE_KARAOKE;
853 #if FF_API_LAVF_AVCTX
854 FF_DISABLE_DEPRECATION_WARNINGS
855 st->codec->audio_service_type = *ast;
856 FF_ENABLE_DEPRECATION_WARNINGS
862 static int mov_read_ddts(MOVContext *c, AVIOContext *pb, MOVAtom atom)
865 uint8_t buf[DDTS_SIZE + AV_INPUT_BUFFER_PADDING_SIZE];
867 uint32_t frame_duration_code = 0;
868 uint32_t channel_layout_code = 0;
872 if ((ret = ffio_read_size(pb, buf, DDTS_SIZE)) < 0)
875 init_get_bits(&gb, buf, 8 * DDTS_SIZE);
877 if (c->fc->nb_streams < 1) {
880 st = c->fc->streams[c->fc->nb_streams-1];
882 st->codecpar->sample_rate = get_bits_long(&gb, 32);
883 if (st->codecpar->sample_rate <= 0) {
884 av_log(c->fc, AV_LOG_ERROR, "Invalid sample rate %d\n", st->codecpar->sample_rate);
885 return AVERROR_INVALIDDATA;
887 skip_bits_long(&gb, 32); /* max bitrate */
888 st->codecpar->bit_rate = get_bits_long(&gb, 32);
889 st->codecpar->bits_per_coded_sample = get_bits(&gb, 8);
890 frame_duration_code = get_bits(&gb, 2);
891 skip_bits(&gb, 30); /* various fields */
892 channel_layout_code = get_bits(&gb, 16);
894 st->codecpar->frame_size =
895 (frame_duration_code == 0) ? 512 :
896 (frame_duration_code == 1) ? 1024 :
897 (frame_duration_code == 2) ? 2048 :
898 (frame_duration_code == 3) ? 4096 : 0;
900 if (channel_layout_code > 0xff) {
901 av_log(c->fc, AV_LOG_WARNING, "Unsupported DTS audio channel layout\n");
903 st->codecpar->channel_layout =
904 ((channel_layout_code & 0x1) ? AV_CH_FRONT_CENTER : 0) |
905 ((channel_layout_code & 0x2) ? AV_CH_FRONT_LEFT : 0) |
906 ((channel_layout_code & 0x2) ? AV_CH_FRONT_RIGHT : 0) |
907 ((channel_layout_code & 0x4) ? AV_CH_SIDE_LEFT : 0) |
908 ((channel_layout_code & 0x4) ? AV_CH_SIDE_RIGHT : 0) |
909 ((channel_layout_code & 0x8) ? AV_CH_LOW_FREQUENCY : 0);
911 st->codecpar->channels = av_get_channel_layout_nb_channels(st->codecpar->channel_layout);
916 static int mov_read_chan(MOVContext *c, AVIOContext *pb, MOVAtom atom)
920 if (c->fc->nb_streams < 1)
922 st = c->fc->streams[c->fc->nb_streams-1];
927 /* skip version and flags */
930 ff_mov_read_chan(c->fc, pb, st, atom.size - 4);
935 static int mov_read_wfex(MOVContext *c, AVIOContext *pb, MOVAtom atom)
940 if (c->fc->nb_streams < 1)
942 st = c->fc->streams[c->fc->nb_streams-1];
944 if ((ret = ff_get_wav_header(c->fc, pb, st->codecpar, atom.size, 0)) < 0)
945 av_log(c->fc, AV_LOG_WARNING, "get_wav_header failed\n");
950 static int mov_read_pasp(MOVContext *c, AVIOContext *pb, MOVAtom atom)
952 const int num = avio_rb32(pb);
953 const int den = avio_rb32(pb);
956 if (c->fc->nb_streams < 1)
958 st = c->fc->streams[c->fc->nb_streams-1];
960 if ((st->sample_aspect_ratio.den != 1 || st->sample_aspect_ratio.num) && // default
961 (den != st->sample_aspect_ratio.den || num != st->sample_aspect_ratio.num)) {
962 av_log(c->fc, AV_LOG_WARNING,
963 "sample aspect ratio already set to %d:%d, ignoring 'pasp' atom (%d:%d)\n",
964 st->sample_aspect_ratio.num, st->sample_aspect_ratio.den,
966 } else if (den != 0) {
967 av_reduce(&st->sample_aspect_ratio.num, &st->sample_aspect_ratio.den,
973 /* this atom contains actual media data */
974 static int mov_read_mdat(MOVContext *c, AVIOContext *pb, MOVAtom atom)
976 if (atom.size == 0) /* wrong one (MP4) */
979 return 0; /* now go for moov */
982 #define DRM_BLOB_SIZE 56
984 static int mov_read_adrm(MOVContext *c, AVIOContext *pb, MOVAtom atom)
986 uint8_t intermediate_key[20];
987 uint8_t intermediate_iv[20];
990 uint8_t file_checksum[20];
991 uint8_t calculated_checksum[20];
995 uint8_t *activation_bytes = c->activation_bytes;
996 uint8_t *fixed_key = c->audible_fixed_key;
1000 sha = av_sha_alloc();
1002 return AVERROR(ENOMEM);
1003 av_free(c->aes_decrypt);
1004 c->aes_decrypt = av_aes_alloc();
1005 if (!c->aes_decrypt) {
1006 ret = AVERROR(ENOMEM);
1010 /* drm blob processing */
1011 avio_read(pb, output, 8); // go to offset 8, absolute position 0x251
1012 avio_read(pb, input, DRM_BLOB_SIZE);
1013 avio_read(pb, output, 4); // go to offset 4, absolute position 0x28d
1014 avio_read(pb, file_checksum, 20);
1016 av_log(c->fc, AV_LOG_INFO, "[aax] file checksum == "); // required by external tools
1017 for (i = 0; i < 20; i++)
1018 av_log(c->fc, AV_LOG_INFO, "%02x", file_checksum[i]);
1019 av_log(c->fc, AV_LOG_INFO, "\n");
1021 /* verify activation data */
1022 if (!activation_bytes) {
1023 av_log(c->fc, AV_LOG_WARNING, "[aax] activation_bytes option is missing!\n");
1024 ret = 0; /* allow ffprobe to continue working on .aax files */
1027 if (c->activation_bytes_size != 4) {
1028 av_log(c->fc, AV_LOG_FATAL, "[aax] activation_bytes value needs to be 4 bytes!\n");
1029 ret = AVERROR(EINVAL);
1033 /* verify fixed key */
1034 if (c->audible_fixed_key_size != 16) {
1035 av_log(c->fc, AV_LOG_FATAL, "[aax] audible_fixed_key value needs to be 16 bytes!\n");
1036 ret = AVERROR(EINVAL);
1040 /* AAX (and AAX+) key derivation */
1041 av_sha_init(sha, 160);
1042 av_sha_update(sha, fixed_key, 16);
1043 av_sha_update(sha, activation_bytes, 4);
1044 av_sha_final(sha, intermediate_key);
1045 av_sha_init(sha, 160);
1046 av_sha_update(sha, fixed_key, 16);
1047 av_sha_update(sha, intermediate_key, 20);
1048 av_sha_update(sha, activation_bytes, 4);
1049 av_sha_final(sha, intermediate_iv);
1050 av_sha_init(sha, 160);
1051 av_sha_update(sha, intermediate_key, 16);
1052 av_sha_update(sha, intermediate_iv, 16);
1053 av_sha_final(sha, calculated_checksum);
1054 if (memcmp(calculated_checksum, file_checksum, 20)) { // critical error
1055 av_log(c->fc, AV_LOG_ERROR, "[aax] mismatch in checksums!\n");
1056 ret = AVERROR_INVALIDDATA;
1059 av_aes_init(c->aes_decrypt, intermediate_key, 128, 1);
1060 av_aes_crypt(c->aes_decrypt, output, input, DRM_BLOB_SIZE >> 4, intermediate_iv, 1);
1061 for (i = 0; i < 4; i++) {
1062 // file data (in output) is stored in big-endian mode
1063 if (activation_bytes[i] != output[3 - i]) { // critical error
1064 av_log(c->fc, AV_LOG_ERROR, "[aax] error in drm blob decryption!\n");
1065 ret = AVERROR_INVALIDDATA;
1069 memcpy(c->file_key, output + 8, 16);
1070 memcpy(input, output + 26, 16);
1071 av_sha_init(sha, 160);
1072 av_sha_update(sha, input, 16);
1073 av_sha_update(sha, c->file_key, 16);
1074 av_sha_update(sha, fixed_key, 16);
1075 av_sha_final(sha, c->file_iv);
1083 static int mov_aaxc_crypto(MOVContext *c)
1085 if (c->audible_key_size != 16) {
1086 av_log(c->fc, AV_LOG_FATAL, "[aaxc] audible_key value needs to be 16 bytes!\n");
1087 return AVERROR(EINVAL);
1090 if (c->audible_iv_size != 16) {
1091 av_log(c->fc, AV_LOG_FATAL, "[aaxc] audible_iv value needs to be 16 bytes!\n");
1092 return AVERROR(EINVAL);
1095 c->aes_decrypt = av_aes_alloc();
1096 if (!c->aes_decrypt) {
1097 return AVERROR(ENOMEM);
1100 memcpy(c->file_key, c->audible_key, 16);
1101 memcpy(c->file_iv, c->audible_iv, 16);
1107 // Audible AAX (and AAX+) bytestream decryption
1108 static int aax_filter(uint8_t *input, int size, MOVContext *c)
1111 unsigned char iv[16];
1113 memcpy(iv, c->file_iv, 16); // iv is overwritten
1114 blocks = size >> 4; // trailing bytes are not encrypted!
1115 av_aes_init(c->aes_decrypt, c->file_key, 128, 1);
1116 av_aes_crypt(c->aes_decrypt, input, input, blocks, iv, 1);
1121 /* read major brand, minor version and compatible brands and store them as metadata */
1122 static int mov_read_ftyp(MOVContext *c, AVIOContext *pb, MOVAtom atom)
1125 int comp_brand_size;
1126 char* comp_brands_str;
1127 uint8_t type[5] = {0};
1128 int ret = ffio_read_size(pb, type, 4);
1132 if (strcmp(type, "qt "))
1134 av_log(c->fc, AV_LOG_DEBUG, "ISO: File Type Major Brand: %.4s\n",(char *)&type);
1135 av_dict_set(&c->fc->metadata, "major_brand", type, 0);
1136 minor_ver = avio_rb32(pb); /* minor version */
1137 av_dict_set_int(&c->fc->metadata, "minor_version", minor_ver, 0);
1139 comp_brand_size = atom.size - 8;
1140 if (comp_brand_size < 0 || comp_brand_size == INT_MAX)
1141 return AVERROR_INVALIDDATA;
1142 comp_brands_str = av_malloc(comp_brand_size + 1); /* Add null terminator */
1143 if (!comp_brands_str)
1144 return AVERROR(ENOMEM);
1146 ret = ffio_read_size(pb, comp_brands_str, comp_brand_size);
1148 av_freep(&comp_brands_str);
1151 comp_brands_str[comp_brand_size] = 0;
1152 av_dict_set(&c->fc->metadata, "compatible_brands",
1153 comp_brands_str, AV_DICT_DONT_STRDUP_VAL);
1155 // Logic for handling Audible's .aaxc files
1156 if (!strcmp(type, "aaxc")) {
1163 /* this atom should contain all header atoms */
1164 static int mov_read_moov(MOVContext *c, AVIOContext *pb, MOVAtom atom)
1168 if (c->found_moov) {
1169 av_log(c->fc, AV_LOG_WARNING, "Found duplicated MOOV Atom. Skipped it\n");
1170 avio_skip(pb, atom.size);
1174 if ((ret = mov_read_default(c, pb, atom)) < 0)
1176 /* we parsed the 'moov' atom, we can terminate the parsing as soon as we find the 'mdat' */
1177 /* so we don't parse the whole file if over a network */
1179 return 0; /* now go for mdat */
1182 static MOVFragmentStreamInfo * get_frag_stream_info(
1183 MOVFragmentIndex *frag_index,
1188 MOVFragmentIndexItem * item;
1190 if (index < 0 || index >= frag_index->nb_items)
1192 item = &frag_index->item[index];
1193 for (i = 0; i < item->nb_stream_info; i++)
1194 if (item->stream_info[i].id == id)
1195 return &item->stream_info[i];
1197 // This shouldn't happen
1201 static void set_frag_stream(MOVFragmentIndex *frag_index, int id)
1204 MOVFragmentIndexItem * item;
1206 if (frag_index->current < 0 ||
1207 frag_index->current >= frag_index->nb_items)
1210 item = &frag_index->item[frag_index->current];
1211 for (i = 0; i < item->nb_stream_info; i++)
1212 if (item->stream_info[i].id == id) {
1217 // id not found. This shouldn't happen.
1221 static MOVFragmentStreamInfo * get_current_frag_stream_info(
1222 MOVFragmentIndex *frag_index)
1224 MOVFragmentIndexItem *item;
1225 if (frag_index->current < 0 ||
1226 frag_index->current >= frag_index->nb_items)
1229 item = &frag_index->item[frag_index->current];
1230 if (item->current >= 0 && item->current < item->nb_stream_info)
1231 return &item->stream_info[item->current];
1233 // This shouldn't happen
1237 static int search_frag_moof_offset(MOVFragmentIndex *frag_index, int64_t offset)
1240 int64_t moof_offset;
1242 // Optimize for appending new entries
1243 if (!frag_index->nb_items ||
1244 frag_index->item[frag_index->nb_items - 1].moof_offset < offset)
1245 return frag_index->nb_items;
1248 b = frag_index->nb_items;
1252 moof_offset = frag_index->item[m].moof_offset;
1253 if (moof_offset >= offset)
1255 if (moof_offset <= offset)
1261 static int64_t get_stream_info_time(MOVFragmentStreamInfo * frag_stream_info)
1263 av_assert0(frag_stream_info);
1264 if (frag_stream_info->sidx_pts != AV_NOPTS_VALUE)
1265 return frag_stream_info->sidx_pts;
1266 if (frag_stream_info->first_tfra_pts != AV_NOPTS_VALUE)
1267 return frag_stream_info->first_tfra_pts;
1268 return frag_stream_info->tfdt_dts;
1271 static int64_t get_frag_time(MOVFragmentIndex *frag_index,
1272 int index, int track_id)
1274 MOVFragmentStreamInfo * frag_stream_info;
1278 if (track_id >= 0) {
1279 frag_stream_info = get_frag_stream_info(frag_index, index, track_id);
1280 return frag_stream_info->sidx_pts;
1283 for (i = 0; i < frag_index->item[index].nb_stream_info; i++) {
1284 frag_stream_info = &frag_index->item[index].stream_info[i];
1285 timestamp = get_stream_info_time(frag_stream_info);
1286 if (timestamp != AV_NOPTS_VALUE)
1289 return AV_NOPTS_VALUE;
1292 static int search_frag_timestamp(MOVFragmentIndex *frag_index,
1293 AVStream *st, int64_t timestamp)
1300 // If the stream is referenced by any sidx, limit the search
1301 // to fragments that referenced this stream in the sidx
1302 MOVStreamContext *sc = st->priv_data;
1308 b = frag_index->nb_items;
1311 m0 = m = (a + b) >> 1;
1314 (frag_time = get_frag_time(frag_index, m, id)) == AV_NOPTS_VALUE)
1317 if (m < b && frag_time <= timestamp)
1326 static int update_frag_index(MOVContext *c, int64_t offset)
1329 MOVFragmentIndexItem * item;
1330 MOVFragmentStreamInfo * frag_stream_info;
1332 // If moof_offset already exists in frag_index, return index to it
1333 index = search_frag_moof_offset(&c->frag_index, offset);
1334 if (index < c->frag_index.nb_items &&
1335 c->frag_index.item[index].moof_offset == offset)
1338 // offset is not yet in frag index.
1339 // Insert new item at index (sorted by moof offset)
1340 item = av_fast_realloc(c->frag_index.item,
1341 &c->frag_index.allocated_size,
1342 (c->frag_index.nb_items + 1) *
1343 sizeof(*c->frag_index.item));
1346 c->frag_index.item = item;
1348 frag_stream_info = av_realloc_array(NULL, c->fc->nb_streams,
1349 sizeof(*item->stream_info));
1350 if (!frag_stream_info)
1353 for (i = 0; i < c->fc->nb_streams; i++) {
1354 // Avoid building frag index if streams lack track id.
1355 if (c->fc->streams[i]->id < 0) {
1356 av_free(frag_stream_info);
1357 return AVERROR_INVALIDDATA;
1360 frag_stream_info[i].id = c->fc->streams[i]->id;
1361 frag_stream_info[i].sidx_pts = AV_NOPTS_VALUE;
1362 frag_stream_info[i].tfdt_dts = AV_NOPTS_VALUE;
1363 frag_stream_info[i].next_trun_dts = AV_NOPTS_VALUE;
1364 frag_stream_info[i].first_tfra_pts = AV_NOPTS_VALUE;
1365 frag_stream_info[i].index_entry = -1;
1366 frag_stream_info[i].encryption_index = NULL;
1369 if (index < c->frag_index.nb_items)
1370 memmove(c->frag_index.item + index + 1, c->frag_index.item + index,
1371 (c->frag_index.nb_items - index) * sizeof(*c->frag_index.item));
1373 item = &c->frag_index.item[index];
1374 item->headers_read = 0;
1376 item->nb_stream_info = c->fc->nb_streams;
1377 item->moof_offset = offset;
1378 item->stream_info = frag_stream_info;
1379 c->frag_index.nb_items++;
1384 static void fix_frag_index_entries(MOVFragmentIndex *frag_index, int index,
1385 int id, int entries)
1388 MOVFragmentStreamInfo * frag_stream_info;
1392 for (i = index; i < frag_index->nb_items; i++) {
1393 frag_stream_info = get_frag_stream_info(frag_index, i, id);
1394 if (frag_stream_info && frag_stream_info->index_entry >= 0)
1395 frag_stream_info->index_entry += entries;
1399 static int mov_read_moof(MOVContext *c, AVIOContext *pb, MOVAtom atom)
1401 // Set by mov_read_tfhd(). mov_read_trun() will reject files missing tfhd.
1402 c->fragment.found_tfhd = 0;
1404 if (!c->has_looked_for_mfra && c->use_mfra_for > 0) {
1405 c->has_looked_for_mfra = 1;
1406 if (pb->seekable & AVIO_SEEKABLE_NORMAL) {
1408 av_log(c->fc, AV_LOG_VERBOSE, "stream has moof boxes, will look "
1410 if ((ret = mov_read_mfra(c, pb)) < 0) {
1411 av_log(c->fc, AV_LOG_VERBOSE, "found a moof box but failed to "
1412 "read the mfra (may be a live ismv)\n");
1415 av_log(c->fc, AV_LOG_VERBOSE, "found a moof box but stream is not "
1416 "seekable, can not look for mfra\n");
1419 c->fragment.moof_offset = c->fragment.implicit_offset = avio_tell(pb) - 8;
1420 av_log(c->fc, AV_LOG_TRACE, "moof offset %"PRIx64"\n", c->fragment.moof_offset);
1421 c->frag_index.current = update_frag_index(c, c->fragment.moof_offset);
1422 return mov_read_default(c, pb, atom);
1425 static void mov_metadata_creation_time(AVDictionary **metadata, int64_t time, void *logctx)
1428 if (time >= 2082844800)
1429 time -= 2082844800; /* seconds between 1904-01-01 and Epoch */
1431 if ((int64_t)(time * 1000000ULL) / 1000000 != time) {
1432 av_log(logctx, AV_LOG_DEBUG, "creation_time is not representable\n");
1436 avpriv_dict_set_timestamp(metadata, "creation_time", time * 1000000);
1440 static int mov_read_mdhd(MOVContext *c, AVIOContext *pb, MOVAtom atom)
1443 MOVStreamContext *sc;
1445 char language[4] = {0};
1447 int64_t creation_time;
1449 if (c->fc->nb_streams < 1)
1451 st = c->fc->streams[c->fc->nb_streams-1];
1454 if (sc->time_scale) {
1455 av_log(c->fc, AV_LOG_ERROR, "Multiple mdhd?\n");
1456 return AVERROR_INVALIDDATA;
1459 version = avio_r8(pb);
1461 avpriv_request_sample(c->fc, "Version %d", version);
1462 return AVERROR_PATCHWELCOME;
1464 avio_rb24(pb); /* flags */
1466 creation_time = avio_rb64(pb);
1469 creation_time = avio_rb32(pb);
1470 avio_rb32(pb); /* modification time */
1472 mov_metadata_creation_time(&st->metadata, creation_time, c->fc);
1474 sc->time_scale = avio_rb32(pb);
1475 if (sc->time_scale <= 0) {
1476 av_log(c->fc, AV_LOG_ERROR, "Invalid mdhd time scale %d, defaulting to 1\n", sc->time_scale);
1479 st->duration = (version == 1) ? avio_rb64(pb) : avio_rb32(pb); /* duration */
1481 lang = avio_rb16(pb); /* language */
1482 if (ff_mov_lang_to_iso639(lang, language))
1483 av_dict_set(&st->metadata, "language", language, 0);
1484 avio_rb16(pb); /* quality */
1489 static int mov_read_mvhd(MOVContext *c, AVIOContext *pb, MOVAtom atom)
1492 int64_t creation_time;
1493 int version = avio_r8(pb); /* version */
1494 avio_rb24(pb); /* flags */
1497 creation_time = avio_rb64(pb);
1500 creation_time = avio_rb32(pb);
1501 avio_rb32(pb); /* modification time */
1503 mov_metadata_creation_time(&c->fc->metadata, creation_time, c->fc);
1504 c->time_scale = avio_rb32(pb); /* time scale */
1505 if (c->time_scale <= 0) {
1506 av_log(c->fc, AV_LOG_ERROR, "Invalid mvhd time scale %d, defaulting to 1\n", c->time_scale);
1509 av_log(c->fc, AV_LOG_TRACE, "time scale = %i\n", c->time_scale);
1511 c->duration = (version == 1) ? avio_rb64(pb) : avio_rb32(pb); /* duration */
1512 // set the AVFormatContext duration because the duration of individual tracks
1513 // may be inaccurate
1514 if (c->time_scale > 0 && !c->trex_data)
1515 c->fc->duration = av_rescale(c->duration, AV_TIME_BASE, c->time_scale);
1516 avio_rb32(pb); /* preferred scale */
1518 avio_rb16(pb); /* preferred volume */
1520 avio_skip(pb, 10); /* reserved */
1522 /* movie display matrix, store it in main context and use it later on */
1523 for (i = 0; i < 3; i++) {
1524 c->movie_display_matrix[i][0] = avio_rb32(pb); // 16.16 fixed point
1525 c->movie_display_matrix[i][1] = avio_rb32(pb); // 16.16 fixed point
1526 c->movie_display_matrix[i][2] = avio_rb32(pb); // 2.30 fixed point
1529 avio_rb32(pb); /* preview time */
1530 avio_rb32(pb); /* preview duration */
1531 avio_rb32(pb); /* poster time */
1532 avio_rb32(pb); /* selection time */
1533 avio_rb32(pb); /* selection duration */
1534 avio_rb32(pb); /* current time */
1535 avio_rb32(pb); /* next track ID */
1540 static int mov_read_enda(MOVContext *c, AVIOContext *pb, MOVAtom atom)
1545 if (c->fc->nb_streams < 1)
1547 st = c->fc->streams[c->fc->nb_streams-1];
1549 little_endian = avio_rb16(pb) & 0xFF;
1550 av_log(c->fc, AV_LOG_TRACE, "enda %d\n", little_endian);
1551 if (little_endian == 1) {
1552 switch (st->codecpar->codec_id) {
1553 case AV_CODEC_ID_PCM_S24BE:
1554 st->codecpar->codec_id = AV_CODEC_ID_PCM_S24LE;
1556 case AV_CODEC_ID_PCM_S32BE:
1557 st->codecpar->codec_id = AV_CODEC_ID_PCM_S32LE;
1559 case AV_CODEC_ID_PCM_F32BE:
1560 st->codecpar->codec_id = AV_CODEC_ID_PCM_F32LE;
1562 case AV_CODEC_ID_PCM_F64BE:
1563 st->codecpar->codec_id = AV_CODEC_ID_PCM_F64LE;
1572 static int mov_read_colr(MOVContext *c, AVIOContext *pb, MOVAtom atom)
1575 uint8_t *icc_profile;
1576 char color_parameter_type[5] = { 0 };
1577 uint16_t color_primaries, color_trc, color_matrix;
1580 if (c->fc->nb_streams < 1)
1582 st = c->fc->streams[c->fc->nb_streams - 1];
1584 ret = ffio_read_size(pb, color_parameter_type, 4);
1587 if (strncmp(color_parameter_type, "nclx", 4) &&
1588 strncmp(color_parameter_type, "nclc", 4) &&
1589 strncmp(color_parameter_type, "prof", 4)) {
1590 av_log(c->fc, AV_LOG_WARNING, "unsupported color_parameter_type %s\n",
1591 color_parameter_type);
1595 if (!strncmp(color_parameter_type, "prof", 4)) {
1596 icc_profile = av_stream_new_side_data(st, AV_PKT_DATA_ICC_PROFILE, atom.size - 4);
1598 return AVERROR(ENOMEM);
1599 ret = ffio_read_size(pb, icc_profile, atom.size - 4);
1603 color_primaries = avio_rb16(pb);
1604 color_trc = avio_rb16(pb);
1605 color_matrix = avio_rb16(pb);
1607 av_log(c->fc, AV_LOG_TRACE,
1608 "%s: pri %d trc %d matrix %d",
1609 color_parameter_type, color_primaries, color_trc, color_matrix);
1611 if (!strncmp(color_parameter_type, "nclx", 4)) {
1612 uint8_t color_range = avio_r8(pb) >> 7;
1613 av_log(c->fc, AV_LOG_TRACE, " full %"PRIu8"", color_range);
1615 st->codecpar->color_range = AVCOL_RANGE_JPEG;
1617 st->codecpar->color_range = AVCOL_RANGE_MPEG;
1620 if (!av_color_primaries_name(color_primaries))
1621 color_primaries = AVCOL_PRI_UNSPECIFIED;
1622 if (!av_color_transfer_name(color_trc))
1623 color_trc = AVCOL_TRC_UNSPECIFIED;
1624 if (!av_color_space_name(color_matrix))
1625 color_matrix = AVCOL_SPC_UNSPECIFIED;
1627 st->codecpar->color_primaries = color_primaries;
1628 st->codecpar->color_trc = color_trc;
1629 st->codecpar->color_space = color_matrix;
1630 av_log(c->fc, AV_LOG_TRACE, "\n");
1635 static int mov_read_fiel(MOVContext *c, AVIOContext *pb, MOVAtom atom)
1638 unsigned mov_field_order;
1639 enum AVFieldOrder decoded_field_order = AV_FIELD_UNKNOWN;
1641 if (c->fc->nb_streams < 1) // will happen with jp2 files
1643 st = c->fc->streams[c->fc->nb_streams-1];
1645 return AVERROR_INVALIDDATA;
1646 mov_field_order = avio_rb16(pb);
1647 if ((mov_field_order & 0xFF00) == 0x0100)
1648 decoded_field_order = AV_FIELD_PROGRESSIVE;
1649 else if ((mov_field_order & 0xFF00) == 0x0200) {
1650 switch (mov_field_order & 0xFF) {
1651 case 0x01: decoded_field_order = AV_FIELD_TT;
1653 case 0x06: decoded_field_order = AV_FIELD_BB;
1655 case 0x09: decoded_field_order = AV_FIELD_TB;
1657 case 0x0E: decoded_field_order = AV_FIELD_BT;
1661 if (decoded_field_order == AV_FIELD_UNKNOWN && mov_field_order) {
1662 av_log(c->fc, AV_LOG_ERROR, "Unknown MOV field order 0x%04x\n", mov_field_order);
1664 st->codecpar->field_order = decoded_field_order;
1669 static int mov_realloc_extradata(AVCodecParameters *par, MOVAtom atom)
1672 uint64_t size = (uint64_t)par->extradata_size + atom.size + 8 + AV_INPUT_BUFFER_PADDING_SIZE;
1673 if (size > INT_MAX || (uint64_t)atom.size > INT_MAX)
1674 return AVERROR_INVALIDDATA;
1675 if ((err = av_reallocp(&par->extradata, size)) < 0) {
1676 par->extradata_size = 0;
1679 par->extradata_size = size - AV_INPUT_BUFFER_PADDING_SIZE;
1683 /* Read a whole atom into the extradata return the size of the atom read, possibly truncated if != atom.size */
1684 static int64_t mov_read_atom_into_extradata(MOVContext *c, AVIOContext *pb, MOVAtom atom,
1685 AVCodecParameters *par, uint8_t *buf)
1687 int64_t result = atom.size;
1690 AV_WB32(buf , atom.size + 8);
1691 AV_WL32(buf + 4, atom.type);
1692 err = ffio_read_size(pb, buf + 8, atom.size);
1694 par->extradata_size -= atom.size;
1696 } else if (err < atom.size) {
1697 av_log(c->fc, AV_LOG_WARNING, "truncated extradata\n");
1698 par->extradata_size -= atom.size - err;
1701 memset(buf + 8 + err, 0, AV_INPUT_BUFFER_PADDING_SIZE);
1705 /* FIXME modify QDM2/SVQ3/H.264 decoders to take full atom as extradata */
1706 static int mov_read_extradata(MOVContext *c, AVIOContext *pb, MOVAtom atom,
1707 enum AVCodecID codec_id)
1710 uint64_t original_size;
1713 if (c->fc->nb_streams < 1) // will happen with jp2 files
1715 st = c->fc->streams[c->fc->nb_streams-1];
1717 if (st->codecpar->codec_id != codec_id)
1718 return 0; /* unexpected codec_id - don't mess with extradata */
1720 original_size = st->codecpar->extradata_size;
1721 err = mov_realloc_extradata(st->codecpar, atom);
1725 err = mov_read_atom_into_extradata(c, pb, atom, st->codecpar, st->codecpar->extradata + original_size);
1728 return 0; // Note: this is the original behavior to ignore truncation.
1731 /* wrapper functions for reading ALAC/AVS/MJPEG/MJPEG2000 extradata atoms only for those codecs */
1732 static int mov_read_alac(MOVContext *c, AVIOContext *pb, MOVAtom atom)
1734 return mov_read_extradata(c, pb, atom, AV_CODEC_ID_ALAC);
1737 static int mov_read_avss(MOVContext *c, AVIOContext *pb, MOVAtom atom)
1739 return mov_read_extradata(c, pb, atom, AV_CODEC_ID_AVS);
1742 static int mov_read_jp2h(MOVContext *c, AVIOContext *pb, MOVAtom atom)
1744 return mov_read_extradata(c, pb, atom, AV_CODEC_ID_JPEG2000);
1747 static int mov_read_dpxe(MOVContext *c, AVIOContext *pb, MOVAtom atom)
1749 return mov_read_extradata(c, pb, atom, AV_CODEC_ID_R10K);
1752 static int mov_read_avid(MOVContext *c, AVIOContext *pb, MOVAtom atom)
1754 int ret = mov_read_extradata(c, pb, atom, AV_CODEC_ID_AVUI);
1756 ret = mov_read_extradata(c, pb, atom, AV_CODEC_ID_DNXHD);
1760 static int mov_read_targa_y216(MOVContext *c, AVIOContext *pb, MOVAtom atom)
1762 int ret = mov_read_extradata(c, pb, atom, AV_CODEC_ID_TARGA_Y216);
1764 if (!ret && c->fc->nb_streams >= 1) {
1765 AVCodecParameters *par = c->fc->streams[c->fc->nb_streams-1]->codecpar;
1766 if (par->extradata_size >= 40) {
1767 par->height = AV_RB16(&par->extradata[36]);
1768 par->width = AV_RB16(&par->extradata[38]);
1774 static int mov_read_ares(MOVContext *c, AVIOContext *pb, MOVAtom atom)
1776 if (c->fc->nb_streams >= 1) {
1777 AVCodecParameters *par = c->fc->streams[c->fc->nb_streams-1]->codecpar;
1778 if (par->codec_tag == MKTAG('A', 'V', 'i', 'n') &&
1779 par->codec_id == AV_CODEC_ID_H264 &&
1783 cid = avio_rb16(pb);
1784 /* For AVID AVCI50, force width of 1440 to be able to select the correct SPS and PPS */
1785 if (cid == 0xd4d || cid == 0xd4e)
1788 } else if ((par->codec_tag == MKTAG('A', 'V', 'd', '1') ||
1789 par->codec_tag == MKTAG('A', 'V', 'j', '2') ||
1790 par->codec_tag == MKTAG('A', 'V', 'd', 'n')) &&
1794 num = avio_rb32(pb);
1795 den = avio_rb32(pb);
1796 if (num <= 0 || den <= 0)
1798 switch (avio_rb32(pb)) {
1800 if (den >= INT_MAX / 2)
1804 c->fc->streams[c->fc->nb_streams-1]->internal->display_aspect_ratio.num = num;
1805 c->fc->streams[c->fc->nb_streams-1]->internal->display_aspect_ratio.den = den;
1812 return mov_read_avid(c, pb, atom);
1815 static int mov_read_aclr(MOVContext *c, AVIOContext *pb, MOVAtom atom)
1819 uint64_t original_size;
1820 if (c->fc->nb_streams >= 1) {
1821 AVCodecParameters *par = c->fc->streams[c->fc->nb_streams-1]->codecpar;
1822 if (par->codec_id == AV_CODEC_ID_H264)
1824 if (atom.size == 16) {
1825 original_size = par->extradata_size;
1826 ret = mov_realloc_extradata(par, atom);
1828 length = mov_read_atom_into_extradata(c, pb, atom, par, par->extradata + original_size);
1829 if (length == atom.size) {
1830 const uint8_t range_value = par->extradata[original_size + 19];
1831 switch (range_value) {
1833 par->color_range = AVCOL_RANGE_MPEG;
1836 par->color_range = AVCOL_RANGE_JPEG;
1839 av_log(c->fc, AV_LOG_WARNING, "ignored unknown aclr value (%d)\n", range_value);
1842 ff_dlog(c->fc, "color_range: %d\n", par->color_range);
1844 /* For some reason the whole atom was not added to the extradata */
1845 av_log(c->fc, AV_LOG_ERROR, "aclr not decoded - incomplete atom\n");
1848 av_log(c->fc, AV_LOG_ERROR, "aclr not decoded - unable to add atom to extradata\n");
1851 av_log(c->fc, AV_LOG_WARNING, "aclr not decoded - unexpected size %"PRId64"\n", atom.size);
1858 static int mov_read_svq3(MOVContext *c, AVIOContext *pb, MOVAtom atom)
1860 return mov_read_extradata(c, pb, atom, AV_CODEC_ID_SVQ3);
1863 static int mov_read_wave(MOVContext *c, AVIOContext *pb, MOVAtom atom)
1868 if (c->fc->nb_streams < 1)
1870 st = c->fc->streams[c->fc->nb_streams-1];
1872 if ((uint64_t)atom.size > (1<<30))
1873 return AVERROR_INVALIDDATA;
1875 if (st->codecpar->codec_id == AV_CODEC_ID_QDM2 ||
1876 st->codecpar->codec_id == AV_CODEC_ID_QDMC ||
1877 st->codecpar->codec_id == AV_CODEC_ID_SPEEX) {
1878 // pass all frma atom to codec, needed at least for QDMC and QDM2
1879 ret = ff_get_extradata(c->fc, st->codecpar, pb, atom.size);
1882 } else if (atom.size > 8) { /* to read frma, esds atoms */
1883 if (st->codecpar->codec_id == AV_CODEC_ID_ALAC && atom.size >= 24) {
1885 ret = ffio_ensure_seekback(pb, 8);
1888 buffer = avio_rb64(pb);
1890 if ( (buffer & 0xFFFFFFFF) == MKBETAG('f','r','m','a')
1891 && buffer >> 32 <= atom.size
1892 && buffer >> 32 >= 8) {
1895 } else if (!st->codecpar->extradata_size) {
1896 #define ALAC_EXTRADATA_SIZE 36
1897 st->codecpar->extradata = av_mallocz(ALAC_EXTRADATA_SIZE + AV_INPUT_BUFFER_PADDING_SIZE);
1898 if (!st->codecpar->extradata)
1899 return AVERROR(ENOMEM);
1900 st->codecpar->extradata_size = ALAC_EXTRADATA_SIZE;
1901 AV_WB32(st->codecpar->extradata , ALAC_EXTRADATA_SIZE);
1902 AV_WB32(st->codecpar->extradata + 4, MKTAG('a','l','a','c'));
1903 AV_WB64(st->codecpar->extradata + 12, buffer);
1904 avio_read(pb, st->codecpar->extradata + 20, 16);
1905 avio_skip(pb, atom.size - 24);
1909 if ((ret = mov_read_default(c, pb, atom)) < 0)
1912 avio_skip(pb, atom.size);
1917 * This function reads atom content and puts data in extradata without tag
1918 * nor size unlike mov_read_extradata.
1920 static int mov_read_glbl(MOVContext *c, AVIOContext *pb, MOVAtom atom)
1925 if (c->fc->nb_streams < 1)
1927 st = c->fc->streams[c->fc->nb_streams-1];
1929 if ((uint64_t)atom.size > (1<<30))
1930 return AVERROR_INVALIDDATA;
1932 if (atom.size >= 10) {
1933 // Broken files created by legacy versions of libavformat will
1934 // wrap a whole fiel atom inside of a glbl atom.
1935 unsigned size = avio_rb32(pb);
1936 unsigned type = avio_rl32(pb);
1937 avio_seek(pb, -8, SEEK_CUR);
1938 if (type == MKTAG('f','i','e','l') && size == atom.size)
1939 return mov_read_default(c, pb, atom);
1941 if (st->codecpar->extradata_size > 1 && st->codecpar->extradata) {
1942 av_log(c->fc, AV_LOG_WARNING, "ignoring multiple glbl\n");
1945 ret = ff_get_extradata(c->fc, st->codecpar, pb, atom.size);
1948 if (atom.type == MKTAG('h','v','c','C') && st->codecpar->codec_tag == MKTAG('d','v','h','1'))
1949 /* HEVC-based Dolby Vision derived from hvc1.
1950 Happens to match with an identifier
1951 previously utilized for DV. Thus, if we have
1952 the hvcC extradata box available as specified,
1953 set codec to HEVC */
1954 st->codecpar->codec_id = AV_CODEC_ID_HEVC;
1959 static int mov_read_dvc1(MOVContext *c, AVIOContext *pb, MOVAtom atom)
1962 uint8_t profile_level;
1965 if (c->fc->nb_streams < 1)
1967 st = c->fc->streams[c->fc->nb_streams-1];
1969 if (atom.size >= (1<<28) || atom.size < 7)
1970 return AVERROR_INVALIDDATA;
1972 profile_level = avio_r8(pb);
1973 if ((profile_level & 0xf0) != 0xc0)
1976 avio_seek(pb, 6, SEEK_CUR);
1977 ret = ff_get_extradata(c->fc, st->codecpar, pb, atom.size - 7);
1985 * An strf atom is a BITMAPINFOHEADER struct. This struct is 40 bytes itself,
1986 * but can have extradata appended at the end after the 40 bytes belonging
1989 static int mov_read_strf(MOVContext *c, AVIOContext *pb, MOVAtom atom)
1994 if (c->fc->nb_streams < 1)
1996 if (atom.size <= 40)
1998 st = c->fc->streams[c->fc->nb_streams-1];
2000 if ((uint64_t)atom.size > (1<<30))
2001 return AVERROR_INVALIDDATA;
2004 ret = ff_get_extradata(c->fc, st->codecpar, pb, atom.size - 40);
2011 static int mov_read_stco(MOVContext *c, AVIOContext *pb, MOVAtom atom)
2014 MOVStreamContext *sc;
2015 unsigned int i, entries;
2017 if (c->trak_index < 0) {
2018 av_log(c->fc, AV_LOG_WARNING, "STCO outside TRAK\n");
2021 if (c->fc->nb_streams < 1)
2023 st = c->fc->streams[c->fc->nb_streams-1];
2026 avio_r8(pb); /* version */
2027 avio_rb24(pb); /* flags */
2029 entries = avio_rb32(pb);
2034 if (sc->chunk_offsets)
2035 av_log(c->fc, AV_LOG_WARNING, "Duplicated STCO atom\n");
2036 av_free(sc->chunk_offsets);
2037 sc->chunk_count = 0;
2038 sc->chunk_offsets = av_malloc_array(entries, sizeof(*sc->chunk_offsets));
2039 if (!sc->chunk_offsets)
2040 return AVERROR(ENOMEM);
2041 sc->chunk_count = entries;
2043 if (atom.type == MKTAG('s','t','c','o'))
2044 for (i = 0; i < entries && !pb->eof_reached; i++)
2045 sc->chunk_offsets[i] = avio_rb32(pb);
2046 else if (atom.type == MKTAG('c','o','6','4'))
2047 for (i = 0; i < entries && !pb->eof_reached; i++)
2048 sc->chunk_offsets[i] = avio_rb64(pb);
2050 return AVERROR_INVALIDDATA;
2052 sc->chunk_count = i;
2054 if (pb->eof_reached) {
2055 av_log(c->fc, AV_LOG_WARNING, "reached eof, corrupted STCO atom\n");
2062 static int mov_codec_id(AVStream *st, uint32_t format)
2064 int id = ff_codec_get_id(ff_codec_movaudio_tags, format);
2067 ((format & 0xFFFF) == 'm' + ('s' << 8) ||
2068 (format & 0xFFFF) == 'T' + ('S' << 8)))
2069 id = ff_codec_get_id(ff_codec_wav_tags, av_bswap32(format) & 0xFFFF);
2071 if (st->codecpar->codec_type != AVMEDIA_TYPE_VIDEO && id > 0) {
2072 st->codecpar->codec_type = AVMEDIA_TYPE_AUDIO;
2073 } else if (st->codecpar->codec_type != AVMEDIA_TYPE_AUDIO &&
2074 /* skip old ASF MPEG-4 tag */
2075 format && format != MKTAG('m','p','4','s')) {
2076 id = ff_codec_get_id(ff_codec_movvideo_tags, format);
2078 id = ff_codec_get_id(ff_codec_bmp_tags, format);
2080 st->codecpar->codec_type = AVMEDIA_TYPE_VIDEO;
2081 else if (st->codecpar->codec_type == AVMEDIA_TYPE_DATA ||
2082 (st->codecpar->codec_type == AVMEDIA_TYPE_SUBTITLE &&
2083 st->codecpar->codec_id == AV_CODEC_ID_NONE)) {
2084 id = ff_codec_get_id(ff_codec_movsubtitle_tags, format);
2086 st->codecpar->codec_type = AVMEDIA_TYPE_SUBTITLE;
2088 id = ff_codec_get_id(ff_codec_movdata_tags, format);
2092 st->codecpar->codec_tag = format;
2097 static void mov_parse_stsd_video(MOVContext *c, AVIOContext *pb,
2098 AVStream *st, MOVStreamContext *sc)
2100 uint8_t codec_name[32] = { 0 };
2105 /* The first 16 bytes of the video sample description are already
2106 * read in ff_mov_read_stsd_entries() */
2107 stsd_start = avio_tell(pb) - 16;
2109 avio_rb16(pb); /* version */
2110 avio_rb16(pb); /* revision level */
2111 id = avio_rl32(pb); /* vendor */
2112 av_dict_set(&st->metadata, "vendor_id", av_fourcc2str(id), 0);
2113 avio_rb32(pb); /* temporal quality */
2114 avio_rb32(pb); /* spatial quality */
2116 st->codecpar->width = avio_rb16(pb); /* width */
2117 st->codecpar->height = avio_rb16(pb); /* height */
2119 avio_rb32(pb); /* horiz resolution */
2120 avio_rb32(pb); /* vert resolution */
2121 avio_rb32(pb); /* data size, always 0 */
2122 avio_rb16(pb); /* frames per samples */
2124 len = avio_r8(pb); /* codec name, pascal string */
2127 mov_read_mac_string(c, pb, len, codec_name, sizeof(codec_name));
2129 avio_skip(pb, 31 - len);
2132 av_dict_set(&st->metadata, "encoder", codec_name, 0);
2134 /* codec_tag YV12 triggers an UV swap in rawdec.c */
2135 if (!strncmp(codec_name, "Planar Y'CbCr 8-bit 4:2:0", 25)) {
2136 st->codecpar->codec_tag = MKTAG('I', '4', '2', '0');
2137 st->codecpar->width &= ~1;
2138 st->codecpar->height &= ~1;
2140 /* Flash Media Server uses tag H.263 with Sorenson Spark */
2141 if (st->codecpar->codec_tag == MKTAG('H','2','6','3') &&
2142 !strncmp(codec_name, "Sorenson H263", 13))
2143 st->codecpar->codec_id = AV_CODEC_ID_FLV1;
2145 st->codecpar->bits_per_coded_sample = avio_rb16(pb); /* depth */
2147 avio_seek(pb, stsd_start, SEEK_SET);
2149 if (ff_get_qtpalette(st->codecpar->codec_id, pb, sc->palette)) {
2150 st->codecpar->bits_per_coded_sample &= 0x1F;
2151 sc->has_palette = 1;
2155 static void mov_parse_stsd_audio(MOVContext *c, AVIOContext *pb,
2156 AVStream *st, MOVStreamContext *sc)
2158 int bits_per_sample, flags;
2159 uint16_t version = avio_rb16(pb);
2161 AVDictionaryEntry *compatible_brands = av_dict_get(c->fc->metadata, "compatible_brands", NULL, AV_DICT_MATCH_CASE);
2163 avio_rb16(pb); /* revision level */
2164 id = avio_rl32(pb); /* vendor */
2165 av_dict_set(&st->metadata, "vendor_id", av_fourcc2str(id), 0);
2167 st->codecpar->channels = avio_rb16(pb); /* channel count */
2168 st->codecpar->bits_per_coded_sample = avio_rb16(pb); /* sample size */
2169 av_log(c->fc, AV_LOG_TRACE, "audio channels %d\n", st->codecpar->channels);
2171 sc->audio_cid = avio_rb16(pb);
2172 avio_rb16(pb); /* packet size = 0 */
2174 st->codecpar->sample_rate = ((avio_rb32(pb) >> 16));
2176 // Read QT version 1 fields. In version 0 these do not exist.
2177 av_log(c->fc, AV_LOG_TRACE, "version =%d, isom =%d\n", version, c->isom);
2179 (compatible_brands && strstr(compatible_brands->value, "qt ")) ||
2180 (sc->stsd_version == 0 && version > 0)) {
2182 sc->samples_per_frame = avio_rb32(pb);
2183 avio_rb32(pb); /* bytes per packet */
2184 sc->bytes_per_frame = avio_rb32(pb);
2185 avio_rb32(pb); /* bytes per sample */
2186 } else if (version == 2) {
2187 avio_rb32(pb); /* sizeof struct only */
2188 st->codecpar->sample_rate = av_int2double(avio_rb64(pb));
2189 st->codecpar->channels = avio_rb32(pb);
2190 avio_rb32(pb); /* always 0x7F000000 */
2191 st->codecpar->bits_per_coded_sample = avio_rb32(pb);
2193 flags = avio_rb32(pb); /* lpcm format specific flag */
2194 sc->bytes_per_frame = avio_rb32(pb);
2195 sc->samples_per_frame = avio_rb32(pb);
2196 if (st->codecpar->codec_tag == MKTAG('l','p','c','m'))
2197 st->codecpar->codec_id =
2198 ff_mov_get_lpcm_codec_id(st->codecpar->bits_per_coded_sample,
2201 if (version == 0 || (version == 1 && sc->audio_cid != -2)) {
2202 /* can't correctly handle variable sized packet as audio unit */
2203 switch (st->codecpar->codec_id) {
2204 case AV_CODEC_ID_MP2:
2205 case AV_CODEC_ID_MP3:
2206 st->need_parsing = AVSTREAM_PARSE_FULL;
2212 if (sc->format == 0) {
2213 if (st->codecpar->bits_per_coded_sample == 8)
2214 st->codecpar->codec_id = mov_codec_id(st, MKTAG('r','a','w',' '));
2215 else if (st->codecpar->bits_per_coded_sample == 16)
2216 st->codecpar->codec_id = mov_codec_id(st, MKTAG('t','w','o','s'));
2219 switch (st->codecpar->codec_id) {
2220 case AV_CODEC_ID_PCM_S8:
2221 case AV_CODEC_ID_PCM_U8:
2222 if (st->codecpar->bits_per_coded_sample == 16)
2223 st->codecpar->codec_id = AV_CODEC_ID_PCM_S16BE;
2225 case AV_CODEC_ID_PCM_S16LE:
2226 case AV_CODEC_ID_PCM_S16BE:
2227 if (st->codecpar->bits_per_coded_sample == 8)
2228 st->codecpar->codec_id = AV_CODEC_ID_PCM_S8;
2229 else if (st->codecpar->bits_per_coded_sample == 24)
2230 st->codecpar->codec_id =
2231 st->codecpar->codec_id == AV_CODEC_ID_PCM_S16BE ?
2232 AV_CODEC_ID_PCM_S24BE : AV_CODEC_ID_PCM_S24LE;
2233 else if (st->codecpar->bits_per_coded_sample == 32)
2234 st->codecpar->codec_id =
2235 st->codecpar->codec_id == AV_CODEC_ID_PCM_S16BE ?
2236 AV_CODEC_ID_PCM_S32BE : AV_CODEC_ID_PCM_S32LE;
2238 /* set values for old format before stsd version 1 appeared */
2239 case AV_CODEC_ID_MACE3:
2240 sc->samples_per_frame = 6;
2241 sc->bytes_per_frame = 2 * st->codecpar->channels;
2243 case AV_CODEC_ID_MACE6:
2244 sc->samples_per_frame = 6;
2245 sc->bytes_per_frame = 1 * st->codecpar->channels;
2247 case AV_CODEC_ID_ADPCM_IMA_QT:
2248 sc->samples_per_frame = 64;
2249 sc->bytes_per_frame = 34 * st->codecpar->channels;
2251 case AV_CODEC_ID_GSM:
2252 sc->samples_per_frame = 160;
2253 sc->bytes_per_frame = 33;
2259 bits_per_sample = av_get_bits_per_sample(st->codecpar->codec_id);
2260 if (bits_per_sample) {
2261 st->codecpar->bits_per_coded_sample = bits_per_sample;
2262 sc->sample_size = (bits_per_sample >> 3) * st->codecpar->channels;
2266 static void mov_parse_stsd_subtitle(MOVContext *c, AVIOContext *pb,
2267 AVStream *st, MOVStreamContext *sc,
2270 // ttxt stsd contains display flags, justification, background
2271 // color, fonts, and default styles, so fake an atom to read it
2272 MOVAtom fake_atom = { .size = size };
2273 // mp4s contains a regular esds atom
2274 if (st->codecpar->codec_tag != AV_RL32("mp4s"))
2275 mov_read_glbl(c, pb, fake_atom);
2276 st->codecpar->width = sc->width;
2277 st->codecpar->height = sc->height;
2280 static uint32_t yuv_to_rgba(uint32_t ycbcr)
2285 y = (ycbcr >> 16) & 0xFF;
2286 cr = (ycbcr >> 8) & 0xFF;
2289 b = av_clip_uint8((1164 * (y - 16) + 2018 * (cb - 128)) / 1000);
2290 g = av_clip_uint8((1164 * (y - 16) - 813 * (cr - 128) - 391 * (cb - 128)) / 1000);
2291 r = av_clip_uint8((1164 * (y - 16) + 1596 * (cr - 128) ) / 1000);
2293 return (r << 16) | (g << 8) | b;
2296 static int mov_rewrite_dvd_sub_extradata(AVStream *st)
2298 char buf[256] = {0};
2299 uint8_t *src = st->codecpar->extradata;
2302 if (st->codecpar->extradata_size != 64)
2305 if (st->codecpar->width > 0 && st->codecpar->height > 0)
2306 snprintf(buf, sizeof(buf), "size: %dx%d\n",
2307 st->codecpar->width, st->codecpar->height);
2308 av_strlcat(buf, "palette: ", sizeof(buf));
2310 for (i = 0; i < 16; i++) {
2311 uint32_t yuv = AV_RB32(src + i * 4);
2312 uint32_t rgba = yuv_to_rgba(yuv);
2314 av_strlcatf(buf, sizeof(buf), "%06"PRIx32"%s", rgba, i != 15 ? ", " : "");
2317 if (av_strlcat(buf, "\n", sizeof(buf)) >= sizeof(buf))
2320 ret = ff_alloc_extradata(st->codecpar, strlen(buf));
2323 memcpy(st->codecpar->extradata, buf, st->codecpar->extradata_size);
2328 static int mov_parse_stsd_data(MOVContext *c, AVIOContext *pb,
2329 AVStream *st, MOVStreamContext *sc,
2334 if (st->codecpar->codec_tag == MKTAG('t','m','c','d')) {
2335 if ((int)size != size)
2336 return AVERROR(ENOMEM);
2338 ret = ff_get_extradata(c->fc, st->codecpar, pb, size);
2342 MOVStreamContext *tmcd_ctx = st->priv_data;
2344 val = AV_RB32(st->codecpar->extradata + 4);
2345 tmcd_ctx->tmcd_flags = val;
2346 st->avg_frame_rate.num = AV_RB32(st->codecpar->extradata + 8); /* timescale */
2347 st->avg_frame_rate.den = AV_RB32(st->codecpar->extradata + 12); /* frameDuration */
2348 #if FF_API_LAVF_AVCTX
2349 FF_DISABLE_DEPRECATION_WARNINGS
2350 st->codec->time_base = av_inv_q(st->avg_frame_rate);
2351 FF_ENABLE_DEPRECATION_WARNINGS
2353 /* adjust for per frame dur in counter mode */
2354 if (tmcd_ctx->tmcd_flags & 0x0008) {
2355 int timescale = AV_RB32(st->codecpar->extradata + 8);
2356 int framedur = AV_RB32(st->codecpar->extradata + 12);
2357 st->avg_frame_rate.num *= timescale;
2358 st->avg_frame_rate.den *= framedur;
2359 #if FF_API_LAVF_AVCTX
2360 FF_DISABLE_DEPRECATION_WARNINGS
2361 st->codec->time_base.den *= timescale;
2362 st->codec->time_base.num *= framedur;
2363 FF_ENABLE_DEPRECATION_WARNINGS
2367 uint32_t len = AV_RB32(st->codecpar->extradata + 18); /* name atom length */
2368 uint32_t format = AV_RB32(st->codecpar->extradata + 22);
2369 if (format == AV_RB32("name") && (int64_t)size >= (int64_t)len + 18) {
2370 uint16_t str_size = AV_RB16(st->codecpar->extradata + 26); /* string length */
2371 if (str_size > 0 && size >= (int)str_size + 30 &&
2372 st->codecpar->extradata[30] /* Don't add empty string */) {
2373 char *reel_name = av_malloc(str_size + 1);
2375 return AVERROR(ENOMEM);
2376 memcpy(reel_name, st->codecpar->extradata + 30, str_size);
2377 reel_name[str_size] = 0; /* Add null terminator */
2378 av_dict_set(&st->metadata, "reel_name", reel_name,
2379 AV_DICT_DONT_STRDUP_VAL);
2385 /* other codec type, just skip (rtp, mp4s ...) */
2386 avio_skip(pb, size);
2391 static int mov_finalize_stsd_codec(MOVContext *c, AVIOContext *pb,
2392 AVStream *st, MOVStreamContext *sc)
2394 if (st->codecpar->codec_type == AVMEDIA_TYPE_AUDIO &&
2395 !st->codecpar->sample_rate && sc->time_scale > 1)
2396 st->codecpar->sample_rate = sc->time_scale;
2398 /* special codec parameters handling */
2399 switch (st->codecpar->codec_id) {
2400 #if CONFIG_DV_DEMUXER
2401 case AV_CODEC_ID_DVAUDIO:
2402 c->dv_fctx = avformat_alloc_context();
2404 av_log(c->fc, AV_LOG_ERROR, "dv demux context alloc error\n");
2405 return AVERROR(ENOMEM);
2407 c->dv_demux = avpriv_dv_init_demux(c->dv_fctx);
2409 av_log(c->fc, AV_LOG_ERROR, "dv demux context init error\n");
2410 return AVERROR(ENOMEM);
2412 sc->dv_audio_container = 1;
2413 st->codecpar->codec_id = AV_CODEC_ID_PCM_S16LE;
2416 /* no ifdef since parameters are always those */
2417 case AV_CODEC_ID_QCELP:
2418 st->codecpar->channels = 1;
2419 // force sample rate for qcelp when not stored in mov
2420 if (st->codecpar->codec_tag != MKTAG('Q','c','l','p'))
2421 st->codecpar->sample_rate = 8000;
2422 // FIXME: Why is the following needed for some files?
2423 sc->samples_per_frame = 160;
2424 if (!sc->bytes_per_frame)
2425 sc->bytes_per_frame = 35;
2427 case AV_CODEC_ID_AMR_NB:
2428 st->codecpar->channels = 1;
2429 /* force sample rate for amr, stsd in 3gp does not store sample rate */
2430 st->codecpar->sample_rate = 8000;
2432 case AV_CODEC_ID_AMR_WB:
2433 st->codecpar->channels = 1;
2434 st->codecpar->sample_rate = 16000;
2436 case AV_CODEC_ID_MP2:
2437 case AV_CODEC_ID_MP3:
2438 /* force type after stsd for m1a hdlr */
2439 st->codecpar->codec_type = AVMEDIA_TYPE_AUDIO;
2441 case AV_CODEC_ID_GSM:
2442 case AV_CODEC_ID_ADPCM_MS:
2443 case AV_CODEC_ID_ADPCM_IMA_WAV:
2444 case AV_CODEC_ID_ILBC:
2445 case AV_CODEC_ID_MACE3:
2446 case AV_CODEC_ID_MACE6:
2447 case AV_CODEC_ID_QDM2:
2448 st->codecpar->block_align = sc->bytes_per_frame;
2450 case AV_CODEC_ID_ALAC:
2451 if (st->codecpar->extradata_size == 36) {
2452 st->codecpar->channels = AV_RB8 (st->codecpar->extradata + 21);
2453 st->codecpar->sample_rate = AV_RB32(st->codecpar->extradata + 32);
2456 case AV_CODEC_ID_AC3:
2457 case AV_CODEC_ID_EAC3:
2458 case AV_CODEC_ID_MPEG1VIDEO:
2459 case AV_CODEC_ID_VC1:
2460 case AV_CODEC_ID_VP8:
2461 case AV_CODEC_ID_VP9:
2462 st->need_parsing = AVSTREAM_PARSE_FULL;
2464 case AV_CODEC_ID_AV1:
2465 st->need_parsing = AVSTREAM_PARSE_HEADERS;
2473 static int mov_skip_multiple_stsd(MOVContext *c, AVIOContext *pb,
2474 int codec_tag, int format,
2477 int video_codec_id = ff_codec_get_id(ff_codec_movvideo_tags, format);
2480 (codec_tag != format &&
2481 // AVID 1:1 samples with differing data format and codec tag exist
2482 (codec_tag != AV_RL32("AV1x") || format != AV_RL32("AVup")) &&
2483 // prores is allowed to have differing data format and codec tag
2484 codec_tag != AV_RL32("apcn") && codec_tag != AV_RL32("apch") &&
2486 codec_tag != AV_RL32("dvpp") && codec_tag != AV_RL32("dvcp") &&
2487 (c->fc->video_codec_id ? video_codec_id != c->fc->video_codec_id
2488 : codec_tag != MKTAG('j','p','e','g')))) {
2489 /* Multiple fourcc, we skip JPEG. This is not correct, we should
2490 * export it as a separate AVStream but this needs a few changes
2491 * in the MOV demuxer, patch welcome. */
2493 av_log(c->fc, AV_LOG_WARNING, "multiple fourcc not supported\n");
2494 avio_skip(pb, size);
2501 int ff_mov_read_stsd_entries(MOVContext *c, AVIOContext *pb, int entries)
2504 MOVStreamContext *sc;
2505 int pseudo_stream_id;
2507 av_assert0 (c->fc->nb_streams >= 1);
2508 st = c->fc->streams[c->fc->nb_streams-1];
2511 for (pseudo_stream_id = 0;
2512 pseudo_stream_id < entries && !pb->eof_reached;
2513 pseudo_stream_id++) {
2514 //Parsing Sample description table
2516 int ret, dref_id = 1;
2517 MOVAtom a = { AV_RL32("stsd") };
2518 int64_t start_pos = avio_tell(pb);
2519 int64_t size = avio_rb32(pb); /* size */
2520 uint32_t format = avio_rl32(pb); /* data format */
2523 avio_rb32(pb); /* reserved */
2524 avio_rb16(pb); /* reserved */
2525 dref_id = avio_rb16(pb);
2526 } else if (size <= 7) {
2527 av_log(c->fc, AV_LOG_ERROR,
2528 "invalid size %"PRId64" in stsd\n", size);
2529 return AVERROR_INVALIDDATA;
2532 if (mov_skip_multiple_stsd(c, pb, st->codecpar->codec_tag, format,
2533 size - (avio_tell(pb) - start_pos))) {
2538 sc->pseudo_stream_id = st->codecpar->codec_tag ? -1 : pseudo_stream_id;
2539 sc->dref_id= dref_id;
2540 sc->format = format;
2542 id = mov_codec_id(st, format);
2544 av_log(c->fc, AV_LOG_TRACE,
2545 "size=%"PRId64" 4CC=%s codec_type=%d\n", size,
2546 av_fourcc2str(format), st->codecpar->codec_type);
2548 st->codecpar->codec_id = id;
2549 if (st->codecpar->codec_type==AVMEDIA_TYPE_VIDEO) {
2550 mov_parse_stsd_video(c, pb, st, sc);
2551 } else if (st->codecpar->codec_type==AVMEDIA_TYPE_AUDIO) {
2552 mov_parse_stsd_audio(c, pb, st, sc);
2553 if (st->codecpar->sample_rate < 0) {
2554 av_log(c->fc, AV_LOG_ERROR, "Invalid sample rate %d\n", st->codecpar->sample_rate);
2555 return AVERROR_INVALIDDATA;
2557 } else if (st->codecpar->codec_type==AVMEDIA_TYPE_SUBTITLE){
2558 mov_parse_stsd_subtitle(c, pb, st, sc,
2559 size - (avio_tell(pb) - start_pos));
2561 ret = mov_parse_stsd_data(c, pb, st, sc,
2562 size - (avio_tell(pb) - start_pos));
2566 /* this will read extra atoms at the end (wave, alac, damr, avcC, hvcC, SMI ...) */
2567 a.size = size - (avio_tell(pb) - start_pos);
2569 if ((ret = mov_read_default(c, pb, a)) < 0)
2571 } else if (a.size > 0)
2572 avio_skip(pb, a.size);
2574 if (sc->extradata && st->codecpar->extradata) {
2575 int extra_size = st->codecpar->extradata_size;
2577 /* Move the current stream extradata to the stream context one. */
2578 sc->extradata_size[pseudo_stream_id] = extra_size;
2579 sc->extradata[pseudo_stream_id] = st->codecpar->extradata;
2580 st->codecpar->extradata = NULL;
2581 st->codecpar->extradata_size = 0;
2586 if (pb->eof_reached) {
2587 av_log(c->fc, AV_LOG_WARNING, "reached eof, corrupted STSD atom\n");
2594 static int mov_read_stsd(MOVContext *c, AVIOContext *pb, MOVAtom atom)
2597 MOVStreamContext *sc;
2600 if (c->fc->nb_streams < 1)
2602 st = c->fc->streams[c->fc->nb_streams - 1];
2605 sc->stsd_version = avio_r8(pb);
2606 avio_rb24(pb); /* flags */
2607 entries = avio_rb32(pb);
2609 /* Each entry contains a size (4 bytes) and format (4 bytes). */
2610 if (entries <= 0 || entries > atom.size / 8) {
2611 av_log(c->fc, AV_LOG_ERROR, "invalid STSD entries %d\n", entries);
2612 return AVERROR_INVALIDDATA;
2615 if (sc->extradata) {
2616 av_log(c->fc, AV_LOG_ERROR,
2617 "Duplicate stsd found in this track.\n");
2618 return AVERROR_INVALIDDATA;
2621 /* Prepare space for hosting multiple extradata. */
2622 sc->extradata = av_mallocz_array(entries, sizeof(*sc->extradata));
2624 return AVERROR(ENOMEM);
2626 sc->extradata_size = av_mallocz_array(entries, sizeof(*sc->extradata_size));
2627 if (!sc->extradata_size) {
2628 ret = AVERROR(ENOMEM);
2632 ret = ff_mov_read_stsd_entries(c, pb, entries);
2636 /* Restore back the primary extradata. */
2637 av_freep(&st->codecpar->extradata);
2638 st->codecpar->extradata_size = sc->extradata_size[0];
2639 if (sc->extradata_size[0]) {
2640 st->codecpar->extradata = av_mallocz(sc->extradata_size[0] + AV_INPUT_BUFFER_PADDING_SIZE);
2641 if (!st->codecpar->extradata)
2642 return AVERROR(ENOMEM);
2643 memcpy(st->codecpar->extradata, sc->extradata[0], sc->extradata_size[0]);
2646 return mov_finalize_stsd_codec(c, pb, st, sc);
2648 if (sc->extradata) {
2650 for (j = 0; j < sc->stsd_count; j++)
2651 av_freep(&sc->extradata[j]);
2654 av_freep(&sc->extradata);
2655 av_freep(&sc->extradata_size);
2659 static int mov_read_stsc(MOVContext *c, AVIOContext *pb, MOVAtom atom)
2662 MOVStreamContext *sc;
2663 unsigned int i, entries;
2665 if (c->fc->nb_streams < 1)
2667 st = c->fc->streams[c->fc->nb_streams-1];
2670 avio_r8(pb); /* version */
2671 avio_rb24(pb); /* flags */
2673 entries = avio_rb32(pb);
2674 if ((uint64_t)entries * 12 + 4 > atom.size)
2675 return AVERROR_INVALIDDATA;
2677 av_log(c->fc, AV_LOG_TRACE, "track[%u].stsc.entries = %u\n", c->fc->nb_streams - 1, entries);
2682 av_log(c->fc, AV_LOG_WARNING, "Duplicated STSC atom\n");
2683 av_free(sc->stsc_data);
2685 sc->stsc_data = av_malloc_array(entries, sizeof(*sc->stsc_data));
2687 return AVERROR(ENOMEM);
2689 for (i = 0; i < entries && !pb->eof_reached; i++) {
2690 sc->stsc_data[i].first = avio_rb32(pb);
2691 sc->stsc_data[i].count = avio_rb32(pb);
2692 sc->stsc_data[i].id = avio_rb32(pb);
2696 for (i = sc->stsc_count - 1; i < UINT_MAX; i--) {
2697 int64_t first_min = i + 1;
2698 if ((i+1 < sc->stsc_count && sc->stsc_data[i].first >= sc->stsc_data[i+1].first) ||
2699 (i > 0 && sc->stsc_data[i].first <= sc->stsc_data[i-1].first) ||
2700 sc->stsc_data[i].first < first_min ||
2701 sc->stsc_data[i].count < 1 ||
2702 sc->stsc_data[i].id < 1) {
2703 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);
2704 if (i+1 >= sc->stsc_count) {
2705 if (sc->stsc_data[i].count == 0 && i > 0) {
2709 sc->stsc_data[i].first = FFMAX(sc->stsc_data[i].first, first_min);
2710 if (i > 0 && sc->stsc_data[i].first <= sc->stsc_data[i-1].first)
2711 sc->stsc_data[i].first = FFMIN(sc->stsc_data[i-1].first + 1LL, INT_MAX);
2712 sc->stsc_data[i].count = FFMAX(sc->stsc_data[i].count, 1);
2713 sc->stsc_data[i].id = FFMAX(sc->stsc_data[i].id, 1);
2716 av_assert0(sc->stsc_data[i+1].first >= 2);
2717 // We replace this entry by the next valid
2718 sc->stsc_data[i].first = sc->stsc_data[i+1].first - 1;
2719 sc->stsc_data[i].count = sc->stsc_data[i+1].count;
2720 sc->stsc_data[i].id = sc->stsc_data[i+1].id;
2724 if (pb->eof_reached) {
2725 av_log(c->fc, AV_LOG_WARNING, "reached eof, corrupted STSC atom\n");
2732 static inline int mov_stsc_index_valid(unsigned int index, unsigned int count)
2734 return index < count - 1;
2737 /* Compute the samples value for the stsc entry at the given index. */
2738 static inline int64_t mov_get_stsc_samples(MOVStreamContext *sc, unsigned int index)
2742 if (mov_stsc_index_valid(index, sc->stsc_count))
2743 chunk_count = sc->stsc_data[index + 1].first - sc->stsc_data[index].first;
2745 // Validation for stsc / stco happens earlier in mov_read_stsc + mov_read_trak.
2746 av_assert0(sc->stsc_data[index].first <= sc->chunk_count);
2747 chunk_count = sc->chunk_count - (sc->stsc_data[index].first - 1);
2750 return sc->stsc_data[index].count * (int64_t)chunk_count;
2753 static int mov_read_stps(MOVContext *c, AVIOContext *pb, MOVAtom atom)
2756 MOVStreamContext *sc;
2757 unsigned i, entries;
2759 if (c->fc->nb_streams < 1)
2761 st = c->fc->streams[c->fc->nb_streams-1];
2764 avio_rb32(pb); // version + flags
2766 entries = avio_rb32(pb);
2768 av_log(c->fc, AV_LOG_WARNING, "Duplicated STPS atom\n");
2769 av_free(sc->stps_data);
2771 sc->stps_data = av_malloc_array(entries, sizeof(*sc->stps_data));
2773 return AVERROR(ENOMEM);
2775 for (i = 0; i < entries && !pb->eof_reached; i++) {
2776 sc->stps_data[i] = avio_rb32(pb);
2781 if (pb->eof_reached) {
2782 av_log(c->fc, AV_LOG_WARNING, "reached eof, corrupted STPS atom\n");
2789 static int mov_read_stss(MOVContext *c, AVIOContext *pb, MOVAtom atom)
2792 MOVStreamContext *sc;
2793 unsigned int i, entries;
2795 if (c->fc->nb_streams < 1)
2797 st = c->fc->streams[c->fc->nb_streams-1];
2800 avio_r8(pb); /* version */
2801 avio_rb24(pb); /* flags */
2803 entries = avio_rb32(pb);
2805 av_log(c->fc, AV_LOG_TRACE, "keyframe_count = %u\n", entries);
2808 sc->keyframe_absent = 1;
2809 if (!st->need_parsing && st->codecpar->codec_type == AVMEDIA_TYPE_VIDEO)
2810 st->need_parsing = AVSTREAM_PARSE_HEADERS;
2814 av_log(c->fc, AV_LOG_WARNING, "Duplicated STSS atom\n");
2815 if (entries >= UINT_MAX / sizeof(int))
2816 return AVERROR_INVALIDDATA;
2817 av_freep(&sc->keyframes);
2818 sc->keyframe_count = 0;
2819 sc->keyframes = av_malloc_array(entries, sizeof(*sc->keyframes));
2821 return AVERROR(ENOMEM);
2823 for (i = 0; i < entries && !pb->eof_reached; i++) {
2824 sc->keyframes[i] = avio_rb32(pb);
2827 sc->keyframe_count = i;
2829 if (pb->eof_reached) {
2830 av_log(c->fc, AV_LOG_WARNING, "reached eof, corrupted STSS atom\n");
2837 static int mov_read_stsz(MOVContext *c, AVIOContext *pb, MOVAtom atom)
2840 MOVStreamContext *sc;
2841 unsigned int i, entries, sample_size, field_size, num_bytes;
2846 if (c->fc->nb_streams < 1)
2848 st = c->fc->streams[c->fc->nb_streams-1];
2851 avio_r8(pb); /* version */
2852 avio_rb24(pb); /* flags */
2854 if (atom.type == MKTAG('s','t','s','z')) {
2855 sample_size = avio_rb32(pb);
2856 if (!sc->sample_size) /* do not overwrite value computed in stsd */
2857 sc->sample_size = sample_size;
2858 sc->stsz_sample_size = sample_size;
2862 avio_rb24(pb); /* reserved */
2863 field_size = avio_r8(pb);
2865 entries = avio_rb32(pb);
2867 av_log(c->fc, AV_LOG_TRACE, "sample_size = %u sample_count = %u\n", sc->sample_size, entries);
2869 sc->sample_count = entries;
2873 if (field_size != 4 && field_size != 8 && field_size != 16 && field_size != 32) {
2874 av_log(c->fc, AV_LOG_ERROR, "Invalid sample field size %u\n", field_size);
2875 return AVERROR_INVALIDDATA;
2880 if (entries >= (UINT_MAX - 4) / field_size)
2881 return AVERROR_INVALIDDATA;
2882 if (sc->sample_sizes)
2883 av_log(c->fc, AV_LOG_WARNING, "Duplicated STSZ atom\n");
2884 av_free(sc->sample_sizes);
2885 sc->sample_count = 0;
2886 sc->sample_sizes = av_malloc_array(entries, sizeof(*sc->sample_sizes));
2887 if (!sc->sample_sizes)
2888 return AVERROR(ENOMEM);
2890 num_bytes = (entries*field_size+4)>>3;
2892 buf = av_malloc(num_bytes+AV_INPUT_BUFFER_PADDING_SIZE);
2894 av_freep(&sc->sample_sizes);
2895 return AVERROR(ENOMEM);
2898 ret = ffio_read_size(pb, buf, num_bytes);
2900 av_freep(&sc->sample_sizes);
2902 av_log(c->fc, AV_LOG_WARNING, "STSZ atom truncated\n");
2906 init_get_bits(&gb, buf, 8*num_bytes);
2908 for (i = 0; i < entries && !pb->eof_reached; i++) {
2909 sc->sample_sizes[i] = get_bits_long(&gb, field_size);
2910 if (sc->sample_sizes[i] < 0) {
2912 av_log(c->fc, AV_LOG_ERROR, "Invalid sample size %d\n", sc->sample_sizes[i]);
2913 return AVERROR_INVALIDDATA;
2915 sc->data_size += sc->sample_sizes[i];
2918 sc->sample_count = i;
2922 if (pb->eof_reached) {
2923 av_log(c->fc, AV_LOG_WARNING, "reached eof, corrupted STSZ atom\n");
2930 static int mov_read_stts(MOVContext *c, AVIOContext *pb, MOVAtom atom)
2933 MOVStreamContext *sc;
2934 unsigned int i, entries, alloc_size = 0;
2935 int64_t duration = 0;
2936 int64_t total_sample_count = 0;
2938 if (c->fc->nb_streams < 1)
2940 st = c->fc->streams[c->fc->nb_streams-1];
2943 avio_r8(pb); /* version */
2944 avio_rb24(pb); /* flags */
2945 entries = avio_rb32(pb);
2947 av_log(c->fc, AV_LOG_TRACE, "track[%u].stts.entries = %u\n",
2948 c->fc->nb_streams-1, entries);
2951 av_log(c->fc, AV_LOG_WARNING, "Duplicated STTS atom\n");
2952 av_freep(&sc->stts_data);
2954 if (entries >= INT_MAX / sizeof(*sc->stts_data))
2955 return AVERROR(ENOMEM);
2957 for (i = 0; i < entries && !pb->eof_reached; i++) {
2958 int sample_duration;
2959 unsigned int sample_count;
2960 unsigned int min_entries = FFMIN(FFMAX(i + 1, 1024 * 1024), entries);
2961 MOVStts *stts_data = av_fast_realloc(sc->stts_data, &alloc_size,
2962 min_entries * sizeof(*sc->stts_data));
2964 av_freep(&sc->stts_data);
2966 return AVERROR(ENOMEM);
2968 sc->stts_count = min_entries;
2969 sc->stts_data = stts_data;
2971 sample_count = avio_rb32(pb);
2972 sample_duration = avio_rb32(pb);
2974 sc->stts_data[i].count= sample_count;
2975 sc->stts_data[i].duration= sample_duration;
2977 av_log(c->fc, AV_LOG_TRACE, "sample_count=%d, sample_duration=%d\n",
2978 sample_count, sample_duration);
2980 duration+=(int64_t)sample_duration*(uint64_t)sample_count;
2981 total_sample_count+=sample_count;
2987 duration <= INT64_MAX - sc->duration_for_fps &&
2988 total_sample_count <= INT_MAX - sc->nb_frames_for_fps) {
2989 sc->duration_for_fps += duration;
2990 sc->nb_frames_for_fps += total_sample_count;
2993 if (pb->eof_reached) {
2994 av_log(c->fc, AV_LOG_WARNING, "reached eof, corrupted STTS atom\n");
2998 st->nb_frames= total_sample_count;
3000 st->duration= FFMIN(st->duration, duration);
3001 sc->track_end = duration;
3005 static int mov_read_sdtp(MOVContext *c, AVIOContext *pb, MOVAtom atom)
3008 MOVStreamContext *sc;
3011 if (c->fc->nb_streams < 1)
3013 st = c->fc->streams[c->fc->nb_streams - 1];
3016 avio_r8(pb); /* version */
3017 avio_rb24(pb); /* flags */
3018 entries = atom.size - 4;
3020 av_log(c->fc, AV_LOG_TRACE, "track[%u].sdtp.entries = %" PRId64 "\n",
3021 c->fc->nb_streams - 1, entries);
3024 av_log(c->fc, AV_LOG_WARNING, "Duplicated SDTP atom\n");
3025 av_freep(&sc->sdtp_data);
3028 sc->sdtp_data = av_mallocz(entries);
3030 return AVERROR(ENOMEM);
3032 for (i = 0; i < entries && !pb->eof_reached; i++)
3033 sc->sdtp_data[i] = avio_r8(pb);
3039 static void mov_update_dts_shift(MOVStreamContext *sc, int duration, void *logctx)
3042 if (duration == INT_MIN) {
3043 av_log(logctx, AV_LOG_WARNING, "mov_update_dts_shift(): dts_shift set to %d\n", INT_MAX);
3046 sc->dts_shift = FFMAX(sc->dts_shift, -duration);
3050 static int mov_read_ctts(MOVContext *c, AVIOContext *pb, MOVAtom atom)
3053 MOVStreamContext *sc;
3054 unsigned int i, entries, ctts_count = 0;
3056 if (c->fc->nb_streams < 1)
3058 st = c->fc->streams[c->fc->nb_streams-1];
3061 avio_r8(pb); /* version */
3062 avio_rb24(pb); /* flags */
3063 entries = avio_rb32(pb);
3065 av_log(c->fc, AV_LOG_TRACE, "track[%u].ctts.entries = %u\n", c->fc->nb_streams - 1, entries);
3069 if (entries >= UINT_MAX / sizeof(*sc->ctts_data))
3070 return AVERROR_INVALIDDATA;
3071 av_freep(&sc->ctts_data);
3072 sc->ctts_data = av_fast_realloc(NULL, &sc->ctts_allocated_size, entries * sizeof(*sc->ctts_data));
3074 return AVERROR(ENOMEM);
3076 for (i = 0; i < entries && !pb->eof_reached; i++) {
3077 int count = avio_rb32(pb);
3078 int duration = avio_rb32(pb);
3081 av_log(c->fc, AV_LOG_TRACE,
3082 "ignoring CTTS entry with count=%d duration=%d\n",
3087 add_ctts_entry(&sc->ctts_data, &ctts_count, &sc->ctts_allocated_size,
3090 av_log(c->fc, AV_LOG_TRACE, "count=%d, duration=%d\n",
3093 if (FFNABS(duration) < -(1<<28) && i+2<entries) {
3094 av_log(c->fc, AV_LOG_WARNING, "CTTS invalid\n");
3095 av_freep(&sc->ctts_data);
3101 mov_update_dts_shift(sc, duration, c->fc);
3104 sc->ctts_count = ctts_count;
3106 if (pb->eof_reached) {
3107 av_log(c->fc, AV_LOG_WARNING, "reached eof, corrupted CTTS atom\n");
3111 av_log(c->fc, AV_LOG_TRACE, "dts shift %d\n", sc->dts_shift);
3116 static int mov_read_sbgp(MOVContext *c, AVIOContext *pb, MOVAtom atom)
3119 MOVStreamContext *sc;
3120 unsigned int i, entries;
3122 uint32_t grouping_type;
3124 if (c->fc->nb_streams < 1)
3126 st = c->fc->streams[c->fc->nb_streams-1];
3129 version = avio_r8(pb); /* version */
3130 avio_rb24(pb); /* flags */
3131 grouping_type = avio_rl32(pb);
3132 if (grouping_type != MKTAG( 'r','a','p',' '))
3133 return 0; /* only support 'rap ' grouping */
3135 avio_rb32(pb); /* grouping_type_parameter */
3137 entries = avio_rb32(pb);
3141 av_log(c->fc, AV_LOG_WARNING, "Duplicated SBGP atom\n");
3142 av_free(sc->rap_group);
3143 sc->rap_group_count = 0;
3144 sc->rap_group = av_malloc_array(entries, sizeof(*sc->rap_group));
3146 return AVERROR(ENOMEM);
3148 for (i = 0; i < entries && !pb->eof_reached; i++) {
3149 sc->rap_group[i].count = avio_rb32(pb); /* sample_count */
3150 sc->rap_group[i].index = avio_rb32(pb); /* group_description_index */
3153 sc->rap_group_count = i;
3155 if (pb->eof_reached) {
3156 av_log(c->fc, AV_LOG_WARNING, "reached eof, corrupted SBGP atom\n");
3164 * Get ith edit list entry (media time, duration).
3166 static int get_edit_list_entry(MOVContext *mov,
3167 const MOVStreamContext *msc,
3168 unsigned int edit_list_index,
3169 int64_t *edit_list_media_time,
3170 int64_t *edit_list_duration,
3171 int64_t global_timescale)
3173 if (edit_list_index == msc->elst_count) {
3176 *edit_list_media_time = msc->elst_data[edit_list_index].time;
3177 *edit_list_duration = msc->elst_data[edit_list_index].duration;
3179 /* duration is in global timescale units;convert to msc timescale */
3180 if (global_timescale == 0) {
3181 avpriv_request_sample(mov->fc, "Support for mvhd.timescale = 0 with editlists");
3184 *edit_list_duration = av_rescale(*edit_list_duration, msc->time_scale,
3190 * Find the closest previous frame to the timestamp_pts, in e_old index
3191 * entries. Searching for just any frame / just key frames can be controlled by
3192 * last argument 'flag'.
3193 * Note that if ctts_data is not NULL, we will always search for a key frame
3194 * irrespective of the value of 'flag'. If we don't find any keyframe, we will
3195 * return the first frame of the video.
3197 * Here the timestamp_pts is considered to be a presentation timestamp and
3198 * the timestamp of index entries are considered to be decoding timestamps.
3200 * Returns 0 if successful in finding a frame, else returns -1.
3201 * Places the found index corresponding output arg.
3203 * If ctts_old is not NULL, then refines the searched entry by searching
3204 * backwards from the found timestamp, to find the frame with correct PTS.
3206 * Places the found ctts_index and ctts_sample in corresponding output args.
3208 static int find_prev_closest_index(AVStream *st,
3209 AVIndexEntry *e_old,
3213 int64_t timestamp_pts,
3216 int64_t* ctts_index,
3217 int64_t* ctts_sample)
3219 MOVStreamContext *msc = st->priv_data;
3220 AVIndexEntry *e_keep = st->internal->index_entries;
3221 int nb_keep = st->internal->nb_index_entries;
3223 int64_t index_ctts_count;
3227 // If dts_shift > 0, then all the index timestamps will have to be offset by
3228 // at least dts_shift amount to obtain PTS.
3229 // Hence we decrement the searched timestamp_pts by dts_shift to find the closest index element.
3230 if (msc->dts_shift > 0) {
3231 timestamp_pts -= msc->dts_shift;
3234 st->internal->index_entries = e_old;
3235 st->internal->nb_index_entries = nb_old;
3236 *index = av_index_search_timestamp(st, timestamp_pts, flag | AVSEEK_FLAG_BACKWARD);
3238 // Keep going backwards in the index entries until the timestamp is the same.
3240 for (i = *index; i > 0 && e_old[i].timestamp == e_old[i - 1].timestamp;
3242 if ((flag & AVSEEK_FLAG_ANY) ||
3243 (e_old[i - 1].flags & AVINDEX_KEYFRAME)) {
3249 // If we have CTTS then refine the search, by searching backwards over PTS
3250 // computed by adding corresponding CTTS durations to index timestamps.
3251 if (ctts_data && *index >= 0) {
3252 av_assert0(ctts_index);
3253 av_assert0(ctts_sample);
3254 // Find out the ctts_index for the found frame.
3257 for (index_ctts_count = 0; index_ctts_count < *index; index_ctts_count++) {
3258 if (*ctts_index < ctts_count) {
3260 if (ctts_data[*ctts_index].count == *ctts_sample) {
3267 while (*index >= 0 && (*ctts_index) >= 0 && (*ctts_index) < ctts_count) {
3268 // Find a "key frame" with PTS <= timestamp_pts (So that we can decode B-frames correctly).
3269 // No need to add dts_shift to the timestamp here becase timestamp_pts has already been
3270 // compensated by dts_shift above.
3271 if ((e_old[*index].timestamp + ctts_data[*ctts_index].duration) <= timestamp_pts &&
3272 (e_old[*index].flags & AVINDEX_KEYFRAME)) {
3277 if (*ctts_sample == 0) {
3279 if (*ctts_index >= 0)
3280 *ctts_sample = ctts_data[*ctts_index].count - 1;
3287 /* restore AVStream state*/
3288 st->internal->index_entries = e_keep;
3289 st->internal->nb_index_entries = nb_keep;
3290 return *index >= 0 ? 0 : -1;
3294 * Add index entry with the given values, to the end of st->internal->index_entries.
3295 * Returns the new size st->internal->index_entries if successful, else returns -1.
3297 * This function is similar to ff_add_index_entry in libavformat/utils.c
3298 * except that here we are always unconditionally adding an index entry to
3299 * the end, instead of searching the entries list and skipping the add if
3300 * there is an existing entry with the same timestamp.
3301 * This is needed because the mov_fix_index calls this func with the same
3302 * unincremented timestamp for successive discarded frames.
3304 static int64_t add_index_entry(AVStream *st, int64_t pos, int64_t timestamp,
3305 int size, int distance, int flags)
3307 AVIndexEntry *entries, *ie;
3309 const size_t min_size_needed = (st->internal->nb_index_entries + 1) * sizeof(AVIndexEntry);
3311 // Double the allocation each time, to lower memory fragmentation.
3312 // Another difference from ff_add_index_entry function.
3313 const size_t requested_size =
3314 min_size_needed > st->internal->index_entries_allocated_size ?
3315 FFMAX(min_size_needed, 2 * st->internal->index_entries_allocated_size) :
3318 if (st->internal->nb_index_entries + 1U >= UINT_MAX / sizeof(AVIndexEntry))
3321 entries = av_fast_realloc(st->internal->index_entries,
3322 &st->internal->index_entries_allocated_size,
3327 st->internal->index_entries= entries;
3329 index= st->internal->nb_index_entries++;
3330 ie= &entries[index];
3333 ie->timestamp = timestamp;
3334 ie->min_distance= distance;
3341 * Rewrite timestamps of index entries in the range [end_index - frame_duration_buffer_size, end_index)
3342 * by subtracting end_ts successively by the amounts given in frame_duration_buffer.
3344 static void fix_index_entry_timestamps(AVStream* st, int end_index, int64_t end_ts,
3345 int64_t* frame_duration_buffer,
3346 int frame_duration_buffer_size) {
3348 av_assert0(end_index >= 0 && end_index <= st->internal->nb_index_entries);
3349 for (i = 0; i < frame_duration_buffer_size; i++) {
3350 end_ts -= frame_duration_buffer[frame_duration_buffer_size - 1 - i];
3351 st->internal->index_entries[end_index - 1 - i].timestamp = end_ts;
3356 * Append a new ctts entry to ctts_data.
3357 * Returns the new ctts_count if successful, else returns -1.
3359 static int64_t add_ctts_entry(MOVStts** ctts_data, unsigned int* ctts_count, unsigned int* allocated_size,
3360 int count, int duration)
3362 MOVStts *ctts_buf_new;
3363 const size_t min_size_needed = (*ctts_count + 1) * sizeof(MOVStts);
3364 const size_t requested_size =
3365 min_size_needed > *allocated_size ?
3366 FFMAX(min_size_needed, 2 * (*allocated_size)) :
3369 if ((unsigned)(*ctts_count) >= UINT_MAX / sizeof(MOVStts) - 1)
3372 ctts_buf_new = av_fast_realloc(*ctts_data, allocated_size, requested_size);
3377 *ctts_data = ctts_buf_new;
3379 ctts_buf_new[*ctts_count].count = count;
3380 ctts_buf_new[*ctts_count].duration = duration;
3382 *ctts_count = (*ctts_count) + 1;
3386 #define MAX_REORDER_DELAY 16
3387 static void mov_estimate_video_delay(MOVContext *c, AVStream* st)
3389 MOVStreamContext *msc = st->priv_data;
3392 int ctts_sample = 0;
3393 int64_t pts_buf[MAX_REORDER_DELAY + 1]; // Circular buffer to sort pts.
3395 int j, r, num_swaps;
3397 for (j = 0; j < MAX_REORDER_DELAY + 1; j++)
3398 pts_buf[j] = INT64_MIN;
3400 if (st->codecpar->video_delay <= 0 && msc->ctts_data &&
3401 st->codecpar->codec_id == AV_CODEC_ID_H264) {
3402 st->codecpar->video_delay = 0;
3403 for (ind = 0; ind < st->internal->nb_index_entries && ctts_ind < msc->ctts_count; ++ind) {
3404 // Point j to the last elem of the buffer and insert the current pts there.
3406 buf_start = (buf_start + 1);
3407 if (buf_start == MAX_REORDER_DELAY + 1)
3410 pts_buf[j] = st->internal->index_entries[ind].timestamp + msc->ctts_data[ctts_ind].duration;
3412 // The timestamps that are already in the sorted buffer, and are greater than the
3413 // current pts, are exactly the timestamps that need to be buffered to output PTS
3414 // in correct sorted order.
3415 // Hence the video delay (which is the buffer size used to sort DTS and output PTS),
3416 // can be computed as the maximum no. of swaps any particular timestamp needs to
3417 // go through, to keep this buffer in sorted order.
3419 while (j != buf_start) {
3421 if (r < 0) r = MAX_REORDER_DELAY;
3422 if (pts_buf[j] < pts_buf[r]) {
3423 FFSWAP(int64_t, pts_buf[j], pts_buf[r]);
3430 st->codecpar->video_delay = FFMAX(st->codecpar->video_delay, num_swaps);
3433 if (ctts_sample == msc->ctts_data[ctts_ind].count) {
3438 av_log(c->fc, AV_LOG_DEBUG, "Setting codecpar->delay to %d for stream st: %d\n",
3439 st->codecpar->video_delay, st->index);
3443 static void mov_current_sample_inc(MOVStreamContext *sc)
3445 sc->current_sample++;
3446 sc->current_index++;
3447 if (sc->index_ranges &&
3448 sc->current_index >= sc->current_index_range->end &&
3449 sc->current_index_range->end) {
3450 sc->current_index_range++;
3451 sc->current_index = sc->current_index_range->start;
3455 static void mov_current_sample_dec(MOVStreamContext *sc)
3457 sc->current_sample--;
3458 sc->current_index--;
3459 if (sc->index_ranges &&
3460 sc->current_index < sc->current_index_range->start &&
3461 sc->current_index_range > sc->index_ranges) {
3462 sc->current_index_range--;
3463 sc->current_index = sc->current_index_range->end - 1;
3467 static void mov_current_sample_set(MOVStreamContext *sc, int current_sample)
3471 sc->current_sample = current_sample;
3472 sc->current_index = current_sample;
3473 if (!sc->index_ranges) {
3477 for (sc->current_index_range = sc->index_ranges;
3478 sc->current_index_range->end;
3479 sc->current_index_range++) {
3480 range_size = sc->current_index_range->end - sc->current_index_range->start;
3481 if (range_size > current_sample) {
3482 sc->current_index = sc->current_index_range->start + current_sample;
3485 current_sample -= range_size;
3490 * Fix st->internal->index_entries, so that it contains only the entries (and the entries
3491 * which are needed to decode them) that fall in the edit list time ranges.
3492 * Also fixes the timestamps of the index entries to match the timeline
3493 * specified the edit lists.
3495 static void mov_fix_index(MOVContext *mov, AVStream *st)
3497 MOVStreamContext *msc = st->priv_data;
3498 AVIndexEntry *e_old = st->internal->index_entries;
3499 int nb_old = st->internal->nb_index_entries;
3500 const AVIndexEntry *e_old_end = e_old + nb_old;
3501 const AVIndexEntry *current = NULL;
3502 MOVStts *ctts_data_old = msc->ctts_data;
3503 int64_t ctts_index_old = 0;
3504 int64_t ctts_sample_old = 0;
3505 int64_t ctts_count_old = msc->ctts_count;
3506 int64_t edit_list_media_time = 0;
3507 int64_t edit_list_duration = 0;
3508 int64_t frame_duration = 0;
3509 int64_t edit_list_dts_counter = 0;
3510 int64_t edit_list_dts_entry_end = 0;
3511 int64_t edit_list_start_ctts_sample = 0;
3513 int64_t curr_ctts = 0;
3514 int64_t empty_edits_sum_duration = 0;
3515 int64_t edit_list_index = 0;
3518 int64_t start_dts = 0;
3519 int64_t edit_list_start_encountered = 0;
3520 int64_t search_timestamp = 0;
3521 int64_t* frame_duration_buffer = NULL;
3522 int num_discarded_begin = 0;
3523 int first_non_zero_audio_edit = -1;
3524 int packet_skip_samples = 0;
3525 MOVIndexRange *current_index_range;
3527 int found_keyframe_after_edit = 0;
3528 int found_non_empty_edit = 0;
3530 if (!msc->elst_data || msc->elst_count <= 0 || nb_old <= 0) {
3534 // allocate the index ranges array
3535 msc->index_ranges = av_malloc((msc->elst_count + 1) * sizeof(msc->index_ranges[0]));
3536 if (!msc->index_ranges) {
3537 av_log(mov->fc, AV_LOG_ERROR, "Cannot allocate index ranges buffer\n");
3540 msc->current_index_range = msc->index_ranges;
3541 current_index_range = msc->index_ranges - 1;
3543 // Clean AVStream from traces of old index
3544 st->internal->index_entries = NULL;
3545 st->internal->index_entries_allocated_size = 0;
3546 st->internal->nb_index_entries = 0;
3548 // Clean ctts fields of MOVStreamContext
3549 msc->ctts_data = NULL;
3550 msc->ctts_count = 0;
3551 msc->ctts_index = 0;
3552 msc->ctts_sample = 0;
3553 msc->ctts_allocated_size = 0;
3555 // Reinitialize min_corrected_pts so that it can be computed again.
3556 msc->min_corrected_pts = -1;
3558 // If the dts_shift is positive (in case of negative ctts values in mov),
3559 // then negate the DTS by dts_shift
3560 if (msc->dts_shift > 0) {
3561 edit_list_dts_entry_end -= msc->dts_shift;
3562 av_log(mov->fc, AV_LOG_DEBUG, "Shifting DTS by %d because of negative CTTS.\n", msc->dts_shift);
3565 start_dts = edit_list_dts_entry_end;
3567 while (get_edit_list_entry(mov, msc, edit_list_index, &edit_list_media_time,
3568 &edit_list_duration, mov->time_scale)) {
3569 av_log(mov->fc, AV_LOG_DEBUG, "Processing st: %d, edit list %"PRId64" - media time: %"PRId64", duration: %"PRId64"\n",
3570 st->index, edit_list_index, edit_list_media_time, edit_list_duration);
3572 edit_list_dts_counter = edit_list_dts_entry_end;
3573 edit_list_dts_entry_end += edit_list_duration;
3574 num_discarded_begin = 0;
3575 if (!found_non_empty_edit && edit_list_media_time == -1) {
3576 empty_edits_sum_duration += edit_list_duration;
3579 found_non_empty_edit = 1;
3581 // If we encounter a non-negative edit list reset the skip_samples/start_pad fields and set them
3582 // according to the edit list below.
3583 if (st->codecpar->codec_type == AVMEDIA_TYPE_AUDIO) {
3584 if (first_non_zero_audio_edit < 0) {
3585 first_non_zero_audio_edit = 1;
3587 first_non_zero_audio_edit = 0;
3590 if (first_non_zero_audio_edit > 0)
3591 st->internal->skip_samples = msc->start_pad = 0;
3594 // While reordering frame index according to edit list we must handle properly
3595 // the scenario when edit list entry starts from none key frame.
3596 // We find closest previous key frame and preserve it and consequent frames in index.
3597 // All frames which are outside edit list entry time boundaries will be dropped after decoding.
3598 search_timestamp = edit_list_media_time;
3599 if (st->codecpar->codec_type == AVMEDIA_TYPE_AUDIO) {
3600 // Audio decoders like AAC need need a decoder delay samples previous to the current sample,
3601 // to correctly decode this frame. Hence for audio we seek to a frame 1 sec. before the
3602 // edit_list_media_time to cover the decoder delay.
3603 search_timestamp = FFMAX(search_timestamp - msc->time_scale, e_old[0].timestamp);
3606 if (find_prev_closest_index(st, e_old, nb_old, ctts_data_old, ctts_count_old, search_timestamp, 0,
3607 &index, &ctts_index_old, &ctts_sample_old) < 0) {
3608 av_log(mov->fc, AV_LOG_WARNING,
3609 "st: %d edit list: %"PRId64" Missing key frame while searching for timestamp: %"PRId64"\n",
3610 st->index, edit_list_index, search_timestamp);
3611 if (find_prev_closest_index(st, e_old, nb_old, ctts_data_old, ctts_count_old, search_timestamp, AVSEEK_FLAG_ANY,
3612 &index, &ctts_index_old, &ctts_sample_old) < 0) {
3613 av_log(mov->fc, AV_LOG_WARNING,
3614 "st: %d edit list %"PRId64" Cannot find an index entry before timestamp: %"PRId64".\n",
3615 st->index, edit_list_index, search_timestamp);
3618 ctts_sample_old = 0;
3621 current = e_old + index;
3622 edit_list_start_ctts_sample = ctts_sample_old;
3624 // Iterate over index and arrange it according to edit list
3625 edit_list_start_encountered = 0;
3626 found_keyframe_after_edit = 0;
3627 for (; current < e_old_end; current++, index++) {
3628 // check if frame outside edit list mark it for discard
3629 frame_duration = (current + 1 < e_old_end) ?
3630 ((current + 1)->timestamp - current->timestamp) : edit_list_duration;
3632 flags = current->flags;
3634 // frames (pts) before or after edit list
3635 curr_cts = current->timestamp + msc->dts_shift;
3638 if (ctts_data_old && ctts_index_old < ctts_count_old) {
3639 curr_ctts = ctts_data_old[ctts_index_old].duration;
3640 av_log(mov->fc, AV_LOG_DEBUG, "stts: %"PRId64" ctts: %"PRId64", ctts_index: %"PRId64", ctts_count: %"PRId64"\n",
3641 curr_cts, curr_ctts, ctts_index_old, ctts_count_old);
3642 curr_cts += curr_ctts;
3644 if (ctts_sample_old == ctts_data_old[ctts_index_old].count) {
3645 if (add_ctts_entry(&msc->ctts_data, &msc->ctts_count,
3646 &msc->ctts_allocated_size,
3647 ctts_data_old[ctts_index_old].count - edit_list_start_ctts_sample,
3648 ctts_data_old[ctts_index_old].duration) == -1) {
3649 av_log(mov->fc, AV_LOG_ERROR, "Cannot add CTTS entry %"PRId64" - {%"PRId64", %d}\n",
3651 ctts_data_old[ctts_index_old].count - edit_list_start_ctts_sample,
3652 ctts_data_old[ctts_index_old].duration);
3656 ctts_sample_old = 0;
3657 edit_list_start_ctts_sample = 0;
3661 if (curr_cts < edit_list_media_time || curr_cts >= (edit_list_duration + edit_list_media_time)) {
3662 if (st->codecpar->codec_type == AVMEDIA_TYPE_AUDIO && st->codecpar->codec_id != AV_CODEC_ID_VORBIS &&
3663 curr_cts < edit_list_media_time && curr_cts + frame_duration > edit_list_media_time &&
3664 first_non_zero_audio_edit > 0) {
3665 packet_skip_samples = edit_list_media_time - curr_cts;
3666 st->internal->skip_samples += packet_skip_samples;
3668 // Shift the index entry timestamp by packet_skip_samples to be correct.
3669 edit_list_dts_counter -= packet_skip_samples;
3670 if (edit_list_start_encountered == 0) {
3671 edit_list_start_encountered = 1;
3672 // Make timestamps strictly monotonically increasing for audio, by rewriting timestamps for
3673 // discarded packets.
3674 if (frame_duration_buffer) {
3675 fix_index_entry_timestamps(st, st->internal->nb_index_entries, edit_list_dts_counter,
3676 frame_duration_buffer, num_discarded_begin);
3677 av_freep(&frame_duration_buffer);
3681 av_log(mov->fc, AV_LOG_DEBUG, "skip %d audio samples from curr_cts: %"PRId64"\n", packet_skip_samples, curr_cts);
3683 flags |= AVINDEX_DISCARD_FRAME;
3684 av_log(mov->fc, AV_LOG_DEBUG, "drop a frame at curr_cts: %"PRId64" @ %"PRId64"\n", curr_cts, index);
3686 if (edit_list_start_encountered == 0) {
3687 num_discarded_begin++;
3688 frame_duration_buffer = av_realloc(frame_duration_buffer,
3689 num_discarded_begin * sizeof(int64_t));
3690 if (!frame_duration_buffer) {
3691 av_log(mov->fc, AV_LOG_ERROR, "Cannot reallocate frame duration buffer\n");
3694 frame_duration_buffer[num_discarded_begin - 1] = frame_duration;
3696 // Increment skip_samples for the first non-zero audio edit list
3697 if (st->codecpar->codec_type == AVMEDIA_TYPE_AUDIO &&
3698 first_non_zero_audio_edit > 0 && st->codecpar->codec_id != AV_CODEC_ID_VORBIS) {
3699 st->internal->skip_samples += frame_duration;
3704 if (msc->min_corrected_pts < 0) {
3705 msc->min_corrected_pts = edit_list_dts_counter + curr_ctts + msc->dts_shift;
3707 msc->min_corrected_pts = FFMIN(msc->min_corrected_pts, edit_list_dts_counter + curr_ctts + msc->dts_shift);
3709 if (edit_list_start_encountered == 0) {
3710 edit_list_start_encountered = 1;
3711 // Make timestamps strictly monotonically increasing by rewriting timestamps for
3712 // discarded packets.
3713 if (frame_duration_buffer) {
3714 fix_index_entry_timestamps(st, st->internal->nb_index_entries, edit_list_dts_counter,
3715 frame_duration_buffer, num_discarded_begin);
3716 av_freep(&frame_duration_buffer);
3721 if (add_index_entry(st, current->pos, edit_list_dts_counter, current->size,
3722 current->min_distance, flags) == -1) {
3723 av_log(mov->fc, AV_LOG_ERROR, "Cannot add index entry\n");
3727 // Update the index ranges array
3728 if (current_index_range < msc->index_ranges || index != current_index_range->end) {
3729 current_index_range++;
3730 current_index_range->start = index;
3732 current_index_range->end = index + 1;
3734 // Only start incrementing DTS in frame_duration amounts, when we encounter a frame in edit list.
3735 if (edit_list_start_encountered > 0) {
3736 edit_list_dts_counter = edit_list_dts_counter + frame_duration;
3739 // Break when found first key frame after edit entry completion
3740 if ((curr_cts + frame_duration >= (edit_list_duration + edit_list_media_time)) &&
3741 ((flags & AVINDEX_KEYFRAME) || ((st->codecpar->codec_type == AVMEDIA_TYPE_AUDIO)))) {
3742 if (ctts_data_old) {
3743 // If we have CTTS and this is the first keyframe after edit elist,
3744 // wait for one more, because there might be trailing B-frames after this I-frame
3745 // that do belong to the edit.
3746 if (st->codecpar->codec_type != AVMEDIA_TYPE_AUDIO && found_keyframe_after_edit == 0) {
3747 found_keyframe_after_edit = 1;
3750 if (ctts_sample_old != 0) {
3751 if (add_ctts_entry(&msc->ctts_data, &msc->ctts_count,
3752 &msc->ctts_allocated_size,
3753 ctts_sample_old - edit_list_start_ctts_sample,
3754 ctts_data_old[ctts_index_old].duration) == -1) {
3755 av_log(mov->fc, AV_LOG_ERROR, "Cannot add CTTS entry %"PRId64" - {%"PRId64", %d}\n",
3756 ctts_index_old, ctts_sample_old - edit_list_start_ctts_sample,
3757 ctts_data_old[ctts_index_old].duration);
3766 // If there are empty edits, then msc->min_corrected_pts might be positive
3767 // intentionally. So we subtract the sum duration of emtpy edits here.
3768 msc->min_corrected_pts -= empty_edits_sum_duration;
3770 // If the minimum pts turns out to be greater than zero after fixing the index, then we subtract the
3771 // dts by that amount to make the first pts zero.
3772 if (st->codecpar->codec_type == AVMEDIA_TYPE_VIDEO) {
3773 if (msc->min_corrected_pts > 0) {
3774 av_log(mov->fc, AV_LOG_DEBUG, "Offset DTS by %"PRId64" to make first pts zero.\n", msc->min_corrected_pts);
3775 for (i = 0; i < st->internal->nb_index_entries; ++i) {
3776 st->internal->index_entries[i].timestamp -= msc->min_corrected_pts;
3780 // Start time should be equal to zero or the duration of any empty edits.
3781 st->start_time = empty_edits_sum_duration;
3783 // Update av stream length, if it ends up shorter than the track's media duration
3784 st->duration = FFMIN(st->duration, edit_list_dts_entry_end - start_dts);
3785 msc->start_pad = st->internal->skip_samples;
3787 // Free the old index and the old CTTS structures
3789 av_free(ctts_data_old);
3790 av_freep(&frame_duration_buffer);
3792 // Null terminate the index ranges array
3793 current_index_range++;
3794 current_index_range->start = 0;
3795 current_index_range->end = 0;
3796 msc->current_index = msc->index_ranges[0].start;
3799 static void mov_build_index(MOVContext *mov, AVStream *st)
3801 MOVStreamContext *sc = st->priv_data;
3802 int64_t current_offset;
3803 int64_t current_dts = 0;
3804 unsigned int stts_index = 0;
3805 unsigned int stsc_index = 0;
3806 unsigned int stss_index = 0;
3807 unsigned int stps_index = 0;
3809 uint64_t stream_size = 0;
3810 MOVStts *ctts_data_old = sc->ctts_data;
3811 unsigned int ctts_count_old = sc->ctts_count;
3813 if (sc->elst_count) {
3814 int i, edit_start_index = 0, multiple_edits = 0;
3815 int64_t empty_duration = 0; // empty duration of the first edit list entry
3816 int64_t start_time = 0; // start time of the media
3818 for (i = 0; i < sc->elst_count; i++) {
3819 const MOVElst *e = &sc->elst_data[i];
3820 if (i == 0 && e->time == -1) {
3821 /* if empty, the first entry is the start time of the stream
3822 * relative to the presentation itself */
3823 empty_duration = e->duration;
3824 edit_start_index = 1;
3825 } else if (i == edit_start_index && e->time >= 0) {
3826 start_time = e->time;
3832 if (multiple_edits && !mov->advanced_editlist)
3833 av_log(mov->fc, AV_LOG_WARNING, "multiple edit list entries, "
3834 "Use -advanced_editlist to correctly decode otherwise "
3835 "a/v desync might occur\n");
3837 /* adjust first dts according to edit list */
3838 if ((empty_duration || start_time) && mov->time_scale > 0) {
3840 empty_duration = av_rescale(empty_duration, sc->time_scale, mov->time_scale);
3841 sc->time_offset = start_time - empty_duration;
3842 sc->min_corrected_pts = start_time;
3843 if (!mov->advanced_editlist)
3844 current_dts = -sc->time_offset;
3847 if (!multiple_edits && !mov->advanced_editlist &&
3848 st->codecpar->codec_id == AV_CODEC_ID_AAC && start_time > 0)
3849 sc->start_pad = start_time;
3852 /* only use old uncompressed audio chunk demuxing when stts specifies it */
3853 if (!(st->codecpar->codec_type == AVMEDIA_TYPE_AUDIO &&
3854 sc->stts_count == 1 && sc->stts_data[0].duration == 1)) {
3855 unsigned int current_sample = 0;
3856 unsigned int stts_sample = 0;
3857 unsigned int sample_size;
3858 unsigned int distance = 0;
3859 unsigned int rap_group_index = 0;
3860 unsigned int rap_group_sample = 0;
3861 int64_t last_dts = 0;
3862 int64_t dts_correction = 0;
3863 int rap_group_present = sc->rap_group_count && sc->rap_group;
3864 int key_off = (sc->keyframe_count && sc->keyframes[0] > 0) || (sc->stps_count && sc->stps_data[0] > 0);
3866 current_dts -= sc->dts_shift;
3867 last_dts = current_dts;
3869 if (!sc->sample_count || st->internal->nb_index_entries)
3871 if (sc->sample_count >= UINT_MAX / sizeof(*st->internal->index_entries) - st->internal->nb_index_entries)
3873 if (av_reallocp_array(&st->internal->index_entries,
3874 st->internal->nb_index_entries + sc->sample_count,
3875 sizeof(*st->internal->index_entries)) < 0) {
3876 st->internal->nb_index_entries = 0;
3879 st->internal->index_entries_allocated_size = (st->internal->nb_index_entries + sc->sample_count) * sizeof(*st->internal->index_entries);
3881 if (ctts_data_old) {
3882 // Expand ctts entries such that we have a 1-1 mapping with samples
3883 if (sc->sample_count >= UINT_MAX / sizeof(*sc->ctts_data))
3886 sc->ctts_allocated_size = 0;
3887 sc->ctts_data = av_fast_realloc(NULL, &sc->ctts_allocated_size,
3888 sc->sample_count * sizeof(*sc->ctts_data));
3889 if (!sc->ctts_data) {
3890 av_free(ctts_data_old);
3894 memset((uint8_t*)(sc->ctts_data), 0, sc->ctts_allocated_size);
3896 for (i = 0; i < ctts_count_old &&
3897 sc->ctts_count < sc->sample_count; i++)
3898 for (j = 0; j < ctts_data_old[i].count &&
3899 sc->ctts_count < sc->sample_count; j++)
3900 add_ctts_entry(&sc->ctts_data, &sc->ctts_count,
3901 &sc->ctts_allocated_size, 1,
3902 ctts_data_old[i].duration);
3903 av_free(ctts_data_old);
3906 for (i = 0; i < sc->chunk_count; i++) {
3907 int64_t next_offset = i+1 < sc->chunk_count ? sc->chunk_offsets[i+1] : INT64_MAX;
3908 current_offset = sc->chunk_offsets[i];
3909 while (mov_stsc_index_valid(stsc_index, sc->stsc_count) &&
3910 i + 1 == sc->stsc_data[stsc_index + 1].first)
3913 if (next_offset > current_offset && sc->sample_size>0 && sc->sample_size < sc->stsz_sample_size &&
3914 sc->stsc_data[stsc_index].count * (int64_t)sc->stsz_sample_size > next_offset - current_offset) {
3915 av_log(mov->fc, AV_LOG_WARNING, "STSZ sample size %d invalid (too large), ignoring\n", sc->stsz_sample_size);
3916 sc->stsz_sample_size = sc->sample_size;
3918 if (sc->stsz_sample_size>0 && sc->stsz_sample_size < sc->sample_size) {
3919 av_log(mov->fc, AV_LOG_WARNING, "STSZ sample size %d invalid (too small), ignoring\n", sc->stsz_sample_size);
3920 sc->stsz_sample_size = sc->sample_size;
3923 for (j = 0; j < sc->stsc_data[stsc_index].count; j++) {
3925 if (current_sample >= sc->sample_count) {
3926 av_log(mov->fc, AV_LOG_ERROR, "wrong sample count\n");
3930 if (!sc->keyframe_absent && (!sc->keyframe_count || current_sample+key_off == sc->keyframes[stss_index])) {
3932 if (stss_index + 1 < sc->keyframe_count)
3934 } else if (sc->stps_count && current_sample+key_off == sc->stps_data[stps_index]) {
3936 if (stps_index + 1 < sc->stps_count)
3939 if (rap_group_present && rap_group_index < sc->rap_group_count) {
3940 if (sc->rap_group[rap_group_index].index > 0)
3942 if (++rap_group_sample == sc->rap_group[rap_group_index].count) {
3943 rap_group_sample = 0;
3947 if (sc->keyframe_absent
3949 && !rap_group_present
3950 && (st->codecpar->codec_type == AVMEDIA_TYPE_AUDIO || (i==0 && j==0)))
3954 sample_size = sc->stsz_sample_size > 0 ? sc->stsz_sample_size : sc->sample_sizes[current_sample];
3955 if (sc->pseudo_stream_id == -1 ||
3956 sc->stsc_data[stsc_index].id - 1 == sc->pseudo_stream_id) {
3958 if (sample_size > 0x3FFFFFFF) {
3959 av_log(mov->fc, AV_LOG_ERROR, "Sample size %u is too large\n", sample_size);
3962 e = &st->internal->index_entries[st->internal->nb_index_entries++];
3963 e->pos = current_offset;
3964 e->timestamp = current_dts;
3965 e->size = sample_size;
3966 e->min_distance = distance;
3967 e->flags = keyframe ? AVINDEX_KEYFRAME : 0;
3968 av_log(mov->fc, AV_LOG_TRACE, "AVIndex stream %d, sample %u, offset %"PRIx64", dts %"PRId64", "
3969 "size %u, distance %u, keyframe %d\n", st->index, current_sample,
3970 current_offset, current_dts, sample_size, distance, keyframe);
3971 if (st->codecpar->codec_type == AVMEDIA_TYPE_VIDEO && st->internal->nb_index_entries < 100)
3972 ff_rfps_add_frame(mov->fc, st, current_dts);
3975 current_offset += sample_size;
3976 stream_size += sample_size;
3978 /* A negative sample duration is invalid based on the spec,
3979 * but some samples need it to correct the DTS. */
3980 if (sc->stts_data[stts_index].duration < 0) {
3981 av_log(mov->fc, AV_LOG_WARNING,
3982 "Invalid SampleDelta %d in STTS, at %d st:%d\n",
3983 sc->stts_data[stts_index].duration, stts_index,
3985 dts_correction += sc->stts_data[stts_index].duration - 1;
3986 sc->stts_data[stts_index].duration = 1;
3988 current_dts += sc->stts_data[stts_index].duration;
3989 if (!dts_correction || current_dts + dts_correction > last_dts) {
3990 current_dts += dts_correction;
3993 /* Avoid creating non-monotonous DTS */
3994 dts_correction += current_dts - last_dts - 1;
3995 current_dts = last_dts + 1;
3997 last_dts = current_dts;
4001 if (stts_index + 1 < sc->stts_count && stts_sample == sc->stts_data[stts_index].count) {
4007 if (st->duration > 0)
4008 st->codecpar->bit_rate = stream_size*8*sc->time_scale/st->duration;
4010 unsigned chunk_samples, total = 0;
4012 if (!sc->chunk_count)
4015 // compute total chunk count
4016 for (i = 0; i < sc->stsc_count; i++) {
4017 unsigned count, chunk_count;
4019 chunk_samples = sc->stsc_data[i].count;
4020 if (i != sc->stsc_count - 1 &&
4021 sc->samples_per_frame && chunk_samples % sc->samples_per_frame) {
4022 av_log(mov->fc, AV_LOG_ERROR, "error unaligned chunk\n");
4026 if (sc->samples_per_frame >= 160) { // gsm
4027 count = chunk_samples / sc->samples_per_frame;
4028 } else if (sc->samples_per_frame > 1) {
4029 unsigned samples = (1024/sc->samples_per_frame)*sc->samples_per_frame;
4030 count = (chunk_samples+samples-1) / samples;
4032 count = (chunk_samples+1023) / 1024;
4035 if (mov_stsc_index_valid(i, sc->stsc_count))
4036 chunk_count = sc->stsc_data[i+1].first - sc->stsc_data[i].first;
4038 chunk_count = sc->chunk_count - (sc->stsc_data[i].first - 1);
4039 total += chunk_count * count;
4042 av_log(mov->fc, AV_LOG_TRACE, "chunk count %u\n", total);
4043 if (total >= UINT_MAX / sizeof(*st->internal->index_entries) - st->internal->nb_index_entries)
4045 if (av_reallocp_array(&st->internal->index_entries,
4046 st->internal->nb_index_entries + total,
4047 sizeof(*st->internal->index_entries)) < 0) {
4048 st->internal->nb_index_entries = 0;
4051 st->internal->index_entries_allocated_size = (st->internal->nb_index_entries + total) * sizeof(*st->internal->index_entries);
4054 for (i = 0; i < sc->chunk_count; i++) {
4055 current_offset = sc->chunk_offsets[i];
4056 if (mov_stsc_index_valid(stsc_index, sc->stsc_count) &&
4057 i + 1 == sc->stsc_data[stsc_index + 1].first)
4059 chunk_samples = sc->stsc_data[stsc_index].count;
4061 while (chunk_samples > 0) {
4063 unsigned size, samples;
4065 if (sc->samples_per_frame > 1 && !sc->bytes_per_frame) {
4066 avpriv_request_sample(mov->fc,
4067 "Zero bytes per frame, but %d samples per frame",
4068 sc->samples_per_frame);
4072 if (sc->samples_per_frame >= 160) { // gsm
4073 samples = sc->samples_per_frame;
4074 size = sc->bytes_per_frame;
4076 if (sc->samples_per_frame > 1) {
4077 samples = FFMIN((1024 / sc->samples_per_frame)*
4078 sc->samples_per_frame, chunk_samples);
4079 size = (samples / sc->samples_per_frame) * sc->bytes_per_frame;
4081 samples = FFMIN(1024, chunk_samples);
4082 size = samples * sc->sample_size;
4086 if (st->internal->nb_index_entries >= total) {
4087 av_log(mov->fc, AV_LOG_ERROR, "wrong chunk count %u\n", total);
4090 if (size > 0x3FFFFFFF) {
4091 av_log(mov->fc, AV_LOG_ERROR, "Sample size %u is too large\n", size);
4094 e = &st->internal->index_entries[st->internal->nb_index_entries++];
4095 e->pos = current_offset;
4096 e->timestamp = current_dts;
4098 e->min_distance = 0;
4099 e->flags = AVINDEX_KEYFRAME;
4100 av_log(mov->fc, AV_LOG_TRACE, "AVIndex stream %d, chunk %u, offset %"PRIx64", dts %"PRId64", "
4101 "size %u, duration %u\n", st->index, i, current_offset, current_dts,
4104 current_offset += size;
4105 current_dts += samples;
4106 chunk_samples -= samples;
4111 if (!mov->ignore_editlist && mov->advanced_editlist) {
4112 // Fix index according to edit lists.
4113 mov_fix_index(mov, st);
4116 // Update start time of the stream.
4117 if (st->start_time == AV_NOPTS_VALUE && st->codecpar->codec_type == AVMEDIA_TYPE_VIDEO && st->internal->nb_index_entries > 0) {
4118 st->start_time = st->internal->index_entries[0].timestamp + sc->dts_shift;
4119 if (sc->ctts_data) {
4120 st->start_time += sc->ctts_data[0].duration;
4124 mov_estimate_video_delay(mov, st);
4127 static int test_same_origin(const char *src, const char *ref) {
4137 av_url_split(src_proto, sizeof(src_proto), src_auth, sizeof(src_auth), src_host, sizeof(src_host), &src_port, NULL, 0, src);
4138 av_url_split(ref_proto, sizeof(ref_proto), ref_auth, sizeof(ref_auth), ref_host, sizeof(ref_host), &ref_port, NULL, 0, ref);
4140 if (strlen(src) == 0) {
4142 } else if (strlen(src_auth) + 1 >= sizeof(src_auth) ||
4143 strlen(ref_auth) + 1 >= sizeof(ref_auth) ||
4144 strlen(src_host) + 1 >= sizeof(src_host) ||
4145 strlen(ref_host) + 1 >= sizeof(ref_host)) {
4147 } else if (strcmp(src_proto, ref_proto) ||
4148 strcmp(src_auth, ref_auth) ||
4149 strcmp(src_host, ref_host) ||
4150 src_port != ref_port) {
4156 static int mov_open_dref(MOVContext *c, AVIOContext **pb, const char *src, MOVDref *ref)
4158 /* try relative path, we do not try the absolute because it can leak information about our
4159 system to an attacker */
4160 if (ref->nlvl_to > 0 && ref->nlvl_from > 0) {
4161 char filename[1025];
4162 const char *src_path;
4165 /* find a source dir */
4166 src_path = strrchr(src, '/');
4172 /* find a next level down to target */
4173 for (i = 0, l = strlen(ref->path) - 1; l >= 0; l--)
4174 if (ref->path[l] == '/') {
4175 if (i == ref->nlvl_to - 1)
4181 /* compose filename if next level down to target was found */
4182 if (i == ref->nlvl_to - 1 && src_path - src < sizeof(filename)) {
4183 memcpy(filename, src, src_path - src);
4184 filename[src_path - src] = 0;
4186 for (i = 1; i < ref->nlvl_from; i++)
4187 av_strlcat(filename, "../", sizeof(filename));
4189 av_strlcat(filename, ref->path + l + 1, sizeof(filename));
4190 if (!c->use_absolute_path) {
4191 int same_origin = test_same_origin(src, filename);
4194 av_log(c->fc, AV_LOG_ERROR,
4195 "Reference with mismatching origin, %s not tried for security reasons, "
4196 "set demuxer option use_absolute_path to allow it anyway\n",
4198 return AVERROR(ENOENT);
4201 if (strstr(ref->path + l + 1, "..") ||
4202 strstr(ref->path + l + 1, ":") ||
4203 (ref->nlvl_from > 1 && same_origin < 0) ||
4204 (filename[0] == '/' && src_path == src))
4205 return AVERROR(ENOENT);
4208 if (strlen(filename) + 1 == sizeof(filename))
4209 return AVERROR(ENOENT);
4210 if (!c->fc->io_open(c->fc, pb, filename, AVIO_FLAG_READ, NULL))
4213 } else if (c->use_absolute_path) {
4214 av_log(c->fc, AV_LOG_WARNING, "Using absolute path on user request, "
4215 "this is a possible security issue\n");
4216 if (!c->fc->io_open(c->fc, pb, ref->path, AVIO_FLAG_READ, NULL))
4219 av_log(c->fc, AV_LOG_ERROR,
4220 "Absolute path %s not tried for security reasons, "
4221 "set demuxer option use_absolute_path to allow absolute paths\n",
4225 return AVERROR(ENOENT);
4228 static void fix_timescale(MOVContext *c, MOVStreamContext *sc)
4230 if (sc->time_scale <= 0) {
4231 av_log(c->fc, AV_LOG_WARNING, "stream %d, timescale not set\n", sc->ffindex);
4232 sc->time_scale = c->time_scale;
4233 if (sc->time_scale <= 0)
4238 static int mov_read_trak(MOVContext *c, AVIOContext *pb, MOVAtom atom)
4241 MOVStreamContext *sc;
4244 st = avformat_new_stream(c->fc, NULL);
4245 if (!st) return AVERROR(ENOMEM);
4247 sc = av_mallocz(sizeof(MOVStreamContext));
4248 if (!sc) return AVERROR(ENOMEM);
4251 st->codecpar->codec_type = AVMEDIA_TYPE_DATA;
4252 sc->ffindex = st->index;
4253 c->trak_index = st->index;
4255 if ((ret = mov_read_default(c, pb, atom)) < 0)
4260 // Here stsc refers to a chunk not described in stco. This is technically invalid,
4261 // but we can overlook it (clearing stsc) whenever stts_count == 0 (indicating no samples).
4262 if (!sc->chunk_count && !sc->stts_count && sc->stsc_count) {
4264 av_freep(&sc->stsc_data);
4268 if ((sc->chunk_count && (!sc->stts_count || !sc->stsc_count ||
4269 (!sc->sample_size && !sc->sample_count))) ||
4270 (!sc->chunk_count && sc->sample_count)) {
4271 av_log(c->fc, AV_LOG_ERROR, "stream %d, missing mandatory atoms, broken header\n",
4275 if (sc->stsc_count && sc->stsc_data[ sc->stsc_count - 1 ].first > sc->chunk_count) {
4276 av_log(c->fc, AV_LOG_ERROR, "stream %d, contradictionary STSC and STCO\n",
4278 return AVERROR_INVALIDDATA;
4281 fix_timescale(c, sc);
4283 avpriv_set_pts_info(st, 64, 1, sc->time_scale);
4285 mov_build_index(c, st);
4287 if (sc->dref_id-1 < sc->drefs_count && sc->drefs[sc->dref_id-1].path) {
4288 MOVDref *dref = &sc->drefs[sc->dref_id - 1];
4289 if (c->enable_drefs) {
4290 if (mov_open_dref(c, &sc->pb, c->fc->url, dref) < 0)
4291 av_log(c->fc, AV_LOG_ERROR,
4292 "stream %d, error opening alias: path='%s', dir='%s', "
4293 "filename='%s', volume='%s', nlvl_from=%d, nlvl_to=%d\n",
4294 st->index, dref->path, dref->dir, dref->filename,
4295 dref->volume, dref->nlvl_from, dref->nlvl_to);
4297 av_log(c->fc, AV_LOG_WARNING,
4298 "Skipped opening external track: "
4299 "stream %d, alias: path='%s', dir='%s', "
4300 "filename='%s', volume='%s', nlvl_from=%d, nlvl_to=%d."
4301 "Set enable_drefs to allow this.\n",
4302 st->index, dref->path, dref->dir, dref->filename,
4303 dref->volume, dref->nlvl_from, dref->nlvl_to);
4307 sc->pb_is_copied = 1;
4310 if (st->codecpar->codec_type == AVMEDIA_TYPE_VIDEO) {
4311 if (!st->sample_aspect_ratio.num && st->codecpar->width && st->codecpar->height &&
4312 sc->height && sc->width &&
4313 (st->codecpar->width != sc->width || st->codecpar->height != sc->height)) {
4314 st->sample_aspect_ratio = av_d2q(((double)st->codecpar->height * sc->width) /
4315 ((double)st->codecpar->width * sc->height), INT_MAX);
4318 #if FF_API_R_FRAME_RATE
4319 if (sc->stts_count == 1 || (sc->stts_count == 2 && sc->stts_data[1].count == 1))
4320 av_reduce(&st->r_frame_rate.num, &st->r_frame_rate.den,
4321 sc->time_scale, sc->stts_data[0].duration, INT_MAX);
4325 // done for ai5q, ai52, ai55, ai1q, ai12 and ai15.
4326 if (!st->codecpar->extradata_size && st->codecpar->codec_id == AV_CODEC_ID_H264 &&
4327 TAG_IS_AVCI(st->codecpar->codec_tag)) {
4328 ret = ff_generate_avci_extradata(st);
4333 switch (st->codecpar->codec_id) {
4334 #if CONFIG_H261_DECODER
4335 case AV_CODEC_ID_H261:
4337 #if CONFIG_H263_DECODER
4338 case AV_CODEC_ID_H263:
4340 #if CONFIG_MPEG4_DECODER
4341 case AV_CODEC_ID_MPEG4:
4343 st->codecpar->width = 0; /* let decoder init width/height */
4344 st->codecpar->height= 0;
4348 // If the duration of the mp3 packets is not constant, then they could need a parser
4349 if (st->codecpar->codec_id == AV_CODEC_ID_MP3
4350 && sc->stts_count > 3
4351 && sc->stts_count*10 > st->nb_frames
4352 && sc->time_scale == st->codecpar->sample_rate) {
4353 st->need_parsing = AVSTREAM_PARSE_FULL;
4355 /* Do not need those anymore. */
4356 av_freep(&sc->chunk_offsets);
4357 av_freep(&sc->sample_sizes);
4358 av_freep(&sc->keyframes);
4359 av_freep(&sc->stts_data);
4360 av_freep(&sc->stps_data);
4361 av_freep(&sc->elst_data);
4362 av_freep(&sc->rap_group);
4367 static int mov_read_ilst(MOVContext *c, AVIOContext *pb, MOVAtom atom)
4370 c->itunes_metadata = 1;
4371 ret = mov_read_default(c, pb, atom);
4372 c->itunes_metadata = 0;
4376 static int mov_read_keys(MOVContext *c, AVIOContext *pb, MOVAtom atom)
4385 count = avio_rb32(pb);
4386 if (count > UINT_MAX / sizeof(*c->meta_keys) - 1) {
4387 av_log(c->fc, AV_LOG_ERROR,
4388 "The 'keys' atom with the invalid key count: %"PRIu32"\n", count);
4389 return AVERROR_INVALIDDATA;
4392 c->meta_keys_count = count + 1;
4393 c->meta_keys = av_mallocz(c->meta_keys_count * sizeof(*c->meta_keys));
4395 return AVERROR(ENOMEM);
4397 for (i = 1; i <= count; ++i) {
4398 uint32_t key_size = avio_rb32(pb);
4399 uint32_t type = avio_rl32(pb);
4401 av_log(c->fc, AV_LOG_ERROR,
4402 "The key# %"PRIu32" in meta has invalid size:"
4403 "%"PRIu32"\n", i, key_size);
4404 return AVERROR_INVALIDDATA;
4407 if (type != MKTAG('m','d','t','a')) {
4408 avio_skip(pb, key_size);
4410 c->meta_keys[i] = av_mallocz(key_size + 1);
4411 if (!c->meta_keys[i])
4412 return AVERROR(ENOMEM);
4413 avio_read(pb, c->meta_keys[i], key_size);
4419 static int mov_read_custom(MOVContext *c, AVIOContext *pb, MOVAtom atom)
4421 int64_t end = av_sat_add64(avio_tell(pb), atom.size);
4422 uint8_t *key = NULL, *val = NULL, *mean = NULL;
4426 MOVStreamContext *sc;
4428 if (c->fc->nb_streams < 1)
4430 st = c->fc->streams[c->fc->nb_streams-1];
4433 for (i = 0; i < 3; i++) {
4437 if (end - avio_tell(pb) <= 12)
4440 len = avio_rb32(pb);
4441 tag = avio_rl32(pb);
4442 avio_skip(pb, 4); // flags
4444 if (len < 12 || len - 12 > end - avio_tell(pb))
4448 if (tag == MKTAG('m', 'e', 'a', 'n'))
4450 else if (tag == MKTAG('n', 'a', 'm', 'e'))
4452 else if (tag == MKTAG('d', 'a', 't', 'a') && len > 4) {
4462 *p = av_malloc(len + 1);
4464 ret = AVERROR(ENOMEM);
4467 ret = ffio_read_size(pb, *p, len);
4475 if (mean && key && val) {
4476 if (strcmp(key, "iTunSMPB") == 0) {
4477 int priming, remainder, samples;
4478 if(sscanf(val, "%*X %X %X %X", &priming, &remainder, &samples) == 3){
4479 if(priming>0 && priming<16384)
4480 sc->start_pad = priming;
4483 if (strcmp(key, "cdec") != 0) {
4484 av_dict_set(&c->fc->metadata, key, val,
4485 AV_DICT_DONT_STRDUP_KEY | AV_DICT_DONT_STRDUP_VAL);
4489 av_log(c->fc, AV_LOG_VERBOSE,
4490 "Unhandled or malformed custom metadata of size %"PRId64"\n", atom.size);
4493 avio_seek(pb, end, SEEK_SET);
4500 static int mov_read_meta(MOVContext *c, AVIOContext *pb, MOVAtom atom)
4502 while (atom.size > 8) {
4506 tag = avio_rl32(pb);
4508 if (tag == MKTAG('h','d','l','r')) {
4509 avio_seek(pb, -8, SEEK_CUR);
4511 return mov_read_default(c, pb, atom);
4517 // return 1 when matrix is identity, 0 otherwise
4518 #define IS_MATRIX_IDENT(matrix) \
4519 ( (matrix)[0][0] == (1 << 16) && \
4520 (matrix)[1][1] == (1 << 16) && \
4521 (matrix)[2][2] == (1 << 30) && \
4522 !(matrix)[0][1] && !(matrix)[0][2] && \
4523 !(matrix)[1][0] && !(matrix)[1][2] && \
4524 !(matrix)[2][0] && !(matrix)[2][1])
4526 static int mov_read_tkhd(MOVContext *c, AVIOContext *pb, MOVAtom atom)
4531 int display_matrix[3][3];
4532 int res_display_matrix[3][3] = { { 0 } };
4534 MOVStreamContext *sc;
4538 if (c->fc->nb_streams < 1)
4540 st = c->fc->streams[c->fc->nb_streams-1];
4543 // Each stream (trak) should have exactly 1 tkhd. This catches bad files and
4544 // avoids corrupting AVStreams mapped to an earlier tkhd.
4546 return AVERROR_INVALIDDATA;
4548 version = avio_r8(pb);
4549 flags = avio_rb24(pb);
4550 st->disposition |= (flags & MOV_TKHD_FLAG_ENABLED) ? AV_DISPOSITION_DEFAULT : 0;
4556 avio_rb32(pb); /* creation time */
4557 avio_rb32(pb); /* modification time */
4559 st->id = (int)avio_rb32(pb); /* track id (NOT 0 !)*/
4560 avio_rb32(pb); /* reserved */
4562 /* highlevel (considering edits) duration in movie timebase */
4563 (version == 1) ? avio_rb64(pb) : avio_rb32(pb);
4564 avio_rb32(pb); /* reserved */
4565 avio_rb32(pb); /* reserved */
4567 avio_rb16(pb); /* layer */
4568 avio_rb16(pb); /* alternate group */
4569 avio_rb16(pb); /* volume */
4570 avio_rb16(pb); /* reserved */
4572 //read in the display matrix (outlined in ISO 14496-12, Section 6.2.2)
4573 // they're kept in fixed point format through all calculations
4574 // save u,v,z to store the whole matrix in the AV_PKT_DATA_DISPLAYMATRIX
4575 // side data, but the scale factor is not needed to calculate aspect ratio
4576 for (i = 0; i < 3; i++) {
4577 display_matrix[i][0] = avio_rb32(pb); // 16.16 fixed point
4578 display_matrix[i][1] = avio_rb32(pb); // 16.16 fixed point
4579 display_matrix[i][2] = avio_rb32(pb); // 2.30 fixed point
4582 width = avio_rb32(pb); // 16.16 fixed point track width
4583 height = avio_rb32(pb); // 16.16 fixed point track height
4584 sc->width = width >> 16;
4585 sc->height = height >> 16;
4587 // apply the moov display matrix (after the tkhd one)
4588 for (i = 0; i < 3; i++) {
4589 const int sh[3] = { 16, 16, 30 };
4590 for (j = 0; j < 3; j++) {
4591 for (e = 0; e < 3; e++) {
4592 res_display_matrix[i][j] +=
4593 ((int64_t) display_matrix[i][e] *
4594 c->movie_display_matrix[e][j]) >> sh[e];
4599 // save the matrix when it is not the default identity
4600 if (!IS_MATRIX_IDENT(res_display_matrix)) {
4603 av_freep(&sc->display_matrix);
4604 sc->display_matrix = av_malloc(sizeof(int32_t) * 9);
4605 if (!sc->display_matrix)
4606 return AVERROR(ENOMEM);
4608 for (i = 0; i < 3; i++)
4609 for (j = 0; j < 3; j++)
4610 sc->display_matrix[i * 3 + j] = res_display_matrix[i][j];
4612 #if FF_API_OLD_ROTATE_API
4613 rotate = av_display_rotation_get(sc->display_matrix);
4614 if (!isnan(rotate)) {
4615 char rotate_buf[64];
4617 if (rotate < 0) // for backward compatibility
4619 snprintf(rotate_buf, sizeof(rotate_buf), "%g", rotate);
4620 av_dict_set(&st->metadata, "rotate", rotate_buf, 0);
4625 // transform the display width/height according to the matrix
4626 // to keep the same scale, use [width height 1<<16]
4627 if (width && height && sc->display_matrix) {
4628 double disp_transform[2];
4630 for (i = 0; i < 2; i++)
4631 disp_transform[i] = hypot(sc->display_matrix[0 + i],
4632 sc->display_matrix[3 + i]);
4634 if (disp_transform[0] > 0 && disp_transform[1] > 0 &&
4635 disp_transform[0] < (1<<24) && disp_transform[1] < (1<<24) &&
4636 fabs((disp_transform[0] / disp_transform[1]) - 1.0) > 0.01)
4637 st->sample_aspect_ratio = av_d2q(
4638 disp_transform[0] / disp_transform[1],
4644 static int mov_read_tfhd(MOVContext *c, AVIOContext *pb, MOVAtom atom)
4646 MOVFragment *frag = &c->fragment;
4647 MOVTrackExt *trex = NULL;
4648 int flags, track_id, i;
4649 MOVFragmentStreamInfo * frag_stream_info;
4651 avio_r8(pb); /* version */
4652 flags = avio_rb24(pb);
4654 track_id = avio_rb32(pb);
4656 return AVERROR_INVALIDDATA;
4657 for (i = 0; i < c->trex_count; i++)
4658 if (c->trex_data[i].track_id == track_id) {
4659 trex = &c->trex_data[i];
4663 av_log(c->fc, AV_LOG_WARNING, "could not find corresponding trex (id %u)\n", track_id);
4666 c->fragment.found_tfhd = 1;
4667 frag->track_id = track_id;
4668 set_frag_stream(&c->frag_index, track_id);
4670 frag->base_data_offset = flags & MOV_TFHD_BASE_DATA_OFFSET ?
4671 avio_rb64(pb) : flags & MOV_TFHD_DEFAULT_BASE_IS_MOOF ?
4672 frag->moof_offset : frag->implicit_offset;
4673 frag->stsd_id = flags & MOV_TFHD_STSD_ID ? avio_rb32(pb) : trex->stsd_id;
4675 frag->duration = flags & MOV_TFHD_DEFAULT_DURATION ?
4676 avio_rb32(pb) : trex->duration;
4677 frag->size = flags & MOV_TFHD_DEFAULT_SIZE ?
4678 avio_rb32(pb) : trex->size;
4679 frag->flags = flags & MOV_TFHD_DEFAULT_FLAGS ?
4680 avio_rb32(pb) : trex->flags;
4681 av_log(c->fc, AV_LOG_TRACE, "frag flags 0x%x\n", frag->flags);
4683 frag_stream_info = get_current_frag_stream_info(&c->frag_index);
4684 if (frag_stream_info)
4685 frag_stream_info->next_trun_dts = AV_NOPTS_VALUE;
4690 static int mov_read_chap(MOVContext *c, AVIOContext *pb, MOVAtom atom)
4695 num = atom.size / 4;
4696 if (!(new_tracks = av_malloc_array(num, sizeof(int))))
4697 return AVERROR(ENOMEM);
4699 av_free(c->chapter_tracks);
4700 c->chapter_tracks = new_tracks;
4701 c->nb_chapter_tracks = num;
4703 for (i = 0; i < num && !pb->eof_reached; i++)
4704 c->chapter_tracks[i] = avio_rb32(pb);
4709 static int mov_read_trex(MOVContext *c, AVIOContext *pb, MOVAtom atom)
4714 if ((uint64_t)c->trex_count+1 >= UINT_MAX / sizeof(*c->trex_data))
4715 return AVERROR_INVALIDDATA;
4716 if ((err = av_reallocp_array(&c->trex_data, c->trex_count + 1,
4717 sizeof(*c->trex_data))) < 0) {
4722 c->fc->duration = AV_NOPTS_VALUE; // the duration from mvhd is not representing the whole file when fragments are used.
4724 trex = &c->trex_data[c->trex_count++];
4725 avio_r8(pb); /* version */
4726 avio_rb24(pb); /* flags */
4727 trex->track_id = avio_rb32(pb);
4728 trex->stsd_id = avio_rb32(pb);
4729 trex->duration = avio_rb32(pb);
4730 trex->size = avio_rb32(pb);
4731 trex->flags = avio_rb32(pb);
4735 static int mov_read_tfdt(MOVContext *c, AVIOContext *pb, MOVAtom atom)
4737 MOVFragment *frag = &c->fragment;
4738 AVStream *st = NULL;
4739 MOVStreamContext *sc;
4741 MOVFragmentStreamInfo * frag_stream_info;
4742 int64_t base_media_decode_time;
4744 for (i = 0; i < c->fc->nb_streams; i++) {
4745 if (c->fc->streams[i]->id == frag->track_id) {
4746 st = c->fc->streams[i];
4751 av_log(c->fc, AV_LOG_WARNING, "could not find corresponding track id %u\n", frag->track_id);
4755 if (sc->pseudo_stream_id + 1 != frag->stsd_id && sc->pseudo_stream_id != -1)
4757 version = avio_r8(pb);
4758 avio_rb24(pb); /* flags */
4760 base_media_decode_time = avio_rb64(pb);
4762 base_media_decode_time = avio_rb32(pb);
4765 frag_stream_info = get_current_frag_stream_info(&c->frag_index);
4766 if (frag_stream_info)
4767 frag_stream_info->tfdt_dts = base_media_decode_time;
4768 sc->track_end = base_media_decode_time;
4773 static int mov_read_trun(MOVContext *c, AVIOContext *pb, MOVAtom atom)
4775 MOVFragment *frag = &c->fragment;
4776 AVStream *st = NULL;
4777 MOVStreamContext *sc;
4780 int64_t dts, pts = AV_NOPTS_VALUE;
4781 int data_offset = 0;
4782 unsigned entries, first_sample_flags = frag->flags;
4783 int flags, distance, i;
4784 int64_t prev_dts = AV_NOPTS_VALUE;
4785 int next_frag_index = -1, index_entry_pos;
4786 size_t requested_size;
4787 size_t old_ctts_allocated_size;
4788 AVIndexEntry *new_entries;
4789 MOVFragmentStreamInfo * frag_stream_info;
4791 if (!frag->found_tfhd) {
4792 av_log(c->fc, AV_LOG_ERROR, "trun track id unknown, no tfhd was found\n");
4793 return AVERROR_INVALIDDATA;
4796 for (i = 0; i < c->fc->nb_streams; i++) {
4797 if (c->fc->streams[i]->id == frag->track_id) {
4798 st = c->fc->streams[i];
4803 av_log(c->fc, AV_LOG_WARNING, "could not find corresponding track id %u\n", frag->track_id);
4807 if (sc->pseudo_stream_id+1 != frag->stsd_id && sc->pseudo_stream_id != -1)
4810 // Find the next frag_index index that has a valid index_entry for
4811 // the current track_id.
4813 // A valid index_entry means the trun for the fragment was read
4814 // and it's samples are in index_entries at the given position.
4815 // New index entries will be inserted before the index_entry found.
4816 index_entry_pos = st->internal->nb_index_entries;
4817 for (i = c->frag_index.current + 1; i < c->frag_index.nb_items; i++) {
4818 frag_stream_info = get_frag_stream_info(&c->frag_index, i, frag->track_id);
4819 if (frag_stream_info && frag_stream_info->index_entry >= 0) {
4820 next_frag_index = i;
4821 index_entry_pos = frag_stream_info->index_entry;
4825 av_assert0(index_entry_pos <= st->internal->nb_index_entries);
4827 avio_r8(pb); /* version */
4828 flags = avio_rb24(pb);
4829 entries = avio_rb32(pb);
4830 av_log(c->fc, AV_LOG_TRACE, "flags 0x%x entries %u\n", flags, entries);
4832 if ((uint64_t)entries+sc->ctts_count >= UINT_MAX/sizeof(*sc->ctts_data))
4833 return AVERROR_INVALIDDATA;
4834 if (flags & MOV_TRUN_DATA_OFFSET) data_offset = avio_rb32(pb);
4835 if (flags & MOV_TRUN_FIRST_SAMPLE_FLAGS) first_sample_flags = avio_rb32(pb);
4837 frag_stream_info = get_current_frag_stream_info(&c->frag_index);
4838 if (frag_stream_info) {
4839 if (frag_stream_info->next_trun_dts != AV_NOPTS_VALUE) {
4840 dts = frag_stream_info->next_trun_dts - sc->time_offset;
4841 } else if (frag_stream_info->first_tfra_pts != AV_NOPTS_VALUE &&
4842 c->use_mfra_for == FF_MOV_FLAG_MFRA_PTS) {
4843 pts = frag_stream_info->first_tfra_pts;
4844 av_log(c->fc, AV_LOG_DEBUG, "found mfra time %"PRId64
4845 ", using it for pts\n", pts);
4846 } else if (frag_stream_info->first_tfra_pts != AV_NOPTS_VALUE &&
4847 c->use_mfra_for == FF_MOV_FLAG_MFRA_DTS) {
4848 dts = frag_stream_info->first_tfra_pts;
4849 av_log(c->fc, AV_LOG_DEBUG, "found mfra time %"PRId64
4850 ", using it for dts\n", pts);
4851 } else if (frag_stream_info->sidx_pts != AV_NOPTS_VALUE) {
4852 // FIXME: sidx earliest_presentation_time is *PTS*, s.b.
4853 // pts = frag_stream_info->sidx_pts;
4854 dts = frag_stream_info->sidx_pts - sc->time_offset;
4855 av_log(c->fc, AV_LOG_DEBUG, "found sidx time %"PRId64
4856 ", using it for pts\n", pts);
4857 } else if (frag_stream_info->tfdt_dts != AV_NOPTS_VALUE) {
4858 dts = frag_stream_info->tfdt_dts - sc->time_offset;
4859 av_log(c->fc, AV_LOG_DEBUG, "found tfdt time %"PRId64
4860 ", using it for dts\n", dts);
4862 dts = sc->track_end - sc->time_offset;
4863 av_log(c->fc, AV_LOG_DEBUG, "found track end time %"PRId64
4864 ", using it for dts\n", dts);
4867 dts = sc->track_end - sc->time_offset;
4868 av_log(c->fc, AV_LOG_DEBUG, "found track end time %"PRId64
4869 ", using it for dts\n", dts);
4871 offset = frag->base_data_offset + data_offset;
4873 av_log(c->fc, AV_LOG_TRACE, "first sample flags 0x%x\n", first_sample_flags);
4875 // realloc space for new index entries
4876 if((uint64_t)st->internal->nb_index_entries + entries >= UINT_MAX / sizeof(AVIndexEntry)) {
4877 entries = UINT_MAX / sizeof(AVIndexEntry) - st->internal->nb_index_entries;
4878 av_log(c->fc, AV_LOG_ERROR, "Failed to add index entry\n");
4883 requested_size = (st->internal->nb_index_entries + entries) * sizeof(AVIndexEntry);
4884 new_entries = av_fast_realloc(st->internal->index_entries,
4885 &st->internal->index_entries_allocated_size,
4888 return AVERROR(ENOMEM);
4889 st->internal->index_entries= new_entries;
4891 requested_size = (st->internal->nb_index_entries + entries) * sizeof(*sc->ctts_data);
4892 old_ctts_allocated_size = sc->ctts_allocated_size;
4893 ctts_data = av_fast_realloc(sc->ctts_data, &sc->ctts_allocated_size,
4896 return AVERROR(ENOMEM);
4897 sc->ctts_data = ctts_data;
4899 // In case there were samples without ctts entries, ensure they get
4900 // zero valued entries. This ensures clips which mix boxes with and
4901 // without ctts entries don't pickup uninitialized data.
4902 memset((uint8_t*)(sc->ctts_data) + old_ctts_allocated_size, 0,
4903 sc->ctts_allocated_size - old_ctts_allocated_size);
4905 if (index_entry_pos < st->internal->nb_index_entries) {
4906 // Make hole in index_entries and ctts_data for new samples
4907 memmove(st->internal->index_entries + index_entry_pos + entries,
4908 st->internal->index_entries + index_entry_pos,
4909 sizeof(*st->internal->index_entries) *
4910 (st->internal->nb_index_entries - index_entry_pos));
4911 memmove(sc->ctts_data + index_entry_pos + entries,
4912 sc->ctts_data + index_entry_pos,
4913 sizeof(*sc->ctts_data) * (sc->ctts_count - index_entry_pos));
4914 if (index_entry_pos < sc->current_sample) {
4915 sc->current_sample += entries;
4919 st->internal->nb_index_entries += entries;
4920 sc->ctts_count = st->internal->nb_index_entries;
4922 // Record the index_entry position in frag_index of this fragment
4923 if (frag_stream_info)
4924 frag_stream_info->index_entry = index_entry_pos;
4926 if (index_entry_pos > 0)
4927 prev_dts = st->internal->index_entries[index_entry_pos-1].timestamp;
4929 for (i = 0; i < entries && !pb->eof_reached; i++) {
4930 unsigned sample_size = frag->size;
4931 int sample_flags = i ? frag->flags : first_sample_flags;
4932 unsigned sample_duration = frag->duration;
4933 unsigned ctts_duration = 0;
4935 int index_entry_flags = 0;
4937 if (flags & MOV_TRUN_SAMPLE_DURATION) sample_duration = avio_rb32(pb);
4938 if (flags & MOV_TRUN_SAMPLE_SIZE) sample_size = avio_rb32(pb);
4939 if (flags & MOV_TRUN_SAMPLE_FLAGS) sample_flags = avio_rb32(pb);
4940 if (flags & MOV_TRUN_SAMPLE_CTS) ctts_duration = avio_rb32(pb);
4942 mov_update_dts_shift(sc, ctts_duration, c->fc);
4943 if (pts != AV_NOPTS_VALUE) {
4944 dts = pts - sc->dts_shift;
4945 if (flags & MOV_TRUN_SAMPLE_CTS) {
4946 dts -= ctts_duration;
4948 dts -= sc->time_offset;
4950 av_log(c->fc, AV_LOG_DEBUG,
4951 "pts %"PRId64" calculated dts %"PRId64
4952 " sc->dts_shift %d ctts.duration %d"
4953 " sc->time_offset %"PRId64
4954 " flags & MOV_TRUN_SAMPLE_CTS %d\n",
4956 sc->dts_shift, ctts_duration,
4957 sc->time_offset, flags & MOV_TRUN_SAMPLE_CTS);
4958 pts = AV_NOPTS_VALUE;
4961 if (st->codecpar->codec_type == AVMEDIA_TYPE_AUDIO)
4965 !(sample_flags & (MOV_FRAG_SAMPLE_FLAG_IS_NON_SYNC |
4966 MOV_FRAG_SAMPLE_FLAG_DEPENDS_YES));
4969 index_entry_flags |= AVINDEX_KEYFRAME;
4971 // Fragments can overlap in time. Discard overlapping frames after
4973 if (prev_dts >= dts)
4974 index_entry_flags |= AVINDEX_DISCARD_FRAME;
4976 st->internal->index_entries[index_entry_pos].pos = offset;
4977 st->internal->index_entries[index_entry_pos].timestamp = dts;
4978 st->internal->index_entries[index_entry_pos].size= sample_size;
4979 st->internal->index_entries[index_entry_pos].min_distance= distance;
4980 st->internal->index_entries[index_entry_pos].flags = index_entry_flags;
4982 sc->ctts_data[index_entry_pos].count = 1;
4983 sc->ctts_data[index_entry_pos].duration = ctts_duration;
4986 av_log(c->fc, AV_LOG_TRACE, "AVIndex stream %d, sample %d, offset %"PRIx64", dts %"PRId64", "
4987 "size %u, distance %d, keyframe %d\n", st->index,
4988 index_entry_pos, offset, dts, sample_size, distance, keyframe);
4990 dts += sample_duration;
4991 offset += sample_size;
4992 sc->data_size += sample_size;
4994 if (sample_duration <= INT64_MAX - sc->duration_for_fps &&
4995 1 <= INT_MAX - sc->nb_frames_for_fps
4997 sc->duration_for_fps += sample_duration;
4998 sc->nb_frames_for_fps ++;
5001 if (frag_stream_info)
5002 frag_stream_info->next_trun_dts = dts + sc->time_offset;
5004 // EOF found before reading all entries. Fix the hole this would
5005 // leave in index_entries and ctts_data
5006 int gap = entries - i;
5007 memmove(st->internal->index_entries + index_entry_pos,
5008 st->internal->index_entries + index_entry_pos + gap,
5009 sizeof(*st->internal->index_entries) *
5010 (st->internal->nb_index_entries - (index_entry_pos + gap)));
5011 memmove(sc->ctts_data + index_entry_pos,
5012 sc->ctts_data + index_entry_pos + gap,
5013 sizeof(*sc->ctts_data) *
5014 (sc->ctts_count - (index_entry_pos + gap)));
5016 st->internal->nb_index_entries -= gap;
5017 sc->ctts_count -= gap;
5018 if (index_entry_pos < sc->current_sample) {
5019 sc->current_sample -= gap;
5024 // The end of this new fragment may overlap in time with the start
5025 // of the next fragment in index_entries. Mark the samples in the next
5026 // fragment that overlap with AVINDEX_DISCARD_FRAME
5027 prev_dts = AV_NOPTS_VALUE;
5028 if (index_entry_pos > 0)
5029 prev_dts = st->internal->index_entries[index_entry_pos-1].timestamp;
5030 for (i = index_entry_pos; i < st->internal->nb_index_entries; i++) {
5031 if (prev_dts < st->internal->index_entries[i].timestamp)
5033 st->internal->index_entries[i].flags |= AVINDEX_DISCARD_FRAME;
5036 // If a hole was created to insert the new index_entries into,
5037 // the index_entry recorded for all subsequent moof must
5038 // be incremented by the number of entries inserted.
5039 fix_frag_index_entries(&c->frag_index, next_frag_index,
5040 frag->track_id, entries);
5042 if (pb->eof_reached) {
5043 av_log(c->fc, AV_LOG_WARNING, "reached eof, corrupted TRUN atom\n");
5047 frag->implicit_offset = offset;
5049 sc->track_end = dts + sc->time_offset;
5050 if (st->duration < sc->track_end)
5051 st->duration = sc->track_end;
5056 static int mov_read_sidx(MOVContext *c, AVIOContext *pb, MOVAtom atom)
5058 int64_t stream_size = avio_size(pb);
5059 int64_t offset = av_sat_add64(avio_tell(pb), atom.size), pts, timestamp;
5060 uint8_t version, is_complete;
5061 unsigned i, j, track_id, item_count;
5062 AVStream *st = NULL;
5063 AVStream *ref_st = NULL;
5064 MOVStreamContext *sc, *ref_sc = NULL;
5065 AVRational timescale;
5067 version = avio_r8(pb);
5069 avpriv_request_sample(c->fc, "sidx version %u", version);
5073 avio_rb24(pb); // flags
5075 track_id = avio_rb32(pb); // Reference ID
5076 for (i = 0; i < c->fc->nb_streams; i++) {
5077 if (c->fc->streams[i]->id == track_id) {
5078 st = c->fc->streams[i];
5083 av_log(c->fc, AV_LOG_WARNING, "could not find corresponding track id %d\n", track_id);
5089 timescale = av_make_q(1, avio_rb32(pb));
5091 if (timescale.den <= 0) {
5092 av_log(c->fc, AV_LOG_ERROR, "Invalid sidx timescale 1/%d\n", timescale.den);
5093 return AVERROR_INVALIDDATA;
5097 pts = avio_rb32(pb);
5098 offset += avio_rb32(pb);
5100 pts = avio_rb64(pb);
5101 offset += avio_rb64(pb);
5104 avio_rb16(pb); // reserved
5106 item_count = avio_rb16(pb);
5108 for (i = 0; i < item_count; i++) {
5110 MOVFragmentStreamInfo * frag_stream_info;
5111 uint32_t size = avio_rb32(pb);
5112 uint32_t duration = avio_rb32(pb);
5113 if (size & 0x80000000) {
5114 avpriv_request_sample(c->fc, "sidx reference_type 1");
5115 return AVERROR_PATCHWELCOME;
5117 avio_rb32(pb); // sap_flags
5118 timestamp = av_rescale_q(pts, timescale, st->time_base);
5120 index = update_frag_index(c, offset);
5121 frag_stream_info = get_frag_stream_info(&c->frag_index, index, track_id);
5122 if (frag_stream_info)
5123 frag_stream_info->sidx_pts = timestamp;
5129 st->duration = sc->track_end = pts;
5133 // See if the remaining bytes are just an mfra which we can ignore.
5134 is_complete = offset == stream_size;
5135 if (!is_complete && (pb->seekable & AVIO_SEEKABLE_NORMAL)) {
5137 int64_t original_pos = avio_tell(pb);
5138 if (!c->have_read_mfra_size) {
5139 if ((ret = avio_seek(pb, stream_size - 4, SEEK_SET)) < 0)
5141 c->mfra_size = avio_rb32(pb);
5142 c->have_read_mfra_size = 1;
5143 if ((ret = avio_seek(pb, original_pos, SEEK_SET)) < 0)
5146 if (offset + c->mfra_size == stream_size)
5151 // Find first entry in fragment index that came from an sidx.
5152 // This will pretty much always be the first entry.
5153 for (i = 0; i < c->frag_index.nb_items; i++) {
5154 MOVFragmentIndexItem * item = &c->frag_index.item[i];
5155 for (j = 0; ref_st == NULL && j < item->nb_stream_info; j++) {
5156 MOVFragmentStreamInfo * si;
5157 si = &item->stream_info[j];
5158 if (si->sidx_pts != AV_NOPTS_VALUE) {
5159 ref_st = c->fc->streams[j];
5160 ref_sc = ref_st->priv_data;
5165 if (ref_st) for (i = 0; i < c->fc->nb_streams; i++) {
5166 st = c->fc->streams[i];
5168 if (!sc->has_sidx) {
5169 st->duration = sc->track_end = av_rescale(ref_st->duration, sc->time_scale, ref_sc->time_scale);
5173 c->frag_index.complete = 1;
5179 /* this atom should be null (from specs), but some buggy files put the 'moov' atom inside it... */
5180 /* like the files created with Adobe Premiere 5.0, for samples see */
5181 /* http://graphics.tudelft.nl/~wouter/publications/soundtests/ */
5182 static int mov_read_wide(MOVContext *c, AVIOContext *pb, MOVAtom atom)
5187 return 0; /* continue */
5188 if (avio_rb32(pb) != 0) { /* 0 sized mdat atom... use the 'wide' atom size */
5189 avio_skip(pb, atom.size - 4);
5192 atom.type = avio_rl32(pb);
5194 if (atom.type != MKTAG('m','d','a','t')) {
5195 avio_skip(pb, atom.size);
5198 err = mov_read_mdat(c, pb, atom);
5202 static int mov_read_cmov(MOVContext *c, AVIOContext *pb, MOVAtom atom)
5207 uint8_t *moov_data; /* uncompressed data */
5208 long cmov_len, moov_len;
5211 avio_rb32(pb); /* dcom atom */
5212 if (avio_rl32(pb) != MKTAG('d','c','o','m'))
5213 return AVERROR_INVALIDDATA;
5214 if (avio_rl32(pb) != MKTAG('z','l','i','b')) {
5215 av_log(c->fc, AV_LOG_ERROR, "unknown compression for cmov atom !\n");
5216 return AVERROR_INVALIDDATA;
5218 avio_rb32(pb); /* cmvd atom */
5219 if (avio_rl32(pb) != MKTAG('c','m','v','d'))
5220 return AVERROR_INVALIDDATA;
5221 moov_len = avio_rb32(pb); /* uncompressed size */
5222 cmov_len = atom.size - 6 * 4;
5224 cmov_data = av_malloc(cmov_len);
5226 return AVERROR(ENOMEM);
5227 moov_data = av_malloc(moov_len);
5230 return AVERROR(ENOMEM);
5232 ret = ffio_read_size(pb, cmov_data, cmov_len);
5234 goto free_and_return;
5236 ret = AVERROR_INVALIDDATA;
5237 if (uncompress (moov_data, (uLongf *) &moov_len, (const Bytef *)cmov_data, cmov_len) != Z_OK)
5238 goto free_and_return;
5239 if (ffio_init_context(&ctx, moov_data, moov_len, 0, NULL, NULL, NULL, NULL) != 0)
5240 goto free_and_return;
5241 ctx.seekable = AVIO_SEEKABLE_NORMAL;
5242 atom.type = MKTAG('m','o','o','v');
5243 atom.size = moov_len;
5244 ret = mov_read_default(c, &ctx, atom);
5250 av_log(c->fc, AV_LOG_ERROR, "this file requires zlib support compiled in\n");
5251 return AVERROR(ENOSYS);
5255 /* edit list atom */
5256 static int mov_read_elst(MOVContext *c, AVIOContext *pb, MOVAtom atom)
5258 MOVStreamContext *sc;
5259 int i, edit_count, version;
5260 int64_t elst_entry_size;
5262 if (c->fc->nb_streams < 1 || c->ignore_editlist)
5264 sc = c->fc->streams[c->fc->nb_streams-1]->priv_data;
5266 version = avio_r8(pb); /* version */
5267 avio_rb24(pb); /* flags */
5268 edit_count = avio_rb32(pb); /* entries */
5271 elst_entry_size = version == 1 ? 20 : 12;
5272 if (atom.size != edit_count * elst_entry_size) {
5273 if (c->fc->strict_std_compliance >= FF_COMPLIANCE_STRICT) {
5274 av_log(c->fc, AV_LOG_ERROR, "Invalid edit list entry_count: %d for elst atom of size: %"PRId64" bytes.\n",
5275 edit_count, atom.size + 8);
5276 return AVERROR_INVALIDDATA;
5278 edit_count = atom.size / elst_entry_size;
5279 if (edit_count * elst_entry_size != atom.size) {
5280 av_log(c->fc, AV_LOG_WARNING, "ELST atom of %"PRId64" bytes, bigger than %d entries.\n", atom.size, edit_count);
5288 av_log(c->fc, AV_LOG_WARNING, "Duplicated ELST atom\n");
5289 av_free(sc->elst_data);
5291 sc->elst_data = av_malloc_array(edit_count, sizeof(*sc->elst_data));
5293 return AVERROR(ENOMEM);
5295 av_log(c->fc, AV_LOG_TRACE, "track[%u].edit_count = %i\n", c->fc->nb_streams - 1, edit_count);
5296 for (i = 0; i < edit_count && atom.size > 0 && !pb->eof_reached; i++) {
5297 MOVElst *e = &sc->elst_data[i];
5300 e->duration = avio_rb64(pb);
5301 e->time = avio_rb64(pb);
5304 e->duration = avio_rb32(pb); /* segment duration */
5305 e->time = (int32_t)avio_rb32(pb); /* media time */
5308 e->rate = avio_rb32(pb) / 65536.0;
5310 av_log(c->fc, AV_LOG_TRACE, "duration=%"PRId64" time=%"PRId64" rate=%f\n",
5311 e->duration, e->time, e->rate);
5313 if (e->time < 0 && e->time != -1 &&
5314 c->fc->strict_std_compliance >= FF_COMPLIANCE_STRICT) {
5315 av_log(c->fc, AV_LOG_ERROR, "Track %d, edit %d: Invalid edit list media time=%"PRId64"\n",
5316 c->fc->nb_streams-1, i, e->time);
5317 return AVERROR_INVALIDDATA;
5325 static int mov_read_tmcd(MOVContext *c, AVIOContext *pb, MOVAtom atom)
5327 MOVStreamContext *sc;
5329 if (c->fc->nb_streams < 1)
5330 return AVERROR_INVALIDDATA;
5331 sc = c->fc->streams[c->fc->nb_streams - 1]->priv_data;
5332 sc->timecode_track = avio_rb32(pb);
5336 static int mov_read_av1c(MOVContext *c, AVIOContext *pb, MOVAtom atom)
5341 if (c->fc->nb_streams < 1)
5343 st = c->fc->streams[c->fc->nb_streams - 1];
5345 if (atom.size < 4) {
5346 av_log(c->fc, AV_LOG_ERROR, "Empty AV1 Codec Configuration Box\n");
5347 return AVERROR_INVALIDDATA;
5350 /* For now, propagate only the OBUs, if any. Once libavcodec is
5351 updated to handle isobmff style extradata this can be removed. */
5357 ret = ff_get_extradata(c->fc, st->codecpar, pb, atom.size - 4);
5364 static int mov_read_vpcc(MOVContext *c, AVIOContext *pb, MOVAtom atom)
5367 int version, color_range, color_primaries, color_trc, color_space;
5369 if (c->fc->nb_streams < 1)
5371 st = c->fc->streams[c->fc->nb_streams - 1];
5373 if (atom.size < 5) {
5374 av_log(c->fc, AV_LOG_ERROR, "Empty VP Codec Configuration box\n");
5375 return AVERROR_INVALIDDATA;
5378 version = avio_r8(pb);
5380 av_log(c->fc, AV_LOG_WARNING, "Unsupported VP Codec Configuration box version %d\n", version);
5383 avio_skip(pb, 3); /* flags */
5385 avio_skip(pb, 2); /* profile + level */
5386 color_range = avio_r8(pb); /* bitDepth, chromaSubsampling, videoFullRangeFlag */
5387 color_primaries = avio_r8(pb);
5388 color_trc = avio_r8(pb);
5389 color_space = avio_r8(pb);
5390 if (avio_rb16(pb)) /* codecIntializationDataSize */
5391 return AVERROR_INVALIDDATA;
5393 if (!av_color_primaries_name(color_primaries))
5394 color_primaries = AVCOL_PRI_UNSPECIFIED;
5395 if (!av_color_transfer_name(color_trc))
5396 color_trc = AVCOL_TRC_UNSPECIFIED;
5397 if (!av_color_space_name(color_space))
5398 color_space = AVCOL_SPC_UNSPECIFIED;
5400 st->codecpar->color_range = (color_range & 1) ? AVCOL_RANGE_JPEG : AVCOL_RANGE_MPEG;
5401 st->codecpar->color_primaries = color_primaries;
5402 st->codecpar->color_trc = color_trc;
5403 st->codecpar->color_space = color_space;
5408 static int mov_read_smdm(MOVContext *c, AVIOContext *pb, MOVAtom atom)
5410 MOVStreamContext *sc;
5413 if (c->fc->nb_streams < 1)
5414 return AVERROR_INVALIDDATA;
5416 sc = c->fc->streams[c->fc->nb_streams - 1]->priv_data;
5418 if (atom.size < 5) {
5419 av_log(c->fc, AV_LOG_ERROR, "Empty Mastering Display Metadata box\n");
5420 return AVERROR_INVALIDDATA;
5423 version = avio_r8(pb);
5425 av_log(c->fc, AV_LOG_WARNING, "Unsupported Mastering Display Metadata box version %d\n", version);
5428 avio_skip(pb, 3); /* flags */
5430 sc->mastering = av_mastering_display_metadata_alloc();
5432 return AVERROR(ENOMEM);
5434 for (i = 0; i < 3; i++) {
5435 sc->mastering->display_primaries[i][0] = av_make_q(avio_rb16(pb), 1 << 16);
5436 sc->mastering->display_primaries[i][1] = av_make_q(avio_rb16(pb), 1 << 16);
5438 sc->mastering->white_point[0] = av_make_q(avio_rb16(pb), 1 << 16);
5439 sc->mastering->white_point[1] = av_make_q(avio_rb16(pb), 1 << 16);
5441 sc->mastering->max_luminance = av_make_q(avio_rb32(pb), 1 << 8);
5442 sc->mastering->min_luminance = av_make_q(avio_rb32(pb), 1 << 14);
5444 sc->mastering->has_primaries = 1;
5445 sc->mastering->has_luminance = 1;
5450 static int mov_read_mdcv(MOVContext *c, AVIOContext *pb, MOVAtom atom)
5452 MOVStreamContext *sc;
5453 const int mapping[3] = {1, 2, 0};
5454 const int chroma_den = 50000;
5455 const int luma_den = 10000;
5458 if (c->fc->nb_streams < 1)
5459 return AVERROR_INVALIDDATA;
5461 sc = c->fc->streams[c->fc->nb_streams - 1]->priv_data;
5463 if (atom.size < 24) {
5464 av_log(c->fc, AV_LOG_ERROR, "Invalid Mastering Display Color Volume box\n");
5465 return AVERROR_INVALIDDATA;
5468 sc->mastering = av_mastering_display_metadata_alloc();
5470 return AVERROR(ENOMEM);
5472 for (i = 0; i < 3; i++) {
5473 const int j = mapping[i];
5474 sc->mastering->display_primaries[j][0] = av_make_q(avio_rb16(pb), chroma_den);
5475 sc->mastering->display_primaries[j][1] = av_make_q(avio_rb16(pb), chroma_den);
5477 sc->mastering->white_point[0] = av_make_q(avio_rb16(pb), chroma_den);
5478 sc->mastering->white_point[1] = av_make_q(avio_rb16(pb), chroma_den);
5480 sc->mastering->max_luminance = av_make_q(avio_rb32(pb), luma_den);
5481 sc->mastering->min_luminance = av_make_q(avio_rb32(pb), luma_den);
5483 sc->mastering->has_luminance = 1;
5484 sc->mastering->has_primaries = 1;
5489 static int mov_read_coll(MOVContext *c, AVIOContext *pb, MOVAtom atom)
5491 MOVStreamContext *sc;
5494 if (c->fc->nb_streams < 1)
5495 return AVERROR_INVALIDDATA;
5497 sc = c->fc->streams[c->fc->nb_streams - 1]->priv_data;
5499 if (atom.size < 5) {
5500 av_log(c->fc, AV_LOG_ERROR, "Empty Content Light Level box\n");
5501 return AVERROR_INVALIDDATA;
5504 version = avio_r8(pb);
5506 av_log(c->fc, AV_LOG_WARNING, "Unsupported Content Light Level box version %d\n", version);
5509 avio_skip(pb, 3); /* flags */
5511 sc->coll = av_content_light_metadata_alloc(&sc->coll_size);
5513 return AVERROR(ENOMEM);
5515 sc->coll->MaxCLL = avio_rb16(pb);
5516 sc->coll->MaxFALL = avio_rb16(pb);
5521 static int mov_read_clli(MOVContext *c, AVIOContext *pb, MOVAtom atom)
5523 MOVStreamContext *sc;
5525 if (c->fc->nb_streams < 1)
5526 return AVERROR_INVALIDDATA;
5528 sc = c->fc->streams[c->fc->nb_streams - 1]->priv_data;
5530 if (atom.size < 4) {
5531 av_log(c->fc, AV_LOG_ERROR, "Empty Content Light Level Info box\n");
5532 return AVERROR_INVALIDDATA;
5535 sc->coll = av_content_light_metadata_alloc(&sc->coll_size);
5537 return AVERROR(ENOMEM);
5539 sc->coll->MaxCLL = avio_rb16(pb);
5540 sc->coll->MaxFALL = avio_rb16(pb);
5545 static int mov_read_st3d(MOVContext *c, AVIOContext *pb, MOVAtom atom)
5548 MOVStreamContext *sc;
5549 enum AVStereo3DType type;
5552 if (c->fc->nb_streams < 1)
5555 st = c->fc->streams[c->fc->nb_streams - 1];
5558 if (atom.size < 5) {
5559 av_log(c->fc, AV_LOG_ERROR, "Empty stereoscopic video box\n");
5560 return AVERROR_INVALIDDATA;
5562 avio_skip(pb, 4); /* version + flags */
5567 type = AV_STEREO3D_2D;
5570 type = AV_STEREO3D_TOPBOTTOM;
5573 type = AV_STEREO3D_SIDEBYSIDE;
5576 av_log(c->fc, AV_LOG_WARNING, "Unknown st3d mode value %d\n", mode);
5580 sc->stereo3d = av_stereo3d_alloc();
5582 return AVERROR(ENOMEM);
5584 sc->stereo3d->type = type;
5588 static int mov_read_sv3d(MOVContext *c, AVIOContext *pb, MOVAtom atom)
5591 MOVStreamContext *sc;
5592 int size, version, layout;
5593 int32_t yaw, pitch, roll;
5594 uint32_t l = 0, t = 0, r = 0, b = 0;
5595 uint32_t tag, padding = 0;
5596 enum AVSphericalProjection projection;
5598 if (c->fc->nb_streams < 1)
5601 st = c->fc->streams[c->fc->nb_streams - 1];
5604 if (atom.size < 8) {
5605 av_log(c->fc, AV_LOG_ERROR, "Empty spherical video box\n");
5606 return AVERROR_INVALIDDATA;
5609 size = avio_rb32(pb);
5610 if (size <= 12 || size > atom.size)
5611 return AVERROR_INVALIDDATA;
5613 tag = avio_rl32(pb);
5614 if (tag != MKTAG('s','v','h','d')) {
5615 av_log(c->fc, AV_LOG_ERROR, "Missing spherical video header\n");
5618 version = avio_r8(pb);
5620 av_log(c->fc, AV_LOG_WARNING, "Unknown spherical version %d\n",
5624 avio_skip(pb, 3); /* flags */
5625 avio_skip(pb, size - 12); /* metadata_source */
5627 size = avio_rb32(pb);
5628 if (size > atom.size)
5629 return AVERROR_INVALIDDATA;
5631 tag = avio_rl32(pb);
5632 if (tag != MKTAG('p','r','o','j')) {
5633 av_log(c->fc, AV_LOG_ERROR, "Missing projection box\n");
5637 size = avio_rb32(pb);
5638 if (size > atom.size)
5639 return AVERROR_INVALIDDATA;
5641 tag = avio_rl32(pb);
5642 if (tag != MKTAG('p','r','h','d')) {
5643 av_log(c->fc, AV_LOG_ERROR, "Missing projection header box\n");
5646 version = avio_r8(pb);
5648 av_log(c->fc, AV_LOG_WARNING, "Unknown spherical version %d\n",
5652 avio_skip(pb, 3); /* flags */
5654 /* 16.16 fixed point */
5655 yaw = avio_rb32(pb);
5656 pitch = avio_rb32(pb);
5657 roll = avio_rb32(pb);
5659 size = avio_rb32(pb);
5660 if (size > atom.size)
5661 return AVERROR_INVALIDDATA;
5663 tag = avio_rl32(pb);
5664 version = avio_r8(pb);
5666 av_log(c->fc, AV_LOG_WARNING, "Unknown spherical version %d\n",
5670 avio_skip(pb, 3); /* flags */
5672 case MKTAG('c','b','m','p'):
5673 layout = avio_rb32(pb);
5675 av_log(c->fc, AV_LOG_WARNING,
5676 "Unsupported cubemap layout %d\n", layout);
5679 projection = AV_SPHERICAL_CUBEMAP;
5680 padding = avio_rb32(pb);
5682 case MKTAG('e','q','u','i'):
5688 if (b >= UINT_MAX - t || r >= UINT_MAX - l) {
5689 av_log(c->fc, AV_LOG_ERROR,
5690 "Invalid bounding rectangle coordinates "
5691 "%"PRIu32",%"PRIu32",%"PRIu32",%"PRIu32"\n", l, t, r, b);
5692 return AVERROR_INVALIDDATA;
5695 if (l || t || r || b)
5696 projection = AV_SPHERICAL_EQUIRECTANGULAR_TILE;
5698 projection = AV_SPHERICAL_EQUIRECTANGULAR;
5701 av_log(c->fc, AV_LOG_ERROR, "Unknown projection type: %s\n", av_fourcc2str(tag));
5705 sc->spherical = av_spherical_alloc(&sc->spherical_size);
5707 return AVERROR(ENOMEM);
5709 sc->spherical->projection = projection;
5711 sc->spherical->yaw = yaw;
5712 sc->spherical->pitch = pitch;
5713 sc->spherical->roll = roll;
5715 sc->spherical->padding = padding;
5717 sc->spherical->bound_left = l;
5718 sc->spherical->bound_top = t;
5719 sc->spherical->bound_right = r;
5720 sc->spherical->bound_bottom = b;
5725 static int mov_parse_uuid_spherical(MOVStreamContext *sc, AVIOContext *pb, size_t len)
5728 uint8_t *buffer = av_malloc(len + 1);
5732 return AVERROR(ENOMEM);
5735 ret = ffio_read_size(pb, buffer, len);
5739 /* Check for mandatory keys and values, try to support XML as best-effort */
5740 if (!sc->spherical &&
5741 av_stristr(buffer, "<GSpherical:StitchingSoftware>") &&
5742 (val = av_stristr(buffer, "<GSpherical:Spherical>")) &&
5743 av_stristr(val, "true") &&
5744 (val = av_stristr(buffer, "<GSpherical:Stitched>")) &&
5745 av_stristr(val, "true") &&
5746 (val = av_stristr(buffer, "<GSpherical:ProjectionType>")) &&
5747 av_stristr(val, "equirectangular")) {
5748 sc->spherical = av_spherical_alloc(&sc->spherical_size);
5752 sc->spherical->projection = AV_SPHERICAL_EQUIRECTANGULAR;
5754 if (av_stristr(buffer, "<GSpherical:StereoMode>") && !sc->stereo3d) {
5755 enum AVStereo3DType mode;
5757 if (av_stristr(buffer, "left-right"))
5758 mode = AV_STEREO3D_SIDEBYSIDE;
5759 else if (av_stristr(buffer, "top-bottom"))
5760 mode = AV_STEREO3D_TOPBOTTOM;
5762 mode = AV_STEREO3D_2D;
5764 sc->stereo3d = av_stereo3d_alloc();
5768 sc->stereo3d->type = mode;
5772 val = av_stristr(buffer, "<GSpherical:InitialViewHeadingDegrees>");
5774 sc->spherical->yaw = strtol(val, NULL, 10) * (1 << 16);
5775 val = av_stristr(buffer, "<GSpherical:InitialViewPitchDegrees>");
5777 sc->spherical->pitch = strtol(val, NULL, 10) * (1 << 16);
5778 val = av_stristr(buffer, "<GSpherical:InitialViewRollDegrees>");
5780 sc->spherical->roll = strtol(val, NULL, 10) * (1 << 16);
5788 static int mov_read_uuid(MOVContext *c, AVIOContext *pb, MOVAtom atom)
5791 MOVStreamContext *sc;
5794 static const uint8_t uuid_isml_manifest[] = {
5795 0xa5, 0xd4, 0x0b, 0x30, 0xe8, 0x14, 0x11, 0xdd,
5796 0xba, 0x2f, 0x08, 0x00, 0x20, 0x0c, 0x9a, 0x66
5798 static const uint8_t uuid_xmp[] = {
5799 0xbe, 0x7a, 0xcf, 0xcb, 0x97, 0xa9, 0x42, 0xe8,
5800 0x9c, 0x71, 0x99, 0x94, 0x91, 0xe3, 0xaf, 0xac
5802 static const uint8_t uuid_spherical[] = {
5803 0xff, 0xcc, 0x82, 0x63, 0xf8, 0x55, 0x4a, 0x93,
5804 0x88, 0x14, 0x58, 0x7a, 0x02, 0x52, 0x1f, 0xdd,
5807 if (atom.size < sizeof(uuid) || atom.size >= FFMIN(INT_MAX, SIZE_MAX))
5808 return AVERROR_INVALIDDATA;
5810 if (c->fc->nb_streams < 1)
5812 st = c->fc->streams[c->fc->nb_streams - 1];
5815 ret = ffio_read_size(pb, uuid, sizeof(uuid));
5818 if (!memcmp(uuid, uuid_isml_manifest, sizeof(uuid))) {
5819 uint8_t *buffer, *ptr;
5821 size_t len = atom.size - sizeof(uuid);
5824 return AVERROR_INVALIDDATA;
5826 ret = avio_skip(pb, 4); // zeroes
5829 buffer = av_mallocz(len + 1);
5831 return AVERROR(ENOMEM);
5833 ret = ffio_read_size(pb, buffer, len);
5840 while ((ptr = av_stristr(ptr, "systemBitrate=\""))) {
5841 ptr += sizeof("systemBitrate=\"") - 1;
5842 c->bitrates_count++;
5843 c->bitrates = av_realloc_f(c->bitrates, c->bitrates_count, sizeof(*c->bitrates));
5845 c->bitrates_count = 0;
5847 return AVERROR(ENOMEM);
5850 ret = strtol(ptr, &endptr, 10);
5851 if (ret < 0 || errno || *endptr != '"') {
5852 c->bitrates[c->bitrates_count - 1] = 0;
5854 c->bitrates[c->bitrates_count - 1] = ret;
5859 } else if (!memcmp(uuid, uuid_xmp, sizeof(uuid))) {
5861 size_t len = atom.size - sizeof(uuid);
5862 if (c->export_xmp) {
5863 buffer = av_mallocz(len + 1);
5865 return AVERROR(ENOMEM);
5867 ret = ffio_read_size(pb, buffer, len);
5873 av_dict_set(&c->fc->metadata, "xmp",
5874 buffer, AV_DICT_DONT_STRDUP_VAL);
5876 // skip all uuid atom, which makes it fast for long uuid-xmp file
5877 ret = avio_skip(pb, len);
5881 } else if (!memcmp(uuid, uuid_spherical, sizeof(uuid))) {
5882 size_t len = atom.size - sizeof(uuid);
5883 ret = mov_parse_uuid_spherical(sc, pb, len);
5887 av_log(c->fc, AV_LOG_WARNING, "Invalid spherical metadata found\n");
5893 static int mov_read_free(MOVContext *c, AVIOContext *pb, MOVAtom atom)
5896 uint8_t content[16];
5901 ret = avio_read(pb, content, FFMIN(sizeof(content), atom.size));
5907 && !memcmp(content, "Anevia\x1A\x1A", 8)
5908 && c->use_mfra_for == FF_MOV_FLAG_MFRA_AUTO) {
5909 c->use_mfra_for = FF_MOV_FLAG_MFRA_PTS;
5915 static int mov_read_frma(MOVContext *c, AVIOContext *pb, MOVAtom atom)
5917 uint32_t format = avio_rl32(pb);
5918 MOVStreamContext *sc;
5922 if (c->fc->nb_streams < 1)
5924 st = c->fc->streams[c->fc->nb_streams - 1];
5929 case MKTAG('e','n','c','v'): // encrypted video
5930 case MKTAG('e','n','c','a'): // encrypted audio
5931 id = mov_codec_id(st, format);
5932 if (st->codecpar->codec_id != AV_CODEC_ID_NONE &&
5933 st->codecpar->codec_id != id) {
5934 av_log(c->fc, AV_LOG_WARNING,
5935 "ignoring 'frma' atom of '%.4s', stream has codec id %d\n",
5936 (char*)&format, st->codecpar->codec_id);
5940 st->codecpar->codec_id = id;
5941 sc->format = format;
5945 if (format != sc->format) {
5946 av_log(c->fc, AV_LOG_WARNING,
5947 "ignoring 'frma' atom of '%.4s', stream format is '%.4s'\n",
5948 (char*)&format, (char*)&sc->format);
5957 * Gets the current encryption info and associated current stream context. If
5958 * we are parsing a track fragment, this will return the specific encryption
5959 * info for this fragment; otherwise this will return the global encryption
5960 * info for the current stream.
5962 static int get_current_encryption_info(MOVContext *c, MOVEncryptionIndex **encryption_index, MOVStreamContext **sc)
5964 MOVFragmentStreamInfo *frag_stream_info;
5968 frag_stream_info = get_current_frag_stream_info(&c->frag_index);
5969 if (frag_stream_info) {
5970 for (i = 0; i < c->fc->nb_streams; i++) {
5971 if (c->fc->streams[i]->id == frag_stream_info->id) {
5972 st = c->fc->streams[i];
5976 if (i == c->fc->nb_streams)
5978 *sc = st->priv_data;
5980 if (!frag_stream_info->encryption_index) {
5981 // If this stream isn't encrypted, don't create the index.
5982 if (!(*sc)->cenc.default_encrypted_sample)
5984 frag_stream_info->encryption_index = av_mallocz(sizeof(*frag_stream_info->encryption_index));
5985 if (!frag_stream_info->encryption_index)
5986 return AVERROR(ENOMEM);
5988 *encryption_index = frag_stream_info->encryption_index;
5991 // No current track fragment, using stream level encryption info.
5993 if (c->fc->nb_streams < 1)
5995 st = c->fc->streams[c->fc->nb_streams - 1];
5996 *sc = st->priv_data;
5998 if (!(*sc)->cenc.encryption_index) {
5999 // If this stream isn't encrypted, don't create the index.
6000 if (!(*sc)->cenc.default_encrypted_sample)
6002 (*sc)->cenc.encryption_index = av_mallocz(sizeof(*frag_stream_info->encryption_index));
6003 if (!(*sc)->cenc.encryption_index)
6004 return AVERROR(ENOMEM);
6007 *encryption_index = (*sc)->cenc.encryption_index;
6012 static int mov_read_sample_encryption_info(MOVContext *c, AVIOContext *pb, MOVStreamContext *sc, AVEncryptionInfo **sample, int use_subsamples)
6015 unsigned int subsample_count;
6016 AVSubsampleEncryptionInfo *subsamples;
6018 if (!sc->cenc.default_encrypted_sample) {
6019 av_log(c->fc, AV_LOG_ERROR, "Missing schm or tenc\n");
6020 return AVERROR_INVALIDDATA;
6023 *sample = av_encryption_info_clone(sc->cenc.default_encrypted_sample);
6025 return AVERROR(ENOMEM);
6027 if (sc->cenc.per_sample_iv_size != 0) {
6028 if ((ret = ffio_read_size(pb, (*sample)->iv, sc->cenc.per_sample_iv_size)) < 0) {
6029 av_log(c->fc, AV_LOG_ERROR, "failed to read the initialization vector\n");
6030 av_encryption_info_free(*sample);
6036 if (use_subsamples) {
6037 subsample_count = avio_rb16(pb);
6038 av_free((*sample)->subsamples);
6039 (*sample)->subsamples = av_mallocz_array(subsample_count, sizeof(*subsamples));
6040 if (!(*sample)->subsamples) {
6041 av_encryption_info_free(*sample);
6043 return AVERROR(ENOMEM);
6046 for (i = 0; i < subsample_count && !pb->eof_reached; i++) {
6047 (*sample)->subsamples[i].bytes_of_clear_data = avio_rb16(pb);
6048 (*sample)->subsamples[i].bytes_of_protected_data = avio_rb32(pb);
6051 if (pb->eof_reached) {
6052 av_log(c->fc, AV_LOG_ERROR, "hit EOF while reading sub-sample encryption info\n");
6053 av_encryption_info_free(*sample);
6055 return AVERROR_INVALIDDATA;
6057 (*sample)->subsample_count = subsample_count;
6063 static int mov_read_senc(MOVContext *c, AVIOContext *pb, MOVAtom atom)
6065 AVEncryptionInfo **encrypted_samples;
6066 MOVEncryptionIndex *encryption_index;
6067 MOVStreamContext *sc;
6068 int use_subsamples, ret;
6069 unsigned int sample_count, i, alloc_size = 0;
6071 ret = get_current_encryption_info(c, &encryption_index, &sc);
6075 if (encryption_index->nb_encrypted_samples) {
6076 // This can happen if we have both saio/saiz and senc atoms.
6077 av_log(c->fc, AV_LOG_DEBUG, "Ignoring duplicate encryption info in senc\n");
6081 avio_r8(pb); /* version */
6082 use_subsamples = avio_rb24(pb) & 0x02; /* flags */
6084 sample_count = avio_rb32(pb);
6085 if (sample_count >= INT_MAX / sizeof(*encrypted_samples))
6086 return AVERROR(ENOMEM);
6088 for (i = 0; i < sample_count; i++) {
6089 unsigned int min_samples = FFMIN(FFMAX(i + 1, 1024 * 1024), sample_count);
6090 encrypted_samples = av_fast_realloc(encryption_index->encrypted_samples, &alloc_size,
6091 min_samples * sizeof(*encrypted_samples));
6092 if (encrypted_samples) {
6093 encryption_index->encrypted_samples = encrypted_samples;
6095 ret = mov_read_sample_encryption_info(
6096 c, pb, sc, &encryption_index->encrypted_samples[i], use_subsamples);
6098 ret = AVERROR(ENOMEM);
6100 if (pb->eof_reached) {
6101 av_log(c->fc, AV_LOG_ERROR, "Hit EOF while reading senc\n");
6102 ret = AVERROR_INVALIDDATA;
6107 av_encryption_info_free(encryption_index->encrypted_samples[i - 1]);
6108 av_freep(&encryption_index->encrypted_samples);
6112 encryption_index->nb_encrypted_samples = sample_count;
6117 static int mov_parse_auxiliary_info(MOVContext *c, MOVStreamContext *sc, AVIOContext *pb, MOVEncryptionIndex *encryption_index)
6119 AVEncryptionInfo **sample, **encrypted_samples;
6121 size_t sample_count, sample_info_size, i;
6123 unsigned int alloc_size = 0;
6125 if (encryption_index->nb_encrypted_samples)
6127 sample_count = encryption_index->auxiliary_info_sample_count;
6128 if (encryption_index->auxiliary_offsets_count != 1) {
6129 av_log(c->fc, AV_LOG_ERROR, "Multiple auxiliary info chunks are not supported\n");
6130 return AVERROR_PATCHWELCOME;
6132 if (sample_count >= INT_MAX / sizeof(*encrypted_samples))
6133 return AVERROR(ENOMEM);
6135 prev_pos = avio_tell(pb);
6136 if (!(pb->seekable & AVIO_SEEKABLE_NORMAL) ||
6137 avio_seek(pb, encryption_index->auxiliary_offsets[0], SEEK_SET) != encryption_index->auxiliary_offsets[0]) {
6138 av_log(c->fc, AV_LOG_INFO, "Failed to seek for auxiliary info, will only parse senc atoms for encryption info\n");
6142 for (i = 0; i < sample_count && !pb->eof_reached; i++) {
6143 unsigned int min_samples = FFMIN(FFMAX(i + 1, 1024 * 1024), sample_count);
6144 encrypted_samples = av_fast_realloc(encryption_index->encrypted_samples, &alloc_size,
6145 min_samples * sizeof(*encrypted_samples));
6146 if (!encrypted_samples) {
6147 ret = AVERROR(ENOMEM);
6150 encryption_index->encrypted_samples = encrypted_samples;
6152 sample = &encryption_index->encrypted_samples[i];
6153 sample_info_size = encryption_index->auxiliary_info_default_size
6154 ? encryption_index->auxiliary_info_default_size
6155 : encryption_index->auxiliary_info_sizes[i];
6157 ret = mov_read_sample_encryption_info(c, pb, sc, sample, sample_info_size > sc->cenc.per_sample_iv_size);
6161 if (pb->eof_reached) {
6162 av_log(c->fc, AV_LOG_ERROR, "Hit EOF while reading auxiliary info\n");
6163 ret = AVERROR_INVALIDDATA;
6165 encryption_index->nb_encrypted_samples = sample_count;
6169 avio_seek(pb, prev_pos, SEEK_SET);
6171 for (; i > 0; i--) {
6172 av_encryption_info_free(encryption_index->encrypted_samples[i - 1]);
6174 av_freep(&encryption_index->encrypted_samples);
6180 * Tries to read the given number of bytes from the stream and puts it in a
6181 * newly allocated buffer. This reads in small chunks to avoid allocating large
6182 * memory if the file contains an invalid/malicious size value.
6184 static int mov_try_read_block(AVIOContext *pb, size_t size, uint8_t **data)
6186 const unsigned int block_size = 1024 * 1024;
6187 uint8_t *buffer = NULL;
6188 unsigned int alloc_size = 0, offset = 0;
6189 while (offset < size) {
6190 unsigned int new_size =
6191 alloc_size >= INT_MAX - block_size ? INT_MAX : alloc_size + block_size;
6192 uint8_t *new_buffer = av_fast_realloc(buffer, &alloc_size, new_size);
6193 unsigned int to_read = FFMIN(size, alloc_size) - offset;
6196 return AVERROR(ENOMEM);
6198 buffer = new_buffer;
6200 if (avio_read(pb, buffer + offset, to_read) != to_read) {
6202 return AVERROR_INVALIDDATA;
6211 static int mov_read_saiz(MOVContext *c, AVIOContext *pb, MOVAtom atom)
6213 MOVEncryptionIndex *encryption_index;
6214 MOVStreamContext *sc;
6216 unsigned int sample_count, aux_info_type, aux_info_param;
6218 ret = get_current_encryption_info(c, &encryption_index, &sc);
6222 if (encryption_index->nb_encrypted_samples) {
6223 // This can happen if we have both saio/saiz and senc atoms.
6224 av_log(c->fc, AV_LOG_DEBUG, "Ignoring duplicate encryption info in saiz\n");
6228 if (encryption_index->auxiliary_info_sample_count) {
6229 av_log(c->fc, AV_LOG_ERROR, "Duplicate saiz atom\n");
6230 return AVERROR_INVALIDDATA;
6233 avio_r8(pb); /* version */
6234 if (avio_rb24(pb) & 0x01) { /* flags */
6235 aux_info_type = avio_rb32(pb);
6236 aux_info_param = avio_rb32(pb);
6237 if (sc->cenc.default_encrypted_sample) {
6238 if (aux_info_type != sc->cenc.default_encrypted_sample->scheme) {
6239 av_log(c->fc, AV_LOG_DEBUG, "Ignoring saiz box with non-zero aux_info_type\n");
6242 if (aux_info_param != 0) {
6243 av_log(c->fc, AV_LOG_DEBUG, "Ignoring saiz box with non-zero aux_info_type_parameter\n");
6247 // Didn't see 'schm' or 'tenc', so this isn't encrypted.
6248 if ((aux_info_type == MKBETAG('c','e','n','c') ||
6249 aux_info_type == MKBETAG('c','e','n','s') ||
6250 aux_info_type == MKBETAG('c','b','c','1') ||
6251 aux_info_type == MKBETAG('c','b','c','s')) &&
6252 aux_info_param == 0) {
6253 av_log(c->fc, AV_LOG_ERROR, "Saw encrypted saiz without schm/tenc\n");
6254 return AVERROR_INVALIDDATA;
6259 } else if (!sc->cenc.default_encrypted_sample) {
6260 // Didn't see 'schm' or 'tenc', so this isn't encrypted.
6264 encryption_index->auxiliary_info_default_size = avio_r8(pb);
6265 sample_count = avio_rb32(pb);
6266 encryption_index->auxiliary_info_sample_count = sample_count;
6268 if (encryption_index->auxiliary_info_default_size == 0) {
6269 ret = mov_try_read_block(pb, sample_count, &encryption_index->auxiliary_info_sizes);
6271 av_log(c->fc, AV_LOG_ERROR, "Failed to read the auxiliary info\n");
6276 if (encryption_index->auxiliary_offsets_count) {
6277 return mov_parse_auxiliary_info(c, sc, pb, encryption_index);
6283 static int mov_read_saio(MOVContext *c, AVIOContext *pb, MOVAtom atom)
6285 uint64_t *auxiliary_offsets;
6286 MOVEncryptionIndex *encryption_index;
6287 MOVStreamContext *sc;
6289 unsigned int version, entry_count, aux_info_type, aux_info_param;
6290 unsigned int alloc_size = 0;
6292 ret = get_current_encryption_info(c, &encryption_index, &sc);
6296 if (encryption_index->nb_encrypted_samples) {
6297 // This can happen if we have both saio/saiz and senc atoms.
6298 av_log(c->fc, AV_LOG_DEBUG, "Ignoring duplicate encryption info in saio\n");
6302 if (encryption_index->auxiliary_offsets_count) {
6303 av_log(c->fc, AV_LOG_ERROR, "Duplicate saio atom\n");
6304 return AVERROR_INVALIDDATA;
6307 version = avio_r8(pb); /* version */
6308 if (avio_rb24(pb) & 0x01) { /* flags */
6309 aux_info_type = avio_rb32(pb);
6310 aux_info_param = avio_rb32(pb);
6311 if (sc->cenc.default_encrypted_sample) {
6312 if (aux_info_type != sc->cenc.default_encrypted_sample->scheme) {
6313 av_log(c->fc, AV_LOG_DEBUG, "Ignoring saio box with non-zero aux_info_type\n");
6316 if (aux_info_param != 0) {
6317 av_log(c->fc, AV_LOG_DEBUG, "Ignoring saio box with non-zero aux_info_type_parameter\n");
6321 // Didn't see 'schm' or 'tenc', so this isn't encrypted.
6322 if ((aux_info_type == MKBETAG('c','e','n','c') ||
6323 aux_info_type == MKBETAG('c','e','n','s') ||
6324 aux_info_type == MKBETAG('c','b','c','1') ||
6325 aux_info_type == MKBETAG('c','b','c','s')) &&
6326 aux_info_param == 0) {
6327 av_log(c->fc, AV_LOG_ERROR, "Saw encrypted saio without schm/tenc\n");
6328 return AVERROR_INVALIDDATA;
6333 } else if (!sc->cenc.default_encrypted_sample) {
6334 // Didn't see 'schm' or 'tenc', so this isn't encrypted.
6338 entry_count = avio_rb32(pb);
6339 if (entry_count >= INT_MAX / sizeof(*auxiliary_offsets))
6340 return AVERROR(ENOMEM);
6342 for (i = 0; i < entry_count && !pb->eof_reached; i++) {
6343 unsigned int min_offsets = FFMIN(FFMAX(i + 1, 1024), entry_count);
6344 auxiliary_offsets = av_fast_realloc(
6345 encryption_index->auxiliary_offsets, &alloc_size,
6346 min_offsets * sizeof(*auxiliary_offsets));
6347 if (!auxiliary_offsets) {
6348 av_freep(&encryption_index->auxiliary_offsets);
6349 return AVERROR(ENOMEM);
6351 encryption_index->auxiliary_offsets = auxiliary_offsets;
6354 encryption_index->auxiliary_offsets[i] = avio_rb32(pb);
6356 encryption_index->auxiliary_offsets[i] = avio_rb64(pb);
6358 if (c->frag_index.current >= 0) {
6359 encryption_index->auxiliary_offsets[i] += c->fragment.base_data_offset;
6363 if (pb->eof_reached) {
6364 av_log(c->fc, AV_LOG_ERROR, "Hit EOF while reading saio\n");
6365 av_freep(&encryption_index->auxiliary_offsets);
6366 return AVERROR_INVALIDDATA;
6369 encryption_index->auxiliary_offsets_count = entry_count;
6371 if (encryption_index->auxiliary_info_sample_count) {
6372 return mov_parse_auxiliary_info(c, sc, pb, encryption_index);
6378 static int mov_read_pssh(MOVContext *c, AVIOContext *pb, MOVAtom atom)
6380 AVEncryptionInitInfo *info, *old_init_info;
6383 uint8_t *side_data, *extra_data, *old_side_data;
6384 size_t side_data_size;
6385 int ret = 0, old_side_data_size;
6386 unsigned int version, kid_count, extra_data_size, alloc_size = 0;
6388 if (c->fc->nb_streams < 1)
6390 st = c->fc->streams[c->fc->nb_streams-1];
6392 version = avio_r8(pb); /* version */
6393 avio_rb24(pb); /* flags */
6395 info = av_encryption_init_info_alloc(/* system_id_size */ 16, /* num_key_ids */ 0,
6396 /* key_id_size */ 16, /* data_size */ 0);
6398 return AVERROR(ENOMEM);
6400 if ((ret = ffio_read_size(pb, info->system_id, 16)) < 0) {
6401 av_log(c->fc, AV_LOG_ERROR, "Failed to read the system id\n");
6406 kid_count = avio_rb32(pb);
6407 if (kid_count >= INT_MAX / sizeof(*key_ids)) {
6408 ret = AVERROR(ENOMEM);
6412 for (unsigned int i = 0; i < kid_count && !pb->eof_reached; i++) {
6413 unsigned int min_kid_count = FFMIN(FFMAX(i + 1, 1024), kid_count);
6414 key_ids = av_fast_realloc(info->key_ids, &alloc_size,
6415 min_kid_count * sizeof(*key_ids));
6417 ret = AVERROR(ENOMEM);
6420 info->key_ids = key_ids;
6422 info->key_ids[i] = av_mallocz(16);
6423 if (!info->key_ids[i]) {
6424 ret = AVERROR(ENOMEM);
6427 info->num_key_ids = i + 1;
6429 if ((ret = ffio_read_size(pb, info->key_ids[i], 16)) < 0) {
6430 av_log(c->fc, AV_LOG_ERROR, "Failed to read the key id\n");
6435 if (pb->eof_reached) {
6436 av_log(c->fc, AV_LOG_ERROR, "Hit EOF while reading pssh\n");
6437 ret = AVERROR_INVALIDDATA;
6442 extra_data_size = avio_rb32(pb);
6443 ret = mov_try_read_block(pb, extra_data_size, &extra_data);
6447 av_freep(&info->data); // malloc(0) may still allocate something.
6448 info->data = extra_data;
6449 info->data_size = extra_data_size;
6451 // If there is existing initialization data, append to the list.
6452 old_side_data = av_stream_get_side_data(st, AV_PKT_DATA_ENCRYPTION_INIT_INFO, &old_side_data_size);
6453 if (old_side_data) {
6454 old_init_info = av_encryption_init_info_get_side_data(old_side_data, old_side_data_size);
6455 if (old_init_info) {
6456 // Append to the end of the list.
6457 for (AVEncryptionInitInfo *cur = old_init_info;; cur = cur->next) {
6463 info = old_init_info;
6465 // Assume existing side-data will be valid, so the only error we could get is OOM.
6466 ret = AVERROR(ENOMEM);
6471 side_data = av_encryption_init_info_add_side_data(info, &side_data_size);
6473 ret = AVERROR(ENOMEM);
6476 ret = av_stream_add_side_data(st, AV_PKT_DATA_ENCRYPTION_INIT_INFO,
6477 side_data, side_data_size);
6482 av_encryption_init_info_free(info);
6486 static int mov_read_schm(MOVContext *c, AVIOContext *pb, MOVAtom atom)
6489 MOVStreamContext *sc;
6491 if (c->fc->nb_streams < 1)
6493 st = c->fc->streams[c->fc->nb_streams-1];
6496 if (sc->pseudo_stream_id != 0) {
6497 av_log(c->fc, AV_LOG_ERROR, "schm boxes are only supported in first sample descriptor\n");
6498 return AVERROR_PATCHWELCOME;
6502 return AVERROR_INVALIDDATA;
6504 avio_rb32(pb); /* version and flags */
6506 if (!sc->cenc.default_encrypted_sample) {
6507 sc->cenc.default_encrypted_sample = av_encryption_info_alloc(0, 16, 16);
6508 if (!sc->cenc.default_encrypted_sample) {
6509 return AVERROR(ENOMEM);
6513 sc->cenc.default_encrypted_sample->scheme = avio_rb32(pb);
6517 static int mov_read_tenc(MOVContext *c, AVIOContext *pb, MOVAtom atom)
6520 MOVStreamContext *sc;
6521 unsigned int version, pattern, is_protected, iv_size;
6523 if (c->fc->nb_streams < 1)
6525 st = c->fc->streams[c->fc->nb_streams-1];
6528 if (sc->pseudo_stream_id != 0) {
6529 av_log(c->fc, AV_LOG_ERROR, "tenc atom are only supported in first sample descriptor\n");
6530 return AVERROR_PATCHWELCOME;
6533 if (!sc->cenc.default_encrypted_sample) {
6534 sc->cenc.default_encrypted_sample = av_encryption_info_alloc(0, 16, 16);
6535 if (!sc->cenc.default_encrypted_sample) {
6536 return AVERROR(ENOMEM);
6541 return AVERROR_INVALIDDATA;
6543 version = avio_r8(pb); /* version */
6544 avio_rb24(pb); /* flags */
6546 avio_r8(pb); /* reserved */
6547 pattern = avio_r8(pb);
6550 sc->cenc.default_encrypted_sample->crypt_byte_block = pattern >> 4;
6551 sc->cenc.default_encrypted_sample->skip_byte_block = pattern & 0xf;
6554 is_protected = avio_r8(pb);
6555 if (is_protected && !sc->cenc.encryption_index) {
6556 // The whole stream should be by-default encrypted.
6557 sc->cenc.encryption_index = av_mallocz(sizeof(MOVEncryptionIndex));
6558 if (!sc->cenc.encryption_index)
6559 return AVERROR(ENOMEM);
6561 sc->cenc.per_sample_iv_size = avio_r8(pb);
6562 if (sc->cenc.per_sample_iv_size != 0 && sc->cenc.per_sample_iv_size != 8 &&
6563 sc->cenc.per_sample_iv_size != 16) {
6564 av_log(c->fc, AV_LOG_ERROR, "invalid per-sample IV size value\n");
6565 return AVERROR_INVALIDDATA;
6567 if (avio_read(pb, sc->cenc.default_encrypted_sample->key_id, 16) != 16) {
6568 av_log(c->fc, AV_LOG_ERROR, "failed to read the default key ID\n");
6569 return AVERROR_INVALIDDATA;
6572 if (is_protected && !sc->cenc.per_sample_iv_size) {
6573 iv_size = avio_r8(pb);
6574 if (iv_size != 8 && iv_size != 16) {
6575 av_log(c->fc, AV_LOG_ERROR, "invalid default_constant_IV_size in tenc atom\n");
6576 return AVERROR_INVALIDDATA;
6579 if (avio_read(pb, sc->cenc.default_encrypted_sample->iv, iv_size) != iv_size) {
6580 av_log(c->fc, AV_LOG_ERROR, "failed to read the default IV\n");
6581 return AVERROR_INVALIDDATA;
6588 static int mov_read_dfla(MOVContext *c, AVIOContext *pb, MOVAtom atom)
6591 int last, type, size, ret;
6594 if (c->fc->nb_streams < 1)
6596 st = c->fc->streams[c->fc->nb_streams-1];
6598 if ((uint64_t)atom.size > (1<<30) || atom.size < 42)
6599 return AVERROR_INVALIDDATA;
6601 /* Check FlacSpecificBox version. */
6602 if (avio_r8(pb) != 0)
6603 return AVERROR_INVALIDDATA;
6605 avio_rb24(pb); /* Flags */
6607 avio_read(pb, buf, sizeof(buf));
6608 flac_parse_block_header(buf, &last, &type, &size);
6610 if (type != FLAC_METADATA_TYPE_STREAMINFO || size != FLAC_STREAMINFO_SIZE) {
6611 av_log(c->fc, AV_LOG_ERROR, "STREAMINFO must be first FLACMetadataBlock\n");
6612 return AVERROR_INVALIDDATA;
6615 ret = ff_get_extradata(c->fc, st->codecpar, pb, size);
6620 av_log(c->fc, AV_LOG_WARNING, "non-STREAMINFO FLACMetadataBlock(s) ignored\n");
6625 static int cenc_decrypt(MOVContext *c, MOVStreamContext *sc, AVEncryptionInfo *sample, uint8_t *input, int size)
6629 if (sample->scheme != MKBETAG('c','e','n','c') || sample->crypt_byte_block != 0 || sample->skip_byte_block != 0) {
6630 av_log(c->fc, AV_LOG_ERROR, "Only the 'cenc' encryption scheme is supported\n");
6631 return AVERROR_PATCHWELCOME;
6634 if (!sc->cenc.aes_ctr) {
6635 /* initialize the cipher */
6636 sc->cenc.aes_ctr = av_aes_ctr_alloc();
6637 if (!sc->cenc.aes_ctr) {
6638 return AVERROR(ENOMEM);
6641 ret = av_aes_ctr_init(sc->cenc.aes_ctr, c->decryption_key);
6647 av_aes_ctr_set_full_iv(sc->cenc.aes_ctr, sample->iv);
6649 if (!sample->subsample_count) {
6650 /* decrypt the whole packet */
6651 av_aes_ctr_crypt(sc->cenc.aes_ctr, input, input, size);
6655 for (i = 0; i < sample->subsample_count; i++) {
6656 if (sample->subsamples[i].bytes_of_clear_data + sample->subsamples[i].bytes_of_protected_data > size) {
6657 av_log(c->fc, AV_LOG_ERROR, "subsample size exceeds the packet size left\n");
6658 return AVERROR_INVALIDDATA;
6661 /* skip the clear bytes */
6662 input += sample->subsamples[i].bytes_of_clear_data;
6663 size -= sample->subsamples[i].bytes_of_clear_data;
6665 /* decrypt the encrypted bytes */
6666 av_aes_ctr_crypt(sc->cenc.aes_ctr, input, input, sample->subsamples[i].bytes_of_protected_data);
6667 input += sample->subsamples[i].bytes_of_protected_data;
6668 size -= sample->subsamples[i].bytes_of_protected_data;
6672 av_log(c->fc, AV_LOG_ERROR, "leftover packet bytes after subsample processing\n");
6673 return AVERROR_INVALIDDATA;
6679 static int cenc_filter(MOVContext *mov, AVStream* st, MOVStreamContext *sc, AVPacket *pkt, int current_index)
6681 MOVFragmentStreamInfo *frag_stream_info;
6682 MOVEncryptionIndex *encryption_index;
6683 AVEncryptionInfo *encrypted_sample;
6684 int encrypted_index, ret;
6686 frag_stream_info = get_frag_stream_info(&mov->frag_index, mov->frag_index.current, st->id);
6687 encrypted_index = current_index;
6688 encryption_index = NULL;
6689 if (frag_stream_info) {
6690 // Note this only supports encryption info in the first sample descriptor.
6691 if (mov->fragment.stsd_id == 1) {
6692 if (frag_stream_info->encryption_index) {
6693 encrypted_index = current_index - frag_stream_info->index_entry;
6694 encryption_index = frag_stream_info->encryption_index;
6696 encryption_index = sc->cenc.encryption_index;
6700 encryption_index = sc->cenc.encryption_index;
6703 if (encryption_index) {
6704 if (encryption_index->auxiliary_info_sample_count &&
6705 !encryption_index->nb_encrypted_samples) {
6706 av_log(mov->fc, AV_LOG_ERROR, "saiz atom found without saio\n");
6707 return AVERROR_INVALIDDATA;
6709 if (encryption_index->auxiliary_offsets_count &&
6710 !encryption_index->nb_encrypted_samples) {
6711 av_log(mov->fc, AV_LOG_ERROR, "saio atom found without saiz\n");
6712 return AVERROR_INVALIDDATA;
6715 if (!encryption_index->nb_encrypted_samples) {
6716 // Full-sample encryption with default settings.
6717 encrypted_sample = sc->cenc.default_encrypted_sample;
6718 } else if (encrypted_index >= 0 && encrypted_index < encryption_index->nb_encrypted_samples) {
6719 // Per-sample setting override.
6720 encrypted_sample = encryption_index->encrypted_samples[encrypted_index];
6722 av_log(mov->fc, AV_LOG_ERROR, "Incorrect number of samples in encryption info\n");
6723 return AVERROR_INVALIDDATA;
6726 if (mov->decryption_key) {
6727 return cenc_decrypt(mov, sc, encrypted_sample, pkt->data, pkt->size);
6730 uint8_t *side_data = av_encryption_info_add_side_data(encrypted_sample, &size);
6732 return AVERROR(ENOMEM);
6733 ret = av_packet_add_side_data(pkt, AV_PKT_DATA_ENCRYPTION_INFO, side_data, size);
6743 static int mov_read_dops(MOVContext *c, AVIOContext *pb, MOVAtom atom)
6745 const int OPUS_SEEK_PREROLL_MS = 80;
6751 if (c->fc->nb_streams < 1)
6753 st = c->fc->streams[c->fc->nb_streams-1];
6755 if ((uint64_t)atom.size > (1<<30) || atom.size < 11)
6756 return AVERROR_INVALIDDATA;
6758 /* Check OpusSpecificBox version. */
6759 if (avio_r8(pb) != 0) {
6760 av_log(c->fc, AV_LOG_ERROR, "unsupported OpusSpecificBox version\n");
6761 return AVERROR_INVALIDDATA;
6764 /* OpusSpecificBox size plus magic for Ogg OpusHead header. */
6765 size = atom.size + 8;
6767 if ((ret = ff_alloc_extradata(st->codecpar, size)) < 0)
6770 AV_WL32(st->codecpar->extradata, MKTAG('O','p','u','s'));
6771 AV_WL32(st->codecpar->extradata + 4, MKTAG('H','e','a','d'));
6772 AV_WB8(st->codecpar->extradata + 8, 1); /* OpusHead version */
6773 avio_read(pb, st->codecpar->extradata + 9, size - 9);
6775 /* OpusSpecificBox is stored in big-endian, but OpusHead is
6776 little-endian; aside from the preceeding magic and version they're
6777 otherwise currently identical. Data after output gain at offset 16
6778 doesn't need to be bytewapped. */
6779 pre_skip = AV_RB16(st->codecpar->extradata + 10);
6780 AV_WL16(st->codecpar->extradata + 10, pre_skip);
6781 AV_WL32(st->codecpar->extradata + 12, AV_RB32(st->codecpar->extradata + 12));
6782 AV_WL16(st->codecpar->extradata + 16, AV_RB16(st->codecpar->extradata + 16));
6784 st->codecpar->initial_padding = pre_skip;
6785 st->codecpar->seek_preroll = av_rescale_q(OPUS_SEEK_PREROLL_MS,
6786 (AVRational){1, 1000},
6787 (AVRational){1, 48000});
6792 static int mov_read_dmlp(MOVContext *c, AVIOContext *pb, MOVAtom atom)
6795 unsigned format_info;
6796 int channel_assignment, channel_assignment1, channel_assignment2;
6799 if (c->fc->nb_streams < 1)
6801 st = c->fc->streams[c->fc->nb_streams-1];
6804 return AVERROR_INVALIDDATA;
6806 format_info = avio_rb32(pb);
6808 ratebits = (format_info >> 28) & 0xF;
6809 channel_assignment1 = (format_info >> 15) & 0x1F;
6810 channel_assignment2 = format_info & 0x1FFF;
6811 if (channel_assignment2)
6812 channel_assignment = channel_assignment2;
6814 channel_assignment = channel_assignment1;
6816 st->codecpar->frame_size = 40 << (ratebits & 0x7);
6817 st->codecpar->sample_rate = mlp_samplerate(ratebits);
6818 st->codecpar->channels = truehd_channels(channel_assignment);
6819 st->codecpar->channel_layout = truehd_layout(channel_assignment);
6824 static int mov_read_dvcc_dvvc(MOVContext *c, AVIOContext *pb, MOVAtom atom)
6828 AVDOVIDecoderConfigurationRecord *dovi;
6832 if (c->fc->nb_streams < 1)
6834 st = c->fc->streams[c->fc->nb_streams-1];
6836 if ((uint64_t)atom.size > (1<<30) || atom.size < 4)
6837 return AVERROR_INVALIDDATA;
6839 dovi = av_dovi_alloc(&dovi_size);
6841 return AVERROR(ENOMEM);
6843 dovi->dv_version_major = avio_r8(pb);
6844 dovi->dv_version_minor = avio_r8(pb);
6846 buf = avio_rb16(pb);
6847 dovi->dv_profile = (buf >> 9) & 0x7f; // 7 bits
6848 dovi->dv_level = (buf >> 3) & 0x3f; // 6 bits
6849 dovi->rpu_present_flag = (buf >> 2) & 0x01; // 1 bit
6850 dovi->el_present_flag = (buf >> 1) & 0x01; // 1 bit
6851 dovi->bl_present_flag = buf & 0x01; // 1 bit
6852 if (atom.size >= 24) { // 4 + 4 + 4 * 4
6854 dovi->dv_bl_signal_compatibility_id = (buf >> 4) & 0x0f; // 4 bits
6856 // 0 stands for None
6857 // Dolby Vision V1.2.93 profiles and levels
6858 dovi->dv_bl_signal_compatibility_id = 0;
6861 ret = av_stream_add_side_data(st, AV_PKT_DATA_DOVI_CONF,
6862 (uint8_t *)dovi, dovi_size);
6868 av_log(c, AV_LOG_TRACE, "DOVI in dvcC/dvvC box, version: %d.%d, profile: %d, level: %d, "
6869 "rpu flag: %d, el flag: %d, bl flag: %d, compatibility id: %d\n",
6870 dovi->dv_version_major, dovi->dv_version_minor,
6871 dovi->dv_profile, dovi->dv_level,
6872 dovi->rpu_present_flag,
6873 dovi->el_present_flag,
6874 dovi->bl_present_flag,
6875 dovi->dv_bl_signal_compatibility_id
6881 static const MOVParseTableEntry mov_default_parse_table[] = {
6882 { MKTAG('A','C','L','R'), mov_read_aclr },
6883 { MKTAG('A','P','R','G'), mov_read_avid },
6884 { MKTAG('A','A','L','P'), mov_read_avid },
6885 { MKTAG('A','R','E','S'), mov_read_ares },
6886 { MKTAG('a','v','s','s'), mov_read_avss },
6887 { MKTAG('a','v','1','C'), mov_read_av1c },
6888 { MKTAG('c','h','p','l'), mov_read_chpl },
6889 { MKTAG('c','o','6','4'), mov_read_stco },
6890 { MKTAG('c','o','l','r'), mov_read_colr },
6891 { MKTAG('c','t','t','s'), mov_read_ctts }, /* composition time to sample */
6892 { MKTAG('d','i','n','f'), mov_read_default },
6893 { MKTAG('D','p','x','E'), mov_read_dpxe },
6894 { MKTAG('d','r','e','f'), mov_read_dref },
6895 { MKTAG('e','d','t','s'), mov_read_default },
6896 { MKTAG('e','l','s','t'), mov_read_elst },
6897 { MKTAG('e','n','d','a'), mov_read_enda },
6898 { MKTAG('f','i','e','l'), mov_read_fiel },
6899 { MKTAG('a','d','r','m'), mov_read_adrm },
6900 { MKTAG('f','t','y','p'), mov_read_ftyp },
6901 { MKTAG('g','l','b','l'), mov_read_glbl },
6902 { MKTAG('h','d','l','r'), mov_read_hdlr },
6903 { MKTAG('i','l','s','t'), mov_read_ilst },
6904 { MKTAG('j','p','2','h'), mov_read_jp2h },
6905 { MKTAG('m','d','a','t'), mov_read_mdat },
6906 { MKTAG('m','d','h','d'), mov_read_mdhd },
6907 { MKTAG('m','d','i','a'), mov_read_default },
6908 { MKTAG('m','e','t','a'), mov_read_meta },
6909 { MKTAG('m','i','n','f'), mov_read_default },
6910 { MKTAG('m','o','o','f'), mov_read_moof },
6911 { MKTAG('m','o','o','v'), mov_read_moov },
6912 { MKTAG('m','v','e','x'), mov_read_default },
6913 { MKTAG('m','v','h','d'), mov_read_mvhd },
6914 { MKTAG('S','M','I',' '), mov_read_svq3 },
6915 { MKTAG('a','l','a','c'), mov_read_alac }, /* alac specific atom */
6916 { MKTAG('a','v','c','C'), mov_read_glbl },
6917 { MKTAG('p','a','s','p'), mov_read_pasp },
6918 { MKTAG('s','i','d','x'), mov_read_sidx },
6919 { MKTAG('s','t','b','l'), mov_read_default },
6920 { MKTAG('s','t','c','o'), mov_read_stco },
6921 { MKTAG('s','t','p','s'), mov_read_stps },
6922 { MKTAG('s','t','r','f'), mov_read_strf },
6923 { MKTAG('s','t','s','c'), mov_read_stsc },
6924 { MKTAG('s','t','s','d'), mov_read_stsd }, /* sample description */
6925 { MKTAG('s','t','s','s'), mov_read_stss }, /* sync sample */
6926 { MKTAG('s','t','s','z'), mov_read_stsz }, /* sample size */
6927 { MKTAG('s','t','t','s'), mov_read_stts },
6928 { MKTAG('s','t','z','2'), mov_read_stsz }, /* compact sample size */
6929 { MKTAG('s','d','t','p'), mov_read_sdtp }, /* independent and disposable samples */
6930 { MKTAG('t','k','h','d'), mov_read_tkhd }, /* track header */
6931 { MKTAG('t','f','d','t'), mov_read_tfdt },
6932 { MKTAG('t','f','h','d'), mov_read_tfhd }, /* track fragment header */
6933 { MKTAG('t','r','a','k'), mov_read_trak },
6934 { MKTAG('t','r','a','f'), mov_read_default },
6935 { MKTAG('t','r','e','f'), mov_read_default },
6936 { MKTAG('t','m','c','d'), mov_read_tmcd },
6937 { MKTAG('c','h','a','p'), mov_read_chap },
6938 { MKTAG('t','r','e','x'), mov_read_trex },
6939 { MKTAG('t','r','u','n'), mov_read_trun },
6940 { MKTAG('u','d','t','a'), mov_read_default },
6941 { MKTAG('w','a','v','e'), mov_read_wave },
6942 { MKTAG('e','s','d','s'), mov_read_esds },
6943 { MKTAG('d','a','c','3'), mov_read_dac3 }, /* AC-3 info */
6944 { MKTAG('d','e','c','3'), mov_read_dec3 }, /* EAC-3 info */
6945 { MKTAG('d','d','t','s'), mov_read_ddts }, /* DTS audio descriptor */
6946 { MKTAG('w','i','d','e'), mov_read_wide }, /* place holder */
6947 { MKTAG('w','f','e','x'), mov_read_wfex },
6948 { MKTAG('c','m','o','v'), mov_read_cmov },
6949 { MKTAG('c','h','a','n'), mov_read_chan }, /* channel layout */
6950 { MKTAG('d','v','c','1'), mov_read_dvc1 },
6951 { MKTAG('s','b','g','p'), mov_read_sbgp },
6952 { MKTAG('h','v','c','C'), mov_read_glbl },
6953 { MKTAG('u','u','i','d'), mov_read_uuid },
6954 { MKTAG('C','i','n', 0x8e), mov_read_targa_y216 },
6955 { MKTAG('f','r','e','e'), mov_read_free },
6956 { MKTAG('-','-','-','-'), mov_read_custom },
6957 { MKTAG('s','i','n','f'), mov_read_default },
6958 { MKTAG('f','r','m','a'), mov_read_frma },
6959 { MKTAG('s','e','n','c'), mov_read_senc },
6960 { MKTAG('s','a','i','z'), mov_read_saiz },
6961 { MKTAG('s','a','i','o'), mov_read_saio },
6962 { MKTAG('p','s','s','h'), mov_read_pssh },
6963 { MKTAG('s','c','h','m'), mov_read_schm },
6964 { MKTAG('s','c','h','i'), mov_read_default },
6965 { MKTAG('t','e','n','c'), mov_read_tenc },
6966 { MKTAG('d','f','L','a'), mov_read_dfla },
6967 { MKTAG('s','t','3','d'), mov_read_st3d }, /* stereoscopic 3D video box */
6968 { MKTAG('s','v','3','d'), mov_read_sv3d }, /* spherical video box */
6969 { MKTAG('d','O','p','s'), mov_read_dops },
6970 { MKTAG('d','m','l','p'), mov_read_dmlp },
6971 { MKTAG('S','m','D','m'), mov_read_smdm },
6972 { MKTAG('C','o','L','L'), mov_read_coll },
6973 { MKTAG('v','p','c','C'), mov_read_vpcc },
6974 { MKTAG('m','d','c','v'), mov_read_mdcv },
6975 { MKTAG('c','l','l','i'), mov_read_clli },
6976 { MKTAG('d','v','c','C'), mov_read_dvcc_dvvc },
6977 { MKTAG('d','v','v','C'), mov_read_dvcc_dvvc },
6981 static int mov_read_default(MOVContext *c, AVIOContext *pb, MOVAtom atom)
6983 int64_t total_size = 0;
6987 if (c->atom_depth > 10) {
6988 av_log(c->fc, AV_LOG_ERROR, "Atoms too deeply nested\n");
6989 return AVERROR_INVALIDDATA;
6994 atom.size = INT64_MAX;
6995 while (total_size <= atom.size - 8 && !avio_feof(pb)) {
6996 int (*parse)(MOVContext*, AVIOContext*, MOVAtom) = NULL;
6999 if (atom.size >= 8) {
7000 a.size = avio_rb32(pb);
7001 a.type = avio_rl32(pb);
7002 if (((a.type == MKTAG('f','r','e','e') && c->moov_retry) ||
7003 a.type == MKTAG('h','o','o','v')) &&
7005 c->fc->strict_std_compliance < FF_COMPLIANCE_STRICT) {
7008 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 &&
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 */
7111 /* ignore invalid offset */
7112 if ((offset + 8) > (unsigned int)p->buf_size)
7114 tag = AV_RL32(p->buf + offset + 4);
7116 /* check for obvious tags */
7117 case MKTAG('m','o','o','v'):
7118 moov_offset = offset + 4;
7119 case MKTAG('m','d','a','t'):
7120 case MKTAG('p','n','o','t'): /* detect movs with preview pics like ew.mov and april.mov */
7121 case MKTAG('u','d','t','a'): /* Packet Video PVAuthor adds this and a lot of more junk */
7122 case MKTAG('f','t','y','p'):
7123 if (AV_RB32(p->buf+offset) < 8 &&
7124 (AV_RB32(p->buf+offset) != 1 ||
7125 offset + 12 > (unsigned int)p->buf_size ||
7126 AV_RB64(p->buf+offset + 8) == 0)) {
7127 score = FFMAX(score, AVPROBE_SCORE_EXTENSION);
7128 } else if (tag == MKTAG('f','t','y','p') &&
7129 ( AV_RL32(p->buf + offset + 8) == MKTAG('j','p','2',' ')
7130 || AV_RL32(p->buf + offset + 8) == MKTAG('j','p','x',' ')
7132 score = FFMAX(score, 5);
7134 score = AVPROBE_SCORE_MAX;
7136 offset = FFMAX(4, AV_RB32(p->buf+offset)) + offset;
7138 /* those are more common words, so rate then a bit less */
7139 case MKTAG('e','d','i','w'): /* xdcam files have reverted first tags */
7140 case MKTAG('w','i','d','e'):
7141 case MKTAG('f','r','e','e'):
7142 case MKTAG('j','u','n','k'):
7143 case MKTAG('p','i','c','t'):
7144 score = FFMAX(score, AVPROBE_SCORE_MAX - 5);
7145 offset = FFMAX(4, AV_RB32(p->buf+offset)) + offset;
7147 case MKTAG(0x82,0x82,0x7f,0x7d):
7148 case MKTAG('s','k','i','p'):
7149 case MKTAG('u','u','i','d'):
7150 case MKTAG('p','r','f','l'):
7151 /* if we only find those cause probedata is too small at least rate them */
7152 score = FFMAX(score, AVPROBE_SCORE_EXTENSION);
7153 offset = FFMAX(4, AV_RB32(p->buf+offset)) + offset;
7156 offset = FFMAX(4, AV_RB32(p->buf+offset)) + offset;
7159 if (score > AVPROBE_SCORE_MAX - 50 && moov_offset != -1) {
7160 /* moov atom in the header - we should make sure that this is not a
7161 * MOV-packed MPEG-PS */
7162 offset = moov_offset;
7164 while (offset < (p->buf_size - 16)) { /* Sufficient space */
7165 /* We found an actual hdlr atom */
7166 if (AV_RL32(p->buf + offset ) == MKTAG('h','d','l','r') &&
7167 AV_RL32(p->buf + offset + 8) == MKTAG('m','h','l','r') &&
7168 AV_RL32(p->buf + offset + 12) == MKTAG('M','P','E','G')) {
7169 av_log(NULL, AV_LOG_WARNING, "Found media data tag MPEG indicating this is a MOV-packed MPEG-PS.\n");
7170 /* We found a media handler reference atom describing an
7171 * MPEG-PS-in-MOV, return a
7172 * low score to force expanding the probe window until
7173 * mpegps_probe finds what it needs */
7185 // must be done after parsing all trak because there's no order requirement
7186 static void mov_read_chapters(AVFormatContext *s)
7188 MOVContext *mov = s->priv_data;
7190 MOVStreamContext *sc;
7195 for (j = 0; j < mov->nb_chapter_tracks; j++) {
7196 chapter_track = mov->chapter_tracks[j];
7198 for (i = 0; i < s->nb_streams; i++)
7199 if (s->streams[i]->id == chapter_track) {
7204 av_log(s, AV_LOG_ERROR, "Referenced QT chapter track not found\n");
7209 cur_pos = avio_tell(sc->pb);
7211 if (st->codecpar->codec_type == AVMEDIA_TYPE_VIDEO) {
7212 st->disposition |= AV_DISPOSITION_ATTACHED_PIC | AV_DISPOSITION_TIMED_THUMBNAILS;
7213 if (st->internal->nb_index_entries) {
7214 // Retrieve the first frame, if possible
7215 AVIndexEntry *sample = &st->internal->index_entries[0];
7216 if (avio_seek(sc->pb, sample->pos, SEEK_SET) != sample->pos) {
7217 av_log(s, AV_LOG_ERROR, "Failed to retrieve first frame\n");
7221 if (av_get_packet(sc->pb, &st->attached_pic, sample->size) < 0)
7224 st->attached_pic.stream_index = st->index;
7225 st->attached_pic.flags |= AV_PKT_FLAG_KEY;
7228 st->codecpar->codec_type = AVMEDIA_TYPE_DATA;
7229 st->codecpar->codec_id = AV_CODEC_ID_BIN_DATA;
7230 st->discard = AVDISCARD_ALL;
7231 for (i = 0; i < st->internal->nb_index_entries; i++) {
7232 AVIndexEntry *sample = &st->internal->index_entries[i];
7233 int64_t end = i+1 < st->internal->nb_index_entries ? st->internal->index_entries[i+1].timestamp : st->duration;
7238 if (end < sample->timestamp) {
7239 av_log(s, AV_LOG_WARNING, "ignoring stream duration which is shorter than chapters\n");
7240 end = AV_NOPTS_VALUE;
7243 if (avio_seek(sc->pb, sample->pos, SEEK_SET) != sample->pos) {
7244 av_log(s, AV_LOG_ERROR, "Chapter %d not found in file\n", i);
7248 // the first two bytes are the length of the title
7249 len = avio_rb16(sc->pb);
7250 if (len > sample->size-2)
7252 title_len = 2*len + 1;
7253 if (!(title = av_mallocz(title_len)))
7256 // The samples could theoretically be in any encoding if there's an encd
7257 // atom following, but in practice are only utf-8 or utf-16, distinguished
7258 // instead by the presence of a BOM
7262 ch = avio_rb16(sc->pb);
7264 avio_get_str16be(sc->pb, len, title, title_len);
7265 else if (ch == 0xfffe)
7266 avio_get_str16le(sc->pb, len, title, title_len);
7269 if (len == 1 || len == 2)
7272 avio_get_str(sc->pb, INT_MAX, title + 2, len - 1);
7276 avpriv_new_chapter(s, i, st->time_base, sample->timestamp, end, title);
7281 avio_seek(sc->pb, cur_pos, SEEK_SET);
7285 static int parse_timecode_in_framenum_format(AVFormatContext *s, AVStream *st,
7286 uint32_t value, int flags)
7289 char buf[AV_TIMECODE_STR_SIZE];
7290 AVRational rate = st->avg_frame_rate;
7291 int ret = av_timecode_init(&tc, rate, flags, 0, s);
7294 av_dict_set(&st->metadata, "timecode",
7295 av_timecode_make_string(&tc, buf, value), 0);
7299 static int mov_read_rtmd_track(AVFormatContext *s, AVStream *st)
7301 MOVStreamContext *sc = st->priv_data;
7302 char buf[AV_TIMECODE_STR_SIZE];
7303 int64_t cur_pos = avio_tell(sc->pb);
7304 int hh, mm, ss, ff, drop;
7306 if (!st->internal->nb_index_entries)
7309 avio_seek(sc->pb, st->internal->index_entries->pos, SEEK_SET);
7310 avio_skip(s->pb, 13);
7311 hh = avio_r8(s->pb);
7312 mm = avio_r8(s->pb);
7313 ss = avio_r8(s->pb);
7314 drop = avio_r8(s->pb);
7315 ff = avio_r8(s->pb);
7316 snprintf(buf, AV_TIMECODE_STR_SIZE, "%02d:%02d:%02d%c%02d",
7317 hh, mm, ss, drop ? ';' : ':', ff);
7318 av_dict_set(&st->metadata, "timecode", buf, 0);
7320 avio_seek(sc->pb, cur_pos, SEEK_SET);
7324 static int mov_read_timecode_track(AVFormatContext *s, AVStream *st)
7326 MOVStreamContext *sc = st->priv_data;
7328 int64_t cur_pos = avio_tell(sc->pb);
7331 if (!st->internal->nb_index_entries)
7334 avio_seek(sc->pb, st->internal->index_entries->pos, SEEK_SET);
7335 value = avio_rb32(s->pb);
7337 if (sc->tmcd_flags & 0x0001) flags |= AV_TIMECODE_FLAG_DROPFRAME;
7338 if (sc->tmcd_flags & 0x0002) flags |= AV_TIMECODE_FLAG_24HOURSMAX;
7339 if (sc->tmcd_flags & 0x0004) flags |= AV_TIMECODE_FLAG_ALLOWNEGATIVE;
7341 /* Assume Counter flag is set to 1 in tmcd track (even though it is likely
7342 * not the case) and thus assume "frame number format" instead of QT one.
7343 * No sample with tmcd track can be found with a QT timecode at the moment,
7344 * despite what the tmcd track "suggests" (Counter flag set to 0 means QT
7346 parse_timecode_in_framenum_format(s, st, value, flags);
7348 avio_seek(sc->pb, cur_pos, SEEK_SET);
7352 static void mov_free_encryption_index(MOVEncryptionIndex **index) {
7354 if (!index || !*index) return;
7355 for (i = 0; i < (*index)->nb_encrypted_samples; i++) {
7356 av_encryption_info_free((*index)->encrypted_samples[i]);
7358 av_freep(&(*index)->encrypted_samples);
7359 av_freep(&(*index)->auxiliary_info_sizes);
7360 av_freep(&(*index)->auxiliary_offsets);
7364 static int mov_read_close(AVFormatContext *s)
7366 MOVContext *mov = s->priv_data;
7369 for (i = 0; i < s->nb_streams; i++) {
7370 AVStream *st = s->streams[i];
7371 MOVStreamContext *sc = st->priv_data;
7376 av_freep(&sc->ctts_data);
7377 for (j = 0; j < sc->drefs_count; j++) {
7378 av_freep(&sc->drefs[j].path);
7379 av_freep(&sc->drefs[j].dir);
7381 av_freep(&sc->drefs);
7383 sc->drefs_count = 0;
7385 if (!sc->pb_is_copied)
7386 ff_format_io_close(s, &sc->pb);
7389 av_freep(&sc->chunk_offsets);
7390 av_freep(&sc->stsc_data);
7391 av_freep(&sc->sample_sizes);
7392 av_freep(&sc->keyframes);
7393 av_freep(&sc->stts_data);
7394 av_freep(&sc->sdtp_data);
7395 av_freep(&sc->stps_data);
7396 av_freep(&sc->elst_data);
7397 av_freep(&sc->rap_group);
7398 av_freep(&sc->display_matrix);
7399 av_freep(&sc->index_ranges);
7402 for (j = 0; j < sc->stsd_count; j++)
7403 av_free(sc->extradata[j]);
7404 av_freep(&sc->extradata);
7405 av_freep(&sc->extradata_size);
7407 mov_free_encryption_index(&sc->cenc.encryption_index);
7408 av_encryption_info_free(sc->cenc.default_encrypted_sample);
7409 av_aes_ctr_free(sc->cenc.aes_ctr);
7411 av_freep(&sc->stereo3d);
7412 av_freep(&sc->spherical);
7413 av_freep(&sc->mastering);
7414 av_freep(&sc->coll);
7417 av_freep(&mov->dv_demux);
7418 avformat_free_context(mov->dv_fctx);
7419 mov->dv_fctx = NULL;
7421 if (mov->meta_keys) {
7422 for (i = 1; i < mov->meta_keys_count; i++) {
7423 av_freep(&mov->meta_keys[i]);
7425 av_freep(&mov->meta_keys);
7428 av_freep(&mov->trex_data);
7429 av_freep(&mov->bitrates);
7431 for (i = 0; i < mov->frag_index.nb_items; i++) {
7432 MOVFragmentStreamInfo *frag = mov->frag_index.item[i].stream_info;
7433 for (j = 0; j < mov->frag_index.item[i].nb_stream_info; j++) {
7434 mov_free_encryption_index(&frag[j].encryption_index);
7436 av_freep(&mov->frag_index.item[i].stream_info);
7438 av_freep(&mov->frag_index.item);
7440 av_freep(&mov->aes_decrypt);
7441 av_freep(&mov->chapter_tracks);
7446 static int tmcd_is_referenced(AVFormatContext *s, int tmcd_id)
7450 for (i = 0; i < s->nb_streams; i++) {
7451 AVStream *st = s->streams[i];
7452 MOVStreamContext *sc = st->priv_data;
7454 if (st->codecpar->codec_type == AVMEDIA_TYPE_VIDEO &&
7455 sc->timecode_track == tmcd_id)
7461 /* look for a tmcd track not referenced by any video track, and export it globally */
7462 static void export_orphan_timecode(AVFormatContext *s)
7466 for (i = 0; i < s->nb_streams; i++) {
7467 AVStream *st = s->streams[i];
7469 if (st->codecpar->codec_tag == MKTAG('t','m','c','d') &&
7470 !tmcd_is_referenced(s, i + 1)) {
7471 AVDictionaryEntry *tcr = av_dict_get(st->metadata, "timecode", NULL, 0);
7473 av_dict_set(&s->metadata, "timecode", tcr->value, 0);
7480 static int read_tfra(MOVContext *mov, AVIOContext *f)
7482 int version, fieldlength, i, j;
7483 int64_t pos = avio_tell(f);
7484 uint32_t size = avio_rb32(f);
7485 unsigned track_id, item_count;
7487 if (avio_rb32(f) != MKBETAG('t', 'f', 'r', 'a')) {
7490 av_log(mov->fc, AV_LOG_VERBOSE, "found tfra\n");
7492 version = avio_r8(f);
7494 track_id = avio_rb32(f);
7495 fieldlength = avio_rb32(f);
7496 item_count = avio_rb32(f);
7497 for (i = 0; i < item_count; i++) {
7498 int64_t time, offset;
7500 MOVFragmentStreamInfo * frag_stream_info;
7503 return AVERROR_INVALIDDATA;
7507 time = avio_rb64(f);
7508 offset = avio_rb64(f);
7510 time = avio_rb32(f);
7511 offset = avio_rb32(f);
7514 // The first sample of each stream in a fragment is always a random
7515 // access sample. So it's entry in the tfra can be used as the
7516 // initial PTS of the fragment.
7517 index = update_frag_index(mov, offset);
7518 frag_stream_info = get_frag_stream_info(&mov->frag_index, index, track_id);
7519 if (frag_stream_info &&
7520 frag_stream_info->first_tfra_pts == AV_NOPTS_VALUE)
7521 frag_stream_info->first_tfra_pts = time;
7523 for (j = 0; j < ((fieldlength >> 4) & 3) + 1; j++)
7525 for (j = 0; j < ((fieldlength >> 2) & 3) + 1; j++)
7527 for (j = 0; j < ((fieldlength >> 0) & 3) + 1; j++)
7531 avio_seek(f, pos + size, SEEK_SET);
7535 static int mov_read_mfra(MOVContext *c, AVIOContext *f)
7537 int64_t stream_size = avio_size(f);
7538 int64_t original_pos = avio_tell(f);
7541 if ((seek_ret = avio_seek(f, stream_size - 4, SEEK_SET)) < 0) {
7545 c->mfra_size = avio_rb32(f);
7546 c->have_read_mfra_size = 1;
7547 if (!c->mfra_size || c->mfra_size > stream_size) {
7548 av_log(c->fc, AV_LOG_DEBUG, "doesn't look like mfra (unreasonable size)\n");
7551 if ((seek_ret = avio_seek(f, -((int64_t) c->mfra_size), SEEK_CUR)) < 0) {
7555 if (avio_rb32(f) != c->mfra_size) {
7556 av_log(c->fc, AV_LOG_DEBUG, "doesn't look like mfra (size mismatch)\n");
7559 if (avio_rb32(f) != MKBETAG('m', 'f', 'r', 'a')) {
7560 av_log(c->fc, AV_LOG_DEBUG, "doesn't look like mfra (tag mismatch)\n");
7563 av_log(c->fc, AV_LOG_VERBOSE, "stream has mfra\n");
7565 ret = read_tfra(c, f);
7570 c->frag_index.complete = 1;
7572 seek_ret = avio_seek(f, original_pos, SEEK_SET);
7574 av_log(c->fc, AV_LOG_ERROR,
7575 "failed to seek back after looking for mfra\n");
7581 static int mov_read_header(AVFormatContext *s)
7583 MOVContext *mov = s->priv_data;
7584 AVIOContext *pb = s->pb;
7586 MOVAtom atom = { AV_RL32("root") };
7589 if (mov->decryption_key_len != 0 && mov->decryption_key_len != AES_CTR_KEY_SIZE) {
7590 av_log(s, AV_LOG_ERROR, "Invalid decryption key len %d expected %d\n",
7591 mov->decryption_key_len, AES_CTR_KEY_SIZE);
7592 return AVERROR(EINVAL);
7596 mov->trak_index = -1;
7597 /* .mov and .mp4 aren't streamable anyway (only progressive download if moov is before mdat) */
7598 if (pb->seekable & AVIO_SEEKABLE_NORMAL)
7599 atom.size = avio_size(pb);
7601 atom.size = INT64_MAX;
7603 /* check MOV header */
7605 if (mov->moov_retry)
7606 avio_seek(pb, 0, SEEK_SET);
7607 if ((err = mov_read_default(mov, pb, atom)) < 0) {
7608 av_log(s, AV_LOG_ERROR, "error reading header\n");
7611 } while ((pb->seekable & AVIO_SEEKABLE_NORMAL) && !mov->found_moov && !mov->moov_retry++);
7612 if (!mov->found_moov) {
7613 av_log(s, AV_LOG_ERROR, "moov atom not found\n");
7614 err = AVERROR_INVALIDDATA;
7617 av_log(mov->fc, AV_LOG_TRACE, "on_parse_exit_offset=%"PRId64"\n", avio_tell(pb));
7619 if (pb->seekable & AVIO_SEEKABLE_NORMAL) {
7620 if (mov->nb_chapter_tracks > 0 && !mov->ignore_chapters)
7621 mov_read_chapters(s);
7622 for (i = 0; i < s->nb_streams; i++)
7623 if (s->streams[i]->codecpar->codec_tag == AV_RL32("tmcd")) {
7624 mov_read_timecode_track(s, s->streams[i]);
7625 } else if (s->streams[i]->codecpar->codec_tag == AV_RL32("rtmd")) {
7626 mov_read_rtmd_track(s, s->streams[i]);
7630 /* copy timecode metadata from tmcd tracks to the related video streams */
7631 for (i = 0; i < s->nb_streams; i++) {
7632 AVStream *st = s->streams[i];
7633 MOVStreamContext *sc = st->priv_data;
7634 if (sc->timecode_track > 0) {
7635 AVDictionaryEntry *tcr;
7636 int tmcd_st_id = -1;
7638 for (j = 0; j < s->nb_streams; j++)
7639 if (s->streams[j]->id == sc->timecode_track)
7642 if (tmcd_st_id < 0 || tmcd_st_id == i)
7644 tcr = av_dict_get(s->streams[tmcd_st_id]->metadata, "timecode", NULL, 0);
7646 av_dict_set(&st->metadata, "timecode", tcr->value, 0);
7649 export_orphan_timecode(s);
7651 for (i = 0; i < s->nb_streams; i++) {
7652 AVStream *st = s->streams[i];
7653 MOVStreamContext *sc = st->priv_data;
7654 fix_timescale(mov, sc);
7655 if (st->codecpar->codec_type == AVMEDIA_TYPE_AUDIO &&
7656 st->codecpar->codec_id == AV_CODEC_ID_AAC) {
7657 st->internal->skip_samples = sc->start_pad;
7659 if (st->codecpar->codec_type == AVMEDIA_TYPE_VIDEO && sc->nb_frames_for_fps > 0 && sc->duration_for_fps > 0)
7660 av_reduce(&st->avg_frame_rate.num, &st->avg_frame_rate.den,
7661 sc->time_scale*(int64_t)sc->nb_frames_for_fps, sc->duration_for_fps, INT_MAX);
7662 if (st->codecpar->codec_type == AVMEDIA_TYPE_SUBTITLE) {
7663 if (st->codecpar->width <= 0 || st->codecpar->height <= 0) {
7664 st->codecpar->width = sc->width;
7665 st->codecpar->height = sc->height;
7667 if (st->codecpar->codec_id == AV_CODEC_ID_DVD_SUBTITLE) {
7668 if ((err = mov_rewrite_dvd_sub_extradata(st)) < 0)
7672 if (mov->handbrake_version &&
7673 mov->handbrake_version <= 1000000*0 + 1000*10 + 2 && // 0.10.2
7674 st->codecpar->codec_id == AV_CODEC_ID_MP3) {
7675 av_log(s, AV_LOG_VERBOSE, "Forcing full parsing for mp3 stream\n");
7676 st->need_parsing = AVSTREAM_PARSE_FULL;
7680 if (mov->trex_data) {
7681 for (i = 0; i < s->nb_streams; i++) {
7682 AVStream *st = s->streams[i];
7683 MOVStreamContext *sc = st->priv_data;
7684 if (st->duration > 0) {
7685 if (sc->data_size > INT64_MAX / sc->time_scale / 8) {
7686 av_log(s, AV_LOG_ERROR, "Overflow during bit rate calculation %"PRId64" * 8 * %d\n",
7687 sc->data_size, sc->time_scale);
7688 err = AVERROR_INVALIDDATA;
7691 st->codecpar->bit_rate = sc->data_size * 8 * sc->time_scale / st->duration;
7696 if (mov->use_mfra_for > 0) {
7697 for (i = 0; i < s->nb_streams; i++) {
7698 AVStream *st = s->streams[i];
7699 MOVStreamContext *sc = st->priv_data;
7700 if (sc->duration_for_fps > 0) {
7701 if (sc->data_size > INT64_MAX / sc->time_scale / 8) {
7702 av_log(s, AV_LOG_ERROR, "Overflow during bit rate calculation %"PRId64" * 8 * %d\n",
7703 sc->data_size, sc->time_scale);
7704 err = AVERROR_INVALIDDATA;
7707 st->codecpar->bit_rate = sc->data_size * 8 * sc->time_scale /
7708 sc->duration_for_fps;
7713 for (i = 0; i < mov->bitrates_count && i < s->nb_streams; i++) {
7714 if (mov->bitrates[i]) {
7715 s->streams[i]->codecpar->bit_rate = mov->bitrates[i];
7719 ff_rfps_calculate(s);
7721 for (i = 0; i < s->nb_streams; i++) {
7722 AVStream *st = s->streams[i];
7723 MOVStreamContext *sc = st->priv_data;
7725 switch (st->codecpar->codec_type) {
7726 case AVMEDIA_TYPE_AUDIO:
7727 err = ff_replaygain_export(st, s->metadata);
7731 case AVMEDIA_TYPE_VIDEO:
7732 if (sc->display_matrix) {
7733 err = av_stream_add_side_data(st, AV_PKT_DATA_DISPLAYMATRIX, (uint8_t*)sc->display_matrix,
7734 sizeof(int32_t) * 9);
7738 sc->display_matrix = NULL;
7741 err = av_stream_add_side_data(st, AV_PKT_DATA_STEREO3D,
7742 (uint8_t *)sc->stereo3d,
7743 sizeof(*sc->stereo3d));
7747 sc->stereo3d = NULL;
7749 if (sc->spherical) {
7750 err = av_stream_add_side_data(st, AV_PKT_DATA_SPHERICAL,
7751 (uint8_t *)sc->spherical,
7752 sc->spherical_size);
7756 sc->spherical = NULL;
7758 if (sc->mastering) {
7759 err = av_stream_add_side_data(st, AV_PKT_DATA_MASTERING_DISPLAY_METADATA,
7760 (uint8_t *)sc->mastering,
7761 sizeof(*sc->mastering));
7765 sc->mastering = NULL;
7768 err = av_stream_add_side_data(st, AV_PKT_DATA_CONTENT_LIGHT_LEVEL,
7769 (uint8_t *)sc->coll,
7779 ff_configure_buffers_for_index(s, AV_TIME_BASE);
7781 for (i = 0; i < mov->frag_index.nb_items; i++)
7782 if (mov->frag_index.item[i].moof_offset <= mov->fragment.moof_offset)
7783 mov->frag_index.item[i].headers_read = 1;
7791 static AVIndexEntry *mov_find_next_sample(AVFormatContext *s, AVStream **st)
7793 AVIndexEntry *sample = NULL;
7794 int64_t best_dts = INT64_MAX;
7796 for (i = 0; i < s->nb_streams; i++) {
7797 AVStream *avst = s->streams[i];
7798 MOVStreamContext *msc = avst->priv_data;
7799 if (msc->pb && msc->current_sample < avst->internal->nb_index_entries) {
7800 AVIndexEntry *current_sample = &avst->internal->index_entries[msc->current_sample];
7801 int64_t dts = av_rescale(current_sample->timestamp, AV_TIME_BASE, msc->time_scale);
7802 av_log(s, AV_LOG_TRACE, "stream %d, sample %d, dts %"PRId64"\n", i, msc->current_sample, dts);
7803 if (!sample || (!(s->pb->seekable & AVIO_SEEKABLE_NORMAL) && current_sample->pos < sample->pos) ||
7804 ((s->pb->seekable & AVIO_SEEKABLE_NORMAL) &&
7805 ((msc->pb != s->pb && dts < best_dts) || (msc->pb == s->pb && dts != AV_NOPTS_VALUE &&
7806 ((FFABS(best_dts - dts) <= AV_TIME_BASE && current_sample->pos < sample->pos) ||
7807 (FFABS(best_dts - dts) > AV_TIME_BASE && dts < best_dts)))))) {
7808 sample = current_sample;
7817 static int should_retry(AVIOContext *pb, int error_code) {
7818 if (error_code == AVERROR_EOF || avio_feof(pb))
7824 static int mov_switch_root(AVFormatContext *s, int64_t target, int index)
7827 MOVContext *mov = s->priv_data;
7829 if (index >= 0 && index < mov->frag_index.nb_items)
7830 target = mov->frag_index.item[index].moof_offset;
7831 if (avio_seek(s->pb, target, SEEK_SET) != target) {
7832 av_log(mov->fc, AV_LOG_ERROR, "root atom offset 0x%"PRIx64": partial file\n", target);
7833 return AVERROR_INVALIDDATA;
7836 mov->next_root_atom = 0;
7837 if (index < 0 || index >= mov->frag_index.nb_items)
7838 index = search_frag_moof_offset(&mov->frag_index, target);
7839 if (index < mov->frag_index.nb_items &&
7840 mov->frag_index.item[index].moof_offset == target) {
7841 if (index + 1 < mov->frag_index.nb_items)
7842 mov->next_root_atom = mov->frag_index.item[index + 1].moof_offset;
7843 if (mov->frag_index.item[index].headers_read)
7845 mov->frag_index.item[index].headers_read = 1;
7848 mov->found_mdat = 0;
7850 ret = mov_read_default(mov, s->pb, (MOVAtom){ AV_RL32("root"), INT64_MAX });
7853 if (avio_feof(s->pb))
7855 av_log(s, AV_LOG_TRACE, "read fragments, offset 0x%"PRIx64"\n", avio_tell(s->pb));
7860 static int mov_change_extradata(MOVStreamContext *sc, AVPacket *pkt)
7862 uint8_t *side, *extradata;
7865 /* Save the current index. */
7866 sc->last_stsd_index = sc->stsc_data[sc->stsc_index].id - 1;
7868 /* Notify the decoder that extradata changed. */
7869 extradata_size = sc->extradata_size[sc->last_stsd_index];
7870 extradata = sc->extradata[sc->last_stsd_index];
7871 if (extradata_size > 0 && extradata) {
7872 side = av_packet_new_side_data(pkt,
7873 AV_PKT_DATA_NEW_EXTRADATA,
7876 return AVERROR(ENOMEM);
7877 memcpy(side, extradata, extradata_size);
7883 static int get_eia608_packet(AVIOContext *pb, AVPacket *pkt, int size)
7888 return AVERROR_INVALIDDATA;
7889 new_size = ((size - 8) / 2) * 3;
7890 ret = av_new_packet(pkt, new_size);
7895 for (int j = 0; j < new_size; j += 3) {
7896 pkt->data[j] = 0xFC;
7897 pkt->data[j+1] = avio_r8(pb);
7898 pkt->data[j+2] = avio_r8(pb);
7904 static int mov_read_packet(AVFormatContext *s, AVPacket *pkt)
7906 MOVContext *mov = s->priv_data;
7907 MOVStreamContext *sc;
7908 AVIndexEntry *sample;
7909 AVStream *st = NULL;
7910 int64_t current_index;
7914 sample = mov_find_next_sample(s, &st);
7915 if (!sample || (mov->next_root_atom && sample->pos > mov->next_root_atom)) {
7916 if (!mov->next_root_atom)
7918 if ((ret = mov_switch_root(s, mov->next_root_atom, -1)) < 0)
7923 /* must be done just before reading, to avoid infinite loop on sample */
7924 current_index = sc->current_index;
7925 mov_current_sample_inc(sc);
7927 if (mov->next_root_atom) {
7928 sample->pos = FFMIN(sample->pos, mov->next_root_atom);
7929 sample->size = FFMIN(sample->size, (mov->next_root_atom - sample->pos));
7932 if (st->discard != AVDISCARD_ALL) {
7933 int64_t ret64 = avio_seek(sc->pb, sample->pos, SEEK_SET);
7934 if (ret64 != sample->pos) {
7935 av_log(mov->fc, AV_LOG_ERROR, "stream %d, offset 0x%"PRIx64": partial file\n",
7936 sc->ffindex, sample->pos);
7937 if (should_retry(sc->pb, ret64)) {
7938 mov_current_sample_dec(sc);
7940 return AVERROR_INVALIDDATA;
7943 if (st->discard == AVDISCARD_NONKEY && !(sample->flags & AVINDEX_KEYFRAME)) {
7944 av_log(mov->fc, AV_LOG_DEBUG, "Nonkey frame from stream %d discarded due to AVDISCARD_NONKEY\n", sc->ffindex);
7948 if (st->codecpar->codec_id == AV_CODEC_ID_EIA_608 && sample->size > 8)
7949 ret = get_eia608_packet(sc->pb, pkt, sample->size);
7951 ret = av_get_packet(sc->pb, pkt, sample->size);
7953 if (should_retry(sc->pb, ret)) {
7954 mov_current_sample_dec(sc);
7958 #if CONFIG_DV_DEMUXER
7959 if (mov->dv_demux && sc->dv_audio_container) {
7960 AVBufferRef *buf = pkt->buf;
7961 ret = avpriv_dv_produce_packet(mov->dv_demux, pkt, pkt->data, pkt->size, pkt->pos);
7963 av_packet_unref(pkt);
7966 ret = avpriv_dv_get_packet(mov->dv_demux, pkt);
7971 if (sc->has_palette) {
7974 pal = av_packet_new_side_data(pkt, AV_PKT_DATA_PALETTE, AVPALETTE_SIZE);
7976 av_log(mov->fc, AV_LOG_ERROR, "Cannot append palette to packet\n");
7978 memcpy(pal, sc->palette, AVPALETTE_SIZE);
7979 sc->has_palette = 0;
7982 if (st->codecpar->codec_id == AV_CODEC_ID_MP3 && !st->need_parsing && pkt->size > 4) {
7983 if (ff_mpa_check_header(AV_RB32(pkt->data)) < 0)
7984 st->need_parsing = AVSTREAM_PARSE_FULL;
7988 pkt->stream_index = sc->ffindex;
7989 pkt->dts = sample->timestamp;
7990 if (sample->flags & AVINDEX_DISCARD_FRAME) {
7991 pkt->flags |= AV_PKT_FLAG_DISCARD;
7993 if (sc->ctts_data && sc->ctts_index < sc->ctts_count) {
7994 pkt->pts = pkt->dts + sc->dts_shift + sc->ctts_data[sc->ctts_index].duration;
7995 /* update ctts context */
7997 if (sc->ctts_index < sc->ctts_count &&
7998 sc->ctts_data[sc->ctts_index].count == sc->ctts_sample) {
8000 sc->ctts_sample = 0;
8003 int64_t next_dts = (sc->current_sample < st->internal->nb_index_entries) ?
8004 st->internal->index_entries[sc->current_sample].timestamp : st->duration;
8006 if (next_dts >= pkt->dts)
8007 pkt->duration = next_dts - pkt->dts;
8008 pkt->pts = pkt->dts;
8010 if (st->discard == AVDISCARD_ALL)
8012 if (sc->sdtp_data && sc->current_sample <= sc->sdtp_count) {
8013 uint8_t sample_flags = sc->sdtp_data[sc->current_sample - 1];
8014 uint8_t sample_is_depended_on = (sample_flags >> 2) & 0x3;
8015 pkt->flags |= sample_is_depended_on == MOV_SAMPLE_DEPENDENCY_NO ? AV_PKT_FLAG_DISPOSABLE : 0;
8017 pkt->flags |= sample->flags & AVINDEX_KEYFRAME ? AV_PKT_FLAG_KEY : 0;
8018 pkt->pos = sample->pos;
8020 /* Multiple stsd handling. */
8021 if (sc->stsc_data) {
8022 /* Keep track of the stsc index for the given sample, then check
8023 * if the stsd index is different from the last used one. */
8025 if (mov_stsc_index_valid(sc->stsc_index, sc->stsc_count) &&
8026 mov_get_stsc_samples(sc, sc->stsc_index) == sc->stsc_sample) {
8028 sc->stsc_sample = 0;
8029 /* Do not check indexes after a switch. */
8030 } else if (sc->stsc_data[sc->stsc_index].id > 0 &&
8031 sc->stsc_data[sc->stsc_index].id - 1 < sc->stsd_count &&
8032 sc->stsc_data[sc->stsc_index].id - 1 != sc->last_stsd_index) {
8033 ret = mov_change_extradata(sc, pkt);
8040 aax_filter(pkt->data, pkt->size, mov);
8042 ret = cenc_filter(mov, st, sc, pkt, current_index);
8050 static int mov_seek_fragment(AVFormatContext *s, AVStream *st, int64_t timestamp)
8052 MOVContext *mov = s->priv_data;
8055 if (!mov->frag_index.complete)
8058 index = search_frag_timestamp(&mov->frag_index, st, timestamp);
8061 if (!mov->frag_index.item[index].headers_read)
8062 return mov_switch_root(s, -1, index);
8063 if (index + 1 < mov->frag_index.nb_items)
8064 mov->next_root_atom = mov->frag_index.item[index + 1].moof_offset;
8069 static int mov_seek_stream(AVFormatContext *s, AVStream *st, int64_t timestamp, int flags)
8071 MOVStreamContext *sc = st->priv_data;
8072 int sample, time_sample, ret;
8075 // Here we consider timestamp to be PTS, hence try to offset it so that we
8076 // can search over the DTS timeline.
8077 timestamp -= (sc->min_corrected_pts + sc->dts_shift);
8079 ret = mov_seek_fragment(s, st, timestamp);
8083 sample = av_index_search_timestamp(st, timestamp, flags);
8084 av_log(s, AV_LOG_TRACE, "stream %d, timestamp %"PRId64", sample %d\n", st->index, timestamp, sample);
8085 if (sample < 0 && st->internal->nb_index_entries && timestamp < st->internal->index_entries[0].timestamp)
8087 if (sample < 0) /* not sure what to do */
8088 return AVERROR_INVALIDDATA;
8089 mov_current_sample_set(sc, sample);
8090 av_log(s, AV_LOG_TRACE, "stream %d, found sample %d\n", st->index, sc->current_sample);
8091 /* adjust ctts index */
8092 if (sc->ctts_data) {
8094 for (i = 0; i < sc->ctts_count; i++) {
8095 int next = time_sample + sc->ctts_data[i].count;
8096 if (next > sc->current_sample) {
8098 sc->ctts_sample = sc->current_sample - time_sample;
8105 /* adjust stsd index */
8106 if (sc->chunk_count) {
8108 for (i = 0; i < sc->stsc_count; i++) {
8109 int64_t next = time_sample + mov_get_stsc_samples(sc, i);
8110 if (next > sc->current_sample) {
8112 sc->stsc_sample = sc->current_sample - time_sample;
8115 av_assert0(next == (int)next);
8123 static int mov_read_seek(AVFormatContext *s, int stream_index, int64_t sample_time, int flags)
8125 MOVContext *mc = s->priv_data;
8130 if (stream_index >= s->nb_streams)
8131 return AVERROR_INVALIDDATA;
8133 st = s->streams[stream_index];
8134 sample = mov_seek_stream(s, st, sample_time, flags);
8138 if (mc->seek_individually) {
8139 /* adjust seek timestamp to found sample timestamp */
8140 int64_t seek_timestamp = st->internal->index_entries[sample].timestamp;
8142 for (i = 0; i < s->nb_streams; i++) {
8144 MOVStreamContext *sc = s->streams[i]->priv_data;
8146 st->internal->skip_samples = (sample_time <= 0) ? sc->start_pad : 0;
8148 if (stream_index == i)
8151 timestamp = av_rescale_q(seek_timestamp, s->streams[stream_index]->time_base, st->time_base);
8152 mov_seek_stream(s, st, timestamp, flags);
8155 for (i = 0; i < s->nb_streams; i++) {
8156 MOVStreamContext *sc;
8159 mov_current_sample_set(sc, 0);
8162 MOVStreamContext *sc;
8163 AVIndexEntry *entry = mov_find_next_sample(s, &st);
8165 return AVERROR_INVALIDDATA;
8167 if (sc->ffindex == stream_index && sc->current_sample == sample)
8169 mov_current_sample_inc(sc);
8175 #define OFFSET(x) offsetof(MOVContext, x)
8176 #define FLAGS AV_OPT_FLAG_VIDEO_PARAM | AV_OPT_FLAG_DECODING_PARAM
8177 static const AVOption mov_options[] = {
8178 {"use_absolute_path",
8179 "allow using absolute path when opening alias, this is a possible security issue",
8180 OFFSET(use_absolute_path), AV_OPT_TYPE_BOOL, {.i64 = 0},
8182 {"seek_streams_individually",
8183 "Seek each stream individually to the closest point",
8184 OFFSET(seek_individually), AV_OPT_TYPE_BOOL, { .i64 = 1 },
8186 {"ignore_editlist", "Ignore the edit list atom.", OFFSET(ignore_editlist), AV_OPT_TYPE_BOOL, {.i64 = 0},
8188 {"advanced_editlist",
8189 "Modify the AVIndex according to the editlists. Use this option to decode in the order specified by the edits.",
8190 OFFSET(advanced_editlist), AV_OPT_TYPE_BOOL, {.i64 = 1},
8192 {"ignore_chapters", "", OFFSET(ignore_chapters), AV_OPT_TYPE_BOOL, {.i64 = 0},
8195 "use mfra for fragment timestamps",
8196 OFFSET(use_mfra_for), AV_OPT_TYPE_INT, {.i64 = FF_MOV_FLAG_MFRA_AUTO},
8197 -1, FF_MOV_FLAG_MFRA_PTS, FLAGS,
8199 {"auto", "auto", 0, AV_OPT_TYPE_CONST, {.i64 = FF_MOV_FLAG_MFRA_AUTO}, 0, 0,
8200 FLAGS, "use_mfra_for" },
8201 {"dts", "dts", 0, AV_OPT_TYPE_CONST, {.i64 = FF_MOV_FLAG_MFRA_DTS}, 0, 0,
8202 FLAGS, "use_mfra_for" },
8203 {"pts", "pts", 0, AV_OPT_TYPE_CONST, {.i64 = FF_MOV_FLAG_MFRA_PTS}, 0, 0,
8204 FLAGS, "use_mfra_for" },
8205 { "export_all", "Export unrecognized metadata entries", OFFSET(export_all),
8206 AV_OPT_TYPE_BOOL, { .i64 = 0 }, 0, 1, .flags = FLAGS },
8207 { "export_xmp", "Export full XMP metadata", OFFSET(export_xmp),
8208 AV_OPT_TYPE_BOOL, { .i64 = 0 }, 0, 1, .flags = FLAGS },
8209 { "activation_bytes", "Secret bytes for Audible AAX files", OFFSET(activation_bytes),
8210 AV_OPT_TYPE_BINARY, .flags = AV_OPT_FLAG_DECODING_PARAM },
8211 { "audible_key", "AES-128 Key for Audible AAXC files", OFFSET(audible_key),
8212 AV_OPT_TYPE_BINARY, .flags = AV_OPT_FLAG_DECODING_PARAM },
8213 { "audible_iv", "AES-128 IV for Audible AAXC files", OFFSET(audible_iv),
8214 AV_OPT_TYPE_BINARY, .flags = AV_OPT_FLAG_DECODING_PARAM },
8215 { "audible_fixed_key", // extracted from libAAX_SDK.so and AAXSDKWin.dll files!
8216 "Fixed key used for handling Audible AAX files", OFFSET(audible_fixed_key),
8217 AV_OPT_TYPE_BINARY, {.str="77214d4b196a87cd520045fd20a51d67"},
8218 .flags = AV_OPT_FLAG_DECODING_PARAM },
8219 { "decryption_key", "The media decryption key (hex)", OFFSET(decryption_key), AV_OPT_TYPE_BINARY, .flags = AV_OPT_FLAG_DECODING_PARAM },
8220 { "enable_drefs", "Enable external track support.", OFFSET(enable_drefs), AV_OPT_TYPE_BOOL,
8221 {.i64 = 0}, 0, 1, FLAGS },
8226 static const AVClass mov_class = {
8227 .class_name = "mov,mp4,m4a,3gp,3g2,mj2",
8228 .item_name = av_default_item_name,
8229 .option = mov_options,
8230 .version = LIBAVUTIL_VERSION_INT,
8233 AVInputFormat ff_mov_demuxer = {
8234 .name = "mov,mp4,m4a,3gp,3g2,mj2",
8235 .long_name = NULL_IF_CONFIG_SMALL("QuickTime / MOV"),
8236 .priv_class = &mov_class,
8237 .priv_data_size = sizeof(MOVContext),
8238 .extensions = "mov,mp4,m4a,3gp,3g2,mj2,psp,m4b,ism,ismv,isma,f4v",
8239 .read_probe = mov_probe,
8240 .read_header = mov_read_header,
8241 .read_packet = mov_read_packet,
8242 .read_close = mov_read_close,
8243 .read_seek = mov_read_seek,
8244 .flags = AVFMT_NO_BYTE_SEEK | AVFMT_SEEK_TO_PTS,